Official agent skill

Copilot SDK

by microsoft in microsoft/skills

Build applications powered by GitHub Copilot using the Copilot SDK.

OfficialMITAuto-check passedAgent Workflows

Install Copilot SDK

skills CLI
$ npx skills add microsoft/skills --skill copilot-sdk -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install microsoft/skills copilot-sdk --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/microsoft/skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.github/skills/copilot-sdk .claude/skills/copilot-sdk && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
copilot-sdk
GitHub stars
3.1k
Token cost
~7.1k tokens
SKILL.md length
1,535 words
Files
1
Skills in repo
150
Repo updated
First seen
Licence
MIT

At a glance

Build applications powered by GitHub Copilot using the Copilot SDK.

  • Works in 6 steps: Explicit token — githubToken in… → HMAC key — CAPI_HMAC_KEY or… → Direct API token —… → …
  • Creating programmatic integrations with Copilot across Node.js/TypeScript
  • SKILL.md covers Prerequisites, Installation, Architecture and Core Pattern: Client → Session…, plus 4 more sections
  • Calls npx, npm and pip; reaches api.githubcopilot.com and api.openai.com; needs COPILOT_GITHUB_TOKEN and GITHUB_TOKEN

What it does

Copilot SDK is an agent skill from microsoft/skills, published by the product's own GitHub organization. Build applications powered by GitHub Copilot using the Copilot SDK. Use when creating programmatic integrations with Copilot across Node.js/TypeScript, Python, Go, or .NET. Covers session management, custom tools, streaming, hooks, MCP servers, BYOK providers, session persistence, custom agents, skills, and deployment patterns. Requires GitHub Copilot CLI installed and a GitHub Copilot subscription (unless using BYOK).

Its SKILL.md is about 7.1k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Agent Workflows, covering Authentication and MCP servers. It works with TypeScript, .NET, Python and Node.js. The repository describes itself as: Skills, MCP servers, Custom Agents, Agents.md for SDKs to ground Coding Agents. The licence is MIT.

When your agent uses it

  • Creating programmatic integrations with Copilot across Node.js/TypeScript
  • Tasks that involve Authentication
  • Tasks that involve MCP servers

Example prompts

  • “/copilot-sdk”

Requirements

  • Python 3
  • Node.js

Workflow steps

6 steps, taken from the first numbered list in SKILL.md.

  1. Explicit token — githubToken in constructor
  2. HMAC key — CAPI_HMAC_KEY or COPILOT_HMAC_KEY env vars
  3. Direct API token — GITHUB_COPILOT_API_TOKEN with COPILOT_API_URL
  4. Environment variables — COPILOT_GITHUB_TOKEN → GH_TOKEN → GITHUB_TOKEN
  5. Stored OAuth — From copilot auth login
  6. GitHub CLI — gh auth credentials

What it can do on your machine

Read from SKILL.md and the folder at commit 354361d. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • npx
    • npm
    • pip
    • go
    • dotnet
    • gh

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Hosts in commands or code, which the agent is likely to contact:

    • api.githubcopilot.com
    • api.openai.com
    • api.anthropic.com
    • cognitiveservices.azure.com

    Also links to:

    • github.com
    • docs.github.com
    • modelcontextprotocol.io

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names these keys or tokens, usually read from environment variables:

    • COPILOT_GITHUB_TOKEN
    • GITHUB_TOKEN
    • CAPI_HMAC_KEY
    • COPILOT_HMAC_KEY
    • GITHUB_COPILOT_API_TOKEN
    • GH_TOKEN
    • OPENAI_API_KEY
    • FOUNDRY_API_KEY
    • AZURE_OPENAI_KEY
    • ANTHROPIC_API_KEY

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Copilot SDK loads about 7.1k tokens when it runs. Until then it costs about 109 tokens; SKILL.md has 1,535 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~109
When it runs · the whole SKILL.md, loaded when a task matches
~7.1k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from microsoft/skills at commit 354361d, republished under its MIT licence (© microsoft). 1,535 words, ~7,118 tokens.

