Agent Mode
|
This content was generated with the assistance of AI and should be verified against the official documentation of each tool and framework before being relied on in production. This section’s bibliography lists the reference material consulted while preparing these pages. |
This page targets VS Code’s current Copilot Chat (with its agent-harness picker and per-tool approval settings)
and the Claude Code CLI’s agentic loop, both checked against
VS Code’s agents documentation and
Claude Code’s official docs as of 2026-09-28; both products change these
screens and setting names often, so re-check the linked pages before relying on an exact label. The running
example is the same DocsAssistant API Spring Boot + Python sample used throughout this sub-section, with its
controller at src/main/java/com/example/docsassistant/DocsController.java and its tests under
src/test/java/com/example/docsassistant/.
Copilot agent mode in VS Code
Selecting an agent
Copilot Chat runs a task through one of several agent harnesses — a harness is the runtime that manages the session’s tool calls, context and code changes. As of the date above, VS Code ships:
| Harness | What it runs |
|---|---|
Local |
Interactively, inside VS Code’s own extension host, using built-in and extension-contributed tools — the best fit for a quick interactive change with immediate feedback. |
Copilot |
Locally, powered by the Copilot SDK’s own Agent Host — the general-purpose default for everyday coding tasks, including background sessions. |
Claude |
Locally, using Anthropic’s Claude Agent SDK, exposing Claude Code’s own permission modes inside VS Code. |
Codex |
Locally, using OpenAI’s Codex harness, for interactive or background tasks. |
Cloud |
Remotely, against a GitHub repository, for a well-scoped task that can run unattended and come back as a pull request — covered in depth on Cloud & Background Agents. |
A harness and an agent are picked from the same control at the bottom of the Chat view; which harnesses appear there depends on which agent-provider extensions are installed. See VS Code — Choose an agent harness.
Tools and terminal access
Whichever harness runs the session, it acts through tools — reading and searching files, editing them,
running terminal commands, and calling anything an MCP server exposes. Which tools are available to a given
request is configured from a tools picker in the chat input (Configure Tools, for the Local harness) or,
persistently, from the Agent Customizations editor’s Tools tab (opened from the gear icon), where individual
tools and whole tool sets can be turned on or off. A tool set groups related tools under one name so a prompt
or a custom agent can pull them in together with #, for example #web for every web-related tool at once. See
VS Code — Use tools with agents.
Terminal commands are a tool like any other, subject to the approvals below, but VS Code also runs the command detection described there against the shell’s own grammar (bash or PowerShell) to tell a read-only command from a risky one.
Approvals and auto-approve settings
By default, a terminal command or other tool call that is not auto-approved pauses and shows a confirmation with the tool’s name and its input, which you approve or reject before it runs. File edits inside the workspace work differently: the agent applies and saves them straight away, and you then Keep or Undo each change (in an Agent Host session, such as the Copilot harness, the edits have no pending review state at all). Only edits to sensitive files and to paths outside the workspace ask for approval before they are applied. Three settings loosen the per-tool confirmations, each with a real risk attached (see VS Code — Review code edits for the edit flow):
| Setting | What it does | Risk of enabling it |
|---|---|---|
|
Lists commands (by exact match, glob or a |
Command detection is best-effort: an obfuscated or chained command can evade the pattern and still run unattended. |
|
Lists file-path patterns whose edits apply without a confirmation; common system folders, dotfiles and files outside the workspace still require one by default. |
A broad pattern can let an agent overwrite a file you did not mean to hand it, such as a CI config or a credentials file that happens to match the glob. |
|
Auto-approves all tools in every workspace, removing the confirmation prompts entirely; the first time you enable it, VS Code shows a warning dialog asking you to confirm. |
Nothing an agent does is confirmed any more — file edits, terminal commands and external tool calls all run unattended, in every workspace you open, including one whose contents you have not reviewed. |
The same trade-off appears in the permissions picker in the chat input, which sets the level for the current session:
| Level | Behaviour and risk |
|---|---|
Manual |
The default: the tool, URL and terminal approval rules above apply, and anything they do not auto-approve asks for confirmation. |
Assisted |
A language model judges each tool call and auto-approves the ones it assesses as safe; the rest ask for confirmation. The model-based risk assessment can make mistakes, so it does not replace your own review. |
Allow all |
Runs every tool call without confirmation, including potentially destructive file edits, terminal commands and external tool calls. |
Autopilot |
Not a permission level but an agent mode, picked from the same chat input: it auto-approves every tool and keeps working, retrying on errors, until the agent decides the task is complete. It carries the same risk as Allow all, over a longer unattended run. |
VS Code’s own documentation is explicit that terminal auto-approval "is a best-effort convenience, not a security boundary," and recommends running agent sessions in a sandbox or container for anything higher-risk than the DocsAssistant API sample. See VS Code — Manage approvals and permissions.
Claude Code’s equivalent loop
Claude Code runs the same three-phase loop — gather context, take action, verify — introduced on
Getting Started with Claude Code, and the
active permission mode (default, acceptEdits, plan or auto, cycled with Shift+Tab) plays the same
role as VS Code’s approval settings above: it decides which of the loop’s actions — file edits, and the
filesystem or shell commands the CLI classifies as safe — run without asking first. There is no separate
"agent mode" to turn on: every claude session is already running this loop, and the IDE and JetBrains
integrations run the identical loop with the extension only changing where diffs are displayed. See
Claude Code — Choose a permission mode.
How agents gather context
Before editing anything, both tools spend part of the loop gathering context on their own, mixing three kinds of action:
-
Search — a semantic or text search over the workspace to find the files relevant to the request, the way Copilot’s
#codebasereference or Claude Code’s own search tool locateDocsControllerfrom a prompt that only names the endpoint. -
Read — opening the files that search turned up (and, for Claude Code, any
CLAUDE.mdin their directory) to see the current code before proposing a change. -
Run — executing a read-only command, such as running the existing test suite once to see which test fails, before writing any fix.
An explicit reference (#DocsController.java in Copilot Chat, @src/main/java/com/example/docsassistant/DocsController.java
in Claude Code) skips the search step and points the agent straight at the right file, which is faster and less
prone to picking the wrong candidate than leaving it to search alone. See
VS Code — Add context to chat and
Claude Code — Common workflows.
Approving tool calls
Reviewing a proposed change is the same idea in both tools, shown differently:
Copilot wants to run: mvn -q -Dtest=DocsControllerTest test
[ Continue ] [ Skip ]
Bash(mvn -q -Dtest=DocsControllerTest test)
Do you want to proceed?
1. Yes
2. Yes, and don't ask again for mvn commands in this project
3. No, tell Claude what to do differently
Approving once lets that single call through; the second option in each tool (an auto-approve rule, or Claude Code’s "don’t ask again") is what widens future approval, with the risks described above. See VS Code — Manage approvals and permissions and Claude Code — Choose a permission mode.
Stopping and steering mid-run
An agent that has gone down the wrong path does not need to be interrupted by closing the session. In VS Code,
selecting Stop (or the equivalent Escape action) above the in-progress response stops the current tool call,
and typing a correction in the chat box continues the same request instead of starting a new one. In Claude
Code, pressing Esc stops the current tool call immediately, and typing a correction without pressing Esc
first queues it — Claude reads the message as soon as the tool calls in flight finish, rather than mid-edit.
Both are cheaper than letting a plausible-looking but wrong change keep compounding across several more turns.
In Claude Code, pressing Esc twice (or running /rewind) also opens the rewind menu to restore an earlier
conversation and code state. See
Claude Code — Best practices:
course-correct early and often and
Claude Code — Interactive mode.
Tool sets and using existing MCP servers
An MCP (Model Context Protocol) server adds tools an agent did not ship with — for example, one that queries DocsAssistant API’s own Postgres database directly instead of the agent guessing at the schema from source. Building a server is out of scope here and is the subject of the Model Context Protocol (MCP) sub-section; this page covers only pointing an existing server at each tool.
// .vscode/mcp.json
{
"inputs": [
{
"type": "promptString",
"id": "docsassistant-dsn",
"description": "DocsAssistant read-only Postgres DSN",
"password": true
}
],
"servers": {
"docsassistant-db": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@bytebase/dbhub", "--dsn", "${input:docsassistant-dsn}"]
}
}
}
The file is meant to be committed, so it holds no credentials: the inputs entry makes VS Code prompt for the
connection string (masked, because of password: true) the first time the server starts, and substitutes it
wherever ${input:docsassistant-dsn} appears. VS Code’s MCP docs advise against hardcoding secrets such as a
database password; an envFile field that loads variables from an uncommitted file is the other option. See
VS Code — MCP configuration reference: input variables for sensitive data.
VS Code also discovers project-portable .mcp.json files (top-level mcpServers key) and a user-level
configuration opened with the MCP: Open User Configuration command; running MCP: Add Server from the
Command Palette writes to whichever of these you target. Once added, a server’s tools appear in the same tools
picker described above, grouped under its name. See
VS Code — Use MCP servers in VS Code.
$ export DOCSASSISTANT_DB_DSN="postgresql://readonly:<password>@localhost:5432/docsassistant"
$ claude mcp add --transport stdio docsassistant-db -- npx -y @bytebase/dbhub \
--dsn "$DOCSASSISTANT_DB_DSN"
$ claude mcp list
$ claude
> /mcp
claude mcp add takes a --scope of local (the current project only), project (written to a shared
.mcp.json checked into the repository) or user (every project); /mcp inside a running session shows
connected servers and their status. The shell expands $DOCSASSISTANT_DB_DSN when the server is added, and
the default local scope stores the result in ~/.claude.json, outside the repository; for a checked-in
project-scope .mcp.json, write ${DOCSASSISTANT_DB_DSN} in the file instead, which Claude Code expands
from each developer’s own environment when it loads the server. See Claude Code — Connect to MCP
servers.
Example: fixing a failing test in agent mode
Suppose DocsControllerTest#getPage_returns404WhenMissing fails after a refactor. The task, and the approvals
it triggers, look like this in each tool.
#DocsControllerTest.java This test is failing. Run it, find out why, and fix DocsController.java
so it passes again.
Copilot wants to run: mvn -q -Dtest=DocsControllerTest test
[ Continue ] [ Skip ]
Copilot edited DocsController.java (applied; review the diff)
[ Keep ] [ Undo ]
Copilot wants to run: mvn -q -Dtest=DocsControllerTest test
[ Continue ] [ Skip ]
$ claude "DocsControllerTest#getPage_returns404WhenMissing is failing. Run it, find out why,
and fix @src/main/java/com/example/docsassistant/DocsController.java so it passes again."
Bash(mvn -q -Dtest=DocsControllerTest test)
Do you want to proceed? 1. Yes 2. Yes, and don't ask again 3. No
Edit(src/main/java/com/example/docsassistant/DocsController.java)
Do you want to make this edit? 1. Yes 2. Yes, and don't ask again 3. No
Bash(mvn -q -Dtest=DocsControllerTest test)
Do you want to proceed? 1. Yes 2. Yes, and don't ask again 3. No
Both runs follow the same loop — gather (open the failing test and the controller), plan (decide the fix), edit, run (the test again) and verify (read its output) — repeating the run/verify pair until the test passes or you stop it: