GitHub Copilot setup

ghcp is the agent runtime behind every AI task. It is the default provider: on ai@1, and today it is the only one that ships — so a task that names no provider runs here, and so does every SDD phase.

It is a prerequisite, not a plugin. Nothing is bundled and nothing is installed for you. Two things have to be true on the machine before an AI task can run, and this page is both of them.

Skip this page entirely if you are not writing AI tasks. run:, shell@1, pwsh@1 and file@1 need none of it.

  1. What must be true
  2. 1. The Copilot CLI
    1. Why it is not bundled
    2. Pointing at a copy you already have
    3. What it says when the CLI is missing
  3. 2. A credential
    1. The one dialog you will see
    2. Nothing is read out of your files
  4. What you do not need
  5. What ai@1 hands to ghcp
    1. Model names
  6. The environment the CLI child gets
  7. Every tool is approved automatically
  8. How long a session may run
  9. Naming a different provider
  10. When it fails
  11. Next

What must be true

    Checked
The GitHub Copilot CLI is installed on PATH, or pointed at by COPILOT_CLI_PATH on the first AI task, not at startup
A credential is available the editor’s GitHub sign-in, or the CLI’s own login when the session is created

That is the whole list. Neither is checked until an AI task actually runs — a window that never runs one never pays for the check and never nags you about it.


1. The Copilot CLI

npm install -g @github/copilot

That is the install GitHub’s own tooling tells you to run, and it puts copilot on PATH, which is where this looks first.

Why it is not bundled

The extension does not talk to GitHub itself. It drives the Copilot CLI — a separate program — through GitHub’s SDK. The SDK is the client; the CLI is the thing that runs.

The CLI is roughly 340 MB per platform, across eight platforms. Shipping that inside an extension is not sensible, so it is a prerequisite you install, exactly like PowerShell is for shell: pwsh.

Pointing at a copy you already have

If the CLI is somewhere that is not on PATH, name it:

tasks:
  draft:
    uses: ai@1
    env:
      COPILOT_CLI_PATH: D:\tools\copilot\copilot.exe
    args:
      prompt: Summarise the commits since the last tag.

COPILOT_CLI_PATH is honoured wherever an environment variable can be set — the task’s env:, your shell, or the machine. A copy installed beside the SDK is found automatically, so most people never set it.

Point it at the executable, not at a .js file. Inside VS Code a .js entry point gets launched through Code.exe, the CLI’s argument parser mistakes that for Electron, and the run dies with error: too many arguments. Expected 0 arguments but got 1.

What it says when the CLI is missing

GitHub Copilot CLI not found. Local Workflows drives the CLI directly rather than the Copilot extension, and does not bundle it (it is ~340 MB per platform). Install it with npm install -g @github/copilot, or point COPILOT_CLI_PATH at a copy you already have.

This is checked deliberately and early. Without the check the same machine fails with a native module failing to load, or a spawn error naming a path inside node_modules — both of which read as “the extension is broken” rather than “install this one thing”.


2. A credential

The Copilot CLI keeps its own credential store. It knows nothing about the editor’s. Being signed in to Copilot in VS Code buys the CLI nothing on its own — it starts, finds no authentication, and the turn dies.

So a credential is looked for in this order:

  Where it comes from When it applies
1 The GitHub sign-in VS Code already holds, requested with the read:user scope any machine signed in to GitHub in the editor
2 The CLI’s own login — whatever copilot holds from you signing in to it directly when 1 produced nothing, or you declined

The one dialog you will see

The editor’s sign-in is asked for silently first. On any machine where this extension has been granted access once, no dialog ever appears again.

But a silent request returns nothing until that first grant has happened — so on the very first AI run you get VS Code’s own consent dialog. That moment is safe to ask in: a run only starts from a click, so someone is watching.

Declining is not fatal. It falls through to the CLI’s own login, and if that is signed in the task runs normally.

Nothing is read out of your files

