{"meta":{"title":"Local CLI setup","intro":"Use a specific CLI binary instead of the SDK's automatic CLI management. This is an advanced option—you supply the CLI path explicitly, and you are responsible for ensuring version compatibility with the SDK.","product":"GitHub Copilot","breadcrumbs":[{"href":"/en/copilot","title":"GitHub Copilot"},{"href":"/en/copilot/how-tos","title":"How-tos"},{"href":"/en/copilot/how-tos/copilot-sdk","title":"Copilot SDK"},{"href":"/en/copilot/how-tos/copilot-sdk/setup","title":"Set up Copilot SDK"},{"href":"/en/copilot/how-tos/copilot-sdk/setup/local-cli","title":"Local CLI"}],"documentType":"article"},"body":"# Local CLI setup\n\nUse a specific CLI binary instead of the SDK's automatic CLI management. This is an advanced option—you supply the CLI path explicitly, and you are responsible for ensuring version compatibility with the SDK.\n\n<!-- markdownlint-disable GHD046 GHD005 -->\n\n<!-- Suppressed: GHD046 (outdated release terminology), GHD005 (hardcoded data variable) -->\n\n**Use when:** You need to pin a specific CLI version, or work with the Go SDK (which does not include a CLI automatically).\n\n## How it works\n\nBy default, the Node.js, Python, and .NET SDKs include their own CLI dependency (see [Default setup (bundled CLI)](/en/copilot/how-tos/copilot-sdk/setup/bundled-cli)). If you need to override this—for example, to use a system-installed CLI—you can use the `Connection` option.\n\n![Diagram: Flowchart showing the described process.](/assets/images/help/copilot/copilot-sdk/setup-local-cli-diagram-0.png)\n\n**Key characteristics:**\n\n* You explicitly provide the CLI binary path\n* You are responsible for CLI version compatibility with the SDK\n* Authentication uses the signed-in user's credentials from the system keychain (or env vars)\n* Communication happens over stdio\n\n## Configuration\n\n### Using a local CLI binary\n\n<div class=\"ghd-codetabs\">\n<div class=\"ghd-codetab\" data-lang=\"typescript\" data-label=\"TypeScript\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">TypeScript</div>\n\n```typescript\nimport { CopilotClient } from \"@github/copilot-sdk\";\n\nconst client = new CopilotClient({\n    cliPath: \"/usr/local/bin/copilot\",\n});\n\nconst session = await client.createSession({ model: \"gpt-5.4\" });\nconst response = await session.sendAndWait({ prompt: \"Hello!\" });\nconsole.log(response?.data.content);\n\nawait client.stop();\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"python\" data-label=\"Python\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Python</div>\n\n```python\nfrom copilot import CopilotClient\nfrom copilot.session_events import AssistantMessageData\nfrom copilot.session import PermissionHandler\n\nclient = CopilotClient({\n    \"cli_path\": \"/usr/local/bin/copilot\",\n})\nawait client.start()\n\nsession = await client.create_session(on_permission_request=PermissionHandler.approve_all, model=\"gpt-5.4\")\nresponse = await session.send_and_wait(\"Hello!\")\nif response:\n    match response.data:\n        case AssistantMessageData() as data:\n            print(data.content)\n\nawait client.stop()\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"go\" data-label=\"Go\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Go</div>\n\n> \\[!NOTE]\n> The Go SDK does not ship a CLI automatically. Install `copilot` on `PATH`, set the `COPILOT_CLI_PATH` environment variable, embed a CLI with the [bundler tool](https://github.com/github/copilot-sdk/tree/main/go/README.md#distributing-your-application-with-an-embedded-github-copilot-cli), or point `StdioConnection.Path` at an installed binary.\n\n```golang\nclient := copilot.NewClient(&copilot.ClientOptions{\n    Connection: copilot.StdioConnection{Path: \"/usr/local/bin/copilot\"},\n})\nif err := client.Start(ctx); err != nil {\n    log.Fatal(err)\n}\ndefer client.Stop()\n\nsession, _ := client.CreateSession(ctx, &copilot.SessionConfig{Model: \"gpt-5.4\"})\nresponse, _ := session.SendAndWait(ctx, copilot.MessageOptions{Prompt: \"Hello!\"})\nif response != nil {\n    if d, ok := response.Data.(*copilot.AssistantMessageData); ok {\n        fmt.Println(d.Content)\n    }\n}\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"dotnet\" data-label=\".NET\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">.NET</div>\n\n```csharp\nvar client = new CopilotClient(new CopilotClientOptions\n{\n    Connection = RuntimeConnection.ForStdio(path: \"/usr/local/bin/copilot\"),\n});\n\nawait using var session = await client.CreateSessionAsync(\n    new SessionConfig { Model = \"gpt-5.4\" });\n\nvar response = await session.SendAndWaitAsync(\n    new MessageOptions { Prompt = \"Hello!\" });\nConsole.WriteLine(response?.Data.Content);\n```\n\n</div>\n\n</div>\n\n## Additional options\n\n```typescript\nconst client = new CopilotClient({\n    cliPath: \"/usr/local/bin/copilot\",\n\n    // Set log level for debugging\n    logLevel: \"debug\",\n\n    // Pass extra CLI arguments\n    cliArgs: [\"--log-dir=/tmp/copilot-logs\"],\n\n    // Set working directory\n    cwd: \"/path/to/project\",\n});\n```\n\n## Using environment variables\n\nInstead of the keychain, you can authenticate via environment variables. This is useful for CI or when you don't want interactive login.\n\n```bash\n# Set one of these (in priority order):\nexport COPILOT_GITHUB_TOKEN=\"gho_xxxx\"   # Recommended\nexport GH_TOKEN=\"gho_xxxx\"               # GitHub CLI compatible\nexport GITHUB_TOKEN=\"gho_xxxx\"           # GitHub Actions compatible\n```\n\nThe SDK picks these up automatically—no code changes needed.\n\n## Managing sessions\n\nSessions default to ephemeral. To create resumable sessions, provide your own session ID:\n\n```typescript\n// Create a named session\nconst session = await client.createSession({\n    sessionId: \"my-project-analysis\",\n    model: \"gpt-5.4\",\n});\n\n// Later, resume it\nconst resumed = await client.resumeSession(\"my-project-analysis\");\n```\n\nSession state is stored locally at `~/.copilot/session-state/{sessionId}/`.\n\n## Limitations\n\n| Limitation                | Details                                                     |\n| ------------------------- | ----------------------------------------------------------- |\n| **Version compatibility** | You must ensure your CLI version is compatible with the SDK |\n| **Single user**           | Credentials are tied to whoever signed in to the CLI        |\n| **Local only**            | The CLI runs on the same machine as your app                |\n| **No multi-tenant**       | Can't serve multiple users from one CLI instance            |\n\n## Next steps\n\n* **[Default setup (bundled CLI)](/en/copilot/how-tos/copilot-sdk/setup/bundled-cli)**: Use the SDK's built-in CLI (recommended for most use cases)\n* **[Build your first Copilot-powered app](/en/copilot/how-tos/copilot-sdk/getting-started)**: Build a complete interactive app\n* **[Authentication](/en/copilot/how-tos/copilot-sdk/auth/authenticate)**: All auth methods in detail"}