Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

GitHub Copilot Hooks Reference

Disclaimer: This document reflects our current understanding of GitHub Copilot’s hook system. It is a working reference for symposium development, not a substitute for the official docs. Details may be outdated or incomplete — always consult the primary sources.

Primary sources: About hooks · Using hooks · Hooks configuration

GitHub Copilot hooks are available for the Cloud Agent (coding agent), Copilot CLI (GA February 2026), and VS Code (8-event preview). The system is command-only and repository-native.

Hook Types

Only type: "command" is supported.

Events

Cloud Agent and CLI (6 events, lowerCamelCase)

EventTriggerCan block?
sessionStartNew or resumed sessionNo
sessionEndSession completes or terminatesNo
userPromptSubmittedUser submits a promptNo
preToolUseBefore tool callYes
postToolUseAfter tool completes (success or failure)No
errorOccurredError during agent executionNo

VS Code (8 events, PascalCase, preview)

SessionStart, UserPromptSubmit, PreToolUse, PostToolUse, PreCompact, SubagentStart, SubagentStop, Stop.

Only preToolUse/PreToolUse can make access-control decisions. All other events are observational.

Configuration

Cloud Agent and CLI

Hooks defined in .github/hooks/*.json. For the Cloud Agent, files must be on the repository’s default branch.

{
  "version": 1,
  "hooks": {
    "preToolUse": [
      {
        "type": "command",
        "bash": "./scripts/security-check.sh",
        "powershell": "./scripts/security-check.ps1",
        "cwd": "scripts",
        "env": { "LOG_LEVEL": "INFO" },
        "timeoutSec": 15,
        "comment": "Documentation string, ignored at runtime"
      }
    ]
  }
}
FieldTypeDescription
typestringMust be "command"
bashstringCommand for Linux/macOS
powershellstringCommand for Windows
cwdstringWorking directory relative to repo root
envobjectEnvironment variables
timeoutSecnumberDefault 30 seconds
commentstringDocumentation, ignored at runtime

There is no matcher field — hooks fire on all invocations of their event type. Tool-level filtering must be done inside the script by inspecting toolName from stdin.

VS Code

Also reads hooks from .claude/settings.json, .claude/settings.local.json, and ~/.claude/settings.json (Claude Code format compatibility). Converts lowerCamelCase to PascalCase and maps bashosx/linux, powershellwindows.

Input Schema (stdin)

preToolUse

{
  "timestamp": 1704614600000,
  "cwd": "/path/to/project",
  "toolName": "bash",
  "toolArgs": "{\"command\":\"rm -rf dist\",\"description\":\"Clean build\"}"
}

Note: toolArgs is a JSON string, not an object. Scripts must parse it (e.g., with jq).

sessionStart

  • source: "new" | "resume"
  • initialPrompt: string

sessionEnd

  • reason: string

Output Schema (stdout)

preToolUse output (Cloud Agent / CLI)

{
  "permissionDecision": "deny",
  "permissionDecisionReason": "Destructive operations blocked"
}
ValueMeaning
"allow"Permit the tool call
"deny"Block the tool call
"ask"Prompt user for confirmation

Exit code 0 = allow (if no JSON output), non-zero = deny.

VS Code output (preview, extended fields)

FieldTypeDescription
continuebooleanfalse stops agent
stopReasonstringMessage when continue is false
systemMessagestringWarning shown to user
hookSpecificOutput.permissionDecisionstringallow, deny, ask
hookSpecificOutput.updatedInputobjectReplace tool arguments
hookSpecificOutput.additionalContextstringExtra context for agent

Execution Behavior

  • Hooks run synchronously and sequentially (array order).
  • If the first hook returns deny, subsequent hooks are skipped.
  • Recommended execution time: under 5 seconds.
  • Default timeout: 30 seconds. On timeout, hook is terminated and agent continues.
  • Scripts read JSON from stdin (INPUT=$(cat)) and write to stdout; debug output goes to stderr.

Environment Variables

No built-in variables beyond those specified in the hook’s env field. The cwd field controls the working directory.

Custom instructions (soft/probabilistic)

FileScope
.github/copilot-instructions.mdRepository-wide instructions
.github/instructions/**/*.instructions.mdPath-specific instructions (with applyTo globs)
AGENTS.mdAgent-mode instructions
~/.copilot/copilot-instructions.mdUser-level (personal)
Organization-level instructionsAdmin-configured

Priority: Personal (user) > Repository (workspace) > Organization.

MCP server configuration

ScopeConfig pathRoot key
VS Code (workspace).vscode/mcp.jsonservers
VS Code (user)Via “MCP: Open User Configuration” commandservers
CLI~/.copilot/mcp-config.jsonmcpServers

Note: VS Code uses "servers" as root key while the CLI uses "mcpServers". MCP tools only work in Copilot’s Agent mode. Supported transports: local/stdio, http/sse.

MCP Server Registration

Symposium registers MCP servers in the Copilot config as top-level keys (matching the CLI’s mcpServers format, not VS Code’s servers format):

{
  "symposium": {
    "command": "/path/to/cargo-agents",
    "args": ["mcp"]
  }
}
  • Project-level: .vscode/mcp.json
  • User-level: ~/.copilot/mcp-config.json

Registration is idempotent — if the entry already exists with the correct values, no changes are made. If the entry exists but has stale values (e.g. the binary moved), it is updated in place.

Copilot SDK (programmatic hooks)

The @github/copilot-sdk (Node.js, Python, Go, .NET, Java) provides callback-style hooks for applications embedding the Copilot runtime:

  • onPreToolUse — can return modifiedArgs
  • onPostToolUse — can return modifiedResult
  • onSessionStart, onSessionEnd, etc.

Agent firewall (Cloud Agent)

Network-layer control with deny-by-default domain allowlist, configured at org/repo level. Not a hook — controls outbound network access.