Skip to content

MCP Server

BMO can expose its tools as an MCP (Model Context Protocol) context server over stdio or proxy-terminated HTTP, making it compatible with Zed, VS Code, and any MCP-aware editor or agent.

On stdio transport there is no per-request identity; a single process/session is assumed, which is suitable for single-user local editors.

Terminal window
bmo serve-mcp

By default this exposes:

  • Four read-only tools: view, glob, grep, ls
  • Two prompts: summarize_session, task

bmo_run is available only when explicitly listed in options.mcp_server.exposed_tools.

bmo_nanite_enqueue (background nanite lane — same as bmo nanite run) is also opt-in via exposed_tools. It needs a coordinator-backed app and configured providers, but it does not require the non-interactive permission policy that bmo_run does. The HTTP server exposes the same behavior at POST /v1/sessions/{id}/nanite (Bearer auth). With merged config, options.nanite_recovery_fail_fast applies to these headless enqueues the same as the CLI (TPM / spend semantics; not a request or response field). See Nanites for behavior and evidence details.

Arena parity tools (also opt-in): bmo_arena_create_round, bmo_arena_get_candidates, bmo_arena_accept, bmo_arena_dismiss, bmo_arena_merge, bmo_arena_stitch. Listing any of them requires a configured agent coordinator (same startup gate as bmo_run without the non-interactive policy requirement). They mirror the HTTP arena lifecycle under bmo serve (including stitch when enabled in config). Optional coordinator auto-winner policies such as options.arena.auto_select_policy = "eval_shadow" apply the same as in the TUI when a round completes. See arena-verified.md for arena behavior and config; see Configuration reference for auto_select_* keys.

Workspace observer parity: bmo_get_workspace_snapshot returns the same JSON as the native workspace_snapshot agent tool (embedding + checkpoint hints; git summary included by default when options.include_git_state is on — set include_git_state = false to omit). The observer is on by default; disable with [options.workspace_observer] enabled = false if you need a slimmer surface. Requires a coordinator-backed MCP runtime and the observer enabled in config. The HTTP server exposes the same JSON at GET /v1/workspace-environment (Bearer auth) when the observer is enabled; MCP still requires listing the tool in exposed_tools. See workspace-observer.md.

When the MCP runtime is attached to the full app, workspace snapshots can also include the current process-local workspace claim snapshot. Minimal PathScope-only serve-mcp has no shared bmo.db, no co-located TUI session/message parity, and no full-app claim store; do not describe that mode as sharing live workspace state with an interactive TUI.

Operating mode parity (opt-in feature): bmo_get_operating_mode returns the same JSON as the native get_operating_mode tool and GET /v1/session-operating-mode (enabled gate, posture state, active pack name, preset id, optional manifest path, and redacted diagnostics/counts). Requires options.operating_packs = true, a coordinator-backed MCP runtime, and listing the tool in exposed_tools. See Operating mode parity.

Agent kinds parity (opt-in): bmo_list_agent_kinds returns the same JSON as the native list_agent_kinds tool and GET /v1/agent-kinds (configured agent kinds from effective merged config). Requires a coordinator-backed MCP runtime (same startup gate as workspace snapshot tools) and listing the tool in exposed_tools. See Agent kinds.

Agent run ledger (opt-in): bmo_list_agent_runs lists rows from the durable agent_runs store with the same JSON as GET /v1/agent-runs (generated_at, total, runs with full records including parent_session_id). Query parameters match the HTTP API (session_id, family_session_id, limit, and optional filters). The agent run ledger tables are available when BMO has a data directory with a bootstrapped bmo.db and a configured run store (the usual full-app path—not PathScope-only serve-mcp without a shared DB). The separate OpenAI-compat run ledger and its HTTP routes need [options.openai_compat] after bootstrap. Requires a coordinator-backed MCP runtime and listing the tool in exposed_tools. See Durable run ledger and agent-run-ledger-sessions.md.

Fleet health signals (HTTP only): bmo serve / bmo up can accept POST /v1/health-signals (Bearer auth) when [options.health_signals_ingress] enabled = true. No MCP tool is registered for this path; use HTTP from Alertmanager or other automation. See health-signals-ingress.md and Fleet and external metrics.

