Scott Wueschinski
← All AI and Agentic POV

Custom MCP servers that compound vs ones that don't

Five practices that separate production-grade MCP servers from glorified internal scripts, written from the Forward Deployed seat.

AI & Agentic POV MCP & Tools

· 4 min read · Source: Phil Schmid ↗

Most teams think they shipped an MCP server. What they actually shipped is an internal script wearing a JSON-RPC costume. It demos clean. It dies quietly in month three.

The cleanest framing I have read on this comes from Phil Schmid, and it is uncomfortable on purpose: MCP servers are not thin wrappers around your existing API. A Good REST API is not a good MCP server. The reason matters. MCP is a User Interface for AI agents. Different users, different design principles.

That single shift, treating the server as an interface for a non-human user, is what separates the servers that compound from the ones that rot. Here are the five practices that decide which one you built.

Outcomes over endpoints, descriptions as code

Practice one: design tools around what the agent is trying to accomplish, not around your route table. The classic trap is converting REST endpoints one to one into MCP tools. The fix is to design tools around what the user or agent wants to achieve. Instead of three atomic order tools, you ship one. A good MCP server exposes one tool, track_order(email). The tool calls all three internally and returns a clean answer. Same outcome, one call, outcome oriented. You do the orchestration in code, where it is testable, not in the model’s context window, where it is expensive and flaky.

Practice two: treat your tool descriptions like production code, because they are. They are the only documentation the model ever reads. Recent work makes this measurable. A 2026 empirical study of MCP tool descriptions argues that seemingly minor underspecification, like missing parameter names or formats, can cause models to call tools with overly broad ranges, inflating payload size, latency, and token cost. The takeaway is operational, not academic: lint them, version them, and run A/B tests on description variants. A server whose descriptions are version-controlled and tested gets sharper every release. A server whose descriptions are an afterthought degrades every time a new model lands.

Security and observability are the table stakes

Practice three: security is not a phase two backlog item. The data here is brutal. Knostic researchers scanned nearly 2,000 publicly accessible MCP servers and found that every single verified instance granted access to internal tool listings without any authentication. That is not a fringe failure mode. That is the median.

Get the architecture right first. The authorization server handles user auth, token issuance, and client registration. The resource server, your MCP server, validates tokens and enforces access controls. Then default to safe. Treat human-in-the-loop as a must, not a suggestion. By default, every tool must be set to read-only, and require explicit user approval for any write action. The threat is not theoretical: tool poisoning and rug-pull attacks exploit servers that trust permanently and validate never.

Practice four: instrument it like the microservice it is, because it is one. Your MCP server is still a microservice. Treat it that way. Emit structured logs with correlation IDs. Track latency, success and failure, and token costs. Surface rate limits explicitly so agents can budget calls. If you cannot monitor it, you cannot run it at scale. The 2026 spec even locked down distributed tracing so a call can be followed from host through server to downstream as a single trace. If you cannot reconstruct what your agent did and why, you do not have a production system. You have a liability with uptime.

The one that decides if you scale

Practice five: build stateless and version your surface area. This is the practice that quietly kills more deployments than any security gap. Running MCP at scale has surfaced a consistent set of gaps: stateful sessions fight with load balancers, horizontal scaling requires workarounds. The protocol itself moved to fix this. For scalability, prefer stateless MCP servers where each request carries all necessary context. Use stateful servers only when maintaining session-specific resources. Pair that with semantic versioning on the server and on individual tools, and you can evolve without breaking every agent downstream.

Here is the Cost of Doing Nothing math, the CODN, that most teams skip. A script-grade server is not free. It is a deferred bill. You pay it when the model upgrade breaks your untested descriptions, when the unauthenticated endpoint leaks, when the stateful session takes down a node behind the load balancer, when nobody can explain a bad agent action because there are no traces. Doing nothing is choosing the rewrite, just later and under pressure.

The compounding server is an asset that gets cheaper to operate every quarter. The script gets more expensive every quarter until someone rips it out. Same protocol. Same SDK. Completely different trajectory.

Build the interface, not the script. The agents you ship next year will route around everything else.