Download SKILL.mdSave it as .claude/skills/copilot-sdk/SKILL.md (or your agent's skills folder).
name
copilot-sdk
description
Build applications powered by GitHub Copilot using the Copilot SDK. Use when creating programmatic integrations with Copilot across Node.js/TypeScript, Python, Go, or .NET. Covers session management, custom tools, streaming, hooks, MCP servers, BYOK providers, session persistence, custom agents, skills, and deployment patterns. Requires GitHub Copilot CLI installed and a GitHub Copilot subscription (unless using BYOK).

GitHub Copilot SDK

Build applications that programmatically interact with GitHub Copilot. The SDK wraps the Copilot CLI via JSON-RPC, providing session management, custom tools, hooks, MCP server integration, and streaming across Node.js, Python, Go, and .NET.

Prerequisites

  • GitHub Copilot CLI installed and authenticated (copilot --version)
  • GitHub Copilot subscription (Individual, Business, or Enterprise) — not required for BYOK
  • Runtime: Node.js 18+ / Python 3.8+ / Go 1.21+ / .NET 8.0+

Installation

LanguagePackageInstall
Node.js@github/copilot-sdknpm install @github/copilot-sdk
Pythongithub-copilot-sdkpip install github-copilot-sdk
Gogithub.com/github/copilot-sdk/gogo get github.com/github/copilot-sdk/go
.NETGitHub.Copilot.SDKdotnet add package GitHub.Copilot.SDK

Architecture

The SDK communicates with the Copilot CLI via JSON-RPC over stdio (default) or TCP. The CLI manages model calls, tool execution, session state, and MCP server lifecycle.

Your App → SDK Client → [stdio/TCP] → Copilot CLI → Model Provider
                                          ↕
                                     MCP Servers

Transport modes:

ModeDescriptionUse Case
Stdio (default)CLI as subprocess via pipesLocal dev, single process
TCPCLI as network serverMulti-client, backend services

Core Pattern: Client → Session → Message

All SDK usage follows: create a client, create a session, send messages.

Node.js / TypeScript
typescript
import { CopilotClient } from "@github/copilot-sdk";

const client = new CopilotClient();
const session = await client.createSession({ model: "gpt-4.1" });

const response = await session.sendAndWait({ prompt: "What is 2 + 2?" });
console.log(response?.data.content);

await client.stop();
Python
python
import asyncio
from copilot import CopilotClient

async def main():
    client = CopilotClient()
    await client.start()
    session = await client.create_session({"model": "gpt-4.1"})
    response = await session.send_and_wait({"prompt": "What is 2 + 2?"})
    print(response.data.content)
    await client.stop()

asyncio.run(main())
Go
go
client := copilot.NewClient(nil)
if err := client.Start(ctx); err != nil { log.Fatal(err) }
defer client.Stop()

session, _ := client.CreateSession(ctx, &copilot.SessionConfig{Model: "gpt-4.1"})
response, _ := session.SendAndWait(ctx, copilot.MessageOptions{Prompt: "What is 2 + 2?"})
fmt.Println(*response.Data.Content)
.NET
csharp
await using var client = new CopilotClient();
await using var session = await client.CreateSessionAsync(new SessionConfig { Model = "gpt-4.1" });
var response = await session.SendAndWaitAsync(new MessageOptions { Prompt = "What is 2 + 2?" });
Console.WriteLine(response?.Data.Content);

Streaming Responses

Enable real-time output by setting streaming: true and subscribing to delta events.

Node.js
typescript
const session = await client.createSession({ model: "gpt-4.1", streaming: true });

session.on("assistant.message_delta", (event) => {
    process.stdout.write(event.data.deltaContent);
});
session.on("session.idle", () => console.log());

await session.sendAndWait({ prompt: "Tell me a joke" });
Python
python
from copilot.generated.session_events import SessionEventType

session = await client.create_session({"model": "gpt-4.1", "streaming": True})

def handle_event(event):
    if event.type == SessionEventType.ASSISTANT_MESSAGE_DELTA:
        sys.stdout.write(event.data.delta_content)
        sys.stdout.flush()
    if event.type == SessionEventType.SESSION_IDLE:
        print()

session.on(handle_event)
await session.send_and_wait({"prompt": "Tell me a joke"})
Event Subscription
MethodDescription
on(handler)Subscribe to all events; returns unsubscribe function
on(eventType, handler)Subscribe to specific event type (Node.js only)

Call the returned function to unsubscribe. In .NET, call .Dispose() on the returned disposable.


Custom Tools

Define tools that Copilot can call to extend its capabilities.

Node.js
typescript
import { CopilotClient, defineTool } from "@github/copilot-sdk";

const getWeather = defineTool("get_weather", {
    description: "Get the current weather for a city",
    parameters: {
        type: "object",
        properties: { city: { type: "string", description: "The city name" } },
        required: ["city"],
    },
    handler: async ({ city }) => ({ city, temperature: "72°F", condition: "sunny" }),
});

const session = await client.createSession({
    model: "gpt-4.1",
    tools: [getWeather],
});
Python
python
from copilot.tools import define_tool
from pydantic import BaseModel, Field

class GetWeatherParams(BaseModel):
    city: str = Field(description="The city name")

@define_tool(description="Get the current weather for a city")
async def get_weather(params: GetWeatherParams) -> dict:
    return {"city": params.city, "temperature": "72°F", "condition": "sunny"}

session = await client.create_session({"model": "gpt-4.1", "tools": [get_weather]})
Go
go
type WeatherParams struct {
    City string `json:"city" jsonschema:"The city name"`
}

getWeather := copilot.DefineTool("get_weather", "Get weather for a city",
    func(params WeatherParams, inv copilot.ToolInvocation) (WeatherResult, error) {
        return WeatherResult{City: params.City, Temperature: "72°F"}, nil
    },
)

session, _ := client.CreateSession(ctx, &copilot.SessionConfig{
    Model: "gpt-4.1",
    Tools: []copilot.Tool{getWeather},
})
.NET
csharp
using Microsoft.Extensions.AI;
using System.ComponentModel;

var getWeather = AIFunctionFactory.Create(
    ([Description("The city name")] string city) => new { city, temperature = "72°F" },
    "get_weather", "Get the current weather for a city");

await using var session = await client.CreateSessionAsync(new SessionConfig {
    Model = "gpt-4.1", Tools = [getWeather],
});
Tool Requirements
  • Handler must return JSON-serializable data (not undefined)
  • Parameters must follow JSON Schema format
  • Tool description should clearly state when the tool should be used

Hooks

Intercept and customize session behavior at key lifecycle points.

HookTriggerUse Case
onPreToolUseBefore tool executesPermission control, argument modification
onPostToolUseAfter tool executesResult transformation, logging, redaction
onUserPromptSubmittedUser sends messagePrompt modification, filtering, context injection
onSessionStartSession begins (new or resumed)Add context, configure session
onSessionEndSession endsCleanup, analytics, metrics
onErrorOccurredError happensCustom error handling, retry logic, monitoring
Pre-Tool Use Hook

Control tool permissions, modify arguments, or inject context before tool execution.

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

Input fields: timestamp, cwd, toolName, toolArgs

Output fields:

FieldTypeDescription
permissionDecision"allow" | "deny" | "ask"Whether to allow the tool call
permissionDecisionReasonstringExplanation for deny/ask
modifiedArgsobjectModified arguments to pass
additionalContextstringExtra context for conversation
suppressOutputbooleanHide tool output from conversation
Post-Tool Use Hook

Transform results, redact sensitive data, or log tool activity after execution.

typescript
hooks: {
    onPostToolUse: async (input) => {
        // Redact sensitive data from results
        if (typeof input.toolResult === "string") {
            let redacted = input.toolResult;
            for (const pattern of SENSITIVE_PATTERNS) {
                redacted = redacted.replace(pattern, "[REDACTED]");
            }
            if (redacted !== input.toolResult) {
                return { modifiedResult: redacted };
            }
        }
        return null; // Pass through unchanged
    },
}

Output fields: modifiedResult, additionalContext, suppressOutput

User Prompt Submitted Hook

Modify or enhance user prompts before processing. Useful for prompt templates, context injection, and input validation.

typescript
hooks: {
    onUserPromptSubmitted: async (input) => {
        return {
            modifiedPrompt: `[User from engineering team] ${input.prompt}`,
            additionalContext: "Follow company coding standards.",
        };
    },
}

Output fields: modifiedPrompt, additionalContext, suppressOutput

Session Lifecycle Hooks
typescript
hooks: {
    onSessionStart: async (input, invocation) => {
        // input.source: "startup" | "resume" | "new"
        console.log(`Session ${invocation.sessionId} started (${input.source})`);
        return { additionalContext: "Project uses TypeScript and React." };
    },
    onSessionEnd: async (input, invocation) => {
        // input.reason: "complete" | "error" | "abort" | "timeout" | "user_exit"
        await recordMetrics({ sessionId: invocation.sessionId, reason: input.reason });
        return null;
    },
}
Error Handling Hook
typescript
hooks: {
    onErrorOccurred: async (input) => {
        // input.errorContext: "model_call" | "tool_execution" | "system" | "user_input"
        // input.recoverable: boolean
        if (input.errorContext === "model_call" && input.error.includes("rate")) {
            return { errorHandling: "retry", retryCount: 3, userNotification: "Rate limited. Retrying..." };
        }
        return null; // Default error handling
    },
}

Output fields: suppressOutput, errorHandling ("retry" | "skip" | "abort"), retryCount, userNotification

Python Hook Example
python
async def on_pre_tool_use(input_data, invocation):
    if input_data["toolName"] in ["shell", "bash"]:
        return {"permissionDecision": "deny", "permissionDecisionReason": "Not permitted"}
    return {"permissionDecision": "allow"}

session = await client.create_session({
    "hooks": {"on_pre_tool_use": on_pre_tool_use}
})
Go Hook Example
go
session, _ := client.CreateSession(ctx, &copilot.SessionConfig{
    Hooks: &copilot.SessionHooks{
        OnPreToolUse: func(input copilot.PreToolUseHookInput, inv copilot.HookInvocation) (*copilot.PreToolUseHookOutput, error) {
            return &copilot.PreToolUseHookOutput{PermissionDecision: "allow"}, nil
        },
    },
})

MCP Server Integration

Connect to MCP (Model Context Protocol) servers for pre-built tool capabilities.

Local Stdio Server
typescript
const session = await client.createSession({
    mcpServers: {
        filesystem: {
            type: "local",
            command: "npx",
            args: ["-y", "@modelcontextprotocol/server-filesystem", "/allowed/path"],
            tools: ["*"],
            env: { DEBUG: "true" },
            cwd: "./servers",
            timeout: 30000,
        },
    },
});
Remote HTTP Server
typescript
const session = await client.createSession({
    mcpServers: {
        github: {
            type: "http",
            url: "https://api.githubcopilot.com/mcp/",
            headers: { Authorization: "Bearer ${TOKEN}" },
            tools: ["*"],
        },
    },
});
MCP Config Fields

Local/Stdio:

FieldTypeRequiredDescription
type"local"NoDefaults to local
commandstringYesExecutable path
argsstring[]YesCommand arguments
envobjectNoEnvironment variables
cwdstringNoWorking directory
toolsstring[]No["*"] for all, [] for none
timeoutnumberNoTimeout in milliseconds

Remote HTTP:

FieldTypeRequiredDescription
type"http"YesServer type
urlstringYesServer URL
headersobjectNoHTTP headers
toolsstring[]NoTool filter
timeoutnumberNoTimeout in ms
MCP Debugging

Test MCP servers independently before integrating:

bash
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}' | /path/to/your/mcp-server

