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, and custom agents. Requires GitHub Copilot CLI installed and a GitHub Copilot subscription (unless using BYOK).
Add this skill
npx mdskills install sickn33/copilot-sdkComprehensive SDK documentation with clear multi-language examples and advanced feature coverage
1---2name: copilot-sdk3description: 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, and custom agents. Requires GitHub Copilot CLI installed and a GitHub Copilot subscription (unless using BYOK).4---56# GitHub Copilot SDK78Build 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.910## Prerequisites1112- **GitHub Copilot CLI** installed and authenticated (`copilot --version` to verify)13- **GitHub Copilot subscription** (Individual, Business, or Enterprise) — not required for BYOK14- **Runtime:** Node.js 18+ / Python 3.8+ / Go 1.21+ / .NET 8.0+1516## Installation1718| Language | Package | Install |19|----------|---------|---------|20| Node.js | `@github/copilot-sdk` | `npm install @github/copilot-sdk` |21| Python | `github-copilot-sdk` | `pip install github-copilot-sdk` |22| Go | `github.com/github/copilot-sdk/go` | `go get github.com/github/copilot-sdk/go` |23| .NET | `GitHub.Copilot.SDK` | `dotnet add package GitHub.Copilot.SDK` |2425---2627## Core Pattern: Client → Session → Message2829All SDK usage follows this pattern: create a client, create a session, send messages.3031### Node.js / TypeScript3233```typescript34import { CopilotClient } from "@github/copilot-sdk";3536const client = new CopilotClient();37const session = await client.createSession({ model: "gpt-4.1" });3839const response = await session.sendAndWait({ prompt: "What is 2 + 2?" });40console.log(response?.data.content);4142await client.stop();43```4445### Python4647```python48import asyncio49from copilot import CopilotClient5051async def main():52 client = CopilotClient()53 await client.start()54 session = await client.create_session({"model": "gpt-4.1"})55 response = await session.send_and_wait({"prompt": "What is 2 + 2?"})56 print(response.data.content)57 await client.stop()5859asyncio.run(main())60```6162### Go6364```go65client := copilot.NewClient(nil)66if err := client.Start(ctx); err != nil { log.Fatal(err) }67defer client.Stop()6869session, _ := client.CreateSession(ctx, &copilot.SessionConfig{Model: "gpt-4.1"})70response, _ := session.SendAndWait(ctx, copilot.MessageOptions{Prompt: "What is 2 + 2?"})71fmt.Println(*response.Data.Content)72```7374### .NET7576```csharp77await using var client = new CopilotClient();78await using var session = await client.CreateSessionAsync(new SessionConfig { Model = "gpt-4.1" });79var response = await session.SendAndWaitAsync(new MessageOptions { Prompt = "What is 2 + 2?" });80Console.WriteLine(response?.Data.Content);81```8283---8485## Streaming Responses8687Enable real-time output by setting `streaming: true` and subscribing to delta events.8889```typescript90const session = await client.createSession({ model: "gpt-4.1", streaming: true });9192session.on("assistant.message_delta", (event) => {93 process.stdout.write(event.data.deltaContent);94});95session.on("session.idle", () => console.log());9697await session.sendAndWait({ prompt: "Tell me a joke" });98```99100**Python equivalent:**101102```python103from copilot.generated.session_events import SessionEventType104105session = await client.create_session({"model": "gpt-4.1", "streaming": True})106107def handle_event(event):108 if event.type == SessionEventType.ASSISTANT_MESSAGE_DELTA:109 sys.stdout.write(event.data.delta_content)110 sys.stdout.flush()111112session.on(handle_event)113await session.send_and_wait({"prompt": "Tell me a joke"})114```115116### Event Subscription117118| Method | Description |119|--------|-------------|120| `on(handler)` | Subscribe to all events; returns unsubscribe function |121| `on(eventType, handler)` | Subscribe to specific event type (Node.js only) |122123---124125## Custom Tools126127Define tools that Copilot can call to extend its capabilities.128129### Node.js130131```typescript132import { CopilotClient, defineTool } from "@github/copilot-sdk";133134const getWeather = defineTool("get_weather", {135 description: "Get the current weather for a city",136 parameters: {137 type: "object",138 properties: { city: { type: "string", description: "The city name" } },139 required: ["city"],140 },141 handler: async ({ city }) => ({ city, temperature: "72°F", condition: "sunny" }),142});143144const session = await client.createSession({145 model: "gpt-4.1",146 tools: [getWeather],147});148```149150### Python151152```python153from copilot.tools import define_tool154from pydantic import BaseModel, Field155156class GetWeatherParams(BaseModel):157 city: str = Field(description="The city name")158159@define_tool(description="Get the current weather for a city")160async def get_weather(params: GetWeatherParams) -> dict:161 return {"city": params.city, "temperature": "72°F", "condition": "sunny"}162163session = await client.create_session({"model": "gpt-4.1", "tools": [get_weather]})164```165166### Go167168```go169type WeatherParams struct {170 City string `json:"city" jsonschema:"The city name"`171}172173getWeather := copilot.DefineTool("get_weather", "Get weather for a city",174 func(params WeatherParams, inv copilot.ToolInvocation) (WeatherResult, error) {175 return WeatherResult{City: params.City, Temperature: "72°F"}, nil176 },177)178179session, _ := client.CreateSession(ctx, &copilot.SessionConfig{180 Model: "gpt-4.1",181 Tools: []copilot.Tool{getWeather},182})183```184185### .NET186187```csharp188var getWeather = AIFunctionFactory.Create(189 ([Description("The city name")] string city) => new { city, temperature = "72°F" },190 "get_weather", "Get the current weather for a city");191192await using var session = await client.CreateSessionAsync(new SessionConfig {193 Model = "gpt-4.1", Tools = [getWeather],194});195```196197---198199## Hooks200201Intercept and customize session behavior at key lifecycle points.202203| Hook | Trigger | Use Case |204|------|---------|----------|205| `onPreToolUse` | Before tool executes | Permission control, argument modification |206| `onPostToolUse` | After tool executes | Result transformation, logging |207| `onUserPromptSubmitted` | User sends message | Prompt modification, filtering |208| `onSessionStart` | Session begins | Add context, configure session |209| `onSessionEnd` | Session ends | Cleanup, analytics |210| `onErrorOccurred` | Error happens | Custom error handling, retry logic |211212### Example: Tool Permission Control213214```typescript215const session = await client.createSession({216 hooks: {217 onPreToolUse: async (input) => {218 if (["shell", "bash"].includes(input.toolName)) {219 return { permissionDecision: "deny", permissionDecisionReason: "Shell access not permitted" };220 }221 return { permissionDecision: "allow" };222 },223 },224});225```226227### Pre-Tool Use Output228229| Field | Type | Description |230|-------|------|-------------|231| `permissionDecision` | `"allow"` \| `"deny"` \| `"ask"` | Whether to allow the tool call |232| `permissionDecisionReason` | string | Explanation for deny/ask |233| `modifiedArgs` | object | Modified arguments to pass |234| `additionalContext` | string | Extra context for conversation |235| `suppressOutput` | boolean | Hide tool output from conversation |236237---238239## MCP Server Integration240241Connect to MCP servers for pre-built tool capabilities.242243### Remote HTTP Server244245```typescript246const session = await client.createSession({247 mcpServers: {248 github: { type: "http", url: "https://api.githubcopilot.com/mcp/" },249 },250});251```252253### Local Stdio Server254255```typescript256const session = await client.createSession({257 mcpServers: {258 filesystem: {259 type: "local",260 command: "npx",261 args: ["-y", "@modelcontextprotocol/server-filesystem", "/allowed/path"],262 tools: ["*"],263 },264 },265});266```267268### MCP Config Fields269270| Field | Type | Description |271|-------|------|-------------|272| `type` | `"local"` \| `"http"` | Server transport type |273| `command` | string | Executable path (local) |274| `args` | string[] | Command arguments (local) |275| `url` | string | Server URL (http) |276| `tools` | string[] | `["*"]` or specific tool names |277| `env` | object | Environment variables |278| `cwd` | string | Working directory (local) |279| `timeout` | number | Timeout in milliseconds |280281---282283## Authentication284285### Methods (Priority Order)2862871. **Explicit token** — `githubToken` in constructor2882. **Environment variables** — `COPILOT_GITHUB_TOKEN` → `GH_TOKEN` → `GITHUB_TOKEN`2893. **Stored OAuth** — From `copilot auth login`2904. **GitHub CLI** — `gh auth` credentials291292### Programmatic Token293294```typescript295const client = new CopilotClient({ githubToken: process.env.GITHUB_TOKEN });296```297298### BYOK (Bring Your Own Key)299300Use your own API keys — no Copilot subscription required.301302```typescript303const session = await client.createSession({304 model: "gpt-5.2-codex",305 provider: {306 type: "openai",307 baseUrl: "https://your-resource.openai.azure.com/openai/v1/",308 wireApi: "responses",309 apiKey: process.env.FOUNDRY_API_KEY,310 },311});312```313314| Provider | Type | Notes |315|----------|------|-------|316| OpenAI | `"openai"` | OpenAI API and compatible endpoints |317| Azure OpenAI | `"azure"` | Native Azure endpoints (don't include `/openai/v1`) |318| Azure AI Foundry | `"openai"` | OpenAI-compatible Foundry endpoints |319| Anthropic | `"anthropic"` | Claude models |320| Ollama | `"openai"` | Local models, no API key needed |321322**Wire API:** Use `"responses"` for GPT-5 series, `"completions"` (default) for others.323324---325326## Session Persistence327328Resume sessions across restarts by providing your own session ID.329330```typescript331// Create with explicit ID332const session = await client.createSession({333 sessionId: "user-123-task-456",334 model: "gpt-4.1",335});336337// Resume later338const resumed = await client.resumeSession("user-123-task-456");339await resumed.sendAndWait({ prompt: "What did we discuss?" });340```341342**Session management:**343344```typescript345const sessions = await client.listSessions(); // List all346await client.deleteSession("user-123-task-456"); // Delete347await session.destroy(); // Destroy active348```349350**BYOK sessions:** Must re-provide `provider` config on resume (keys are not persisted).351352### Infinite Sessions353354For long-running workflows that may exceed context limits:355356```typescript357const session = await client.createSession({358 infiniteSessions: {359 enabled: true,360 backgroundCompactionThreshold: 0.80,361 bufferExhaustionThreshold: 0.95,362 },363});364```365366---367368## Custom Agents369370Define specialized AI personas:371372```typescript373const session = await client.createSession({374 customAgents: [{375 name: "pr-reviewer",376 displayName: "PR Reviewer",377 description: "Reviews pull requests for best practices",378 prompt: "You are an expert code reviewer. Focus on security, performance, and maintainability.",379 }],380});381```382383---384385## System Message386387Control AI behavior and personality:388389```typescript390const session = await client.createSession({391 systemMessage: { content: "You are a helpful assistant. Always be concise." },392});393```394395---396397## Skills Integration398399Load skill directories to extend Copilot's capabilities:400401```typescript402const session = await client.createSession({403 skillDirectories: ["./skills/code-review", "./skills/documentation"],404 disabledSkills: ["experimental-feature"],405});406```407408---409410## Permission & Input Handlers411412Handle tool permissions and user input requests programmatically:413414```typescript415const session = await client.createSession({416 onPermissionRequest: async (request) => {417 // Auto-approve git commands only418 if (request.kind === "shell") {419 return { approved: request.command.startsWith("git") };420 }421 return { approved: true };422 },423 onUserInputRequest: async (request) => {424 // Handle ask_user tool calls425 return { response: "yes" };426 },427});428```429430---431432## External CLI Server433434Connect to a separately running CLI instead of auto-managing the process:435436```bash437copilot --headless --port 4321438```439440```typescript441const client = new CopilotClient({ cliUrl: "localhost:4321" });442```443444---445446## Client Configuration447448| Option | Type | Description |449|--------|------|-------------|450| `cliPath` | string | Path to Copilot CLI executable |451| `cliUrl` | string | URL of external CLI server |452| `githubToken` | string | GitHub token for auth |453| `useLoggedInUser` | boolean | Use stored CLI credentials (default: true) |454| `logLevel` | string | `"none"` \| `"error"` \| `"warning"` \| `"info"` \| `"debug"` |455| `autoRestart` | boolean | Auto-restart CLI on crash (default: true) |456| `useStdio` | boolean | Use stdio transport (default: true) |457458## Session Configuration459460| Option | Type | Description |461|--------|------|-------------|462| `model` | string | Model to use (e.g., `"gpt-4.1"`) |463| `sessionId` | string | Custom ID for resumable sessions |464| `streaming` | boolean | Enable streaming responses |465| `tools` | Tool[] | Custom tools |466| `mcpServers` | object | MCP server configurations |467| `hooks` | object | Session hooks |468| `provider` | object | BYOK provider config |469| `customAgents` | object[] | Custom agent definitions |470| `systemMessage` | object | System message override |471| `skillDirectories` | string[] | Directories to load skills from |472| `disabledSkills` | string[] | Skills to disable |473| `reasoningEffort` | string | Reasoning effort level |474| `availableTools` | string[] | Restrict available tools |475| `excludedTools` | string[] | Exclude specific tools |476| `infiniteSessions` | object | Auto-compaction config |477| `workingDirectory` | string | Working directory |478479---480481## Debugging482483Enable debug logging to troubleshoot issues:484485```typescript486const client = new CopilotClient({ logLevel: "debug" });487```488489**Common issues:**490- `CLI not found` → Install CLI or set `cliPath`491- `Not authenticated` → Run `copilot auth login` or provide `githubToken`492- `Session not found` → Don't use session after `destroy()`493- `Connection refused` → Check CLI process, enable `autoRestart`494495---496497## Key API Summary498499| Language | Client | Session Create | Send | Stop |500|----------|--------|---------------|------|------|501| Node.js | `new CopilotClient()` | `client.createSession()` | `session.sendAndWait()` | `client.stop()` |502| Python | `CopilotClient()` | `client.create_session()` | `session.send_and_wait()` | `client.stop()` |503| Go | `copilot.NewClient(nil)` | `client.CreateSession()` | `session.SendAndWait()` | `client.Stop()` |504| .NET | `new CopilotClient()` | `client.CreateSessionAsync()` | `session.SendAndWaitAsync()` | `client.DisposeAsync()` |505506## References507508- [GitHub Copilot SDK](https://github.com/github/copilot-sdk)509- [Copilot CLI Installation](https://docs.github.com/en/copilot/how-tos/set-up/install-copilot-cli)510- [MCP Protocol Specification](https://modelcontextprotocol.io)511
Full transparency — inspect the skill content before installing.