A Practical Checklist for MCP Tool Contracts (Because the Connection Is the Easy Part)
A universal socket is useful, but an agent still needs a legible contract for what each tool does, when it is safe to call, and how to prove the effect.
Picture two tools on a model's menu. One is called lookup. The other is called send. Both are valid under the protocol, and both connect cleanly. Neither one tells the model whether lookup can quietly pull a customer's full email history, or whether send drafts a message for review versus firing it to an external inbox the instant it is called.
The connection succeeded, but the decision surface failed. MCP gives that surface a standard shape, but it does not make the decision legible by itself. If you build agent tools, that gap is where your work actually starts, and this piece is meant to be run as a checklist against your own surfaces.
What the connection gets you for free
Give the protocol its due. When Anthropic introduced MCP in late 2024, the stated purpose was to replace one-off, custom connectors with a single open standard for wiring AI systems to tools and data. That was a real problem, and MCP is a real answer to it. Instead of rebuilding integration plumbing for every model and every data source, you get a common boundary.
The current tools specification makes that boundary concrete. Tools are model-controlled, and each one is represented with metadata: a name, a description, an input schema, an optional output schema, and optional behavior annotations. Discovery, invocation, and the shape of the exchange are standardized. That is genuine leverage.
But notice what standardization does and does not buy you. With a conforming application, a tool can be discovered and called through a standard interface. It does not guarantee that the tool can be understood, chosen correctly, or safely invoked. Transport compatibility is not semantic clarity, and it is not host policy. The same specification is careful about this line. It recommends that a human remain able to deny tool invocations, and it warns that behavior annotations must be treated as untrusted unless they come from a server you already trust. In other words, the protocol itself tells you that its metadata is a starting point, not a safety guarantee. Everything below is the part you have to build.
The contract, part by part
When people say a tool is "wired up," they usually mean the call works. The more useful question is whether the tool exposes a legible contract. Treat that contract as one mechanism with several moving parts, not a checklist to pad out a config file.
Caption: An MCP socket carries the request. Tool meaning, host permission, and proof of effect are designed downstream.
An intent-revealing name lets the model separate this tool from its nearest look-alike before it reads anything else. A bounded description states what the tool does and, critically, what it does not do. A constrained input schema can make invalid or underspecified calls harder to express, reducing the room for a dangerous or ambiguous argument. A structured output gives the caller evidence of what actually happened, rather than a friendly sentence that sounds like success. Explicit side effects and preconditions say what changes the moment the tool runs and what must be true first. And failure semantics tell the model how to recognize and recover when the call does not go as planned.
Compare lookup(query) against two better-specified tools. A read-only customer search that promises no writes and returns structured records is a fundamentally different object from a tool that immediately transmits an external email. Under a vague surface, both can hide behind the same generic verb. Under a real contract, the model can tell them apart before it commits to an action. The parts of the contract are not decoration. They are the information the model uses to choose.
A small experiment you can reason about
I wanted to see how much the wording of a tool surface changes a model's first move, so I ran a small local fixture for this article. I want to be precise about how small it is, because it is directional evidence and nothing more.
I wrote ten synthetic CRM and email requests. I showed each request to the same model, GPT-5.6 Sol, under two conditions. The vague condition used generic names, one-line descriptions, and permissive schemas. The contract-rich condition bundled intent-revealing names, side-effect and precondition descriptions, and constrained schemas. Each condition received six observations per case across two independent runs. No tool was ever actually executed. I used an OpenAI-compatible function-calling adapter rather than a live MCP server, so there was no backend, no authorization layer, no latency, and no recovery path in the loop.
Caption: In two runs of ten synthetic prompts, the vague surface produced 49 expected first actions out of 60; the contract-rich surface produced 60 out of 60. One model was tested, the treatment changed several interface dimensions together, and no tool ran.
The vague surface produced the expected first action in 49 of 60 observations, or 81.7 percent. The contract-rich surface produced it in 60 of 60, or 100 percent. Two categories of prompt drove the gap. On the six prompts that asked for an action the tools did not actually support, an email audit, the vague surface failed all six by reaching for a generic lookup instead of declining or clarifying. On the six prompts that explicitly asked to send an email, the vague surface handled only one as expected. Better metadata closed both gaps in this fixture.
I will not oversell it. This is one model, ten hand-authored prompts, and provider-default temperature. The treatment bundled names, descriptions, and schemas together, so it cannot isolate which of the three did the work. It is a fixture rather than a benchmark, and it shows a direction rather than a coefficient.
Why the checklist matters beyond one fixture
Two recent preprints show why the boundary matters beyond my toy setup.
DynamicMCPBench, a preprint submitted in July 2026, evaluates 24 models across 121 servers and 750 tasks in 15 categories, using effect-scored traces and a strict pass^3 rule that requires three successes. The strongest agents solved only about half of the tasks. Thirty-one percent were solved by no model at all. Accuracy fell from 39 percent on the shortest tool chains to 13 percent on the longest. Connectivity, in other words, is not completion. In this benchmark, longer tool chains were less reliable. The authors also make a point worth stealing: an effect-scored trace tells you more about whether a real action occurred than a polished final answer does.
The second preprint, an empirical study of 1,723 GitHub MCP applications submitted the same month, looks at how these systems are built rather than how they score. It reports that 90.8 percent log at least part of execution and 77.2 percent expose enable and disable controls, but only 37.2 percent implement a blocking approval gate before a tool executes. Treat that as a GitHub sample analyzed with an LLM-assisted classification pipeline, not a census of production deployments. Still, it says the host-side controls that actually govern safety are heterogeneous. The protocol permits a human veto. Most inspected projects did not enforce one before execution.
Put the two together. The tool interface gives the model its decision surface, and host policy governs what happens when a choice becomes an action. Neither comes for free with a working connection.
The checklist: five questions for your next tool review
Run this against any tool surface before you ship it. It is short on purpose.
- Could another tool plausibly match the same request? If yes, your names and descriptions are doing too little.
- Can the schema represent an underspecified or dangerous call too easily? Tighten the inputs until the wrong call is hard to express.
- Does the model know what changes immediately? Side effects and preconditions belong in the contract, not in tribal knowledge.
- Can the result prove the effect in structured data? A confident sentence is not evidence that an action occurred.
- What does the host enforce even if the model makes the wrong choice? Authorization, approval, and traceability live outside the model, and better wording cannot substitute for them.
The plug fits. Now the engineering starts.
MCP made the plug fit, and that was worth doing. But a socket only moves the hard part downstream. The real work begins when you decide what may flow through it, how a model can tell one tool from another, and how your host proves that an action happened the way it was supposed to.
Here is my question for you: what is the most dangerously ambiguous tool contract you have shipped or inherited, and what finally made you tighten it?


Top comments (0)