Use the MCP Inspector for interactive debugging:

bash
npx @modelcontextprotocol/inspector /path/to/your/mcp-server

Common MCP issues:

  • Tools not appearing → Set tools: ["*"] and verify server responds to tools/list
  • Server not starting → Use absolute command paths, check cwd
  • Stdout pollution → Debug output must go to stderr, not stdout

Authentication

Methods (Priority Order)
  1. Explicit token — githubToken in constructor
  2. HMAC key — CAPI_HMAC_KEY or COPILOT_HMAC_KEY env vars
  3. Direct API token — GITHUB_COPILOT_API_TOKEN with COPILOT_API_URL
  4. Environment variables — COPILOT_GITHUB_TOKEN → GH_TOKEN → GITHUB_TOKEN
  5. Stored OAuth — From copilot auth login
  6. GitHub CLI — gh auth credentials
Programmatic Token
typescript
const client = new CopilotClient({ githubToken: process.env.GITHUB_TOKEN });
OAuth GitHub App

For multi-user apps where users sign in with GitHub:

typescript
const client = new CopilotClient({
    githubToken: userAccessToken,    // gho_ or ghu_ token from OAuth flow
    useLoggedInUser: false,          // Don't use stored CLI credentials
});

Supported token types: gho_ (OAuth), ghu_ (GitHub App), github_pat_ (fine-grained PAT). Not supported: ghp_ (classic PAT — deprecated).

