docs(adr): agent-consoles Part D — fs = MCP files server, Studio-brokered - #70
Merged
Conversation
…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
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)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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
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.)oabtool → Studio dials the target/acpwith the token it already holds inagents.toml→ target's fs MCP server. Bearers + policy stay in Studio; theoabgrant stays management-only (least privilege). Two MCP hops ("MCP in MCP"). Rejected: the management agent holding every target's bearer directly.writabledefault-off, explicit Apply, no/-wide default.Sections touched
fs/*wire to the fs MCP server +oabfs-relay; adds the "fs + management ride one channel, one policy point" consequence.oabrelay shape, runtime-ships vs Studio-injects); OQ#2 roots via MCP roots capability; OQ#3 (agents.toml) marked shipped (feat(acp): endpoint registry + RemoteState per-agent keying (agent-consoles slice 1) #66 + feat(agent-consoles): registry editor — point "Edit config" at agents.toml #69).fs.rsdraft in feat(agent-consoles): remote file browser — read-only, MCP-backed (slice 3) #68); (4) write/apply = fs MCP server +oabrelay.Follow-ups (not in this PR)
fileBrowser/fsListingHtml/ Files region — source-agnostic), replace the bespokefs.rswire with the MCP-backed read.oabfs-relay tool is upstream-coordinated (openab), like streaming /tool_call.Docs-only.
🤖 Generated with Claude Code