Portfolio MCP Server
Portfolio MCP Server
Ein MCP (Model Context Protocol) Server, der Cheng-Yun Wus Portfolio – Projekte, Fähigkeiten und Lebenslauf – als Werkzeuge bereitstellt, die jeder MCP-kompatible KI-Assistent (Claude Desktop, Claude.ai Connectors, MCP Inspector usw.) direkt aufrufen kann, anstatt eine Website zu scrapen.
Warum das existiert
Ich wollte wirklich verstehen, wie MCP von Anfang bis Ende funktioniert, nicht nur darüber lesen – also habe ich einen kleinen Server gebaut, der den Inhalt meiner Portfolio-Seite in strukturierte Werkzeuge verwandelt. Es ist auch ein bewusster Vorwand, zwei Dinge anzugehen, die ich vorher kaum angefasst hatte: Docker und eine grundlegende CI/CD-Pipeline, die beide in Stellenausschreibungen, auf die ich abziele, immer wieder auftauchen.
Related MCP server: personal-mcp
Was ist MCP, kurz erklärt
MCP ist ein offenes Protokoll (von Anthropic), das es einem KI-Assistenten erlaubt, externe "Werkzeuge" aufzurufen – typisierte Funktionen mit einem Namen, einer Beschreibung und einem Schema – um Live-Informationen abzurufen oder Aktionen auszuführen, anstatt sich nur auf das zu verlassen, was in seinen Trainingsdaten oder einem eingefügten Dokument steht. Ein Server deklariert seine Werkzeuge; jeder MCP-fähige Client kann sie entdecken und aufrufen. Dieses Projekt ist ein solcher Server: Er deklariert vier Werkzeuge, die auf meinen eigenen Portfolio-Daten basieren.
Werkzeuge
Werkzeug | Was es tut |
| Jedes Portfolio-Element – ausgelieferte Systeme, Wettbewerbsbeiträge, Forschungsprojekte, veröffentlichte Papers und Kursberichte, nicht nur die Flaggschiff-Fallstudien – mit ID, Name, Untertitel, Kategorie, Jahr, einzeiliger Zusammenfassung und den Links direkt in der Auflistung (Live-System, GitHub, Bericht, Demovideo usw.) |
| Vollständiger Datensatz für ein Element. Für ein Flaggschiff-Projekt: Rolle, Technologie-Stack, Problem, Herausforderungen und Lösungen, Ergebnis, Links. Für ein leichteres Element: was immer vorhanden ist – mindestens eine Beschreibung und Links. Die Zuordnung ist nachsichtig und alias-bewusst ( |
| Schlüsselwortsuche über die Fähigkeiten-Taxonomie, nach Relevanz geordnet, jedes Ergebnis nennt die Projekte, die es demonstrieren |
| Selbstvorstellung bei |
Der Docstring jedes Werkzeugs ist das, was der KI-Assistent tatsächlich liest, um zu entscheiden, wann er es aufrufen soll – siehe src/portfolio_mcp/server.py.
Abdeckung: data/projects.json enthält alle 31 Portfolio-Elemente – 7 tiefgehende Fallstudien (ausgelieferte Systeme, die Thesis, das NSTC-Forschungsprojekt, ein preisgekröntes Paper) plus 24 leichtere Einträge (andere Wettbewerbsbeiträge, Kursberichte, Konferenzpapiere). Jeder einzelne hat mindestens einen Link. Berichte im Kursstadium und Begleitpapiere enthalten eine related_project-ID, die auf die umfassendere Fallstudie verweist, zu der sie gehören, sodass ein Assistent von einem Bericht aus in die vollständige Geschichte eintauchen kann.
Architektur
Claude Desktop / Claude.ai / MCP Inspector
│ (stdio locally, or Streamable HTTP remotely)
▼
MCPServer instance (server.py)
│ registers 4 tools
▼
tools.py (pure, unit-tested logic)
│
▼
data_loader.py → data/*.json (projects, skills, resume)Transport: Streamable HTTP, nicht stdio – der Punkt ist, dass ein entfernter Client (z.B. Claude.ai Connectors) diesen Server über eine öffentliche URL erreichen kann, nicht nur über einen lokal gestarteten Prozess. Stdio wird für lokale Tests mit Claude Desktop / MCP Inspector weiterhin unterstützt.
Datenschicht: drei flache JSON-Dateien unter
data/, einmal geladen und zwischengespeichert (functools.lru_cache). Keine Datenbank – die Daten sind klein, öffentlich und ändern sich selten.Werkzeuglogik vs. MCP-Verdrahtung: absichtlich getrennt (
tools.pyvs.server.py), sodass die Logik ohne einen laufenden MCP-Server oder Transport unit-testbar ist.SDK-Hinweis: Das offizielle
mcpPython SDK hat seine High-Level-Server-API mit v2.0.0 vonFastMCPaufmcp.server.mcpserver.MCPServerumgestellt – dieses Projekt zielt aufmcp>=2.0.0und diese aktuelle API ab. Wenn Sie ältere MCP-Tutorials gesehen haben, diefrom mcp.server.fastmcp import FastMCPverwenden, ist das die API vor 2.0 und kann nicht gegen das importieren, waspip install mcpIhnen heute liefert.
Projektstruktur
portfolio-mcp-server/
├── data/ # projects.json, skills.json, resume.json
├── src/portfolio_mcp/
│ ├── server.py # MCPServer app: registers tools, stdio/HTTP entrypoints, /chat route
│ ├── tools.py # MCP tool logic (testable, no MCP dependency)
│ ├── chat.py # /chat: Claude + Tool Runner over the same data, for the site's Q&A widget
│ └── data_loader.py # cached JSON loading
├── tests/ # pytest suite run in CI (tools, server security, chat, chat route)
├── Dockerfile # python:3.12-slim + uvicorn, Streamable HTTP
├── .github/workflows/ci.yml # lint (ruff) + test (pytest) on every push
└── claude_desktop_config.json # example config for local stdio testingLokales Ausführen
# from the repo root
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"Option A — stdio, mit MCP Inspector
npx @modelcontextprotocol/inspector python -m portfolio_mcp.serverÖffnet eine lokale Web-Oberfläche, in der Sie jedes Werkzeug direkt aufrufen und die Anfrage/Antwort inspizieren können.
Option B — stdio, mit Claude Desktop
Fügen Sie den mcpServers-Eintrag aus claude_desktop_config.json in Ihre eigene Claude Desktop-Konfiguration ein (Einstellungen → Entwickler → Konfiguration bearbeiten), passen Sie die Pfade für Ihren Rechner an, starten Sie dann Claude Desktop neu und fragen Sie etwas wie "An welchen Projekten hat diese Person gearbeitet?"
Option C — Streamable HTTP, lokal
TRANSPORT=http python -m portfolio_mcp.server
# equivalent — both serve the exact same ASGI app, /chat included:
uvicorn portfolio_mcp.server:app --host 0.0.0.0 --port 8000Tests
pytest -v
ruff check .Ausführen mit Docker
docker build -t portfolio-mcp-server .
docker run -p 8000:8000 portfolio-mcp-serverDer Container bedient immer Streamable HTTP (das ist der Sinn der Containerisierung – eine portable, öffentlich bereitstellbare Einheit, kein an einen Rechner gebundener stdio-Prozess).
Bereitstellen (Render)
Ausgewähltes Bereitstellungsziel: Render, Free-Tier – es führt langlebige Container aus (keine serverlosen Funktionen mit Ausführungszeit-Limits), die die persistenten Verbindungen von Streamable HTTP benötigen, und es braucht keine Kreditkarte zum Starten.
Pushen Sie dieses Repository zu GitHub.
Auf render.com: Neu → Web Service → dieses Repository verbinden.
Render erkennt automatisch die
Dockerfileund baut/führt sie als Container aus.Wählen Sie den Free-Instanztyp → Sie erhalten eine
https://<etwas>.onrender.com-URL.Überprüfen Sie, ob sie läuft:
npx @modelcontextprotocol/inspector https://<something>.onrender.com/mcp(Optional) Aktivieren Sie Render's GitHub Auto-Deploy, sodass
git pushaufmainautomatisch neu bereitstellt – zusammen mit dem CI-Workflow unten ist das die vollständige CI/CD-Geschichte.
Free-Tier-Hinweis: Render's kostenlose Webdienste schlafen nach etwa 15 Minuten Inaktivität ein und brauchen 30-60s zum Aufwachen bei der nächsten Anfrage. In Ordnung für eine Portfolio-Demo; erwähnenswert als bewusster Kosten/Latenz-Kompromiss, falls gefragt.
Live-Bereitstellung: https://yun-portfolio-mcp.onrender.com/mcp – verbinden Sie einen MCP-Client mit dieser URL (beachten Sie den /mcp-Pfad; die bloße Domain gibt einen 404-Fehler, das ist erwartet – Streamable HTTP bedient nur diesen einen Pfad). Überprüfen Sie es selbst mit npx @modelcontextprotocol/inspector https://yun-portfolio-mcp.onrender.com/mcp.
Wenn Sie dies forken: Die Host-Header-Whitelist in
server.pyist standardmäßig fest aufyun-portfolio-mcp.onrender.comcodiert (DNS-Rebinding-Schutz lehnt jeden anderen Host-Header mit einem 421 ab). Setzen Sie die UmgebungsvariableMCP_ALLOWED_HOSTSauf den Hostnamen Ihrer eigenen Bereitstellung oder bearbeiten SieALLOWED_HOSTSdirekt.
Chat-Endpunkt (/chat) – das Q&A-Widget der Portfolio-Seite
Eine zweite, separate Tür auf demselben Render-Dienst, für ein einfaches Chat-Widget, das auf yunwcy.github.io eingebettet ist – nicht Teil der oben beschriebenen MCP-Protokolloberfläche. Ein Browser POSTet {"message": "..."} an /chat; der Server verwendet den Anthropic Tool Runner, um Claude entscheiden zu lassen, welches der gleichen vier Werkzeuge aufgerufen werden soll (indem tools.py direkt aufgerufen wird – kein MCP-Handshake erforderlich), und gibt dann {"reply": "..."} zurück. Siehe src/portfolio_mcp/chat.py für die vollständige Implementierung.
Warum dies ein echtes Backend braucht und GitHub Pages allein es nicht kann: Das Antworten in natürlicher Sprache bedeutet, dass ein LLM die Frage sehen und entscheiden muss, welches Werkzeug aufgerufen werden soll, was einen Anthropic-API-Schlüssel erfordert – und ein Schlüssel kann niemals in clientseitigem JavaScript auf einer statischen Seite sein, da jeder den Quelltext einsehen und das Konto leerräumen kann. /chat hält den Schlüssel serverseitig (eine Render-Umgebungsvariable, die niemals an den Browser gesendet wird) und liefert nur das Widget, das der Browser braucht, an GitHub Pages aus.
Einrichtung (erforderlich, bevor dieser Endpunkt funktioniert):
Holen Sie sich einen API-Schlüssel von der Anthropic Console und fügen Sie ihn in Render als Umgebungsvariable
ANTHROPIC_API_KEYhinzu (Render-Dashboard → dieser Dienst → Environment). Ohne ihn gibt/chat503 {"error": "not_configured"}zurück, anstatt den Server abstürzen zu lassen.CHAT_ALLOWED_ORIGINS(kommagetrennt) steuert CORS – standardmäßighttps://yunwcy.github.io. Setzen Sie es, wenn das Widget jemals woanders lebt.ANTHROPIC_CHAT_MODEL(Standardclaude-opus-5) – die stärkste Allzweckwahl, aber dies ist ein einfaches, potenziell hochfrequentes, kostensensibles öffentliches Widget, daher istclaude-haiku-4-5hier speziell eine Überlegung wert. Dies ist eine bewusste Entscheidung, die demjenigen überlassen wird, der den Server betreibt, nicht fest codiert.CHAT_RATE_LIMIT_PER_HOUR(Standard30) – eine einfache In-Memory-pro-IP-Begrenzung, damit ein einzelner Besucher nicht allein die Rechnung in die Höhe treiben kann. Sie setzt sich bei jedem Neustart/Neubereitstellung zurück und wird nicht über Instanzen hinweg geteilt – ausreichend für eine wenig frequentierte persönliche Seite, keine allgemeine Missbrauchsabwehr.
CI/CD
.github/workflows/ci.yml wird bei jedem Push/PR auf main ausgeführt: installiert das Paket, lintet mit ruff und führt die pytest-Suite aus. Render's GitHub Auto-Deploy (siehe oben) übernimmt die CD-Hälfte.
Sicherheits-/Kostenhinweise
Die MCP-Werkzeugoberfläche (
/mcp) ruft selbst kein LLM auf – sie liest nur lokales JSON und gibt es zurück. Wer sich verbindet (sein Claude, seine Tokens), trägt diese Kosten, nicht dieser Server.Der
/chat-Endpunkt ruft ein LLM auf, und zwar mit dem eigenen Anthropic-API-Schlüssel dieses Servers – das ist der ganze Sinn (ein Browser kann einen Schlüssel nicht sicher halten). Die Kosten werden durch eine Pro-IP-Ratenbegrenzung,effort: "low"und ein kleinesmax_tokensbegrenzt; siehe den Abschnitt zum Chat-Endpunkt oben für die Stellschrauben.Alle Daten sind bereits auf meiner Portfolio-Seite öffentlich – auf keinem Endpunkt ist eine Authentifizierung implementiert, da es nichts Privates zu schützen gibt. Die CORS-Whitelist von
/chatdient dazu, zu kontrollieren, wer das API-Budget ausgeben kann, nicht um die Daten zu schützen.
Aktualisieren der Daten
Bearbeiten Sie die JSON-Dateien unter data/ direkt – id ist der stabile Bezeichner, mit dem get_project_details abgleicht; jedes andere Feld ist frei gestaltbar. Für Inhaltsaktualisierungen sind keine Codeänderungen erforderlich.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Alicense-qualityCmaintenanceExposes a person's structured professional profile as MCP tools, enabling Claude and other MCP clients to answer questions about that person based on real data.111MIT
- Flicense-qualityBmaintenanceExposes personal portfolio data as tools for Claude to answer questions about the developer, including profile, skills, experience, projects, and contact information.
- Alicense-qualityCmaintenanceTransforms professional data (CV, projects) into MCP tools for LLMs to query, list, match job descriptions, and ask about experience.77MIT
- FlicenseAqualityCmaintenanceExposes a personal portfolio's resume, projects, skills, certifications, and live GitHub repositories as tools for AI assistants to query via natural language.61
Related MCP Connectors
A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…
Personal assistant MCP server with search, execute, packages, jobs, secrets, and integrations.
The personal context layer for AI: your profile and files, read by any MCP client over OAuth.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Yunwcy/portfolio-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server