Disable Auto-Login

Prevent the SDK from using stored credentials:

typescript
const client = new CopilotClient({ useLoggedInUser: false });

BYOK (Bring Your Own Key)

Use your own API keys — no Copilot subscription required. The CLI acts as agent runtime only.

Provider Configurations

OpenAI:

typescript
provider: { type: "openai", baseUrl: "https://api.openai.com/v1", apiKey: process.env.OPENAI_API_KEY }

Azure AI Foundry (OpenAI-compatible):

typescript
provider: {
    type: "openai",
    baseUrl: "https://your-resource.openai.azure.com/openai/v1/",
    apiKey: process.env.FOUNDRY_API_KEY,
    wireApi: "responses",  // Use "responses" for GPT-5 series, "completions" for others
}

Azure OpenAI (native endpoint):

typescript
provider: {
    type: "azure",
    baseUrl: "https://my-resource.openai.azure.com",  // Just the host — no /openai/v1
    apiKey: process.env.AZURE_OPENAI_KEY,
    azure: { apiVersion: "2024-10-21" },
}

Anthropic:

typescript
provider: { type: "anthropic", baseUrl: "https://api.anthropic.com", apiKey: process.env.ANTHROPIC_API_KEY }

Ollama (local):

typescript
provider: { type: "openai", baseUrl: "http://localhost:11434/v1" }
Provider Config Reference
FieldTypeDescription
type"openai" | "azure" | "anthropic"Provider type
baseUrlstringRequired. API endpoint URL
apiKeystringAPI key (optional for local providers)
bearerTokenstringBearer token auth (takes precedence over apiKey)
wireApi"completions" | "responses"API format (default: "completions")
azure.apiVersionstringAzure API version (default: "2024-10-21")
Azure Managed Identity with BYOK

Use DefaultAzureCredential to get short-lived bearer tokens for Azure deployments:

python
from azure.identity import DefaultAzureCredential
from copilot import CopilotClient, ProviderConfig, SessionConfig

credential = DefaultAzureCredential()
token = credential.get_token("https://cognitiveservices.azure.com/.default").token

session = await client.create_session(SessionConfig(
    model="gpt-4.1",
    provider=ProviderConfig(
        type="openai",
        base_url=f"{foundry_url}/openai/v1/",
        bearer_token=token,
        wire_api="responses",
    ),
))

Note: Bearer tokens expire (~1 hour). For long-running apps, refresh the token before each new session. The SDK does not auto-refresh tokens.

BYOK Limitations
  • Static credentials only — no native Entra ID, OIDC, or managed identity support
  • No auto-refresh — expired tokens require creating a new session
  • Keys not persisted — must re-provide provider config on session resume
  • Model availability — limited to what your provider offers

Session Persistence

Resume sessions across restarts by providing your own session ID.

typescript
// Create with explicit ID
const session = await client.createSession({
    sessionId: "user-123-task-456",
    model: "gpt-4.1",
});

// Resume later (even from a different client instance)
const resumed = await client.resumeSession("user-123-task-456");
await resumed.sendAndWait({ prompt: "What did we discuss?" });
Session Management
typescript
const sessions = await client.listSessions();           // List all
const lastId = await client.getLastSessionId();          // Get most recent
await client.deleteSession("user-123-task-456");         // Delete from storage
await session.destroy();                                 // Destroy active session
Resume Options

When resuming, you can reconfigure: model, systemMessage, availableTools, excludedTools, provider (required for BYOK), reasoningEffort, streaming, mcpServers, customAgents, skillDirectories, infiniteSessions.

Session ID Best Practices
PatternExampleUse Case
user-{userId}-{taskId}user-alice-pr-review-42Multi-user apps
tenant-{tenantId}-{workflow}tenant-acme-onboardingMulti-tenant SaaS
{userId}-{taskType}-{timestamp}alice-deploy-1706932800Time-based cleanup
What Gets Persisted

Session state is saved to ~/.copilot/session-state/{sessionId}/:

DataPersisted?Notes
Conversation history✅ YesFull message thread
Tool call results✅ YesCached for context
Agent planning state✅ Yesplan.md file
Session artifacts✅ YesIn files/ directory
Provider/API keys❌ NoMust re-provide on resume
In-memory tool state❌ NoDesign tools to be stateless
Show full SKILL.md (588 more words)Show less
Infinite Sessions

For long-running workflows that may exceed context limits, enable auto-compaction:

typescript
const session = await client.createSession({
    infiniteSessions: {
        enabled: true,
        backgroundCompactionThreshold: 0.80,  // Start background compaction at 80%
        bufferExhaustionThreshold: 0.95,       // Block and compact at 95%
    },
});

Thresholds are context utilization ratios (0.0–1.0), not absolute token counts.


Custom Agents

Define specialized AI personas:

typescript
const session = await client.createSession({
    customAgents: [{
        name: "pr-reviewer",
        displayName: "PR Reviewer",
        description: "Reviews pull requests for best practices",
        prompt: "You are an expert code reviewer. Focus on security, performance, and maintainability.",
    }],
});

