Meilleur pour : Back-ends d’application web, services API, outils internes, intégrations CI/CD, n’importe quelle charge de travail côté serveur.
Fonctionnement
Au lieu du SDK qui génère un processus enfant CLI, vous exécutez l’interface CLI indépendamment en mode serveur sans tête. Votre back-end se connecte à celui-ci via TCP à l’aide de l’option Connection (UriConnection).

Principales caractéristiques :
- L’interface CLI s’exécute en tant que processus de serveur persistant (non généré par requête)
- Le SDK se connecte via TCP : l’interface CLI et l’application peuvent s’exécuter dans différents conteneurs
- Plusieurs clients du Kit de développement logiciel (SDK) peuvent partager un serveur CLI
- Fonctionne avec n’importe quelle méthode d’authentification (GitHub jetons, env vars, BYOK)
Architecture : gérée automatiquement par rapport à l’interface CLI externe

Étape 1 : démarrer l’interface CLI en mode sans tête
Exécutez l’interface CLI en tant que serveur en arrière-plan :
# Start with a specific port
copilot --headless --port 4321
# Or let it pick a random port (prints the URL)
copilot --headless
# Output: Listening on http://localhost:52431
Par défaut, le serveur headless accepte uniquement les connexions depuis loopback (127.0.0.1). Pour accepter les connexions à partir d’autres hôtes, par exemple à partir d’un autre ordinateur sur votre réseau, liez-vous à une adresse de non-bouclage avec --host:
copilot --headless --host 0.0.0.0 --port 4321
Pour la production, exécutez-le en tant que service système ou dans un conteneur.
Remarque
Il n’existe aucune image Docker prédéfinie officielle pour l’interface CLI Copilot. Vous pouvez créer votre propre version à partir des versions GitHub :
FROM debian:bookworm-slim
ARG COPILOT_VERSION=1.0.7
RUN apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates wget \
&& ARCH=$(dpkg --print-architecture) \
&& case "${ARCH}" in amd64) COPILOT_ARCH="x64" ;; arm64) COPILOT_ARCH="arm64" ;; *) echo "Unsupported: ${ARCH}" && exit 1 ;; esac \
&& wget -q "https://github.com/github/copilot-cli/releases/download/v${COPILOT_VERSION}/copilot-linux-${COPILOT_ARCH}.tar.gz" \
&& tar -xzf "copilot-linux-${COPILOT_ARCH}.tar.gz" \
&& mv copilot /usr/local/bin/ \
&& rm "copilot-linux-${COPILOT_ARCH}.tar.gz" \
&& apt-get purge -y wget && apt-get autoremove -y && rm -rf /var/lib/apt/lists/*
ENTRYPOINT ["copilot"]
# Build the image
docker build --build-arg COPILOT_VERSION=1.0.7 -t copilot-cli:latest .
# For remote deployments (Kubernetes, ACI, etc.), push to your registry
docker tag copilot-cli:latest your-registry/copilot-cli:latest
docker push your-registry/copilot-cli:latest
# Docker — must bind to 0.0.0.0 so the container's published port is reachable
docker run -d --name copilot-cli \
-p 4321:4321 \
-e COPILOT_GITHUB_TOKEN="$TOKEN" \
copilot-cli:latest \
--headless --host 0.0.0.0 --port 4321
# systemd
[Service]
ExecStart=/usr/local/bin/copilot --headless --port 4321
Environment=COPILOT_GITHUB_TOKEN=your-token
Restart=always
Étape 2 : connecter le Kit de développement logiciel (SDK)
import { CopilotClient } from "@github/copilot-sdk";
const client = new CopilotClient({
cliUrl: "localhost:4321",
});
const session = await client.createSession({
sessionId: `user-${userId}-${Date.now()}`,
model: "gpt-4.1",
});
const response = await session.sendAndWait({ prompt: req.body.message });
res.json({ content: response?.data.content });
from copilot import CopilotClient, RuntimeConnection
from copilot.session import PermissionHandler
client = CopilotClient(
connection=RuntimeConnection.for_uri("localhost:4321"),
)
await client.start()
session = await client.create_session(on_permission_request=PermissionHandler.approve_all, model="gpt-4.1", session_id=f"user-{user_id}-{int(time.time())}")
response = await session.send_and_wait(message)
package main
import (
"context"
"fmt"
"time"
copilot "github.com/github/copilot-sdk/go"
)
func main() {
ctx := context.Background()
userID := "user1"
message := "Hello"
client := copilot.NewClient(&copilot.ClientOptions{
Connection: copilot.UriConnection{URL: "localhost:4321"},
})
client.Start(ctx)
defer client.Stop()
session, _ := client.CreateSession(ctx, &copilot.SessionConfig{
SessionID: fmt.Sprintf("user-%s-%d", userID, time.Now().Unix()),
Model: "gpt-4.1",
})
response, _ := session.SendAndWait(ctx, copilot.MessageOptions{Prompt: message})
_ = response
}
client := copilot.NewClient(&copilot.ClientOptions{
Connection: copilot.UriConnection{URL: "localhost:4321"},
})
client.Start(ctx)
defer client.Stop()
session, _ := client.CreateSession(ctx, &copilot.SessionConfig{
SessionID: fmt.Sprintf("user-%s-%d", userID, time.Now().Unix()),
Model: "gpt-4.1",
})
response, _ := session.SendAndWait(ctx, copilot.MessageOptions{Prompt: message})
using GitHub.Copilot;
var userId = "user1";
var message = "Hello";
var client = new CopilotClient(new CopilotClientOptions
{
Connection = RuntimeConnection.ForUri("localhost:4321"),
});
await using var session = await client.CreateSessionAsync(new SessionConfig
{
SessionId = $"user-{userId}-{DateTimeOffset.UtcNow.ToUnixTimeSeconds()}",
Model = "gpt-4.1",
});
var response = await session.SendAndWaitAsync(
new MessageOptions { Prompt = message });
var client = new CopilotClient(new CopilotClientOptions
{
Connection = RuntimeConnection.ForUri("localhost:4321"),
});
await using var session = await client.CreateSessionAsync(new SessionConfig
{
SessionId = $"user-{userId}-{DateTimeOffset.UtcNow.ToUnixTimeSeconds()}",
Model = "gpt-4.1",
});
var response = await session.SendAndWaitAsync(
new MessageOptions { Prompt = message });
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.events.*;
import com.github.copilot.sdk.json.*;
var userId = "user1";
var message = "Hello!";
var client = new CopilotClient(new CopilotClientOptions()
.setCliUrl("localhost:4321")
);
try {
client.start().get();
var session = client.createSession(new SessionConfig()
.setSessionId(String.format("user-%s-%d", userId, System.currentTimeMillis() / 1000))
.setModel("gpt-4.1")
.setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
).get();
var response = session.sendAndWait(new MessageOptions()
.setPrompt(message)).get();
} finally {
client.stop().get();
}
Authentification pour les services principaux
Jetons de variables d'environnement
L’approche la plus simple : définissez un jeton sur le serveur CLI :

# All requests use this token
export COPILOT_GITHUB_TOKEN="gho_service_account_token"
copilot --headless --port 4321
Jetons OAuth par utilisateur
Transmettez des jetons d’utilisateur individuels lors de la création de sessions. Consultez configuration de GitHub OAuth pour le flux complet.
// Your API receives user tokens from your auth layer
app.post("/chat", authMiddleware, async (req, res) => {
const client = new CopilotClient({
cliUrl: "localhost:4321",
gitHubToken: req.user.githubToken,
useLoggedInUser: false,
});
const session = await client.createSession({
sessionId: `user-${req.user.id}-chat`,
model: "gpt-4.1",
});
const response = await session.sendAndWait({
prompt: req.body.message,
});
res.json({ content: response?.data.content });
});
BYOK (aucune authentification GitHub)
Utilisez vos propres clés API pour le fournisseur de modèles. Pour plus d’informations, consultez BYOK (bring your own key).
const client = new CopilotClient({
cliUrl: "localhost:4321",
});
const session = await client.createSession({
model: "gpt-4.1",
provider: {
type: "openai",
baseUrl: "https://api.openai.com/v1",
apiKey: process.env.OPENAI_API_KEY,
},
});
Modèles courants de backend
API web avec Express

import express from "express";
import { CopilotClient } from "@github/copilot-sdk";
const app = express();
app.use(express.json());
// Single shared CLI connection
const client = new CopilotClient({
cliUrl: process.env.CLI_URL || "localhost:4321",
});
app.post("/api/chat", async (req, res) => {
const { sessionId, message } = req.body;
// Create or resume session
let session;
try {
session = await client.resumeSession(sessionId);
} catch {
session = await client.createSession({
sessionId,
model: "gpt-4.1",
});
}
const response = await session.sendAndWait({ prompt: message });
res.json({
sessionId,
content: response?.data.content,
});
});
app.listen(3000);
Travailleur en arrière-plan
import { CopilotClient } from "@github/copilot-sdk";
const client = new CopilotClient({
cliUrl: process.env.CLI_URL || "localhost:4321",
});
// Process jobs from a queue
async function processJob(job: Job) {
const session = await client.createSession({
sessionId: `job-${job.id}`,
model: "gpt-4.1",
});
const response = await session.sendAndWait({
prompt: job.prompt,
});
await saveResult(job.id, response?.data.content);
await session.disconnect(); // Clean up after job completes
}
Déploiement Docker Compose
version: "3.8"
services:
copilot-cli:
image: copilot-cli:latest # See "Step 1" above for how to build this image
command: ["--headless", "--host", "0.0.0.0", "--port", "4321"]
environment:
- COPILOT_GITHUB_TOKEN=${COPILOT_GITHUB_TOKEN}
ports:
- "4321:4321"
restart: always
volumes:
- session-data:/root/.copilot/session-state
api:
build: .
environment:
- CLI_URL=copilot-cli:4321
depends_on:
- copilot-cli
ports:
- "3000:3000"
volumes:
session-data:

Contrôles de santé
Surveillez l’intégrité du serveur CLI :
// Periodic health check
async function checkCLIHealth(): Promise<boolean> {
try {
const status = await client.getStatus();
return status !== undefined;
} catch {
return false;
}
}
Nettoyage de session
Les services principaux doivent nettoyer activement les sessions pour éviter les fuites de ressources :
// Clean up expired sessions periodically
async function cleanupSessions(maxAgeMs: number) {
const sessions = await client.listSessions();
const now = Date.now();
for (const session of sessions) {
const age = now - new Date(session.createdAt).getTime();
if (age > maxAgeMs) {
await client.deleteSession(session.sessionId);
}
}
}
// Run every hour
setInterval(() => cleanupSessions(24 * 60 * 60 * 1000), 60 * 60 * 1000);
Limitations
| Limitation | Détails |
|---|---|
| Serveur CLI unique = point de défaillance unique | Voir Mise à l’échelle et multilocation pour les modèles haute disponibilité |
| Aucune authentification intégrée entre le SDK et l’interface CLI | Sécuriser le chemin d’accès réseau (même hôte, VPC, etc.) |
| État de session sur le disque local | Monter un stockage persistant pour les redémarrages du conteneur |
| Délai d’inactivité de 30 minutes | Les sessions sans activité sont nettoyées automatiquement |
Quand se déplacer
| Besoin | Guide suivant |
|---|---|
| Serveurs CLI multiples / haute disponibilité | |
| Mise à l’échelle et multilocation | |
| Authentification du compte GitHub pour les utilisateurs | |
| configuration de GitHub OAuth | |
| Vos propres clés de modèle | |
| BYOK (bring your own key) |
Étapes suivantes
- Mise à l’échelle et multilocation : Gérer davantage d’utilisateurs, ajouter une redondance
- Reprise de session et persistance : Reprendre les sessions après le redémarrage
- configuration de GitHub OAuth : Ajouter une authentification utilisateur