feat(acp): let hosts start sessions with only client-provided mcpServers (no builtin default, no config extensions)
- Vorherrschende Sprache
- Rust
- Sterne
- 54.2k
- Forks
- 6.2k
- Ø Merge
- 3 T. 2 Std.
- Gemergte PRs (30 T.)
- 262
Beschreibung
## What problem would this solve?
ACP hosts that embed goose as a subprocess (editor plugins: Zed, JetBrains, Neovim, custom harnesses) typically provide their own tool surface via `session/new` → `mcpServers` — the host *is* the environment. Today there is no way for such a host to start a session where goose's tools are exactly these client-provided servers:
1. `goose acp` with no `--with-builtin` silently defaults to the `developer` builtin (`AcpBuiltinSelection::from_requested`, `crates/goose/src/acp/server.rs:301`), adding shell/file tools alongside the host's own — duplicated capability, prompt/token overhead, and a least-privilege problem (an editor-embedded agent that only needs the host's bridge tools should not have arbitrary shell execution).
2. Every new session also inherits the user's personal config extensions and project plugin MCP servers (`get_enabled_extensions_with_config` + `enabled_plugin_mcp_servers` in `initial_session_extensions`), so the host's tool surface is nondeterministic and depends on the local user's `~/.config/goose/config.yaml`.
3. `session/new` `mcpServers` is purely additive; `--with-builtin` requires at least one name, so an explicit "none" cannot be expressed.
This blocks clean host-owned-tool embeddings. A viable workaround (isolated `GOOSE_PATH_ROOT` + config dir) is undermined because `migrate_platform_extensions` seeds all `default_enabled: true` platform extensions into an empty config (`config/migrations.rs`, see `test_migrate_platform_extensions_empty_config`), so config-dir isolation can't actually produce an empty set.
## What would a good outcome look like?
A host can launch `goose acp` (or otherwise opt in per session) such that a session's tool surface is deterministic and exactly: client `mcpServers` + explicitly requested builtins. Absent the opt-in, existing behavior is unchanged (developer default, config extensions, plugins).
## Possible approaches
- A `--no-extensions` flag on `goose acp`, mirroring `goose run --no-extensions` semantics: empty builtin selection (no `developer` default) and skip the config/plugin fallback in `initial_session_extensions`, leaving only client `mcpServers`.
- Or split knobs (`--no-config-extensions`, plus accepting an explicit "none" value for `--with-builtin`).
- A session-scoped `session/new` `_meta` option could complement the launch flag (useful for roaming/shared agents), but launch-level matches the existing `--with-builtin` precedent.
- Should be designed together with #11643 (union-on-`mcpServers`): after union, dropping opt-out would leave no path to host isolation at all. Related: #11573 (empty sets replaced by defaults is the same "empty ⇒ default" conflation).
Implementation looks contained: plumb a flag through `cli.rs` → `acp::server::run()` → `AcpServerFactoryConfig`/`build_enabled_extensions_data`; in `initial_session_extensions`, skip the config/plugin/mcp fallback only on the last branch; add tests mirroring `new_session_mcp_is_additive_to_enabled_config_extensions`. I can implement and PR once this reaches **Ready**; verification would be those unit tests plus a stdio ACP probe (like the one in #11643) asserting the tool list.
**Side observation** found while reading the path: a `session/new` that carries `meta.enabledExtensions` never calls `add_mcp_servers`, so client `mcp_servers` are silently dropped on that branch (`new_session.rs:157` → `build_enabled_extensions_data` → `initial_session_extensions` recipe/extensions branches).
## Additional context
- Repro: user config with any enabled extension; ACP client sends `session/new` with `mcpServers=[bridge]`; resulting session announces `shell`/`edit` (developer) + config extension tools in addition to the bridge tools.
- Observed on `main` @ `ed9648b92` (Linux, v1.48.0).
- I've searched open issues; nearest are #11643 and #11573 (above) — neither covers a host-side isolation opt-out.
- [x] I have verified this does not duplicate an existing feature request
Beitragsleitfaden
Bewertung
Dieses Issue wurde noch nicht bewertet.