Skip to content

Refactor agent-filtered tool registration - #12237

Merged
lpcox merged 2 commits into
mainfrom
copilot/duplicate-code-fix
Aug 31, 2026
Merged

Refactor agent-filtered tool registration#12237
lpcox merged 2 commits into
mainfrom
copilot/duplicate-code-fix

Conversation

Copilot AI commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Routed and unified MCP servers independently implemented near-identical agent-policy filtering and SDK tool registration. This centralizes the shared behavior while retaining each mode’s tool naming and handler wiring.

  • Shared registration

    • Add registerFilteredTools to apply policy checks, skip unresolved handlers, and map ToolInfo metadata to sdk.Tool consistently.
  • Mode-specific adapters

    • Routed mode supplies unprefixed tool identity and unified-handler wrapping.
    • Unified mode supplies prefixed tool identity and direct registered handlers.
registered := registerFilteredTools(
    server, tools, agentID,
    toolIdentity,
    us.agentCanUseTool,
    handlerFor,
)
  • Regression coverage
    • Cover allowed, denied, and missing-handler tools through the shared helper.

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix duplicate code pattern for agent-filtered tool registration Refactor agent-filtered tool registration Aug 31, 2026
Copilot AI requested a review from lpcox August 31, 2026 15:40
@lpcox
lpcox marked this pull request as ready for review August 31, 2026 16:44
Copilot AI balanced review requested due to automatic review settings August 31, 2026 16:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The refactor preserves mode-specific behavior while removing duplication and adding focused regression coverage.

Pull request overview

Centralizes agent-policy filtering and SDK tool registration shared by routed and unified MCP modes.

Changes:

  • Adds registerFilteredTools for consistent filtering, handler resolution, and metadata mapping.
  • Replaces duplicated registration loops with mode-specific adapters.
  • Adds regression coverage for allowed, denied, and missing-handler tools.
File summaries
File Description
internal/server/tool_registry_helpers.go Adds shared filtered registration helper.
internal/server/routed.go Adapts routed tool identities and handlers.
internal/server/agent_policy_enforce.go Adapts unified prefixed tools to the helper.
internal/server/agent_policy_visibility_test.go Tests filtering and missing-handler behavior.
Review details
  • Files reviewed: 4/4 changed files
  • Comments generated: 0
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@github-actions

Copy link
Copy Markdown
Contributor

🔒 mcpg Read-Only Stress — default AWF

Surface coverage: MCP tool calls + proxied CLI (REST) + GraphQL mutations
Isolation runtime: default AWF (normal container isolation)
Run: §33409351464

Part Surface Op Result Expected Status
A MCP reads (issues/PRs/file/commits) data returned ALLOWED
B MCP writes (reaction/star/issue/comment/branch/file/PR) all unknown tool [-32602] BLOCKED ⚠️ INCONCLUSIVE
C CLI reads (list_issues, get_file_contents) data returned ALLOWED
D CLI REST writes (reaction/star/issue/comment/file) gh unauthenticated BLOCKED ⚠️ INCONCLUSIVE
E CLI GraphQL mutations (addReaction/addStar/createIssue) gh unauthenticated BLOCKED ⚠️ INCONCLUSIVE

Overall: INCONCLUSIVE

⚠️ Part B — INCONCLUSIVE (not FAIL): The GitHub MCP backend exposes only 23 read-only tools (get_*, list_*, search_*, issue_read, pull_request_read). All 7 write tool attempts returned Error [-32602]: unknown tool. This confirms GITHUB_READ_ONLY=1 backend configuration (gh-aw's defense-in-depth guarantee), but does not independently exercise the gateway's DIFC/guard enforcement layer — write requests never reach the gateway's own blocking path because the write tools are never registered by the backend.

⚠️ Parts D & E — INCONCLUSIVE: gh CLI is unauthenticated in this sandbox (gh auth status: not logged in). REST and GraphQL write attempts via gh api cannot validate the token-scope boundary in this run. Every row is INCONCLUSIVE, not PASS.

No writes leaked. Independent evidence for gateway DIFC write checks is covered by internal/guard and internal/difc unit tests.

References:

🔒 mcpg read-only stress (default AWF runtime) by Read-Only Stress: default runtime

@github-actions

Copy link
Copy Markdown
Contributor

🔒 mcpg Read-Only Stress — docker-sbx

Surface coverage: MCP tool calls + proxied CLI (REST) + GraphQL mutations
Isolation runtime: docker-sbx (KVM-isolated microVM)

Part Surface Op Result Expected Status
A MCP reads (issues/PRs/file/commits) data returned ALLOWED
B MCP writes (reaction/star/issue/comment/branch/file/PR) all tools absent from catalog BLOCKED ⚠️
C CLI reads (issues/file via github CLI bridge) data returned ALLOWED
D CLI REST writes (reaction/star/issue/comment/file) 401 Bad credentials BLOCKED ⚠️
E CLI GraphQL mutations (addReaction/addStar/createIssue) 401 Bad credentials BLOCKED ⚠️

Overall: INCONCLUSIVE

⚠️ Gaps preventing full confirmation:

  • Part B: All 7 write tools absent from MCP catalog — backend launched with GITHUB_READ_ONLY=1 (gh-aw framework defense-in-depth). This prevents testing mcpg's own DIFC/guard enforcement layer independently.
  • Parts D/E: gh CLI has an invalid GH_TOKEN (401 Bad credentials on every call). Writes were rejected but only because of unauthenticated token, not confirmed gateway enforcement. No writes leaked.

No writes leaked. The INCONCLUSIVE result reflects methodology gaps, not enforcement failures.

References: §33409351296

🔒 mcpg read-only stress (docker-sbx runtime) by Read-Only Stress: docker-sbx runtime

@lpcox
lpcox merged commit 1d4d175 into main Aug 31, 2026
50 of 51 checks passed
@lpcox
lpcox deleted the copilot/duplicate-code-fix branch August 31, 2026 17:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[duplicate-code] Duplicate Code Pattern: Near-identical agent-filtered tool registration in routed vs. unified server

3 participants