# MCP Server Distribution Playbook (Indie Dev)

How to ship an MCP server that other people can use in Claude Code, Codex, Cursor and others **without drowning in per-environment testing**.

---

## Core idea

Most cross-environment pain comes from **local stdio servers**: every client on every machine launches your process with its own PATH, runtime version, env vars and shell quoting (Windows is worst).

**Fix:** host the server yourself and hand users a **URL**. The only environment that matters is the one you control. Your test matrix collapses from *clients × OSes × runtimes* to *"does my endpoint speak MCP correctly?"*, which you test once, in CI.

---

## 1. Primary product: remote Streamable HTTP server

- [ ] Expose a Streamable HTTP endpoint, e.g. `https://mcp.yourservice.com/mcp`
- [ ] Support **OAuth** with standard discovery documents:
  - `/.well-known/oauth-protected-resource`
  - `/.well-known/oauth-authorization-server`
  - Dynamic client registration, so users never paste a client ID or secret
- [ ] Offer **API keys** as a fallback (sent as `Authorization: Bearer <key>`)
- [ ] Rate limiting, logging and health check on your side

### Why this works

- Claude Code and Codex both support remote HTTP servers natively.
- In Codex, the CLI, IDE extension and desktop app share one `~/.codex/config.toml`, so one setup covers all three.

---

## 2. Optional: local stdio package

Only ship this if users need local access, such as their files or offline use.

- [ ] Publish as **one pinned command**:
  - Node: `npx -y yourpkg@x.y.z`
  - Python: `uvx yourpkg==x.y.z`
  - Or a Docker image (`ghcr.io/you/yourpkg:x.y.z`)
- [ ] No reliance on global installs or the user's PATH beyond `npx`/`uvx`/`docker`
- [ ] All config via env vars, documented
- [ ] Smoke test runs on an OS matrix in CI (see section 3)

---

## 3. Automate protocol testing (not client testing)

Test the **server**, not each client. If the protocol test passes, the clients will work.

- [ ] Use the official **MCP Inspector** in CLI mode in CI:
  - connect → `tools/list` → call each tool → assert on results
- [ ] For the stdio package, run it on `ubuntu-latest`, `macos-latest`, `windows-latest`
- [ ] Manual check in Claude Code + Codex **only at release time**

### Example CI workflow (template)

```yaml
# .github/workflows/mcp-smoke.yml
name: MCP smoke test
on: [push, pull_request]

jobs:
  remote:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: 22 }
      # Start your server locally (adjust to your stack)
      - run: ./scripts/start-server.sh &
      - run: sleep 5
      # Check that tools are listed (check Inspector flags for your version)
      - run: |
          npx -y @modelcontextprotocol/inspector --cli \
            http://localhost:3000/mcp --transport http \
            --method tools/list

  stdio:
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: 22 }
      - run: npm ci && npm run build
      - run: npx -y @modelcontextprotocol/inspector --cli node dist/index.js --method tools/list
```

---

## 4. Distribution: official MCP Registry

- [ ] Install `mcp-publisher` (`brew install mcp-publisher` or a release binary)
- [ ] `mcp-publisher init` → edit `server.json` (supports **remote** endpoints and packages)
- [ ] Namespace:
  - `io.github.<username>/<server>` → verified via GitHub login
  - `com.yourdomain/<server>` → verified via DNS TXT or a `.well-known` file
- [ ] `mcp-publisher validate`
- [ ] Auto-publish on release from GitHub Actions:

```yaml
# .github/workflows/publish.yml (excerpt)
permissions:
  id-token: write
  contents: read
steps:
  # ... publish npm/PyPI/Docker package first, if any ...
  - name: Install mcp-publisher
    run: |
      curl -L https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher-linux-amd64 -o mcp-publisher
      chmod +x mcp-publisher
  - name: Publish to MCP Registry
    run: |
      ./mcp-publisher login github-oidc
      ./mcp-publisher publish
```

> **Caveat:** The official registry is still a preview service, and most clients don't auto-discover from it yet. It helps people find you, but you still need copy-paste install snippets in your docs.

---

## 5. Docs: per-client "Install" section

This prevents most support questions. Keep one snippet per client.

### Claude Code

```bash
claude mcp add --transport http yourservice https://mcp.yourservice.com/mcp
```

### Codex (CLI / IDE extension / desktop app)

```bash
codex mcp add yourservice --url https://mcp.yourservice.com/mcp
codex mcp login yourservice   # OAuth
```

Or in `~/.codex/config.toml`:

```toml
[mcp_servers.yourservice]
url = "https://mcp.yourservice.com/mcp"
# API key alternative. Must be an env var name; a literal bearer_token is rejected for HTTP servers
bearer_token_env_var = "YOURSERVICE_API_KEY"
```

### Cursor / others

```json
{
  "mcpServers": {
    "yourservice": { "url": "https://mcp.yourservice.com/mcp" }
  }
}
```

### Local (stdio) variant, if offered

```toml
# Codex
[mcp_servers.yourservice]
command = "npx"
args = ["-y", "yourpkg@x.y.z"]
```

---

## Minimal indie setup (TL;DR)

1. Hosted Streamable HTTP endpoint + OAuth (API key fallback)
2. Inspector-based protocol test in CI
3. Auto-publish to the MCP Registry on release
4. Per-client install snippets in docs
5. *(Optional)* pinned `npx`/`uvx`/Docker package, tested on an OS matrix

---

## Sources

- [Codex MCP docs (OpenAI)](https://developers.openai.com/codex/mcp)
- [PolicyLayer: Codex MCP config](https://policylayer.com/integrations/codex)
- [Sevalla: Connect Codex](https://docs.sevalla.com/ai-agents/codex.md)
- [LiteLLM: Codex CLI setup](https://docs.litellm.ai/docs/proxy/client_setup/codex_cli)
- [NeuralTrust: TrustGate with Codex (OAuth discovery)](https://docs.neuraltrust.ai/trustgate/mcp/codex)
- [MCP Registry publishing guide](https://modelcontextprotocol.info/tools/registry/publishing/)
- [Microsoft: Publish to the Official MCP Registry](https://learn.microsoft.com/en-us/dotnet/ai/quickstarts/publish-mcp-registry)
- [StackOne: MCP Registry, how to get listed](https://www.stackone.com/blog/mcp-registry-how-to-get-listed/)
- [Augment Code: MCP Registry](https://www.augmentcode.com/mcp/mcp-registry)