System Message

Control AI behavior and personality:

typescript
const session = await client.createSession({
    systemMessage: { content: "You are a helpful assistant. Always be concise." },
});

Skills Integration

Load skill directories to extend Copilot's capabilities:

typescript
const session = await client.createSession({
    skillDirectories: ["./skills/code-review", "./skills/documentation"],
    disabledSkills: ["experimental-feature"],
});

Skills can be combined with custom agents and MCP servers:

typescript
const session = await client.createSession({
    skillDirectories: ["./skills/security"],
    customAgents: [{ name: "auditor", prompt: "Focus on OWASP Top 10." }],
    mcpServers: { postgres: { type: "local", command: "npx", args: ["-y", "@modelcontextprotocol/server-postgres"], tools: ["*"] } },
});

Permission & Input Handlers

Handle tool permissions and user input requests programmatically. The SDK uses a deny-by-default permission model — all permission requests are denied unless you provide a handler.

typescript
const session = await client.createSession({
    onPermissionRequest: async (request) => {
        if (request.kind === "shell") {
            return { approved: request.command.startsWith("git") };
        }
        return { approved: true };
    },
    onUserInputRequest: async (request) => {
        return { response: "yes" };
    },
});
Token Usage Tracking

Subscribe to usage events instead of using CLI /usage:

typescript
session.on("assistant.usage", (event) => {
    console.log("Tokens:", { input: event.data.inputTokens, output: event.data.outputTokens });
});

Deployment Patterns

Local CLI (Default)

SDK auto-spawns CLI as subprocess. Simplest setup — zero configuration.

typescript
const client = new CopilotClient(); // Auto-manages CLI process
External CLI Server (Backend Services)

Run CLI in headless mode, connect SDK over TCP:

bash
copilot --headless --port 4321
typescript
const client = new CopilotClient({ cliUrl: "localhost:4321" });

Multi-client support: Multiple SDK clients can share one CLI server.

Bundled CLI (Desktop Apps)

Ship CLI binary with your app:

typescript
const client = new CopilotClient({ cliPath: path.join(__dirname, "vendor", "copilot") });
Docker Compose
yaml
services:
  copilot-cli:
    image: ghcr.io/github/copilot-cli:latest
    command: ["--headless", "--port", "4321"]
    environment:
      - COPILOT_GITHUB_TOKEN=${COPILOT_GITHUB_TOKEN}
    volumes:
      - session-data:/root/.copilot/session-state
  api:
    build: .
    environment:
      - CLI_URL=copilot-cli:4321
    depends_on: [copilot-cli]
volumes:
  session-data:
Session Isolation Patterns
PatternIsolationResourcesBest For
CLI per userCompleteHighMulti-tenant SaaS, compliance
Shared CLI + session IDsLogicalLowInternal tools
Shared sessionsNoneLowTeam collaboration (requires locking)
Production Checklist
  • Session cleanup: periodic deletion of expired sessions
  • Health checks: ping CLI server, restart if unresponsive
  • Persistent storage: mount ~/.copilot/session-state/ for containers
  • Secret management: use Vault/K8s Secrets for tokens
  • Session locking: Redis or similar for shared session access
  • Graceful shutdown: drain active sessions before stopping CLI

Client Configuration

OptionTypeDefaultDescription
cliPathstringAuto-detectedPath to Copilot CLI executable
cliUrlstring—URL of external CLI server
githubTokenstring—GitHub token for auth
useLoggedInUserbooleantrueUse stored CLI credentials
logLevelstring"none""none" | "error" | "warning" | "info" | "debug"
autoRestartbooleantrueAuto-restart CLI on crash
useStdiobooleantrueUse stdio transport

Session Configuration

OptionTypeDescription
modelstringModel to use (e.g., "gpt-4.1", "claude-sonnet-4")
sessionIdstringCustom ID for resumable sessions
streamingbooleanEnable streaming responses
toolsTool[]Custom tools
mcpServersobjectMCP server configurations
hooksobjectSession hooks
providerobjectBYOK provider config
customAgentsobject[]Custom agent definitions
systemMessageobjectSystem message override
skillDirectoriesstring[]Directories to load skills from
disabledSkillsstring[]Skills to disable
reasoningEffortstringReasoning effort level
availableToolsstring[]Restrict available tools
excludedToolsstring[]Exclude specific tools
infiniteSessionsobjectAuto-compaction config
workingDirectorystringWorking directory

SDK vs CLI Feature Comparison

✅ Available in SDK

Session management, messaging (send/sendAndWait/abort), message history (getMessages), custom tools, tool permission hooks, MCP servers (local + HTTP), streaming, model selection, BYOK providers, custom agents, system message, skills, infinite sessions, permission handlers, 40+ event types.

❌ CLI-Only Features

Session export (--share), slash commands, interactive UI, terminal rendering, YOLO mode, login/logout flows, /compact (use infiniteSessions instead), /usage (use usage events), /review, /delegate.

Workarounds:

  • Session export → Collect events manually with session.on() + session.getMessages()
  • Permission control → Use onPermissionRequest handler instead of --allow-all-paths
  • Context compaction → Use infiniteSessions config instead of /compact

Debugging

Enable debug logging:

typescript
const client = new CopilotClient({ logLevel: "debug" });

Custom log directory:

typescript
const client = new CopilotClient({ cliArgs: ["--log-dir", "/path/to/logs"] });
Common Issues
IssueCauseSolution
CLI not foundCLI not installed or not in PATHInstall CLI or set cliPath
Not authenticatedNo valid credentialsRun copilot auth login or provide githubToken
Session not foundUsing session after destroy()Check listSessions() for valid IDs
Connection refusedCLI process crashedEnable autoRestart: true, check port conflicts
MCP tools missingServer init failure or tools not enabledSet tools: ["*"], test server independently
Connection State
typescript
console.log("State:", client.getState());  // "connected" after start()
client.on("stateChange", (state) => console.log("Changed to:", state));

Key API Summary

LanguageClientSession CreateSendResumeStop
Node.jsnew CopilotClient()client.createSession()session.sendAndWait()client.resumeSession()client.stop()
PythonCopilotClient()client.create_session()session.send_and_wait()client.resume_session()client.stop()
Gocopilot.NewClient(nil)client.CreateSession()session.SendAndWait()client.ResumeSession()client.Stop()
.NETnew CopilotClient()client.CreateSessionAsync()session.SendAndWaitAsync()client.ResumeSessionAsync()client.DisposeAsync()

References

© microsoft, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .github/skills/copilot-sdk of microsoft/skills.

Open the folder on GitHubat commit 354361d

Compare with similar skills

Copilot SDK next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Copilot SDK compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Copilot SDK this skillmicrosoft/skills3.1k—~7.1kAutomated safety check: PassMIT
Copilot SDKintellectronica/agent-skills295—~3.2kAutomated safety check: PassCC0-1.0
Copilot SDKaiskillstore/marketplace4305 repos~3.8kAutomated safety check: PassNone
Copilot SDKgithub/awesome-copilot40k5 repos~6.3kAutomated safety check: PassMIT
MCP Server Builderanthropics/skills180k62 repos~2.3kAutomated safety check: PassApache-2.0
MCP Server BuildershareAI-lab/learn-claude-code78k5 repos~1.2kAutomated safety check: PassMIT

Similar skills

  • Copilot SDK

    intellectronica/agent-skills

    This skill helps with GitHub Copilot SDK work across Node.js/TypeScript, Python, Go, .NET, and Java.

    295 GitHub stars~3.2k tokensUpdated 5 mo ago
    Agent WorkflowsAuto-check passed
  • Copilot SDK

    aiskillstore/marketplace

    Build applications that programmatically interact with GitHub Copilot.

    430 GitHub starsUsed in 5 repos~3.8k tokens
    Agent WorkflowsAuto-check passed
  • Copilot SDK

    github/awesome-copilot

    Official

    Build agentic applications with GitHub Copilot SDK. An agent skill from github/awesome-copilot.

    40k GitHub starsUsed in 5 repos~6.3k tokens
    AI & LLM EngineeringAuto-check passed
  • MCP Server Builder

    anthropics/skills

    Official

    Guides the design and implementation of Model Context Protocol servers in TypeScript or Python, from tool naming and error messages to evaluation.

    180k GitHub starsUsed in 62 repos~2.3k tokens
    Agent WorkflowsAuto-check passed
  • MCP Server Builder

    shareAI-lab/learn-claude-code

    Walks through building MCP servers in Python or TypeScript that expose tools, resources and prompts to Claude, with templates, registration and testing.

    78k GitHub starsUsed in 5 repos~1.2k tokens
    Agent WorkflowsAuto-check passed
  • Builds, modifies, debugs, migrates and verifies TypeScript MCP servers and MCP Apps with the mcp-use framework, treating the installed package's types as the source of truth.

    11k GitHub stars~923 tokensUpdated yesterday
    Agent WorkflowsAuto-check passed

