AgentS Multi-Agent HarnessRun Claude Code, Antigravity ( Instead of juggling a terminal per agent, you get one conversation. Ask the same question of several agents at once and compare their answers, keep working in the same session when you switch models, and review every file change before it lands.
Quick startTwo steps: install the backend, then the extension. The backend is a single command —
Open the chat with
Already have AgentS installed? Upgrading is a separate, shorter path — see Keeping the backend in step. The rest of this page covers agent prerequisites, discovery, and every feature in detail. 1. Install the backendPrerequisitesAgentS drives the official agent CLIs as subprocesses — it doesn't embed or replace them. Install and sign in to whichever you plan to use. You only need one.
Verify before continuing:
Install
|
| Status bar | Meaning |
|---|---|
✓ AgentS |
Connected. Hover for the server URL. |
↻ AgentS starting… |
Spawning or waiting for the server. |
⚠ AgentS down |
Couldn't reach or start it. Click to retry. |
⚠ AgentS: ags not found |
ags isn't on PATH. Click to locate the binary or open settings. |
If ags isn't found, open a fresh terminal first — uv adds its tool directory to PATH, but
existing terminals won't have picked it up. Otherwise set agents.serverPath to the binary.
3. Using it
Start a session
Open the chat with Ctrl+Alt+A (Cmd+Alt+A on macOS), or click a session in the sidebar.
Type an objective and press Enter (Shift+Enter for a newline). Replies stream as
markdown; reasoning collapses into a 💭 Thinking block, and tool calls expand to show their
full arguments and output.
The panel survives window reloads — it re-hydrates from the backend's event ledger, so an in-flight run is never lost.
Plan mode vs edit mode
New sessions are read-only. The agent can read and analyze but not modify anything until
you tick edit in the top bar (or set agents.defaultWriteMode). Toggling it mid-session
applies from the next turn.
Tick worktree on a new session to isolate its changes in a private git worktree on its own branch — nothing touches your working tree until you merge.
Choosing agents: policies
The Policy dropdown controls routing:
| Policy | Behavior |
|---|---|
single |
One agent answers. Pick the agent and model for the turn. |
fanout |
Every agent you tick answers concurrently, in its own column. |
propose_merge |
The policy graph picks agents and merges their proposals. |
local_first_escalate |
Tries a local model first, escalates to a stronger agent if needed. |
With fanout, tick two or more agents and send. When the columns finish you can Compare (judge) to rank the answers, Merge them into one result, or click use on a column to continue single-agent with that winner.
Approvals & Review → Implement Loop
When a run hits a gated action — a shell command, for example — it pauses and shows an Approval required card with the full command in a code block:
- Approve: runs the command and continues streaming.
- Approve & always allow "": approves and remembers the command prefix (editable, default first two tokens) so future matching commands run automatically without re-prompting.
- Deny…: opens a reason prompt so the refusal explanation is recorded and surfaced directly in the agent transcript.
On plan-mode turns, an action row appears at the end of the final response:
- Implement this plan: automatically switches the session to edit mode (in an isolated git worktree when
agents.implementInWorktreeis enabled) and instructs the agent to implement the plan. - Copy as issue: copies the plan text to the clipboard formatted as an issue description.
For worktree sessions, a persistent top bar provides one-click Merge and Discard actions.
Approvals raised while the panel is closed light up a badge on the Sessions view. Run AgentS: Review Approvals to handle them from a quick-pick.
Permission model
Two layers decide whether an agent action happens, and both surface in the same approvals UI (panel card, Sessions badge, AgentS: Review Approvals):
- Session mode. A plan-mode session is read-only; an edit-mode session may write. This is
the coarse gate, set per session by the edit checkbox,
/write//plan, oragents.defaultWriteMode. - Per-action approvals. Inside an edit-mode session, actions the harness classifies as
risky still stop and ask: shell commands (
command), file writes (high_risk) and network fetches (egress). Approve & always allow "" records the prefix on the workspace's auto-approve patterns, so matching commands run unattended from then on. Denials carry your reason into the transcript.
Read-only tools (read, glob, grep, ls, listing tasks, web search) and read-only shell commands
(git status, ls, cat, …) are allowed immediately and never raise a card. WebFetch always
asks — it is not treated as read-only.
CLI-backed agents are covered by the same queue. Claude Code runs headless under AgentS and has
no terminal to prompt on; its permission prompts are routed into AgentS approvals over a
dedicated MCP server, so "Allow Bash(npm run build)?" appears as an ordinary approval card and
the CLI resumes in place once you decide — no restarted process, no continuation run. Anything
unexpected (an unreachable API, a malformed reply, a vanished approval) resolves as deny, and
a run that ends with a prompt still pending has it denied for you. While a prompt is waiting, the
run's stall and timeout clocks are paused, so thinking time spent waiting on you never fails the
run. Backend detail: docs/cli-permissions.md.
Reviewing changes
After a run that writes files, click diff in the top bar, or right-click the session → View Session Diff.
- Normal sessions open a unified diff as a read-only document.
- Worktree sessions open a file picker, then a native side-by-side diff against your workspace copy.
Right-click a worktree session to Merge Worktree (conflicts are reported so you can resolve them) or Discard Worktree (deletes the branch and its changes). Both confirm first. AgentS: Prune Orphan Worktrees cleans up worktrees whose sessions are gone.
Plan-mode runs and runs that changed nothing have no diff.
Changes view
The Changes view lists every run in the current session that touched a file, newest first,
labeled with the session's objective and a +added −deleted badge. Expand a run to see the
files it changed, each with its status (added, modified, deleted, renamed); click one to open a
native diff against a read-only snapshot of the file as it stood before that run.
Right-click a file to Revert File, or a run to Revert Run (reverts every file it changed) — both confirm first, since reverting cannot be undone. The view refreshes itself whenever a run finishes.
In a multi-root window the runs are grouped under the folder the session actually belongs to (resolved from the session's own AgentS workspace, not from whichever folder happens to be first), and a worktree session's files are grouped under — and opened from — its worktree.
Adding providers and MCP servers
Click + on the Providers view to add any OpenAI-compatible endpoint. The wizard asks for
a name, base URL (e.g. https://api.groq.com/openai/v1), default model, optional API key, and
whether to enable tool calling. It runs a connection test on save, and the provider then shows
up in the agent picker.
The MCP Servers view works the same way, with stdio (a local command to spawn) or http (a remote endpoint with an optional bearer token) transports. You can set a tool allowlist and hit test to list the tools a server exposes.
An API key you type into the provider wizard is held by the editor, not by the server: it
goes into VSCode's encrypted SecretStorage, the provider is registered with
key_storage: "client", and the key is pushed over POST /adapters/{name}/key for the server to
keep in memory only (mem:<name>). It never reaches VSCode settings, globalState, a log line,
an error message, or the server's disk — and because the server's copy is RAM-only, restarting it
drops every key, so the extension re-pushes them when it reconnects.
Editing a provider that already has a key offers keep / replace / clear; clearing forgets it
on both sides (DELETE /adapters/{name}/key plus a SecretStorage delete). Deleting the provider
clears it too. Keys configured on the server instead (config.yaml, or ags adapter) keep the
backend's own 0600 file storage. Providers declared in config.yaml are edit-protected; change
those in the file directly.
Overriding the model list
The Model picker shows whatever the backend reports for that agent, and how it gets that list depends on the agent:
| Agent | Model list comes from | Stays current? |
|---|---|---|
| Antigravity | Runs agy models |
Yes — reflects your CLI |
| OpenAI-compatible | GET /v1/models on the endpoint |
Yes — reflects the server |
| Claude Code | A static list built into the backend | No — goes stale |
The claude CLI has no machine-readable way to enumerate models, so the backend ships a
hardcoded snapshot. It doesn't know which models your login is actually entitled to, and it
won't grow when Anthropic ships new ones. If the picker is missing a model you know you have,
this is why.
Fix it by setting params.models on the provider in ~/.ags/config.yaml
(%USERPROFILE%\.ags\config.yaml on Windows). When present, the list is used verbatim —
it replaces the built-in one entirely:
providers:
- name: claude
kind: claude_code
enabled: true
model: claude-opus-4-8 # the default selection
params:
bin: claude
models: # replaces the built-in list
- claude-opus-4-8
- claude-fable-5
- claude-sonnet-5
- claude-haiku-4-5
This is also how you expose account- or CLI-specific variants the built-in list can't know
about, such as claude-fable-5[1m].
Because the list is used verbatim, anything you leave out disappears from the picker — include
every model you want selectable, not just the new ones. Keep model: pointing at something
that's still in the list.
Then restart the backend so it re-reads the config, and refresh the extension:
# macOS / Linux
kill "$(cat ~/.ags/server.pid)"
# Windows (PowerShell)
Stop-Process -Id (Get-Content "$env:USERPROFILE\.ags\server.pid")
Then run AgentS: Reconnect / Start Server (it respawns the backend), followed by AgentS: Refresh Providers. Verify from a terminal with:
ags models list claude
Tip: the
claudeCLI also accepts the tier aliasesopus,sonnet,haiku, andfable, which always resolve to the newest model in that tier. Adding those tomodels:gives you entries that never go stale.
params.models applies to claude_code providers only — Antigravity and OpenAI-compatible
providers enumerate live, so setting it there has no effect.
From the editor
Select code, right-click, and choose Send Selection to Chat, Explain Selection, or
Fix Selection. Each prefills the composer with the selection as a path:line-range code
block — nothing sends automatically, so you can edit the prompt first.
Attaching context
Type @ in the composer to attach context to your message. A popover lists keyword and
file-path matches as you type:
| Mention | Resolves to |
|---|---|
@selection |
The active editor's current selection (path, line range, and text). |
@diagnostics |
The problems currently reported for the active file. |
@editors |
Every file currently open in the editor group. |
@git-diff |
The diff for each file with pending changes in the bound workspace. |
@path/to/file or @path/to/file:10-20 |
A project file, optionally ranged to specific lines. |
Use the arrow keys and Enter (or Tab) to accept a suggestion, or click one; Escape closes the
popover without inserting anything. Mentions are resolved against the editor at send time —
including for a message that lands in the follow-up queue — so a queued @selection captures
what was selected when you typed it, not whatever is selected when the run finally dispatches it.
Editor-aware tools (LSP bridge)
The extension hosts an in-process MCP server (vscode-lsp-<slug>) exposed to AgentS via Streamable-HTTP loopback (127.0.0.1). This provides every agent (including CLI-driven agents like Claude Code and Antigravity) with editor-grade navigation and code intelligence:
get_definition(path, line, character): Jump directly to a symbol's declaration.find_references(path, line, character, include_declaration, max): Enumerate call sites and references across the workspace.workspace_symbols(query, max): Query workspace symbols matching a search term.document_outline(path): Retrieve the structural outline and symbol hierarchy of a file.diagnostics(path, severity): Fetch real-time compiler and linter diagnostics (errors and warnings).open_editors(): List currently open editor tabs.current_selection(): Read the user's active editor selection, line range, and text.rename_symbol(path, line, character, new_name): Perform workspace-wide semantic symbol renaming (available in write mode).
The LSP bridge is enabled by default (agents.lspBridge.enabled: true) and authenticates with a per-process local bearer token.
Chat participant, inline edit and LSP write mode
@agents in the Chat view. Type @agents in VSCode's own Chat view to ask AgentS a question
without leaving it. Tokens stream in as they arrive, tool calls appear as progress lines, and the
#file / #selection references you attach are forwarded as the same context refs an @-mention
in the AgentS panel would build. Follow-ups in the same thread resume the same AgentS session, so
the conversation keeps its history; cancelling the response cancels the run on the server.
| Command | Behavior |
|---|---|
@agents <question> |
Plan mode (read-only). The default — nothing on disk is touched. |
@agents /plan <question> |
Plan mode, explicitly. |
@agents /write <task> |
Write mode against the bound folder. If the folder isn't bound to an AgentS workspace, the turn falls back to plan mode and says so. |
The panel (AgentS: Open Chat) is still the full surface — approvals, fanout, diffs and the
changes tree live there. The participant is for quick questions in the flow of editing.
Inline edit on a selection. Select code and press Ctrl+Alt+I (Cmd+Alt+I on macOS), or pick
AgentS: Edit Selection… from the editor context menu or the Command Palette. Describe the
change, and the agent answers in plan mode with a single replacement block that the extension
applies to your selection with a workspace edit — so the change lands in the editor's normal undo
stack and Ctrl+Z reverts it. The notification that follows offers Show diff, which opens the
file against its pre-edit contents. The run is cancellable from its progress notification.
LSP bridge write mode. The bridge described above is rebuilt whenever the active chat session changes mode, and it only advertises the tools that mode allows:
| Mode | Bridge tools | Backend MCP entry |
|---|---|---|
Plan (/plan, the default) |
The seven read-only tools. rename_symbol is not advertised at all. |
read_only: true |
Write (/write, Implement Plan, or agents.defaultWriteMode: true) |
The read-only tools plus rename_symbol. |
read_only: false |
Switching modes stops the running bridge and starts a fresh one, so a session that began in plan mode can never pick up a write tool part-way through a turn.
Workspaces
Each open folder gets its own AgentS workspace — a folder named api and one named web
never share history or project state, even in the same VSCode window. The Sessions view groups
sessions under a header per folder; new runs started from a folder's chat go to that folder's
workspace automatically.
Binding happens the first time a folder is opened (and again whenever you add one), governed by
agents.bindProject:
| Mode | Behavior |
|---|---|
prompt (default) |
Asks once per folder, then remembers your answer. |
auto |
Binds every open folder immediately, no prompt. |
off |
Never binds. Runs go to the server's default workspace. |
Binding re-runs automatically whenever the set of open folders changes (adding or removing a folder from a multi-root workspace); there's no separate command to force it.
Slash commands
Type / at the beginning of the composer to see available slash commands:
| Command | Description |
|---|---|
/context |
Show the context gauge for this session (window, last prompt size). |
/new |
Start a fresh chat session. |
/rename <title> |
Rename the current session. |
/branch |
Fork the session from this point into a new work branch. |
/write |
Switch the session to write (edit) mode. |
/plan |
Switch the session to plan (read-only) mode. |
/worktree |
Move the session into an isolated git worktree. |
/help |
List these commands in the transcript. |
Anything else beginning with / is left alone and sent to the agent as text.
The ags chat REPL in the terminal is a separate surface with its own, larger set
(/use, /model, /mode, /merge, /handoff, /compare, /thinking, /status,
/exit, …) — run /help there to see it. The composer deliberately does not mirror it:
the picker, the edit checkbox and the worktree bar already cover those in the UI.
Keyboard shortcuts
| Keybinding | Command | Description |
|---|---|---|
Ctrl+Alt+A (Cmd+Alt+A on macOS) |
agents.openChat |
Open or focus the active AgentS chat panel. |
Ctrl+Alt+S (Cmd+Alt+S on macOS) |
agents.sendSelectionToChat |
Send the current editor selection to the chat composer. Only active when text is selected. |
Ctrl+Alt+C (Cmd+Alt+C on macOS) |
agents.changes.focus |
Focus the AgentS Changes view. |
Status Bar & Context Gauge
- Status Bar: Indicates connectivity (
$(check)), active agent provider, and operating mode (planorwrite). When an agent is working, a spinner ($(sync~spin)) appears. Clicking the status bar opens or focuses the chat. - Context Gauge: The chat panel shows how full the model's context window is, using only
numbers the backend reports: the window the run was budgeted (
context_meta.window, falling back to the provider's advertisedmax_context) and the size the provider billed for the last prompt (prompt_tokens). When either is missing — an older backend, a provider that advertises no window or reports no usage, or a session that hasn't taken a turn yet — it readscontext: unknownand says which number is missing on hover, rather than inventing a percentage. - Clickable File Paths: File paths and
path:line:colreferences in agent responses are automatically linkified so you can click to jump straight to the referenced code in your editor.
Settings
| Setting | Default | Description |
|---|---|---|
agents.apiUrl |
(empty) | Explicit server URL, bypassing auto-discovery. |
agents.apiToken |
(empty) | Bearer token for the local API. Leave empty to use ~/.ags/api_token (what ags init mints). |
agents.serverPath |
(empty) | Path to the ags executable, if not on PATH. |
agents.autoStartServer |
true |
Auto-spawn ags serve when no server is reachable. |
agents.bindProject |
prompt |
Bind each open folder to its own AgentS workspace: prompt, auto, or off. |
agents.defaultPolicy |
single |
Routing policy preselected for new sessions. |
agents.defaultWriteMode |
false |
Preselect edit mode for new sessions. |
agents.dirtyBufferGuard |
"ask" |
Guard unsaved buffers before edit-mode send (ask, saveAll, off). |
agents.implementInWorktree |
true |
Implement plans inside an isolated git worktree. |
agents.stopServerOnExit |
true |
Stop managed AgentS background server on VSCode exit. |
agents.lspBridge.enabled |
true |
Expose editor LSP navigation and diagnostics to AgentS via an in-process MCP server. |
All commands live under "AgentS:" in the Command Palette (Ctrl+Shift+P).
Keeping the backend in step
The extension and the backend ship separately and are upgraded separately. VSCode
updates the extension on its own schedule; nothing updates ags for you. So after every
extension update, check the backend too — a new extension talking to an old backend is the
single most common cause of a feature that "doesn't work":
ags version
ags 0.2.6 (ags-cli, CLI + backend)
server 0.2.6
api v1
Three things worth knowing about that output:
agsandserverare two different numbers on purpose. The first is what is installed on disk; the second is what is actually answering requests.uv tool upgradereplaces the files without touching a server that is already running, so a server started before the upgrade keeps serving the old code until it restarts. If they disagree,ags versionsays so and tells you what to do.- There is no separate "backend version". The
agsCLI and the harness backend ship as one package (ags-cli) under one release tag, so on any machine they are the same build. ags versionneeds backend ≥ 0.2.5. Older servers have no/api/v1/versionendpoint; the command detects that and reports it as "running, but too old to report it", which is itself the answer.
New install
# 1. uv (skip if you have it)
# macOS / Linux:
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows (PowerShell):
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
# 2. Backend
uv tool install ags-cli
ags init
# 3. Extension
code --install-extension agent-smith.agents-vscode
Then ags doctor to confirm the agent CLIs are visible. See §1 and §2 for the detail.
Upgrading an existing install
# 1. Backend on disk
uv tool upgrade ags-cli
# 2. Restart the server so it picks up the new code.
# Command Palette -> "AgentS: Restart Server"
#
# This step is not optional and not the same as reconnecting: reconnect finds
# the same stale process and reports success, which is exactly how an upgrade
# appears to have done nothing.
# 3. Confirm both numbers moved
ags version
ags init is safe to re-run after an upgrade and is worth doing if a release adds config
(it is idempotent — it will not overwrite providers you have added). It also re-mints
~/.ags/api_token if it is missing.
Your data is not touched by an upgrade: sessions, transcripts, memory, providers and API
keys all live in ~/.ags/ and are left alone.
Version compatibility
From 0.2.5 the extension and the backend are released under the same number, so matching them is a matter of reading one figure rather than a table. Earlier pairings are listed for reference.
| Extension | Needs backend |
|---|---|
| 0.2.6 | ≥ 0.2.6 — fanout survives reopen, approval gate works for Claude Code |
| 0.2.5 | ≥ 0.2.5 — ags version, adapter params preserved on edit, context window settable |
| 0.2.4 | ≥ 0.2.1 |
| 0.2.0 – 0.2.3 | ≥ 0.2.1 |
The extension degrades rather than breaks against an older backend: features that need a
newer endpoint are simply absent or fall back. The context gauge reading context: unknown
and provider params being reset on edit are both symptoms of a backend older than 0.2.5.
Removing it
ags uninstall # deletes ~/.ags (asks first; --dry-run to preview)
uv tool uninstall ags-cli # then remove the program itself
ags uninstall never removes the ags program — only uv/pipx/pip can do that
cleanly, and it prints the right command for your install. It refuses while a server is
still running, and --keep-secrets leaves your provider API keys in place.
Note that ags service uninstall is a different, narrower command: it removes the systemd
unit or launchd plist that auto-starts the server on login, and nothing else. It is not
available on Windows.
Troubleshooting
Status bar stuck on "down" — click it to reconnect. If it says ags not found, open a new
terminal (so PATH refreshes) or set agents.serverPath. AgentS: Open Server Log shows
~/.ags/server.log for startup crashes.
Agent picker is empty — the backend isn't reachable, or no providers are enabled. Reconnect, then check the Providers view.
Model picker is missing a newer model — for Claude Code the list is a static snapshot in
the backend, not a live query. Override it with params.models in config.yaml — see
Overriding the model list.
An agent shows as unavailable — almost always PATH. VSCode may not inherit the shell PATH
that has claude or agy on it. Run ags doctor to check, and set the adapter's binary path in
the backend config if needed.
"Authentication required" / the extension can't reach a server that is clearly running — the
server has a local API token the extension could not find. Run ags init (it mints
~/.ags/api_token and is safe to re-run), then reconnect; if your token lives elsewhere, point
agents.apiToken at its value. The extension re-reads the token automatically once per rejected
request, so re-minting it does not require a reload.
A run seems stuck — it's probably waiting on an approval. Check the panel or the Sessions badge. Dropped streams reconnect automatically.
Diff says "no changes" — the run was plan-mode, or genuinely wrote nothing.
License
Apache-2.0. Source: github.com/farookmfk/agents-vs-code