skills/copilot-sdk-dotnet/SKILL.md
Build applications with GitHub Copilot CLI SDKs for .NET. Use for direct CopilotClient integration or Microsoft Agent Framework. Covers sessions, streaming, tools, MCP, permissions, and multi-agent workflows.
npx skillsauth add arisng/github-copilot-fc copilot-sdk-dotnetInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Use this skill to guide SDK integration, select appropriate APIs, and provide C# code examples. Focus on practical implementation patterns for .NET.
CopilotClient or Microsoft.Agents.AI integration.dotnet add package GitHub.Copilot.SDK (uses AIFunctionFactory and attributes)dotnet add package Microsoft.Agents.AI.GitHub.Copilot --prereleaseNote:
All SDKs communicate via JSON-RPC over stdio (default) or TCP transports.
AIFunctionFactory or manual definitions.assistant.message_delta for chunks).For .NET, use the Microsoft Agent Framework wrapper to treat Copilot as a building block in larger agentic systems.
AIAgent.AIAgent, workflows, approvals) for new orchestration code instead of building direct orchestration plumbing on top of raw session events.When users are migrating existing agent systems:
AIAgent, tools, workflows, checkpoints, approvals).See Agent Framework Integration for full guide on installation, agent creation, and multi-agent orchestration.
await using var client = new CopilotClient();Common options:
CliPath: Custom CLI binary path (default: auto-detect)LogLevel: "none", "error", "warning", "info", "debug", "all"AutoStart: Auto-spawn server on first use (default: true)AutoRestart: Auto-restart on crash (default: true)UseStdio: Use stdio transport (default: true)Port: TCP port (0 = random, only when useStdio is false)Cwd: Working directory for CLI processUse CliUrl to connect to existing server:
"localhost:8080", "http://127.0.0.1:9000", or just "8080"await client.StartAsync() (manual start if AutoStart is false)client.State (returns "disconnected", "connecting", "connected", "error")await client.PingAsync() (verify connectivity)await client.StopAsync() (graceful shutdown)await client.ForceStopAsync() (force stop if graceful shutdown hangs)var session = await client.CreateSessionAsync(new SessionConfig { Model = "gpt-5" });
Common options:
SessionId: Custom session identifier (optional)Model: Model to use (e.g., "gpt-5", "claude-sonnet-4.5")Streaming: Enable streaming responses (default: false)AvailableTools: Whitelist specific toolsExcludedTools: Blacklist specific toolsSystemMessage: Custom system prompt with mode ("append" or "replace")OnPermissionRequest: Permission handler functionawait client.ListSessionsAsync() (all sessions)await client.GetLastSessionIdAsync() (for resuming)await client.ResumeSessionAsync(sessionId, options) (re-open existing)await client.DeleteSessionAsync(sessionId) (permanent delete)await session.DestroyAsync() (release resources, don't delete)Subscribe before sending messages. Use session.Events (IObservable or event based):
session.Events.Subscribe(@event => {
switch (@event) {
case UserMessageEvent: // User's input
case AssistantMessageEvent: // Complete response
case AssistantMessageDeltaEvent: // Streaming chunk
case ToolExecutionStartEvent: // Tool invoked
case ToolExecutionEndEvent: // Tool completed
case SessionIdleEvent: // No activity
case SessionErrorEvent: // Error occurred
}
});
Synchronous (wait for completion):
var response = await session.SendAndWaitAsync(new MessageOptions {
Prompt = "Your question",
Attachments = [/* optional files/dirs */]
}, TimeSpan.FromSeconds(60)); // Optional timeout
Asynchronous (non-blocking, event-driven):
var messageId = await session.SendAsync(new MessageOptions {
Prompt = "Long task",
Mode = MessageMode.Enqueue // or Immediate
});
Support two types:
Attachments = [
new Attachment { Type = "file", Path = "/path/to/file", DisplayName = "File" },
new Attachment { Type = "directory", Path = "/path/to/dir", DisplayName = "Folder" }
]
var history = await session.GetMessagesAsync();
await session.AbortAsync();
using Microsoft.Extensions.AI;
using System.ComponentModel;
var myTool = AIFunctionFactory.Create(
async ([Description("...")] string param1) => {
// Implementation
return new { result = "..." };
},
"tool_name",
"What this tool does"
);
var session = await client.CreateSessionAsync(new SessionConfig {
Tools = new[] { myTool }
});
All languages support returning rich structured results:
{
"textResultForLlm": "Human-readable text for model",
"resultType": "success", // or "failure"
"sessionLog": "Internal diagnostic message",
"toolTelemetry": { /* structured data */ },
"error": "Error message if failure"
}
Register a permission handler to approve/deny sensitive operations. Available kinds: "shell", "write", "read", "url", "mcp".
var session = await client.CreateSessionAsync(new SessionConfig {
OnPermissionRequest = async (request, context) => {
switch (request.Kind) {
case "write":
var path = request.Properties["path"]?.ToString();
if (path?.StartsWith("/safe/") == true) {
return new PermissionRequestResult { Kind = "approved" };
}
return new PermissionRequestResult {
Kind = "denied-by-rules",
Message = "Path not allowed"
};
case "shell":
return new PermissionRequestResult { Kind = "denied-interactively-by-user" };
case "read":
return new PermissionRequestResult { Kind = "approved" };
default:
return new PermissionRequestResult {
Kind = "denied-no-approval-rule-and-could-not-request-from-user"
};
}
}
});
"approved": Allow the operation"denied-by-rules": Deny with rule explanation"denied-interactively-by-user": User denied"denied-no-approval-rule-and-could-not-request-from-user": No rule and no user interactionUse your own API keys with OpenAI, Azure OpenAI, Anthropic, or compatible providers.
var session = await client.CreateSessionAsync(new SessionConfig {
Provider = new ProviderConfig {
Type = "azure",
BaseUrl = "https://your-resource.openai.azure.com",
ApiKey = Environment.GetEnvironmentVariable("AZURE_OPENAI_KEY"),
Azure = new AzureProviderConfig { ApiVersion = "2024-10-21" }
}
});
Connect local (stdio) or remote (HTTP/SSE) MCP servers.
using GitHub.Copilot.SDK.Mcp;
var session = await client.CreateSessionAsync(new SessionConfig {
McpServers = new Dictionary<string, McpServerConfig> {
["filesystem"] = new McpLocalServerConfig {
Type = "local",
Command = "npx",
Args = ["-y", "@modelcontextprotocol/server-filesystem", "/path"],
Tools = "*"
},
["remote-api"] = new McpRemoteServerConfig {
Type = "http",
Url = "https://mcp-server.example.com/mcp",
Tools = ["search"]
}
}
});
Define specialized personas with scoped system prompts and tool access.
var session = await client.CreateSessionAsync(new SessionConfig {
CustomAgents = [
new CustomAgent {
Name = "security-reviewer",
DisplayName = "Security Reviewer",
Description = "Reviews code for vulnerabilities",
Prompt = "You are a security expert...",
Tools = ["Read", "Grep", "Glob"],
Infer = true
}
]
});
// Invoke via prompt
await session.SendAndWaitAsync(new MessageOptions {
Prompt = "@security-reviewer Review src/auth.cs"
});
await using var client = new CopilotClient();
await client.StartAsync();
await using var session = await client.CreateSessionAsync(new SessionConfig { Model = "gpt-5" });
var response = await session.SendAndWaitAsync(new MessageOptions { Prompt = "Your question" });
Console.WriteLine(response.Data.Content);
var session = await client.CreateSessionAsync(new SessionConfig {
Model = "gpt-5",
Streaming = true
});
session.Events.Subscribe(@event => {
if (@event is AssistantMessageDeltaEvent delta) {
Console.Write(delta.DeltaContent);
}
});
await session.SendAndWaitAsync(new MessageOptions { Prompt = "Write a story" });
var session = await client.CreateSessionAsync(new SessionConfig {
Tools = new[] { myTool }
});
session.Events.Subscribe(@event => {
if (@event is ToolExecutionStartEvent start) {
Console.WriteLine($"Tool {start.ToolName} started");
}
});
await session.SendAndWaitAsync(new MessageOptions { Prompt = "Use the tool" });
await session.SendAndWaitAsync(new MessageOptions {
Prompt = "Analyze this code",
Attachments = [
new Attachment { Type = "file", Path = "./src/Program.cs", DisplayName = "Main" }
]
});
Choose the provider once during session creation.
The GitHub Copilot ecosystem comprises multiple distinct products, each serving different use cases and contexts. Understanding the boundaries between them is essential for choosing the right tool and understanding SDK capabilities.
| Product | Alias | Description | Execution Context | Primary Interface | Key Use Cases | | ---------------------------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | ------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- | | Copilot in VS Code | Copilot VS Code | GitHub Copilot integrated into Visual Studio Code IDE. Provides chat, inline suggestions, and agent mode for autonomous edits in local development environment. | Local machine (developer's computer) | VS Code editor window | Interactive coding assistance, pair programming, quick fixes, IDE-native automation | | Copilot in GitHub Mobile | Copilot Mobile | GitHub Copilot accessible via GitHub Mobile app on iOS/Android. Limited to chat-based assistance. | Cloud-side processing | GitHub Mobile app | Quick questions, code review assistance on the go, mobile browsing context | | Copilot in GitHub Web | Copilot Web | GitHub Copilot accessible via GitHub.com web interface. Provides chat and integration with GitHub issues, pull requests, and repository context. | Cloud-side processing | GitHub.com web UI (pull requests, issues, code view) | Pull request assistance, issue triage, repository questions, web-based workflows | | Copilot in CLI | Copilot CLI | Standalone command-line interface to GitHub Copilot. Interactive shell mode for prompt-based assistance with file system access and terminal commands. | Local machine (terminal) | Terminal/shell command line | Terminal automation, scripting assistance, local file operations, batch workflows | | Copilot CLI SDK | Copilot SDK | Programmatic SDKs (Node.js/TypeScript, Python, Go, .NET) for integrating GitHub Copilot into applications. Provides low-level APIs for session management, streaming, custom tools, and MCP integration. | Local machine or application runtime | Application code (embedded programmatically) | Application-level AI integration, custom tool development, embedded conversational AI, multi-language app development | | Copilot Coding Agent | Copilot Agent | Autonomous background agent that works on GitHub to complete development tasks. Creates pull requests independently based on issues or chat prompts. Runs in GitHub Actions environment. | GitHub cloud infrastructure (GitHub Actions) | GitHub Issues, Pull Requests, GitHub Chat, CLI, Third-party integrations | Autonomous bug fixes, feature implementation, test coverage, documentation updates, technical debt resolution |
streaming: trueautoRestart: false to prevent auto-recoverycliPathexcludedTools)streaming: true in session config and subscribed to assistant.message_deltatimeout is sufficientsessionId was preserved and matches existing sessiondevops
Programmatically create tldraw whiteboards and visualize them with a self-hosted tldraw instance. Create boards with shapes, text, and connectors, then deploy to a self-hosted server for collaborative editing and gallery management.
tools
Execute Google Cloud Platform operations using the gcloud CLI (and gsutil/bq where applicable). Use when the user wants to: authenticate with GCP, manage GCP resources, deploy applications, configure projects or IAM, view logs, run SQL/BigQuery, or interact with any GCP service from the command line. Triggers on phrases like "gcloud", "Google Cloud CLI", "deploy to GCP", "create a VM", "Cloud Run", "GKE cluster", "Cloud Storage bucket", "set GCP project", "service account", "Cloud Functions", "App Engine deploy", or any request to manage Google Cloud resources via command line.
testing
Grilling session that challenges your plan against the existing domain model, sharpens terminology, and updates documentation (CONTEXT.md, ADRs) inline as decisions crystallise. Use when user wants to stress-test a plan against their project's language and documented decisions.
development
Session-scoped git commit orchestrator that commits only current-session changes and leaves unrelated dirty worktree edits untouched. Inherits git-atomic-commit for atomic grouping and commit message execution, and git-commit-scope-constitution for scope governance and validation. Use when asked to commit this session only or isolate commits from mixed worktree state.