AIStackInsightsAIStackInsights
HomeBlogCategoriesAboutNewsletter
AIStackInsightsAIStackInsights

Practical AI insights — LLMs, machine learning, prompt engineering, and the tools shaping the future.

Content

  • All Posts
  • LLMs
  • Tutorials
  • AI Tools

Company

  • About
  • Newsletter
  • RSS Feed

Connect

© 2026 AIStackInsights. All rights reserved.

Tutorials

MCP: The Developer's Guide to the Protocol Quietly Rewiring AI Applications

Model Context Protocol (MCP) is becoming the USB-C of AI integration — a single standard for connecting LLMs to any tool, database, or API. Here's the architecture, the primitives, and how to build your first server.

UnbreakableCloud TeamMarch 16, 202611 min read
mcpmodel-context-protocolai-agentsllmtoolsapiclaudecursor

If you've been building LLM-powered applications for more than six months, you've almost certainly hit the same wall: getting your AI to actually do things — query your database, read your files, call your API — requires bespoke glue code for every combination of model and tool. Each integration is its own adventure in prompt formatting, context limits, and error handling. And every time you want to switch models or add a new tool, you rebuild the plumbing.

Model Context Protocol (MCP) is the attempt to fix this at the protocol level. Launched by Anthropic as an open standard in late 2024, MCP has rapidly become the most consequential AI integration standard since OpenAI popularized function calling. Claude, ChatGPT, VS Code Copilot, Cursor, and a growing ecosystem of tools all support it — which means you can build once and integrate everywhere.

This guide explains what MCP actually is under the hood, how its architecture works, what the key primitives are, and how to start building with it today.


The Problem MCP Solves

Before MCP, connecting an LLM to an external system looked something like this:

  1. Decide on a function calling schema (OpenAI format? Anthropic format? Something custom?)
  2. Write a wrapper that maps your tool to that schema
  3. Handle the model's response, parse out the tool call, execute it, and stuff the result back into context
  4. Repeat for every tool, every model, every application

The result was a fragmented ecosystem where the same tool — say, a GitHub integration — needed to be reimplemented differently for Claude Desktop, for LangChain, for a custom agent framework, and for whatever VS Code extension you were using. Thousands of engineering hours, reinventing the same wheel.

MCP's framing is direct: it's "the USB-C of AI applications." Just as USB-C standardized physical connections across devices, MCP standardizes the protocol for connecting AI models to external systems. Build one MCP server for your database, and every MCP-compatible AI client can use it immediately, without any per-client integration work.


Architecture Overview

MCP follows a client-server architecture with three key participants:

MCP Host

The AI application that the user interacts with — Claude Desktop, VS Code with Copilot, Cursor, or a custom agent you've built. The host orchestrates connections to one or more MCP servers and manages how the AI uses the context they provide.

MCP Client

A component inside the host that maintains a dedicated connection to a single MCP server. If your host connects to three servers (say: filesystem, database, and GitHub), it creates three separate client instances — one per server.

MCP Server

A program that exposes data, tools, or workflows to MCP clients. Servers can run locally (on the same machine, communicating via stdio) or remotely (over HTTP). The server doesn't know or care which host is using it — it just speaks the protocol.

┌──────────────────────────────────┐
│         MCP Host                 │
│  (Claude Desktop / VS Code /     │
│   your custom agent)             │
│                                  │
│  ┌──────────┐  ┌──────────┐      │
│  │ Client 1 │  │ Client 2 │  ... │
│  └────┬─────┘  └────┬─────┘      │
└───────┼─────────────┼────────────┘
        │             │
   ┌────▼─────┐  ┌────▼──────┐
   │ MCP      │  │ MCP       │
   │ Server A │  │ Server B  │
   │ (local)  │  │ (remote)  │
   └──────────┘  └───────────┘

Two Layers

MCP separates concerns into two protocol layers:

Data Layer — the JSON-RPC 2.0 based protocol that defines message structure: lifecycle management, capability negotiation, and the core primitives (tools, resources, prompts). This is where the semantics live.

Transport Layer — the communication mechanism: local servers use STDIO (the server is a subprocess, communicating via stdin/stdout), while remote servers use Streamable HTTP. The transport layer handles connection establishment, message framing, and authorization.

