Interaction & Data Flow
An MCP tool's description is multi-thousand-token boilerplate — every tool listing burns LLM context, can crowd out other tools, and dilutes the model's ability to choose the right tool. Tool-listing variant of the unbounded-cost family; compute/memory is MCP-110, paid-LLM API is MCP-084, MCP sampling is MCP-211.
MCP clients send `tools/list` results into the model's context. A 5,000-token tool description gets paid for on every model call, even when that tool isn't selected. Worse, when many tools have bloated descriptions, the model's selection signal degrades — it can't tell which tool fits because they all use the same vocabulary at length.
Tool description is the only documentation the model sees. There's a temptation to put everything there: examples, edge cases, gotchas, link to docs. Resist. Describe the tool in 1-2 sentences and put the rest in the `inputSchema` description fields and external docs. The token budget is real money.
@server.tool(description=""" |
This tool sends an email to a user. It supports the following features: |
- HTML and plain-text bodies |
- CC and BCC recipients |
- File attachments up to 10MB |
- Multiple recipients (up to 50) |
- Custom Reply-To |
- Tracking pixels (opt-in) |
- ... [hundreds more lines of description] ... |
""") |
def send_email(to: str, subject: str, body: str) -> str: |
... |
@server.tool(description="Send a transactional email. See readme.md for advanced features.") |
def send_email( |
to: str, |
subject: str, |
body: str, |
cc: list[str] = [], |
attachments: list[Attachment] = [], |
) -> str: |
... |
MCPSafe flags tool registrations where the `description` argument exceeds a token-budget cap (default 200 tokens, configurable). Long descriptions can either be migrated into `inputSchema` field-level descriptions or external readme links.
See the full threat catalog for every documented detection.
MCPSafe runs this check — and every other rule in the catalog — on any MCP server you paste in.
Scan now