MCP in App settings and the status bar (#189) #202

Merged
crowmaki merged 2 commits from issue-189-mcp-settings into main 2026-10-11 08:09:12 +00:00
Owner

Closes #189. Part of #157.

What changed

  • App settings → MCP server page: the on/off switch, the port, the URL and the token, plus Copy URL, Copy token, Regenerate token… (asks first) and Copy client configuration. The configuration snippet holds a claude mcp add --transport http ai-studio <url> --header "Authorization: Bearer <token>" line and a JSON mcpServers entry for other harnesses. A port the page refuses goes back to the saved port.
  • A port in use shows the server's error on the page ("port N is already in use; choose another port").
  • Client sessions are counted. The server makes one handler per session. Each handler holds an OpenSession guard that counts the session while it lives, so the count drops when a harness ends its session, the session idles out, or the server stops. McpSettingsDto reports the count as clients.
  • Every window is told. A changed event of kind mcp (MCP_CHANGE) goes out when the server starts, stops or fails, and when a harness connects or leaves. A new mcp store in the root layout follows it.
  • Status bar: while the server is on, an MCP indicator shows "No client connected", "N client(s) connected" (green) or "Not listening" (red).
  • ADR-0006 lists the new indicator. CONTEXT.md defines the MCP server and Harness.

Known limits

  • The count follows rmcp's session lifetime, which has a 5-minute idle timeout by default (from #188). A harness that crashes without ending its session counts for up to 5 minutes. A harness that stays idle for 5 minutes drops to "No client connected".
  • The page shows and copies http://127.0.0.1:<port>/mcp even while the server is off, so the configuration can be set up before switching it on.

Testing

  • cargo test --workspace --all-features, bun test src and bun run check all pass.
  • New Rust tests: connecting and leaving is counted and broadcast. The settings report the count, and regenerating the token or changing settings broadcasts an mcp change. #188's test already covers the old token being refused.
  • Checked in the running app with run-ai-studio:
    • The switch turns the server on and off.
    • All three copy buttons put the right text on the clipboard.
    • A curl initialize makes the status bar and the page show a connected client.
    • After a regenerate, the old token gets 401 and the new one gets 200.
    • Port 8791, held by another process, shows the error on the page and "Not listening" in the status bar.
    • An invalid port shows an error and the box goes back to 8790.
    • The native confirm before Regenerate was not clicked, because the driver can't reach native dialogs. The regenerate itself was run through the same RPC.

The screenshots were taken before the review fixes, so the status line reads "Listening, …" where it now reads "Listening. …". The token is blacked out.

MCP page
Client connected
Port in use

Closes #189. Part of #157. ## What changed - **App settings → MCP server page:** the on/off switch, the port, the URL and the token, plus Copy URL, Copy token, Regenerate token… (asks first) and Copy client configuration. The configuration snippet holds a `claude mcp add --transport http ai-studio <url> --header "Authorization: Bearer <token>"` line and a JSON `mcpServers` entry for other harnesses. A port the page refuses goes back to the saved port. - **A port in use** shows the server's error on the page ("port N is already in use; choose another port"). - **Client sessions are counted.** The server makes one handler per session. Each handler holds an `OpenSession` guard that counts the session while it lives, so the count drops when a harness ends its session, the session idles out, or the server stops. `McpSettingsDto` reports the count as `clients`. - **Every window is told.** A `changed` event of kind `mcp` (`MCP_CHANGE`) goes out when the server starts, stops or fails, and when a harness connects or leaves. A new `mcp` store in the root layout follows it. - **Status bar:** while the server is on, an MCP indicator shows "No client connected", "N client(s) connected" (green) or "Not listening" (red). - ADR-0006 lists the new indicator. CONTEXT.md defines the MCP server and Harness. ## Known limits - The count follows rmcp's session lifetime, which has a 5-minute idle timeout by default (from #188). A harness that crashes without ending its session counts for up to 5 minutes. A harness that stays idle for 5 minutes drops to "No client connected". - The page shows and copies `http://127.0.0.1:<port>/mcp` even while the server is off, so the configuration can be set up before switching it on. ## Testing - `cargo test --workspace --all-features`, `bun test src` and `bun run check` all pass. - New Rust tests: connecting and leaving is counted and broadcast. The settings report the count, and regenerating the token or changing settings broadcasts an `mcp` change. #188's test already covers the old token being refused. - Checked in the running app with run-ai-studio: - The switch turns the server on and off. - All three copy buttons put the right text on the clipboard. - A curl `initialize` makes the status bar and the page show a connected client. - After a regenerate, the old token gets 401 and the new one gets 200. - Port 8791, held by another process, shows the error on the page and "Not listening" in the status bar. - An invalid port shows an error and the box goes back to 8790. - The native confirm before Regenerate was not clicked, because the driver can't reach native dialogs. The regenerate itself was run through the same RPC. The screenshots were taken before the review fixes, so the status line reads "Listening, …" where it now reads "Listening. …". The token is blacked out. ![MCP page](https://git.crowmaki.me/attachments/631ad9e0-60ea-4228-9228-bff467e6ebd6) ![Client connected](https://git.crowmaki.me/attachments/f1d0f122-0274-4b23-8e54-895adcb0103f) ![Port in use](https://git.crowmaki.me/attachments/d68b5cb7-0d44-4c9c-bc62-c7f1b1a8e468)
- App settings gains an MCP server page: the on/off switch, the port,
  the URL and token with copy buttons, Regenerate token (after a
  confirm), and Copy client configuration, whose snippet holds a
  `claude mcp add` command line and a JSON server entry.
- A port that can't be bound shows the server's error on the page.
- The server counts open harness sessions: each session's handler holds
  a guard that counts it while it lives. McpSettingsDto reports the
  count as `clients`.
- A `changed` event of kind `mcp` tells every window when the server
  starts, stops or fails, and when a harness connects or leaves.
- The status bar shows an MCP indicator while the server is on: no
  client, client connected, or not listening.
- One helper words the client count for the page and the status bar.
- The MCP store owns its changes (load, save, regenerate token), and
  reports a failed read like the other stores.
- A port the page refuses goes back to the saved port, and the box
  follows a port changed in another window.
- Rename the Rust session counter to OpenSession and the TS status
  bar summary to McpIndicator, so neither clashes with McpStatus.
- Tests use the public MCP_CHANGE constant.
- ADR-0006 lists the MCP indicator in the status bar; CONTEXT.md
  defines the MCP server and Harness.
crowmaki deleted branch issue-189-mcp-settings 2026-10-11 08:09:13 +00:00
Sign in to join this conversation.
No description provided.