# GitHub Copilot setup for a Next.js app

> Copilot reads AGENTS.md, custom agents, hooks, a plugin and MCP from your repo. Where each file goes, with the real ones from a generated Next.js repo.

*Updated 2026-10-08.*

GitHub Copilot reads AGENTS.md, root and nested, in the CLI, in VS Code and in the cloud agent. That covers the instructions. A generated repo adds the four things AGENTS.md can't carry: custom agents, hooks, a plugin and MCP servers.

Below: each file, what Copilot does with it, and the real version from a generated Next.js repo.

## What Copilot reads

| File | What it is |
|---|---|
| `AGENTS.md`, root and nested | Instructions |
| `.github/copilot-instructions.md`, `.github/instructions/*.instructions.md` | Copilot's own instruction files |
| `.claude/rules/` | Claude Code's rules. Copilot reads them too |
| `.agents/skills/`, `.claude/skills/`, `.github/skills/` | Skills |
| `.github/agents/*.agent.md`, `.claude/agents/` | Custom agents |
| `.github/hooks/*.json`, `.claude/settings.json` | Hooks. The Claude file in the CLI and VS Code |
| `.github/copilot/settings.json` | Plugins, through `enabledPlugins` |
| `.mcp.json` | MCP servers |

## Instructions: AGENTS.md, not copilot-instructions.md

Copilot CLI looks for AGENTS.md at the repo root, in your working folder, in the folders between them, and in folders on the path to a file. When several instruction files apply, it combines them.

So a generated repo ships no `.github/copilot-instructions.md`. AGENTS.md already reaches Copilot, and every other agent too. There's a second reason. Zed reads one instruction file: the first match from a list where `.github/copilot-instructions.md` comes before AGENTS.md. Ship both, and Zed never sees AGENTS.md.

Folder rules sit in nested AGENTS.md files, like this one in `src/app/api/webhooks/stripe/`:

```markdown
# src/app/api/webhooks/stripe

Rules for files under `src/app/api/webhooks/stripe`. The root `AGENTS.md` and every
`AGENTS.md` between it and this folder apply here too.

## Verify every Stripe webhook, keep every handler idempotent

Applies to: `src/app/api/webhooks/stripe/**`, `src/lib/billing/provider.ts`, `src/lib/billing/webhook.ts`
Source: `stripe`
```

*First 9 of 72 lines of `src/app/api/webhooks/stripe/AGENTS.md`.*

One cost to know. Copilot also reads `.claude/rules/`. When Claude Code is picked too, a scoped rule reaches Copilot twice: once from the nested AGENTS.md, once from `.claude/rules/`. That costs tokens, not correctness. Without Claude Code, the generator writes `.github/instructions/<id>.instructions.md` with `applyTo` globs instead, for any rule that didn't fit in its AGENTS.md.

The full AGENTS.md walkthrough: [AGENTS.md examples](/guides/agents-md-examples).

## Custom agents: .github/agents/*.agent.md

A custom agent is a markdown file with an `.agent.md` extension in `.github/agents/`. The frontmatter sets its name, description and tools. The body is its prompt. Copilot can pick one on its own when a task fits the description. Here is the top of the generated PR reviewer:

````markdown
---
description: Reviews a diff against this repo's rules before it becomes a PR. Convention-aware, blocking on correctness and security, advisory on taste.
name: pr-reviewer
tools:
  - read
  - search
  - execute
---

You are the PR reviewer for this repository. You review a change *against the
rules this repo has already written down*, not against your own preferences.
A reviewer who invents new standards mid-review is worse than no reviewer.
````

*First 12 of 89 lines of `.github/agents/pr-reviewer.agent.md`.*

`tools` lists `read`, `search` and `execute`, and no `edit`. The reviewer can run checks, but it can't change code. The repo ships 7 custom agents. Copilot also reads `.claude/agents/`. Personal agents go in `~/.copilot/agents/`.

## Hooks: .github/hooks/agentic-guards.json

Copilot loads hooks from every `.github/hooks/*.json` file. A `preToolUse` hook can deny a tool call before it runs. This is the generated file:

```json
{
  "version": 1,
  "hooks": {
    "postToolUse": [
      {
        "type": "command",
        "bash": "bun .agents/hooks/run.mjs auto-lint --from copilot",
        "powershell": "bun .agents/hooks/run.mjs auto-lint --from copilot",
        "cwd": ".",
        "matcher": "create|edit",
        "timeoutSec": 60
      },
      {
        "type": "command",
        "bash": "bun .agents/hooks/run.mjs enforce-doc-meta --from copilot",
        "powershell": "bun .agents/hooks/run.mjs enforce-doc-meta --from copilot",
        "cwd": ".",
        "matcher": "create|edit",
        "timeoutSec": 60
      },
      {
        "type": "command",
        "bash": "bun .agents/hooks/run.mjs env-leak-detector-write --from copilot",
        "powershell": "bun .agents/hooks/run.mjs env-leak-detector-write --from copilot",
        "cwd": ".",
        "matcher": "create|edit",
        "timeoutSec": 60
      }
    ],
    "preToolUse": [
      {
        "type": "command",
        "bash": "bun .agents/hooks/run.mjs block-destructive --from copilot",
        "powershell": "bun .agents/hooks/run.mjs block-destructive --from copilot",
        "cwd": ".",
        "matcher": "bash|powershell",
        "timeoutSec": 60
      },
      {
        "type": "command",
        "bash": "bun .agents/hooks/run.mjs enforce-typecheck --from copilot",
        "powershell": "bun .agents/hooks/run.mjs enforce-typecheck --from copilot",
        "cwd": ".",
        "matcher": "bash|powershell",
        "timeoutSec": 60
      },
      {
        "type": "command",
        "bash": "bun .agents/hooks/run.mjs env-leak-detector --from copilot",
        "powershell": "bun .agents/hooks/run.mjs env-leak-detector --from copilot",
        "cwd": ".",
        "matcher": "bash|grep|powershell|view",
        "timeoutSec": 60
      },
      {
        "type": "command",
        "bash": "bun .agents/hooks/run.mjs guard-neon-sql --from copilot",
        "powershell": "bun .agents/hooks/run.mjs guard-neon-sql --from copilot",
        "cwd": ".",
        "matcher": "bash|powershell",
        "timeoutSec": 60
      }
    ]
  }
}
```

*`.github/hooks/agentic-guards.json`, as generated.*

How it works:

- **A command per shell.** `bash` and `powershell` hold the same command for each shell.
- **Copilot's tool names.** Matchers use `bash`, `powershell`, `view`, `grep`, `create` and `edit`.
- **One launcher.** Each hook runs `.agents/hooks/run.mjs <guard> --from copilot`. It turns Copilot's payload into the format the guards speak, and answers with `permissionDecision: "deny"` and a reason when a guard blocks.
- **It never fails closed.** In Copilot, any non-zero exit from a `preToolUse` hook denies the call, a crash included, not only exit 2. A broken guard would lock you out of every tool. So the launcher always exits cleanly, and lets the call through with a warning when a guard can't run.

Copilot also reads Claude Code's hooks from `.claude/settings.json`, in the CLI and VS Code. The launcher sees Copilot's payload there and steps aside, so each guard runs once.

Two limits outside Claude Code: a rewrite becomes a block that names the command to run instead, and hiding a secret in command output doesn't happen. The check before the command is what stops a leak. More: [guard hooks in every agent](/guides/ai-coding-agent-hooks).

## The plugin: .github/copilot/settings.json

Copilot turns on the plugins listed under `enabledPlugins` in `.github/copilot/settings.json`. The generated file adds the Compound Engineering plugin, pinned to a release tag:

```json
{
  "extraKnownMarketplaces": {
    "compound-engineering-plugin": {
      "source": {
        "source": "github",
        "repo": "EveryInc/compound-engineering-plugin",
        "ref": "compound-engineering-v3.28.2"
      }
    }
  },
  "enabledPlugins": {
    "compound-engineering@compound-engineering-plugin": true
  }
}
```

*`.github/copilot/settings.json`, as generated.*

Copilot offers it the first time you trust the folder. To install it by hand:

```bash
copilot plugin marketplace add EveryInc/compound-engineering-plugin
copilot plugin install compound-engineering@compound-engineering-plugin
```

It adds `/ce-brainstorm`, `/ce-plan`, `/ce-work`, `/ce-code-review` and `/ce-compound`.

## MCP: .mcp.json

Copilot CLI reads the root `.mcp.json` in a trusted folder. It's the same format Claude Code uses, so one file serves both. Every tool is on by default:

```json
{
  "mcpServers": {
    "better-auth": {
      "type": "http",
      "url": "https://mcp.better-auth.com/mcp"
    },
    "neon": {
      "type": "http",
      "url": "https://mcp.neon.tech/mcp?readonly=true"
    },
    "posthog": {
      "type": "http",
      "url": "https://mcp.posthog.com/mcp?readonly=true"
    },
    "sentry": {
      "type": "http",
      "url": "https://mcp.sentry.dev/mcp"
    },
    "stripe": {
      "type": "http",
      "url": "https://mcp.stripe.com"
    }
  }
}
```

*`.mcp.json`, as generated.*

Start each server from the MCP list in Copilot CLI or VS Code, and sign in to the remote ones. Neon and PostHog connect read-only. Copilot never reads `.env.local`, so a server that needs a key reads it from your environment.

## Skills

Copilot reads Agent Skills from `.agents/skills/`, `.claude/skills/` and `.github/skills/`. Run one as `/name`. The generated repo ships 29 skills, all in `.agents/skills/`. On a fresh clone, start with `/setup`. More: [Agent Skills in every agent](/guides/agent-skills-every-agent).

## Copilot setup checklist

1. Open the repo in Copilot CLI or VS Code, and trust the folder. Copilot skips a repo's own hooks, MCP servers or custom agents until you do.
2. Run `/setup`. It fills `.env.local` and connects the services, after you say yes.
3. Start each MCP server and sign in.
4. Accept the Compound Engineering plugin, or install it with the two commands above.
5. Run `bun run verify:hooks`. It replays every guard in Copilot's own payload format.

## Get a Copilot-ready Next.js repo

Pick your stack at [/build](/build). GitHub Copilot is one of 10 agents, all on by default. You get AGENTS.md and its nested files, `.agents/` with every skill and guard, and `.github/` with custom agents, hooks and the plugin. The same repo works in Claude Code, Codex, Cursor and the rest. $99 once, with lifetime updates. What each agent gets: [the agentic layer](/docs/the-agentic-layer).


Other agents: [Codex setup](/guides/codex-setup-nextjs), [Claude Code setup](/guides/claude-code-setup-nextjs), [Cursor rules](/guides/cursor-rules-nextjs).

## FAQ

### Does GitHub Copilot read AGENTS.md?

Yes, root and nested, in the CLI, VS Code and the cloud agent. When an AGENTS.md and a `.github/copilot-instructions.md` both exist, Copilot uses both.

### Do I need a copilot-instructions.md file?

No. AGENTS.md covers Copilot and most other agents. A `.github/copilot-instructions.md` also hides AGENTS.md from Zed, which reads only the first file it finds.

### Where do Copilot custom agents go?

In `.github/agents/`, one `<name>.agent.md` file each, with a `description` and a `tools` list in the frontmatter. Personal agents go in `~/.copilot/agents/`. Copilot also reads `.claude/agents/`.

### Does GitHub Copilot support hooks?

Yes. Hooks live in `.github/hooks/*.json`. A `preToolUse` hook can deny a call with `permissionDecision: "deny"` or with any non-zero exit. Copilot CLI and VS Code also read hooks from `.claude/settings.json`.

### Does Copilot read .mcp.json?

Copilot CLI reads the root `.mcp.json` in a trusted folder, in the same format Claude Code uses, with every tool on by default.

### Why does Copilot deny every tool call?

Usually a broken `preToolUse` hook. Copilot treats a non-zero exit as a deny, so a hook that crashes on every call blocks every call. Pipe a sample payload into the hook by hand and check its exit code.


## Sources

- [GitHub docs: Custom instructions for Copilot CLI](https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/add-custom-instructions)
- [GitHub docs: Custom agents for Copilot CLI](https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/create-custom-agents-for-cli)
- [GitHub docs: Hooks reference](https://docs.github.com/en/copilot/reference/hooks-reference)
- [GitHub changelog: Copilot coding agent supports AGENTS.md](https://github.blog/changelog/2025-08-28-copilot-coding-agent-now-supports-agents-md-custom-instructions)

## Generate it

[Build your repo](https://agenticboilerplate.com/build)

---

Agentic Boilerplate: A Next.js repo your agent already knows. $99 once. Lifetime access and updates.

- Site map for agents: https://agenticboilerplate.com/llms.txt
- Public API: https://agenticboilerplate.com/openapi.json
- Contact: agenticstudio@gmail.com
