mcp-best-practices
MCP server best practices
These are rules to apply, not a document to read. Every rung below ends in a checkable bar, and the completion criterion at the bottom binds you to all of them — whether you are authoring a surface or auditing one, the work is the same and finishes the same way.
An MCP server publishes two things. The surface is everything it advertises — names, titles, descriptions, schemas, annotations, resource metadata. The boundary is everything crossing into it — arguments, tokens, URIs, state handles.
Two frames carry the whole thing:
The surface is prompt. Every advertised character is text a model reads and reasons over, spending the same window and the same attention as a system prompt. Judge it as prompt, not as API documentation. A description that reads well to a developer and gives the model no reason to act is a defect.
The boundary is untrusted. Every argument is model output, and model output is shaped by whatever the model just read. Judge each entry point as if the argument were chosen by an attacker, because a prompt injection three tool calls ago means it may have been.
Scope: the surface and the boundary. Building a server end to end — scaffolding, bundling, releasing — is the mcpb skill.
Read the advertised surface, never the source alone
Frameworks reshape what the source appears to say, and they disagree with each other. One Python docstring with an Args: block, read over the wire on current releases: