HELIX

ADR-0005 — OAuth 2.1 and external MCP servers

Context

ADR-0004 gave us static scoped keys (hlx_...), which are fine for a first-party embedder but wrong for third-party ones: they cannot be delegated, scoped down per-user, or revoked independently. Separately, G4 requires that every tool be reached through MCP semantics — including tools that live outside the runtime.

Decision: OAuth 2.1 as an advertised capability

When a runtime advertises auth.oauth2, OAuth 2.1 flows are available and discoverable via .well-known/oauth-authorization-server. Static keys remain supported; OAuth is additive, not a replacement. The scope vocabulary from ADR-0004 is reused verbatim as the OAuth scope set, so there is exactly one permission model regardless of how the token was obtained.

Decision: two tool paths, one uniform tool list

The agent sees a single tool list regardless of where a tool physically lives.

On every invocation the runtime resolves the tool’s source by namespace prefix, applies budget/ceiling/scope checks, then propagates execution contextsession_id, agent_id, run_id, subject_id(s) — to the MCP server via MCP-standard _meta, so downstream tools can tag their outputs for compliance.

Tool metadata carries requires_subject_id, side_effect_class (read | write | external) and cost_hint. These are advisory inputs the runtime uses for budget and retry decisions, not enforcement.

Consequences