Run the Copilot CLI inside a Docker container with a simple proxy on the host that returns canned responses. This demonstrates the deployment pattern where an external service intercepts the agent's LLM calls — in production the proxy would add credentials and forward to a real provider; here it just returns a fixed reply as proof-of-concept.
Host Machine
┌──────────────────────────────────────────────────────┐
│ │
│ ┌─────────────┐ │
│ │ Your App │ TCP :3000 │
│ │ (SDK) │ ────────────────┐ │
│ └─────────────┘ │ │
│ ▼ │
│ ┌──────────────────────────┐ │
│ │ Docker Container │ │
│ │ Copilot CLI │ │
│ │ --port 3000 --headless │ │
│ │ --bind 0.0.0.0 │ │
│ │ --auth-token-env │ │
│ └────────────┬─────────────┘ │
│ │ │
│ HTTP to host.docker.internal:4000 │
│ │ │
│ ┌───────────▼──────────────┐ │
│ │ proxy.py │ │
│ │ (port 4000) │ │
│ │ Returns canned response │ │
│ └─────────────────────────-┘ │
│ │
└──────────────────────────────────────────────────────┘
The agent runtime (Copilot CLI) has no access to API keys. All LLM traffic flows through a proxy on the host. In production you would replace proxy.py with a real proxy that injects credentials and forwards to OpenAI/Anthropic/etc. This means:
- No secrets in the image — safe to share, scan, deploy anywhere
- No secrets at runtime — even if the container is compromised, there are no tokens to steal
- Swap providers freely — change the proxy target without rebuilding the container
- Centralized key management — one proxy manages keys for all your agents/services
- Docker with Docker Compose
- Python 3 (for the proxy — uses only stdlib, no pip install needed)
python3 proxy.py 4000This starts a minimal OpenAI-compatible HTTP server on port 4000 that returns a canned "The capital of France is Paris." response for every request.
docker compose up -d --buildThis builds the Copilot CLI from source and starts it on port 3000. It sends LLM requests to host.docker.internal:4000 — no API keys are passed into the container.
TypeScript
cd typescript && npm install && npm run build && npm startPython
cd python && pip install -r requirements.txt && python main.pyGo
cd go && go run main.goAll samples connect to localhost:3000 by default. Override with COPILOT_CLI_URL.
Run all samples end-to-end:
chmod +x verify.sh
./verify.sh| Directory | SDK / Approach | Language |
|---|---|---|
typescript/ |
@github/copilot-sdk |
TypeScript (Node.js) |
python/ |
github-copilot-sdk |
Python |
go/ |
github.com/github/copilot-sdk/go |
Go |
- Copilot CLI starts in Docker with
COPILOT_API_URL=http://host.docker.internal:4000— this overrides the default Copilot API endpoint to point at the proxy - When the agent needs to call an LLM, it sends a standard OpenAI-format request to the proxy
- proxy.py receives the request and returns a canned response (in production, this would inject credentials and forward to a real provider)
- The response flows back: proxy → Copilot CLI → your app
The container never sees or needs any API credentials.