This separation matters: you write your server logic once against the data layer, and choose a transport based on your deployment context.


The Three Core Primitives

Everything in MCP flows through three primitives. Understanding these is the key to understanding what you can build.

1. Tools

Tools are functions the AI can call — the closest equivalent to OpenAI's function calling. A tool has a name, a description (which the model reads to decide when to use it), and an input schema.

{
  "name": "query_database",
  "description": "Execute a read-only SQL query against the production database. Use this to look up records, aggregate data, or answer questions about stored information.",
  "inputSchema": {
    "type": "object",
    "properties": {
      "sql": {
        "type": "string",
        "description": "The SQL query to execute. Must be SELECT only."
      }
    },
    "required": ["sql"]
  }
}

When the model decides to call this tool, it sends a tools/call request to your server with the SQL string. Your server executes the query and returns the result. The host injects that result back into the model's context, and the conversation continues.

Critical design principle: Tool descriptions are prompt engineering. The model decides which tools to use (and how) based entirely on your descriptions. Write them like you're writing docs for a smart junior developer who has never seen your system — specific, unambiguous, and explicit about what the tool does not do.

2. Resources

Resources are data the AI can read — files, database records, API responses, live system state. Unlike tools (which take action), resources are read-only context sources.

Each resource has a URI, a MIME type, and content:

{
  "uri": "file:///home/user/project/README.md",
  "mimeType": "text/markdown",
  "text": "# My Project\n..."
}

Resources can be static (always the same content) or dynamic (generated on read, like a live database query). They can also support subscriptions: a client can subscribe to a resource and receive notifications when it changes — useful for things like tailing a log file or watching for new database records.

The host decides which resources to inject into context. This gives you a clean separation: your server exposes what's available, and the host decides what the model sees.

3. Prompts

Prompts are reusable, parameterized prompt templates — pre-built workflows that users or applications can invoke.

{
  "name": "code_review",
  "description": "Review a pull request diff for bugs, security issues, and style violations",
  "arguments": [
    {
      "name": "diff",
      "description": "The git diff to review",
      "required": true
    },
    {
      "name": "language",
      "description": "Programming language of the changed files",
      "required": false
    }
  ]
}

Prompts let you encode domain-specific workflows — the "code review" procedure, the "incident triage" checklist, the "data analysis" starting point — and surface them as first-class primitives in any MCP client. Users can invoke them directly; hosts can include them automatically.


Building Your First MCP Server (Python)

Let's walk through a minimal MCP server that exposes a single tool — a weather lookup — using the official Python SDK.

Install:

pip install mcp

Server:

from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent
import httpx
 
app = Server("weather-server")
 
@app.list_tools()
async def list_tools() -> list[Tool]:
    return [
        Tool(
            name="get_weather",
            description="Get current weather conditions for a city. Returns temperature, conditions, and humidity.",
            inputSchema={
                "type": "object",
                "properties": {
                    "city": {
                        "type": "string",
                        "description": "City name, e.g. 'San Francisco' or 'London'"
                    }
                },
                "required": ["city"]
            }
        )
    ]
 
@app.call_tool()
async def call_tool(name: str, arguments: dict) -> list[TextContent]:
    if name == "get_weather":
        city = arguments["city"]
        async with httpx.AsyncClient() as client:
            resp = await client.get(
                f"https://wttr.in/{city}?format=3"
            )
            return [TextContent(type="text", text=resp.text)]
    raise ValueError(f"Unknown tool: {name}")
 
async def main():
    async with stdio_server() as (read_stream, write_stream):
        await app.run(read_stream, write_stream, app.create_initialization_options())
 
if __name__ == "__main__":
    import asyncio
    asyncio.run(main())

Register with Claude Desktop by adding to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or the equivalent on your OS:

{
  "mcpServers": {
    "weather": {
      "command": "python",
      "args": ["/path/to/weather_server.py"]
    }
  }
}

Restart Claude Desktop. The tool is now available — Claude will automatically call it when you ask about weather in any city.


Local vs. Remote Servers

Local servers (STDIO) run as a subprocess of the host. They're simple to build and deploy, but they only serve one client at a time. Good for personal tools, development workflows, and anything that needs access to local files or system resources.