More from microsoft/skills

All 150 skills in this repo
  • Official

    Reference for building on Microsoft Foundry with the azure-ai-projects Python SDK: project clients, versioned agents, evaluations, connections, datasets and indexes.

    3.1k GitHub starsUsed in 6 repos~2.8k tokens
    Auto-check passed
  • Official

    Python guidance for the Azure AI Search SDK covering vector, hybrid and semantic search, index management and indexers, with Entra ID authentication preferred over keys.

    3.1k GitHub starsUsed in 6 repos~4.4k tokens
    Auto-check passed
  • Official

    Covers producer, consumer, and checkpoint-store setup for Azure Event Hubs streaming in Python, with Entra ID auth and partition targeting.

    3.1k GitHub starsUsed in 1 repo~2.3k tokens
    Auto-check passed
  • Pydantic Models Py

    microsoft/skills

    Official

    Create Pydantic models following the multi-model pattern with Base, Create, Update, Response, and InDB variants.

    3.1k GitHub starsUsed in 6 repos~496 tokens
    Auto-check passed
  • Official

    Builds podcast-style audio narration from text with Azure OpenAI's GPT Realtime Mini over WebSocket, from a Python FastAPI backend to a React player.

    3.1k GitHub starsUsed in 1 repo~947 tokens
    Auto-check passed
  • Frontend UI Dark TS

    microsoft/skills

    Official

    Build dark-themed React applications using Tailwind CSS with custom theming, glassmorphism effects, and Framer Motion animations.

    3.1k GitHub starsUsed in 5 repos~3.6k tokens
    Auto-check passed

Questions about Copilot SDK

What does Copilot SDK do?

Build applications powered by GitHub Copilot using the Copilot SDK. Copilot SDK is an agent skill from microsoft/skills, published by the product's own GitHub organization. Build applications powered by GitHub Copilot using the Copilot SDK.

When should I use Copilot SDK?

Copilot SDK fits situations like: creating programmatic integrations with Copilot across Node.js/TypeScript; tasks that involve Authentication; tasks that involve MCP servers.

How do I install Copilot SDK in Claude Code?

Run `npx skills add microsoft/skills --skill copilot-sdk -a claude-code`. Or copy the skill folder (.github/skills/copilot-sdk in microsoft/skills) into .claude/skills/copilot-sdk in your project. Claude Code loads it when a task matches its description.

How do I install Copilot SDK in Codex?

Run `npx skills add microsoft/skills --skill copilot-sdk -a codex`. Or copy the skill folder (.github/skills/copilot-sdk in microsoft/skills) into .agents/skills/copilot-sdk in your project. Codex loads it when a task matches its description.

Can I use Copilot SDK in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add microsoft/skills --skill copilot-sdk -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/copilot-sdk, .gemini/skills/copilot-sdk, .github/skills/copilot-sdk and .opencode/skills/copilot-sdk in your project.

What does Copilot SDK need to run?

Going by SKILL.md and its folder, Copilot SDK needs the command-line tools its instructions call (npx, npm, pip, go, dotnet and gh) and credentials named COPILOT_GITHUB_TOKEN, GITHUB_TOKEN, CAPI_HMAC_KEY and COPILOT_HMAC_KEY. Our summary lists: Python 3; Node.js.

Does Copilot SDK access the network?

SKILL.md names 7 domains. In commands or code: api.githubcopilot.com, api.openai.com, api.anthropic.com and cognitiveservices.azure.com; the agent is likely to contact these when it follows the instructions. As links in the text: github.com, docs.github.com and modelcontextprotocol.io. This is read from the text; nothing was executed.

Is Copilot SDK safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Copilot SDK use?

Copilot SDK is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Copilot SDK use?

About 7.1k tokens (SKILL.md is roughly 28k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Copilot SDK?

Skills that share tags, products or a category with Copilot SDK: Copilot SDK (intellectronica/agent-skills, 295 stars), Copilot SDK (aiskillstore/marketplace, 430 stars), Copilot SDK (github/awesome-copilot, 40k stars) and MCP Server Builder (anthropics/skills, 180k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Copilot SDK?

microsoft (a GitHub organization, an official publisher) maintains it in microsoft/skills, which has 3,086 GitHub stars. The repository holds 150 skills in this directory. The repository was last updated on October 6, 2026.

Source: microsoft/skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.