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
  • •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.

For CI/CD pipelines, use pharos login --manual to paste a pre-issued token, or pass --token directly to pharos publish in your workflow.

Login
# Authenticate with your GitHub account
pharos login

# → 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

# If you cannot use a browser, paste a token manually
pharos login --manual

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 (interactive)
pharos init

# Non-interactive with defaults
pharos init --yes
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)

Publish Flags

The publish command supports dry-run validation and explicit auth tokens for CI/CD environments.

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

# Publish with an explicit auth token
pharos publish --token phs_live_xxx

# Short form for --token
pharos publish -t phs_live_xxx

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

# Hide a version from search and direct lookup
pharos unpublish my-awesome-mcp-server --version 1.0.0

# Re-activate a previously unpublished version
pharos republish my-awesome-mcp-server --version 1.0.0

# Permanently remove a version (irreversible)
pharos purge my-awesome-mcp-server --version 1.0.0 --yes
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, store a Pharos token as a GitHub Actions secret and pass it to pharos publish --token.

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

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install Pharos
        run: go install github.com/Wpnx330/pharos-cli@latest
      - name: Publish
        run: pharos publish --token ${{ secrets.PHAROS_TOKEN }}

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

OAuth-Enabled Servers

If your MCP server requires OAuth (e.g. accessing a user's Google Drive or Salesforce), register your OAuth provider details with the Pharos registry. This lets Pharos handle the OAuth flow inline — users authorize without leaving their chat app.

Register OAuth config
pharos oauth configure my-salesforce-server \
  --auth-url https://login.salesforce.com/services/oauth2/authorize \
  --client-id 3MVG9...your-client-id \
  --scopes api,refresh_token \
  --pkce

Flags

  • --auth-url — OAuth authorization endpoint (required)
  • --client-id — Your registered client ID (required)
  • --scopes — Comma-separated scopes to request
  • --pkce — Require PKCE (default: true)
  • --client-secret — For confidential clients (optional)

See the Agent MCP + OAuth guide for the full end-to-end flow from the user's perspective.

Next Steps