Note
Copilot SDK is currently in public preview. Functionality and availability are subject to change.
GitHub Copilot SDK lets you build applications powered by GitHub Copilot in your preferred programming language. In this guide, you'll install the SDK using npm, send your first message, and add streaming responses.
For more information and steps for other languages, see Install the SDK in the github/copilot-sdk repository.
Prerequisites
Before you begin, make sure you have Node.js 18 or later installed.
Authentication
Follow the instructions at Installing GitHub Copilot CLI to install and authenticate with GitHub Copilot CLI. This will allow the SDK to access your GitHub account and use Copilot.
-
Verify that Copilot CLI is installed and working:
Bash copilot --version
copilot --version
Installation
-
Create a new directory and initialize your project:
Bash mkdir copilot-demo && cd copilot-demo npm init -y --init-type module
mkdir copilot-demo && cd copilot-demo npm init -y --init-type module -
Install the SDK and TypeScript runner:
Bash npm install @github/copilot-sdk tsx
npm install @github/copilot-sdk tsx
Send your first message
-
Create a new file
index.tsand add the following code. This sends a single prompt to Copilot and prints the response.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(); process.exit(0);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(); process.exit(0); -
Run the code:
Bash npx tsx index.ts
npx tsx index.ts
In this example:
CopilotClient()creates a new client that manages the connection to Copilot CLI.createSession()starts a new conversation session with the specified model.sendAndWait()sends a prompt and waits for the complete response before returning.
Add streaming responses
Instead of waiting for the full response, you can stream it as it's generated. This is useful for long responses or interactive applications where you want to display output in real time.
-
Update
index.tswith the following code to listen and print response chunks as they arrive:TypeScript import { CopilotClient } from "@github/copilot-sdk"; const client = new CopilotClient(); const session = await client.createSession({ model: "gpt-4.1", streaming: true, }); // Listen for response chunks session.on("assistant.message_delta", (event) => { process.stdout.write(event.data.deltaContent); }); session.on("session.idle", () => { console.log(); // New line when done }); await session.sendAndWait({ prompt: "Tell me a short joke" }); await client.stop(); process.exit(0);import { CopilotClient } from "@github/copilot-sdk"; const client = new CopilotClient(); const session = await client.createSession({ model: "gpt-4.1", streaming: true, }); // Listen for response chunks session.on("assistant.message_delta", (event) => { process.stdout.write(event.data.deltaContent); }); session.on("session.idle", () => { console.log(); // New line when done }); await session.sendAndWait({ prompt: "Tell me a short joke" }); await client.stop(); process.exit(0); -
Run the code:
Bash npx tsx index.ts
npx tsx index.ts
With streaming enabled, the response appears incrementally as it's generated. You can subscribe to events to process each chunk in real time:
assistant.message_deltafires for each chunk of the response as it's generated.session.idlefires when the response is complete and the session is ready for the next message.
Event subscription methods
The SDK provides the following methods to subscribe to events:
- on(handler): Subscribe to all events. Returns the unsubscribe function.
- on(eventType, handler): Subscribe to a specific event type. Returns the unsubscribe function.
Add the following code to index.ts to subscribe to events and unsubscribe when you no longer need them:
// Subscribe to all events
const unsubscribeAll = session.on((event) => {
console.log("Event:", event.type);
});
// Subscribe to specific event type
const unsubscribeIdle = session.on("session.idle", (event) => {
console.log("Session is idle");
});
// Later, to unsubscribe:
unsubscribeAll();
unsubscribeIdle();
// Subscribe to all events
const unsubscribeAll = session.on((event) => {
console.log("Event:", event.type);
});
// Subscribe to specific event type
const unsubscribeIdle = session.on("session.idle", (event) => {
console.log("Session is idle");
});
// Later, to unsubscribe:
unsubscribeAll();
unsubscribeIdle();
Next steps
Add a custom tool
Give Copilot the ability to call your code by defining a custom tool. Here's a weather lookup tool:
import { CopilotClient, defineTool } from "@github/copilot-sdk";
// Define a tool that Copilot can call
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 (args: { city: string }) => {
const { city } = args;
// In a real app, you'd call a weather API here
const conditions = ["sunny", "cloudy", "rainy", "partly cloudy"];
const temp = Math.floor(Math.random() * 30) + 50;
const condition = conditions[Math.floor(Math.random() * conditions.length)];
return { city, temperature: `${temp}°F`, condition };
},
});
const client = new CopilotClient();
const session = await client.createSession({
model: "gpt-4.1",
streaming: true,
tools: [getWeather],
});
session.on("assistant.message_delta", (event) => {
process.stdout.write(event.data.deltaContent);
});
session.on("session.idle", () => {
console.log(); // New line when done
});
await session.sendAndWait({
prompt: "What's the weather like in Seattle and Tokyo?",
});
await client.stop();
process.exit(0);
import { CopilotClient, defineTool } from "@github/copilot-sdk";
// Define a tool that Copilot can call
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 (args: { city: string }) => {
const { city } = args;
// In a real app, you'd call a weather API here
const conditions = ["sunny", "cloudy", "rainy", "partly cloudy"];
const temp = Math.floor(Math.random() * 30) + 50;
const condition = conditions[Math.floor(Math.random() * conditions.length)];
return { city, temperature: `${temp}°F`, condition };
},
});
const client = new CopilotClient();
const session = await client.createSession({
model: "gpt-4.1",
streaming: true,
tools: [getWeather],
});
session.on("assistant.message_delta", (event) => {
process.stdout.write(event.data.deltaContent);
});
session.on("session.idle", () => {
console.log(); // New line when done
});
await session.sendAndWait({
prompt: "What's the weather like in Seattle and Tokyo?",
});
await client.stop();
process.exit(0);
For examples in Python, Go, .NET, and Rust, see Getting started in the github/copilot-sdk repository. For Java, see the github/copilot-sdk-java repository.
When you define a tool, you're telling Copilot:
- What the tool does (description)
- What parameters it needs (schema)
- What code to run (handler)
Copilot decides when to call your tool based on the user's question. When it does, the Copilot SDK runs your handler function and sends the result back to Copilot, which incorporates it into the response.
Build an interactive assistant
Combine everything into an interactive chat assistant:
import { CopilotClient, defineTool } from "@github/copilot-sdk";
import * as readline from "readline";
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 }) => {
const conditions = ["sunny", "cloudy", "rainy", "partly cloudy"];
const temp = Math.floor(Math.random() * 30) + 50;
const condition = conditions[Math.floor(Math.random() * conditions.length)];
return { city, temperature: `${temp}°F`, condition };
},
});
const client = new CopilotClient();
const session = await client.createSession({
model: "gpt-4.1",
streaming: true,
tools: [getWeather],
});
session.on("assistant.message_delta", (event) => {
process.stdout.write(event.data.deltaContent);
});
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
console.log("Weather Assistant (type 'exit' to quit)");
console.log(" Try: 'What's the weather in Paris?'\n");
const prompt = () => {
rl.question("You: ", async (input) => {
if (input.toLowerCase() === "exit") {
await client.stop();
rl.close();
return;
}
process.stdout.write("Assistant: ");
await session.sendAndWait({ prompt: input });
console.log("\n");
prompt();
});
};
prompt();
import { CopilotClient, defineTool } from "@github/copilot-sdk";
import * as readline from "readline";
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 }) => {
const conditions = ["sunny", "cloudy", "rainy", "partly cloudy"];
const temp = Math.floor(Math.random() * 30) + 50;
const condition = conditions[Math.floor(Math.random() * conditions.length)];
return { city, temperature: `${temp}°F`, condition };
},
});
const client = new CopilotClient();
const session = await client.createSession({
model: "gpt-4.1",
streaming: true,
tools: [getWeather],
});
session.on("assistant.message_delta", (event) => {
process.stdout.write(event.data.deltaContent);
});
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
console.log("Weather Assistant (type 'exit' to quit)");
console.log(" Try: 'What's the weather in Paris?'\n");
const prompt = () => {
rl.question("You: ", async (input) => {
if (input.toLowerCase() === "exit") {
await client.stop();
rl.close();
return;
}
process.stdout.write("Assistant: ");
await session.sendAndWait({ prompt: input });
console.log("\n");
prompt();
});
};
prompt();
Run with:
npx tsx weather-assistant.ts
npx tsx weather-assistant.ts
For examples in Python, Go, .NET, and Rust, see Getting started in the github/copilot-sdk repository. For Java, see the github/copilot-sdk-java repository.
Connect to MCP servers
MCP (Model Context Protocol) servers provide pre-built tools. Connect to GitHub's MCP server to give Copilot access to repositories, issues, and pull requests:
const session = await client.createSession({
mcpServers: {
github: {
type: "http",
url: "https://api.githubcopilot.com/mcp/",
},
},
});
const session = await client.createSession({
mcpServers: {
github: {
type: "http",
url: "https://api.githubcopilot.com/mcp/",
},
},
});
For more information, see Using MCP servers with the Copilot SDK.
Create custom agents
Define specialized AI personas for specific tasks:
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.",
}],
});
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.",
}],
});
For more information, see Custom agents and sub-agent orchestration.
Customize the system message
Control the AI's behavior and personality by appending instructions:
const session = await client.createSession({
systemMessage: {
content: "You are a helpful assistant for our engineering team. Always be concise.",
},
});
const session = await client.createSession({
systemMessage: {
content: "You are a helpful assistant for our engineering team. Always be concise.",
},
});
Further reading
- Choosing a setup path for Copilot SDK
- Understanding the agent loop
- Connecting to an external CLI server in the
github/copilot-sdkrepository - Telemetry and observability in the
github/copilot-sdkrepository