Field notes
Shipping a production MCP server
Tool names, input schemas, results and errors shape how an agent uses an MCP server. Test them before release.
MCP gives compatible clients a shared interface to tools and reference material. A server that responds correctly still needs testing for how agents select tools, interpret results and handle errors.
This site runs one, at the same domain you are reading, so the notes below are from something live rather than from a sample repository.
Design the tool surface first
Before writing code, write the list of tool names and one-line descriptions. If you cannot describe a tool in one sentence without "and", it is two tools. If two descriptions sound similar, the model will pick the wrong one at some point and you will spend a day confused about why.
- Name for intent, not implementation.
find_customer_by_emailbeatsdb_query. - Prefer specific over flexible. Flexible tools shift the burden of correctness onto the model, which is exactly backwards.
- Ten is a lot. Beyond that, group by domain and consider separate servers rather than one sprawling surface.
- Write descriptions for a smart stranger. Include when not to use the tool. That line does more work than any other.
Inputs and outputs are a contract
Validate every input with a real schema at the boundary and reject early with a message that tells the caller how to fix it. Agents recover well from precise errors and badly from vague ones.
On the way out, three rules have saved me repeatedly:
- Stable shape, always. Same fields on success and failure, with an explicit status. Shape-shifting responses cause hallucinated field names.
- Cap size and say so. Return the first N results plus the omitted count and a hint for narrowing. Unbounded returns eat the context window and the agent loses the task.
- Errors as data, not exceptions.
{ status: 'not_found', hint: '...' }'lets the agent adapt. A stack trace makes it retry blindly.
Resources and prompts, the underused half
Check whether the server also needs resources or prompts. Resources let a client read reference material without spending a tool call, and prompts let you ship the correct usage pattern along with the capability.
On this site's server, static positioning and bio content are resources while contact submission is a tool. That split keeps read-only material out of the agent's decision loop, which is both cheaper and less error-prone.
Transport, auth, and the security floor
Local stdio servers inherit the trust of the machine. Remote servers do not, and a remote MCP server is a public execution surface with a friendly protocol on top.
- Scoped tokens per client, revocable, never long-lived shared keys.
- Per-token tool allowlists, so a read-only integration cannot reach a write tool even by mistake.
- Rate limits per token and per tool, with clear 429 semantics.
- Audit log of every call with caller, arguments, and outcome. This is your only forensic record.
The full model, including per-user consent and irreversible-action gating, is in MCP server security and auth.
Performance: cache like the caller is impatient
Agents call the same tools repeatedly within a run, often with identical arguments. Without caching you pay for that in latency and in provider load.
- Short-lived response cache keyed on tool plus normalized arguments. Even 30 seconds removes most duplicate work.
- Longer cache for genuinely static resources, with an explicit invalidation path.
- Aggressive timeouts. A tool that hangs is worse than a tool that fails, because the agent has no signal to act on.
The bug was not in the server. Two tools had descriptions that overlapped by one clause, and the agent picked the wrong one about a fifth of the time.
Testing at three levels
- Unit. The functions behind the tools, tested normally. Boring and essential.
- Protocol. Assert the tool list, input schemas, and error shapes. This is your compatibility contract with every client, and it should fail loudly on any accidental change.
- Behavioral. Give a real agent a task and assert which tools it chose. This is the only layer that catches ambiguous descriptions, which is the most common real defect.
Behavioral tests belong in the same suite as everything else in LLM evals that actually catch regressions.
Versioning without breaking clients
You do not control the clients. Assume old agents will call your server for a long time.
- Additive changes are safe. Renames and removals are not.
- To change a tool's behavior, add a new tool and mark the old one deprecated in its description.
- Never repurpose an existing field name. Add a new one and let the old one go quiet.
A checklist before release
- Ten or fewer tools, each describable in one sentence.
- Schema validation and instructive errors on every input.
- Capped, stable-shaped responses with explicit status.
- Scoped tokens, allowlists, rate limits, audit log.
- Caching plus timeouts on everything external.
- Protocol tests and at least five behavioral tests.
- A deprecation path documented before the first client integrates.
Review the tools in the context of an existing AI workflow before agreeing on implementation changes. If you have a stalled product build that has to work for a real customer, pilot, or launch, send the project brief. Scope and price are agreed before work starts.
Frequently asked
What is an MCP server?
A Model Context Protocol server exposes tools, resources, and prompts over a standard protocol so any compatible AI client can use them. Write the integration once and Claude, Cursor, and other clients can all call it.
How many tools should an MCP server expose?
Fewer than you want to. Every tool competes for the model's attention and for context space. Ten sharply defined tools beat forty overlapping ones. If two tools have similar descriptions, the model will pick wrong.
How do you test an MCP server?
Three layers. Unit tests on the underlying functions, protocol tests that assert schemas and error shapes, and behavioral tests where a real agent is given a task and you check that it selects the right tools.
Should an MCP server be remote or local?
Local over stdio for developer tooling that touches a machine. Remote over HTTP for anything multi-user or backed by shared data, which then needs real auth, rate limits, and audit logging.
Have a stalled product build?
I help founders turn stalled product builds into software ready for a real customer, pilot, or launch.
Show me what exists, what is stuck, and what needs to work. I take ownership of the implementation, test the agreed user journey, and document the handoff.
New field notes also go out on my newsletter. Subscribe on Substack.

Written by
Alex Cinovoj, TechTide AI
Founder & CTO, TechTide AI · CTO & Co-Founder, CPG Playbook. I’m based in Columbus, Ohio, and spent 13 years in IT across support, systems, cloud, architecture, and engineering, and the last 2 years on AI implementation. I’m a Lovable Senior Champion, an earned Discord community-support volunteer role, with 9 Anthropic Academy course completions. Logs over vibes. Production over theater.