17 KiB
date, topic
| date | topic |
|---|---|
| 2026-05-19 | vscode-copilot-agent-tool-access |
VS Code Copilot Agent Tool Access for CE Plugin
Problem Frame
When the Compound Engineering plugin is installed in VS Code via "Chat: Install Plugin from Source", CE subagents (reviewers, researchers, etc.) cannot read workspace files. Invoking ce-correctness-reviewer produces:
ACCESS_FAILED No filesystem read tool is available in this session to read README.md
Meanwhile, built-in subagents like Explore succeed in the same session, proving the VS Code Copilot host does provide workspace access to subagents — but only when tools are properly declared in the agent's frontmatter.
The root cause is a gap in the converter pipeline:
- Claude agent
.agent.mdfiles declare tools (tools: Read, Grep, Glob, Bash), but the parser never captures them. - The Copilot converter intentionally drops tools, emitting agents without a
toolsfield. - VS Code Copilot interprets a missing
toolsfield as "no tools granted" for custom plugin agents (contrary to the converter's original assumption that omitting means defaults).
This renders all CE subagents inert under Copilot — they can reason but cannot inspect code.
Actors
- A1. Developer using CE in VS Code Copilot: Invokes CE skills and agents expecting them to read/search/execute against the workspace.
- A2. CE converter pipeline: Parses Claude plugin source, converts agents/skills to Copilot-compatible format, and writes output files.
- A3. VS Code Copilot host: Loads plugin agent definitions, grants tools based on frontmatter declarations, and dispatches subagents.
Key Flows
-
F1. Subagent tool access (broken path)
- Trigger: User invokes a CE skill that dispatches a reviewer/researcher subagent.
- Actors: A1, A3
- Steps:
- User invokes
/compound-engineering:ce-code-review - Skill dispatches
ce-correctness-revieweras subagent - VS Code Copilot loads the agent definition, finds no
toolsfield - Subagent receives no filesystem tools
- Subagent fails to read any files
- User invokes
- Outcome: Review fails with tool-access error.
- Covered by: R1, R2, R3
-
F2. Subagent tool access (fixed path)
- Trigger: Same as F1, after fix is applied.
- Actors: A1, A2, A3
- Steps:
- Parser captures
toolsfrom Claude agent frontmatter - Converter maps Claude tools to Copilot aliases (
read,search,execute, etc.) - Emitted
.agent.mdincludestools: [read, search, execute] - VS Code Copilot grants declared tools to subagent
- Subagent reads workspace files successfully
- Parser captures
- Outcome: CE reviewers and researchers operate with full workspace access.
- Covered by: R1, R2, R3, R4
Requirements
Parser: Capture agent tools
- R1. The Claude parser (
src/parsers/claude.tsloadAgents) must parse thetoolsfield from agent frontmatter and populate it on theClaudeAgenttype. - R2. The
ClaudeAgenttype (src/types/claude.ts) must include an optionaltools?: string[]field.
Converter: Map tools to Copilot aliases
- R3. The Copilot converter (
src/converters/claude-to-copilot.ts) must map Claude tool names to VS Code Copilot tool aliases and emit atoolsarray in agent frontmatter. Mapping:Read→readGrep,Glob→searchGlob→search(deduplicated with Grep)Bash→executeWrite,Edit,Patch,MultiEdit→editWebFetch,WebSearch→webTodoRead,TodoWrite→todoTask→agent- MCP tool references (e.g.,
mcp__context7__*) → omitted (not mappable to Copilot built-in aliases)
- R4. Output deduplication: the emitted
toolsarray must contain unique values only (e.g.,Grep+Globboth map tosearch, emitsearchonce). - R5. If no tools are declared on the source agent, the converter must omit the
toolsfield (preserving current behavior for agents that genuinely have no tool declarations).
Copilot type: Support tools field
- R6. The
CopilotAgenttype should support tools metadata so the converter's output is type-safe. This may be achieved by adding a field to the type or by ensuring the frontmatter serialization path handles it.
Tests
- R7. Update
tests/copilot-converter.test.tsto assert that agents with declared tools produce correct Copilottoolsarrays. - R8. Add test cases for: deduplication, unknown/unmappable tools (omitted gracefully), agents with no tools (field omitted), agents with web/MCP tools.
- R9. Add or update parser tests to verify
toolsis captured from agent frontmatter.
No install target required for plugin-from-source
- R10. The fix must work when VS Code loads the plugin directly from the repo via "Chat: Install Plugin from Source" — meaning the plugin-native
.agent.mdfiles must carry the correct Copilottoolsfrontmatter, OR the conversion happens at install time. Determine which path applies (see Outstanding Questions).
Acceptance Examples
-
AE1. Covers R1, R2, R3, R4. Given a CE agent file with
tools: Read, Grep, Glob, Bash, when the plugin is parsed and converted to Copilot format, the output.agent.mdfrontmatter includestools: [read, search, execute](search appears once despite two source entries). -
AE2. Covers R3, R5. Given a CE agent file with no
toolsfield, when converted to Copilot format, the output.agent.mdfrontmatter does NOT include atoolskey. -
AE3. Covers R3. Given a CE agent with
tools: Read, Grep, Glob, Bash, WebFetch, WebSearch, mcp__context7__*, when converted, the output istools: [read, search, execute, web](MCP reference omitted, web deduplicated). -
AE4. Covers R1, R3, R7. Given the
ce-correctness-revieweragent is installed in VS Code Copilot, when it is dispatched as a subagent, it can successfully readREADME.mdfrom the workspace.
Success Criteria
- CE reviewer and researcher subagents can read, search, and execute in the workspace when invoked through VS Code Copilot.
- The smoke test (invoke
ce-correctness-reviewer, ask it to readREADME.md) returns file content instead ofACCESS_FAILED. - No regression: agents without declared tools continue to work as before (tools field omitted).
- Existing non-Copilot targets (OpenCode, Codex, Pi, Gemini, Kiro) are unaffected.
Scope Boundaries
- Not in scope: Changing VS Code Copilot host behavior. We work within the host's documented tool-declaration mechanism.
- Not in scope: Changing
/compound-engineering:ce-*namespacing. This is VS Code Copilot host behavior for installed plugins. Document it but do not attempt to override. - Not in scope:
.compound-engineering/config.local.yamlas a tool-access fix. That config controls CE preferences (Codex delegation, etc.), not Copilot tool grants. - Not in scope: Adding a full
copilotinstall target tosrc/targets/index.ts. The immediate fix is making the converter emit tools. A dedicated install target may be added later. - Not in scope: Changing how the plugin is distributed/installed. The fix must work with the existing "Install Plugin from Source" workflow.
- Deferred: Copilot skill
toolsfield. Skills (SKILL.md) may also benefit from tool declarations, but the immediate failure is in subagents. Skill tool access can be addressed separately if needed. - Deferred: Registering a
copilottarget insrc/targets/index.ts. This would enablebun convert --to copilotas a first-class workflow but is not required for the plugin-from-source fix.
Key Decisions
- Map tools explicitly rather than emitting all tools unconditionally. An explicit mapping ensures CE agents get precisely the capabilities they declare, matching the principle of least privilege. Emitting
tools: [read, search, execute, edit, web, todo, agent]on every agent would work but grants unnecessary capabilities. - Omit unmappable tools (MCP references) rather than erroring. MCP tools are platform-specific and have no Copilot built-in equivalent. Silently dropping them with a warning is the safe default.
- Parse tools as a flat string array. Claude agent frontmatter declares tools as a comma-separated line (
tools: Read, Grep, Glob, Bash). Parse by splitting on commas and trimming whitespace.
Dependencies / Assumptions
- VS Code honors
toolsin plugin agent files. Confirmed: the docs explicitly state custom agents use thetoolsfrontmatter field to declare available tools. - "Install Plugin from Source" reads raw agent files. Confirmed: VS Code clones the repo and loads files directly. No conversion step occurs. The fix must modify source files or the plugin format.
- VS Code Claude format detection uses file extension. The docs state Claude agents are "plain
.mdfiles" in.claude/agents. The CE plugin uses.agent.md— this likely causes format mis-detection. Needs empirical verification. - Tool set names are stable. The
read,search,execute,edit,web,agent,todos,vscode,browsertool sets are documented as of May 2026. - Claude Code may or may not accept Copilot-native tool format. If we change tools to
tools: [read, search, execute], Claude Code behavior needs testing. This is the key cross-platform compatibility question.
Research Findings (2026-05-20)
Q1: How does "Install Plugin from Source" load agents?
Answer: VS Code reads raw agent files directly from the cloned repo. There is no conversion step.
Evidence from VS Code Agent Plugins docs:
- "Run Chat: Install Plugin From Source from the Command Palette. Enter a Git repository URL and VS Code clones and installs the plugin."
- Cached at:
%APPDATA%\Code\agentPlugins\github.com\{org}\{repo}(Windows) - VS Code auto-detects plugin format by checking:
.plugin/plugin.json→plugin.json(root) →.github/plugin/plugin.json→.claude-plugin/plugin.json - The CE plugin has
.claude-plugin/plugin.json, so VS Code identifies it as Claude format
Critical implication: Fixing only the converter is INSUFFICIENT. The raw plugin files must carry tool declarations that VS Code can interpret correctly.
Q2: Does VS Code map Claude tool names automatically?
Answer: YES — documented, but likely broken for this specific case.
From the Custom Agents docs, Claude agent format section:
"VS Code maps Claude-specific tool names to the corresponding VS Code tools. Both the VS Code
.agent.mdformat (with YAML arrays for tools) and the Claude format (with comma-separated strings) are supported."
However, the same docs state:
"Agent files in the
.claude/agentsfolder use plain.mdfiles"
The CE plugin agents use .agent.md extension (ce-correctness-reviewer.agent.md), NOT plain .md. VS Code's Claude format detection for agent files appears to depend on the file extension:
.mdin.claude/agents/→ Claude format (comma-separated tools string, auto-mapped).agent.md→ Copilot format (YAML array of VS Code tool names)
Likely root cause: The CE agent files have Copilot file extension (.agent.md) but Claude-style frontmatter (tools: Read, Grep, Glob, Bash). VS Code parses them as Copilot-format agents and looks for VS Code tool names like Read, Grep — which don't exist. Unrecognized tools are silently ignored, leaving the agent with zero tools.
Q3: Canonical VS Code tool set names
From the VS Code cheat sheet, built-in tool sets:
| Tool Set | Individual Tools |
|---|---|
agent |
agent/runSubagent |
browser |
(experimental, multiple) |
edit |
edit/createDirectory, edit/createFile, edit/editFiles, edit/editNotebook |
execute |
execute/runInTerminal, execute/getTerminalOutput, execute/createAndRunTask, execute/runNotebookCell, execute/testFailure |
read |
read/readFile, read/problems, read/getNotebookSummary, read/readNotebookCellOutput, read/terminalLastCommand, read/terminalSelection |
search |
search/changes, search/codebase, search/fileSearch, search/listDirectory, search/textSearch, search/usages |
todos |
(todo list tool) |
vscode |
vscode/askQuestions, vscode/extensions, vscode/runCommand, vscode/VSCodeAPI |
web |
web/fetch |
Custom agent tools field accepts: tool set names (e.g. read), individual tool names (e.g. read/readFile), MCP tool names, or * for all.
Q4: Does tools: [] differ from omitting tools?
Answer: Not explicitly documented. Based on the error behavior ("No filesystem read tool is available"), an agent with unrecognized tools behaves the same as one with no tools — it gets nothing. The distinction between explicit empty array and omission is academic for this fix since the real issue is the format mismatch.
Q5: Subagent tool inheritance
From the docs, subagents:
- Run as isolated instances with their own agent definition
- The parent agent needs
agentin its tools list and the subagent in itsagentsfield - The subagent uses its own
toolsdeclaration - Built-in
Exploresucceeds because it's a built-in agent with proper tool access
This confirms the issue is in how the subagent's own tools are parsed, not in inheritance.
Revised Problem Analysis
The root cause is a format mismatch, not a missing converter feature:
- CE agent files use
.agent.mdextension (Copilot format indicator) - CE agent files contain Claude-style frontmatter:
tools: Read, Grep, Glob, Bash(comma-separated string) - VS Code sees
.agent.md→ applies Copilot-format parsing → looks for VS Code tool names Read,Grep,Glob,Bashare not valid VS Code tool names → silently dropped- Agent ends up with zero tools → "No filesystem read tool is available"
The built-in Explore agent works because it's VS Code's own agent with proper Copilot-native tool declarations.
Outstanding Questions
Resolve Before Planning
- [Affects fix strategy][Needs testing] Does renaming CE agents to plain
.md(and keepingtools: Read, Grep, Glob, Bash) trigger VS Code's Claude-to-Copilot tool mapping? If yes, the fix is just a file extension rename. If no, we must also change the tool declarations to Copilot-native format. - [Affects fix strategy][Needs testing] If we keep
.agent.mdextension but changetoolsto Copilot-native format (tools: [read, search, execute]), does Claude Code still function correctly? Claude's docs saytoolsis a comma-separated string — does Claude also accept YAML arrays?
Deferred to Planning
- [Affects R6][Technical] Should
CopilotAgenttype carry atools?: string[]field, or is it sufficient for the converter to inject tools into the frontmatter string without type-level modeling? - [Affects scope][Technical] Should the parser change also benefit other converter targets (Codex, Gemini, etc.), or is tool mapping currently handled differently for those targets?
- [Affects upstream][Decision] Should this be reported as a VS Code bug (Claude format mapping not applied to
.agent.mdfiles in Claude-format plugins)?
Validation Plan
After implementation, verify the fix end-to-end:
- Build/convert the plugin (if a build step is required).
- Install in VS Code via "Chat: Install Plugin from Source" pointing at the fork repo.
- Confirm plugin loaded: Check VS Code's extension/plugin list shows compound-engineering from the fork.
- Smoke test — subagent file read:
- Invoke
/compound-engineering:ce-correctness-reviewer(or dispatch it from a skill) - Ask it to read
README.mdand report the first heading - Expected: returns content (e.g.,
# fantastic-chainsawor whatever the repo's H1 is) - Failure:
ACCESS_FAILED No filesystem read tool
- Invoke
- Comparative test — built-in agent:
- Invoke built-in
Explorewith the same request - Expected: succeeds (baseline proof the host provides tools)
- Invoke built-in
- Full flow test — code review:
- Invoke
/compound-engineering:ce-code-reviewon a small diff - Verify reviewer subagents produce findings referencing actual file content
- Invoke
- Regression — no-tools agent:
- If any CE agent legitimately has no
toolsfield, verify it still loads without error
- If any CE agent legitimately has no
Next Steps
Two quick empirical tests will determine the fix strategy:
-
Test A (file extension): Rename one CE agent to
.md(e.g.,ce-correctness-reviewer.md), keep Claude-styletools: Read, Grep, Glob, Bash. Install plugin, invoke as subagent. If it works → fix is renaming all agent files. -
Test B (tool format): Keep
.agent.mdextension, changetoolstotools: [read, search, execute, edit](Copilot-native YAML array). Install plugin, invoke as subagent. If it works → fix is converting tool declarations to Copilot format.
After one test succeeds → /ce-plan for full implementation across all 49 agent files, converter updates, and test changes.