MCP support (#140)
Publish Nexus's control plane as an MCP server, so Claude — on a phone, on the desktop, or inside another Nexus worker — can open sessions, message them, tear them down, and answer "is anything waiting on me?" without opening the web UI.
Tracks docs/superpowers/specs/2026-09-15-mcp-server-design.md (issue #140).
Shape
Nexus is an OAuth 2.0 resource server; an embedded but pluggable OAuth 2.1 authorization server issues the tokens. One instance setting drives both the advertised issuer and the active verifier, so they cannot disagree — point it at an external IdP and the authorization server simply isn't mounted.
Phone access requires OAuth, not a bearer token: static_headers is Beta and org-admin-only. Nexus is already public at a.lck.sh behind TLS, so there is no exposure work.
Sequence
Prerequisites — independent of MCP, shippable now:
- Migrate to zod v4 (the SDK needs it)
- Rate-limit
/api/auth/unlock(#110 item 1 — already live-exposed) - Unify the unlock redirect onto one builder
Authorization server: oidc-provider + storage adapter + consent; CIMD allowlist and resolver; Settings → MCP panel.
Resource server: the /api/mcp endpoint — transport, metadata, bearer challenge, Host/Origin validation, per-tool scopes.
Tools: get_nexus_info + attention roll-up; session lifecycle; workspace lifecycle; send_message.
Slice 2: the machine principal, unlocking create_workspace and start_workspace — the only two tools needing a vault key.
Findings that reversed a decision
Recorded in full in the spec. Three are worth repeating because they overturned choices already made:
- Forgejo OAuth2 tokens are unscoped and account-wide, which killed delegating authorization to it — a token to list workspaces would also delete every repo on the forge.
- MCP 2026-07-28 deprecated DCR in favour of CIMD, inverting which registration mechanism to build on.
@modelcontextprotocol/serverv2.0.0 is Fetch-native, which reversed the decision to hand-roll the protocol layer and keeps/api/mcpinside the auth gate.