"A working MCP server is easy; a great one is thoughtful — clear, safe, efficient, and pleasant for both models and humans."
Level: Advanced · Time: ~12 min · Prerequisites: Modules 26–28
Learning Objectives
By the end of this module, you will be able to:
- Apply best practices for designing servers
- Understand sampling and roots (advanced features)
- Keep servers efficient and maintainable
- Design for real production use
1. Design Servers for the Model
The model only sees names, descriptions, and schemas — so design for it:
- Name tools clearly (
search_orders, notso) - Write descriptions that state exactly what a tool does and when to use it
- Keep inputs simple and typed
- Return concise, structured results (protect the context window)
- Group related capabilities into focused servers, not one giant catch-all
Explain like I'm new: Think of your server as a menu for the AI. A clear menu with good descriptions gets the right order every time; a cryptic one leads to mistakes. You're writing UX — for a model.
Common mistake: Leaking implementation details into tool names. pg_query_v2 tells the model nothing about when to use it; search_customers_by_email tells it exactly. Name for the job the tool does, not for how you built it — the model has never seen your codebase.
2. Advanced Features
MCP includes powerful extras you'll meet as you grow:
- Sampling: a server can ask the host's LLM to generate something — enabling smarter servers without their own model.
- Roots: let a client tell a server which files/folders it's allowed to touch — a built-in scoping mechanism.
- Progress & streaming: long tasks can report progress instead of blocking.
Key idea: These features exist to make MCP servers capable yet controlled. Roots scope access; sampling shares intelligence; streaming improves UX. You don't need them on day one, but knowing they exist shapes better designs.
To make sampling concrete: imagine a "summarize document" server. Without sampling, it would need to bundle its own language model — heavy and expensive. With sampling, it simply asks the host's LLM to write the summary, staying lightweight while still being smart. Roots work the opposite direction: the client hands the server a boundary ("you may only read files under /project"), so even a buggy server can't wander into your home directory. Together they capture MCP's design philosophy — push capability outward, but keep the guardrails in the client's hands.
3. Efficiency & Reliability
- Handle errors gracefully — return clear error messages, not crashes
- Paginate or summarize large results
- Cache expensive lookups when safe
- Log actions for debugging and auditing
- Version your server so hosts can adapt to changes
Real-world use case: A production database MCP server returns summaries of large query results (with an option to fetch details), caches schema lookups, validates every query for safety, and logs each call. It's fast, safe, and debuggable — the marks of production quality.
Real-world use case: Consider what happens when a query returns 10,000 rows. A naïve server dumps them all into the context window, blowing the token budget and confusing the model. A thoughtful server returns "10,000 matches; here are the first 20, call fetch_page for more." The model stays oriented, costs stay low, and the user still gets everything they need on request. Respecting the context window is one of the highest-leverage habits in MCP design.
4. Keep It Focused
The best servers do one domain well. A "GitHub server" and a "database server" beat one sprawling "everything server" — easier to secure, reason about, and reuse.
Common mistake: Building a mega-server with dozens of loosely related tools. It overwhelms the model's tool selection and widens your security surface. Prefer several small, focused servers a host can mix and match.
Hands-On: Try This
Try this: Take a tool you'd expose and write two descriptions — one lazy ("handles data") and one great ("Search customer orders by email; returns up to 10 recent orders with status and total"). Notice how the second removes all ambiguity. That gap is the difference between a flaky and a reliable server.
✅ Checkpoint
- Why design tool names/descriptions for the model?
- What does the "roots" feature do?
- Why prefer several focused servers over one giant one?
Answers: 1) The model selects tools purely from names/descriptions. 2) Lets a client scope which files/folders a server may access. 3) Easier to secure, reason about, and reuse; better tool selection.
Key Takeaway: Great MCP servers are designed for the model: clear names/descriptions, simple typed inputs, concise results. Advanced features — sampling (use the host's LLM), roots (scope access), streaming — add capability with control. Handle errors, cache, log, version, and keep each server focused on one domain rather than building a sprawling catch-all.
Further Learning
Adapted from Microsoft's MCP for Beginners (MIT License).