copilot-sdk について
GitHub Copilot SDK は、Copilot CLI のエージェント実行環境をアプリケーションに組み込む SDK です。Python、TypeScript、Go、.NET で AI ワークフローを構築する開発者向けに、セッション、ストリーミング、カスタムツール、エージェントを提供します。
主な機能
- 014言語向けの SDK
- 02永続セッションの作成と再開
- 03ストリーミング応答とイベント処理
- 04カスタムツールとエージェントの定義
- 05システムメッセージとツール権限の設定
活用シーン
- 01Copilot エージェントのワークフローをアプリに組み込む
- 02複数ターンの会話とストリーミング出力の実装
- 03エージェントへのカスタムツールの提供
- 04GitHub MCP サーバー経由でリポジトリ、Issue、PR のツールを利用
MCP 対応
セッション設定で MCP サーバーに接続し、事前構築されたツールを利用できます。例では GitHub の MCP サーバーへの HTTP 接続を示しています。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ hoodini/ ai-agents-skills --skill copilot-sdkインストール後、Claude Code で/copilot-sdkを入力して読み込まれたか確認します。
詳細
GitHub Copilot SDK
Python、TypeScript、Go、または .NET を使用して、あらゆるアプリケーションに Copilot のエージェント型ワークフローを組み込めます。
概要
GitHub Copilot SDK は、Copilot CLI の背後にあるものと同じエンジンを公開します。これは、本番環境でテスト済みのエージェントランタイムで、プログラムから呼び出せます。独自のオーケストレーションを構築する必要はありません。エージェントの動作を定義すれば、計画、ツールの呼び出し、ファイルの編集などは Copilot が処理します。
前提条件
- GitHub Copilot CLI がインストールされ、認証済みであること(インストールガイド)
- 言語ランタイム:Node.js 18 以降、Python 3.8 以降、Go 1.21 以降、または .NET 8.0 以降
CLI を確認します:copilot --version
インストール
Node.js/TypeScript
mkdir copilot-demo && cd copilot-demo
npm init -y --init-type module
npm install @github/copilot-sdk tsx
Python
pip install github-copilot-sdk
Go
mkdir copilot-demo && cd copilot-demo
go mod init copilot-demo
go get github.com/github/copilot-sdk/go
.NET
dotnet new console -n CopilotDemo && cd CopilotDemo
dotnet add package GitHub.Copilot.SDK
クイックスタート
TypeScript
import { CopilotClient } from "@github/copilot-sdk";
const client = new CopilotClient();
const session = await client.createSession({ model: "gpt-4.1" });
const response = await session.sendAndWait({ prompt: "What is 2 + 2?" });
console.log(response?.data.content);
await client.stop();
process.exit(0);
実行:npx tsx index.ts
Python
import asyncio
from copilot import CopilotClient
async def main():
client = CopilotClient()
await client.start()
session = await client.create_session({"model": "gpt-4.1"})
response = await session.send_and_wait({"prompt": "What is 2 + 2?"})
print(response.data.content)
await client.stop()
asyncio.run(main())
Go
package main
import (
"fmt"
"log"
"os"
copilot "github.com/github/copilot-sdk/go"
)
func main() {
client := copilot.NewClient(nil)
if err := client.Start(); err != nil {
log.Fatal(err)
}
defer client.Stop()
session, err := client.CreateSession(&copilot.SessionConfig{Model: "gpt-4.1"})
if err != nil {
log.Fatal(err)
}
response, err := session.SendAndWait(copilot.MessageOptions{Prompt: "What is 2 + 2?"}, 0)
if err != nil {
log.Fatal(err)
}
fmt.Println(*response.Data.Content)
os.Exit(0)
}
.NET (C#)
using GitHub.Copilot.SDK;
await using var client = new CopilotClient();
await using var session = await client.CreateSessionAsync(new SessionConfig { Model = "gpt-4.1" });
var response = await session.SendAndWaitAsync(new MessageOptions { Prompt = "What is 2 + 2?" });
Console.WriteLine(response?.Data.Content);
実行:dotnet run
ストリーミング応答
より優れた UX を実現するため、リアルタイム出力を有効にします。
TypeScript
import { CopilotClient, SessionEvent } from "@github/copilot-sdk";
const client = new CopilotClient();
const session = await client.createSession({
model: "gpt-4.1",
streaming: true,
});
session.on((event: SessionEvent) => {
if (event.type === "assistant.message_delta") {
process.stdout.write(event.data.deltaContent);
}
if (event.type === "session.idle") {
console.log(); // New line when done
}
});
await session.sendAndWait({ prompt: "Tell me a short joke" });
await client.stop();
process.exit(0);
Python
import asyncio
import sys
from copilot import CopilotClient
from copilot.generated.session_events import SessionEventType
async def main():
client = CopilotClient()
await client.start()
session = await client.create_session({
"model": "gpt-4.1",
"streaming": True,
})
def handle_event(event):
if event.type == SessionEventType.ASSISTANT_MESSAGE_DELTA:
sys.stdout.write(event.data.delta_content)
sys.stdout.flush()
if event.type == SessionEventType.SESSION_IDLE:
print()
session.on(handle_event)
await session.send_and_wait({"prompt": "Tell me a short joke"})
await client.stop()
asyncio.run(main())
Go
session, err := client.CreateSession(&copilot.SessionConfig{
Model: "gpt-4.1",
Streaming: true,
})
session.On(func(event copilot.SessionEvent) {
if event.Type == "assistant.message_delta" {
fmt.Print(*event.Data.DeltaContent)
}
if event.Type == "session.idle" {
fmt.Println()
}
})
_, err = session.SendAndWait(copilot.MessageOptions{Prompt: "Tell me a short joke"}, 0)
.NET
await using var session = await client.CreateSessionAsync(new SessionConfig
{
Model = "gpt-4.1",
Streaming = true,
});
session.On(ev =>
{
if (ev is AssistantMessageDeltaEvent deltaEvent)
Console.Write(deltaEvent.Data.DeltaContent);
if (ev is SessionIdleEvent)
Console.WriteLine();
});
await session.SendAndWaitAsync(new MessageOptions { Prompt = "Tell me a short joke" });
カスタムツール
推論中に Copilot が呼び出せるツールを定義します。ツールを定義するときは、Copilot に次の内容を伝えます。
- ツールの機能(説明)
- 必要なパラメーター(スキーマ)
- 実行するコード(ハンドラー)
TypeScript (JSON Schema)
import { CopilotClient, defineTool, SessionEvent } from "@github/copilot-sdk";
const getWeather = defineTool("get_weather", {
description: "Get the current weather for a city",
parameters: {
type: "object",
properties: {
city: { type: "string", description: "The city name" },
},
required: ["city"],
},
handler: async (args: { city: string }) => {
const { city } = args;
// In a real app, call a weather API here
const conditions = ["sunny", "cloudy", "rainy", "partly cloudy"];
const temp = Math.floor(Math.random() * 30) + 50;
const condition = conditions[Math.floor(Math.random() * conditions.length)];
return { city, temperature: `${temp}°F`, condition };
},
});
const client = new CopilotClient();
const session = await client.createSession({
model: "gpt-4.1",
streaming: true,
tools: [getWeather],
});
session.on((event: SessionEvent) => {
if (event.type === "assistant.message_delta") {
process.stdout.write(event.data.deltaContent);
}
});
await session.sendAndWait({
prompt: "What's the weather like in Seattle and Tokyo?",
});
await client.stop();
process.exit(0);
Python (Pydantic)
import asyncio
import random
import sys
from copilot import CopilotClient
from copilot.tools import define_tool
from copilot.generated.session_events import SessionEventType
from pydantic import BaseModel, Field
class GetWeatherParams(BaseModel):
city: str = Field(description="The name of the city to get weather for")
@define_tool(description="Get the current weather for a city")
async def get_weather(params: GetWeatherParams) -> dict:
city = params.city
conditions = ["sunny", "cloudy", "rainy", "partly cloudy"]
temp = random.randint(50, 80)
condition = random.choice(conditions)
return {"city": city, "temperature": f"{temp}°F", "condition": condition}
async def main():
client = CopilotClient()
await client.start()
session = await client.create_session({
"model": "gpt-4.1",
"streaming": True,
"tools": [get_weather],
})
def handle_event(event):
if event.type == SessionEventType.ASSISTANT_MESSAGE_DELTA:
sys.stdout.write(event.data.delta_content)
sys.stdout.flush()
session.on(handle_event)
await session.send_and_wait({
"prompt": "What's the weather like in Seattle and Tokyo?"
})
await client.stop()
asyncio.run(main())
Go
type WeatherParams struct {
City string `json:"city" jsonschema:"The city name"`
}
type WeatherResult struct {
City string `json:"city"`
Temperature string `json:"temperature"`
Condition string `json:"condition"`
}
getWeather := copilot.DefineTool(
"get_weather",
"Get the current weather for a city",
func(params WeatherParams, inv copilot.ToolInvocation) (WeatherResult, error) {
conditions := []string{"sunny", "cloudy", "rainy", "partly cloudy"}
temp := rand.Intn(30) + 50
condition := conditions[rand.Intn(len(conditions))]
return WeatherResult{
City: params.City,
Temperature: fmt.Sprintf("%d°F", temp),
Condition: condition,
}, nil
},
)
session, _ := client.CreateSession(&copilot.SessionConfig{
Model: "gpt-4.1",
Streaming: true,
Tools: []copilot.Tool{getWeather},
})
.NET (Microsoft.Extensions.AI)
using GitHub.Copilot.SDK;
using Microsoft.Extensions.AI;
using System.ComponentModel;
var getWeather = AIFunctionFactory.Create(
([Description("The city name")] string city) =>
{
var conditions = new[] { "sunny", "cloudy", "rainy", "partly cloudy" };
var temp = Random.Shared.Next(50, 80);
var condition = conditions[Random.Shared.Next(conditions.Length)];
return new { city, temperature = $"{temp}°F", condition };
},
"get_weather",
"Get the current weather for a city"
);
await using var session = await client.CreateSessionAsync(new SessionConfig
{
Model = "gpt-4.1",
Streaming = true,
Tools = [getWeather],
});
ツールの仕組み
Copilot がツールを呼び出すことを決定すると、次のように処理されます。
- Copilot がパラメーター付きのツール呼び出しリクエストを送信します
- SDK がハンドラー関数を実行します
- 結果が Copilot に返されます
- Copilot がその結果を応答に反映します
Copilot は、ユーザーの質問とツールの説明に基づいて、ツールを呼び出すタイミングを決定します。
対話型 CLI アシスタント
完全な対話型アシスタントを構築します。
TypeScript
import { CopilotClient, defineTool, SessionEvent } from "@github/copilot-sdk";
import * as readline from "readline";
const getWeather = defineTool("get_weather", {
description: "Get the current weather for a city",
parameters: {
type: "object",
properties: {
city: { type: "string", description: "The city name" },
},
required: ["city"],
},
handler: async ({ city }) => {
const conditions = ["sunny", "cloudy", "rainy", "partly cloudy"];
const temp = Math.floor(Math.random() * 30) + 50;
const condition = conditions[Math.floor(Math.random() * conditions.length)];
return { city, temperature: `${temp}°F`, condition };
},
});
const client = new CopilotClient();
const session = await client.createSession({
model: "gpt-4.1",
streaming: true,
tools: [getWeather],
});
session.on((event: SessionEvent) => {
if (event.type === "assistant.message_delta") {
process.stdout.write(event.data.deltaContent);
}
});
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
console.log("Weather Assistant (type 'exit' to quit)");
console.log("Try: 'What's the weather in Paris?'\n");
const prompt = () => {
rl.question("You: ", async (input) => {
if (input.toLowerCase() === "exit") {
await client.stop();
rl.close();
return;
}
process.stdout.write("Assistant: ");
await session.sendAndWait({ prompt: input });
console.log("\n");
prompt();
});
};
prompt();
Python
import asyncio
import random
import sys
from copilot import CopilotClient
from copilot.tools import define_tool
from copilot.generated.session_events import SessionEventType
from pydantic import BaseModel, Field
class GetWeatherParams(BaseModel):
city: str = Field(description="The name of the city to get weather for")
@define_tool(description="Get the current weather for a city")
async def get_weather(params: GetWeatherParams) -> dict:
conditions = ["sunny", "cloudy", "rainy", "partly cloudy"]
temp = random.randint(50, 80)
condition = random.choice(conditions)
return {"city": params.city, "temperature": f"{temp}°F", "condition": condition}
async def main():
client = CopilotClient()
await client.start()
session = await client.create_session({
"model": "gpt-4.1",
"streaming": True,
"tools": [get_weather],
})
def handle_event(event):
if event.type == SessionEventType.ASSISTANT_MESSAGE_DELTA:
sys.stdout.write(event.data.delta_content)
sys.stdout.flush()
session.on(handle_event)
print("Weather Assistant (type 'exit' to quit)")
print("Try: 'What's the weather in Paris?'\n")
while True:
try:
user_input = input("You: ")
except EOFError:
break
if user_input.lower() == "exit":
break
sys.stdout.write("Assistant: ")
await session.send_and_wait({"prompt": user_input})
print("\n")
await client.stop()
asyncio.run(main())
MCP サーバーとの統合
事前に構築されたツールを利用するため、MCP(Model Context Protocol)サーバーに接続します。リポジトリ、issue、PR にアクセスするには、GitHub の MCP サーバーに接続します。
TypeScript
const session = await client.createSession({
model: "gpt-4.1",
mcpServers: {
github: {
type: "http",
url: "https://api.githubcopilot.com/mcp/",
},
},
});
Python
session = await client.create_session({
"model": "gpt-4.1",
"mcp_servers": {
"github": {
"type": "http",
"url": "https://api.githubcopilot.com/mcp/",
},
},
})
Go
session, _ := client.CreateSession(&copilot.SessionConfig{
Model: "gpt-4.1",
MCPServers: map[string]copilot.MCPServerConfig{
"github": {
Type: "http",
URL: "https://api.githubcopilot.com/mcp/",
},
},
})
.NET
await using var session = await client.CreateSessionAsync(new SessionConfig
{
Model = "gpt-4.1",
McpServers = new Dictionary<string, McpServerConfig>
{
["github"] = new McpServerConfig
{
Type = "http",
Url = "https://api.githubcopilot.com/mcp/",
},
},
});
カスタムエージェント
特定のタスク向けに、専門化された AI ペルソナを定義します。
TypeScript
const session = await client.createSession({
model: "gpt-4.1",
customAgents: [{
name: "pr-reviewer",
displayName: "PR Reviewer",
description: "Reviews pull requests for best practices",
prompt: "You are an expert code reviewer. Focus on security, performance, and maintainability.",
}],
});
Python
session = await client.create_session({
"model": "gpt-4.1",
"custom_agents": [{
"name": "pr-reviewer",
"display_name": "PR Reviewer",
"description": "Reviews pull requests for best practices",
"prompt": "You are an expert code reviewer. Focus on security, performance, and maintainability.",
}],
})
システムメッセージ
AI の動作とパーソナリティをカスタマイズします。
TypeScript
const session = await client.createSession({
model: "gpt-4.1",
systemMessage: {
content: "You are a helpful assistant for our engineering team. Always be concise.",
},
});
Python
session = await client.create_session({
"model": "gpt-4.1",
"system_message": {
"content": "You are a helpful assistant for our engineering team. Always be concise.",
},
})
外部 CLI サーバー
CLI をサーバーモードで別途実行し、SDK を接続します。デバッグ、リソースの共有、カスタム環境に役立ちます。
CLI をサーバーモードで起動する
copilot --server --port 4321
SDK を外部サーバーに接続する
TypeScript
const client = new CopilotClient({
cliUrl: "localhost:4321"
});
const session = await client.createSession({ model: "gpt-4.1" });
Python
client = CopilotClient({
"cli_url": "localhost:4321"
})
await client.start()
session = await client.create_session({"model": "gpt-4.1"})
Go
client := copilot.NewClient(&copilot.ClientOptions{
CLIUrl: "localhost:4321",
})
if err := client.Start(); err != nil {
log.Fatal(err)
}
session, _ := client.CreateSession(&copilot.SessionConfig{Model: "gpt-4.1"})
.NET
using var client = new CopilotClient(new CopilotClientOptions
{
CliUrl = "localhost:4321"
});
await using var session = await client.CreateSessionAsync(new SessionConfig { Model = "gpt-4.1" });
注: cliUrl を指定すると、SDK は CLI プロセスを起動または管理せず、既存のサーバーに接続するだけです。
イベントの種類
| イベント | 説明 |
|---|---|
user.message | ユーザー入力が追加されました |
assistant.message | モデルからの完全な応答 |
assistant.message_delta | ストリーミング応答のチャンク |
assistant.reasoning | モデルの推論(モデルに依存) |
assistant.reasoning_delta | ストリーミング推論のチャンク |
tool.execution_start | ツールの呼び出しが開始されました |
tool.execution_complete | ツールの実行が完了しました |
session.idle | 処理中の項目はありません |
session.error | エラーが発生しました |
クライアントの設定
| オプション | 説明 | デフォルト |
|---|---|---|
cliPath | Copilot CLI 実行ファイルのパス | システム PATH |
cliUrl | 既存のサーバーに接続(例:「localhost:4321」) | なし |
port | サーバー通信用ポート | ランダム |
useStdio | TCP の代わりに stdio トランスポートを使用 | true |
logLevel | ログの詳細度 | "info" |
autoStart | サーバーを自動的に起動 | true |
autoRestart | クラッシュ時に再起動 | true |
cwd | CLI プロセスの作業ディレクトリ | 継承 |
セッション設定
| オプション | 説明 |
|---|---|
model | 使用する LLM(「gpt-4.1」、「claude-sonnet-4.5」など) |
sessionId | カスタムセッション識別子 |
tools | カスタムツール定義 |
mcpServers | MCP サーバー接続 |
customAgents | カスタムエージェントのペルソナ |
systemMessage | デフォルトのシステムプロンプトを上書き |
streaming | 応答チャンクの逐次送信を有効化 |
availableTools | 使用を許可するツールのホワイトリスト |
excludedTools | 無効にするツールのブラックリスト |
セッションの永続化
再起動をまたいで会話を保存し、再開できます。
カスタム ID で作成
const session = await client.createSession({
sessionId: "user-123-conversation",
model: "gpt-4.1"
});
セッションを再開
const session = await client.resumeSession("user-123-conversation");
await session.send({ prompt: "What did we discuss earlier?" });
セッションの一覧表示と削除
const sessions = await client.listSessions();
await client.deleteSession("old-session-id");
エラー処理
try {
const client = new CopilotClient();
const session = await client.createSession({ model: "gpt-4.1" });
const response = await session.sendAndWait(
{ prompt: "Hello!" },
30000 // timeout in ms
);
} catch (error) {
if (error.code === "ENOENT") {
console.error("Copilot CLI not installed");
} else if (error.code === "ECONNREFUSED") {
console.error("Cannot connect to Copilot server");
} else {
console.error("Error:", error.message);
}
} finally {
await client.stop();
}
安全なシャットダウン
process.on("SIGINT", async () => {
console.log("Shutting down...");
await client.stop();
process.exit(0);
});
よく使われるパターン
複数ターンの会話
const session = await client.createSession({ model: "gpt-4.1" });
await session.sendAndWait({ prompt: "My name is Alice" });
await session.sendAndWait({ prompt: "What's my name?" });
// Response: "Your name is Alice"
ファイル添付
await session.send({
prompt: "Analyze this file",
attachments: [{
type: "file",
path: "./data.csv",
displayName: "Sales Data"
}]
});
長時間処理の中断
const timeoutId = setTimeout(() => {
session.abort();
}, 60000);
session.on((event) => {
if (event.type === "session.idle") {
clearTimeout(timeoutId);
}
});
利用可能なモデル
実行時に利用可能なモデルを取得します。
const models = await client.getModels();
// Returns: ["gpt-4.1", "gpt-4o", "claude-sonnet-4.5", ...]
ベストプラクティス
- 必ずクリーンアップする:
try-finallyまたはdeferを使用し、client.stop()が呼び出されるようにします - タイムアウトを設定する:長時間の処理では、タイムアウトを指定して
sendAndWaitを使用します - イベントを処理する:堅牢なエラー処理のため、エラーイベントを購読します
- ストリーミングを使用する:長い応答でより良い UX を実現するため、ストリーミングを有効にします
- セッションを永続化する:複数ターンの会話では、カスタムセッション ID を使用します
- 明確なツールを定義する:説明的なツール名と説明を記述します
アーキテクチャ
Your Application
|
SDK Client
| JSON-RPC
Copilot CLI (server mode)
|
GitHub (models, auth)
SDK は CLI プロセスのライフサイクルを自動的に管理します。すべての通信は、stdio または TCP 経由の JSON-RPC で行われます。
リソース
- GitHub リポジトリ:https://github.com/github/copilot-sdk
- スタートガイドのチュートリアル:https://github.com/github/copilot-sdk/blob/main/docs/tutorials/first-app.md
- GitHub MCP サーバー:https://github.com/github/github-mcp-server
- MCP サーバーのディレクトリ:https://github.com/modelcontextprotocol/servers
- クックブック:https://github.com/github/copilot-sdk/tree/main/cookbook
- サンプル:https://github.com/github/copilot-sdk/tree/main/samples
ステータス
この SDK はテクニカルプレビュー段階であり、破壊的変更が行われる可能性があります。現時点では、本番環境での使用は推奨されません。