Motivation
A production MCP server with many tools (e.g. mcp-erpnext has 120+) floods the LLM context window. The model gets confused, picks wrong tools, or ignores relevant ones. We need a way to show only what's relevant and reveal more tools as the session context evolves.
Proposal
Add a visibility system that allows hiding/showing tools by tag, and per-session state to toggle visibility dynamically.
Registration with tags
server.registerTool(
{
name: "delete_all_records",
description: "Nuclear option",
tags: ["admin", "dangerous"],
visible: false, // hidden by default
inputSchema: { ... },
},
handler,
);
Visibility middleware
// Hide all admin tools by default
server.disable({ tags: ["admin"] });
// A gatekeeper tool that unlocks admin tools for the current session
server.registerTool(
{
name: "unlock_admin",
description: "Unlock admin tools (requires authentication)",
requiredScopes: ["admin:write"],
inputSchema: {},
},
async (args, ctx) => {
ctx.session.enable({ tags: ["admin"] });
// Next tools/list call for this session will include admin tools
return "Admin tools unlocked.";
},
);
How it works
tools/list filters results based on session visibility state
- Tools hidden by default don't appear until explicitly enabled
- Visibility is per-session — one client unlocking admin doesn't affect others
- Works with the existing middleware pipeline (auth check → scope check → visibility check)
Use cases
- Multi-tenant SaaS: free tier sees 10 tools, paid tier sees 50
- Progressive onboarding: start with basics, reveal advanced tools as the agent demonstrates competence
- Security layers: admin/destructive tools hidden until authenticated
- Context optimization: reduce token usage by only exposing relevant tool subset
Prior art
- FastMCP 3.0 visibility system (
disable(tags=...) + ctx.enable_components())
- Feature flags / progressive rollout patterns
Scope
Motivation
A production MCP server with many tools (e.g. mcp-erpnext has 120+) floods the LLM context window. The model gets confused, picks wrong tools, or ignores relevant ones. We need a way to show only what's relevant and reveal more tools as the session context evolves.
Proposal
Add a visibility system that allows hiding/showing tools by tag, and per-session state to toggle visibility dynamically.
Registration with tags
Visibility middleware
How it works
tools/listfilters results based on session visibility stateUse cases
Prior art
disable(tags=...)+ctx.enable_components())Scope
tagsandvisiblefields on tool/resource registrationVisibilityFiltermiddleware with per-session stateenable()/disable()methods on session contexttools/listrespects visibility state