Skip to content

cli: stored-auth suite — --use-stored-auth, --wait-for-auth, --list-stored-auth, --print-handoff #1575

Description

@cliffhall

Summary

Let the CLI reuse OAuth credentials obtained in the web inspector on the same machine (web → CLI handoff):

  • --use-stored-auth — read oauth.json (the shared store the web backend writes) and inject Authorization: Bearer <token> for --server-url; error (exit 3, auth_required) listing stored keys when no token matches.
  • --wait-for-auth <sec> — poll oauth.json (500ms interval) for the URL-normalized server key, then proceed.
  • --list-stored-auth — print stored server keys and exit (short-circuit, no connect).
  • --print-handoff <serverUrl> — emit {deepLink, portForwardCmd, oauthStatePath, apiToken} for driving the browser-side OAuth dance from a script/remote VM.
  • State-path resolution precedence: MCP_INSPECTOR_OAUTH_STATE_PATHMCP_STORAGE_DIR/oauth.json~/.mcp-inspector/storage/oauth.json.
  • Server keys normalized with the same new URL().href scheme the web store uses, so both sides agree.

Reference implementation (PR #1510)

Re-implement informed by these changes at 33fac3f:

  • clients/cli/src/cli.tsnormalizeServerUrl(), resolveOAuthStatePath(), readOAuthServers(), waitForStoredToken(), buildHandoff(), async parseArgs with short-circuit modes, token-injection block
  • clients/cli/tests/stored-auth.test.ts — injection, polling/timeout, listing, handoff, normalization (+373)

Depends on

Notes

  • The reference implementation reads the Zustand-persist blob directly from disk (not through NodeOAuthStorage) so polling works — decide deliberately whether to keep that or route through the storage class.
  • Tokens are injected blindly; a stale token surfaces as HTTP 401 → exit 3. Document this and all four flags in clients/cli/README.md.
  • Coverage gate ≥90 on all four dimensions.

Part of the PR #1510 decomposition (see tracking issue).

Metadata

Metadata

Assignees

Labels

v2Issues and PRs for v2

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions