REST standardized how services talk to each other. GraphQL standardized how clients query data. MCP is standardizing how AI models interact with tools, data, and systems.

If you are building agentic AI -- systems where language models make decisions, call tools, and affect state -- you are building an integration layer. That layer is the most important part of your architecture. Not the model. Not the prompt. The layer that stands between the model's intentions and the world's state.

We have been using MCP in production across multiple systems. This article is about what we learned: why MCP exists, how it compares to what came before, where the security boundaries live, and the patterns that survive contact with real traffic.


I. The Problem MCP Solves

Every team building with AI models hits the same wall: tool integration.

The model needs to read a database. It needs to call an API. It needs to access files. It needs to search a knowledge base. Each integration is a custom job: write a JSON schema, wire up authentication, handle errors, parse responses, pray the model calls it correctly.

Multiply this by ten tools and three models and you have a combinatorial mess. Each model has its own function-calling format. Each tool has its own authentication pattern. Each integration is bespoke. Testing is manual. Auditing is aspirational.

Before MCP:

Model A ---custom--> Tool 1 (custom auth, custom schema) Model A ---custom--> Tool 2 (different auth, different schema) Model B ---custom--> Tool 1 (rewire everything) Model B ---custom--> Tool 2 (rewire everything again)

N models x M tools = N*M integrations

MCP collapses this. It defines a standard protocol so that any model can talk to any tool server, and any tool server can serve any model. The integration matrix becomes additive, not multiplicative.

After MCP:

Model A --MCP--> Server 1 (tools: DB, files) Model A --MCP--> Server 2 (tools: API, search) Model B --MCP--> Server 1 (same protocol) Model B --MCP--> Server 2 (same protocol)

N models + M servers = N+M integrations

This is the same shift REST brought to service-to-service communication. A shared protocol that makes the integration cost predictable.


II. The Protocol: What MCP Actually Defines

MCP is a JSON-RPC 2.0 based protocol with three core capabilities:

Tools

