| name | copilot-sdk |
| description | Use when building or modifying review/src/agents/ using @github/copilot-sdk, or migrating from @opencode-ai/sdk, or asking how to run parallel agent sessions, get structured JSON output, configure custom OpenAI providers, use hooks, MCP servers, custom agents/skills, session persistence, observability, or troubleshoot SDK issues. |
@github/copilot-sdk — Documentation Index
Public preview. npm install @github/copilot-sdk. Requires Node.js ≥ 18 and GitHub Copilot CLI in PATH (or COPILOT_CLI_PATH env var).
Official docs root: https://docs.github.com/en/enterprise-cloud@latest/copilot/how-tos/copilot-sdk
Getting Started
Getting started with Copilot SDK
Install the SDK, send your first message, and add streaming. Covers CopilotClient, createSession({ model }), sendAndWait({ prompt }), and streaming via assistant.message_delta / session.idle events. Auth via Copilot CLI.
Set Up (Deployment & Configuration)
Set up Copilot SDK — index
Index of all setup guides. Start here to pick the right path.
-
Choosing a setup path — Find the right setup guide that matches how you plan to use Copilot SDK (local dev, backend service, bundled CLI, OAuth, Azure).
-
Local CLI — Use the CLI already signed in on your machine—the simplest configuration, with no auth code or infrastructure required.
-
GitHub OAuth — Let users authenticate with their GitHub accounts to use GitHub Copilot through your application.
-
Bundled CLI — Package Copilot CLI alongside your application so that users do not need to install or configure anything separately.
-
Backend services — Run GitHub Copilot SDK in server-side applications such as APIs, web backends, microservices, and background workers.
-
Azure Managed Identity — Use Azure Managed Identity (Entra ID) to authenticate with Azure AI Foundry models instead of static API keys.
-
Scaling deployments — Design your deployment to serve multiple users, handle concurrent sessions, and scale horizontally across infrastructure.
Authentication
Authenticating with Copilot SDK — index
Index of authentication options.
-
Authenticating with Copilot SDK — Choose the authentication method that best fits your deployment scenario (local, OAuth, service account, BYOK).
-
Bring your own key (BYOK) — Use your own API keys from different model providers (OpenAI, Azure OpenAI, etc.), bypassing GitHub Copilot authentication entirely. Set provider: { type, baseUrl, apiKey } in createSession.
Using the SDK (Capabilities)
Use Copilot SDK — index
Index of all capability guides.
-
Custom agents & sub-agent orchestration — Define specialized agents with scoped tools and prompts; let Copilot orchestrate them as sub-agents within a single session. Use for multi-agent workflows.
-
Working with hooks — Use hooks to customize the behavior of your Copilot SDK sessions at lifecycle points (pre/post tool use, prompt submitted, session start/end, errors).
-
Image input — Send images to Copilot SDK sessions as file or blob attachments.
-
MCP servers — Integrate MCP (Model Context Protocol) servers with the Copilot SDK to extend your application's capabilities with external tools.
-
Session persistence — Pause, resume, and manage Copilot SDK sessions across restarts and deployments.
-
Custom skills — Use skills to extend Copilot's capabilities with reusable prompt modules; attach skills to sessions.
-
Steering and queueing messages — Send messages to an active Copilot SDK session to redirect it mid-turn or queue follow-up tasks.
-
Streaming events reference — Full reference of all session events emitted by the SDK and the data fields each contains (e.g. assistant.message_delta, session.idle, tool events).
Hooks (Conversation Lifecycle)
Use hooks — index
Hooks let you intercept and customize session behavior at key points.
-
Hooks quickstart — Get started with hooks to control tool execution, transform results, add context, handle errors, and audit interactions.
-
onPreToolUse — Use to control tool execution, modify arguments, and add context before a tool runs.
-
onPostToolUse — Use to transform tool results, log tool execution, and add context after a tool runs.
-
onUserPromptSubmitted — Use to modify prompts, add context, and filter user input when a prompt is submitted.
-
onSessionStart / onSessionEnd — Use to initialize context and resources at session start; clean up and track metrics at session end.
-
onErrorOccurred — Implement custom error logging, track error patterns, and provide user-friendly error messages.
Observability
Observability for Copilot SDK — index
Integrations
Copilot SDK integrations — index
- Microsoft Agent Framework — Use Copilot SDK as an agent provider inside Microsoft Agent Framework to build and orchestrate multi-agent workflows alongside other AI providers.
Troubleshooting
Troubleshooting Copilot SDK — index
-
SDK and CLI compatibility — Compare which Copilot CLI features are available through the SDK, identify CLI-only features, and find programmatic workarounds.
-
Debugging Copilot SDK — Enable debug logging and resolve common connection, authentication, and tool execution issues.
-
Debugging MCP servers — Diagnose and fix issues with MCP servers, including server startup failures, tool discovery problems, and protocol errors.
This Project's Quick-Reference Patterns
Code patterns used in src/reviewer/ for this project. See docs above for full API reference.
Core Lifecycle
import { CopilotClient, approveAll } from "@github/copilot-sdk";
const client = new CopilotClient();
await client.start();
const session = await client.createSession({
model: "gpt-4o",
onPermissionRequest: approveAll,
provider: {
type: "openai",
baseUrl: "https://api.openai.com/v1",
apiKey: process.env.OPENAI_API_KEY,
},
systemMessage: { content: AGENT_SYSTEM_PROMPT },
});
const result = await session.sendAndWait({ prompt: userMessage });
const text = result?.data.content ?? "";
await session.disconnect();
await client.stop();
Structured JSON Output
No native format: { type: 'json_schema' } — enforce via system prompt:
const systemPrompt = `${SECURITY_PROMPT}
Respond ONLY with a valid JSON array matching this schema — no markdown, no explanation:
${JSON.stringify(findingSchema, null, 2)}`;
const raw = result?.data.content ?? "";
const json = raw
.replace(/^```json\s*/i, "")
.replace(/\s*```$/, "")
.trim();
const findings = JSON.parse(json) as Finding[];
Parallel Sessions
const [secRaw, qualRaw] = await Promise.all([
runAgentSession(client, SECURITY_PROMPT, diff, findingSchema),
runAgentSession(client, QUALITY_PROMPT, diff, findingSchema),
]);
BYOK / Custom Provider
provider: { type: "openai", baseUrl: "https://api.openai.com/v1", apiKey: process.env.OPENAI_API_KEY }
Timeout Pattern
sendAndWait accepts an optional timeout in ms:
const result = await session.sendAndWait({ prompt }, 5 * 60 * 1000);
Or wrap at a higher level:
async function withTimeout<T>(p: Promise<T>, ms: number): Promise<T> {
return Promise.race([
p,
new Promise<never>((_, r) => setTimeout(() => r(new Error("timeout")), ms)),
]);
}
Migration from @opencode-ai/sdk
| @opencode-ai/sdk | @github/copilot-sdk |
|---|
createOpencode({ config: { model } }) | new CopilotClient(); await client.start() |
client.session.create() | await client.createSession({ model, onPermissionRequest, provider }) |
client.session.prompt({ id, prompt, format }) | await session.sendAndWait({ prompt }) |
pollUntilIdle(client, sessionId) | built into sendAndWait |
server.close() | await client.stop() (or client.forceStop() for forced) |
format: { type: 'json_schema', schema } | enforce JSON in system prompt + JSON.parse |
Full Agent Session Helper
async function runAgentSession(
client: CopilotClient,
systemPrompt: string,
userMessage: string,
schema: object,
): Promise<string> {
const prompt = `${systemPrompt}
Respond ONLY with valid JSON matching this schema — no markdown fences:
${JSON.stringify(schema, null, 2)}`;
const session = await client.createSession({
model: "gpt-4o",
onPermissionRequest: approveAll,
provider: {
type: "openai",
baseUrl: "https://api.openai.com/v1",
apiKey: process.env.OPENAI_API_KEY,
},
systemMessage: { content: prompt },
});
try {
const result = await session.sendAndWait({ prompt: userMessage }, 5 * 60 * 1000);
const raw = result?.data.content ?? "";
return raw
.replace(/^```json\s*/i, "")
.replace(/\s*```$/, "")
.trim();
} finally {
await session.disconnect();
}
}
Cleanup: stop() vs forceStop()
client.stop() is a graceful shutdown — returns Promise<Error[]> (errors from the shutdown process, not thrown). Use it in finally blocks:
} finally {
const errors = await client.stop();
if (errors.length) console.error("shutdown errors:", errors);
}
client.forceStop() kills the CLI process immediately without cleanup — use only when stop() hangs or as a fallback in a catch.
Common Mistakes
| Mistake | Fix |
|---|
Missing onPermissionRequest | Always required — use approveAll |
Custom provider without model | model is required with provider |
| Expecting JSON without schema in system prompt | No native structured output — must instruct via prompt |
Calling server.close() (opencode pattern) | Use await client.stop() |
Creating a new CopilotClient per session | Create once, call createSession multiple times |
try { await client.stop() } catch — wrapping stop() in try/catch | stop() returns errors in an array, it doesn't throw |