GitHub Copilot Custom Agent Examples (.agent.md)
Three complete custom agent files you can copy, a reviewer, a planner and a docs writer, with the frontmatter explained field by field: tools, MCP servers, handoffs, and where the files go for a repository, an organisation or an enterprise.
8 min read
A GitHub Copilot custom agent is one Markdown file: YAML frontmatter that says what the agent is called, what it is for and which tools it may use, followed by the instructions it works to. Put it in .github/agents/ as reviewer.agent.md and the same file works in VS Code, in the Copilot CLI and in Copilot’s cloud agent on GitHub. Below are three complete files, a reviewer that cannot edit, a planner that hands off to the next step, and a docs writer that edits only documentation, followed by the fields they use and how to call each one in each place.
This post is about writing the files. What an agent is for compared with a skill is in GitHub Copilot agents vs skills, and rules for every request belong in instructions, with examples in Copilot instructions examples.
The format in one screen
GitHub’s custom agents configuration reference (opens in a new tab) lists the frontmatter properties that work on GitHub.com, in the CLI and in supported IDEs. Only one is required.
description, required: what the agent does. It is also what Copilot matches a request against when it picks an agent by itself, so write it as “use this when…”.name: optional. Without it, the file name minus.mdor.agent.mdis used.tools: the tools it may use. Leave it out, or use["*"], for everything;[]for nothing. Unrecognised names are ignored, which means a typo quietly removes a tool.model: the model to use; without it the agent inherits the default.target:vscodeorgithub-copilotto restrict the agent to one environment. Without it, both.disable-model-invocation: when true, Copilot will not pick the agent by itself.user-invocable: when false, people cannot pick it. These two replaceinfer, which GitHub lists as retired.mcp-servers: MCP servers for this agent only, written as YAML. Used by the cloud agent and the CLI; VS Code ignores it and uses its own MCP configuration.metadata: name and value pairs for your own annotations, also ignored in IDEs.
Everything below the frontmatter is the agent’s prompt, up to 30,000 characters. VS Code adds a few fields of its own: handoffs for buttons that pass the work to another agent, agents for which agents it may call as subagents, and argument-hint for the text shown in the chat box. GitHub’s reference says the cloud agent on GitHub.com ignores handoffs and argument-hint, so a file that uses them still works there, just without the buttons.
Tool names that work everywhere
Tool names differ between VS Code, the CLI and the cloud agent, so GitHub defines aliases that each environment maps to its own tools. They are case-insensitive.
read: read files.search: search for files or text in files.edit: change files.execute: run shell commands, also accepted asshell.agent: call another custom agent.webandtodo: fetching pages and keeping a task list. Both work in VS Code and are not available to the cloud agent.- MCP tools:
server/toolfor one tool,server/*for all of a server’s tools. The cloud agent hasgithubandplaywrightservers built in, sogithub/*works there without setup.
VS Code also takes its own finer names, such as search/codebase or web/fetch. They are more precise, but a file using them loses those tools when it runs somewhere else; the aliases travel.
Example 1: a reviewer that cannot edit
The point of a reviewer is that it only reads. The tools list is what enforces that: with no edit and no execute, “do not change files” is not a request the model can ignore, because it has nothing to change them with.
--- name: reviewer description: Reviews a change for bugs, missing tests and risky code. Use when asked to review a diff, branch or pull request. Never edits files. tools: ['read', 'search', 'github/*'] --- You review code. You do not write it. 1. Find what changed: the pull request, the branch diff, or the files named. 2. For each change, check it does what the description says, handles empty and error cases, and has a test that would fail without it. 3. Report findings as a list, most serious first. Each finding gives file:line, what is wrong, and a concrete fix. 4. If you find nothing, say so in one line. Do not invent issues. Style comments go last, and only if the repository's instructions file sets that style.
On the cloud agent, github/* gives read-only access to the repository it is working in, which is what a reviewer needs for pull request context. In VS Code it matches only if you have a server named github in your MCP configuration; otherwise it is ignored and the agent reads the files locally.
Example 2: a planner that hands off
A planner reads the code and a task, writes a plan, and stops. This one reads the task from a board over MCP and writes the plan back to it, then offers two buttons in VS Code: implement, or get the plan reviewed first. The mcp-servers block gives the cloud agent and the CLI the connection; in VS Code the same tool names reach the fenbs server in your own MCP configuration.
---
name: planner
description: Turns a board task into a step-by-step plan with files and tests. Use before implementing anything non-trivial. Never edits code.
tools: ['read', 'search', 'fenbs/fenbs_get_item', 'fenbs/fenbs_search', 'fenbs/fenbs_update_item']
mcp-servers:
fenbs:
type: 'http'
url: 'https://fenbs.ai/api/mcp'
headers:
Authorization: 'Bearer $COPILOT_MCP_FENBS_TOKEN'
tools: ['fenbs_get_item', 'fenbs_search', 'fenbs_update_item']
handoffs:
- label: Implement the plan
agent: implementer
prompt: Implement the plan above, one step at a time. Stop and ask if a step is unclear.
- label: Review the plan first
agent: reviewer
prompt: Review the plan above for risks, missing tests and steps in the wrong order.
---
You plan. You do not change code.
1. Read the task with fenbs_get_item. If you were given no task reference,
ask for one; do not guess.
2. Read the code it touches. Name every file you expect to change.
3. Write a numbered plan: each step, the files, and how it will be checked.
List what could go wrong.
4. Save the plan to the task's plan field with fenbs_update_item.
Do not change its lane or kind.Two details. A handoff button switches to the named agent, here an implementer agent of your own, with the prompt filled in; send: true would submit it automatically, and leaving it out keeps a person in the loop. And the header uses $COPILOT_MCP_FENBS_TOKEN: GitHub’s reference says secrets for agent MCP servers must be set as Agents secrets at repository or organisation level, and its MCP configuration refers to them by names that start with COPILOT_MCP_. The cloud agent cannot sign in to a remote server with OAuth, so it needs a token issued by hand; in fenbs that is under Settings, “Connect an AI assistant”, with only read and write ticked for this agent.
Example 3: a docs writer that edits only docs
A docs writer needs edit, which means it can edit anything. The tools list cannot limit it to a folder, so the prompt says where it may write and the review catches the rest. Leaving out execute at least keeps it from running commands.
--- name: docs-writer description: Writes and updates documentation for a change. Use after code is merged, or when asked to document a feature. Edits only Markdown under docs/ and README files. tools: ['read', 'search', 'edit'] --- You write documentation for people who did not write the code. - Only create or change files under docs/ and README.md files. If code looks wrong, say so in your summary; do not fix it. - Read the code before describing it. Every option, flag and default you document must exist in the code as it is now. - One task per page. Start with what the reader is trying to do, then the steps, then a working example. - Use British spelling and short sentences. No marketing language. End with a list of the files you changed.
Where the files live
- A repository:
.github/agents/NAME.agent.md. GitHub also accepts plain.md; file names may use only letters, digits,.,-and_. - An organisation: an
agents/folder at the root of its.githubor.github-privaterepository, according to GitHub’s page about custom agents (opens in a new tab). Every repository in the organisation then sees them. - An enterprise: an
agents/folder in the.github-privaterepository of an organisation the enterprise designates. - Yourself:
~/.copilot/agents/for the CLI and VS Code. VS Code also reads.claude/agents/in the workspace and~/.claude/agents/in your home folder.
When two levels define an agent with the same file name, the lower one wins: repository over organisation over enterprise. In the CLI, your home folder beats the repository. GitHub versions an agent by the commit that last changed its file, and a pull request keeps using the version it started with.
Calling them
- VS Code: pick the agent from the agents dropdown in Chat, or run Chat: New Custom Agent to create one. Organisation agents appear when
github.copilot.chat.organizationCustomAgents.enabledis on, as the VS Code custom agents page (opens in a new tab) describes. - The cloud agent on GitHub.com: choose the agent from the dropdown when you assign an issue to Copilot, or in the agents panel when you start a task. GitHub’s guide to creating custom agents (opens in a new tab) walks through both. Azure Boards shows the same list when you start Copilot from a work item; see Copilot’s cloud agent with Azure Boards.
- The Copilot CLI:
/agentin an interactive session, the--agentoption, or naming the agent in your prompt. GitHub’s CLI guide (opens in a new tab) also says Copilot may pick one by itself when a prompt matches its description.
copilot --agent reviewer --prompt "Review the changes on this branch against main"
Mistakes that make an agent do nothing
- A misspelt tool. It is ignored without a warning, so the agent simply lacks it. Ask the agent which tools it has on its first run.
- An MCP tool listed in
toolswhose server is not configured where the agent runs.fenbs/*needs a server calledfenbsin VS Code’s MCP configuration, the agent’smcp-servers, or the repository’s MCP settings. - A vague description. Copilot chooses agents by their description; “helpful assistant” matches everything and nothing.
- Relying on
handoffson GitHub.com. They are ignored there, so a sequence that depends on them needs a person to start each step.
What the agents share
Each of these agents starts from nothing: it does not remember the last session, and none of them knows what the others did. What connects them is the task. On fenbs a task has a note that says what is wrong, a plan that says how it will be done, and a test status with notes, in lanes To Do, Next Up, In Progress and Completed. The planner writes the plan, the implementer follows it, the reviewer comments, and every change is recorded under the assistant’s name and yours. The agent’s tools list, the token’s scopes and your role on the board each cap what it can do, and there is no assignee field or sprint for an agent to fill in: moving a task to In Progress with a comment is how an agent says it has it.
Related
Several agents at once: multi-agent setups with GitHub Copilot. Connecting the board in VS Code: GitHub Copilot integration. What a token can do: assistant tokens and scopes.