How to Include the GitHub Copilot SDK in a Rust Project Using Cargo

Add the github-copilot-sdk crate to your Cargo.toml dependencies, optionally enabling the bundled-in-process feature for FFI runtime or disabling default features to use an external CLI binary.

The GitHub Copilot SDK provides a Rust crate that wraps the Copilot CLI via JSON-RPC, enabling programmatic access to GitHub's AI pair programming capabilities. To include the GitHub Copilot SDK in a Rust project using Cargo, you add the crate as a dependency and initialize the Client struct with your preferred transport configuration. This guide walks through the exact steps required to integrate the SDK according to the github/copilot-sdk source code, configure its feature flags, and establish your first client connection.

Adding the Dependency to Cargo.toml

The SDK is published to crates.io as github-copilot-sdk. The crate uses feature flags to control how the Copilot runtime is packaged and executed.

According to rust/Cargo.toml, the default feature set includes bundled-cli, which automatically packages the Copilot CLI binary inside your compiled application. You can modify this behavior depending on your deployment requirements.

Add the dependency to your Cargo.toml:

[dependencies]

# Default: includes the bundled CLI binary

github-copilot-sdk = "0.0.0-dev"

# Option A: Enable in-process FFI runtime instead of CLI spawning

github-copilot-sdk = { version = "0.0.0-dev", features = ["bundled-in-process"] }

# Option B: Disable bundling entirely to provide your own CLI binary

github-copilot-sdk = { version = "0.0.0-dev", default-features = false }

Available features defined in rust/Cargo.toml include:

  • bundled-cli (default): Embeds the Copilot CLI binary and extracts it at runtime
  • bundled-in-process: Links the Copilot runtime as an in-process FFI library instead of spawning a separate process
  • derive: Enables schemars support for JSON schema generation via derive macros
  • test-support: Exposes internal testing utilities and mock transports

Understanding the SDK Architecture

Before initializing the client, understand the core types defined in rust/src/lib.rs. These types handle the connection lifecycle, configuration, and communication protocol.

Client

The Client struct serves as the primary entry point. When you call Client::start(), the SDK resolves the transport method, spawns the CLI process (or connects to an existing one), and validates protocol compatibility. The client encapsulates the JSON-RPC connection and manages background tasks for message handling.

ClientOptions

ClientOptions provides a builder-pattern configuration struct. Located in rust/src/lib.rs, it allows you to specify:

  • Transport mode (Transport::Stdio, Tcp, External, or InProcess)
  • CLI binary location via CliProgram
  • Authentication tokens forwarded via COPILOT_SDK_AUTH_TOKEN
  • Logging levels for the Copilot runtime
  • OpenTelemetry telemetry configuration

Transport

The Transport enum in rust/src/lib.rs defines four communication methods:

  • Stdio: Spawns the CLI as a subprocess and communicates over stdin/stdout pipes (default behavior)
  • Tcp: Binds to a local TCP port for remote debugging or containerized deployments
  • External: Connects to an already-running Copilot server instance
  • InProcess: Uses the FFI runtime when bundled-in-process is enabled, eliminating subprocess overhead

Feature Flags and Binary Resolution

When using the default bundled-cli feature, the SDK uses logic in rust/src/resolve.rs to extract the appropriate platform-specific CLI binary from the crate's assets to a temporary location at runtime. If you disable default features and provide your own binary, the SDK skips this extraction step and uses the path specified in ClientOptions.

Initializing the SDK in Your Rust Code

Once the dependency is added, import the SDK and initialize a client. The following minimal example demonstrates starting a client with default options and creating a session:

use github_copilot_sdk::{Client, ClientOptions, LogLevel, Transport};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Configure client options using the builder pattern
    let opts = ClientOptions::new()
        .with_log_level(LogLevel::Info)
        .with_transport(Transport::Stdio);

    // Start the client: spawns CLI process and establishes JSON-RPC connection
    let client = Client::start(opts).await?;

    // Create a new conversation session
    let session = client.create_session(Default::default()).await?;

    // Send a message to the Copilot model
    let response = session
        .send_message("Explain Rust ownership and borrowing")
        .await?;

    println!("Response: {}", response.text);
    Ok(())
}

Key implementation details from rust/src/session.rs:

  • create_session() returns a Session handle that manages conversation state
  • send_message() serializes the request to JSON-RPC, sends it to the CLI process, and deserializes the response
  • All async methods require a Tokio runtime

Advanced Configuration Examples

Using TCP Transport

For scenarios requiring network accessibility or container orchestration, configure the TCP transport as implemented in rust/src/lib.rs:

use github_copilot_sdk::{Client, ClientOptions, LogLevel, Transport};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let opts = ClientOptions::new()
        .with_transport(Transport::Tcp {
            port: 0, // 0 allows the OS to assign an available port
            connection_token: None, // SDK auto-generates a secure token
        })
        .with_log_level(LogLevel::Debug)
        .with_github_token("ghp_xxxxxxxxxxxx"); // Optional: forward GitHub token

    let client = Client::start(opts).await?;
    
    // Session handling remains identical to the stdio example
    let session = client.create_session(Default::default()).await?;
    let response = session.send_message("Refactor this code").await?;
    
    Ok(())
}

Disabling Bundled Features for Custom CLI

If you distribute the Copilot CLI separately or need to comply with specific licensing requirements, disable bundling and provide the binary path:

// In Cargo.toml
[dependencies]
github-copilot-sdk = { version = "0.0.0-dev", default-features = false }

// In your code
let opts = ClientOptions::new()
    .with_cli_program("/usr/local/bin/copilot-cli");

Summary

  • Add github-copilot-sdk to your Cargo.toml dependencies to include the GitHub Copilot SDK in your Rust project using Cargo.
  • The default bundled-cli feature automatically packages the Copilot CLI; use default-features = false to provide your own binary.
  • Enable the bundled-in-process feature for FFI-based in-process runtime instead of subprocess communication.
  • Core types (Client, ClientOptions, Transport) are defined in rust/src/lib.rs and re-exported for public use.
  • Initialize the SDK with Client::start(opts).await? after configuring options via ClientOptions::new().
  • Session management and message handling are implemented in rust/src/session.rs using asynchronous JSON-RPC over your selected transport.

Frequently Asked Questions

What is the difference between the bundled-cli and bundled-in-process features?

The bundled-cli feature (enabled by default) packages the Copilot CLI as an external binary that the SDK spawns as a subprocess and communicates with via JSON-RPC over pipes or TCP. The bundled-in-process feature links the Copilot runtime directly into your application as a shared library using FFI, eliminating the subprocess overhead and allowing tighter integration. You can enable both features simultaneously, but typically you choose one based on whether you prefer process isolation or lower latency.

How do I provide my own Copilot CLI binary instead of using the bundled one?

Set default-features = false in your Cargo.toml dependency declaration to disable the automatic bundling. Then, when constructing your client in Rust, use ClientOptions::new().with_cli_program("/path/to/copilot-cli") to specify the exact location of your custom binary. The SDK will skip the extraction logic in rust/src/resolve.rs and spawn your provided executable instead.

What transport options does the SDK support for communicating with the Copilot runtime?

As defined in rust/src/lib.rs, the SDK supports four transport variants: Stdio (default, uses stdin/stdout pipes), Tcp (binds to a TCP socket for remote connections), External (connects to an already-running server), and InProcess (uses FFI when the bundled-in-process feature is enabled). Each variant implements the same Transport trait, allowing you to switch communication methods without changing your session handling code.

Where are the core SDK types like Client and ClientOptions defined?

All public SDK types are defined in rust/src/lib.rs and re-exported at the crate root. This includes Client (the main entry point), ClientOptions (configuration builder), Transport (communication protocol selector), and Session (conversation management). Internal implementation details for binary resolution reside in rust/src/resolve.rs, while JSON-RPC protocol handling is implemented in rust/src/rpc.rs.

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 →