MCP Server Too Many Tools: Keeping Agent Context Small
An MCP server with too many tools fills the agent's context with schemas before any work starts, and gives the model more ways to pick the wrong one. The fix is to expose fewer, more general tools: a search tool over the catalogue, a lookup tool for one item's parameters, and one call tool. That's how Perceptlayer puts 1,659 endpoints behind three tools. The checklist below covers the rest: scoping, naming, trimming responses and capping calls.
Why do too many MCP tools hurt an agent?
Every tool a client loads is sent to the model as a name, a description and a JSON Schema, on every request, whether the task needs it or not. Anthropic's engineering team measured a five-server setup at "58 tools consuming approximately 55K tokens before the conversation even starts" (Anthropic, 2025). That is context you pay for and can't use for the task. Size isn't the only cost. The same post names "wrong tool selection and incorrect parameters" as the most common failures, especially when tools have similar names. When it let the model search for tools rather than load them all, accuracy in its evaluations rose from 49% to 74% for Opus 4. So a long tool list costs tokens and makes the agent worse at choosing.
The MCP specification doesn't cap the number of tools. tools/list supports pagination with a cursor (MCP specification, 2025), so a server can list thousands. Whether it should is a design question, and for agents the answer is usually no.
How big would one tool per endpoint be?
For a large catalogue, one tool per endpoint is far bigger than any context window you'd want to spend on schemas. We generated a tool for each of the 1,659 live endpoints in our catalogue: the endpoint ID as the name, a one-line description, and an input schema built from that endpoint's parameters (7,210 parameters in all, with their types, allowed values and length limits). Serialised as a tool list, that is about 567,000 characters of JSON. The three tools our server actually lists come to about 3,200 characters.
| Tool list | Tools | Size as JSON |
|---|---|---|
| One tool per endpoint, whole catalogue | 1,659 | about 567,000 characters |
| One tool per endpoint, Google Search only | 7 | about 5,100 characters |
| Search, inspect, call | 3 | about 3,200 characters |
Token counts depend on the model's tokenizer, so we report characters. The point holds either way. Even seven Google Search endpoint tools are bigger than the three general tools, and the three general tools reach every endpoint. You can read the real list yourself. The server answers tools/list without an API key:
curl -s https://api.perceptlayer.com/mcp \
-H "Content-Type: application/json" \
-H "MCP-Protocol-Version: 2025-06-18" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | wc -c
The checklist
Work through these in order. The first three shrink what the model sees on every turn, and the rest keep each call small and bounded.
- Count what the client loads. List every connected server and every tool it exposes, then remove servers the agent doesn't use for this job. Each one adds its schemas to every request.
- Replace per-item tools with search, inspect, call. If tools differ only by which item they hit (one per site, per table, per endpoint), merge them. Offer a search tool that returns compact matches, a lookup tool that returns one item's parameters, and a single call tool that takes an ID and parameters.
- Make discovery free and cheap. Lookups should spend nothing and return little.
search_endpointsreturns the endpoint ID, name, method, credits per call, tier and required parameters for each match, 10 matches by default and at most 50. The full parameter list waits forget_endpoint. - Name tools by action, not by system.
search_endpoints,get_endpointandcall_endpointsay what each does. Avoid near-duplicates such asget_dataandfetch_data. Similar names are where wrong picks happen. - Put the usage order in the descriptions. Say when to call each tool. Our
get_endpointdescription says to call it "before call_endpoint unless you already know the parameters". The server's instructions spell out the same order. - Keep schemas strict. Mark required parameters, use
enumfor fixed values and setadditionalProperties: falseon the tool's own arguments. A tight schema takes fewer tokens to describe than prose and catches bad arguments before a call. - Bound the response. Ask for less data with an endpoint's paging or limit parameters, and filter fields before the model sees them.
call_endpointtruncates anything over 100,000 characters and says so. Trim API Responses for LLM Context shows field filtering in Python. - Return errors the model can act on. A failed call should name a code and the next step.
call_endpointreturns codes such asinvalid_parameters(fix and retry),rate_limited(wait and retry) andinsufficient_credits, and failed calls cost nothing. The errors docs list every code. - Cap calls per task. Set a maximum number of
call_endpointcalls per run in the agent loop, and pace them under the account's rate limit. MCP Server Rate Limiting covers the pacing. AI Agent API Cost Control covers the spend. - Turn tools off per conversation. Clients let you switch connectors off for a chat, and Claude also lets you set an individual tool to Blocked (Claude, 2026). Leave on only what the task needs.
What does search, inspect, call look like in practice?
The agent spends two free lookups before one paid call, and only the call's response is large. Say the task is "find the top Google results for a query". The agent calls search_endpoints with {"query": "google search"} and gets back a short list of matches, each with an ID such as google-search.search, its credits per call and its required parameters. If the match is obvious it can skip straight to the call. Otherwise it calls get_endpoint with {"endpoint": "google-search.search"} to read the full parameter list. That shows query is required and hl, gl and page are among the optional ones.
Then it calls call_endpoint:
{
"endpoint": "google-search.search",
"params": { "query": "best restaurants in Berlin", "hl": "en" }
}
The result is the endpoint's JSON, followed by a line such as Credits used: 1. Credits remaining: …. The agent never loaded a schema for any other endpoint in the catalogue, and it can reach any of them the same way. The AI agents (MCP) docs have the connection details for each client.
When should you keep dedicated tools instead?
Keep a dedicated tool when an agent calls one endpoint constantly and nothing else. A support agent that only ever looks up an order, or a price tracker that only hits one shopping endpoint, gains little from a search step. One named tool with a tight schema is simpler and saves a round trip. MCP vs Function Calling for Live Web Data walks through that trade-off, and LLM Tool Schema Design covers writing that one schema well.
The rule of thumb: dedicated tools for the two or three calls an agent makes every run, search, inspect, call for everything else. If you want to try the general pattern, get a free API key, add the server, and ask your agent for data from a site you haven't wired up.
Frequently asked questions
How many tools is too many for an MCP server?
There is no fixed number, because the cost depends on how long each schema is and how similar the tools are. Anthropic's example of 58 tools took about 55K tokens before any conversation, and similar tool names were a common cause of wrong picks. If the tool list costs more context than the task, or tools differ only by the item they hit, merge them behind a search tool.
Do search_endpoints and get_endpoint cost credits?
No. Both only read the catalogue, need no API key and cost nothing. Only call_endpoint spends credits: the endpoint's cost, 1 credit for nearly all of them, and only when the call succeeds. A failed call returns an error code and debits nothing. See the credits docs for how balances work.
Does a search step make the agent slower?
It adds one or two short tool calls before the paid one, so a task takes an extra round trip or two. In return, the model reads a few compact matches instead of thousands of schemas on every turn. An agent that already knows the endpoint ID can call call_endpoint directly and skip the lookups.
What happens if a response is too large for the context?
call_endpoint returns at most 100,000 characters and adds a note with the full length when it truncates. Ask for less with the endpoint's paging or limit parameters, or call the HTTP API directly and filter the fields in your own code before passing them to the model.
Can I limit which tools Claude uses from a connector?
Yes. Claude lets you turn each connector on or off for a conversation from the + menu, and block individual tools under Customize > Connectors. With Perceptlayer's server you might block call_endpoint for a research-only chat, so the agent can browse the catalogue but can't spend credits.