Skip to content

Search mode: explain tools hidden by expose: except on a running server - #356

Merged
Minitour merged 1 commit into
developfrom
fix/expose-reason-live-tools
Oct 23, 2026
Merged

Minitour merged 1 commit into
developfrom
fix/expose-reason-live-tools

Conversation

@Minitour

Copy link
Copy Markdown
Member

Summary

Found while verifying the v2.4.0 release (#351) locally. In search mode, a tool hidden by expose: except should be explained (#323, #352), but against a running server the explanation never appeared. The agent got the plain "not in this project's capa tool catalog" message instead.

What changed

  • serverIdsWithDeclaredTools (server-tool-exposure.ts) counted the tools capa synthesizes from a server's expose policy as if they were authored tools: entries. The running server's capabilities carry those synthesized tools, so every server with a policy looked hand-curated and exposurePolicyReason skipped it. Synthesized tools (fromServerExpose) no longer count.
  • The other callers already passed authored capabilities only (synthesizedToolsAllowedByPolicy filters them out itself, and configure expands the file's capabilities), so their behavior is unchanged.

Screenshots / logs

Release build, servers.billing with expose: except and tools: [delete_invoice], call_tool with delete_invoice:

Before:

Tool not found: "delete_invoice" is not in this project's capa tool catalog. Closest names: billing.lookup_invoice. ...

After:

Tool "delete_invoice" is not exposed by this project: servers.billing lists it under "expose: except". ...

Test plan

  • New test: exposurePolicyReason with a synthesized tool for the same server, as the running server holds it. It fails without the fix.
  • Re-ran the release build check against a real stdio MCP server: call_tool and search both explain the except policy.
  • bunx tsc --noEmit; shared, server and CLI suites have no assertion failures (only the known Windows EBUSY/EPERM temp cleanup).

Checklist

  • Tests added or updated
  • bunx tsc --noEmit passes
  • Docs updated (if user-facing): not needed

🤖 Generated with Claude Code

The running server's capabilities carry the tools synthesized from each
server's expose policy, so serverIdsWithDeclaredTools treated every policy
server as hand-curated and exposurePolicyReason never explained a tool
hidden by expose: except.
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Explain expose: except for tools hidden on a running server

🐞 Bug fix 🧪 Tests 🕐 Less than 10 minutes

Grey Divider

AI Description

• Exclude synthesized tools when deciding whether authored tools override a server’s exposure
 policy.
• Restore policy-specific explanations for hidden tools in search mode and call_tool.
• Add a regression test using capabilities shaped like those held by a running server.
Diagram

graph TD
  A["Running capabilities"] --> B["Search and call_tool"] --> C["Exposure reason"] --> D["Authored server IDs"] --> E{"Server curated?"} -->|no| F["Except explanation"]
  E -->|yes| G["Catalog message"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Filter capabilities at the diagnostic call site
  • ➕ Limits the change to missing-tool diagnostics.
  • ➖ Duplicates the authored-tool rule and leaves the shared helper’s meaning dependent on its caller.

Recommendation: Keep the shared-helper fix. Its contract is to identify servers with authored tools, so excluding synthesized tools there preserves that distinction for every caller without changing the rule that genuinely curated servers override expose policies.

Files changed (2) +18 / -2

Bug fix (1) +6 / -2
server-tool-exposure.tsExclude synthesized tools from authored server detection +6/-2

Exclude synthesized tools from authored server detection

• The server-ID helper now ignores MCP tools marked fromServerExpose. Running-server capabilities can retain synthesized tools without incorrectly disabling their server’s exposure policy.

src/shared/server-tool-exposure.ts

Tests (1) +12 / -0
mcp-handler.integration.test.tsCover except-policy diagnosis with synthesized server tools +12/-0

Cover except-policy diagnosis with synthesized server tools

• Adds a regression case where a running server holds a synthesized allowed tool alongside an except policy. It verifies that exposurePolicyReason still identifies the excluded tool as hidden by that policy.

src/server/tests/mcp-handler.integration.test.ts

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider

Great, no issues found!

Qodo reviewed your code and found no material issues that require review

Grey Divider

Tip of the day
💡 Did you know, you can reply 'qodo' on any finding to push back, ask questions, or dig deeper

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

@Minitour
Minitour merged commit 6b99712 into develop Oct 23, 2026
8 checks passed
@Minitour Minitour mentioned this pull request Oct 23, 2026
8 of 9 tasks
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