DEV Community

Cover image for Model Context Protocol (MCP) for Backend Engineers
Ameer Hamza
Ameer Hamza

Posted on

Model Context Protocol (MCP) for Backend Engineers

Introduction

Every AI agent needs tools. Before standardized protocols, every tool integration was a custom hack.

Model Context Protocol (MCP) standardizes how LLMs discover and call external tools. Instead of writing a bespoke integration for each API, you expose tools through a common protocol. The model sees a standard interface. Your backend handles authorization, execution, and error handling.

Think of MCP like OpenAPI for AI agents: one spec, many tools, consistent calling conventions.

Why This Matters

Backend engineers scale systems by standardizing interfaces. REST replaced ad-hoc RPC. OpenAPI replaced tribal knowledge about endpoints. MCP applies the same principle to agent tool access.

Before MCP, connecting an agent to Slack, a database, and a search API meant three different integration patterns, three auth flows, and three error-handling conventions. That does not scale when your tool catalog grows from 3 to 30.

Prerequisites

This article assumes you have read Blog 001 and Blog 002. You should understand LLM inference basics and how RAG provides external knowledge at query time.

The Problem

Custom tool integrations create:

  1. N×M coupling: N agents times M tools means N×M integration code paths.
  2. Schema drift: Tool signatures change; agent prompts break silently.
  3. Inconsistent auth: Each tool handles credentials differently.
  4. Poor observability: No uniform logging across tool calls.
  5. Vendor lock-in: Switching agent frameworks means rewriting integrations.

Understanding the Core Concept

MCP defines a client-server model:

Role Responsibility
MCP Host The application (IDE, chat UI, agent runtime) that runs the LLM
MCP Client Connects host to one or more MCP servers
MCP Server Exposes tools, resources, and prompts over the protocol
Tools Callable functions with typed input schemas
Resources Readable data (files, records) the model can fetch

The LLM does not call HTTP endpoints directly. The host translates model tool requests into MCP messages, routes them to the correct server, and returns structured results.

Tools vs resources

Tools are actions: query a database, send a message, create a ticket. Resources are read-only context: file contents, configuration, documentation snippets. Separating reads from writes helps you apply different auth policies.

Discovery

MCP servers advertise available tools with JSON Schema descriptions. The host injects tool definitions into the model context. When the model emits a tool call, the host validates arguments against the schema before execution.

How It Works Internally (High Level)

  1. Host starts MCP client and connects to configured servers (stdio, HTTP, or SSE transport).
  2. Client requests tools/list from each server.
  3. Host merges tool catalogs and presents them to the LLM.
  4. Model generates a tool call with name and arguments.
  5. Host validates, routes to the correct MCP server via tools/call.
  6. Server executes, returns structured content or error.
  7. Host feeds result back into the conversation for the next model turn.

Step-by-Step Example

Task: Agent looks up a customer's order status.

  1. MCP server for orders exposes get_order(order_id: string).
  2. User asks: "Where is order 48291?"
  3. Model selects get_order with order_id: "48291".
  4. Host validates schema, calls MCP server.
  5. Server queries internal API, returns {"status": "shipped", "eta": "2026-07-08"}.
  6. Model summarizes for the user.

If the server returns an error, the host should surface it to the model so it can retry or escalate.

Architecture

MCP Architecture

Standardize the interface layer first. Then scale the number of tools.

Python Example

Illustrative MCP-style tool registry pattern. Production MCP servers use the official SDK.

"""
Illustrative tool registry pattern (MCP-style).
Production: use the official MCP Python SDK.
"""
from dataclasses import dataclass
from typing import Any, Callable
import json

@dataclass
class Tool:
    name: str
    description: str
    parameters: dict
    handler: Callable[[dict], Any]

class ToolRegistry:
    def __init__(self):
        self._tools: dict[str, Tool] = {}

    def register(self, tool: Tool) -> None:
        self._tools[tool.name] = tool

    def list_tools(self) -> list[dict]:
        return [
            {
                "name": t.name,
                "description": t.description,
                "parameters": t.parameters,
            }
            for t in self._tools.values()
        ]

    def call(self, name: str, arguments: dict) -> str:
        if name not in self._tools:
            return json.dumps({"error": f"Unknown tool: {name}"})
        try:
            result = self._tools[name].handler(arguments)
            return json.dumps({"result": result})
        except Exception as exc:
            return json.dumps({"error": str(exc)})

