---
name: mcp-fixed-callback-port
description: "How to pin a static OAuth callback port for MCP server adds on the VPS (use --callback-port, NOT an env var)"
metadata: 
  node_type: memory
  type: reference
  originSessionId: 2af123ba-23bf-4756-828d-a7027cf187ae
---

To pin a static OAuth callback port for MCP server authentication in Claude Code, use the `--callback-port` flag on `claude mcp add` — there is **no** `MCP_OAUTH_CALLBACK_PORT` env var (that does not exist and is silently ignored).

VPS standard port: **8976**. Redirect URI to pre-register with the provider: `http://localhost:8976/callback`.

```bash
claude mcp add --transport http --callback-port 8976 <name> https://mcp.example.com/mcp
# Provider without Dynamic Client Registration → add: --client-id <id> --client-secret
```

Or via JSON config: `"oauth": { "callbackPort": 8976 }`.

**Critical for headless VPS:** Claude Code runs headless on the VPS but the OAuth browser flow runs on the Mac. The provider redirects the Mac's browser to `http://localhost:8976/callback`, but the listener is on the VPS. Without forwarding, "localhost" = the Mac (nothing listening) → `connection refused` / curl exit 7. Open an SSH tunnel from the Mac BEFORE running the OAuth flow:

```bash
# on the Mac, before the /mcp OAuth flow:
ssh -L 8976:localhost:8976 root@<vps-ip>
```

Three things must share the same port: (1) `--callback-port 8976` on the VPS add, (2) `ssh -L 8976:localhost:8976` tunnel on the Mac, (3) `http://localhost:8976/callback` registered with the provider.

**Why:** Ephemeral random ports (e.g. 62090, 63518) make re-auth fragile — the listener closes after timeout and the provider can't pre-register a moving redirect URI. A fixed port + SSH tunnel makes headless re-auth reliable.

**How to apply:** When adding any new MCP server on the VPS: tunnel `8976` from the Mac first, then `claude mcp add --callback-port 8976 ...`, then `/mcp`. Source: code.claude.com/docs/en/mcp.md → "Use a fixed OAuth callback port".
