GitHub Actions로 게시 자동화하기
GitHub Actions로 게시 자동화하기 (How to Automate Publishing with GitHub Actions)
레지스트리에 서버를 게시하는 과정을 GitHub Actions 워크플로로 자동화할 수 있어요. 이 글은 버전 태그를 푸시할 때마다 MCP 서버를 레지스트리에 자동 게시하는 워크플로를 만드는 방법을 단계별로 안내합니다.
출처: MCP 공식 문서 - How to Automate Publishing with GitHub Actions
💡 MCP 레지스트리는 현재 프리뷰 단계예요. 일반 공개 전에 파괴적 변경이나 데이터 리셋이 있을 수 있습니다. 이슈가 있으면 GitHub에 보고해 주세요.
1단계: 워크플로 파일 만들기
서버 프로젝트 디렉토리에 .github/workflows/publish-mcp.yml 파일을 만드세요. 다음은 npm 기반 로컬 서버의 예시이지만, MCP 레지스트리 게시 단계는 모든 패키지 유형에서 동일해요.
OIDC 인증(권장):
name: Publish to MCP Registry
on:
push:
tags: ["v*"] # Triggers on version tags like v1.0.0
jobs:
publish:
runs-on: ubuntu-latest
permissions:
id-token: write # Required for OIDC authentication
contents: read
steps:
- name: Checkout code
uses: actions/checkout@v5
### Publish underlying npm package:
- name: Set up Node.js
uses: actions/setup-node@v5
with:
node-version: "lts/*"
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm run test --if-present
- name: Build package
run: npm run build --if-present
- name: Publish package to npm
run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
### Publish MCP server:
- name: Install mcp-publisher
run: |
curl -L "https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz" | tar xz mcp-publisher
- name: Authenticate to MCP Registry
run: ./mcp-publisher login github-oidc
# Optional:
# - name: Set version in server.json
# run: |
# VERSION=${GITHUB_REF#refs/tags/v}
# jq --arg v "$VERSION" '.version = $v' server.json > server.tmp && mv server.tmp server.json
- name: Publish server to MCP Registry
run: ./mcp-publisher publish
PAT 인증:
name: Publish to MCP Registry
on:
push:
tags: ["v*"] # Triggers on version tags like v1.0.0
jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout code
uses: actions/checkout@v5
### Publish underlying npm package:
- name: Set up Node.js
uses: actions/setup-node@v5
with:
node-version: "lts/*"
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm run test --if-present
- name: Build package
run: npm run build --if-present
- name: Publish package to npm
run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
### Publish MCP server:
- name: Install mcp-publisher
run: |
curl -L "https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz" | tar xz mcp-publisher
- name: Authenticate to MCP Registry
run: ./mcp-publisher login github --token ${{ secrets.MCP_GITHUB_TOKEN }}
# Optional:
# - name: Set version in server.json
# run: |
# VERSION=${GITHUB_REF#refs/tags/v}
# jq --arg v "$VERSION" '.version = $v' server.json > server.tmp && mv server.tmp server.json
- name: Publish server to MCP Registry
run: ./mcp-publisher publish
DNS 인증:
name: Publish to MCP Registry
on:
push:
tags: ["v*"] # Triggers on version tags like v1.0.0
jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout code
uses: actions/checkout@v5
### Publish underlying npm package:
- name: Set up Node.js
uses: actions/setup-node@v5
with:
node-version: "lts/*"
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm run test --if-present
- name: Build package
run: npm run build --if-present
- name: Publish package to npm
run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
### Publish MCP server:
- name: Install mcp-publisher
run: |
curl -L "https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz" | tar xz mcp-publisher
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# TODO: Replace `example.com` with your domain name
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- name: Authenticate to MCP Registry
run: ./mcp-publisher login dns --domain example.com --private-key ${{ secrets.MCP_PRIVATE_KEY }}
# Optional:
# - name: Set version in server.json
# run: |
# VERSION=${GITHUB_REF#refs/tags/v}
# jq --arg v "$VERSION" '.version = $v' server.json > server.tmp && mv server.tmp server.json
- name: Publish server to MCP Registry
run: ./mcp-publisher publish
2단계: 시크릿 추가
선택한 인증 방법에 따라 저장소에 시크릿을 추가해야 할 수 있어요.
- GitHub OIDC 인증: 전용 시크릿 불필요.
- GitHub PAT 인증:
read:org와read:user스코프를 가진 GitHub Personal Access Token(PAT)으로MCP_GITHUB_TOKEN시크릿 추가. - DNS 인증: Ed25519 비공개 키로
MCP_PRIVATE_KEY시크릿 추가.
패키지 레지스트리용 시크릿도 추가해야 할 수 있어요. 예를 들어 위 워크플로는 npm 토큰이 담긴 NPM_TOKEN 시크릿이 필요해요.
저장소에 시크릿을 추가하는 방법은 GitHub Actions에서 시크릿 사용하기를 보세요.
3단계: 태그 만들고 릴리스
워크플로를 트리거하려면 버전 태그를 만들고 푸시하세요.
git tag v1.0.0
git push origin v1.0.0
워크플로가 테스트를 실행하고, 패키지를 빌드하고, 패키지를 npm에 게시하고, 서버를 MCP 레지스트리에 게시할 거예요.
문제 해결
| 오류 메시지 | 조치 |
|---|---|
| "Authentication failed" | OIDC용으로 id-token: write 권한이 설정됐는지 확인하거나, 시크릿을 확인하세요. |
| "Package validation failed" | 패키지가 패키지 레지스트리(예: npm, PyPI)에 성공적으로 게시됐는지, 패키지에 필요한 검증 정보가 있는지 확인하세요. |
더 알아보기 (Learn more)
- 레지스트리 인증 — 게시 전 인증 방법(GitHub/DNS/HTTP)
- 레지스트리 지원 패키지 유형 — 각 패키지 유형과 검증
- MCP 레지스트리 퀵스타트 — 레지스트리 시작 가이드