Tools are functions the model can invoke. Each tool has a name, a description (which the model reads to decide when to use it), and a JSON Schema for its parameters. The server registers tools; the client (the model's runtime) discovers them and presents them to the model as available actions.

{
  "name": "query_database",
  "description": "Execute a read-only SQL query against the analytics database",
  "inputSchema": {
    "type": "object",
    "properties": {
      "query": {
        "type": "string",
        "description": "SQL SELECT query (read-only)"
      }
    },
    "required": ["query"]
  }
}

The model sees this schema and decides -- based on the user's request and its own reasoning -- whether and how to call the tool. The MCP client sends the invocation to the server. The server executes it and returns a structured result.

Resources

Resources are data the model can read. Files, database records, API responses, configuration -- anything the model might need as context. Resources have URIs and can be listed, read, and subscribed to for updates.

This is the "context" in Model Context Protocol. Instead of cramming everything into the system prompt, the model can pull what it needs, when it needs it.

Prompts

Prompts are reusable templates that servers can offer to clients. A database server might offer a "schema exploration" prompt. A documentation server might offer a "code review" prompt. These are optional but useful for standardizing common workflows across teams.

The transport layer

MCP supports two transports: stdio (for local processes) and HTTP with SSE (for remote servers). The stdio transport is simple: launch a process, send JSON-RPC over stdin/stdout. The HTTP transport adds network capability with Server-Sent Events for streaming.

stdio transport (local):

Client --stdin/stdout--> MCP Server Process

HTTP transport (remote):

Client --HTTP POST--> MCP Server --SSE--> Client

Most production setups use stdio for local tools (filesystem, database) and HTTP for remote services. The protocol is the same; the transport is an implementation detail.


III. MCP vs REST vs GraphQL: Different Problems, Different Eras

This is not a "which is better" comparison. These protocols solve different problems for different consumers.

REST standardized service-to-service communication. The consumer is a programmer who writes code against a known API. The API is designed for human comprehension: endpoints are named, documented, and versioned. The consumer knows what it wants before making the request.

GraphQL standardized client-driven data queries. The consumer is a frontend developer who needs flexible access to a data graph. The API is designed for query composition: the client specifies exactly what data it needs. The consumer knows the schema and constructs queries against it.

MCP standardizes model-to-tool interaction. The consumer is a language model that discovers tools at runtime and decides which to use based on natural language reasoning. The API is designed for machine comprehension: tool descriptions are written so models can understand when and how to use them.

Protocol   Consumer     Discovery      Selection
  -------------------------------------------------------
  REST       Programmer   Documentation  Code-time choice
  GraphQL    Frontend     Schema intro   Query composition
  MCP        LLM          Runtime list   Reasoning-based

The key insight: MCP tools must be self-describing in a way that models can reason about. A REST endpoint named /api/v2/analytics/query is fine for a programmer who read the docs. An MCP tool needs a description like "Execute a read-only SQL query against the analytics database. Use this when the user asks about metrics, usage patterns, or historical data." The description is part of the interface, not a comment.


IV. Security Boundaries: The MCP Server as Chokepoint

This is where MCP earns its keep in production. The MCP server is not just a bridge between the model and tools. It is a security boundary.

Principle: The model holds no secrets

The model never sees database credentials, API keys, or authentication tokens. The MCP server holds secrets. The model holds tool schemas. When the model invokes a tool, the server authenticates the request, applies the credentials, executes the action, and returns the result. The model sees the output, not the plumbing.

{
  "mcpServers": {
    "database": {
      "command": "mcp-server-postgres",
      "args": ["--read-only", "--connection", "$DB_URL"],
      "env": { "DB_URL": "postgres://readonly:***@db.internal/analytics" }
    }
  }
}

The $DB_URL is resolved server-side. The model never sees it.

Principle: Scope access per server

Each MCP server should expose the minimum tools needed for its purpose. A reporting server exposes read-only database queries. A file server exposes read access to specific directories. A publishing server exposes write access to a specific CMS.

Do not build one MCP server that can do everything. Build many servers that can each do one thing well. This is the principle of least privilege applied to AI tool access.

Principle: Audit everything

Every tool invocation passes through the MCP server. That makes it the natural audit point. Log:

  • Timestamp
  • Tool name and parameters
  • Calling model/agent identity
  • User context (who triggered the task)
  • Result summary
  • Latency and token cost

This audit trail is not just for debugging. It is for compliance. The EU AI Act requires logging and traceability for high-risk AI systems. MCP gives you the chokepoint where that logging naturally lives.

Principle: Rate limit at the server

The model does not know it is expensive. A model in a retry loop will happily call a tool fifty times. The MCP server should enforce rate limits per tool, per agent, per task. When the limit is hit, return a structured error: "Rate limit exceeded. You have used 10 of 10 allowed calls to query_database for this task."

The model can reason about this feedback and adjust its approach. This is not a crash. It is a constraint that the agent can work within.


V. Production Patterns

Pattern 1: The read-only analyst

The most common production MCP pattern. A model has read-only access to databases and files. It answers questions by querying data, not by modifying state.

User: "What was our conversion rate last week?"
       |
  Agent --MCP--> database server (read-only)
       |         -> SELECT ... FROM events WHERE ...
       |
  Agent: "Last week's conversion rate was 3.2%, up from 2.8%."

Security profile: low risk. The model cannot modify data. The worst case is an expensive query, which the server rate-limits.

Pattern 2: The scoped writer

The model can write to a specific, bounded system. A content management system. A task tracker. A deployment pipeline. Write access is scoped to specific operations with validation.

{
  "name": "create_draft",
  "description": "Create a new draft article in the CMS",
  "inputSchema": {
    "type": "object",
    "properties": {
      "title": { "type": "string", "maxLength": 200 },
      "body": { "type": "string", "maxLength": 50000 },
      "status": { "type": "string", "enum": ["draft"] }
    },
    "required": ["title", "body"]
  }
}

Note: the status field is constrained to "draft". The model cannot publish directly. A human reviews and publishes. The schema is the guardrail.

Pattern 3: The multi-server orchestrator

Complex tasks require multiple MCP servers. The agent queries a database, reads documentation, and updates a task tracker -- each through a different server with different permissions.

Agent --MCP--> database (read-only)
       --MCP--> documentation (read-only)
       --MCP--> task-tracker (scoped write)
       --MCP--> slack-notifier (scoped write)

Each server is independently auditable. Each server has its own rate limits and permissions. The agent orchestrates; the servers enforce.

Pattern 4: The gateway server

For enterprise deployments with many tools, a gateway MCP server aggregates multiple backends behind a single interface. The gateway handles authentication, routing, and cross-cutting concerns (logging, rate limiting, circuit breaking).

Agent --MCP--> Gateway Server ---> Backend A
                                ---> Backend B
                                ---> Backend C

This adds a layer but simplifies client configuration and centralizes security policy.


VI. Building MCP Servers: Practical Notes

Keep descriptions honest

The tool description is the most important field. Models use it to decide when to call the tool. A vague description produces incorrect tool selection. A description that promises more than the tool delivers produces runtime errors.

Write descriptions as if you are explaining the tool to a competent colleague who has never seen your codebase. Be specific about what the tool does, what it does not do, and when it should be used.

Validate inputs strictly

The model will hallucinate parameters. It will send strings where you expect numbers. It will omit required fields. It will invent field names. Your server must validate every input against the schema and return helpful error messages.

A good error message: "Parameter 'date_range' must be an object with 'start' and 'end' string fields in ISO 8601 format. Received: string."

A bad error message: "Invalid input."

The model can self-correct with good feedback. It cannot self-correct with bad feedback.

Return structured results

Models reason better about structured data than about prose. Return JSON objects with clear field names, not paragraphs of text.

{
  "result": {
    "rows_returned": 42,
    "data": [...],
    "query_time_ms": 23,
    "note": "Results limited to 100 rows per policy"
  }
}

Handle errors as data

Tool errors are not exceptional in agentic systems. They are normal. A query that returns no results. A rate limit that is hit. A permission that is denied. Return these as structured error responses, not as exceptions that crash the agent.


VII. The Enterprise Adoption Path

Start with read-only

Every enterprise MCP adoption should start with read-only servers. Connect the model to databases, documentation, and monitoring systems. Let teams build confidence that the model uses tools correctly before granting write access.

Add write access behind gates

When read-only is proven, add scoped write access with human-in-the-loop approval. The model proposes actions; humans approve or reject. Track approval rates, rejection reasons, and error rates. When the error rate is consistently low, consider reducing the approval gate to sampling review.

Standardize across teams

The power of MCP is the shared protocol. If every team builds their own tool integration, you lose the composability benefit. Publish internal MCP server templates. Define naming conventions for tools. Establish security baselines for server configuration.

Monitor tool usage patterns

MCP servers generate rich telemetry: which tools are called, how often, by which agents, with what success rates. This data is gold for understanding how AI is actually being used in your organization -- and where it is struggling.


VIII. What MCP Does Not Solve

MCP is an integration protocol. It does not solve:

  • Model quality. A bad model with good tools is still a bad system.
  • Prompt engineering. MCP provides tools; you still need to instruct the model on how to use them wisely.
  • Eval. MCP does not tell you whether the model is using tools correctly. You need eval harnesses for that.
  • Multi-model orchestration. MCP connects a model to tools. Coordinating multiple models is a higher-level concern.
  • Data governance. MCP enforces access at the server level, but the decision about what data the model should access is yours.

MCP is a plumbing standard. Like REST, its value is in what it enables, not in what it does by itself.


IX. Why This Matters Now

The AI industry is at the integration inflection point. The model capability curve has outrun the integration infrastructure. Models can reason about complex tasks, plan multi-step workflows, and use tools effectively -- but connecting them to the tools they need is still a manual, fragile, team-by-team effort.

MCP is the most credible attempt to standardize this layer. It is not the only attempt -- OpenAI has function calling, Google has extensions, LangChain has tool abstractions. But MCP has three advantages: it is model-agnostic, it is open-source, and it defines security boundaries as a first-class concern.

We use MCP because it lets us build once and connect any model. We use it because the server-as-chokepoint architecture gives us the audit and security properties we need. We use it because it is boring in the right ways -- a protocol, not a framework; a standard, not an opinion.

The teams that build good MCP infrastructure now will have a compounding advantage. Every new tool, every new model, every new use case plugs into existing infrastructure instead of requiring a new integration. That is the promise of standards. MCP is delivering on it.


References

  1. Model Context Protocol. Specification. spec.modelcontextprotocol.io
  2. Anthropic. Introducing the Model Context Protocol. anthropic.com
  3. MCP. Official Server Implementations. github.com/modelcontextprotocol/servers
  4. JSON-RPC 2.0 Specification. jsonrpc.org
  5. Fielding, R. (2000). Architectural Styles and the Design of Network-Based Software Architectures. Doctoral dissertation, UC Irvine.
  6. GraphQL Foundation. GraphQL Specification. graphql.org
  7. European Parliament. EU AI Act -- Logging and Traceability Requirements. artificialintelligenceact.eu
  8. OWASP. LLM Top 10. owasp.org
  9. Anthropic. Tool Use Documentation. docs.anthropic.com
  10. OpenAI. Function Calling. platform.openai.com
  11. Google. Gemini Function Calling. ai.google.dev
  12. NIST. AI Risk Management Framework. nist.gov