Liking cljdoc? Tell your friends :D

Local CLI Setup

Use a specific CLI binary instead of the SDK's bundled CLI. This is an advanced option — you supply the CLI path explicitly, and you are responsible for ensuring version compatibility with the SDK.

Use when: You need to pin a specific CLI version, or work with the Go SDK (which does not bundle a CLI).

How It Works

By default, the Node.js, Python, and .NET SDKs include their own CLI dependency (see Default Setup). If you need to override this — for example, to use a system-installed CLI — you can use the cliPath option.

flowchart LR
    subgraph YourMachine["Your Machine"]
        App["Your App"] --> SDK["SDK Client"]
        SDK -- "cliPath" --> CLI["Copilot CLI<br/>(your own binary)"]
        CLI --> Keychain["🔐 System Keychain<br/>(stored credentials)"]
    end
    CLI -- "API calls" --> Copilot["☁️ GitHub Copilot"]

    style YourMachine fill:#0d1117,stroke:#58a6ff,color:#c9d1d9

Key characteristics:

  • You explicitly provide the CLI binary path
  • You are responsible for CLI version compatibility with the SDK
  • Authentication uses the signed-in user's credentials from the system keychain (or env vars)
  • Communication happens over stdio

Configuration

Using a local CLI binary

Node.js / TypeScript
import { CopilotClient } from "copilot-sdk-supercharged";

const client = new CopilotClient({
    cliPath: "/usr/local/bin/copilot",
});

const session = await client.createSession({ model: "gpt-4.1" });
const response = await session.sendAndWait({ prompt: "Hello!" });
console.log(response?.data.content);

await client.stop();
Python
from copilot import CopilotClient
from copilot.generated.session_events import AssistantMessageData
from copilot.session import PermissionHandler

client = CopilotClient({
    "cli_path": "/usr/local/bin/copilot",
})
await client.start()

session = await client.create_session(on_permission_request=PermissionHandler.approve_all, model="gpt-4.1")
response = await session.send_and_wait("Hello!")
if response:
    match response.data:
        case AssistantMessageData() as data:
            print(data.content)

await client.stop()
Go

Note: The Go SDK does not bundle a CLI, so you must always provide CLIPath.

package main

import (
	"context"
	"fmt"
	"log"
	copilot "github.com/github/copilot-sdk/go"
)

func main() {
	ctx := context.Background()

	client := copilot.NewClient(&copilot.ClientOptions{
		CLIPath: "/usr/local/bin/copilot",
	})
	if err := client.Start(ctx); err != nil {
		log.Fatal(err)
	}
	defer client.Stop()

	session, _ := client.CreateSession(ctx, &copilot.SessionConfig{Model: "gpt-4.1"})
	response, _ := session.SendAndWait(ctx, copilot.MessageOptions{Prompt: "Hello!"})
	if response != nil {
		if d, ok := response.Data.(*copilot.AssistantMessageData); ok {
			fmt.Println(d.Content)
		}
	}
}
client := copilot.NewClient(&copilot.ClientOptions{
    CLIPath: "/usr/local/bin/copilot",
})
if err := client.Start(ctx); err != nil {
    log.Fatal(err)
}
defer client.Stop()

session, _ := client.CreateSession(ctx, &copilot.SessionConfig{Model: "gpt-4.1"})
response, _ := session.SendAndWait(ctx, copilot.MessageOptions{Prompt: "Hello!"})
if response != nil {
    if d, ok := response.Data.(*copilot.AssistantMessageData); ok {
        fmt.Println(d.Content)
    }
}
.NET
var client = new CopilotClient(new CopilotClientOptions
{
    CliPath = "/usr/local/bin/copilot",
});

await using var session = await client.CreateSessionAsync(
    new SessionConfig { Model = "gpt-4.1" });

var response = await session.SendAndWaitAsync(
    new MessageOptions { Prompt = "Hello!" });
Console.WriteLine(response?.Data.Content);

Additional Options

const client = new CopilotClient({
    cliPath: "/usr/local/bin/copilot",

    // Set log level for debugging
    logLevel: "debug",

    // Pass extra CLI arguments
    cliArgs: ["--log-dir=/tmp/copilot-logs"],

    // Set working directory
    cwd: "/path/to/project",
});

Using Environment Variables

Instead of the keychain, you can authenticate via environment variables. This is useful for CI or when you don't want interactive login.

# Set one of these (in priority order):
export COPILOT_GITHUB_TOKEN="gho_xxxx"   # Recommended
export GH_TOKEN="gho_xxxx"               # GitHub CLI compatible
export GITHUB_TOKEN="gho_xxxx"           # GitHub Actions compatible

The SDK picks these up automatically — no code changes needed.

Managing Sessions

Sessions default to ephemeral. To create resumable sessions, provide your own session ID:

// Create a named session
const session = await client.createSession({
    sessionId: "my-project-analysis",
    model: "gpt-4.1",
});

// Later, resume it
const resumed = await client.resumeSession("my-project-analysis");

Session state is stored locally at ~/.copilot/session-state/{sessionId}/.

Limitations

LimitationDetails
Version compatibilityYou must ensure your CLI version is compatible with the SDK
Single userCredentials are tied to whoever signed in to the CLI
Local onlyThe CLI runs on the same machine as your app
No multi-tenantCan't serve multiple users from one CLI instance

Next Steps

Can you improve this documentation? These fine people already did:
Stephen Toub, Sanzo, Brett Cannon, Jeremiah Isaacson, Bruno Borges, Steve Sanderson & Patrick Nikoletich
Edit on GitHub

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close