Awesome-omni-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 managemen...
git clone https://github.com/diegosouzapw/awesome-omni-skill
T=$(mktemp -d) && git clone --depth=1 https://github.com/diegosouzapw/awesome-omni-skill "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/development/copilot-sdk-yunaamelia" ~/.claude/skills/diegosouzapw-awesome-omni-skill-copilot-sdk-6c43af && rm -rf "$T"
skills/development/copilot-sdk-yunaamelia/SKILL.mdGitHub 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 (
to verify)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
| Language | Package | Install |
|---|---|---|
| Node.js | | |
| Python | | |
| Go | | |
| .NET | | |
Core Pattern: Client → Session → Message
All SDK usage follows this pattern: create a client, create a session, send messages.
Node.js / 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
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
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
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.
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 equivalent:
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() session.on(handle_event) await session.send_and_wait({"prompt": "Tell me a joke"})
Event Subscription
| Method | Description |
|---|---|
| Subscribe to all events; returns unsubscribe function |
| Subscribe to specific event type (Node.js only) |
Custom Tools
Define tools that Copilot can call to extend its capabilities.
Node.js
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
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
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
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], });
Hooks
Intercept and customize session behavior at key lifecycle points.
| Hook | Trigger | Use Case |
|---|---|---|
| Before tool executes | Permission control, argument modification |
| After tool executes | Result transformation, logging |
| User sends message | Prompt modification, filtering |
| Session begins | Add context, configure session |
| Session ends | Cleanup, analytics |
| Error happens | Custom error handling, retry logic |
Example: Tool Permission Control
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" }; }, }, });
Pre-Tool Use Output
| Field | Type | Description |
|---|---|---|
| | | | Whether to allow the tool call |
| string | Explanation for deny/ask |
| object | Modified arguments to pass |
| string | Extra context for conversation |
| boolean | Hide tool output from conversation |
MCP Server Integration
Connect to MCP servers for pre-built tool capabilities.
Remote HTTP Server
const session = await client.createSession({ mcpServers: { github: { type: "http", url: "https://api.githubcopilot.com/mcp/" }, }, });
Local Stdio Server
const session = await client.createSession({ mcpServers: { filesystem: { type: "local", command: "npx", args: ["-y", "@modelcontextprotocol/server-filesystem", "/allowed/path"], tools: ["*"], }, }, });
MCP Config Fields
| Field | Type | Description |
|---|---|---|
| | | Server transport type |
| string | Executable path (local) |
| string[] | Command arguments (local) |
| string | Server URL (http) |
| string[] | or specific tool names |
| object | Environment variables |
| string | Working directory (local) |
| number | Timeout in milliseconds |
Authentication
Methods (Priority Order)
- Explicit token —
in constructorgithubToken - Environment variables —
→COPILOT_GITHUB_TOKEN
→GH_TOKENGITHUB_TOKEN - Stored OAuth — From
copilot auth login - GitHub CLI —
credentialsgh auth
Programmatic Token
const client = new CopilotClient({ githubToken: process.env.GITHUB_TOKEN });
BYOK (Bring Your Own Key)
Use your own API keys — no Copilot subscription required.
const session = await client.createSession({ model: "gpt-5.2-codex", provider: { type: "openai", baseUrl: "https://your-resource.openai.azure.com/openai/v1/", wireApi: "responses", apiKey: process.env.FOUNDRY_API_KEY, }, });
| Provider | Type | Notes |
|---|---|---|
| OpenAI | | OpenAI API and compatible endpoints |
| Azure OpenAI | | Native Azure endpoints (don't include ) |
| Azure AI Foundry | | OpenAI-compatible Foundry endpoints |
| Anthropic | | Claude models |
| Ollama | | Local models, no API key needed |
Wire API: Use
"responses" for GPT-5 series, "completions" (default) for others.
Session Persistence
Resume sessions across restarts by providing your own session ID.
// Create with explicit ID const session = await client.createSession({ sessionId: "user-123-task-456", model: "gpt-4.1", }); // Resume later const resumed = await client.resumeSession("user-123-task-456"); await resumed.sendAndWait({ prompt: "What did we discuss?" });
Session management:
const sessions = await client.listSessions(); // List all await client.deleteSession("user-123-task-456"); // Delete await session.destroy(); // Destroy active
BYOK sessions: Must re-provide
provider config on resume (keys are not persisted).
Infinite Sessions
For long-running workflows that may exceed context limits:
const session = await client.createSession({ infiniteSessions: { enabled: true, backgroundCompactionThreshold: 0.80, bufferExhaustionThreshold: 0.95, }, });
Custom Agents
Define specialized AI personas:
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:
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:
const session = await client.createSession({ skillDirectories: ["./skills/code-review", "./skills/documentation"], disabledSkills: ["experimental-feature"], });
Permission & Input Handlers
Handle tool permissions and user input requests programmatically:
const session = await client.createSession({ onPermissionRequest: async (request) => { // Auto-approve git commands only if (request.kind === "shell") { return { approved: request.command.startsWith("git") }; } return { approved: true }; }, onUserInputRequest: async (request) => { // Handle ask_user tool calls return { response: "yes" }; }, });
External CLI Server
Connect to a separately running CLI instead of auto-managing the process:
copilot --headless --port 4321
const client = new CopilotClient({ cliUrl: "localhost:4321" });
Client Configuration
| Option | Type | Description |
|---|---|---|
| string | Path to Copilot CLI executable |
| string | URL of external CLI server |
| string | GitHub token for auth |
| boolean | Use stored CLI credentials (default: true) |
| string | | | | | |
| boolean | Auto-restart CLI on crash (default: true) |
| boolean | Use stdio transport (default: true) |
Session Configuration
| Option | Type | Description |
|---|---|---|
| string | Model to use (e.g., ) |
| string | Custom ID for resumable sessions |
| boolean | Enable streaming responses |
| Tool[] | Custom tools |
| object | MCP server configurations |
| object | Session hooks |
| object | BYOK provider config |
| object[] | Custom agent definitions |
| object | System message override |
| string[] | Directories to load skills from |
| string[] | Skills to disable |
| string | Reasoning effort level |
| string[] | Restrict available tools |
| string[] | Exclude specific tools |
| object | Auto-compaction config |
| string | Working directory |
Debugging
Enable debug logging to troubleshoot issues:
const client = new CopilotClient({ logLevel: "debug" });
Common issues:
→ Install CLI or setCLI not foundcliPath
→ RunNot authenticated
or providecopilot auth logingithubToken
→ Don't use session afterSession not founddestroy()
→ Check CLI process, enableConnection refusedautoRestart
Key API Summary
| Language | Client | Session Create | Send | Stop |
|---|---|---|---|---|
| Node.js | | | | |
| Python | | | | |
| Go | | | | |
| .NET | | | | |