No credential is asked for, stored, or read out of a tasks.yml. A credential in a workflow file is a credential in someone’s git history, which is why there is no key for one.


What you do not need

The GitHub Copilot VS Code extension. Nothing here calls it. A machine with it installed and signed in still needs the CLI; a machine without it works fine with the CLI.

Copilot is also deliberately not declared as an extension dependency — that field force-installs it, and you should not get Copilot pushed onto you for tasks you may never write.


What ai@1 hands to ghcp

Every setting on the task is passed straight through. ghcp adds no settings of its own, which is what makes swapping a vendor one line.

On the task What ghcp does with it
model: the model the session runs on. auto lets the provider pick
system: appended to the SDK’s own system message, so its environment context, tool instructions and guardrails all still stand
allow: / deny: set once on the session as its available and excluded tools, declaratively — not decided per request
mcp: MCP servers the session may call
attachments: files handed over by path, with name as what the agent sees them called
env: layered over the environment the CLI child gets — see below
the task’s cwd the session’s working directory. One client per session, so two tasks can work in different folders at once

Full arg table, mode: review, and the mcp: guidance: ai@1.

Model names

They are the provider’s vocabulary, not this extension’s. ai@1 passes the string through and never validates it. model: auto is the sane default — a pinned name goes stale.


The environment the CLI child gets

Three layers, in this order:

  1. The whole of the editor’s environment. Merged, never replaced — handing the child only the task’s declared env: left it with no PATH and no APPDATA, so it could not even find your Copilot sign-in.
  2. The task’s own env:, layered on top. The same order a run: task gets.
  3. COPILOT_CLI_PATH resolved to the native binary, and ELECTRON_RUN_AS_NODE=1. Both are set for you.

Every tool is approved automatically

ghcp approves each tool the agent asks for, without a card and without a pause. There is no per-tool permission prompt anywhere in the run.

The agent reads, writes and works in your repository. The place a human decides anything is a trigger: manual task you put in the file. See It enforces no gate for why it is built this way, and use allow: / deny: to set policy once instead.


How long a session may run

The task’s own timeout: is the limit that matters — it is the one that actually stops the work.

Underneath it there is a one hour backstop on waiting for a session to report itself idle. That is not a policy; it only stops the extension waiting forever on a session that will never say it has finished.


Naming a different provider

provider: is the only place a vendor is named, so swapping one is that line:

plugins:
  ai:
    uses: ai@1
    args:
      provider: ghcp
      model: auto

Only providers this build registers are accepted. A name it does not know fails before the session starts, with the list of the ones it does:

No agent provider ‘claude’ is registered. Available: ghcp.

That is a configuration error, and it reads as one — it is not reported as an agent that could not finish.


When it fails

Every AI task logs one system line naming the provider and the folder it is working in, which is where to start:

ghcp agent working in D:\src\my-repo
What you see What it means
GitHub Copilot CLI not found... the CLI is not on PATH and COPILOT_CLI_PATH is unset — see above
No agent provider '...' is registered. Available: ghcp. a typo in provider:, or a vendor this build does not ship
MCP server 'x' needs a 'command' to launch - or a 'type: http' and a 'url'. a malformed mcp: block. Checked before any session opens
The agent could not finish: ... the session started and then failed. Authentication failures land here
Cancelled before the agent finished. the run was stopped

Authentication looks like the fourth row. The editor’s sign-in was declined or absent and the CLI has no login of its own, so the session is created without authentication and every turn dies. Fix it by signing in to the CLI directly, or by granting the editor’s request the next time it is offered.

The one-line message is the headline. The full story — the error’s own properties, its cause chain and the stacks — is written to the task’s log, because a one-line message flattens away exactly what you need to debug a timeout or a rejected token.


Next

  • Your first spec — the first thing that needs all of the above.
  • ai@1 — every argument, and mode: review.
  • SDD config — setting provider: and model: once for every phase.

Back to top

Local Workflows is a VS Code extension. Everything it does is declared in a YAML file you own.