Switched-off tools still appear in context via mcp list/connect/description
Maintainers usually reply within 1 day
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 57/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- typescript
- Domain
- ai-infra-agents, backend
Research direction
Start with core/server/src/pi/guard.ts and core/server/src/mcp-offer.ts, tracing how the switch set from offFor() or toolDefaultsForSession() reaches list, connect, search, and prompt-description paths. Check the existing coverage for those paths and for mcp_script; done means off tool names and descriptions never reach model context, fully switched-off servers are not offered for connection, and codemode still blocks them.
Written by the indexing model from the issue text.
Description
What happens now
When a tool (including any MCP server's tools) is switched off for a chat, the calls are refused — switchedOffVia() in core/server/src/pi/guard.ts blocks mcp({tool:...}), describe, direct calls and the tools gateway. But the tool still appears in the model's context:
mcp({ server: "name" })lists every cached tool of the server, off ones included, with descriptions.mcp({ connect: "name" })connects a switched-off server and hands back its full tool list.- The bare
mcp({})status call reports "N tools (cached)" per server. - The
mcpmeta-tool's description lists the servers and their direct tools regardless of switches ("Direct tools available (call as normal tools): understory (5), nextcloud_uni (27)"). - A switched-off MCP tool therefore can be listed, its parameters learned via
describe, and a "refused: switched off" result is all that stands between the model and it — the refusal even tells the model the exact name it could try elsewhere.
The current split is deliberate (see the doc comment above switchedOffVia(): "a search or a list ... hands back what every server says"), but for the common case — "this tool does not exist in this chat" — off should mean gone, not visible-but-refused.
Expected behavior
If a tool is switched off for a chat, it should not surface at all:
mcp({ server: "name" })lists only the tools that are on (or reports the server as off when none of its tools are).mcp({ connect: "name" })either refuses to connect a fully-off server or connects without advertising its off tools.- The
mcptool's prompt description ("servers", "N tools", "Direct tools available") is built from what is actually offered in this conversation, not from the adapter cache. describekeeps refusing (already does).
The switches are known to the portal already (offFor() / toolDefaultsForSession() / switchedOffVia() in guard.ts, catalogue via mcpCatalogue() in core/server/src/mcp-offer.ts), so filtering the list/connect/description paths is a question of applying the same off set that call-refusal already uses.
Reproduction
- Configure an MCP server (e.g.
nextcloud_uni, 27 tools) with tools reachable through themcpgateway. - Switch all its tools off in Settings → Tools (or per chat/project).
- In a chat where they are off:
mcp({ server: "nextcloud_uni" })→ lists all 27 with descriptions;mcp({ connect: "nextcloud_uni" })→ connects and re-lists them. - Any actual call is refused: "Refused: 'nextcloud_uni_read_nc_get_capabilities' is switched off in this conversation, and the mcp tool does not reach it either."
So: unusable, but fully present in context.
Acceptance criteria
- No switched-off tool name or description reaches the model's prompt (system prompt,
mcptool description, list/connect/search results) in a chat where it is off. - A server whose tools are all off is not offered for connect by default.
- Codemode scripts (
mcp_script) already cannot reach switched-off tools — keep that true.
- Dominant language
- TypeScript
- Stars
- 297
- Forks
- 81
- Avg merge
- 8h 47m
- Merged PRs (30d)
- 167
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from thecodacus/pithagoras
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
thecodacus/pithagoras#364 ·
Maintainers usually reply within 1 day
-
documentation
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
thecodacus/pithagoras#306 ·
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
thecodacus/pithagoras#43 · 2 comments ·
Maintainers usually reply within 1 day
-
enhancement
Difficulty 5/5 Over a week Newbie friendliness 6/100
thecodacus/pithagoras#361 · 1 comment ·
Maintainers usually reply within 1 day
-
enhancement
Difficulty 5/5 Over a week Newbie friendliness 32/100
thecodacus/pithagoras#347 ·
Maintainers usually reply within 1 day
All issues in thecodacus/pithagoras
Similar issues
-
Billion-context documentation addendum: nudge is independent of window occupancy. | billion-context 文档补充:nudge 与窗口占用无关Possibly taken A pull request linked to this issue is open or already merged. Open
Difficulty 1/5 1-3 hours Newbie friendliness 86/100
ranxianglei/billion-context#5893 ·
Maintainers usually reply within 1 day
-
stringify escapes leading digits in pseudo-class arguments (:nth-child(1) becomes :nth-child(\31 ))Open
Difficulty 2/5 1-3 hours Newbie friendliness 83/100
Maintainers usually reply within 1 day
-
enhancement security severity:low
Difficulty 2/5 1-3 hours Newbie friendliness 83/100
Battle-Cattle/BCUK-Bot-4#959 ·
Maintainers usually reply within 1 day
-
[Bug]: Claude account rows no longer show the email (since #8055), so "Account 1, 2, 3" cannot be told apartPossibly taken A pull request linked to this issue is open or already merged. Openaccount-pool bug gui
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
lidge-jun/opencodex#8286 · 2 comments · 1 reaction ·
Maintainers usually reply within 1 day
-
Difficulty 1/5 Under an hour Newbie friendliness 72/100
Maintainers usually reply within 1 day