What Is the GitHub Copilot SDK? A Complete Developer Guide

The GitHub Copilot SDK is a family of language-specific libraries (Node.js/TypeScript, Python, Go, Rust, .NET, and Java) that let you embed the same agentic AI engine that powers the Copilot CLI directly inside your own applications.

The GitHub Copilot SDK, hosted at github/copilot-sdk, provides stable client libraries that abstract the complexity of orchestrating AI sessions. Instead of building custom AI infrastructure, developers can leverage these production-ready APIs to manage conversation context, stream responses, and register custom tools using idiomatic patterns in their preferred programming language.

GitHub Copilot SDK Architecture

The GitHub Copilot SDK operates on a common architecture across all supported languages. Your application communicates with a Copilot CLI process through JSON-RPC messages, abstracting the complexity of the AI runtime.

JSON-RPC Communication Protocol

Every SDK follows this communication pattern:

  • The SDK starts the Copilot CLI in server mode (or connects to an external instance)
  • It opens a communication channel over standard I/O
  • High-level client APIs translate method calls into JSON-RPC requests

Your Application → SDK Client → JSON-RPC → Copilot CLI (server mode)

According to the source code in nodejs/src/client.ts, the CopilotClient class manages this lifecycle, handling process spawning and connection management automatically for most languages.

Bundled vs. External CLI

Language support varies by deployment model as documented in docs/setup/bundled-cli.md:

  • Node.js, Python, and .NET: The CLI is bundled automatically with the SDK
  • Go, Rust, and Java: You must have the Copilot CLI available on your system PATH or run it in server mode separately

Session Management and Workflow

The GitHub Copilot SDK uses a session-based architecture defined in nodejs/src/session.ts. A session represents a persistent conversation context with specific configuration for model selection, streaming behavior, tools, and authentication.

Creating and Configuring Sessions

To begin interacting with the AI, instantiate a client and create a session using the createSession method:

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);   // → 4

await client.stop();

The createSession method accepts configuration for model selection, streaming preferences, custom tools, and permission handlers. In nodejs/src/index.ts, the public export surface exposes these classes along with type definitions for session events.

Streaming and Event Handling

For real-time applications, the SDK supports event-driven streaming. You can listen for assistant.message_delta events to receive incremental output as the model generates text, and session.idle events to detect when processing completes.

The session object exposes an on method for registering event handlers. As shown in the Python implementation, you process events by checking the SessionEventType:

def handler(ev):
    if ev.type == SessionEventType.ASSISTANT_MESSAGE_DELTA:
        sys.stdout.write(ev.data.delta_content)
        sys.stdout.flush()
    if ev.type == SessionEventType.SESSION_IDLE:
        print()

session.on(handler)

Authentication Options

The GitHub Copilot SDK supports multiple authentication strategies to accommodate different deployment scenarios. According to the repository's README, you can authenticate using:

  • GitHub OAuth tokens obtained through standard OAuth flows
  • Environment variables for CI/CD automation
  • BYOK (Bring Your Own Key) for enterprise scenarios requiring custom API key management

Authentication configuration is passed during session creation or set globally on the client instance.

Extensibility: Custom Tools and Agents

One of the SDK's most powerful features is the ability to define custom tools—functions that Copilot can invoke during conversation to retrieve data or perform actions.

Defining Tools with JSON Schema

Tools are defined with a JSON schema for parameter validation and a handler function for execution. In Python, the @define_tool decorator creates a callable tool that the AI can reference:

from pydantic import BaseModel, Field
from copilot.tools import define_tool

class GetWeatherParams(BaseModel):
    city: str = Field(description="City name")

@define_tool(description="Get the current weather for a city")
async def get_weather(p: GetWeatherParams) -> dict:
    # placeholder implementation

    return {"city": p.city, "temperature": "64°F", "condition": "sunny"}

The PermissionHandler class allows automatic approval or denial of tool invocations, as demonstrated by PermissionHandler.approve_all in the example above.

MCP Server Integration

The SDK supports the Model Context Protocol (MCP), allowing you to connect to external servers for repository-aware tools. You can also implement custom agents and override system messages through the extensibility hooks documented in docs/features/custom-agents.md.

Implementation Examples by Language

TypeScript and Node.js

The Node.js SDK, exported from nodejs/src/index.ts, provides a promise-based API. The CopilotClient class handles CLI lifecycle management, while the session manages tool invocation callbacks:

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);   // → 4

await client.stop();

Python Async Patterns

The Python SDK supports async/await patterns for non-blocking I/O with full streaming support:

import asyncio, sys
from copilot import CopilotClient
from copilot.session import PermissionHandler
from copilot.tools import define_tool
from copilot.session_events import SessionEventType
from pydantic import BaseModel, Field

class GetWeatherParams(BaseModel):
    city: str = Field(description="City name")

@define_tool(description="Get the current weather for a city")
async def get_weather(p: GetWeatherParams) -> dict:
    # placeholder implementation

    return {"city": p.city, "temperature": "64°F", "condition": "sunny"}

async def main():
    client = CopilotClient()
    await client.start()
    session = await client.create_session(
        on_permission_request=PermissionHandler.approve_all,
        model="gpt-4.1",
        streaming=True,
        tools=[get_weather],
    )

    # Print streamed chunks

    def handler(ev):
        if ev.type == SessionEventType.ASSISTANT_MESSAGE_DELTA:
            sys.stdout.write(ev.data.delta_content)
            sys.stdout.flush()
        if ev.type == SessionEventType.SESSION_IDLE:
            print()

    session.on(handler)
    await session.send_and_wait("What's the weather in Seattle?")
    await client.stop()

asyncio.run(main())

Go Structures and Handlers

The Go SDK uses struct tags for JSON schema generation and explicit error handling. The copilot.DefineTool function accepts a name, description, and handler closure:

package main

import (
    "context"
    "fmt"
    "log"
    "math/rand"

    copilot "github.com/github/copilot-sdk/go"
)

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"`
}

func main() {
    ctx := context.Background()
    client := copilot.NewClient(nil)
    if err := client.Start(ctx); err != nil { log.Fatal(err) }
    defer client.Stop()

    getWeather := copilot.DefineTool(
        "get_weather",
        "Get the current weather for a city",
        func(p WeatherParams, _ copilot.ToolInvocation) (WeatherResult, error) {
            conditions := []string{"sunny", "cloudy", "rainy", "partly cloudy"}
            temp := rand.Intn(30) + 50
            condition := conditions[rand.Intn(len(conditions))]
            return WeatherResult{
                City: p.City, Temperature: fmt.Sprintf("%d°F", temp), Condition: condition,
            }, nil
        },
    )

    session, err := client.CreateSession(ctx, &copilot.SessionConfig{
        Model:     "gpt-4.1",
        Streaming: copilot.Bool(true),
        Tools:     []copilot.Tool{getWeather},
    })
    if err != nil { log.Fatal(err) }

    session.On(func(ev copilot.SessionEvent) {
        switch d := ev.Data.(type) {
        case *copilot.AssistantMessageDeltaData:
            fmt.Print(d.DeltaContent)
        case *copilot.SessionIdleData:
            fmt.Println()
        }
    })

    _, err = session.SendAndWait(ctx, copilot.MessageOptions{Prompt: "Weather in Tokyo?"})
    if err != nil { log.Fatal(err) }
}

Summary

  • The GitHub Copilot SDK provides language-specific libraries for embedding Copilot's AI engine into custom applications across Node.js, Python, Go, Rust, .NET, and Java.
  • Architecture relies on JSON-RPC communication between your application and a Copilot CLI process, with the CopilotClient class managing connections as implemented in nodejs/src/client.ts.
  • Session management follows a consistent pattern: create a session with createSession, send prompts via sendAndWait or streaming handlers, and register custom tools using define_tool.
  • Authentication supports GitHub OAuth tokens, environment variables, and BYOK strategies for flexible deployment.
  • File locations for core logic include nodejs/src/session.ts for event handling and nodejs/src/index.ts for the public API surface.

Frequently Asked Questions

What languages does the GitHub Copilot SDK support?

The GitHub Copilot SDK officially supports Node.js/TypeScript, Python, Go, Rust, .NET, and Java. Each implementation provides idiomatic APIs that map to the same underlying JSON-RPC protocol, ensuring consistent behavior across languages while respecting platform-specific patterns like Python's async/await or Go's struct tags.

How does the GitHub Copilot SDK handle authentication?

The SDK supports three primary authentication methods: GitHub OAuth tokens for user-specific access, environment variables for automated CI/CD pipelines, and Bring Your Own Key (BYOK) for enterprises requiring custom API key management. Authentication credentials can be passed during session creation or configured globally on the client instance.

What is the difference between bundled and external CLI modes?

Node.js, Python, and .NET SDKs bundle the Copilot CLI automatically, handling process lifecycle internally through the CopilotClient class. Go, Rust, and Java implementations require you to install the Copilot CLI separately and ensure it exists on your system PATH, or run it explicitly in server mode before connecting your application.

Can I create custom tools with the GitHub Copilot SDK?

Yes. The SDK allows you to define custom tools using JSON schema for parameter validation and handler functions for execution. These tools enable Copilot to invoke external functions during conversations, such as querying databases or calling APIs, with support for MCP servers to extend functionality further as documented in docs/features/custom-agents.md.

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 →