Best Practices for Building MCP Servers
Building a basic MCP server can be quick.
Building one that agents can use safely and effectively takes design.
The biggest mistake is treating MCP as an automatic export of your existing API. A good MCP server is not a giant list of endpoints. It is a focused, agent-friendly interface.
Start With the Agent Story
Do not start by listing every API endpoint.
Start with the workflows you want the agent to support.
For example:
As a support engineer, I want the agent to find a customer's recent orders, identify the damaged one, and prepare a refund with confirmation.
That story suggests a small number of useful tools.
It does not suggest exposing every customer, order, payment, shipment, and inventory endpoint separately.
Keep the Tool Surface Small
Large tool lists make model selection harder.
As a practical default, aim for five to eight tools per server. Be cautious once a server has more than ten to twelve tools.
If the domain is too large, split it.
Examples:
- billing-mcp
- inventory-mcp
- support-mcp
- repo-mcp
One server should have one coherent job.
Design Workflow Tools
Prefer workflow-shaped tools over raw CRUD tools.
Instead of:
- list_orders
- get_order
- get_customer
- get_payment
- create_refund
Consider:
- find_refundable_order
- prepare_refund
- submit_refund_after_confirmation
The MCP server can call multiple internal APIs behind the scenes and return one clean, agent-shaped result.
Write Tool Descriptions for the Model
Tool descriptions are not just docs.
They are instructions the model uses to decide what to call.
A good tool description is:
- Action-first
- Short
- Clear about side effects
- Clear about when to use it
- Clear about when not to use it
Avoid vague descriptions like:
Gets data from the order service.
Prefer:
Find recent customer orders by email address. Use this before preparing a refund or investigating a delivery issue. Does not modify data.
Return Less, But Better
Raw API responses often contain too much.
An MCP tool result goes into the model's context, so every extra field costs attention.
Return what the model needs for the next decision:
- Key identifiers
- Relevant status
- A concise summary
- Possible next actions
- Warnings or missing permissions
Offer a separate detail tool if deeper inspection is needed.
Recommended by LinkedIn
Treat Errors as Guidance
Errors should help the agent recover.
Instead of:
403 Forbidden
Return:
Permission denied. This action requires the billing:refund scope. Ask the user to reconnect with refund permission before retrying.
That gives the model something useful to do next.
Design Session Boundaries Deliberately
Session management is one of the most important production architecture choices for MCP servers.
The practical default:
Use one MCP session per user and agent session.
That means each active agent conversation gets its own MCP session, tied to the user and the current agent workflow.
Avoid sharing one MCP session across multiple users, agents, or conversations. Shared sessions create hard-to-debug risks:
- Cross-user data leakage
- Auth confusion
- Mixed audit trails
- Concurrent state bugs
- One agent polluting another agent's context
Session boundaries are also security boundaries.
If User A's agent and User B's agent share the same MCP session, it becomes much harder to answer basic production questions:
- Whose token is being used?
- Which user approved this action?
- Which agent called this tool?
- Which workflow owns this cursor, cache, or intermediate state?
Keep those boundaries clear.
Externalise Durable State
Some MCP flows need a state.
Examples:
- Pagination cursors
- Long-running job IDs
- Workflow checkpoints
- Temporary upload references
- Tool progress
- User approval state
Do not rely only on in-memory session state for anything important.
For production servers, store durable state outside the server process in a database, queue, cache, or workflow system. The MCP session can hold lightweight coordination state, but the important parts should survive restarts, deploys, and load balancing.
This makes horizontal scaling easier. A request can land on any healthy server instance, and the instance can recover the needed state from the shared store.
Stateful vs Stateless Tradeoffs
Stateful sessions can be useful.
They let the server pay the initialisation cost once, keep bidirectional flows open, and support compact follow-up calls. They can also make streaming, notifications, elicitation, and multi-step workflows smoother.
But stateful sessions have real operational cost:
- Sticky routing becomes harder
- Rolling deploys can interrupt sessions
- Restarts can lose context
- Load balancing becomes more complex
- Memory use grows with open sessions
For most production deployments, design the MCP server so the process is as stateless as practical, while session metadata and durable workflow state live in external storage.
If you need to share an expensive resource across agents, share the resource, not the MCP session.
Build for Production
A production MCP server needs the same discipline as any other service:
- Health checks
- Readiness probes
- Timeouts
- Structured logs
- Metrics
- Audit trails
- Contract tests
- Versioned schemas
- Least-privilege auth
- Graceful shutdown
MCP is new, but the operational basics are not.
The Takeaway
Design MCP servers as products for agents.
Keep them small, workflow-focused, secure, observable, and easy for the model to understand.
Full knowledge base: https://sagart-cactus.github.io/learn-mcp/
Originally published on LinkedIn.