def get_order_handler(args: dict) -> dict:
    order_id = args.get("order_id")
    if not order_id:
        raise ValueError("order_id required")
    return {"order_id": order_id, "status": "shipped", "eta": "2026-07-08"}

registry = ToolRegistry()
registry.register(Tool(
    name="get_order",
    description="Fetch order status by order ID",
    parameters={
        "type": "object",
        "properties": {"order_id": {"type": "string"}},
        "required": ["order_id"],
    },
    handler=get_order_handler,
))

if __name__ == "__main__":
    print("Tools:", json.dumps(registry.list_tools(), indent=2))
    print(registry.call("get_order", {"order_id": "48291"}))
Enter fullscreen mode Exit fullscreen mode

Wrap handlers with auth checks, rate limits, timeouts, and audit logging.

Real-World Applications

  • IDE assistants accessing repositories, linters, and documentation via MCP servers
  • Enterprise agents querying internal databases through governed MCP gateways
  • Multi-tool agents where Slack, Jira, and search share one protocol layer
  • Local-first workflows exposing filesystem and CLI tools to a model host

Performance Considerations

  • Cold start: Each MCP server connection adds startup latency. Pool connections in long-running hosts.
  • Serialization: Large tool results bloat context. Truncate or summarize before feeding back to the model.
  • Concurrency: Parallel tool calls need idempotent handlers and clear ordering semantics.
  • Network hops: Remote MCP servers add RTT. Co-locate servers with data when possible.

Common Mistakes

  1. Exposing destructive tools without confirmation gates.
  2. Returning raw API responses instead of structured, model-friendly summaries.
  3. No schema validation before execution.
  4. Building MCP servers without auth scoped to the requesting user.
  5. Treating MCP as a replacement for RAG (tools fetch live data; RAG indexes documents).

Interview Questions

Q1: What problem does MCP solve?

A: It standardizes how LLM applications discover and invoke external tools, reducing bespoke integration code.

Q2: How is MCP similar to OpenAPI?

A: Both define machine-readable interfaces. OpenAPI describes HTTP APIs; MCP describes tools and resources for LLM hosts.

Q3: What is the difference between an MCP tool and a resource?

A: Tools perform actions with side effects. Resources provide read-only context the model can fetch.

Q4: Who validates tool call arguments?

A: The MCP host validates against the tool schema before invoking the server.

Q5: When would you not use MCP?

A: For a single static integration with no growth in tool count, a direct API wrapper may be simpler.

Q6: How does MCP relate to function calling in chat APIs?

A: Chat APIs define how models emit tool calls. MCP defines how hosts connect to and execute those tools across servers.

MCP Transport and Deployment

MCP supports multiple transports:

Transport Use case Notes
stdio Local tools, IDE plugins Simple, single machine
HTTP/SSE Remote servers Network auth required
Hosted gateway Enterprise tool bus Central policy enforcement

Security model

Treat every MCP server like an internal API:

  • Authenticate the host to the server
  • Scope tools per user or tenant
  • Audit every tools/call with arguments and result hash
  • Rate limit destructive operations
  • Never expose raw SQL without read-only roles

Scaling tool catalogs

As tools grow past twenty, add:

  • Namespacing: billing.get_invoice vs crm.get_invoice
  • Discovery tiers: Load core tools always; load extended tools on demand
  • Schema registry: Version tool definitions; reject calls against stale schemas

MCP vs direct function calling

Provider function calling defines the model-facing schema. MCP standardizes server-side implementation. You can implement MCP servers behind OpenAI-compatible function routes so one tool implementation serves multiple agent hosts.

Extended Example: Multi-Server Host

A coding agent host connects to three MCP servers:

  1. Filesystem server (stdio): read_file, list_dir scoped to workspace root.
  2. Git server (HTTP): diff, commit with OAuth user token.
  3. Docs server (HTTP): search_docs backed by your RAG index.

The host merges tool catalogs at startup. When the model calls search_docs, the host routes to server 3. When it calls read_file, server 1. Auth and rate limits are per server, not global defaults.

Comparison: MCP vs Ad-Hoc Integrations

