Skip to content

docs(adr): Studio as a reverse MCP-over-ACP client (Part B connection model) - #36

Merged
brettchien merged 3 commits into
mainfrom
docs/adr-reverse-mcp-client
Aug 14, 2026
Merged

brettchien merged 3 commits into
mainfrom
docs/adr-reverse-mcp-client

Conversation

@brettchien

Copy link
Copy Markdown
Contributor

Drafted by Orca (ecs-claude) — flagging authorship (shared GitHub identity).

Part B of the fleet grouping + connection model ADR: the design for Studio as a reverse MCP-over-ACP client, so Orca (ECS) can drive Brett's fleet through Brett's running Studio, under Studio's identity. Product of the Part B study (study → ADR → implement).

Topology

  • Studio = ACP-WS client + MCP server — dials out (solves NAT), serves oab-mcp over the socket it holds.
  • Orca = the in-pod agent (MCP client) — consumes Studio's tools via the OAB MCP Facade meta-tools, executing under Studio's AWS identity (no creds provisioned on Orca).
  • Reuses openab's as-built reverse MCP-over-ACP (#1447) + wire contract; Studio only codes the client side.

Decisions (per Brett, 2026-08-14)

  • D1 — a single oab server with fleet-parameterized tools, not per-fleet servers. A single server addresses any number of fleets because the tools take a fleet name arg (needed anyway: fleets share a cluster, so a cluster arg can't name a fleet). Per-fleet deferred to cross-account/hard-isolation.
  • D2 — writes granted by the authed /acp connection (D-29 alignment); no per-call consent gate.
  • D3 — no server-initiated inbound (spec-aligned; oab-mcp tool set is static).

The one openab-side dependency (not auth — that's settled)

Session attachment + endpoint: Studio's declared server must land on Orca's session (Discord-driven, so Studio is a third party to it), and Studio must reach the hosting gateway with a scoped bearer. Sharply bounded; the feasibility gate for path (i). Path (ii) (headless standalone oab-mcp) needs none of this and is the interim.

Slices

  1. oab-mcp tools become fleet-aware (also completes Part A on the MCP side) — no openab dep
  2. Extract in-process oab-mcp handler (one impl, two transports) — no openab dep
  3. ACP-WS client + session lifecycle
  4. Tunnel dispatch (mcp/connect/mcp/message/mcp/disconnect/mcp/cancel)

Slices 1–2 can land immediately; 3–4's end-to-end verification depends on the §5 item.

Docs-only. Requesting review on the design (esp. §5) before I start slice 1.

🤖 Generated with Claude Code

… model)

Realizes the fleet ADR's Part B path (i) and resolves its §5 open questions.
Topology: Studio = ACP-WS client + MCP server (dials out, NAT-friendly),
Orca = in-pod agent/MCP-client consuming Studio's oab-mcp tools via the OAB MCP
Facade under Studio's identity. Reuses openab's as-built reverse MCP-over-ACP
(#1447) + wire contract; Studio codes the client side.

Decisions: D1 single `oab` server with fleet-parameterized tools (not per-fleet);
D2 writes granted by the authed /acp connection (D-29 alignment, no per-call
consent); D3 no server-initiated inbound. Names the one genuine openab-side
dependency — session attachment (land Studio's server on Orca's Discord-driven
session) + endpoint reachability/bearer — distinct from auth, which is settled.
Slices 1-2 (fleet-aware tools, in-process handler) need no openab dep.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
…tach gap)

Per Brett (2026-08-14): Studio is the session creator, dialing the remote agent
runtime; the gateway spawns the agent for that session (katashiro pattern), so
oab-mcp reaches the session's agent by construction — no "attach to a session you
didn't create" mechanism needed. A human later drives the session via a chat
surface in Studio for fleet management.

§5 rewritten: the OpenAB-side need shrinks to ordinary ACP-client concerns
(endpoint + transport bearer), not a new capability. Model B (inject tools into
the always-on Discord Orca's live session) is documented and explicitly deferred.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Reading src-tauri showed the desktop reaches oab-mcp only over the stdio sidecar
(McpClient), deliberately keeping aws out of the Tauri build (desktop-core-sidecar
ADR; src-tauri is its own workspace). So the tunnel dispatch relays inner MCP to
the running sidecar rather than linking oab-mcp in-process. Slice 2's lib split
stays useful (a future headless client) but the desktop path is a WS↔sidecar
relay. §6 slices 2-4 updated to match (acp-tunnel crate + src-tauri relay).

🤖 Generated with [Claude Code](https://claude.com/claude-code)
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.

1 participant