Building Custom AI Tooling with the GitHub Copilot SDK for .NET

The landscape of AI development is shifting rapidly from simple chat interfaces to fully integrated, agentic workflows like the Ralph Loop . GitHub has recently introduced the GitHub Copilot SDK , a powerful toolkit that allows developers to programmatically harness the engine behind the GitHub Copilot CLI.

In this post, we’ll explore how to use the .NET version of the SDK to build your own custom AI tooling, enabling you to create agents that can plan, execute tools, and interact with your file system just like Copilot does.

What is the GitHub Copilot SDK?

The GitHub Copilot SDK exposes the Copilot Agent Runtime-the same intelligence that powers the Copilot CLI - as a library you can consume in your applications. This isn’t just a wrapper around an LLM API; it’s a full orchestration engine that handles:

  • Context Management: Efficiently handling large contexts and file attachments.
  • Tool Execution: Automatically calling functions (tools) when the model requests them.
  • Planning: Breaking down complex user requests into executable steps.
  • Persistence: Managing session state via “Infinite Sessions”.

It communicates with the Copilot CLI via JSON-RPC, meaning you get the full power of GitHub’s first-party agent capabilities right out of the box (which means you are better by default compared to IntelliJ :-) ).

Getting Started

To use the SDK, you’ll need:

  1. GitHub Copilot Subscription
  2. .NET 8.0 SDK or later
  3. GitHub Copilot CLI installed and available in your PATH.

Installation

Create a new console application and install the necessary packages. We’ll need the SDK main package and the Microsoft.Extensions.AI package for defining tools easily.

1dotnet new console -n MyCopilotTool
2cd MyCopilotTool
3dotnet add package GitHub.Copilot.SDK
4dotnet add package Microsoft.Extensions.AI

Your First Copilot Agent

Let’s build a simple agent that can answer questions. The core abstraction is the CopilotClient, which manages the connection to the CLI server, and CopilotSession, which represents a conversation.

Here is a basic “Hello World” example:

 1using GitHub.Copilot.SDK;
 2using System;
 3
 4// 1. Initialize and start the client
 5await using CopilotClient client = new CopilotClient();
 6await client.StartAsync();
 7
 8Console.WriteLine("Copilot Client Connected.");
 9
10// 2. Create a session
11// We specify the model we want to use (e.g., gpt-5 or claude-sonnet)
12await using CopilotSession session = await client.CreateSessionAsync(new SessionConfig
13{
14    Model = "gpt-5.2"
15});
16
17// 3. Set up an event loop to handle responses
18TaskCompletionSource tcs = new TaskCompletionSource();
19
20session.On(evt =>
21{
22    switch (evt)
23    {
24        case AssistantMessageEvent msg:
25            Console.WriteLine($"\n[Copilot]: {msg.Data.Content}");
26            break;
27
28        case SessionIdleEvent:
29            // The turn is complete
30            tcs.TrySetResult();
31            break;
32
33        case SessionErrorEvent err:
34            Console.WriteLine($"[Error]: {err.Data.Message}");
35            tcs.TrySetResult();
36            break;
37    }
38});
39
40// 4. Send a message
41Console.WriteLine("Sending request...");
42await session.SendAsync(new MessageOptions { Prompt = "Explain how you work in one sentence." });
43
44// Wait for the session to become idle again
45await tcs.Task;

This simple loop sends a prompt and prints the assistant’s response. But the real magic happens when we add Tools.

Extending Capabilities with Custom Tools

The SDK integrates beautifully with Microsoft.Extensions.AI. You can define C# functions and expose them to the AI agent. The agent will decide when to call them based on the user’s prompt.

Let’s generic a tool that simulates looking up the status of a hypothetical system.

 1using Microsoft.Extensions.AI;
 2using System.ComponentModel;
 3
 4// Define a tool method
 5[Description("Gets the current status of a specific system component")]
 6static string GetSystemStatus([Description("The component name (e.g., 'database', 'api')")] string component)
 7{
 8    // In a real app, you would check a real service
 9    return component.ToLower() switch
10    {
11        "database" => "Online - Latency 12ms",
12        "api" => "Degraded - High error rate on /v1/users",
13        _ => "Unknown component"
14    };
15}
16
17// Register the tool in the session configuration
18AIFunction[] tools = new[]
19{
20    AIFunctionFactory.Create(GetSystemStatus, "get_system_status")
21};
22
23await using CopilotSession session = await client.CreateSessionAsync(new SessionConfig
24{
25    Model = "gpt-5",
26    Tools = tools,
27    SystemMessage = new SystemMessageConfig
28    {
29        Content = "You are a system diagnostic assistant. Use tools to check status."
30    }
31});
32
33// Now ask a question that requires the tool
34await session.SendAsync(new MessageOptions
35{
36    Prompt = "Why is the user service failing?"
37});

When you run this, you will see ToolExecutionStartEvent and ToolExecutionCompleteEvent fire in your event loop. The AI will:

  1. Receive the prompt.
  2. Decide it needs to check the “api” status.
  3. Call your C# function.
  4. Read the return value (“Degraded…”).
  5. Generate a final response explaining the situation to you.

Advanced Features: Hooks and Infinite Sessions

Session Hooks

The SDK allows you to intercept nearly every part of the lifecycle. This is crucial for enterprise governance, logging, or requiring human-in-the-loop approval before executing sensitive tools.

 1SessionHooks hooks = new SessionHooks
 2{
 3    OnPreToolUse = async (input, ctx) =>
 4    {
 5        Console.WriteLine($"[Audit] Agent is trying to run: {input.ToolName}");
 6
 7        if (input.ToolName == "delete_database")
 8        {
 9            return new PreToolUseHookOutput { PermissionDecision = "deny" };
10        }
11
12        return new PreToolUseHookOutput { PermissionDecision = "allow" };
13    }
14};
15
16SessionConfig config = new SessionConfig { Hooks = hooks, /*...*/ };

Infinite Sessions

One of the most impressive features is Infinite Sessions. By enabling this, the SDK automatically manages the context window for you. As usage grows, it compacts older conversation history into the background while keeping the session purely functional. It also persists the workspace state to disk, so you can resume conversations across application restarts.

1CopilotSession session = await client.CreateSessionAsync(new SessionConfig
2{
3    Model = "gpt-5",
4    InfiniteSessions = new InfiniteSessionConfig { Enabled = true }
5});
6
7Console.WriteLine($"Session Workspace: {session.WorkspacePath}");
8// You can now access persisted checkpoints and state in that directory

Conclusion

The GitHub Copilot SDK for .NET opens up a new frontier for .NET developers. We are no longer limited to stateless “call and response” LLM interactions. We can now build stateful, tool-using agents that live alongside our code and help us automate complex tasks.

Whether you are building internal developer platforms, automated support bots, or complex workflow automation, this SDK provides the robust “brain” you need.

Get started by checking out the official repository and exploring the cookbook examples.


Comments

Twitter Facebook LinkedIn WhatsApp