MCP on a self-hosted deployment#

Connect an MCP client to a self-hosted Nominal deployment. On a Nominal-managed deployment, follow Nominal MCP instead.

Your administrator enables one of two modes, OAuth or API key. Ask your administrator which one your deployment uses. In the commands below, replace <api-host> with your deployment’s API host.

OAuth#

OAuth sign-in works when the deployment’s identity provider is Okta and your administrator has enabled OAuth on the MCP endpoint. 🔒︎Configure AI > External MCP server explains the administrator’s setup.

Set up your client as described in Nominal-managed setup. Your administrator also registers each client’s sign-in callback (redirect URI) on the Okta application, for both localhost and 127.0.0.1. Claude Code and Codex use different callbacks, so tell your administrator which clients you use:

  • Claude Code: http://localhost:54545/callback, the bare /callback path.

  • Codex: http://localhost:54545/callback/<segment>. The segment is derived from your MCP server URL and is the same for everyone on your deployment. Compute it before signing in:

    python3 -c 'import hashlib,base64,sys;print(base64.urlsafe_b64encode(hashlib.sha256(sys.argv[1].encode()).digest()[:9]).decode().rstrip("="))' \
      "https://<api-host>/mcp"
    

API key#

Create a Nominal API key (see API Keys Setup). The client sends it on every request as Authorization: Bearer <your-api-key>. API key mode needs no client ID or callback port.

claude mcp add nominal --transport http \
  https://<api-host>/mcp \
  --header "Authorization: Bearer <your-api-key>"

In ~/.codex/config.toml:

[mcp_servers.nominal]
url = "https://<api-host>/mcp"
bearer_token_env_var = "NOMINAL_API_KEY"

Then set the API key in the environment Codex runs in:

export NOMINAL_API_KEY="<your-api-key>"
{
  "mcpServers": {
    "nominal": {
      "url": "https://<api-host>/mcp",
      "headers": {
        "Authorization": "Bearer <your-api-key>"
      }
    }
  }
}

If a step fails, see Troubleshooting.