Skip to main content
Glama

Portfolio MCP

Salman Butt의 포트폴리오에 사용되는 Supabase 기반 엔지니어링 블로그를 관리하기 위한 독립형 Model Context Protocol (MCP) 서버입니다.

공개 Next.js 포트폴리오는 읽기 전용으로 유지됩니다. 이 서비스는 권한이 필요한 블로그 관리 기능을 담당하며, Supabase 비밀 키를 프론트엔드 배포 환경 밖에 보관합니다.

제공 기능

아티클 도구

  • list_blog_posts

  • get_blog_post

  • create_blog_post

  • update_blog_post

  • publish_blog_post

  • unpublish_blog_post

  • delete_blog_post

이미지 도구

  • upload_blog_image

  • replace_blog_image

  • delete_blog_image

  • get_blog_image_url

이 서버는 임의의 SQL 또는 제한 없는 Supabase 접근을 노출하지 않습니다.

Related MCP server: Self-Hosted Supabase MCP Server

아키텍처

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 access

요구 사항

  • Node.js 22+

  • 포트폴리오 blogs 테이블이 포함된 Supabase 프로젝트

  • 블로그 테이블과 Storage 버킷에 접근할 수 있는 서버 측 Supabase 비밀 키

  • ChatGPT 사용 시: 이 MCP 서버의 HTTPS 접근 가능한 원격 배포

설정

git clone https://github.com/salman0butt/portfolio-mcp.git
cd portfolio-mcp
npm ci
cp .env.example .env

.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=5242880

HTTP 및 stdio 진입점은 로컬 .env 파일이 있으면 자동으로 로드합니다. 배포 플랫폼에서 주입한 환경 변수는 정상적으로 계속 작동합니다.

MCP 토큰 생성

이 명령을 두 번 실행하세요:

node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

두 개의 서로 다른 출력을 사용하세요:

  • PORTFOLIO_MCP_TOKENAuthorization 헤더를 보낼 수 있는 클라이언트용 bearer 토큰.

  • PORTFOLIO_MCP_URL_TOKEN — 정적 커스텀 헤더 설정이 어려운 클라이언트용 일회용 토큰.

두 토큰 모두 최소 32자 이상이어야 하며 서로 달라야 합니다.

Supabase 비밀 키를 MCP 토큰으로 절대 사용하지 마세요. ChatGPT 커넥터 URL에 SUPABASE_SECRET_KEY를 절대 넣지 마세요.

Supabase 인증

최신 Supabase 서버 측 비밀 키를 사용하는 것을 권장합니다:

sb_secret_...

이 서비스는 최신 sb_secret_* 키를 Supabase apikey 헤더에만 전송합니다. 이러한 키는 불투명한 API 키이며 Authorization: Bearer JWT로 전송되지 않습니다.

레거시 JWT 기반 service_role 키는 마이그레이션 호환성을 위해 계속 지원되지만, 새 배포에서는 sb_secret_*를 사용해야 합니다.

개발

원격 HTTP 모드:

npm run dev:http

MCP 엔드포인트:

http://localhost:3000/mcp

헬스 체크:

http://localhost:3000/healthz

로컬 stdio 모드:

npm run dev:stdio

stdio 모드는 서버를 실행하는 로컬 프로세스가 접근을 제어하므로 HTTP MCP 토큰을 사용하지 않습니다.

프로덕션 배포

빌드 후 직접 실행:

npm run build
npm start

또는 Docker 사용:

docker build -t portfolio-mcp .
docker run --rm -p 3000:3000 --env-file .env portfolio-mcp

컨테이너는 package-lock.json에서 의존성을 설치하고, 비루트 node 사용자로 실행되며, /healthz Docker 헬스 체크를 노출합니다.

이 서비스를 Railway, Render, Fly.io, Kubernetes 또는 VPS와 같이 장기 실행 Node HTTP 프로세스/컨테이너를 지원하는 플랫폼에 배포하세요. 현재 구현은 아닙니다 Vercel 서버리스 함수 진입점이 아닙니다.

ChatGPT의 경우 배포된 MCP 엔드포인트가 HTTPS로 접근 가능해야 합니다. 예:

https://portfolio-mcp.example.com/mcp

