Every AI demo you've ever seen has the same problem: the model talks about doing things, but it doesn't actually do them. You ask it to check your calendar, it describes what it would do. You ask it to send an email, it writes the email but doesn't send it. That's not an agent — that's a sophisticated autocomplete.
The gap between "describes" and "does" is tool access. And the standard way to give AI models tool access in 2026 is MCP — Model Context Protocol.
This guide gets you from zero to a working MCP connection. Not theory. Not marketing. The actual plumbing.
MCP is a protocol, not a framework. Think HTTP — a defined way for two systems to talk to each other. In this case, the two systems are a language model (Claude, GPT, Gemini, etc.) and a tool (database, API, filesystem, whatever you need).
The protocol defines:
That's it. The rest is implementation.
The reason it matters: without a standard protocol, every model-to-tool integration is custom glue code. With MCP, you write the tool once and any MCP-compatible model can use it.
[AI Model] <-- MCP --> [MCP Server] <---> [Your Tool/API/Database]
The MCP Server is the middle layer. It:
1. Exposes your tools via the MCP spec
2. Receives tool call requests from the model
3. Executes the actual operation against your system
4. Returns structured results back to the model
The model doesn't call your database directly. It calls the MCP Server, which handles the translation.
MCP has official SDKs for Python and TypeScript. Use the one that matches your server environment.
pip install mcp
npm install @modelcontextprotocol/sdk
Here's a minimal MCP server that exposes a single tool: "get current weather for a city."
from mcp.server import MCPServer
from mcp.types import Tool, CallToolResult
server = MCPServer(name="weather-server")
@server.list_tools()
def get_weather_tool() -> Tool:
return Tool(
name="get_weather",
description="Get current weather for a city",
inputSchema={
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "City name"
}
},
"required": ["city"]
}
)
@server.call_tool()
def handle_weather(city: str) -> CallToolResult:
temp = fetch_weather_from_api(city) # Your function
return CallToolResult(
content=[{"type": "text", "text": f"{city}: {temp}°C"}]
)
server.run() # Starts stdio server
This server communicates over stdio — meaning it can be run as a subprocess by any MCP-compatible client. That's the key: stdio means no network configuration, no ports, just stdin/stdout JSON messages.
Each provider handles MCP client connections differently. Here's the pattern for the major ones:
**Anthropic (Claude via SDK):**
from anthropic import Anthropic
client = Anthropic()
The configuration typically lives in a `mcp.json` file that tells the client which server to spawn and how:
{
"mcpServers": {
"weather": {
"command": "python",
"args": ["/path/to/your/server.py"]
}
}
}
**OpenAI (via Agents SDK):**
from openai import OpenAI
client = OpenAI()
client.mcp.servers.configure("weather", command="python", args=["/path/to/server.py"])
**The pattern is the same everywhere:** point the client at the server script, and the client handles spawning the subprocess and communicating over stdio.
The best way to verify your MCP setup works: ask the model to use the tool and describe what it does.
Prompt: "What's the weather in Berlin?"
The model should:
1. Recognize it has a `get_weather` tool available
2. Call it with `{"city": "Berlin"}`
3. Receive `{"content": [{"text": "Berlin: 18°C"}]}`
4. Respond with that information
If the model describes what it would do but doesn't actually call the tool, the MCP server isn't being recognized. Check:
**Wrong JSON Schema format.** MCP uses JSON Schema for tool definitions. A malformed schema silently fails — the tool just won't appear to the model. Validate your schema before testing.
**Stdio buffer issues.** Some MCP implementations have small stdout buffers. If your tool returns large payloads, flush explicitly or use chunked responses.
**Server crashes silently.** If the subprocess dies, the model gets no response. Add process monitoring and restart logic for production MCP servers.
**Model doesn't support tool calling.** Not all models have tool-calling enabled by default. Check your provider's configuration — you often need to explicitly enable it in the API call options.
The value of MCP isn't the weather tool. It's that once you have one MCP server running, adding more tools is trivial. You need email? Write an MCP server. Database? MCP server. GitHub API? MCP server. Each one becomes available to the model without changing the model's code — you just register the new server.
That's the architectural shift: your AI stops being a chatbot with a fixed skill set and becomes a runtime that can access any tool you can describe in the MCP spec. The model doesn't change. The tools multiply.
That's the difference between an AI that helps and an AI that works.