opik-mcp

hosted-auth

Purpose

hosted-auth is the HTTP app the Docker image serves. It checks the bearer on each request, validates OAuth tokens against opik-backend, serves the OAuth discovery documents and records who the caller is. Open it to learn what a host sees when a token is missing, expired or an API key, and where to change that.

What it does now

Two kinds of bearer

Every request to the MCP path needs Authorization: Bearer <token>. A token that starts with OAUTH_ACCESS_TOKEN_PREFIX (in src/opik_mcp/identity/context.py) is an OAuth token. Any other bearer is an API key.

  OAuth token API key
Checked by opik-mcp Introspected on every request, with a short cache No
Forwarded to opik-backend The full Authorization header The full Authorization header
Workspace Taken from the token by opik-backend; an inbound Comet-Workspace header is forwarded and checked against it The inbound Comet-Workspace header, else OPIK_WORKSPACE (or COMET_WORKSPACE), else default
Dead credential HTTP 401 invalid_token, so the host refreshes. A backend 401 on a data call first comes back as a tool error inside HTTP 200; the retry gets the 401 A tool error inside HTTP 200 that says to check OPIK_API_KEY and OPIK_WORKSPACE

Whether a hosted API-key call should fall back to OPIK_WORKSPACE is an open question in runtime.

What a host gets back

OAuth validation and refresh

Workspace name and caller identity

opik-mcp never chooses an OAuth call’s workspace. opik-backend rejects a forwarded header that does not match the token (McpOAuthService.verifyWorkspaceHeaderMatchesToken, per the comment on inbound_workspace). The introspected name is display-only (resolved_workspace_name); its precedence is in tool-surface.

Caller identity feeds analytics and never decides access. The rule is in caller_identity_with_outcome (src/opik_mcp/identity/caller.py): an OAuth token uses what introspection stored for it, an inbound API key is a miss, and stdio resolves the install’s own key through src/opik_mcp/identity/account.py on cloud Comet only.

How it works

host -> AuthRejectionMiddleware -> BearerAuthMiddleware
        (shape check, OAuth validation, ContextVars set)
     -> MCP session manager -> session task
     -> install_request_auth_rebinding (ContextVars from this request)
     -> tool -> resolve_opik_config -> OpikClient -> opik-backend

Boundaries: runtime owns the outbound client and resolve_opik_config, analytics the rejection event and identity fields, release the image and chart, tool-surface the instructions and links.

Decisions

Traps

Proven by

Log