GitHub Copilot Developer Playbook · Part 1.3
Copilot's subagents don't work for your custom agents
Six Copilot mechanisms fit one org chart. VS Code Hooks are in preview, Visual Studio 2026 18.5+ supports Agent Skills, and Xcode Prompt Files remain disputed.
Marcin
Java since 2007, .NET since 2010 · Azure · lately deep in LLMs
I've seen this exact mix up happen more than once: someone sets up what they're sure is a guaranteed step, every time Copilot touches a file in a certain directory it has to run a formatting pass first, no exceptions. They build it as a Skill, watch it fire a couple of times, call it done. Weeks later it quietly doesn't fire on the one task where it actually mattered, and the debugging starts from the wrong assumption entirely, that something broke, instead of the real answer: a Skill was never a guarantee to begin with. It's a good guess Copilot makes when something looks relevant. What they actually wanted was a Hook.
Here's the mental model that would have saved that debugging session: Copilot doesn't have one undifferentiated bucket of "customization." It has something closer to an org chart, and the position you slot something into changes what you can actually promise about it.
The Whole Roster, at a Glance
Six positions on this org chart, and they're easy to blur together if you only half remember each one:
| Mechanism | Definition | Trigger | Scope | File location |
|---|---|---|---|---|
| Custom Agents | Specialist persona with its own instructions, tool restrictions, and context | Manual, and automatic on both Copilot CLI and Copilot cloud agent | Repository, organization, enterprise, personal | .github/agents/AGENT-NAME.md (repo); also organization, enterprise, and personal levels |
| Subagents | Separate agent spawned by the main agent to handle delegated work in an isolated context | Automatic, or direct reference in a prompt | Runtime only, no persistent configuration | None. A runtime role, not a file |
| Agent Skills | Folder of instructions, scripts, and resources Copilot loads when relevant to a task | Automatic | Project, personal | .github/skills/<name>/SKILL.md, plus a couple of cross tool variants |
| Hooks | Custom shell commands that execute deterministically at specific points in an agent's workflow | Automatic, at configured lifecycle events | Repository by default, with several more CLI only forms | See below |
| Prompt Files | Reusable, standalone prompt template with input variables | Manual, reference in chat or the prompt file picker | Repository only | .github/prompts/*.prompt.md |
AGENTS.md | Portable, cross tool instructions file | File based | Cloud agent: root and nested. Code review: root only | AGENTS.md |
Six named things, and I want to walk the ones that trip people up, starting with the one that's stated backwards more often than not.
Custom Agents Don't Have Assistants. They Get Borrowed.
A custom agent is a specialist you name and give a job description to, a React reviewer, a read only auditor, whatever your team needs a distinct persona for. You give it its own instructions and tool restrictions, and it shows up as a real option in VS Code, Visual Studio, JetBrains (preview), Eclipse (preview), Xcode (preview), GitHub.com, Copilot CLI, and now the GitHub Copilot desktop app too, which picks a custom agent the exact same way the CLI does: type /agent and choose one.
Here's the part that's easy to get backwards on a quick skim, before you've read the source carefully: a custom agent does not spawn subagents. It's the other way around. The main Copilot agent is the one doing the delegating, and when it decides a task deserves an isolated side room with its own context window, it puts one of your custom agents, or a built in one, into that room. The specialist gets borrowed for the task. It doesn't run its own crew of side rooms.
That distinction matters because Subagents' own footprint is much smaller than Custom Agents'. No Visual Studio, no GitHub.com, despite the two being directly related. Don't assume support for one carries over to the other just because they're joined at the hip conceptually.
Selection into a custom agent role is dual mode too, and worth knowing exactly where each half applies. Copilot CLI will infer which agent fits the task, no explicit ask required, and separately gives you three manual ways in: the /agent command, naming the agent directly, or a CLI flag. Copilot cloud agent has its own automatic path as well, controlled by a disable-model-invocation property in the agent's own file. Set that to true and the agent must be manually selected. Built in agents get automatic selection too, on a different page from custom agents' own. Don't cite one as covering both, and don't treat this as a CLI only story, because it genuinely isn't.
One correction worth carrying, since it trips up anyone skimming the library of prebuilt examples: "Code reviewer," "Pull request assistant," and "Issue manager" all sound like agents. They're filed under custom instructions instead. If you're hunting for agent examples specifically, the real ones are things like "Implementation planner," "Bug fix teammate," and "Cleanup specialist."
A Specialist Can Bring Their Own Outside Contacts
Here's something that isn't just a repo wide setting: a custom agent's own file can list its own MCP servers directly, through an mcp-servers property, rather than going through whatever's already configured for the whole repository. Think of it as the specialist bringing their own outside vendor relationships straight into their personnel file, instead of using only the building's official approved vendor list. No procurement meeting required.
That property runs on GitHub.com and Copilot CLI. It does not apply to IDE custom agents.
There are two fields called "tools" living close together here, and they do different jobs, which is exactly the kind of thing worth getting precise about before it costs you a debugging session:
- The agent's own top level
tools:list filters everything that specialist is allowed to touch, built in tools and anything sourced from MCP servers alike, the MCP ones referenced with aserver-name/tool-nameformat. Leave it unset and the agent defaults to everything. - A
tools:field can also live nested inside one specific server's own block withinmcp-servers, and that one restricts what that single server exposes in the first place, before the agent level filter even gets a say.
One filters what the specialist can reach across the board. The other limits what one particular outside contact is willing to hand over at all.
Here's what that looks like written out, an illustrative example rather than something pulled from a real repo:
---
name: release-notes-drafter
description: Drafts release notes from merged PRs and flags breaking changes for review.
tools: ['read', 'search', 'changelog/generate_entry']
mcp-servers:
changelog:
type: 'local'
command: 'npx'
args: ['-y', '@example/changelog-mcp-server']
tools: ['generate_entry', 'list_merged_prs']
env:
CHANGELOG_API_KEY: ${{ secrets.COPILOT_MCP_CHANGELOG_API_KEY }}
---
Draft release notes from the PRs merged since the last tag. Group changes by
type (feature, fix, breaking change), and flag anything touching a public
API surface for human review before publishing.
Notice the changelog server itself is narrowed to two operations at the server level, generate_entry and list_merged_prs, but the agent's own top level list only actually grants changelog/generate_entry. This specialist can draft entries but can't go pull a list of every merged PR, even though the server it's talking to would happily let it. Two separate gates, stacked. And that secret reference, the ${{ secrets... }} form, uses GitHub Actions style syntax. It's an addition on top of the same forms Part 1.2's repository level config already uses, not a rival system replacing them. Same COPILOT_MCP_ naming convention underneath either way.
Skills Are a Good Guess. Hooks Are a Promise.
Here's the distinction that actually costs people that afternoon. A Skill is a folder of instructions, scripts, and resources Copilot loads automatically when it judges the task relevant. That word, judges, is the whole story. Picture the colleague who wanders over and pitches in because the conversation sounded like their department, not because anyone actually assigned them the work. It's a good guess, not a commitment.
A Hook is a shell command that fires deterministically at a specific point in the workflow. Automatic and guaranteed, not automatic and probable, the mandatory sign off nobody on the org chart gets to route around. That's the entire reason to reach for one over the other: formatter runs after an edit, approval or denial before a tool executes, secret scanning before a credential ever has the chance to leak. Anywhere "probably loaded if relevant" genuinely isn't good enough, that's a Hook, not a Skill dressed up to look like one.
Hooks turn out to be a lot more elaborate under the hood than "a script that runs," and this is the part most likely to get flattened into something simpler than it is. The GitHub Hooks Reference lays out six separate configuration forms for it, spread across four load order tiers, but that's the reference's model for two specific surfaces, Copilot CLI and Copilot cloud agent, not a universal Hooks taxonomy. VS Code runs its own separate, preview stage configuration model, more on that below. Within the CLI and cloud agent's own six forms, each one is an actual file path worth bookmarking rather than taking on faith. Combined load order: policy, then user, then project, then plugins:
| # | Form | Tier | Location | Applies to |
|---|---|---|---|---|
| 1 | Policy files | Policy | /etc/github-copilot/policy.d/*.json (macOS/Linux); Windows Registry or ProgramData on Windows | Copilot CLI only, loads before everything else |
| 2 | User hook files | User | ~/.copilot/hooks/, or $COPILOT_HOME/hooks/ if that variable is set | Copilot CLI only |
| 3 | User inline settings | User | hooks field in ~/.copilot/settings.json, distinct from #2 | Copilot CLI only |
| 4 | Repository hook files | Project | .github/hooks/*.json | Copilot CLI, and cloud agent by default |
| 5 | Repository inline settings | Project | hooks field in .github/copilot/settings.json | Copilot CLI only |
| 6 | Plugin provided | Plugins | Each plugin's own hooks.json | Copilot CLI confirmed, cloud agent unconfirmed |
That "by default" on form four is deliberate wording, not a hedge for its own sake. GitHub's own line is that in a cloud agent job, the only hook configuration that exists by default is the repository's own hook files, and the sandbox doesn't ship with user level files, settings, or installed plugins. Default, though, isn't the same as ceiling. Cloud agent plugin installation is a real, documented thing now, and plugins can bundle Hooks among their capabilities. Whether a cloud agent installed plugin's Hooks actually fire the same way they do under the CLI isn't spelled out anywhere I could find. Treat that one as genuinely open, not settled either direction.
The Copilot desktop app turns out to be a further, indirect route into Hooks too. Its own documentation lists plugins as extending the app with skills, hooks, and custom agents among their capabilities. Same caveat as the cloud agent plugin question: the exact execution details aren't spelled out, so treat the app as plugin mediated, not a first class surface the way GitHub.com and CLI are.
VS Code runs Hooks entirely outside that table, worth a quick separate mention rather than folding it in. Preview stage, its own discovery locations: a workspace .github/hooks/*.json file, a user level ~/.copilot/hooks folder, and a setting for pointing at more locations besides. Hooks can live in a custom agent's own configuration too, and plugins can ship their own. It speaks the same hook format Claude Code and Copilot CLI use, for compatibility, converting event names between the two. None of that belongs in the table above, that one's the CLI and cloud agent's specifically, but VS Code clearly isn't left without a system of its own.
One Argument Nobody's Settled Yet, and Two That Got Settled
Every one of these mechanisms has an official surface support answer somewhere, and one of those answers still contradicts itself depending on which page you're reading. The org chart says one thing, the department's own handbook says another. Not a close call. A genuine, unresolved disagreement between two current official sources, worth testing yourself before you trust either page blindly.
Prompt Files and Xcode: one reference marks it preview, a separate page states Prompt Files are only available in VS Code, Visual Studio, and JetBrains, full stop, with Xcode never mentioned at all. Nothing checked resolves it either way, so treat it as open until you've tested your own setup.
Hooks and Agent Skills both used to sit on this list too, and it's worth saying why neither one does anymore.
Hooks and VS Code first: the reference marked VS Code as preview support, while the dedicated Hooks page stated plainly that Hooks are supported in exactly two surfaces, Copilot CLI and Copilot cloud agent, VS Code never coming up. Looked like a standoff, except the department in question, VS Code itself, keeps its own handbook, and it had not yet been checked in this project's research. Turns out it exists: VS Code's own documentation, titled "Agent hooks in Visual Studio Code (Preview)," says outright that agent hooks are currently in preview. That's not a summary table guessing about VS Code. That's VS Code telling you about itself. The question is answered, not argued: VS Code has Hooks, in preview, agreeing with the org chart all along. The dedicated Hooks page hasn't changed, though, and it still says only two surfaces, full stop. That's still a real disagreement, with the reference and with VS Code's own handbook both, and answering the support question elsewhere doesn't make it go away. Keep the Hooks page around for what it's actually good at, the CLI and cloud agent's own configuration detail covered above, and don't lean on its surface count as a directory of everywhere Hooks live.
Agent Skills and Visual Studio ran the exact same play. The reference marks Visual Studio supported, while GitHub's own dedicated Agent Skills page names Visual Studio Code and JetBrains specifically and never mentions Visual Studio anywhere on it. Different product, never mentioned. And once again, the department itself, Visual Studio, keeps a handbook on its own vendor's site that had not yet been checked in this project's research. It exists, and it settles things, with a version number the summary table never carried in the first place: Agent Skills work in Visual Studio 2026 version 18.5 and later. That's Visual Studio telling you about itself, not a guess dressed up as a table row. The question is answered, not argued: Visual Studio has Agent Skills, starting at 18.5, agreeing with the org chart all along.
One nuance worth keeping straight rather than letting the metaphor flatten it: a separate skills management panel for browsing and editing skills exists too, and that panel really is Insiders only, version 18.6 and up. But the panel being Insiders-only doesn't mean the feature is. Discovery and execution work fine on the regular 18.5+ release without ever opening that panel. Two different availability boundaries, not two preview statuses: the feature itself ships on the stable 18.5+ release, and only the management panel sits behind the Insiders line at 18.6+. Easy to blur those together if you're not asking which piece of Visual Studio you actually mean. GitHub's general Agent Skills page hasn't changed either, and it still doesn't mention Visual Studio anywhere. That's still a real gap between GitHub's own two pages, and answering the support question elsewhere doesn't make the omission disappear, it just stops being evidence that Visual Studio lacks the feature.
One more scope note that's easy to miss and specific enough to be worth stating exactly: Agent Skills support for code review is public preview, and so is MCP server support there. That's not a general Agent Skills caveat, it's specific to code review, so don't over apply it to every surface in the table.
Prompt Files and the Handbook
Two more worth a quick word. A Prompt File is a reusable template with input variables, manual only, and it lives at the repository level exclusively. No GitHub.com, no Copilot CLI, which is genuinely unusual among these six. Custom Agents and Skills both reach GitHub.com and CLI. Prompt Files stay IDE bound.
AGENTS.md earns a narrower mention here than you might expect, because its precedence relationship to .github/copilot-instructions.md already got covered back in Part 1.1, and I'm not re-deriving that here. What's worth knowing in this context: cloud agent support shipped first, on 2025-08-28, reading both a root file and nested ones. Code review support arrived later, on 2026-06-18, and reads the root file only, no nested support documented for it. Same file format, genuinely different reach depending on who's reading it. And it's additive, not a takeover: the cloud agent keeps reading .github/copilot-instructions.md, path specific instructions, CLAUDE.md, and GEMINI.md right alongside it. Think of AGENTS.md as a handbook portable enough that other companies' staff, other AI tools, can read the same copy, while your own departments still differ on how much of it they actually open.
I keep landing on the same realization writing these: almost everything that trips people up in Copilot's customization surface comes down to assuming two things are the same job because they sit near each other on the page. A specialist and their assistant aren't the same relationship you'd guess. A good guess and a guarantee aren't the same promise. A summary table and a feature's own documentation aren't always telling you the same story, and when they don't, neither one settles it by itself. Your own environment is the tiebreaker. None of this is Copilot being needlessly complicated for its own sake. It's what six genuinely different tools look like once you stop assuming they're one tool wearing different hats. Check which position you actually asked for before you build around it.