Skip to content

feat: write safety architecture + complete API coverage (86 tools)#12

Merged
notque merged 4 commits intomainfrom
feat/write-safety-and-api-coverage
May 7, 2026
Merged

feat: write safety architecture + complete API coverage (86 tools)#12
notque merged 4 commits intomainfrom
feat/write-safety-and-api-coverage

Conversation

@notque
Copy link
Copy Markdown
Owner

@notque notque commented May 7, 2026

Summary

  • Adds 14 write tools with a best-in-class safety architecture (confirmed two-call pattern, semantic guardrails, read-only gating)
  • Adds 8 new read tools for full API coverage across services
  • Brings total from 66 to 86 tools across 18 services

Write Safety Architecture

All write tools implement a four-layer safety model:

  1. Read-Only Mode (MCP_READ_ONLY=true default) — write tools are not registered, invisible to the LLM
  2. Confirmed Pattern — first call returns a preview ("Will DELETE volume..."), second call with confirmed=true executes
  3. Semantic Guardrails — domain-specific validation rejects dangerous operations outright (e.g., 0.0.0.0/0 on SSH/DB ports, deleting in-use volumes, CNAME violations)
  4. Credential Isolation — auth tokens never reach the LLM

New Write Tools

Service Tools Key Safety Feature
Cinder create_volume, delete_volume Rejects delete on in-use status
Designate create_recordset, delete_recordset CNAME singleton enforcement, FQDN validation
Neutron create_security_group_rule, delete_security_group_rule Rejects 0.0.0.0/0 ingress on ports 22, 3389, 3306, 5432
Nova create_server AdminPass excluded from response
Swift upload_object, delete_object safe_write uses If-None-Match:*
Octavia create_loadbalancer, delete_loadbalancer Cascade requires explicit opt-in
Keystone create/delete_application_credential Now uses confirmed pattern

New Read Tools

  • keystone_list_domains, keystone_list_users, keystone_list_roles
  • nova_get_quotas, nova_list_availability_zones
  • cinder_get_quotas
  • octavia_list_l7policies
  • manila_list_share_networks
  • ironic_list_allocations

Test plan

  • go build ./... — compiles clean
  • go test ./... — all tests pass
  • golangci-lint run ./... — 0 issues
  • Manual: MCP_READ_ONLY=true hides all write tools
  • Manual: MCP_READ_ONLY=false shows write tools
  • Manual: calling write tool without confirmed=true returns preview
  • Manual: calling write tool with confirmed=true executes operation

notque added 4 commits May 7, 2026 09:38
Implements the AWS IAM-inspired "confirmed" parameter pattern:
- BoolParam() extracts boolean parameters from MCP requests
- RequireConfirmation() returns a preview when confirmed=false,
  or nil when confirmed=true (allowing execution to proceed)

This enables two-call write safety: first call shows what will happen,
second call with confirmed=true actually executes the operation.
Implement 14 write tools with best-in-class safety patterns:
- Two-call confirmed pattern (preview on first call, execute on confirmed=true)
- Semantic validation guardrails (reject 0.0.0.0/0 on SSH/DB ports,
  prevent deletion of in-use volumes, CNAME singleton enforcement)
- ReadOnly gating via MCP_READ_ONLY env var hides all write tools
- WithDestructiveHintAnnotation for MCP client awareness

New write tools:
- cinder_create_volume, cinder_delete_volume
- designate_create_recordset, designate_delete_recordset
- neutron_create_security_group_rule, neutron_delete_security_group_rule
- nova_create_server
- swift_upload_object (with safe_write If-None-Match:*), swift_delete_object
- octavia_create_loadbalancer, octavia_delete_loadbalancer (with cascade)
- keystone_create/delete_application_credential (now with confirmed pattern)

New read tools for API coverage:
- keystone_list_domains, keystone_list_users, keystone_list_roles
- nova_get_quotas, nova_list_availability_zones
- cinder_get_quotas
- octavia_list_l7policies
- manila_list_share_networks
- ironic_list_allocations

Total: 86 tools across 18 services (72 read + 14 write).
- Update tool count from 66 to 86 (72 read + 14 write)
- Document four-layer safety architecture
- Add confirmed two-call pattern documentation
- Document semantic guardrails per service
- List all 14 write tools in security section
- Add write operation example prompts
- Update service tables with new tools
…istency

