MCP servers in production: lessons from three connectors.
Anthropic's Model Context Protocol is becoming the new integration layer between LLMs and the tools they call. After three production deployments — including one against a SaaS API with a thoroughly hostile auth model — here's what we've learned.
What MCP actually solves.
Before MCP, every agent platform reinvented tool calling. Same problem, different shape, every time. MCP standardizes the contract: tools have typed inputs, typed outputs, capability descriptions, and a transport layer. Once you write the server, every MCP-compliant client can use it.
That's the pitch. The reality is messier — but the pitch holds. We're betting on it.
What we've shipped.
- An internal CRM connector for a sales operations team. Read-only first, then write with explicit approval steps. Live since Q4 2025.
- A document repository connector with per-tenant index isolation, used for grounded retrieval in a regulated buyer's environment.
- A scheduling/calendar connector with real auth — the hostile case, where the upstream API is OAuth-token based with refresh logic that misbehaves.
What works.
1. Treat the tool list as the API.
The tool list is the public contract; everything below is implementation. Version it. Deprecate carefully. Document the input schemas like you'd document a public REST API, because that's what they are now — to LLMs.
2. Type everything, return JSON.
The temptation is to return strings ("Booking confirmed for John on Tuesday"). Don't. Return structured JSON. The LLM is more reliable summarizing structured data than parsing your prose.
3. Idempotency keys on writes.
Models retry. Networks fail. Without idempotency keys you'll get duplicate writes the first time the model gets nervous. Make every write tool accept an idempotency key from the caller, and enforce it server-side.
4. One server per logical domain, not per backend system.
Don't write "the Salesforce MCP server." Write "the customer-records MCP server" that may or may not be backed by Salesforce. The agent doesn't care; the seam should be at the domain, not the vendor.
What doesn't work.
1. The "user-token" auth model for multi-tenant servers.
Holding the user's OAuth token in the MCP server creates a per-user secret rotation nightmare and a fat compliance surface. The pattern that works: service account on the upstream + per-user authorization layer in front of MCP. The server uses one token; your access logic decides what each user can call.
2. Letting the model retry on errors.
If the tool returns an error, the model will often "try a different way." Sometimes that means calling four other tools to recover. Half the time, none of them is right. Be specific in error responses about what failed and what the LLM should do next; otherwise it improvises.
3. Long-running tool calls.
Tools that take more than ~5 seconds break the orchestration story. Async tool patterns (return a job ID, poll) work, but only if your client supports them well. Better: design tools to be fast or fail.
The mistake we keep seeing.
Teams expose too many tools. Twenty tools in a server, fifteen of which the model never calls correctly. The model gets worse at picking among too many; the audit surface gets larger; the security review gets longer.
Three to seven tools per server is the right count. If you have more, you have multiple servers in disguise. Split them.
The shortest version.
Type your tools. Limit your surface. Idempotency on writes. Service-account auth at the bottom; per-user authorization on top. Fast or async. Three to seven tools per logical server.
MCP is the right bet for 2026 integrations. The standard is real, the clients are landing, and the alternative — bespoke tool plumbing per agent platform — is worse.
Oviompt builds production MCP servers and agent runtimes. File an intent if you're building one.