Recipe 00211 min read

Model Context Protocol

A practical guide to MCP for engineers: what it is, where it helps, how to design better tools, and where production implementations usually go wrong.

TL;DR
  • MCP is a standard way for AI applications to connect to tools, data, and workflows without every host needing a custom integration for every system.
  • The host stays in charge. Servers expose capabilities, but the host decides what to show, what to attach as context, and when consent is required.
  • Tools are the center of gravity in real deployments, but resources and prompts matter because they shape who controls access and when each primitive is used.
  • Good MCP design is mostly good interface design for models: fewer tools, clearer descriptions, tighter outputs, and errors that help the model recover.
  • Most production pain comes from security, observability, and over-granular tool design rather than from the protocol basics.
  • If one application is calling one API in a fixed workflow, plain code is usually simpler than MCP.
  • The stable spec is 2025-11-25 today, while the 2026-07-28 release candidate signals where remote and multi-tenant MCP deployments are headed next.
Quick view
Best for
AI apps with many tools or swappable integrations
Core shift
One protocol instead of one-off connectors
Do first
Design one intent-shaped tool well
Primary risk
Prompt injection and tool sprawl

What & why

MCP stands for Model Context Protocol. In plain English, it is a shared protocol for connecting AI applications to external systems such as local files, APIs, databases, SaaS products, and custom workflows.

The useful mental shortcut is USB-C for AI. Without a standard, every host needs a custom integration for every capability. With MCP, hosts and servers can implement one protocol and interoperate across many combinations.

That matters most when you want the same integration to work in more than one host, or when you want users to mix and match tools without rebuilding the whole stack each time.

It matters much less when one application is calling one backend in one predictable sequence. In that case, direct code is often cleaner.

Mental model

Think of MCP as a contract between three roles. The host is the AI application the user actually uses. The client is the protocol-speaking connector inside that host. The server is the thing exposing capabilities.

The design rule that keeps implementations sane is simple: the server serves, and the host decides. Servers do not own the conversation, the consent model, or the orchestration loop.

If you build your server like a humble capability provider instead of a mini-agent with hidden assumptions, almost every later design choice gets easier.

The three primitives

  • Tools: model-invoked actions such as searching, updating a record, or running a workflow.
  • Resources: host-attached context such as files, documents, records, or schemas.
  • Prompts: reusable templates a person or application can select explicitly for a repeated job.
  • The practical lesson is not that all three are equally used. It is that each one has a different control surface, so choosing the wrong primitive makes the whole integration clumsier.

If you only do three things this month

  • Collapse API-shaped tool sprawl into a smaller set of intent-shaped tools that map to actual user jobs.
  • Rewrite every tool description so it explains when to use the tool, when not to use it, and what success looks like.
  • Add structured logging for tool inputs, tool outputs, and validation failures before you try to debug real agent behavior.

Start here

  1. 01
    Choose the transport that fits the deployment

    Use `stdio` for local tools and developer workflows because it keeps the setup simple and avoids adding a network surface.

    Use Streamable HTTP for remote servers and hosted infrastructure where many clients may need the same capability.

  2. 02
    Design one tool around a user intent

    Do not begin by mirroring your REST or RPC surface one endpoint at a time.

    Start with a task a user actually wants completed, such as looking up a customer issue, summarizing it, and returning the next recommended action in one compact result.

  3. 03
    Write the tool description for the model, not for humans browsing docs

    A good tool description tells the model what the tool does, when to call it, what arguments mean, and which nearby situations are not a fit.

    If the description is vague, the model will be vague in how it selects and sequences the tool.

  4. 04
    Return compact, structured outputs

    Do not dump raw JSON responses if the model only needs five fields and a status.

    Every extra token competes with the rest of the task, so output shape is part of the product design, not just a serialization detail.

  5. 05
    Make errors teach the retry

    Prefer messages like `date must be YYYY-MM-DD` or `customer_id was missing` over generic failures or stack traces.

    Models recover much better when your server makes the repair path explicit.