Remote servers (Streamable HTTP) run as web services and can serve many clients simultaneously. They're the right choice for:

  • Multi-user applications
  • SaaS tools exposing MCP endpoints
  • Enterprise integrations where the data lives in the cloud
  • Any scenario where you can't install software on the client machine

Remote servers also handle authorization via OAuth 2.0 — the MCP spec includes a full auth flow so your server can verify that the requesting client has the right permissions before exposing sensitive data.


What's Already in the Ecosystem

One of MCP's biggest advantages is an already-rich server ecosystem. The official reference implementations include servers for:

  • Filesystem — read, write, search local files
  • GitHub — repos, issues, PRs, code search
  • PostgreSQL — schema inspection, read-only queries
  • Slack — channel history, sending messages
  • Brave Search — web search results
  • Puppeteer — browser automation
  • Sentry — error tracking and issue management
  • Memory — persistent key-value storage across sessions

Beyond the official list, the community has built MCP servers for Notion, Linear, Jira, Snowflake, Stripe, and dozens of other services. Tools like VS Code Copilot, Cursor, and Zed all have MCP support, meaning you can pull your entire development context — code, issues, error logs, database schema — into your AI assistant without writing any glue code.


Practical Patterns and Gotchas

A few things worth knowing before you build in earnest:

Context is still finite. MCP makes it easy to expose data, but you still need to think about what you actually inject into context. A resource that returns a 500KB database dump will burn your context window. Design your tools to return focused, relevant results — not everything, just what the model needs to answer the current question.

Tool descriptions are not free. Every tool you expose is included in the system prompt sent to the model. If you have 40 tools, you're paying tokens for 40 descriptions on every call. Be deliberate about what you expose, and consider grouping related functionality into fewer, more general tools.

Error handling matters a lot. When a tool call fails, the model gets your error message as context and has to decide what to do next. Write descriptive error messages — not "query failed" but "query failed: column 'user_id' does not exist in table 'orders'. Available columns are: id, customer_id, product_id, created_at." The model can often self-correct if the error message is good enough.

Local servers have security implications. An MCP server that can read arbitrary files or execute shell commands is powerful — and dangerous if a malicious prompt can manipulate it into accessing things it shouldn't. Apply the principle of least privilege: expose only what's needed, and validate inputs carefully.

The Inspector is your best friend. The MCP Inspector is a debugging tool that lets you test your MCP server interactively — invoke tools, browse resources, inspect the full JSON-RPC exchange. Use it before you plug your server into any host.


Where MCP Is Going

MCP's current momentum is real. OpenAI added MCP support to ChatGPT. Microsoft baked it into VS Code Copilot. Cursor built its entire context system around it. The protocol is on a trajectory to become the de-facto standard for AI tool integration the same way REST became the de-facto standard for web APIs.

What that means for developers: investing in MCP today is not a bet on Anthropic's ecosystem. It's a bet on an open standard with broad, accelerating adoption. MCP servers you build now will work with Claude, ChatGPT, and whatever model is leading the benchmarks six months from now.

The immediate opportunity: most enterprise systems still have no MCP server. Internal databases, proprietary APIs, custom data pipelines — the organizations that build MCP servers for their internal tooling first will have AI assistants that are genuinely useful for employees, not just generically capable. That gap is closing fast, and the developers who understand the protocol today will be the ones closing it.


Getting Started

  • Official docs: modelcontextprotocol.io
  • Python SDK: pip install mcp
  • TypeScript SDK: npm install @modelcontextprotocol/sdk
  • Reference servers: github.com/modelcontextprotocol/servers
  • Inspector: github.com/modelcontextprotocol/inspector
  • Community servers: mcpjam.com and the #mcp channels on relevant Discord servers

If you build something worth sharing, drop it in the comments — the MCP server ecosystem is still early enough that a well-built integration can get real visibility.

Share:

Related Posts

Tutorials

Building Production RAG Applications: A Complete Guide

Learn how to build Retrieval-Augmented Generation systems that actually work in production — from chunking strategies to evaluation frameworks.

Read more
Weekly AI insights

Join developers getting LLM tips, ML guides, and tool reviews.

Ad Slot:

Sponsor this space

Reach thousands of AI engineers weekly.