MCP · Referenz · Cheatsheet
Model Context Protocol — Spickzettel
Kompakte Referenz für Bau & Workshop. Stabile Spec: 2025-11-25. Stets gegen modelcontextprotocol.io prüfen.
Architektur
Host (App + LLM, schwer) → Client (1:1 pro Server, Sicherheitsgrenze) → Server (Fähigkeit, leicht).
Transport-agnostisch, gebaut auf JSON-RPC 2.0, stateful Session. Ziel: N+M statt N×M Integrationen.
Die 3 Primitive
| Primitive | Steuert | Wie |
|---|---|---|
| Tool | Modell | Aktion (POST) |
| Resource | App | Lesen (GET) |
| Prompt | User | Vorlage/Makro |
Methoden: tools/list·call,
resources/list·read·subscribe, prompts/list·get.
Handshake (immer zuerst, 3 Nachrichten)
C→S {"jsonrpc":"2.0","id":1,"method":"initialize",
"params":{"protocolVersion":"2025-06-18",
"capabilities":{...},"clientInfo":{"name":...,"version":...}}}
S→C {"jsonrpc":"2.0","id":1,"result":{"protocolVersion":...,
"capabilities":{"tools":{},"resources":{},"prompts":{}},"serverInfo":{...}}}
C→S {"jsonrpc":"2.0","method":"notifications/initialized"} // keine id!
Capability Negotiation: beide deklarieren vorab, was sie können → Erweiterbarkeit. Nicht deklariert = nicht nutzbar.
JSON-RPC: 3 Nachrichten-Sorten
| Sorte | id? | Antwort? |
|---|---|---|
| Request | ja | ja |
| Response | ja (gleich) | – |
| Notification | nein | nein |
Transports
STDIO — Client startet Server als Subprozess; stdin/stdout, newline-delimited. stdout = nur MCP! kein print(). Lokal, simpel.
Streamable HTTP — ein Endpunkt,
POST (+ optional SSE), GET für Server-Stream, Mcp-Session-Id. Remote/Prod.
Origin prüfen, localhost-Bind, Auth.
Python-Server (FastMCP)
pip install "mcp[cli]" # oder: uv add "mcp[cli]"
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("Demo")
@mcp.tool()
def add(a: int, b: int) -> int:
"""Addiere zwei Zahlen.""" # Docstring → Beschreibung, Type-Hints → Schema
return a + b
@mcp.resource("note://{title}")
def read_note(title: str) -> str: ... # lesbarer Kontext
@mcp.prompt()
def summarize(title: str) -> str: ... # User-Workflow
if __name__ == "__main__":
mcp.run(transport="stdio") # oder "streamable-http"
Testen — MCP Inspector
uv run mcp dev server.py
# oder:
npx @modelcontextprotocol/inspector \
uv run server.py
Connect → Tools → List → Run. Zeigt den echten Wire ohne Agent.
Anbinden — Claude Code
# STDIO (lokal):
claude mcp add demo -- uv run server.py
# HTTP (remote):
claude mcp add --transport http \
demo https://host/mcp
claude mcp list # Status
claude mcp get demo # Details
.mcp.json (teilbar im Repo, Scope project)
{ "mcpServers": {
"demo": { "command": "uv", "args": ["run", "/pfad/server.py"], "env": {"KEY":"..."} }
} }
// Remote: "type": "http" (Alias "streamable-http") + "url": "https://host/mcp"
// Scopes: local (privat) · project (.mcp.json, Team) · user (alle Projekte)
Merksätze für den Workshop
- MCP standardisiert, wie ein Agent ein Tool entdeckt & aufruft — N×M → N+M.
- Host schwer, Server leicht → 20-Zeilen-Server.
- Tool/Resource/Prompt = Modell-/App-/User-gesteuert.
- Es ist „nur“ JSON-RPC über stdio oder HTTP.
Quellen: MCP Specification (Architecture, Lifecycle, Transports, Server) · Python SDK README · Claude Code MCP-Docs. Lektionen 1–7 im Ordner lessons/.