Skip to main content
Skip to content

Session hooks

Hooks allow you to intercept and customize the behavior of Copilot 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
Pre-tool use hookBefore a tool executesPermission control, argument validation
Post-tool use hookAfter a tool executes (success only)Result transformation, logging
Post-tool use hookAfter a tool execution whose result was a failureInject retry guidance, log failures
User prompt submitted hookWhen user sends a messagePrompt modification, filtering
User prompt transformed hookAfter runtime prompt transformationInspect or replace model-facing content
Session lifecycle hooksSession beginsAdd context, configure session
Session lifecycle hooksSession endsCleanup, analytics
Error handling hookError happensCustom error handling
Session lifecycle hooksTop-level agent naturally stopsValidate completion or request another turn

Quick start

Code languages navigation

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." };
    },
  },
});

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)}`,
      };
    },
  },
});

Hook guides

See also