Customising GitHub Copilot: instructions, prompts, agents, skills, MCP, and hooks
GitHub Copilot reads several kinds of file from your repository and changes its
behaviour based on them. Most live under .github/, and most are YAML
frontmatter plus a Markdown body. The difference between them is what each one
is for, when Copilot pulls it in, and how much discretion the model has over
whether to follow it.
Custom instructions
Background context Copilot reads on every chat request, automatically.
.github/copilot-instructions.md— applies to every interaction in the repository..github/instructions/*.instructions.md— scoped to a path glob via theapplyTo:frontmatter field. One file for tests, one for migrations, one for the API surface.
Frontmatter:
1---
2description: 'Instructions for writing Go code following idiomatic Go practices and community standards'
3applyTo: '**/*.go,**/go.mod,**/go.sum'
4---The body is the actual guidance: coding standards, naming conventions, architectural rules, team defaults. Nothing is invoked explicitly. Files are injected into the context whenever the matching paths are in scope.
Docs: Your first custom instructions, repository instructions reference.
Reusable prompts
Templates for tasks you run repeatedly. Triggered explicitly via a slash command.
.github/prompts/*.prompt.md— noteprompt.md, singular. The filename inkebab-casebecomes the slash command:create-react-form.prompt.mdruns as/create-react-form.
Frontmatter:
1---
2description: "Generate a new React form component"
3mode: agent # 'agent', 'ask', or 'edit'
4model: Claude Sonnet 4.6 # optional; falls back to the picked model
5tools: ["editFiles", "search", "githubRepo"]
6---The body is the prompt itself, optionally with ${input:name} placeholders that
get prompted for at run time. Useful for code-review templates, scaffolding,
test generation, migration steps — anything where the alternative is pasting the
same prompt twice a week.
Docs: prompt files tutorial.
Custom agents
Specialist personas with their own tool scope and a separate context window.
.github/agents/*.agent.md— repository-level. Organisation- or enterprise-level agents go in a.github-privaterepository underagents/.
Frontmatter:
1---
2name: test-specialist
3description: "Improves test coverage and quality without modifying production code."
4tools: ["read", "edit", "search"]
5---The body is the persona, the boundaries, and the workflow. The tools array is
what keeps an agent in its lane: a test-specialist granted only read,
edit, and search cannot start rewriting production code. mcp-servers: can
be declared in frontmatter to give a single agent access to a connector the rest
of the workspace does not need.
The main Copilot agent can delegate to a custom agent as a subagent. The subagent runs in its own context window, so focused, long-running work does not crowd the main thread.
Docs: custom agents guide.
Agent skills
Reference packages — instructions plus bundled scripts and files — loaded on demand when Copilot judges them relevant.
.github/skills/<skill-name>/SKILL.md, with optional scripts, examples, and reference Markdown alongside.
Frontmatter:
1---
2name: github-actions-failure-debugging
3description: "Use this when asked to debug failing GitHub Actions workflows."
4---The body is the procedure: numbered steps, the tools or MCP servers to call,
examples of correct output. Only the description is in context at session
start. The full body and the bundled files load when Copilot decides the skill
applies. This keeps the working context window clean compared with stuffing the
same content into instructions.
Skills use the same SKILL.md format as Claude Code and Codex, so a
well-written skill ports across tools.
Docs: adding agent skills.
MCP servers
External tools and data sources Copilot can call during a session. The Model Context Protocol is an open standard; servers exist for GitHub itself, Atlassian, Sentry, databases, browsers, and most things with an API worth querying.
Configuration is JSON, not Markdown, and lives in one of:
.vscode/mcp.json— workspace, picked up by VS Code.~/.copilot/mcp-config.json— user, picked up by Copilot CLI.mcp-servers:in an agent’s frontmatter — scoped to that agent only.
Example, .vscode/mcp.json:
1{
2 "servers": {
3 "github": {
4 "type": "http",
5 "url": "https://api.githubcopilot.com/mcp/"
6 },
7 "playwright": {
8 "type": "stdio",
9 "command": "npx",
10 "args": ["-y", "@playwright/mcp@latest"]
11 }
12 }
13}Servers can be local (stdio) or remote (http, sse). Tools from configured
servers are pre-loaded into context, which is why enabling fewer servers and
toolsets is usually the right default — every tool description costs tokens
whether it gets called or not. On Copilot Business and Enterprise the MCP
servers in Copilot policy controls whether MCP can be used at all.
Docs: extending Copilot Chat with MCP.
Hooks
Shell commands that run at lifecycle events. The only deterministic mechanism on the list — everything above is advisory and the model can ignore it. Hooks execute outside the model’s reasoning loop and can block tool calls outright.
.github/hooks/*.json— flat layout, one file per hook..github/hooks/<name>/hooks.jsonplus scripts — folder layout, for hooks that bundle their own logic.
Events: sessionStart, userPromptSubmitted, preToolUse, postToolUse,
agentStop, subagentStop, errorOccurred, sessionEnd. preToolUse is the
one with teeth — a non-zero exit code blocks the tool call.
Example, .github/hooks/format.json — run Prettier after every file write:
1{
2 "version": 1,
3 "hooks": {
4 "postToolUse": [
5 {
6 "type": "command",
7 "bash": "npx prettier --write \"$TOOL_INPUT_FILE_PATH\"",
8 "powershell": "npx prettier --write \"$env:TOOL_INPUT_FILE_PATH\"",
9 "timeoutSec": 30
10 }
11 ]
12 }
13}Hooks are currently in preview and may be disabled by enterprise policy.
Docs: hooks configuration reference.
When to use which
| When it runs | Scoped by | Discretion | |
|---|---|---|---|
| Instruction | Every chat request matching the path | applyTo: glob |
Advisory |
| Prompt | When you type the slash command | The user, explicitly | Advisory |
| Agent | When invoked, or as a subagent | Main agent’s routing | Advisory |
| Skill | When Copilot judges it relevant | Skill description |
Advisory |
| MCP server | When a tool from it is called | Tool name | Model chooses |
| Hook | On a lifecycle event | Event name | Deterministic (exit code) |
Standards and conventions go in instructions. Repeatable workflows go in prompts. Specialised personas go in agents. Procedural recipes with bundled scripts go in skills. External data and tools go in MCP. Anything that must happen, or must not happen, regardless of what the model decides — goes in a hook.
AGENTS.md at the repository root is a parallel convention Copilot’s cloud
agent now also reads, useful if you want one file the cloud agent, Claude Code,
and other tools all pick up.
Other configuration
A few smaller surfaces, worth knowing about but not central:
- Chat modes (
.github/chatmodes/*.chatmode.md) — VS Code chat presets that combine a mode, model, tool set, and instructions. Predates custom agents and overlaps with them; agents are the more portable option. - Content exclusion — repo, organisation, and enterprise settings in GitHub, plus per-language toggles in VS Code, that keep specified files out of Copilot’s context. Worth setting before pointing Copilot at a repository with secrets or licensed code.
copilot-setup-steps.yml— a workflow file the Copilot cloud agent runs in its sandbox before starting a job. Installs dependencies and configures credentials so the agent does not have to.- Monorepo discovery — Copilot CLI and the cloud agent walk up the directory
tree and merge customisations at every level. In VS Code, set
chat.useCustomizationsInParentRepositoriesto get the same behaviour.
References
- Want better AI outputs? Try context engineering — GitHub’s writeup of Harald Kirschner’s GitHub Universe 2025 talk on this material.
- Context engineering guide for VS Code.
- Building reliable AI workflows with agentic primitives.
- How to write a great
agents.mdfile (lessons from 2,500+ repositories).