npx skills add ...
npx skills add microsoft/skills --skill copilot-sdk
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).
npx skills add microsoft/skills --skill 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.
copilot --version)| Language | Package | Install |
|---|---|---|
| Node.js | @github/copilot-sdk | npm install @github/copilot-sdk |
| Python | github-copilot-sdk | pip install github-copilot-sdk |
| Go | github.com/github/copilot-sdk/go | go get github.com/github/copilot-sdk/go |
| .NET | GitHub.Copilot.SDK | dotnet add package GitHub.Copilot.SDK |
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.
Transport modes:
| Mode | Description | Use Case |
|---|---|---|
| Stdio (default) | CLI as subprocess via pipes | Local dev, single process |
| TCP | CLI as network server | Multi-client, backend services |
All SDK usage follows: create a client, create a session, send messages.
Enable real-time output by setting streaming: true and subscribing to delta events.
| Method | Description |
|---|---|
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.
Define tools that Copilot can call to extend its capabilities.
undefined)Intercept and customize session behavior at key lifecycle points.
| Hook | Trigger | Use Case |
|---|---|---|
onPreToolUse | Before tool executes | Permission control, argument modification |
onPostToolUse | After tool executes | Result transformation, logging, redaction |
onUserPromptSubmitted | User sends message | Prompt modification, filtering, context injection |
onSessionStart | Session begins (new or resumed) | Add context, configure session |
onSessionEnd | Session ends | Cleanup, analytics, metrics |
onErrorOccurred | Error happens | Custom error handling, retry logic, monitoring |
Control tool permissions, modify arguments, or inject context before tool execution.
Input fields: timestamp, cwd, toolName, toolArgs
Output fields:
| Field | Type | Description |
|---|---|---|
permissionDecision | "allow" | "deny" | "ask" | Whether to allow the tool call |
permissionDecisionReason | string | Explanation for deny/ask |
modifiedArgs | object | Modified arguments to pass |
additionalContext | string | Extra context for conversation |
suppressOutput | boolean | Hide tool output from conversation |
Transform results, redact sensitive data, or log tool activity after execution.
Output fields: modifiedResult, additionalContext, suppressOutput
Modify or enhance user prompts before processing. Useful for prompt templates, context injection, and input validation.
Output fields: modifiedPrompt, additionalContext, suppressOutput
Output fields: suppressOutput, errorHandling ("retry" | "skip" | "abort"), retryCount, userNotification
Connect to MCP (Model Context Protocol) servers for pre-built tool capabilities.
Local/Stdio:
| Field | Type | Required | Description |
|---|---|---|---|
type | "local" | No | Defaults to local |
command | string | Yes | Executable path |
args | string[] | Yes | Command arguments |
env | object | No | Environment variables |
cwd | string | No | Working directory |
tools | string[] | No | ["*"] for all, [] for none |
timeout | number | No | Timeout in milliseconds |
Remote HTTP:
| Field | Type | Required | Description |
|---|---|---|---|
type | "http" | Yes | Server type |
url | string | Yes | Server URL |
headers | object | No | HTTP headers |
tools | string[] | No | Tool filter |
timeout | number | No | Timeout in ms |
Test MCP servers independently before integrating:
Use the MCP Inspector for interactive debugging:
Common MCP issues:
tools: ["*"] and verify server responds to tools/listcwdgithubToken in constructorCAPI_HMAC_KEY or COPILOT_HMAC_KEY env varsGITHUB_COPILOT_API_TOKEN with COPILOT_API_URLCOPILOT_GITHUB_TOKEN → GH_TOKEN → GITHUB_TOKENcopilot auth logingh auth credentialsFor multi-user apps where users sign in with GitHub:
Supported token types: gho_ (OAuth), ghu_ (GitHub App), github_pat_ (fine-grained PAT).
Not supported: ghp_ (classic PAT — deprecated).
Prevent the SDK from using stored credentials:
Use your own API keys — no Copilot subscription required. The CLI acts as agent runtime only.
OpenAI:
Azure AI Foundry (OpenAI-compatible):
Azure OpenAI (native endpoint):
Anthropic:
Ollama (local):
| Field | Type | Description |
|---|---|---|
type | "openai" | "azure" | "anthropic" | Provider type |
baseUrl | string | Required. API endpoint URL |
apiKey | string | API key (optional for local providers) |
bearerToken | string | Bearer token auth (takes precedence over apiKey) |
wireApi | "completions" | "responses" | API format (default: "completions") |
azure.apiVersion | string | Azure API version (default: "2024-10-21") |
Use DefaultAzureCredential to get short-lived bearer tokens for Azure deployments:
Note: Bearer tokens expire (~1 hour). For long-running apps, refresh the token before each new session. The SDK does not auto-refresh tokens.
provider config on session resumeResume sessions across restarts by providing your own session ID.
When resuming, you can reconfigure: model, systemMessage, availableTools, excludedTools, provider (required for BYOK), reasoningEffort, streaming, mcpServers, customAgents, skillDirectories, infiniteSessions.
| Pattern | Example | Use Case |
|---|---|---|
user-{userId}-{taskId} | user-alice-pr-review-42 | Multi-user apps |
tenant-{tenantId}-{workflow} | tenant-acme-onboarding | Multi-tenant SaaS |
{userId}-{taskType}-{timestamp} | alice-deploy-1706932800 | Time-based cleanup |
Session state is saved to ~/.copilot/session-state/{sessionId}/:
| Data | Persisted? | Notes |
|---|---|---|
| Conversation history | ✅ Yes | Full message thread |
| Tool call results | ✅ Yes | Cached for context |
| Agent planning state | ✅ Yes | plan.md file |
| Session artifacts | ✅ Yes | In files/ directory |
| Provider/API keys | ❌ No | Must re-provide on resume |
| In-memory tool state | ❌ No | Design tools to be stateless |
For long-running workflows that may exceed context limits, enable auto-compaction:
Thresholds are context utilization ratios (0.0–1.0), not absolute token counts.
Define specialized AI personas:
Control AI behavior and personality:
Load skill directories to extend Copilot's capabilities:
Skills can be combined with custom agents and MCP servers:
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.
Subscribe to usage events instead of using CLI /usage:
SDK auto-spawns CLI as subprocess. Simplest setup — zero configuration.
Run CLI in headless mode, connect SDK over TCP:
Multi-client support: Multiple SDK clients can share one CLI server.
Ship CLI binary with your app:
| Pattern | Isolation | Resources | Best For |
|---|---|---|---|
| CLI per user | Complete | High | Multi-tenant SaaS, compliance |
| Shared CLI + session IDs | Logical | Low | Internal tools |
| Shared sessions | None | Low | Team collaboration (requires locking) |
~/.copilot/session-state/ for containers| Option | Type | Default | Description |
|---|---|---|---|
cliPath | string | Auto-detected | Path to Copilot CLI executable |
cliUrl | string | — | URL of external CLI server |
githubToken | string | — | GitHub token for auth |
useLoggedInUser | boolean | true | Use stored CLI credentials |
logLevel | string | "none" | "none" | "error" | "warning" | "info" | "debug" |
autoRestart | boolean | true | Auto-restart CLI on crash |
useStdio | boolean | true | Use stdio transport |
| Option | Type | Description |
|---|---|---|
model | string | Model to use (e.g., "gpt-4.1", "claude-sonnet-4") |
sessionId | string | Custom ID for resumable sessions |
streaming | boolean | Enable streaming responses |
tools | Tool[] | Custom tools |
mcpServers | object | MCP server configurations |
hooks | object | Session hooks |
provider | object | BYOK provider config |
customAgents | object[] | Custom agent definitions |
systemMessage | object | System message override |
skillDirectories | string[] | Directories to load skills from |
disabledSkills | string[] | Skills to disable |
reasoningEffort | string | Reasoning effort level |
availableTools | string[] | Restrict available tools |
excludedTools | string[] | Exclude specific tools |
infiniteSessions | object | Auto-compaction config |
workingDirectory | string | Working directory |
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.
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.on() + session.getMessages()onPermissionRequest handler instead of --allow-all-pathsinfiniteSessions config instead of /compactEnable debug logging:
Custom log directory:
| Issue | Cause | Solution |
|---|---|---|
CLI not found | CLI not installed or not in PATH | Install CLI or set cliPath |
Not authenticated | No valid credentials | Run copilot auth login or provide githubToken |
Session not found | Using session after destroy() | Check listSessions() for valid IDs |
Connection refused | CLI process crashed | Enable autoRestart: true, check port conflicts |
| MCP tools missing | Server init failure or tools not enabled | Set tools: ["*"], test server independently |
| Language | Client | Session Create | Send | Resume | Stop |
|---|---|---|---|---|---|
| Node.js | new CopilotClient() | client.createSession() | session.sendAndWait() | client.resumeSession() | client.stop() |
| Python | CopilotClient() | client.create_session() | session.send_and_wait() | client.resume_session() | client.stop() |
| Go | copilot.NewClient(nil) | client.CreateSession() | session.SendAndWait() | client.ResumeSession() | client.Stop() |
| .NET | new CopilotClient() | client.CreateSessionAsync() | session.SendAndWaitAsync() | client.ResumeSessionAsync() | client.DisposeAsync() |