HTTP 인증

요청 헤더를 지원하는 클라이언트는 다음을 사용해야 합니다:

Authorization: Bearer <PORTFOLIO_MCP_TOKEN>

정적 bearer 헤더 구성이 불편한 클라이언트의 경우 엔드포인트는 다음도 허용합니다:

https://YOUR_MCP_HOST/mcp?token=YOUR_PORTFOLIO_MCP_URL_TOKEN

쿼리 문자열 자격 증명은 인프라/접근 로그에 나타날 수 있습니다. PORTFOLIO_MCP_URL_TOKEN을 일회용으로 취급하고 노출되면 교체하세요. MCP 클라이언트가 지원하는 경우 bearer 인증을 우선 사용하세요.

ChatGPT에 연결

ChatGPT는 localhost에서만 실행되는 서버가 아닌 원격 MCP 서버에 연결합니다.

이 저장소 업데이트 시점(2026년 8월) 기준, OpenAI는 ChatGPT Business, Enterprise 및 Edu 워크스페이스의 웹에서 쓰기/수정 작업을 포함한 전체 커스텀 MCP 지원을 문서화하고 있습니다. 가용성은 변경될 수 있으므로 UI가 다를 경우 현재 OpenAI ChatGPT 커스텀 앱/MCP 문서를 확인하세요.

ChatGPT 워크스페이스에서 커스텀 MCP 앱/커넥터를 노출하는 경우:

  1. 이 저장소를 HTTPS 엔드포인트에 배포하세요.

  2. 배포 플랫폼에서 모든 서버 환경 변수를 구성하세요.

  3. ChatGPT에서 워크스페이스 권한에 따라 Developer Mode / 커스텀 앱을 활성화하세요.

  4. 커스텀 MCP 앱을 생성하세요.

  5. ChatGPT 양식에 정적 커스텀 bearer 헤더 필드가 없는 경우 URL 토큰 엔드포인트를 사용하세요:

    https://YOUR_MCP_HOST/mcp?token=YOUR_PORTFOLIO_MCP_URL_TOKEN
  6. ChatGPT에서 해당 커넥터에 대해 No Auth를 선택하세요. 인증은 URL 토큰을 통해 이 서버에서 여전히 적용됩니다.

  7. Scan Tools를 선택하세요. 서버는 위에 나열된 아티클 및 이미지 도구를 노출해야 합니다.

  8. 새 채팅에서 앱을 추가/활성화하고 쓰기 작업을 테스트하기 전에 list_blog_posts와 같은 읽기 작업을 테스트하세요.

  9. ChatGPT는 워크스페이스/앱 권한 및 도구 주석에 따라 쓰기/파괴적 작업에 대한 확인을 요청할 수 있습니다.

ChatGPT에 SUPABASE_SECRET_KEY를 입력하지 마세요. ChatGPT에는 원격 MCP 엔드포인트(및 이 URL 토큰 설정에서는 일회용 MCP URL 토큰)만 필요합니다.

권장 ChatGPT 테스트 순서

커넥터가 성공적으로 스캔된 후:

List my portfolio blog posts.

그 다음:

Create a draft blog post titled "MCP Connection Test". Do not publish it.

그런 다음 확인:

Get the MCP Connection Test draft and show me its metadata.

마지막으로 명시적으로 삭제하려는 경우에만 테스트 초안을 삭제하세요.

CORS / 오리진

MCP_ALLOWED_ORIGINS는 쉼표로 구분된 목록을 허용합니다:

MCP_ALLOWED_ORIGINS=https://example.com,https://another-client.example

HTTP 서버는 브라우저 CORS 사전 요청에서 Mcp-Protocol-Version, Mcp-Method, Mcp-Name, Mcp-Session-Id를 포함한 최신 MCP 요청 헤더를 지원합니다.

기본값 *는 토큰 인증이 필수인 상태에서 최대 호환성을 보장합니다. 서비스를 호출해야 하는 정확한 브라우저 오리진을 알게 되면 목록을 좁히세요.

요청 및 이미지 제한

기본 HTTP MCP 요청 상한은 5 MiB입니다:

MCP_MAX_REQUEST_BYTES=5242880

