Skip to content

MCP Phase 2: Startup Status and User-Initiated OAuth

In this phase, Keen will move MCP authentication from automatic startup resolution to an explicit user action. On startup, Keen will only try to connect to configured MCP servers using credentials that are already available: no auth, configured API keys, or OAuth access tokens stored on disk. If a server cannot connect for any reason, Keen will mark it disconnected and notify the user in the REPL with a suggestion to run /mcp refresh <tool-name>.

OAuth authorization will happen only when the user runs the refresh command. At that point, Keen can open the browser, complete the authorization-code flow, exchange the code for tokens, store the tokens on disk, and reconnect the MCP server. The implementation should reuse the existing OAuth and token storage code in internal/auth/oauth.go and internal/auth/store.go where possible.

Todo

  1. Inspect current MCP implementation and startup wiring:
  2. internal/mcp
  3. internal/cli/cmd/root.go
  4. REPL command structure
  5. existing auth files: internal/auth/oauth.go, internal/auth/store.go

  6. Review current OAuth helper capabilities:

  7. how browser opening works
  8. how callback/code exchange is handled
  9. how tokens are stored and loaded
  10. whether token refresh is already supported

  11. Define the MCP auth lifecycle:

  12. startup only attempts connection with available credentials
  13. startup does not open browser
  14. startup does not initiate OAuth
  15. failed OAuth, missing token, or expired token marks server disconnected
  16. /mcp refresh <tool-name> initiates OAuth when needed

  17. Update MCP config/auth model if needed:

  18. support no auth
  19. support API key auth
  20. support OAuth using disk-backed token lookup
  21. make sure config names map cleanly to /mcp refresh <tool-name>

  22. Add disk-backed OAuth token support for MCP:

  23. reuse internal/auth/store.go
  24. define token keying strategy per MCP server
  25. load token during MCP startup
  26. save token after successful OAuth flow
  27. avoid logging token values

  28. Refactor MCP manager startup behavior:

  29. attempt connect for each configured server
  30. use API key when configured
  31. use stored OAuth token when available
  32. do not trigger OAuth flow automatically
  33. record disconnected state and reason on failure

  34. Add user-facing REPL notification for startup failures:

  35. collect MCP connection failures
  36. show concise REPL notices after startup
  37. suggest /mcp refresh <tool-name>
  38. avoid noisy repeated messages

  39. Add /mcp REPL command support:

  40. /mcp status
  41. /mcp refresh <tool-name>
  42. possibly /mcp list if status is not enough
  43. validate unknown tool or server names clearly

  44. Implement /mcp refresh <tool-name> flow:

  45. find configured MCP server
  46. detect auth type
  47. for OAuth: open browser and perform authorization-code flow
  48. store received token on disk
  49. reconnect the MCP server
  50. update status and notify user
  51. for API key or no-auth: retry connection without OAuth

  52. Integrate OAuth with MCP SDK correctly:

    • ensure authorization and token endpoints follow MCP auth spec discovery
    • use existing OAuth helpers where possible
    • keep MCP protocol behavior inside internal/mcp
    • keep CLI, browser, and user prompts in REPL or CLI layer
  53. Handle token refresh:

    • if a refresh token exists, try refresh before requiring browser flow
    • if refresh fails, mark disconnected
    • /mcp refresh <tool-name> should recover by running browser flow
  54. Improve MCP status model:

    • connected
    • disconnected
    • auth required
    • auth failed
    • config error
    • include last error safely redacted
  55. Add logging:

    • startup connection attempts
    • successful connection and tool count
    • disconnected or auth-required states
    • refresh attempts and outcomes
    • no secrets in logs
  56. Add tests for auth and startup behavior:

    • startup with no-auth server succeeds
    • startup with API key succeeds
    • startup with OAuth stored token succeeds
    • startup with OAuth missing token does not open browser
    • startup failure returns user-facing notification
    • failed connect marks server disconnected
    • missing config removes or ignores server as intended
  57. Add tests for /mcp refresh:

    • OAuth refresh opens flow only on command
    • token is stored after success
    • server reconnects after token save
    • API key and no-auth refresh retry connection
    • unknown server or tool name returns useful error
  58. Validate end-to-end configs:

    • public no-auth MCP server
    • OAuth MCP server, PostHog
    • API-key MCP server, Context7
    • keep local test fixture usable and documented
  59. Run required cleanup and validation:

    • gofmt on modified Go files
    • go mod tidy
    • go test ./...
    • manual go run cmd/main.go sanity check if needed
  60. Review git state:

    • separate our changes from pre-existing dirty files
    • summarize tracked and untracked changes clearly
    • do not revert unrelated user changes