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.
# 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.yourusernameCreate 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 a new pharos.json in the current directory
pharos init --name my-awesome-mcp-server --runtime npm --transport stdio{
"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.tsfiles.transport—stdio,http, orsse.runtime—npm,python,rust,dotnet, ordocker.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 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 metadataManifest: [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:
# 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.
# 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 --signMulti-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].
# 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 tryManaging 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.
# 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-serverPackage: 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... ✓ verifiedCI/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
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-supportedVerified 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.