Protokoll · Tools / Resources / Prompts · Debug & Deploy · Wissensbasis-Praxis
Backend- und AI-Entwickler mit Python- oder TypeScript-Grundlagen kennen das Problem: Claude und GPT sind leistungsfähig, greifen aber nicht auf Ihre Datenbank, interne APIs oder lokale Dateien zu — es fehlt ein standardisierter Kanal für externe Tools. Das Model Context Protocol (MCP) von Anthropic ist ein offenes Protokoll, über das AI-Clients (Cursor, Claude Desktop) per JSON-RPC mit Ihrem Server sprechen. Nach diesem Artikel können Sie eigenständig einen produktionsreifen MCP Server entwickeln und deployen: Architektur → Umgebung → Hello World → Tools / Resources / Prompts → HTTP-Transport → Debug & Tests → Docker → Wissensbasis-Projekt → Ökosystem 2026.
Selbst starke Modelle kennen weder Ihre CRM-Kunden noch die Logs von gestern Nacht. Der Branchenpfad ist klar: Function Calling → Plugins → MCP. Die ersten beiden sind oft vendor-spezifisch; MCP standardisiert, welche Tools eine KI entdeckt und wie sie sie aufruft — einmal schreiben, mehrere Clients nutzen.
Schmerz: Claude / GPT soll DB, API und Dateien nutzen — jedes Format ist anders.
Szenario: In Cursor Markdown-Notizen lesen, in Claude Desktop GitHub-Issues abfragen.
Versprechen: Vom leeren Verzeichnis zum deploybaren Server — mit Code und Fehlertabelle.
Anthropic veröffentlichte MCP im November 2024, um KI-Tool-Kommunikation zu standardisieren und das N×M-Adapter-Problem zu lösen. Mehr Kontext in unserem MCP-HTTP-Vergleich.
Client ↔ Server: Der Client sitzt bei der KI (Claude Desktop, Cursor); der Server liefert Fähigkeiten per JSON-RPC:
Tools: Aufrufbare Funktionen — Suche, Berechnung, DB-Query.
Resources: Lesbare Daten — Dateien, URLs, Konfiguration.
Prompts: Vordefinierte, parametrisierbare Prompt-Vorlagen.
Basis: JSON-RPC 2.0. Transport: stdio (lokaler Subprozess, Cursor-Standard) oder HTTP + SSE / Streamable HTTP (Remote). Lebenszyklus: Handshake → initialize → Request/Response → Shutdown.
| Dimension | MCP | OpenAI Function Calling | LangChain Tools |
|---|---|---|---|
| Standard | Offenes Protokoll | Vendor-proprietär | Framework-gebunden |
| Transport | stdio / HTTP | HTTP | HTTP |
| Cross-Model | Ja | Nein | Teilweise |
| Resources / Prompts | Nativ | Nein | Nein |
| Ökosystem 2026 | 10.000+ Server | Reif | Reif |
Python (mcp, FastMCP) für Einsteiger; TypeScript (@modelcontextprotocol/sdk) für Frontend/Full-Stack. Dieser Artikel nutzt Python, TS als Referenz.
# Python python -m venv .venv && source .venv/bin/activate pip install mcp httpx pydantic # TypeScript (Referenz) npm init -y && npm install @modelcontextprotocol/sdk
my-mcp-server/ ├── server.py # Einstieg ├── tools/ # calculator.py, web_search.py ├── resources/ # file_reader.py ├── prompts/ # templates.py ├── tests/test_tools.py ├── pyproject.toml └── README.md
MCP Inspector: npx @modelcontextprotocol/inspector python server.py
Claude Desktop: claude_desktop_config.json bearbeiten.
Cursor: Settings → MCP → command + args hinzufügen.
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("my-first-server")
@mcp.tool()
def say_hello(name: str) -> str:
"""Begrüßt eine Person"""
return f"Hello, {name}! Das ist Ihr erster MCP-Tool."
if __name__ == "__main__":
mcp.run()Nach python server.py in Cursor {"command":"python","args":["/abs/path/server.py"]} eintragen — say_hello sollte in der Tool-Liste erscheinen.
Absolute Pfade zu server.py und venv-Python.
Nach Codeänderung MCP-Verbindung neu starten oder Cursor-Fenster schließen.
Tool-Aufruf im Chat explizit anfordern und registrierten Kontext prüfen.
Signatur = Dokumentation: Typen, Rückgabe und Docstring steuern die Tool-Auswahl. Namen: snake_case, Verb zuerst (search_web). Fehler als strukturiertes JSON statt nackter Exceptions.
from pydantic import BaseModel, Field
class SearchInput(BaseModel):
query: str = Field(description="Suchbegriff")
max_results: int = Field(default=5, description="Max. Treffer")
language: str = Field(default="de", description="Ergebnissprache")
@mcp.tool()
def web_search(input: SearchInput) -> list[dict]:
"""Websuche, liefert Ergebnisliste"""
...| Tool | Zweck | Hinweis |
|---|---|---|
| Rechner | Mathe-Ausdrücke | ast.literal_eval, kein eval |
| Datei-I/O | Lokal lesen/schreiben | Whitelist, Pfad-Normalisierung |
| HTTP | Externe APIs | Timeout, Retry, Größenlimit |
| DB-Query | Read-only SQL | Parametrisiert, kein DDL |
| Zeit | Now, Zeitzonen | ISO 8601 zurückgeben |
@mcp.tool()
async def fetch_url(url: str) -> str:
"""Lädt URL-Inhalt"""
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url)
return response.textNetzwerk/IO: Timeout 15–30 s.
Sensible Ops: Auth (API Key, erlaubte Pfade).
{"error": "...", "hint": "..."} für Modell-Retry.
Resource vs. Tool: Resource = Datenlieferant (read-only); Tool = Aktion. Adressierung per URI: file://, http://, custom://.
@mcp.resource("config://app-settings")
def get_app_settings() -> str:
"""App-Konfiguration"""
return json.dumps({"version": "1.0", "env": "production"})
@mcp.resource("user://{user_id}/profile")
def get_user_profile(user_id: str) -> str:
"""Nutzerprofil nach ID"""
return json.dumps(db.query_user(user_id))Typen: Text (text/plain, JSON), Binär (Bilder, PDF), Stream (Live-Daten). Praxis: Dateisystem-Server mit Verzeichnisliste, Lesen, optional Watch.
MCP-Prompts sind parametrisierbare Fragmente für konsistente Team-Prompts.
from mcp.types import PromptMessage, TextContent
@mcp.prompt()
def code_review_prompt(language: str, code: str) -> list[PromptMessage]:
"""Code-Review-Vorlage"""
return [PromptMessage(
role="user",
content=TextContent(type="text", text=f"""Bitte prüfe diesen {language}-Code:
1. Qualität 2. Bugs & Sicherheit 3. Performance
```{language}
{code}
```""")
)]Mehrturn-Vorlagen (user + assistant) für Interviews oder Debug-Hilfe. Client ruft prompts/get auf.
| Merkmal | stdio | HTTP + SSE |
|---|---|---|
| Deploy | Lokal | Remote-Server |
| Latenz | Sehr niedrig | Netzwerk |
| Multi-Client | Nein | Ja |
| Szenario | IDE lokal | SaaS / Team |
mcp = FastMCP("remote-server", transport="streamable-http")
if __name__ == "__main__":
mcp.run(host="0.0.0.0", port=8000)Produktion: Bearer Token, CORS, Rate Limiting. Unauthentifizierten HTTP-MCP nicht ins Internet stellen.
Grafisch testen: tools/list, tools/call, JSON-RPC-Logs, Fehlersimulation.
@pytest.mark.asyncio
async def test_calculator_tool():
server_params = StdioServerParameters(command="python", args=["server.py"])
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
result = await session.call_tool("calculate", {"expression": "2 + 2"})
assert result.content[0].text == "4"| Fehler | Ursache | Lösung |
|---|---|---|
| Tool fehlt | Falscher Pfad | Absoluten Pfad in config prüfen |
| JSON-Fehler | Typ nicht serialisierbar | str oder dict |
| Timeout | Langsame Tool-Ausführung | Async + Timeout |
| Permission denied | Pfad / TCC | Whitelist / VNC für Dialog |
FROM python:3.12-slim WORKDIR /app COPY requirements.txt . RUN pip install -r requirements.txt COPY . . EXPOSE 8000 CMD ["python", "server.py"]
Railway / Render: Schnell für Side Projects.
Lambda / Cloud Run: Serverless — Cold Start, stdio-Limits beachten.
VPS + Nginx: Reverse Proxy, TLS, Rate Limit.
Strukturierte Logs, Prometheus-Metriken, Sentry, /health. MCP-Version deklarieren, Tools rückwärtskompatibel erweitern.
Ziel: KI durchsucht lokale Markdown-Notizen, semantische Suche, Notizen anlegen. In Cursor: „Was habe ich letzte Woche zu MCP notiert?“
| Komponente | Empfehlung |
|---|---|
| Vektor-DB | ChromaDB / Qdrant (lokal) |
| Embeddings | text-embedding-3-small |
| File Watch | watchfiles für inkrementellen Index |
index_notes: Verzeichnis scannen, Vektorindex.
semantic_search: Semantische Treffer.
write_note: Markdown erstellen/anhängen.
Resource: notes://{path} Einzelnotiz.
semantic_search spart Tokens gegenüber dem Einfügen des gesamten Archivs und liefert präzisere Antworten.
mcp-server-filesystem — Dateisystem
mcp-server-github — GitHub
mcp-server-brave-search — Websuche
mcp-server-postgres — Datenbank
mcp-server-slack — Slack
2026 unterstützen Cursor, Claude Desktop, OpenAI, Google Gemini und Microsoft MCP; Marketplace und Enterprise-Security (OAuth 2.1, Audit) reifen. Docs: modelcontextprotocol.io; Python SDK: github.com/modelcontextprotocol/python-sdk.
Host wählen (Cursor / Claude Desktop), MCP-Support in 2026-Version prüfen.
Lokal mit stdio entwickeln, Inspector für tools/list.
In Cursor MCP registrieren, Hello-World-Smoke-Test.
Browser-, Keychain-, Screen-Capture-Server: macOS-GUI für TCC (SSH reicht nicht).
HTTP + Docker + Auth live; verknüpfen mit Agent-Skill-Leitfaden und Browser-MCP.
Python (mcp + FastMCP) am schnellsten; TypeScript (@modelcontextprotocol/sdk) für Node-Teams. Protokollebene identisch.
IDE lokal: stdio. Multi-User / SaaS: HTTP + SSE / Streamable HTTP mit Authentifizierung.
Tools führen Aktionen aus; Resources liefern lesbare Daten über URI-Templates.
Browser-MCP, Keychain und Bildschirmaufnahme lösen macOS-TCC-Dialoge aus. SSH kann „Immer erlauben“ nicht klicken — VNC-GUI auf dem Host nötig.
MCP ist das Standardprotokoll für AI-Tooling — die Kette von Hello World bis Produktion ist 2026 Kernkompetenz für AI-Engineers. Welches Tool bauen Sie als Nächstes?
Die versteckten Kosten liegen selten im Code, sondern in der Laufzeitumgebung: Windows + Cloud-Mac + Cursor MCP erfordert TCC-Dialoge, venv und Inspector-Logs in einer Desktop-Sitzung. Eigenes Mac mini bringt Sleep, Updates und Abschreibung; 8 GB RAM reichen bei Vektorindex und parallelen Servern schnell nicht.
MCP stundenweise mit GUI auf derselben Maschine wie Cursor validieren? VNCMac Remote-Mac mieten — Hauptbutton zur Preisseite, Pakete auf der Startseite.