Skip to content

feat(mcp): /mcp panel + status-bar slot + tool/serverUpdated handler#2

Open
ssjoleary wants to merge 3 commits into
mainfrom
phase-7-mcp
Open

feat(mcp): /mcp panel + status-bar slot + tool/serverUpdated handler#2
ssjoleary wants to merge 3 commits into
mainfrom
phase-7-mcp

Conversation

@ssjoleary
Copy link
Copy Markdown
Contributor

Summary

  • New src/eca_cli/mcp.clj — MCP state slice, tool/serverUpdated handler, /mcp panel, status-bar fragment, and mcp/connectServer dispatch on requires-auth activation.
  • Status-bar slot shows aggregate health: MCPs: 3/4 ⚠ (wide) / M:3/4 (narrow); hidden when no MCPs configured.
  • Panel rows show per-status emoji (🟢 running · 🟡 starting · 🔴 failed · ⚪ stopped · ⚫ disabled · 🟠 requires-auth), tool count, status text, and [connect] affordance on requires-auth rows.
  • Init is event-driven — server emits one tool/serverUpdated per configured MCP at startup, no client pre-population needed.

Tracks Phase 7 in docs/roadmap.md.

Decisions worth flagging

  • No error field in tool/serverUpdated — protocol confirms (no error field). Failed rows render (check ~/.cache/eca/eca-cli.log) as a generic hint, matching the eca-emacs UX (eca-mcp.el:250-256).
  • No per-MCP provider mapping for auth — protocol confirms. requires-auth rows show a generic [connect] button that dispatches mcp/connectServer {name}.
  • Empty /mcp shows a system message rather than opening an empty picker, mirroring the existing cmd-open-model-picker empty-state pattern.

Status-bar slot order

Frozen as part of Wave 1 architecture decision:
```
workspace · loading · model · agent · variant · [MCPs:n/m] · [N jobs] · tokens · cost · ctx% · title · trust
```
This PR owns the `[MCPs:n/m]` slot. The `[N jobs]` slot is delivered by the Phase 11b PR.

Test plan

  • `bb test` — 93 tests, 429 assertions, 0 failures
  • New `test/eca_cli/mcp_test.clj` (6 deftests): notification handler upsert, no-duplicate, status-bar widths, panel render snapshot, connect-server dispatch, command registration
  • clj-kondo: 0 new warnings on `mcp.clj` / `mcp_test.clj`

brepl smoke

```
AC4 (160 cols, 3/4 running): "MCPs: 3/4 ⚠"
AC5 (160 cols, 4/4 running): "MCPs: 4/4 ✓"
AC6 (80 cols, 3/4 running): "M:3/4"

Panel rows:
🟠 alpha · 0 tools · requires-auth [connect]
🔴 bravo · 1 tools · failed (check ~/.cache/eca/eca-cli.log)
🟢 charlie · 2 tools · running
```

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds MCP awareness to the CLI by tracking server updates, exposing a /mcp status panel, and surfacing aggregate MCP health in the status bar.

Changes:

  • Introduces eca-cli.mcp for MCP state handling, panel rendering, status-bar fragments, and connect dispatch.
  • Wires tool/serverUpdated notifications, /mcp command registration, and mcp/connectServer protocol notification.
  • Adds MCP-focused tests and includes them in the Babashka test task.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/eca_cli/mcp.clj Adds MCP state, rendering, status summary, and connect handling.
src/eca_cli/view.clj Renders the MCP picker panel and inserts MCP status into the status bar.
src/eca_cli/state.clj Routes MCP notifications and MCP picker Enter handling.
src/eca_cli/protocol.clj Adds mcp/connectServer notification helper.
src/eca_cli/commands.clj Registers the /mcp command.
test/eca_cli/mcp_test.clj Adds tests for MCP updates, rendering, connect dispatch, and command registration.
bb.edn Includes MCP tests in the test task.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/eca_cli/view.clj
Comment on lines +69 to +73
(let [{:keys [kind query list]} (:picker state)]
(if (= :mcp kind)
(str "MCP servers\n"
(divider (:width state)) "\n"
(str/join "\n" (mcp/render-mcp-panel-lines state)))
Comment thread src/eca_cli/mcp.clj Outdated
(update :tools #(or % []))
(update :prompts #(or % []))
(update :resources #(or % [])))
state' (assoc-in state [:mcps name] entry)]
ssjoleary and others added 2 commits May 15, 2026 19:44
Addresses PR #2 review:
- Panel now renders from picker's :filtered, not :mcps directly,
  so display matches Enter target after filter typing.
- tool/serverUpdated refreshes picker :all/:filtered when the
  panel is open, preserving query/selection where possible.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace three copies of `(and (= :picking (:mode state)) (= :mcp (get-in state [:picker :kind])))` (two in mcp.clj, one in state.clj) with `mcp/picker-open?`. Policy of "MCP picker is the active overlay" lives in one place.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants