API StudioSDK StudioMonitoringMCP ServerSpec AuditFeatures
ComparePricingBlogDocs
Log inStart for free
API StudioSDK StudioMonitoringMCP ServerSpec AuditFeatures
ComparePricingBlogDocs
Log inStart for free
API StudioSDK StudioMonitoringMCP ServerSpec AuditFeatures
ComparePricingBlogDocs
Log inStart for free
Blog/Engineering
Engineering·September 6, 2026·5 min read

How many tools should an MCP server expose?

Exposing your whole API to an agent makes it worse, not more capable. Tool choice is a selection problem, and every extra option makes the selection harder.

#mcp#ai-agents#api-design#developer-experience
How many tools should an MCP server expose?

The instinct when generating an MCP server from an OpenAPI document is to expose everything. You have 300 endpoints, the generator can emit 300 tools, and more capability sounds like more value.

It is the opposite, and the reason is worth understanding because it is not a limitation anyone is going to engineer away soon.

Tool choice is a selection problem

Every tool you expose is an option a model has to consider on every step. The tool list goes into context, competes for attention with the actual task, and gets re-evaluated each time the agent decides what to do next.

Three things degrade as that list grows.

Selection accuracy. With eight tools, picking the right one is easy. With two hundred, many of which are near-duplicates that differ in one parameter, the model is doing disambiguation rather than work. listUsers, listUsersByOrg, listActiveUsers and searchUsers are four plausible answers to one question, and the model has only the names and descriptions to go on.

Context budget. Tool definitions are not free. Each carries a name, a description and a parameter schema. Several hundred of those is a meaningful fraction of a context window spent before any work happens, and it is spent again on every turn.

Blast radius. More tools means more surface an agent can reach when it reasons its way somewhere unexpected. This is the safety argument, and it is real, but the accuracy argument bites first and bites everyone.

The rule of thumb, and its edges

The pattern the ecosystem has landed on in 2026 is roughly this: under about twenty endpoints, all of them relevant to what an agent would do, pure auto-generation is fine. Above that, generate and then curate.

That number is a proxy for something more useful. The real question is not how many endpoints you have. It is how many distinct things an agent might reasonably want to do.

An API with eighty endpoints where sixty are CRUD variations on the same eight resources probably has around a dozen agent-relevant operations. An API with fifteen endpoints that each do something genuinely different might want all fifteen.

Count intentions, not routes.

How to pick the subset

Start from what you would want an agent to accomplish, not from your endpoint list. Write down the three or four jobs someone would ask an assistant to do with your API. Then work backwards to the operations those jobs need.

What usually survives:

Reads that answer questions. Get one thing by id, list a collection with a filter, search. These are the tools an agent uses constantly and they are safe.

The one or two creates that represent your product's core action. Creating an invoice, opening a ticket, starting a job. The thing people integrate your API to do.

Anything an agent needs to check its own work. If a create returns an id, the read that resolves that id belongs in the set.

What usually should not:

CRUD completeness for its own sake. You do not need update, partialUpdate and replace as three tools. Pick the one a caller should use.

Every filter variant as its own operation. If listUsers takes a status parameter, you do not also need listActiveUsers. Parameters are cheaper than tools, because a parameter is a field the model fills in rather than a decision it has to make first.

Administrative and internal operations. Same list you excluded from your public SDK.

Anything irreversible. Deletes, refunds, anything that sends a message to a human. Not because an agent is careless but because the failure is unrecoverable and the value of automating it is close to zero.

Names and descriptions do more work than the count

Once the set is chosen, the text matters more than people expect. A tool description is not documentation. It is a decision aid read by a model choosing between options, and it should answer one question: when should I use this instead of the others?

code
1234
Bad:  "Lists users."
Good: "Lists users in an organisation, newest first. Use when you need
       several users or do not know a specific id. To fetch one known
       user, use get_user instead."

That cross-reference is the part almost nobody writes, and it is the part that fixes the most selection errors. If two tools are frequently confused, saying so inside both descriptions is more effective than renaming either.

Names carry the same weight. A model reads create_invoice as an action. It reads postV1InvoicesCreate as a string it has to parse a transport detail out of. If your tool names come from operationIds that were written for a code generator, they are probably wrong for this audience.

Curation is not a one-time task

The set that is right at launch is not right six months later, because you will learn which tools agents actually reach for and which ones they never touch or always misuse.

Log the tool calls. The distribution is usually lopsided: a handful of tools carry nearly all the traffic and a long tail is never selected. That tail is costing you context on every turn and buying nothing, and removing it typically improves accuracy on the tools that matter.

Look also for the tools that get called and then immediately followed by a correction. That is a naming or description problem, not a capability problem.

Where the configuration should live

The practical version of all this is that curation should not be a separate artifact you maintain by hand, because a hand-maintained list drifts from the API it describes.

The version that holds up is one where the tool set derives from configuration you already keep: the endpoints you excluded from your public SDK stay excluded from the tools, the method names you overrode carry through, and a deprecated operation is surfaced as deprecated. One decision applied in both places, rather than an agent permissions system to keep in sync with a client library.

That is how Octri builds it: the MCP server is a projection of the same SDK configuration, so the curation you did once is the curation the agent gets. Generating an MCP server from an OpenAPI spec covers the setup, and what to exclude first covers the safety half of the same decision.

Start narrow. It is much easier to add a tool that people ask for than to work out which of your two hundred is the one confusing the model.

← PreviousGiving an agent write access to your API: what to exclude first
Next →Your MCP server needs documentation, and it is not your API docs

Related articles

What counts as a breaking change when your SDK is generated
Engineering·5 min read

What counts as a breaking change when your SDK is generated

A one-line spec edit can break every call site your users wrote. Here is the table of what is additive, what is breaking, and which ones your spec diff will not warn you about.

September 11, 2026
Your operationIds are your public method names, and unique is not enough
Engineering·5 min read

Your operationIds are your public method names, and unique is not enough

An operationId is not documentation metadata. It is the name your users type. Here is why uniqueness does not save you, and what actually collides.

September 9, 2026
Should you hand-write your SDKs or generate them?
Engineering·5 min read

Should you hand-write your SDKs or generate them?

The honest answer depends on how many languages you ship and how often your API changes. For one language and a stable API, hand-writing wins.

September 9, 2026
41% of APIs drift within 30 days, and most of it is invisible
Engineering·5 min read

41% of APIs drift within 30 days, and most of it is invisible

Schema drift is not usually a breaking change. It is a field nobody told you about, found by a test that failed in CI two weeks later.

September 7, 2026

A letter when something ships

New SDK languages, changes in the generator, and now and then a longer piece on keeping docs from rotting. Roughly one a month.

Join developers keeping tabs on Octri.

Octri

Upload an OpenAPI spec. Get complete docs and production-ready SDKs in 10 languages, live in minutes.

Contact support

Product

  • API Studio
  • SDK Studio
  • Monitoring
  • MCP Server
  • Pricing
  • Compare
  • Blog
  • Changelog
  • Press Kit

From your spec

  • Spec Audit
  • TypeScript SDK
  • Python SDK
  • Go SDK
  • Java SDK
  • MCP Server

Developers

  • Documentation
  • API Reference
  • SDK Libraries
  • MCP Server
  • Monitoring
  • CLI
  • Support

Legal

  • Terms of Service
  • Privacy Policy
  • Fair Use Policy
  • Data Processing (DPA)
  • Cookie Policy
  • Security
  • Subprocessors

© 2026 Octri, LLC. All rights reserved.

Made by devs who got tired of hand-writing SDKs.