Skip to main content

Quickstart for hooks

Get started with hooks in Copilot SDK to control tool execution, transform results, add context, handle errors, and audit interactions.

この機能を使用できるユーザーについて

GitHub Copilot SDK はすべてのCopilotプランで利用可能です。

メモ

Copilot SDK is currently in テクニカル プレビュー. Functionality and availability are subject to change.

Hooks allow you to intercept and customize the behavior of Copilot SDK sessions at key points in the conversation lifecycle. Use hooks to:

  • Control tool execution—approve, deny, or modify tool calls
  • Transform results—modify tool outputs before they're processed
  • Add context—inject additional information at session start
  • Handle errors—implement custom error handling
  • Audit and log—track all interactions for compliance

Available hooks

HookTriggerUse case
onPreToolUseBefore a tool executesPermission control, argument validation
onPostToolUseAfter a tool executesResult transformation, logging
onUserPromptSubmittedWhen user sends a messagePrompt modification, filtering
onSessionStartSession beginsAdd context, configure session
onSessionEndSession endsCleanup, analytics
onErrorOccurredError happensCustom error handling

Quick start

The following example demonstrates how to register hooks when creating a session in Node.js/TypeScript.

import { CopilotClient } from "@github/copilot-sdk";

const client = new CopilotClient();

const session = await client.createSession({
  hooks: {
    onPreToolUse: async (input) => {
      console.log(`Tool called: ${input.toolName}`);
      // Allow all tools
      return { permissionDecision: "allow" };
    },
    onPostToolUse: async (input) => {
      console.log(
        `Tool result: ${JSON.stringify(input.toolResult)}`
      );
      return null; // No modifications
    },
    onSessionStart: async (input) => {
      return {
        additionalContext:
          "User prefers concise answers.",
      };
    },
  },
});

For examples in Python, Go, and .NET, see the github/copilot-sdk repository.

Hook invocation context

Every hook receives an invocation parameter with context about the current session.

FieldTypeDescription
sessionIdstringThe ID of the current session

This allows hooks to maintain state or perform session-specific logic.

Common patterns

Logging all tool calls

const session = await client.createSession({
  hooks: {
    onPreToolUse: async (input) => {
      console.log(
        `[${new Date().toISOString()}] Tool: `
        + `${input.toolName}, `
        + `Args: ${JSON.stringify(input.toolArgs)}`
      );
      return { permissionDecision: "allow" };
    },
    onPostToolUse: async (input) => {
      console.log(
        `[${new Date().toISOString()}] `
        + `Result: ${JSON.stringify(input.toolResult)}`
      );
      return null;
    },
  },
});

Blocking dangerous tools

const BLOCKED_TOOLS = ["shell", "bash", "exec"];

const session = await client.createSession({
  hooks: {
    onPreToolUse: async (input) => {
      if (BLOCKED_TOOLS.includes(input.toolName)) {
        return {
          permissionDecision: "deny",
          permissionDecisionReason:
            "Shell access is not permitted",
        };
      }
      return { permissionDecision: "allow" };
    },
  },
});

Adding user context

const session = await client.createSession({
  hooks: {
    onSessionStart: async () => {
      const userPrefs = await loadUserPreferences();
      return {
        additionalContext:
          `User preferences: `
          + `${JSON.stringify(userPrefs)}`,
      };
    },
  },
});

Next steps