Build the full system

  1. 01
    Keep the tool surface small and memorable

    A model choosing between six clear tools usually performs better than a model choosing between thirty narrowly sliced ones.

    If two tools are almost always called in sequence, treat that as a design smell and consider combining them.

  2. 02
    Design for weak memory between calls

    Return IDs, handles, and enough context for the next call to stand on its own.

    This improves robustness now and also lines up with the draft direction toward more stateless remote operation.

  3. 03
    Treat observability as a first-class feature

    Log every request and response pair, plus validation errors and downstream failures.

    Most MCP debugging pain comes from understanding the gap between what the model appeared to intend and what your server actually received.

  4. 04
    Use least privilege and explicit confirmations

    Keep scopes narrow, prefer read-only access when possible, and require a human checkpoint for destructive actions.

    An MCP server should be treated more like a browser extension than a harmless library because it may sit in a trusted agent workflow with real credentials.

  5. 05
    Separate domains instead of building a mega-server

    Single-purpose servers for files, tickets, CRM, billing, or docs are easier to audit, permission, and evolve than one large all-knowing server.

    Composition belongs in the host layer.

  6. 06
    Plan for draft-era changes if you run remote infrastructure

    As of July 9, 2026, the latest stable MCP spec is `2025-11-25`, while `2026-07-28` is the current release candidate on the official site.

    The release candidate emphasizes a stateless core, first-class extensions, and operational changes that matter most for remote, multi-tenant, or horizontally scaled deployments.

What stronger MCP design looks like

  1. 01
    API mirror to intent-shaped tool

    Before: separate tools for `get_customer`, `get_orders`, and `get_order_items`.

    After: one tool like `summarize_customer_recent_purchases` that returns the specific facts the model needs for the user’s question.

    Why it works: the model has fewer chances to choose the wrong path and burns fewer tokens on plumbing.

  2. 02
    Documentation-style description to action-oriented description

    Before: `Fetches order data for a customer.`

    After: `Use when the user wants recent purchase history, order status, or refund context for a known customer. Do not use for product catalog search or account creation.`

    Why it works: the description becomes a routing hint instead of a label.

  3. 03
    Raw payload to model-ready output

    Before: return the full upstream API response with every nested field.

    After: return a compact object with the order summary, relevant IDs, timestamps, and any follow-up action the caller can take next.

    Why it works: the model spends context on the user problem instead of cleaning your API response.

Choose the next move

  1. 01
    If your server has too many tools, merge by job-to-be-done

    Group around what the user is trying to accomplish rather than around backend endpoints or database tables.

  2. 02
    If tool calls are wrong, rewrite descriptions before rewriting architecture

    Many selection problems are really prompt problems hiding in metadata.

  3. 03
    If remote deployments are fragile, audit hidden session assumptions

    Look for places where the server expects memory between calls and replace them with explicit handles or resumable state passed through the protocol.

  4. 04
    If security review is weak, shrink privileges before adding more capabilities

    Reducing scope usually lowers risk faster than adding more validation after the fact.

  5. 05
    If your workflow is fixed and deterministic, remove MCP from the path

    MCP helps when the host or model needs runtime choice. It adds overhead when the sequence is fully known already.

Prove it is working

  • Track successful task completion, not just successful tool invocation.
  • Measure how often the first tool choice is correct and how often the model self-recovers after an error.
  • Watch average output size per tool response so context bloat does not quietly erode downstream performance.
  • Review destructive-action confirmation rates and denied calls to confirm least-privilege boundaries are real.
  • For remote servers, monitor retries, timeout rates, and whether requests still succeed when routed across different instances.

Final checklist

Each tool maps to a user intent instead of a thin wrapper around an API endpoint.
Tool descriptions explain when to use the tool and when not to use it.
Outputs are compact and structured for model consumption, not raw upstream dumps.
Validation errors tell the caller how to retry successfully.
Requests and responses are logged well enough to debug real agent behavior.
Privileges and scopes are limited to the smallest useful surface.
Destructive actions require an explicit human checkpoint in the host.
The server does not depend on hidden conversational state to function correctly.
Remote deployments have been reviewed for statelessness and multi-instance safety.
The team has confirmed MCP is actually the right abstraction for this workflow.

Common ways this goes off track

  • Treating MCP as a magic agent framework instead of a protocol boundary.
  • Exposing dozens of tiny tools because the backend already has dozens of endpoints.
  • Returning raw payloads that force the model to do cleanup work on every call.
  • Assuming the server controls the conversation or can enforce UX decisions the host never implemented.
  • Ignoring prompt injection risk in tool descriptions, tool results, or connected content sources.
  • Shipping write access before least-privilege review and confirmation flows are in place.
  • Building one mega-server that mixes unrelated domains and permissions.
  • Using MCP for fixed, deterministic flows that would be simpler as normal application code.

Examples

  • MCP introduction — Official overview of MCP, including the standard USB-C-for-AI framing and the basic roles involved.
  • MCP server concepts — A practical official guide to tools, resources, prompts, and the responsibilities of MCP servers.
  • MCP specification — The current stable specification as of July 9, 2026.

Read next

References

More recipes

Subscribe to all Software Cookbook updates

If this recipe was useful, subscribe for the next ones. New pages arrive with the same concise, technical format.

New cookbook updates, sent when there's something worth reading.