Concern Ad-hoc MCP
Tool discovery Hardcoded in app Server advertisement
Schema versioning Scattered Central per server
Auth Per integration Per server policy
Reuse across hosts Copy-paste Same server binary
Testing Mock each API Mock MCP server

Failure Handling

When tools/call fails:

  1. Return structured error to model (timeout, permission_denied, not_found).
  2. Increment failure counter; trip circuit breaker after N failures.
  3. Do not silently swallow errors; models loop on empty results.

Define idempotency keys for tools that mutate state.

Building Your First MCP Server

Minimal server responsibilities:

  1. Implement tools/list returning name, description, JSON Schema parameters.
  2. Implement tools/call executing the handler and returning text or structured content.
  3. Validate inputs before side effects.
  4. Return errors as structured JSON, not stack traces to the model.

Start with read-only tools. Add writes after auth and audit paths exist.

Governance Model

Central platform team owns:

  • Approved MCP server registry
  • Security review checklist per server
  • Shared client library in the agent host

Product teams own:

  • Domain-specific tool implementations
  • Business logic inside handlers

This mirrors API gateway governance for microservices.

Interop with OpenAI Function Calling

Map MCP tool schemas to provider function definitions at the host. When the provider returns a function call, translate to MCP tools/call. One MCP server can back multiple provider formats with a thin adapter layer.

Operations Runbook

Deploy: Version MCP servers independently from agent host. Pin server version in host config.

Rollback: If new tool schema breaks agents, revert server version; host rejects unknown tools gracefully.

Monitor: tools/call rate, error rate, p95 latency per tool, auth failure count.

Incident: On runaway tool loop, circuit-break the server at host level without redeploying the LLM.

Testing MCP Servers

Contract tests per tool:

  • Valid args return expected shape
  • Invalid args return structured error
  • Auth missing returns permission_denied
  • Timeout enforced at 30s default

Load test with parallel tools/list and tools/call matching peak agent traffic.

Enterprise Rollout Pattern

Phase 1: Read-only MCP servers (docs, search, metrics). Phase 2: Write tools with approval in staging. Phase 3: Production writes with audit and rate limits. Phase 4: Federated registry where teams publish servers to a central catalog with security sign-off. Skipping phases causes the same incidents as exposing raw admin APIs to junior scripts.

Document each tool with owner, on-call rotation, and deprecation policy. MCP without ownership becomes undeletable legacy surface area.

Reference Appendix: Production FAQ

How do I know this is working in production?

Instrument the layer this article describes before changing models or prompts. Compare p50 and p95 latency, error rate, and task-specific quality scores week over week. AI regressions are subtle: flat aggregate uptime can hide wrong answers.

What is the first config change to try?

Reduce variability before increasing capability. Lower temperature for factual paths, shrink retrieval top-K, tighten context budgets, add output validation. Complexity is not a substitute for measurement.

What belongs in an on-call runbook?

Symptom, dashboard link, rollback lever (model version, feature flag, index snapshot), owner team, and customer communication template. LLM incidents need content rollback, not only service restart.

How do I explain tradeoffs to product managers?

Use dollars and seconds: cost per successful task, p95 time to first token, accuracy on golden set. Avoid debating model intelligence; debate measurable user outcomes and failure tolerance.

When should we retrain, re-index, or rewrite prompts?

Re-index when documents change. Rewrite prompts when behavior spec changes. Retrain or fine-tune when prompt plus RAG cannot meet format or tone requirements after eval iteration. Default order: prompt, RAG, fine-tune.

What is the common rollback path?

Keep previous model version, previous index snapshot, and previous prompt template addressable by version id for at least seven days. Rollback should be one feature flag or deploy revert, not a fire drill.

How does this interact with the rest of the handbook?

This topic is one layer in a stack. Read prerequisites listed in frontmatter. When debugging end-to-end failures, walk the request path from ingress through retrieval, inference, and output validation before concluding the model is wrong.

Summary

MCP is infrastructure for agent tool access. Design a standardized tool interface layer before your integration count explodes. The model sees a uniform catalog. Your backend enforces auth, limits, and observability behind each server.

Further Reading

  • Anthropic Model Context Protocol specification
  • MCP SDK documentation (Python and TypeScript)
  • Blog 004 for agent loops that consume MCP tools

Next in Series

Blog 004: AI Agents Explained: Loops, Guardrails, and Production Harnesses

Top comments (0)