Publishing Guide

Package your MCP server, publish to Pharos, and reach every agent platform from one registry.

Prerequisites

  • A Pharos account — create one with pharos login --github
  • An MCP server that follows the MCP spec (stdio or HTTP transport)
  • Your server code in a GitHub repository

Namespace Verification

Pharos uses GitHub-based namespace verification. Your GitHub username becomes your namespace: io.github.<username>. Packages published under your namespace are marked as verified.

The login flow exchanges your GitHub auth for a Pharos JWT (valid 24 hours, HMAC-SHA256). The JWT proves you own the io.github.<username> namespace. The token is stored in your OS keyring — not in a plaintext file on disk.

OIDC keyless publish is available in GitHub Actions — no pharos login needed. The job token is exchanged inline.

Login
# Authenticate with your GitHub account
pharos login --github

# → Opens browser for GitHub OAuth
# → Exchanges auth code for a JWT (valid 24 hours)
# → Stores token in your OS keyring (not on disk in plaintext)
# → Your namespace is now: io.github.yourusername

Create Your Manifest

Every package needs a pharos.json manifest in the repository root. You can scaffold one with pharos init or write it by hand.

Scaffold with init
# Scaffold a new pharos.json in the current directory
pharos init --name my-awesome-mcp-server --runtime npm --transport stdio
pharos.json
{
  "name": "my-awesome-mcp-server",
  "version": "1.0.0",
  "description": "An MCP server that does awesome things",
  "license": "MIT",
  "homepage": "https://github.com/yourusername/my-awesome-mcp-server",
  "repository": "https://github.com/yourusername/my-awesome-mcp-server",
  "transport": "stdio",
  "runtime": "npm",
  "command": "npx -y my-awesome-mcp-server",
  "entrypoint": "server.js",
  "files": ["server.js", "lib/"],
  "capabilities": ["tools", "resources"]
}

Manifest fields

  • name — package slug (required).
  • version — semver string (required).
  • description — short summary shown in search results.
  • command — the launch command for your server (e.g. npx -y my-server).
  • entrypoint — main script file, included in the tarball automatically.
  • files — explicit list of files to pack. If omitted, Pharos auto-detects .py, .js, and .ts files.
  • transport stdio, http, or sse.
  • runtime npm, python, rust, dotnet, or docker.
  • capabilities tools, resources, prompts, sampling, logging.

Package and Publish

The pharos publish command handles everything: it reads your manifest, validates it, packages your files into a tarball, uploads to the registry, and publishes the metadata. You do not need to run a separate packaging step.

Publish
# Publish to Pharos (packaging is built-in)
pharos publish

# The publish command:
# 1. Reads pharos.json from the current directory
# 2. Validates the manifest
# 3. Packages your files into a tarball
# 4. Uploads to the registry
# 5. Publishes the package metadata
Example output
Manifest:  [email protected]
Packaging...  my-awesome-mcp-server-1.0.0.tgz
Tarball size:  12.3 KB
Creating package...  my-awesome-mcp-server
Uploading...
Publishing...  my-awesome-mcp-server
✓ Published: [email protected]

If you want to inspect the tarball without publishing — for example, to check which files are included — use the standalone package command:

Package only (no upload)
# Create a .tgz tarball without publishing (like npm pack)
pharos package

# ✓ Created my-awesome-mcp-server-1.0.0.tgz (12.3 KB)

Signing and Multi-Registry Publish

The publish command supports signing, SBOM attachment, and publishing to multiple registries in one shot.

Useful flags
# Validate manifest without uploading
pharos publish --dry-run

# Sign the version with Ed25519 from your keyring
pharos publish --sign

# Keyless signing via GitHub Actions OIDC
pharos publish --oidc --sign

# Attach an SBOM (CycloneDX or SPDX)
pharos publish --sbom sbom.json

# Publish to multiple registries at once
pharos publish --also-mcp.so --also-smithery

# Publish to all supported registries
pharos publish --also-all-supported --oidc --sign

Multi-registry publish uses the --also-* flags to mirror your package to other registries. --also-all-supported publishes to every supported registry in one command.

Version Management

To publish a new version, edit the version field in your pharos.json and run pharos publish again. Versions are immutable — you cannot overwrite a published version. Users can install any previous version with pharos install [email protected].

Publishing a new version
# Edit the version field in pharos.json
# "version": "1.0.0" → "version": "1.0.1"

# Then publish the new version
pharos publish

# Re-publishing the same version is blocked (version immutability)
# → 409 VERSION_CONFLICT if you try

Managing Your Packages

Use the CLI to inspect packages, check for advisories, and remove installed servers. You can also manage your published packages from your profile dashboard.

Management commands
# View detailed info about your package from the registry
pharos info my-awesome-mcp-server

# List MCP servers installed in the current project
pharos list

# Check installed packages for security advisories
pharos audit

# Remove a package from client configs and local store
pharos remove my-awesome-mcp-server
Info output
Package:   my-awesome-mcp-server
Version:   1.0.0 (latest)
Publisher: io.github.yourusername
Verified:  ✓
License:   MIT
Transport: stdio
Repo:      github.com/yourusername/my-awesome-mcp-server
Downloads: 1,234 total | 456 (30-day)

Capabilities:
  tools, resources

Integrity:
  sha512-3a7f8b2c...  ✓ verified

CI/CD with GitHub Actions

For automated publishing on release, use keyless OIDC signing. No stored tokens required — the GitHub Actions job token is exchanged inline.

.github/workflows/publish.yml
# .github/workflows/publish.yml
name: Publish MCP Server
on:
  release:
    types: [published]

jobs:
  publish:
    runs-on: ubuntu-latest
    permissions:
      id-token: write  # required for OIDC
      contents: read
    steps:
      - uses: actions/checkout@v4
      - name: Install Pharos
        run: curl -fsSL https://discoverpharos.dev/install.sh | bash
      - name: Publish (keyless)
        run: pharos publish --oidc --sign --also-all-supported

Verified Badge

Packages published under your verified namespace (io.github.<username>) get a special badge on Pharos. The badge appears as a navy badge with a gold checkmark on search results and package pages.

This signals to users that the package comes from a verified source — the GitHub account that owns the namespace. Packages synced from other registries (mcp.so, Smithery) do not get this badge; only PHAROS-hosted packages from verified namespaces carry it.

VerifiedPHAROS-hosted · verified namespace

Next Steps