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: true to createSession() and listen with session.on("assistant.message_delta", ...).
  • Python: Set streaming=True in create_session() and handle SessionEventType.ASSISTANT_MESSAGE_DELTA.
  • Go: Set Streaming: copilot.Bool(true) and register a handler with session.On using the *copilot.AssistantMessageDeltaData type.
  • Rust: Set config.streaming = Some(true) and filter the subscription stream for "assistant.message_delta".
  • .NET: Set Streaming = true and subscribe with session.On<AssistantMessageDeltaEvent>(...).
  • Java: Call setStreaming(true) and register a listener via session.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.
  • CopilotClient manages the CLI process and JSON-RPC transport according to go/client.go.
  • Session maintains conversation state, model configuration, and event subscriptions as defined in go/session.go.
  • Enable streaming by setting the configuration flag and subscribing to assistant.message_delta events.
  • Register custom tools using DefineTool (Go), define_tool (Python), or equivalent classes to expose functions to the LLM.
  • Handle permissions via PermissionHandler implementations in go/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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →