The Model Context Protocol (MCP) is an open standard for exposing tools, resources, and prompts to any compatible LLM client. Write a server once; every MCP-aware app can use it. This is the deep-dive companion to Building MCP Tools for a Local LLM.
The three primitives
| Primitive | Is | Example |
|---|---|---|
| Tools | Functions the model can call | get_weather(city) |
| Resources | Readable data/context | a file, a DB row |
| Prompts | Reusable prompt templates | "summarize this ticket" |
A minimal tool server (Python)
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("demo")
@mcp.tool()
def add(a: int, b: int) -> int:
"""Add two numbers."""
return a + b
if __name__ == "__main__":
mcp.run() # stdio transport by default
What makes a good MCP server
- Clear tool names + typed args + docstrings — the model picks tools from these (Agentic Tool-Use Loops).
- Small, composable tools beat one giant do-everything tool.
- Return errors as data so the model can recover.
- Choose transport: stdio (local subprocess) or HTTP+SSE (networked).
Running it reliably
Run servers as supervised services that auto-restart and survive logout — see Building MCP Servers as systemd User Services.
Related: Building MCP Tools for a Local LLM · Building MCP Servers as systemd User Services · Agentic Tool-Use Loops