A Developer’s Guide to GitHub Copilot CLI: Agentic Coding in Your Terminal
Most of us live in the terminal. We build, test, commit, grep, tail logs, and wire together pipelines without ever reaching for the mouse. So it makes sense that GitHub brought the full power of its Copilot coding agent to exactly where developers already spend their time — the command line.
GitHub Copilot CLI is not “autocomplete in a shell”. It’s an agentic assistant that can read your code, plan multi-step work, run commands (with your approval), edit files, drive Git and gh, talk to GitHub.com, and call out to MCP servers and custom agents. It uses the same agentic harness as the Copilot coding agent, so what you get in the terminal is a genuine collaborator rather than a fancy prompt box.
This post is a practical, hands-on guide. We’ll cover installation, the core interactive workflow, plan mode, permissions, MCP servers, custom agents, and then finish with a set of tips and tricks for advanced usage.
What is Copilot CLI (and what makes it different)?
At a high level, Copilot CLI gives you:
- Terminal-native agentic development — build, edit, debug, and refactor without leaving your shell.
- GitHub integration out of the box — the GitHub MCP server is pre-configured, so it can work with repos, issues, and pull requests using natural language, authenticated with your existing GitHub account.
- Two ways to drive it — an interactive session for conversational, iterative work, and a programmatic (
-p) mode for scripting and automation. - Full control by default — every action that could modify or execute files is previewed and requires your approval, unless you explicitly opt in to broader permissions.
It’s available on all Copilot plans (Free, Pro, Business, Enterprise). If you get Copilot through an organisation, an admin needs to have the Copilot CLI policy enabled. It runs on Linux, macOS, and Windows (via PowerShell 6+ or WSL).
A note on cost: each prompt you submit consumes from your premium request / AI credit allowance, and the amount varies by model. Keep an eye on this with
/usage, which we’ll cover later.
Installing Copilot CLI
There are several installation paths — pick whichever fits your platform and tooling.
Install script (macOS and Linux):
curl -fsSL https://gh.io/copilot-install | bash
Homebrew (macOS and Linux):
brew install copilot-cli
# or the prerelease channel for the newest features
brew install copilot-cli@prerelease
WinGet (Windows):
winget install GitHub.Copilot
npm (all platforms):
npm install -g @github/copilot
Because GitHub is iterating on this tool very quickly (there have been hundreds of releases), it’s worth keeping your client up to date to get the latest features and fixes.
First launch and authentication
Launch the CLI from a folder containing code you want to work with:
copilot
On first launch you’ll be asked to confirm you trust the files in (and below) the current directory — more on why that matters in the security section. If you’re not logged in, run:
/login
and follow the on-screen instructions. You can also authenticate headlessly using a fine-grained Personal Access Token with the “Copilot Requests” permission, exposed via the GH_TOKEN or GITHUB_TOKEN environment variable — handy for CI and containers.
By default Copilot CLI uses Claude Sonnet 4.5. You can switch models (for example to GPT-5) at any time with the /model slash command.
The core workflow: interactive sessions
The interactive interface is where you’ll spend most of your time. Start a session with copilot, then just talk to it. A prompt can be a simple question or a request to do real work.
Example 1: Ask a question about your codebase
> Where is rate limiting implemented in this service, and what limits are applied?
Copilot will search the code, read the relevant files, and answer with references to the exact locations — without you having to grep through anything.
Example 2: Make a change
> Change the background-color of H1 headings to dark blue
Copilot finds the relevant CSS file, proposes the edit, and asks for your approval before writing it. This preview-then-approve loop is the heart of how the CLI keeps you in control.
Example 3: Investigate history
> Show me the last 5 changes made to CHANGELOG.md. Who changed it, when, and give a brief summary of each change.
Here it drives Git on your behalf and summarises the results in plain language.
Example 4: Build something from scratch
> Use create-next-app and Tailwind to scaffold a Next.js dashboard that pulls
build metrics from the GitHub API — build success rate, average duration,
failed builds, and test pass rate. When it's done, give me clear instructions
to build, run, and view it.
This is where the agentic nature shines: Copilot plans the work, runs the scaffolding commands (with approval), writes the code across multiple files, and then hands you run instructions.
Referencing files with @
To pull a specific file into your prompt as context, use @ followed by the path:
> Explain @config/ci/ci-required-checks.yml
> Fix the bug in @src/app.js
As you type a path, matching files appear below the prompt box; use the arrow keys and Tab to complete it. You can also drag and drop files, or paste images (and PDFs) directly — useful for handing Copilot a screenshot of a stack trace or a design mock, on models that support image input.
Running shell commands directly
Prefix input with ! to run a shell command yourself without involving the model:
!git status
!npm test
This is great for quickly checking state mid-conversation without spending a request.
Plan mode: think before you build
For anything non-trivial, plan mode is your friend. Press Shift+Tab to cycle into it. In plan mode, Copilot analyses your request, asks clarifying questions to nail down scope and requirements, and produces a structured implementation plan before writing a single line of code.
> [plan mode] Add OAuth2 login with GitHub as a provider to this Express app,
including session handling and a protected /profile route.
Copilot will come back with questions (“Which session store do you want — in-memory, Redis, or database?”) and then a step-by-step plan. You catch misunderstandings early, stay in control of complex multi-step tasks, and only proceed to implementation once the plan looks right. Press Shift+Tab again to cycle back out and execute.
Rolling back when things go wrong
Copilot doesn’t always do exactly what you had in mind — it might edit the wrong file, take a task in an unexpected direction, or run a command whose results you’d rather undo. When that happens, you can rewind the session to an earlier prompt. Press Esc twice in quick succession (with an empty input box), or use the /undo slash command — or its alias /rewind — to open the rewind picker.
The picker lists the rewind points for your session, most recent first, showing the start of each prompt and how long ago you submitted it. Choosing one takes you back to the state before Copilot started working on that prompt, and the selected prompt is dropped back into the input box so you can tweak and resubmit it.
There are two rewind behaviours, and Copilot picks the best one for your environment automatically:
- Git-based rewind rolls the whole workspace back to a snapshot taken at the start of the prompt. This is thorough but blunt: it reverts everything after that point — Copilot’s changes, your own manual edits, and the effects of shell commands — and deletes any files created since the snapshot. It requires a Git repository with at least one commit.
- Tools-based rewind is more surgical, letting you choose “Conversation only” (rewind the chat history but leave files untouched) or “Conversation + files” (also restore files Copilot changed). It’s currently experimental, so enable it first with
/experimental onor the--experimentalflag.
A word of caution: rewinding can’t be undone — once you roll back, the later session history is gone for good. Afterwards, it’s worth confirming the result with a quick shell command (remember the ! prefix), for example !git status, !git log --oneline -1, or !git diff, without leaving the CLI.
Understanding permissions (and staying safe)
By default, the first time Copilot wants to use a tool that could modify or execute files — touch, chmod, node, sed, and so on — it asks for approval. You’ll typically see three options:
1. Yes
2. Yes, and approve TOOL for the rest of the running session
3. No, and tell Copilot what to do differently (Esc)
- Option 1 allows this one command, this once.
- Option 2 allows that tool for the rest of the session — convenient for something like
chmodyou’ll use repeatedly, but be careful: approvingrmthis way lets Copilot run anyrm(includingrm -rf ./*) without asking again. - Option 3 cancels and lets you steer it in a different direction. You can give inline feedback on the rejection so Copilot adapts without stopping entirely.
Fine-grained control from the command line
You can pre-authorise or block specific tools using flags that work in both interactive and programmatic modes:
# Allow a specific tool without prompting
copilot --allow-tool='shell(git)'
# Allow all shell commands, but explicitly block the dangerous ones
copilot --allow-all-tools --deny-tool='shell(rm)' --deny-tool='shell(git push)'
# Allow all tools from an MCP server except one specific tool
copilot --allow-tool='My-MCP-Server' --deny-tool='My-MCP-Server(tool_name)'
A few things worth knowing:
--deny-toolalways takes precedence over--allow-tooland--allow-all-tools.- For
gitandgh, you can scope to a subcommand, e.g.shell(git push). --allow-tool='write'lets Copilot edit files without per-file approval.- Inside a session,
/allow-alland/yolo(or launching with--allow-all/--yolo) enable everything at once.
Use the broad options with care. With --allow-all-tools, Copilot has the same access to your machine that you do and can run any command without prior approval.
Trusted directories and sandboxing
Copilot CLI only operates within directories you’ve marked as trusted, which is why it prompts you on launch. Don’t launch it from your home directory or from folders full of untrusted executables or sensitive data. You can add directories mid-session with /add-dir /path/to/dir, and switch the working directory with /cwd or /cd.
For extra safety when using automatic approvals, run inside a sandbox:
- Local sandboxing — run
/sandbox enableinside a session to restrict Copilot’s access to your filesystem, network, and system capabilities. - Cloud sandboxing — start an isolated, cloud-hosted session with
copilot --cloud. This keeps session state between uses, lets you continue from a different machine, and run tasks in parallel — without touching your local environment. (Sandboxes are in public preview.)
Working with GitHub.com
Because the GitHub MCP server is pre-configured, Copilot CLI is fluent in your GitHub workflow. Some things you can just ask for:
> List my open PRs
> List all open issues assigned to me in OWNER/REPO
> I've been assigned https://github.com/octo-org/octo-repo/issues/1234 —
start working on it for me in a suitably named branch.
> Create a PR that changes the "How to run" heading to "Example usage" in the
README of https://github.com/octo-org/octo-repo
> Check the changes in PR https://github.com/octo-org/octo-repo/pull/57575 and
report any serious errors.
> Merge all of the open PRs I've created in octo-org/octo-repo
When Copilot opens a PR or issue, it does so on your behalf, and you’re recorded as the author. This turns the CLI into a genuinely useful “assign it and walk away” tool for small, well-scoped changes.
Programmatic mode: Copilot in scripts and pipelines
Pass a single prompt with -p (or --prompt) and the CLI completes the task and exits — perfect for automation. Pair it with approval flags so it can run unattended:
copilot -p "Show me this week's commits and summarise them" --allow-tool='shell(git)'
copilot -p "Revert the last commit, leaving the changes unstaged" --allow-all-tools
You can also generate flags dynamically and pipe them in:
./script-outputting-options.sh | copilot
This unlocks patterns like nightly summarisation jobs, scripted refactors across many repos, or a CI step that asks Copilot to review a diff. Just remember: with automatic approval, there’s no human in the loop, so sandboxing and tightly-scoped --deny-tool rules become important.
Working autonomously: autopilot and /delegate
Sometimes you don’t want to babysit each step — you just want to hand off a task. Copilot CLI gives you two ways to do this, and the difference comes down to where the work happens.
Autopilot mode runs locally. You grant full permissions and Copilot works through the task without stopping to prompt you, while you watch progress in real time on your own machine. Enable it interactively by pressing Shift+Tab until you see “autopilot” in the status bar, then enter your prompt. Or run it programmatically:
copilot --autopilot --yolo --max-autopilot-continues 10 -p "Migrate the test suite from Jest to Vitest and make it pass"
The --max-autopilot-continues flag is a useful safety valve — it caps how many times autopilot will keep going before handing back control.
/delegate pushes the work to the cloud. Instead of running locally, it hands the task to the Copilot cloud agent on GitHub: Copilot creates a branch, opens a draft pull request, and works in the background — so the task keeps running even if you close your laptop.
/delegate complete the API integration tests and fix any failing edge cases
You can also prefix a prompt with & as shorthand for the same thing:
& complete the API integration tests and fix any failing edge cases
Copilot will offer to commit any unstaged changes as a checkpoint on the new branch, then give you a link to the pull request and cloud agent session so you can follow along and review when it’s done. Reach for autopilot when you want hands-free local execution, and /delegate when you want to offload a task entirely and get on with something else.
Running work in parallel with /fleet
When a task breaks down into several independent pieces, the /fleet slash command speeds things up by farming the work out to multiple subagents that run in parallel. It pairs naturally with plan mode: build a plan first, then let a fleet execute it.
The typical flow is:
- Press Shift+Tab to switch into plan mode and describe the feature or change you want.
- Work with Copilot to refine the implementation plan.
- Once the plan looks right, either choose “Accept plan and build on autopilot + /fleet” to have it work autonomously with subagents, or exit plan mode and prompt it yourself:
/fleet implement the plan
Copilot then splits the work across subagents, running independent parts concurrently. Monitor them with the /tasks slash command, which lists the background tasks for the session — including each subagent’s subtask. Use the arrow keys to navigate; press Enter to view details (or a summary once complete), k to kill a process, and r to clear finished ones. Press Esc to return to the prompt.
Extending Copilot CLI
This is where the CLI goes from “useful” to “tailored to how your team works”.
MCP servers
Model Context Protocol (MCP) servers give Copilot access to additional data sources and tools. The GitHub server ships by default; to add more:
/mcp add
Fill in the details (use Tab to move between fields) and press Ctrl+S to save. Configurations live in ~/.copilot/mcp-config.json (override the location with COPILOT_HOME). You can list configured servers and their tool names with /mcp — useful when you want to reference a server precisely in an --allow-tool / --deny-tool rule.
Tip: if you know a specific MCP server can do the job, name it in your prompt — e.g. “Use the GitHub MCP server to find good first issues in octo-org/octo-repo” — to steer Copilot toward the result you want.
Custom instructions
Copilot CLI automatically reads custom instructions from your repository, so it understands your conventions and how to build, test, and validate changes. It supports:
- Repository-wide:
.github/copilot-instructions.md - Path-specific:
.github/instructions/**/*.instructions.md - Agent files:
AGENTS.md
All applicable instruction files now combine rather than falling back by priority, so you can layer general and path-specific guidance.
Tip: keep your instructions files minimal for efficient token usage. They’re injected into every prompt, so every line costs context. Include only the essential guidance for working in the repository — build and test commands, key conventions, and anything non-obvious — and leave out anything Copilot can readily infer from the code itself.
Custom agents
Custom agents are specialised versions of Copilot for particular workflows. The CLI ships with a set of built-in ones it can delegate to automatically:
| Agent | Purpose |
|---|---|
| Explore | Fast, read-only codebase analysis without polluting your main context |
| Task | Runs commands like tests and builds; brief summary on success, full output on failure |
| General purpose | Complex multi-step work using the full toolset, in a separate context |
| Code review | Reviews changes, focusing on genuine issues and minimising noise |
| Research | Deep research across your code, related repos, and the web, with citations |
| Rubber duck | A constructive critic; consulted automatically by Copilot |
You can invoke agents three ways:
# Pick from a list interactively
/agent
# Ask for one in natural language
> Use the code review agent to check my staged changes
# Select one at launch
copilot --agent=refactor-agent --prompt "Refactor this code block"
Define your own agents as Markdown “agent profiles” specifying their expertise, allowed tools, and instructions — at user level (~/.copilot/agents), repository level (.github/agents), or organisation/enterprise level (.github-private/agents). On naming conflicts, user overrides repository overrides organisation.
Skills and hooks
Two more extension points let you package know-how and enforce guardrails.
Skills enhance Copilot’s ability to perform specialised tasks with bundled instructions, scripts, and resources. A skill is a folder containing a SKILL.md file (with a name and description) plus any helper scripts or reference material. Copilot reads the description to decide when the skill is relevant, then follows its instructions.
For example, a skill that standardises how release notes are generated might live at .github/skills/release-notes/SKILL.md:
---
name: release-notes
description: Generate release notes from merged PRs since the last tag, grouped
by Added / Changed / Fixed, following our CHANGELOG format.
---
# Release notes
1. Find the most recent git tag.
2. Collect merged PRs since that tag using `gh pr list --state merged`.
3. Group them by Conventional Commit type into Added / Changed / Fixed.
4. Write the result to the top of `CHANGELOG.md`, keeping the existing entries.
Now a prompt like “Draft the release notes for the next version” will pick up the skill and produce output that matches your conventions every time.
Hooks let you run custom shell commands automatically at key points in a session — great for validation, logging, security scanning, or workflow automation. Because a hook fires deterministically around agent events, it’s a good place to enforce guardrails rather than relying on the model to remember a rule.
Hooks are configured in JSON. Create a NAME.json file in .github/hooks/ (repository-level) or ~/.copilot/hooks/ (user-level), with a version and a hooks object keyed by event — the available triggers include sessionStart, sessionEnd, userPromptSubmitted, preToolUse, postToolUse, and errorOccurred.
Each entry provides both a bash command (for Linux/macOS) and a powershell command (for Windows), so the hook runs everywhere. For example, a preToolUse hook that logs every tool the agent is about to run — handy for auditing — would live in .github/hooks/audit.json:
{
"version": 1,
"hooks": {
"preToolUse": [
{
"type": "command",
"bash": "echo \"$(date): about to run tool\" >> logs/agent-audit.log",
"powershell": "Add-Content -Path logs/agent-audit.log -Value \"$(Get-Date): about to run tool\"",
"cwd": ".",
"timeoutSec": 10
}
]
}
}
You can also point a hook at an external script instead of an inline command — useful for anything non-trivial, like scanning a proposed change for secrets before it’s written:
{
"version": 1,
"hooks": {
"preToolUse": [
{
"type": "command",
"bash": "./scripts/scan-secrets.sh",
"powershell": "./scripts/scan-secrets.ps1",
"cwd": "scripts",
"timeoutSec": 30
}
]
}
}
The hook receives details of the event as JSON on stdin (timestamp, working directory, tool name, and arguments), so your script can inspect what’s happening and act accordingly. A couple of things to remember: hook config is loaded when the CLI starts, so restart after editing it; any referenced script needs to be executable (chmod +x) with a proper shebang; and the default timeout is 30 seconds, tunable with timeoutSec.
Copilot Memory
Normally, anything you teach Copilot in a session is forgotten when that session ends — so the next time you start up, you’re explaining your conventions all over again. Copilot Memory fixes that by letting the agent keep notes about your repository between sessions.
As it works, Copilot notices recurring facts, conventions, and preferences and saves them as short “memories”. For instance, if you correct it once — “we use Vitest here, not Jest”, or “always put new API routes under src/routes/ and export them from the barrel file” — it can store that and apply it automatically next time, without you having to repeat yourself.
The practical payoff is that later sessions get progressively more useful: Copilot already knows how your project is laid out, which tools you use, and how you like things done, so you spend less time on context and more on the actual task. Think of it as the agent gradually onboarding itself to your codebase.
Tips and tricks for advanced usage
Here’s the stuff that makes daily use noticeably better.
Review before you commit. Run /review to have Copilot analyse your uncommitted changes and give you feedback right in the terminal — no PR required. You can narrow the scope by adding a prompt, path, or file pattern after the command (e.g. /review focus on error handling in src/api). If Copilot needs to run a command to inspect the diff, it’ll ask first; then it reports back any issues so you can fix them before they ever reach a pull request.
Steer while it’s thinking. You don’t have to wait for Copilot to finish. Enqueue follow-up messages to redirect it or queue up the next instruction, and it’ll feel far more like a real conversation.
Connect it to VS Code for the best of both worlds. If you like the speed of the terminal but miss the visual tools of an editor, connect the CLI to VS Code. Start Copilot from a directory that matches an open (trusted) VS Code workspace and it connects automatically — you’ll see “Visual Studio Code connected” in the startup message — or use the /ide slash command to connect, switch, or disconnect at any time. This works whether you’re in VS Code’s integrated terminal or an external one. Once connected you get: your editor selection as context (highlight code and just say “Debug this” — no file paths needed), proposed edits shown as side-by-side diffs you accept or reject visually, access to VS Code’s live diagnostics so Copilot can fix errors your editor already spotted, and the ability to view CLI session transcripts in the Copilot Chat Sessions view and Resume in Terminal to pick up where you left off.
Stop instantly. Pressed enter and immediately regretted the prompt? Hit Esc while it’s “Thinking” to stop.
Resume where you left off. Sessions are saved with their context:
copilot --continue # resume the most recently closed session
copilot --resume # pick a session to resume
You can even kick off a Copilot cloud agent session on GitHub and pull it down into your local CLI to keep going.
Manage your context window. Long sessions are handled automatically — Copilot auto-compacts your history in the background at ~95% of the token limit, enabling effectively endless sessions. To take manual control:
/context— a visual breakdown of current token usage/compact— compress history now (press Esc to cancel)/usage— AI credits used, session duration, lines edited, and per-model token breakdown
Schedule prompts. Automate recurring or delayed work right from a session:
/every 1h Run frontend tests and report any failures
/after 30m Summarise today's merged PRs
At time of writing, scheduled prompts are currently an experimental feature, so you’ll need to enable experimental mode first — either with the /experimental on slash command inside a session, or by launching with the --experimental command-line option.
Toggle reasoning visibility. Press Ctrl+T to show or hide the model’s reasoning as it works. The setting persists across sessions — handy when you want to understand how it reached a conclusion.
Tune settings without leaving the CLI. Use /settings to open an interactive editor, /settings KEY VALUE to set something directly (works in scripts too), and /settings show KEY to print a value. Ctrl+R restores a setting to its default.
Pick the right model for the job. Newer models support a 1M-token context window and configurable reasoning levels. Larger context and higher reasoning consume more credits, so use the regular settings by default and reach for the big context / deep reasoning only on genuinely complex, multi-file tasks.
Bring your own model. You can point Copilot CLI at an OpenAI-compatible endpoint, Azure OpenAI, Anthropic, or a local model like Ollama, using environment variables (COPILOT_PROVIDER_BASE_URL, COPILOT_PROVIDER_TYPE, COPILOT_PROVIDER_API_KEY, COPILOT_MODEL). The model must support tool calling and streaming; run copilot help providers for details.
Wire it into other tools via ACP. Copilot CLI can act as an agent over the Agent Client Protocol (ACP), so IDEs and automation systems that speak ACP can use it directly. See Copilot CLI ACP server for more info.
Voice input. On supported setups you can speak your prompt instead of typing — handy when your hands are busy or you’re describing something long. First, run /voice in a session to download the local speech runtime and a voice model (transcription runs entirely on your machine — no audio leaves it; English and Spanish are supported). Then dictate one of two ways: hold the space bar while you talk and release when done for short prompts, or press Ctrl+X then V to toggle recording on for longer ones (press any key to stop). The transcribed text lands at your cursor so you can tweak it before submitting.
Discover everything fast. Type ? in a session, or run copilot help in your terminal. For deeper reference, use the subcommands copilot help config, copilot help environment, copilot help logging, and copilot help permissions.
A pragmatic workflow to adopt
If you want a starting point, this is a solid loop:
- Launch
copilotfrom your project root and trust the directory. - For anything beyond a one-liner, drop into plan mode (Shift+Tab) and refine the plan before any code is written.
- Let it work, approving tools individually until you trust the pattern, then approve for the session.
- Use
!for quick checks (!git diff,!npm test) without spending requests. - Run
/review(or ask the code review agent) to sanity-check the diff before you commit. - Have Copilot commit, push, and open a PR — then keep an eye on
/usage.
For unattended automation, script it with -p, scope permissions tightly with --allow-tool / --deny-tool, and run inside a sandbox.
Wrapping up
GitHub Copilot CLI brings a real agentic collaborator to the place developers already work. The core loop — converse, plan, approve, execute — keeps you firmly in control while offloading the mechanical parts of building, debugging, and shipping. Layer on MCP servers, custom agents, custom instructions, and memory, and it starts to feel like a teammate that already knows your codebase and conventions.
The tool is evolving quickly, so keep your client updated, start small with tightly-scoped tasks, and lean on plan mode and sandboxes as you build trust. Once it’s part of your muscle memory, you’ll wonder how you shipped without it.
Leave a comment