Skip to content

docs(adr): agent-consoles Part D — fs = MCP files server, Studio-brokered - #70

Merged
brettchien merged 1 commit into
mainfrom
docs/adr-fs-mcp
Aug 17, 2026
Merged

docs(adr): agent-consoles Part D — fs = MCP files server, Studio-brokered#70
brettchien merged 1 commit into
mainfrom
docs/adr-fs-mcp

Conversation

@brettchien

Copy link
Copy Markdown
Contributor

What

Locks the remote file editor (Part D) mechanism after the design call: fs is an MCP surface — a files server the target agent exposes — not a bespoke fs/* method set on /acp.

This resolves the ADR's own Open Question #1 (it already asked "native ACP methods or an agent-served MCP files server").

The decision

  • Why MCP (the actor changed). fs is not only Studio's UI reading a disk — the driver is the management agent reaching into a target agent to manage it, of which editing a file is one op. That is the ordinary agent→MCP-server direction, and the management→target channel must exist regardless; a bespoke fs/* RPC would build that channel twice. (The earlier bespoke preference scoped fs as Studio-reads-agent = the reverse MCP direction; once the actor is the management agent, that objection dissolves.)
  • Topology — Studio-brokered (decided). management agent → Studio reverse-MCP oab tool → Studio dials the target /acp with the token it already holds in agents.toml → target's fs MCP server. Bearers + policy stay in Studio; the oab grant stays management-only (least privilege). Two MCP hops ("MCP in MCP"). Rejected: the management agent holding every target's bearer directly.
  • Gating moves to tool-level in the fs server: agent-declared roots (MCP roots capability), writable default-off, explicit Apply, no /-wide default.

Sections touched

Follow-ups (not in this PR)

Docs-only.

🤖 Generated with Claude Code

…espoke fs/*)

Locks the remote file editor's mechanism after the design call with Brett: fs is
an MCP surface a target agent exposes, consumed by the management agent (and by
Studio's UI), not a bespoke `fs/*` method set on `/acp`.

- §5 Part D rewritten: the actor is the management agent reaching into a target
  to manage it (fs = one op of that channel), which is the ordinary agent→MCP
  direction — so a bespoke wire would build the management channel twice. Topology
  decided as **Studio-brokered**: management agent → Studio `oab` reverse-MCP tool
  → Studio dials the target `/acp` with the registry-held token → target fs MCP.
  Bearers + policy stay in Studio; the `oab` grant stays management-only. Roots/
  writable/apply gating moves to tool-level in the fs server.
- §6/§7: the dependency + security bullets re-pointed from the `fs/*` wire to the
  fs MCP server + `oab` fs-relay; adds the "one channel, one policy point" win.
- §8: OQ#1 (native ACP vs MCP files server) resolved → MCP, Studio-brokered, with
  the remaining sub-questions (fs tool set, `oab` relay shape, runtime vs injected
  server); OQ#2 roots via MCP roots capability; OQ#3 (agents.toml) marked shipped.
- Closing slices: (3) read = browser over MCP-backed read (replaces the slice-3
  bespoke `fs.rs` draft); (4) write/apply = fs MCP server + `oab` relay.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@brettchien
brettchien merged commit 652e2eb into main Aug 17, 2026
1 check passed
@brettchien
brettchien deleted the docs/adr-fs-mcp branch August 17, 2026 06:14
brettchien added a commit that referenced this pull request Aug 17, 2026
…ice 3)

Slice 3 of the agent-consoles ADR (#49): the remote file editor's read
path (Part D). Adds a capability-gated, read-only directory browser +
file viewer to the agent console.

Per the merged Part D decision (#70), fs is an MCP files server the
target agent exposes, reached Studio-brokered via the `oab` reverse-MCP
tool — not a bespoke `fs/*` method set on `/acp`. The fs MCP server + the
`oab` fs-relay are upstream (openab) and absent today, the same bucket as
token streaming / `tool_call`. So this slice ships the browser UI + the
source-agnostic read contract now; live fs traffic (MCP-backed read, then
write/apply) lands in slice 4 with the server + relay.

The earlier draft's bespoke `crates/acp-tunnel` `fs/*` client is dropped
(the mechanism #70 rejected); the browser UI it fronted is source-
agnostic and unchanged.

- console/fileBrowser.ts: capability-gated browser + read-only CodeMirror
  viewer, mounted per open console, disposed on close/switch. Read-only.
- render.ts: pure `fsListingHtml` (dirs-before-files, sizes, open-marking,
  `data-fs-*` nav hooks) + `fsUnavailableHtml`.
- types/source/fixtures: the fs view-models; `fsCapability`/`fsList`/
  `fsRead` (Mock = fixture FS; Tauri = honestly unsupported until slice 4).
- index.html / styles.css: the Files region (listing + viewer split).

Security (Part D): read-only — write/Apply is slice 4, gated at the fs
server's tool level (agent-declared roots, `writable` default-off, no
`/`-wide default). No orchestrator/kube creds; the `oab` relay stays
management-only.

Testing: console — `tsc --noEmit` clean · 84 vitest (incl. fs render
cases) · `vite build` OK. No Rust change (the bespoke client is removed).

🤖 Generated with [Claude Code](https://claude.com/claude-code)
brettchien added a commit that referenced this pull request Aug 17, 2026
…ice 3) (#68)

Slice 3 of the agent-consoles ADR (#49): the remote file editor's read
path (Part D). Adds a capability-gated, read-only directory browser +
file viewer to the agent console.

Per the merged Part D decision (#70), fs is an MCP files server the
target agent exposes, reached Studio-brokered via the `oab` reverse-MCP
tool — not a bespoke `fs/*` method set on `/acp`. The fs MCP server + the
`oab` fs-relay are upstream (openab) and absent today, the same bucket as
token streaming / `tool_call`. So this slice ships the browser UI + the
source-agnostic read contract now; live fs traffic (MCP-backed read, then
write/apply) lands in slice 4 with the server + relay.

The earlier draft's bespoke `crates/acp-tunnel` `fs/*` client is dropped
(the mechanism #70 rejected); the browser UI it fronted is source-
agnostic and unchanged.

- console/fileBrowser.ts: capability-gated browser + read-only CodeMirror
  viewer, mounted per open console, disposed on close/switch. Read-only.
- render.ts: pure `fsListingHtml` (dirs-before-files, sizes, open-marking,
  `data-fs-*` nav hooks) + `fsUnavailableHtml`.
- types/source/fixtures: the fs view-models; `fsCapability`/`fsList`/
  `fsRead` (Mock = fixture FS; Tauri = honestly unsupported until slice 4).
- index.html / styles.css: the Files region (listing + viewer split).

Security (Part D): read-only — write/Apply is slice 4, gated at the fs
server's tool level (agent-declared roots, `writable` default-off, no
`/`-wide default). No orchestrator/kube creds; the `oab` relay stays
management-only.

Testing: console — `tsc --noEmit` clean · 84 vitest (incl. fs render
cases) · `vite build` OK. No Rust change (the bespoke client is removed).

🤖 Generated with [Claude Code](https://claude.com/claude-code)
brettchien added a commit that referenced this pull request Aug 17, 2026
…eration fallback) (#71)

Revises the remote file editor's backend after the design call. fs stays
Studio-brokered (agent never holds the credential; `oab` grant stays
management-only), but the backend is chosen by one axis — **does Studio
own the target's runtime?**

- Backend 1 (primary, every agent in the fleet today): Studio's platform
  exec channel — ECS `ExecuteCommand` / k8s `pods/exec` — with a control-
  plane credential Studio already holds. Ships now, no openab dependency.
- Backend 2 (fallback, federation): the target-hosted fs MCP server over
  the `oab` relay, for an agent Studio can reach only over `/acp` but whose
  platform it does not own. Depends on openab; deferred until such an agent
  exists.

Consequence: the fleet's fs write is no longer gated on an upstream fs
server — that item drops from "gating dependency" to "federation fallback."
The trade the exec backend buys, stated plainly: gating (`roots`/`writable`)
becomes Studio-enforced (path validation + argv-form exec), not resource-
enforced, and a control-plane credential enters the fs path — held only by
Studio's broker, never by an agent.

- §5 Part D rewritten around the two-backend model + the deciding axis.
- §6/§7 re-pointed: read+write ship over exec for owned runtimes; the MCP
  server is the deferred federation fallback; security consequences updated
  (enforcement locus, control-plane cred in the fs path).
- §8: OQ#1 re-resolved (two backends); new OQ#2 on the exec backend's
  enforcement locus. Closing slices: (4) read+write over exec (no openab),
  (5) federation MCP backend when needed.

Supersedes the Part D mechanism locked in #70 (fs = target-exposed MCP
server as the sole backend).

Docs-only.

🤖 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