BlogIntegration
Designing MCP tools around business actions instead of endpoints
For an assistant that serves business users, expose a small set of tools that match the actions people actually ask for, not one tool per API endpoint. A tool such as find_orders can call three endpoints internally and return only what the model needs. A mirror of the whole API leaves the model to work out sequencing, filtering and permissions from documentation. There are exceptions, and they are covered below.
What goes wrong with one tool per endpoint
Servers generated from an API description are quick to build and hard for a model to use well. Anthropic's engineering write-up on tools for agents names the pattern: tools that merely wrap existing endpoints whether or not they suit an agent, and overlapping tools that distract it from efficient strategies. In practice the costs show up in three places.
- Context: list endpoints return everything, and the model reads every record to find one
- Sequencing: the model has to learn that an order lookup needs a customer ID from another call first, and sometimes gets it wrong
- Permissions: every exposed endpoint is something the model can call, including ones nobody meant it to use
Start from real requests, not from the API
Collect twenty to fifty real requests from the people who will use the assistant: tickets, chat messages, questions they ask colleagues. Group them by the business action behind them. Each action becomes a candidate tool, and for each one you write down who may use it, what it reads, what it changes and what a correct result looks like. Requests that fit no action are a reason to leave something out, not to add a generic tool that can do anything.
Worked example: a hypothetical order support API
Take an order service with fourteen endpoints for customers, orders, line items, shipments, tracking, returns, refunds and notes. The support team's requests fall into four actions, so the server offers four tools.
- find_orders: takes a customer email or order number and returns up to ten orders with status, total and latest shipment event
- get_order_details: one order with items, tracking and open returns, assembled from five endpoints
- prepare_return: checks eligibility under the returns policy and returns a proposal with a short-lived confirmation handle, changing nothing
- confirm_return: creates the return from that handle only if the server has recorded the user's approval of that exact proposal; a call without it, or for a changed proposal, is refused
Refunds, address changes and cancellations stay out of the first version. Each needs its own rules and an owner willing to sign off the tool.
What a tool definition should promise
In MCP, each tool declares a name, a description and an input schema, and optionally an output schema and annotations. Treat the definition as a contract that both the model and a reviewer can read. Constrain inputs with types, enums and patterns, and reject unexpected properties. If you declare an output schema, the specification requires the server to return structured results that conform to it.
{
"name": "find_orders",
"title": "Find orders",
"description": "Find a customer's recent orders by email address or order number. Returns at most 10 orders, newest first.",
"inputSchema": {
"type": "object",
"properties": {
"customer_email": { "type": "string", "format": "email" },
"order_number": { "type": "string", "pattern": "^SO-[0-9]{8}$" },
"status": { "type": "string", "enum": ["open", "shipped", "delivered", "returned"] }
},
"additionalProperties": false
},
"annotations": { "readOnlyHint": true, "openWorldHint": false }
}The annotations describe the tool to the client as read-only. They are hints that clients must not trust from unknown servers, so the server still enforces read-only behaviour and checks that at least one search field was supplied.
Errors and write steps the model can predict
MCP separates two kinds of failure. Protocol errors cover unknown tools and malformed requests. Tool execution errors, returned in the result with isError set to true, cover API failures, invalid values and business rule violations, and the specification asks clients to pass them to the model so it can correct course. Write those messages for the model: a message saying that order SO-12345678 was delivered 41 days ago and returns close after 30 days lets it explain the refusal, where HTTP 422 does not.
For changes, split preparation from confirmation as in the example, make the confirming call idempotent so a retry cannot create a second return, and bind each handle to the user who requested it. The current specification has no protocol sessions, so state that spans calls travels as an explicit handle, and the server must check the caller against it on every call.
When a thin API wrapper is the better choice
Business-action tools cost more to build and must change when the process changes. A thin wrapper can be right for a developer assistant exploring an internal API, a read-only reporting server over a well-designed query API, or a prototype you will discard. Overlap matters more than tool count: twenty clearly distinct tools can work better than eight that nearly duplicate each other.
Whichever shape you choose, measure it. Anthropic's write-up recommends evaluating tools on realistic tasks and reading the transcripts. A set of your collected requests with expected outcomes is enough to compare two designs before users see either.
Questions
How many tools should one MCP server expose?
There is no fixed number. Start with the actions that cover your collected requests and add tools when evaluation shows a gap. Overlapping tools tend to cause more trouble than the total count.
Do we need to rewrite our APIs first?
Usually not. The tool composes existing endpoints inside the server. An API change is worth it when an action needs a check or a transaction the API cannot express, such as creating a return only if it is still eligible.
Should tool descriptions contain rules for the model?
Describe what the tool does, its limits and when to use it, as you would for a new colleague. Rules that must hold, such as who may confirm a return, belong in server code, because a model may not follow a description.
Related services
MCP server development
MCP servers that connect approved internal APIs to AI assistants, with narrow permissions, approval for changes and tests.
AI engineering and architecture
Assistants, voice interfaces and agents in the products you sell, with the serving and retrieval underneath.
AI agents and process automation
Agents that take on the routine steps of complex cases and pass decisions to people, with a cost per handled case.
More from the blog
MCP server permissions
How to connect an assistant to internal systems without giving every MCP tool broad access: scopes, checks inside each tool and separate downstream identities.
MCP server test plan
A test plan for an MCP server before users connect: contract tests, negative authorisation tests, failure tests and state-change tests, with checks that run in CI.
Prompt injection boundaries
How to limit the damage when an agent follows instructions hidden in a document, email or tool result: map untrusted inputs to actions, cut the paths and test the boundaries.
Talk to an engineer
Bring one piece of work you would like to improve. The call takes 30 minutes and needs no access to your systems or your data.
Booking runs on Google Calendar.
Prefer to write first? Leave your email and a few lines, and we reply with times.
Look for the draft in your email program
Send it from there, and an engineer replies in person with times for a 30-minute call. If no draft has opened, write to us at miki@cloudsail.com.