When serve-mcp uses the full app (same data directory and bmo.db as bmo serve / the TUI), opt-in MCP tools mirror session operator, todo/message, schedule, and curated config surfaces. Add the tool names you need to options.mcp_server.exposed_tools (see internal/mcp/tools/catalog.go groups session, session_data, schedule, config).

GroupExample MCP tools
Session operatorbmo_list_sessions, bmo_get_session_budget, bmo_session_diagnose
Session databmo_list_todos, bmo_add_todo, bmo_update_todo, bmo_delete_todo, bmo_list_messages, bmo_send_message
Finding lifecyclebmo_list_findings (opt-in options.finding_lifecycle.enabled; same JSON as agent list_findings)
Schedulebmo_schedule_list, bmo_schedule_create, bmo_schedule_update, bmo_schedule_delete
Configbmo_config_get, bmo_config_set, bmo_config_list, bmo_config_unset

Maintainer hub (CLI equivalents, tri-surface expectations): headless-session-automation.md and session-operator-cli.md.

The read-only tools are confined to allowed_roots (default: the working directory). The bmo_run tool delegates complete coding tasks back to BMO, but it is opt-in and requires a non-interactive permission policy (no approval UI) and configured providers/models. If you add bmo_run to exposed_tools without those prerequisites, bmo serve-mcp exits at startup with a clear configuration error instead of starting in a degraded state.

The MCP server exposes two prompts that clients can use for context or one-off Q&A:

  • summarize_session — Template for summarizing a BMO conversation to preserve context (e.g. when resuming work later).
  • task — Concise Q&A prompt for one-off questions or task-style turns; responses are tuned for CLI display.

Clients can list available prompts with ListPrompts and fetch a prompt’s description and message content with GetPrompt (standard MCP prompt methods).

See Zed for the full setup guide. Quick start:

Terminal window
task zed:configure # auto-detects bmo binary and writes ~/.config/zed/settings.json

Add BMO as an MCP server in your editor’s MCP configuration. Refer to your editor’s MCP documentation for the exact config format, providing:

  • Command: path to the bmo binary
  • Args: ["serve-mcp"]

The serve-mcp command reads options.mcp_server from config: bind (HTTP listen address), allowed_roots (filesystem scope for read-only tools), and http (identity_header, trusted_proxies) for proxy-terminated HTTP. Configure in bmo.toml:

[options.mcp_server]
enabled = true
bind = "127.0.0.1:8765"
allowed_roots = ["."]
# exposed_tools = ["view", "glob", "grep", "ls", "bmo_send_message", "bmo_run"]
[options.mcp_server.http]
identity_header = "X-Authenticated-User"
trusted_proxies = ["127.0.0.1"]

Once the MCP export hub is enabled, BMO offers parallel surfaces with the HTTP/SSE hub so operators can read posture from any front end without spelunking logs:

  • CLI: bmo config show-mcp-server prints the merged options.mcp_server block — enabled, transport, bind, allowed_roots, exposed_tools, and the proxy-guard mode (loopback_only vs proxy_guard). It does not print secrets.
  • TUI slash: /serve-mcp (aliases /serve_mcp, /mcp-server, /mcp_server) renders the same merged config plus a Live hub panel with the running endpoint, tool_count, exposed_tools, and LocalServiceState (running / failed / etc.) when the in-process server is attached. The pre-existing /mcp command still resolves to client protocols (external MCP clients), unchanged.
  • Sidebar: The MCP export row mirrors the Serve row’s posture chip — off, idle (stdio), idle (http, proxy), running (loopback), running (proxy), or failed.
  • Structured logs: All lifecycle transitions are emitted under mcp_server.fired / mcp_server.action (outcomes: listening, startup_rejected, shutdown_started, shutdown_complete, tool_call_started, tool_call_completed, tool_call_failed). These are distinct from http_server.* (the HTTP/SSE hub) and mcp_client.* (external MCP clients BMO talks to).

HTTP transport is intended for deployments behind a trusted reverse proxy. BMO requires:

  • options.mcp_server.http.identity_header
  • options.mcp_server.http.trusted_proxies

Requests from untrusted proxy IPs are rejected, and requests missing the configured identity header are rejected. BMO does not terminate TLS or provide built-in bearer auth in this mode.

See Configuration Reference for all MCP server options.