Skip to content

MCP Phase 2

  1. Here's what we want to do:
  2. On startup, Keen should simply try to connect using whatever credentials are already available.
  3. If connection fails, Keen should notify the user in the REPL and suggest /mcp refresh <tool-name>.
  4. OAuth tokens must be stored on disk and reused.
  5. Reuse the existing OAuth flow in internal/auth/oauth.go and internal/auth/store.go.
  6. Startup must not try to resolve auth or open the browser.
  7. User-triggered refresh should initiate the full OAuth flow and open the browser.
  8. Save a comprehensive phase 2 todo list in .ai-interactions/tasks/issue-43/output-2_mcp-phase-2.md, first describing what this phase is doing and then listing all tasks.
  9. Implement phase 2.
  10. Reuse existing OAuth code where possible. Explain what was missing if it is not reused directly.
  11. /mcp refresh should not be only for OAuth. It should refresh the configured server using whatever auth mode applies.
  12. mcpRuntime should be part of the REPL context or app state only if that matches existing architecture. Prefer declaring MCP runtime-related types in the mcp package, like config/providers patterns.
  13. Put MCP-specific OAuth helpers in the mcp package and reuse generic pieces from internal/auth. Keep Keen provider OAuth and MCP OAuth separated.
  14. The startup wait timeout is for the UI status command, not the underlying MCP connection attempts. Avoid making the REPL wait too long.
  15. In handleMCPStartupStatus, wrap messages within the window and reuse existing wrapping helpers where sensible.
  16. internal/cli/repl/mcp.go should not exist. Move those types into internal/mcp/types.go.
  17. Remove premature synchronization from Manager.Start. Keen will not call Start twice inside the same process.
  18. Remove manager-level wg; use local wait groups only.
  19. Close() should sequentially close in-memory server sessions. Do not add locking unless it is needed.
  20. Closing Streamable HTTP sessions on Keen shutdown is unnecessary and slows exit. Stop attempting to close Streamable HTTP on shutdown; still close stdio sessions.
  21. Simplify closeSession after skipping Streamable HTTP in Close.
  22. MCP can use its own logger; do not propagate the root logger into the MCP manager.
  23. Since slog.Default() is the logger initialized in cmd/main.go, use slog.Default() directly in MCP.
  24. Add proper MCP logs and review the latest log file to verify startup/connection visibility.
  25. Add proper MCP logs and review the latest log file to verify startup/connection visibility.
  26. /mcp status should use the same table style as the skills status table. Reuse existing table rendering where possible.
  27. In /mcp status, disconnected should use ErrorStyle.
  28. Startup should show failed MCPs early; do not wait for the full connection timeout before notifying the user.
  29. Manual /mcp refresh needs enough time for OAuth browser authentication. Use a named refresh timeout constant and apply it to both the command context and refresh connect timeout.
  30. Explain the MCP authentication flow from entry point to final authentication success.
  31. Simplify MCP authentication:
  32. Load OAuth tokens from auth.json once into manager memory.
  33. API keys remain available from MCP config.
  34. Startup goroutines read in-memory credentials.
  35. /mcp refresh <server> opens browser for OAuth, saves the token to auth.json, and updates memory.
  36. Remove unnecessary memory/disk token-store split.
  37. Remove internal/mcp/doc.go.
  38. In loadOAuthTokens, only load auth store entries with the mcp: prefix.
  39. Simplify the MCP package by moving REPL-specific messages into internal/cli/repl/stream_msgs.go.
  40. Remove runtimeSnapshot from Manager.
  41. Remove local MCP tool argument schema validation and rely on server-side validation.
  42. Remove unused Manager fields configPath and config.
  43. Inspect the newly introduced serverRuntime RWMutex, explain whether races are real, and identify every scenario where serverRuntime can be concurrently accessed.
  44. Fix the unsynchronized rt.status read in discoverServer by moving it into the existing locked commit section.
  45. Run race tests and confirm go test -race ./... passes.