이는 3 MiB 디코딩 이미지 제한보다 의도적으로 큰데, base64가 약 1/3의 오버헤드에 JSON 프레이밍을 더하기 때문입니다.

허용되는 이미지 콘텐츠 유형:

  • PNG

  • JPEG

  • WebP

  • GIF

  • AVIF

스토리지 경로는 정규화되며 ../와 같은 경로 탐색을 거부합니다. 이미지 페이로드는 유효한 base64여야 합니다.

권장 객체 경로:

senior-software-engineer/cover.webp
production-rag-systems/architecture.webp
nextjs-at-scale/performance.webp

블로그 아티클을 삭제해도 해당 이미지는 자동으로 삭제되지 않습니다. 이는 공유되거나 재사용될 수 있는 미디어의 우발적 삭제를 방지하기 위함입니다.

블로그 워크플로우

권장 게시 흐름:

  1. 아티클을 초안으로 생성합니다.

  2. 필요한 경우 커버/다이어그램 이미지를 업로드합니다.

  3. 반환된 공개 이미지 URL로 초안을 업데이트합니다.

  4. 제목, 발췌문, Markdown, 카테고리, 태그 및 게시 날짜를 검토합니다.

  5. publish_blog_post를 사용하여 게시합니다.

  6. 필요할 때 나중에 업데이트하거나 게시를 취소합니다.

  7. 명시적으로 의도한 경우에만 아티클이나 이미지를 삭제합니다.

published_at는 ISO 8601 날짜 또는 날짜시간을 허용합니다. 예:

2026-08-25
2026-08-25T12:00:00+05:00

보안 모델

  • Supabase 비밀 자격 증명은 서버 측에만 있습니다.

  • 최신 sb_secret_* 키는 JWT bearer 토큰이 아닌 Supabase API 키로 전송됩니다.

  • Next.js 포트폴리오는 공개 읽기 전용 Supabase 접근 모델을 유지합니다.

  • HTTP MCP 요청에는 bearer 토큰 또는 URL 토큰이 필요합니다.

  • MCP 토큰은 강력하고 서로 달라야 합니다.

  • 토큰 비교는 타이밍 안전 동등성을 사용합니다.

  • 일반 SQL/쿼리 실행기는 노출되지 않습니다.

  • 슬러그, 게시 날짜, 이미지 경로, 이미지 유형, base64 페이로드, 이미지 크기 및 HTTP 요청 크기가 검증됩니다.

  • 덮어쓰기, 게시 취소, 교체 및 삭제 도구는 위험에 적합한 MCP 주석을 사용합니다.

  • 종료 시 새 트래픽 수신을 중지하고 MCP 리소스가 닫히기 전에 활성 요청에 제한된 드레인 기간을 제공합니다.

  • 비밀은 GitHub에 커밋되어서는 안 됩니다.

MCP 프로토콜

HTTP 서버는 안정적인 MCP TypeScript SDK v2를 사용하며 /mcp에서 Streamable HTTP를 노출합니다. 로컬 MCP 호스트를 위한 stdio 진입점이 포함되어 있습니다.

원격 HTTP 래퍼는 최신 MCP 트래픽과 SDK의 상태 비저장 레거시 폴백을 모두 지원하여 클라이언트 호환성을 극대화합니다.

검증

CI에서 사용하는 것과 동일한 검증을 실행하세요:

npm run check

이것은 다음을 실행합니다:

  • 엄격한 TypeScript 타입 검사

  • 런타임 회귀 테스트

  • 프로덕션 TypeScript 빌드

런타임 테스트는 Supabase 비밀 키 처리, HTTP 인증, CORS, 요청 제한, 환경 로딩, 토큰 검증 및 원격 HTTP 어댑터를 통한 실제 MCP tools/list 요청을 다룹니다.

GitHub Actions는 커밋된 lockfile에서 npm ci로 정확한 의존성 그래프를 설치합니다.

F
license - not found
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

  • A
    license
    Not graded
    quality
    D
    maintenance
    Manage 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.
    14
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables 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.
  • A
    license
    A
    quality
    F
    maintenance
    Enables 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.
    11
    8
    MIT

View all related MCP servers

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

View all MCP Connectors

Latest Blog Posts

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