Skip to content

MCP Registry Publishing Setup ​

Overview ​

NCP automatically publishes to the MCP Registry when a GitHub Release is created. This document explains the authentication setup.

Authentication Methods ​

Method 1: GitHub OIDC (Automatic) ​

Pros:

  • ✅ No secrets to configure
  • ✅ Automatic via GitHub Actions
  • ✅ Most secure (short-lived tokens)

Cons:

  • ⚠️ May not detect organization membership correctly
  • ⚠️ Known issue with portel-dev organization detection

How it works:

  • Workflow has id-token: write permission
  • GitHub Actions generates OIDC token automatically
  • MCP Publisher uses token to authenticate

No setup required - works out of the box (if organization detection works)


Method 2: GitHub Personal Access Token (Fallback) ​

Use this if OIDC fails to detect portel-dev organization

Setup Steps ​

  1. Create GitHub PAT:

    • Go to: https://github.com/settings/tokens
    • Click: "Tokens (classic)" → "Generate new token (classic)"
    • Name: MCP Registry Publishing
    • Scopes needed:
      • ✅ repo (Full control of private repositories)
      • ✅ read:org (Read org and team membership)
    • Click "Generate token"
    • Copy the token (you won't see it again!)
  2. Add as GitHub Secret:

  3. Workflow will automatically use it:

    • Workflow tries OIDC first
    • If OIDC fails, falls back to MCP_GITHUB_TOKEN
    • No code changes needed!

Verification ​

Check Organization Membership ​

Verify you're an admin of portel-dev:

bash
gh api orgs/portel-dev/memberships/$(gh api user -q .login)

Expected output:

json
{
  "role": "admin",
  "state": "active"
}

Check Repository Permissions ​

bash
gh api repos/portel-dev/ncp/collaborators/$(gh api user -q .login)/permission

Expected output:

json
{
  "permission": "admin",
  "role_name": "admin"
}

Validate server.json ​

bash
curl -sS https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json -o /tmp/server.schema.json
jsonschema -i server.json /tmp/server.schema.json

Should output: (no errors = valid)


Testing the Workflow ​

Option 1: Wait for Real Release ​

The workflow triggers automatically when you publish a GitHub Release via the Release workflow.

Option 2: Retry an Existing Release ​

Run the updated workflow from main with the existing release tag:

bash
gh workflow run publish-mcp-registry.yml --ref main -f release_tag=3.0.0

The workflow checks out that tag and verifies its package version. This retries only MCP Registry publication; it does not republish npm or change the tag. Rerunning an old failed release-event run uses the workflow from that release, so use this manual trigger to pick up a workflow fix.

Publisher v1.8.1 derives the GitHub OIDC audience from the registry URL. Older publishers can fail with invalid audience; their fallback also does not support the --token-stdin flag. The workflow pins the publisher and verifies the downloaded archive against its release checksum.

Option 3: Manual Validation (Local) ​

You can test MCP Publisher authentication locally:

bash
# Download MCP Publisher
VERSION="v1.8.1"
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')

curl -L "https://github.com/modelcontextprotocol/registry/releases/download/${VERSION}/mcp-publisher_${OS}_${ARCH}.tar.gz" | tar xz

# Test authentication
./mcp-publisher login github-oidc  # Try OIDC first

# Or with PAT
export GITHUB_TOKEN="your-pat-here"
./mcp-publisher login github --token "$GITHUB_TOKEN"

# Dry run publish (doesn't actually publish)
./mcp-publisher validate server.json

Troubleshooting ​

"Organization portel-dev not detected" ​

Solution: Use GitHub PAT (Method 2 above)

This is a known limitation with GitHub OIDC tokens not always exposing organization membership.

"Authentication failed" ​

Check:

  1. PAT is valid and not expired
  2. PAT has repo and read:org scopes
  3. Secret name is exactly MCP_GITHUB_TOKEN
  4. You're an admin of portel-dev organization

"Invalid server.json" ​

Check:

  • Description is ≤100 characters
  • Version format is valid (e.g., 1.4.0)
  • All required fields present
  • Run validation: jsonschema -i server.json /tmp/server.schema.json

Security Notes ​

GitHub PAT Best Practices ​

  • ✅ Use classic tokens (fine-grained tokens not yet supported by MCP Publisher)
  • ✅ Minimum scopes: repo, read:org
  • ✅ Store as GitHub Secret (never commit to code)
  • ✅ Rotate token periodically
  • ✅ Revoke immediately if compromised

OIDC vs PAT ​

FeatureOIDCPAT
Security⭐⭐⭐⭐⭐ Short-lived⭐⭐⭐ Long-lived
SetupZero configRequires secret
Org Detection⚠️ May fail✅ Reliable
RecommendedIf it worksIf OIDC fails

What Gets Published ​

Each release publishes to:

  1. NPM: @portel/ncp@X.Y.Z
  2. MCP Registry: io.github.portel-dev/ncp
  3. GitHub Releases: Tagged release

All automatic via GitHub Actions!


Support ​

If you encounter issues:

  1. Check GitHub Actions logs
  2. Review this troubleshooting guide
  3. Test authentication locally
  4. Open an issue: https://github.com/portel-dev/ncp/issues

Released under the Elastic License 2.0.