portfolio-mcp
Portfolio MCP
Eigenständiger Model Context Protocol (MCP)-Server zur Verwaltung des Supabase-gestützten Engineering-Blogs, der für das Portfolio von Salman Butt verwendet wird.
Das öffentliche Next.js-Portfolio bleibt schreibgeschützt. Dieser Dienst besitzt die privilegierte Blog-Verwaltungsoberfläche und hält den Supabase-Geheimschlüssel außerhalb des Frontend-Deployments.
Was er bereitstellt
Artikel-Tools
list_blog_postsget_blog_postcreate_blog_postupdate_blog_postpublish_blog_postunpublish_blog_postdelete_blog_post
Bild-Tools
upload_blog_imagereplace_blog_imagedelete_blog_imageget_blog_image_url
Der Server legt keine beliebigen SQL- oder uneingeschränkten Supabase-Zugriffe offen.
Related MCP server: Self-Hosted Supabase MCP Server
Architektur
ChatGPT / remote MCP host / local MCP client
|
| Streamable HTTP or stdio
v
portfolio-mcp service
|
+--> MCP token authentication (HTTP)
|
+--> MCP SDK v2 tool layer
|
+--> Supabase REST: public.blogs
|
+--> Supabase Storage: blog-images
Public visitors
|
v
Next.js portfolio --> Supabase anon read-only accessAnforderungen
Node.js 22+
Ein Supabase-Projekt mit der Portfolio-
blogs-TabelleEin serverseitiger Supabase-Geheimschlüssel mit Zugriff auf die Blog-Tabelle und den Storage-Bucket
Für ChatGPT: ein über HTTPS erreichbares Remote-Deployment dieses MCP-Servers
Einrichtung
git clone https://github.com/salman0butt/portfolio-mcp.git
cd portfolio-mcp
npm ci
cp .env.example .envKonfigurieren Sie .env:
SUPABASE_URL=https://YOUR_PROJECT.supabase.co
SUPABASE_SECRET_KEY=sb_secret_REPLACE_ME
SUPABASE_BLOG_BUCKET=blog-images
PORTFOLIO_MCP_TOKEN=replace-with-long-random-bearer-token
PORTFOLIO_MCP_URL_TOKEN=replace-with-different-long-random-url-token
PORT=3000
HOST=0.0.0.0
MCP_ALLOWED_ORIGINS=*
MCP_MAX_REQUEST_BYTES=5242880Die HTTP- und Stdio-Einstiegspunkte laden automatisch eine lokale .env-Datei, falls vorhanden. Von Ihrer Deployment-Plattform injizierte Umgebungsvariablen funktionieren weiterhin normal.
MCP-Tokens generieren
Führen Sie diesen Befehl zweimal aus:
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"Verwenden Sie zwei verschiedene Ausgaben:
PORTFOLIO_MCP_TOKEN— Bearer-Token für Clients, dieAuthorization-Header senden können.PORTFOLIO_MCP_URL_TOKEN— Wegwerf-Token für Clients, bei denen ein statischer benutzerdefinierter Header unpraktisch ist.
Beide Tokens müssen mindestens 32 Zeichen lang und unterschiedlich sein.
Verwenden Sie den Supabase-Geheimschlüssel niemals als MCP-Token. Setzen Sie SUPABASE_SECRET_KEY niemals in eine ChatGPT-Connector-URL.
Supabase-Authentifizierung
Bevorzugen Sie den modernen serverseitigen Supabase-Geheimschlüssel:
sb_secret_...Der Dienst sendet moderne sb_secret_*-Schlüssel nur im Supabase-apikey-Header. Diese Schlüssel sind undurchsichtige API-Schlüssel und werden nicht als Authorization: Bearer-JWTs gesendet.
Legacy-JWT-basierte service_role-Schlüssel bleiben aus Kompatibilitätsgründen für Migrationen unterstützt, aber neue Deployments sollten sb_secret_* verwenden.
Entwicklung
Remote-HTTP-Modus:
npm run dev:httpMCP-Endpunkt:
http://localhost:3000/mcpHealth-Check:
http://localhost:3000/healthzLokaler Stdio-Modus:
npm run dev:stdioDer Stdio-Modus verwendet keine HTTP-MCP-Tokens, da der Zugriff durch den lokalen Prozess gesteuert wird, der den Server startet.
Produktions-Deployment
Direkt bauen und ausführen:
npm run build
npm startOder Docker verwenden:
docker build -t portfolio-mcp .
docker run --rm -p 3000:3000 --env-file .env portfolio-mcpDer Container installiert Abhängigkeiten aus package-lock.json, läuft als nicht-Root-Benutzer node und stellt einen /healthz-Docker-Health-Check bereit.
Stellen Sie diesen Dienst auf einer Plattform bereit, die einen langlaufenden Node-HTTP-Prozess/-Container unterstützt, z. B. Railway, Render, Fly.io, Kubernetes oder einem VPS. Die aktuelle Implementierung ist kein Vercel-Serverless-Function-Einstiegspunkt.
Für ChatGPT muss der bereitgestellte MCP-Endpunkt über HTTPS erreichbar sein, zum Beispiel:
https://portfolio-mcp.example.com/mcpHTTP-Authentifizierung
Clients, die Request-Header unterstützen, sollten Folgendes verwenden:
Authorization: Bearer <PORTFOLIO_MCP_TOKEN>Für einen Client, bei dem die Konfiguration eines statischen Bearer-Headers unpraktisch ist, akzeptiert der Endpunkt auch:
https://YOUR_MCP_HOST/mcp?token=YOUR_PORTFOLIO_MCP_URL_TOKENQuery-String-Anmeldeinformationen können in Infrastruktur-/Zugriffsprotokollen erscheinen. Behandeln Sie PORTFOLIO_MCP_URL_TOKEN als Wegwerf-Token und rotieren Sie es, falls es offengelegt wird. Bevorzugen Sie die Bearer-Authentifizierung, wenn der MCP-Client sie unterstützt.
Mit ChatGPT verbinden
ChatGPT verbindet sich mit Remote-MCP-Servern, nicht mit einem Server, der nur auf localhost läuft.
Zum Zeitpunkt dieses Repository-Updates (August 2026) dokumentiert OpenAI volle benutzerdefinierte MCP-Unterstützung, einschließlich Schreib-/Änderungsaktionen für ChatGPT Business-, Enterprise- und Edu-Workspaces im Web. Die Verfügbarkeit kann sich ändern. Überprüfen Sie daher die aktuelle OpenAI-ChatGPT-Dokumentation zu benutzerdefinierten Apps/MCP, falls Ihre Benutzeroberfläche abweicht.
Wenn Ihr ChatGPT-Workspace benutzerdefinierte MCP-Apps/Connectors bereitstellt:
Stellen Sie dieses Repository auf einem HTTPS-Endpunkt bereit.
Konfigurieren Sie alle Server-Umgebungsvariablen auf der Deployment-Plattform.
Aktivieren Sie in ChatGPT den Entwicklermodus / benutzerdefinierte Apps gemäß Ihren Workspace-Berechtigungen.
Erstellen Sie eine benutzerdefinierte MCP-App.
Wenn das ChatGPT-Formular kein statisches benutzerdefiniertes Bearer-Header-Feld bereitstellt, verwenden Sie den URL-Token-Endpunkt:
https://YOUR_MCP_HOST/mcp?token=YOUR_PORTFOLIO_MCP_URL_TOKENWählen Sie in ChatGPT für diesen Connector No Auth aus. Die Authentifizierung wird weiterhin von diesem Server über das URL-Token erzwungen.
Wählen Sie Scan Tools. Der Server sollte die oben aufgeführten Artikel- und Bild-Tools bereitstellen.
Fügen Sie die App in einem neuen Chat hinzu/aktivieren Sie sie und testen Sie eine Leseaktion wie
list_blog_posts, bevor Sie eine Schreibaktion testen.ChatGPT kann basierend auf Workspace-/App-Berechtigungen und den Tool-Annotationen eine Bestätigung für Schreib-/destruktive Aktionen anfordern.
Geben Sie SUPABASE_SECRET_KEY nicht in ChatGPT ein. ChatGPT benötigt nur den Remote-MCP-Endpunkt (und, mit diesem URL-Token-Setup, das Wegwerf-MCP-URL-Token).
Empfohlene ChatGPT-Testsequenz
Nachdem der Connector erfolgreich gescannt hat:
List my portfolio blog posts.Dann:
Create a draft blog post titled "MCP Connection Test". Do not publish it.Dann verifizieren Sie es:
Get the MCP Connection Test draft and show me its metadata.Löschen Sie den Testentwurf schließlich nur, wenn Sie ihn ausdrücklich entfernen möchten.
CORS / Ursprünge
MCP_ALLOWED_ORIGINS akzeptiert eine kommagetrennte Liste:
MCP_ALLOWED_ORIGINS=https://example.com,https://another-client.exampleDer HTTP-Server unterstützt aktuelle MCP-Request-Header, einschließlich Mcp-Protocol-Version, Mcp-Method, Mcp-Name und Mcp-Session-Id, in Browser-CORS-Preflights.
Der Standardwert * maximiert die Kompatibilität, während die Token-Authentifizierung weiterhin obligatorisch ist. Engen Sie die Liste ein, wenn Sie die genauen Browser-Ursprünge kennen, die den Dienst aufrufen müssen.
Anfrage- und Bildlimits
Die Standard-Obergrenze für HTTP-MCP-Anfragen beträgt 5 MiB:
MCP_MAX_REQUEST_BYTES=5242880Dies ist absichtlich größer als das 3-MiB-Limit für decodierte Bilder, da base64 etwa ein Drittel Overhead plus JSON-Framing hinzufügt.
Akzeptierte Bild-Content-Typen:
PNG
JPEG
WebP
GIF
AVIF
Speicherpfade werden normalisiert und lehnen Traversal wie ../ ab. Bild-Payloads müssen gültiges base64 enthalten.
Empfohlene Objektpfade:
senior-software-engineer/cover.webp
production-rag-systems/architecture.webp
nextjs-at-scale/performance.webpDas Löschen eines Blog-Artikels löscht nicht automatisch dessen Bilder. Dies vermeidet versehentliches Löschen von Medien, die möglicherweise geteilt oder wiederverwendet werden.
Blog-Workflow
Empfohlener Veröffentlichungsablauf:
Erstellen Sie den Artikel als Entwurf.
Laden Sie bei Bedarf Titel-/Diagrammbilder hoch.
Aktualisieren Sie den Entwurf mit den zurückgegebenen öffentlichen Bild-URLs.
Überprüfen Sie Titel, Auszug, Markdown, Kategorie, Tags und Veröffentlichungsdatum.
Veröffentlichen Sie mit
publish_blog_post.Aktualisieren Sie später oder nehmen Sie die Veröffentlichung zurück, wenn nötig.
Löschen Sie den Artikel oder die Bilder nur, wenn es ausdrücklich beabsichtigt ist.
published_at akzeptiert ein ISO-8601-Datum oder -Datetime, zum Beispiel:
2026-08-25
2026-08-25T12:00:00+05:00Sicherheitsmodell
Supabase-Geheimanmeldeinformationen sind nur serverseitig.
Moderne
sb_secret_*-Schlüssel werden als Supabase-API-Schlüssel gesendet, nicht als JWT-Bearer-Tokens.Das Next.js-Portfolio behält sein öffentliches, schreibgeschütztes Supabase-Zugriffsmodell.
HTTP-MCP-Anfragen erfordern ein Bearer-Token oder URL-Token.
MCP-Tokens müssen stark und unterschiedlich sein.
Der Token-Vergleich verwendet timing-sichere Gleichheit.
Es wird kein generischer SQL-/Query-Executor offengelegt.
Slugs, Veröffentlichungsdaten, Bildpfade, Bildtypen, base64-Payloads, Bildgrößen und HTTP-Anfragegrößen werden validiert.
Überschreib-, Unpublish-, Ersetz- und Lösch-Tools verwenden risikogerechte MCP-Annotationen.
Beim Herunterfahren wird kein neuer Datenverkehr mehr akzeptiert und aktiven Anfragen wird eine begrenzte Drain-Periode gewährt, bevor MCP-Ressourcen geschlossen werden.
Geheimnisse dürfen niemals in GitHub committet werden.
MCP-Protokoll
Der HTTP-Server verwendet das stabile MCP TypeScript SDK v2 und stellt Streamable HTTP unter /mcp bereit. Ein Stdio-Einstiegspunkt ist für lokale MCP-Hosts enthalten.
Der Remote-HTTP-Wrapper unterstützt sowohl modernen MCP-Datenverkehr als auch den zustandslosen Legacy-Fallback des SDK, um die Client-Kompatibilität zu maximieren.
Validierung
Führen Sie dieselbe Validierung aus, die von CI verwendet wird:
npm run checkDies führt aus:
strikte TypeScript-Typüberprüfung
Laufzeit-Regressionstests
Produktions-TypeScript-Build
Laufzeittests decken die Supabase-Geheimschlüsselbehandlung, HTTP-Authentifizierung, CORS, Anfragelimits, Umgebungsladen, Token-Validierung und eine echte MCP-tools/list-Anfrage über den Remote-HTTP-Adapter ab.
GitHub Actions installiert den exakten Abhängigkeitsgraphen mit npm ci aus der committeten Lockfile.
This server cannot be installed
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
- AlicenseNot gradedqualityDmaintenanceManage your Ghost blog content directly from Claude, Cursor, or any MCP-compatible client, allowing you to create, edit, search, and delete posts with support for tag management and analytics.14MIT
- FlicenseNot gradedqualityDmaintenanceEnables developers to interact with self-hosted Supabase instances, providing database introspection, migration management, auth user operations, storage management, and TypeScript type generation directly from MCP-compatible development environments.
- AlicenseAqualityFmaintenanceEnables AI tools to programmatically manage Substack content, including creating drafts, publishing posts, and posting to Substack Notes. It supports image uploads, live blogging, and document formatting compatible with Substack's ProseMirror editor.118MIT
- AlicenseNot gradedqualityDmaintenanceManages Supabase projects, databases, edge functions, secrets, and branches across organizations using the Supabase Management API with 24 tools.MIT
Related MCP Connectors
Publish and manage articles, series, comments, reactions, newsletters and blog analytics.
Manage Supabase projects end to end across database, auth, storage, realtime, and migrations. Moni…
Manage Appwrite projects, databases, auth, storage, functions, and messaging; search Appwrite docs
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/salman0butt/portfolio-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server