Review loop 1 fixes:

Security guardrails (neutron):
- Block all-ports-open rules (no port range + 0.0.0.0/0)
- Block ::/0 (IPv6 equivalent of world-open)
- Check if any dangerous port falls within specified port range
  (e.g., port_range_min=20, port_range_max=25 now caught for port 22)

Confirmation pattern consistency:
- nova_server_action: add confirmed parameter and RequireConfirmation
- octavia delete_loadbalancer: always fetch LB (verify state on both paths)
- swift delete_object: always fetch metadata (verify existence on both paths)

Null vs empty array:
- New pagination handlers use make([]map[string]any, 0) to return []
  instead of null when no results match filters
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 7, 2026

Merging this branch changes the coverage (6 decrease, 4 increase)

Impacted Packages Coverage Δ 🤖
github.com/notque/openstack-mcp-server/internal/server 0.00% (ø)
github.com/notque/openstack-mcp-server/internal/tools/cinder 9.50% (-0.60%) 👎
github.com/notque/openstack-mcp-server/internal/tools/designate 8.46% (-1.22%) 👎
github.com/notque/openstack-mcp-server/internal/tools/ironic 8.60% (-0.35%) 👎
github.com/notque/openstack-mcp-server/internal/tools/keystone 8.85% (-0.47%) 👎
github.com/notque/openstack-mcp-server/internal/tools/manila 9.52% (+0.15%) 👍
github.com/notque/openstack-mcp-server/internal/tools/neutron 8.13% (-0.69%) 👎
github.com/notque/openstack-mcp-server/internal/tools/nova 8.46% (-1.63%) 👎
github.com/notque/openstack-mcp-server/internal/tools/octavia 7.79% (+0.69%) 👍
github.com/notque/openstack-mcp-server/internal/tools/shared 74.24% (+4.60%) 👍
github.com/notque/openstack-mcp-server/internal/tools/swift 9.17% (+0.34%) 👍

Coverage by file

Changed files (no unit tests)

Changed File Coverage Δ Total Covered Missed 🤖
github.com/notque/openstack-mcp-server/internal/server/server.go 0.00% (ø) 58 0 58
github.com/notque/openstack-mcp-server/internal/tools/cinder/cinder.go 9.50% (-0.60%) 179 (+80) 17 (+7) 162 (+73) 👎
github.com/notque/openstack-mcp-server/internal/tools/designate/designate.go 8.46% (-1.22%) 130 (+68) 11 (+5) 119 (+63) 👎
github.com/notque/openstack-mcp-server/internal/tools/ironic/ironic.go 8.60% (-0.35%) 93 (+26) 8 (+2) 85 (+24) 👎
github.com/notque/openstack-mcp-server/internal/tools/keystone/keystone.go 8.85% (-0.47%) 192 (+74) 17 (+6) 175 (+68) 👎
github.com/notque/openstack-mcp-server/internal/tools/manila/manila.go 9.52% (+0.15%) 84 (+20) 8 (+2) 76 (+18) 👍
github.com/notque/openstack-mcp-server/internal/tools/neutron/neutron.go 8.13% (-0.69%) 209 (+73) 17 (+5) 192 (+68) 👎
github.com/notque/openstack-mcp-server/internal/tools/nova/nova.go 8.46% (-1.63%) 201 (+92) 17 (+6) 184 (+86) 👎
github.com/notque/openstack-mcp-server/internal/tools/octavia/octavia.go 7.79% (+0.69%) 244 (+75) 19 (+7) 225 (+68) 👍
github.com/notque/openstack-mcp-server/internal/tools/shared/helpers.go 63.64% (+10.70%) 88 (+20) 56 (+20) 32 🎉
github.com/notque/openstack-mcp-server/internal/tools/swift/swift.go 9.17% (+0.34%) 120 (+52) 11 (+5) 109 (+47) 👍

Please note that the "Total", "Covered", and "Missed" counts above refer to code statements instead of lines of code. The value in brackets refers to the test coverage of that file in the old version of the code.

Changed unit test files

  • github.com/notque/openstack-mcp-server/internal/server/server_test.go
  • github.com/notque/openstack-mcp-server/internal/tools/shared/helpers_test.go

@notque notque merged commit 8260925 into main May 7, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant