How to Create a CopilotClient Instance in Your Node.js Application

To create a CopilotClient instance, import the CopilotClient class from @github/copilot-sdk and instantiate it with optional CopilotClientOptions, selecting your transport mode via the RuntimeConnection factory methods.

The github/copilot-sdk repository provides the official Node.js SDK for integrating GitHub Copilot into your applications. This guide walks through the instantiation patterns found in the source code, from basic stdio transport to advanced TCP and in-process configurations.

Importing the CopilotClient Class

The entry point for the SDK is the CopilotClient class defined in [nodejs/src/client.ts](https://github.com/github/copilot-sdk/blob/main/nodejs/src/client.ts). Before creating an instance, install the package and import the necessary constructors.

import { CopilotClient, RuntimeConnection } from "@github/copilot-sdk";

The RuntimeConnection factory, defined in [nodejs/src/types.ts](https://github.com/github/copilot-sdk/blob/main/nodejs/src/types.ts), provides static methods to configure how your client connects to the Copilot runtime.

Understanding Connection Modes

The CopilotClient constructor accepts a CopilotClientOptions object that specifies the transport mechanism. According to the source code at line 96, the constructor resolves the requested transport, validates incompatible option combinations, and stores the effective environment for later use.

Default stdio Transport (Spawn Bundled CLI)

If you provide no connection option, the client defaults to RuntimeConnection.forStdio(), which spawns the bundled CLI binary and communicates over stdio streams. This is handled by the resolveDefaultConnection logic at lines 81-86 of client.ts.

const client = new CopilotClient();

The SDK automatically locates the appropriate platform-specific package using getBundledCliPath() at lines 72-88.

TCP Connection

To spawn a runtime that listens on a TCP socket, use RuntimeConnection.forTcp(). Pass port: 0 to auto-allocate an available port.

const client = new CopilotClient({
  connection: RuntimeConnection.forTcp({ port: 9001 }),
});

URI Connection (External Server)

Connect to an already-running Copilot server by specifying a URI. This pattern is useful when managing the runtime lifecycle separately from your application.

const client = new CopilotClient({
  connection: RuntimeConnection.forUri("localhost:3000"),
});

In-Process Runtime (Experimental)

For scenarios requiring the native runtime library loaded directly into your process, use the experimental forInProcess() factory.

const client = new CopilotClient({
  connection: RuntimeConnection.forInProcess(),
});

Custom CLI Binary

Override the default bundled CLI by providing a path to a custom binary. This is useful when testing patched versions or platform-specific builds.

const client = new CopilotClient({
  connection: RuntimeConnection.forStdio({ path: "/usr/local/bin/copilot" }),
  logLevel: "debug",
});

Configuring Client Options

The CopilotClientOptions interface at lines 63-132 of types.ts defines additional configuration fields:

  • workingDirectory: Sets the runtime's startup directory.
  • baseDirectory: Overrides the default ~/.copilot data location.
  • gitHubToken: Provides explicit authentication (note: incompatible with URI connections).
  • telemetry: Configures OpenTelemetry export via otlpEndpoint.
  • sessionFs: Registers a custom session-filesystem provider.
  • logLevel: Controls debug output verbosity.
const client = new CopilotClient({
  connection: RuntimeConnection.forStdio(),
  workingDirectory: "/my/project",
  gitHubToken: process.env.COPILOT_TOKEN,
  logLevel: "debug",
});

Starting the Client and Creating Sessions

The Copilot runtime uses lazy initialization. Instantiation only prepares the connection parameters; the actual process spawn or network connection occurs when you explicitly call client.start() or implicitly via client.createSession().

The start logic performs four steps:

  1. Connection resolution – Selects transport based on the connection option or the COPILOT_SDK_DEFAULT_CONNECTION environment variable.
  2. Environment preparation – Merges client-level env with transport-level env for child-process transports.
  3. CLI binary location – Resolves the platform package path for stdio transports.
  4. Protocol handshake – Establishes the JSON-RPC connection and validates protocol versions.
async function initialize() {
  const client = new CopilotClient({
    connection: RuntimeConnection.forTcp({ port: 0 }),
    logLevel: "debug",
  });

  // Explicit start (optional - createSession() does this automatically)
  await client.start();
  
  return client;
}

Once started, create a session to interact with Copilot:

import { approveAll } from "@github/copilot-sdk";

async function run() {
  const client = await initialize();
  
  const session = await client.createSession({
    onPermissionRequest: approveAll,
    model: "gpt-4o",
  });

  await session.send({ 
    prompt: "Explain the difference between let and const in JavaScript." 
  });
}

Summary

  • Import CopilotClient and RuntimeConnection from @github/copilot-sdk to begin instantiation.
  • Choose a transport: Use forStdio() (default), forTcp(), forUri(), or forInProcess() from the RuntimeConnection factory.
  • Configure options via CopilotClientOptions to set working directories, authentication tokens, and telemetry endpoints as defined in nodejs/src/types.ts.
  • Lazy start: The runtime spawns only when you call client.start() or client.createSession(), with connection logic centralized in nodejs/src/client.ts.

Frequently Asked Questions

What happens if I don't specify a connection when creating a CopilotClient?

If no connection option is provided, the constructor defaults to RuntimeConnection.forStdio(), which spawns the bundled Copilot CLI binary and communicates over stdio streams. The SDK locates the correct binary for your platform using the getBundledCliPath() method.

Can I connect to an existing Copilot server instead of spawning a new process?

Yes. Use RuntimeConnection.forUri("host:port") in your CopilotClientOptions to connect to an external server. This is useful when the runtime is managed by an orchestrator or runs as a persistent service, though you cannot use gitHubToken authentication with URI connections according to the validation logic in the constructor.

How do I provide authentication tokens when creating a client?

Pass the gitHubToken field in your CopilotClientOptions object. The constructor stores this token at lines 122-130 for use during the RPC handshake. Note that this option is validated as incompatible with URI-based connections, which must handle authentication separately.

When should I use in-process transport versus stdio?

Use RuntimeConnection.forInProcess() when you need minimal latency by loading the native runtime library directly into your Node.js process; this is marked as experimental in the source. Use forStdio() (the default) for stability and isolation, as it spawns the CLI as a separate process with stdio-based JSON-RPC communication.

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 →