How to Get Started with the GitHub Copilot SDK: A Complete Guide for Node.js, Python, Go, and More
Install the GitHub Copilot SDK for your language, initialize a CopilotClient to manage the CLI process, create a Session with your chosen model, and call sendAndWait() to exchange messages with the LLM via JSON-RPC transport.
The GitHub Copilot SDK provides language-specific client libraries that wrap the GitHub Copilot CLI, enabling developers to build conversational AI applications in Node.js, Python, Go, Rust, .NET, and Java. This guide follows the official getting-started workflow from the docs/getting-started.md file in the github/copilot-sdk repository, covering installation, your first API call, streaming responses, and custom tool registration.
Prerequisites
Before installing the SDK, verify your runtime meets the minimum version requirements and that the GitHub Copilot CLI is accessible. The SDK automatically bundles the CLI for Node.js, Python, and .NET environments.
- Node.js: Version 20 or higher
- Python: Version 3.11 or higher
- Go: Version 1.24 or higher
- Rust: Version 1.94 or higher
- Java: Version 17 or higher
- .NET: Version 8.0 or higher
Confirm CLI availability by running:
copilot --version
This should return a version string like 1.123.0. If the CLI is not found, ensure the Copilot extension is installed in your IDE or install the CLI manually.
Install the GitHub Copilot SDK
Select your language below and execute the installation command. Language-specific READMEs are available in the repository under nodejs/README.md, python/README.md, go/README.md, rust/README.md, dotnet/README.md, and java/README.md.
Node.js / TypeScript
npm init -y && npm install @github/copilot-sdk tsx
Python
pip install github-copilot-sdk
Go
go get github.com/github/copilot-sdk/go
Rust
cargo add github-copilot-sdk --features derive
.NET
dotnet add package GitHub.Copilot.SDK
Java
Add the Maven coordinates com.github:copilot-sdk-java:${copilot.sdk.version} to your pom.xml or Gradle configuration as shown in the repository README.
Send Your First Message
Create an entry file (e.g., main.ts, main.py, or main.go) and instantiate the CopilotClient. According to the source code in go/client.go, this class manages the CLI process lifecycle and JSON-RPC transport. Then create a Session—defined in go/session.go—which represents a conversational context with model configuration.
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();
process.exit(0);
Run the script with npx tsx main.ts.
Python
import asyncio
from copilot import CopilotClient
from copilot.session import PermissionHandler
async def main():
client = CopilotClient()
await client.start()
session = await client.create_session(
on_permission_request=PermissionHandler.approve_all,
model="gpt-4.1"
)
response = await session.send_and_wait("What is 2 + 2?")
print(response.data.content)
await client.stop()
asyncio.run(main())
Run with python main.py. The CopilotClient implementation in python/copilot/client.py handles the CLI handshake, while python/copilot/session.py manages the session state.
Go
package main
import (
"context"
"fmt"
"log"
copilot "github.com/github/copilot-sdk/go"
)
func main() {
ctx := context.Background()
client := copilot.NewClient(nil)
if err := client.Start(ctx); err != nil { log.Fatal(err) }
defer client.Stop()
session, err := client.CreateSession(ctx, &copilot.SessionConfig{Model: "gpt-4.1"})
if err != nil { log.Fatal(err) }
resp, err := session.SendAndWait(ctx, copilot.MessageOptions{Prompt: "What is 2 + 2?"})
if err != nil { log.Fatal(err) }
if d, ok := resp.Data.(*copilot.AssistantMessageData); ok {
fmt.Println(d.Content)
}
}
Execute with go run main.go.
Rust
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = github_copilot_sdk::Client::start(github_copilot_sdk::ClientOptions::default()).await?;
let session = client.create_session(
github_copilot_sdk::SessionConfig::default()
.with_model("gpt-4.1")
.with_permission_handler(github_copilot_sdk::handler::ApproveAllHandler)
).await?;
let response = session.send_and_wait(github_copilot_sdk::MessageOptions::new("What is 2 + 2?")).await?;
if let Some(content) = response.data.get("content").and_then(|v| v.as_str()) {
println!("{content}");
}
Ok(())
}
Run with cargo run.
.NET (C#)
using GitHub.Copilot;
await using var client = new CopilotClient();
await using var session = await client.CreateSessionAsync(new SessionConfig {
Model = "gpt-4.1",
OnPermissionRequest = PermissionHandler.ApproveAll
});
var response = await session.SendAndWaitAsync(new MessageOptions { Prompt = "What is 2 + 2?" });
Console.WriteLine(response?.Data.Content);
Run with dotnet run.
Java
import com.github.copilot.CopilotClient;
import com.github.copilot.rpc.*;
try (var client = new CopilotClient()) {
client.start().get();
var session = client.createSession(
new SessionConfig()
.setModel("gpt-4.1")
.setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
).get();
var resp = session.sendAndWait(new MessageOptions().setPrompt("What is 2 + 2?")).get();
System.out.println(resp.getData().content());
client.stop().get();
}
Compile and run with javac -cp copilot-sdk.jar HelloCopilot.java && java -cp .:copilot-sdk.jar HelloCopilot.
Enable Streaming Responses
To receive LLM output incrementally, enable streaming in the SessionConfig and subscribe to the assistant.message_delta event. The SDK delivers chunks via the event system implemented in go/session.go.
- Node.js: Pass
streaming: truetocreateSession()and listen withsession.on("assistant.message_delta", ...). - Python: Set
streaming=Trueincreate_session()and handleSessionEventType.ASSISTANT_MESSAGE_DELTA. - Go: Set
Streaming: copilot.Bool(true)and register a handler withsession.Onusing the*copilot.AssistantMessageDeltaDatatype. - Rust: Set
config.streaming = Some(true)and filter the subscription stream for"assistant.message_delta". - .NET: Set
Streaming = trueand subscribe withsession.On<AssistantMessageDeltaEvent>(...). - Java: Call
setStreaming(true)and register a listener viasession.on(AssistantMessageDeltaEvent.class, ...).
The go/session.go file defines the event subscription interface that all language SDKs implement.
Register Custom Tools
Define functions that the LLM can invoke by creating a Tool using the defineTool helper (or language-specific equivalent). As implemented in go/toolset.go, you supply a JSON Schema for parameters, a handler implementation, and optional permission logic.
The following Go example from the repository demonstrates the DefineTool pattern:
type WeatherParams struct {
City string `json:"city" jsonschema:"The city name"`
}
type WeatherResult struct {
City string `json:"city"`
Temperature string `json:"temperature"`
Condition string `json:"condition"`
}
getWeather := copilot.DefineTool(
"get_weather",
"Get the current weather for a city",
func(p WeatherParams, inv copilot.ToolInvocation) (WeatherResult, error) {
// Replace with actual API logic
return WeatherResult{
City: p.City,
Temperature: "72°F",
Condition: "sunny",
}, nil
},
)
Register the tool during session creation:
session, err := client.CreateSession(ctx, &copilot.SessionConfig{
Model: "gpt-4.1",
Streaming: copilot.Bool(true),
Tools: []copilot.Tool{getWeather},
})
The Tool interface in go/toolset.go handles JSON Schema generation and parameter deserialization automatically.
Build an Interactive Assistant
Combine streaming, tool registration, and a REPL loop to create an interactive assistant. The repository provides complete weather-assistant examples for each language in the docs/getting-started.md guide. These implementations demonstrate:
- Processing user input in a loop
- Streaming assistant responses to the console
- Executing tool calls when the LLM requests them
- Returning tool results to the conversation context
The Python implementation uses python/copilot/tools.py for the define_tool decorator, while the .NET implementation relies on dotnet/CopilotSDK/Tool.cs for the handler delegate wiring.
Summary
- The GitHub Copilot SDK wraps the CLI with language-specific clients for Node.js, Python, Go, Rust, .NET, and Java.
CopilotClientmanages the CLI process and JSON-RPC transport according togo/client.go.Sessionmaintains conversation state, model configuration, and event subscriptions as defined ingo/session.go.- Enable streaming by setting the configuration flag and subscribing to
assistant.message_deltaevents. - Register custom tools using
DefineTool(Go),define_tool(Python), or equivalent classes to expose functions to the LLM. - Handle permissions via
PermissionHandlerimplementations ingo/permissions.go.
Frequently Asked Questions
Do I need to install the GitHub Copilot CLI separately before using the SDK?
No. The SDK automatically bundles the CLI for Node.js, Python, and .NET environments. For Go, Rust, and Java, ensure the copilot binary is in your PATH by running copilot --version to verify installation.
How do I approve or deny tool calls programmatically?
Pass a permission handler during session creation. The SDK validates tool invocations through the PermissionHandler interface defined in go/permissions.go. Use built-in options like PermissionHandler.ApproveAll (or PermissionHandler.approve_all in Python) to automatically allow all calls, or provide a custom callback to inspect each request before execution.
Which LLM models are supported when creating a Session?
The examples in this guide use gpt-4.1, which you specify in the SessionConfig model parameter. The SDK negotiates protocol compatibility automatically via the CopilotClient handshake implemented in go/client.go, supporting any model available through the GitHub Copilot CLI.
How does the SDK handle communication between my application and the CLI?
The CopilotClient class spawns the CLI as a subprocess and establishes a JSON-RPC pipe for message transport. This architecture, detailed in go/client.go and go/session.go, allows the SDK to serialize requests, deserialize responses, and emit events across all supported languages using a unified protocol.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →