How to Build Custom AI Agents Using the GitHub Copilot SDK: Complete Guide

Yes, the GitHub Copilot SDK provides a production-tested agent runtime that supports custom AI agents through JSON-RPC communication with the Copilot CLI, available in Node.js/TypeScript, Python, Go, .NET, Java, and Rust.

The github/copilot-sdk repository offers a production-ready framework for embedding AI agent capabilities into your applications. You can build custom AI agents using the GitHub Copilot SDK by defining lightweight configurations that include system prompts, tool permissions, and optional MCP servers, which the runtime then executes in isolated sub-agent contexts.

What Are Custom Agents?

A custom agent in the Copilot SDK is a named configuration object that ships with its own system prompt, a scoped set of allowed tools, and optional MCP (Model Context Protocol) servers. When user requests match the agent's description—or when an explicit agent name is supplied—the runtime automatically spawns a sub-agent that operates in an isolated context.

Key concepts include:

  • Custom agent: The definition containing name, prompt, optional description, and tools
  • Sub-agent: The actual instance of a custom agent invoked during runtime
  • Inference: Automatic selection based on prompt intent (controlled by the infer parameter, which defaults to true)
  • Session: The top-level interaction that may host multiple custom agents
  • Tool scoping: Restriction of which first-party tools (e.g., grep, edit) an agent may invoke

According to the source code in docs/features/custom-agents.md, this architecture allows you to enforce least-privilege security by limiting tool access per agent while maintaining composable workflows.

Architecture and Internal Runtime Flow

The SDK abstracts JSON-RPC plumbing through the CopilotClient class that manages the CLI process automatically.

The internal execution flow works as follows:

  1. Session initialization: The SDK constructs a SessionConfig containing the customAgents array and establishes a JSON-RPC handshake with the Copilot CLI running in server mode.
  2. Intent evaluation: For each incoming prompt, the runtime evaluates custom agent description fields. If a match is detected and infer is not explicitly set to false, the runtime spawns a sub-agent.
  3. Isolated execution: The sub-agent receives its dedicated system prompt and only the tools listed in its tools array (or all available tools if the array is omitted).
  4. Event streaming: Lifecycle events including subagent.started, subagent.completed, and subagent.failed stream back to the parent session, enabling real-time UI updates or logging.
  5. Result integration: The sub-agent's final response merges into the parent session's answer and returns to the caller.

This process requires no manual process management from developers—you supply configuration objects and event handlers while the SDK handles the underlying JSON-RPC communication.

Multi-Language SDK Support

The GitHub Copilot SDK supports building custom agents across six languages through dedicated client libraries:

  • Node.js/TypeScript: Primary implementation with full feature parity

  • Python: Async/await support with the copilot package

  • Go: Native routines for concurrent agent management

  • .NET: C# implementation for enterprise applications

  • Java: Maven and Gradle compatible

  • Rust: Systems programming integration

Each implementation communicates with the same underlying Copilot CLI via JSON-RPC, ensuring consistent behavior across language ecosystems.

Creating a Custom Agent

To build custom AI agents, you instantiate a CopilotClient, create a session with a customAgents configuration array, and handle lifecycle events.

Node.js/TypeScript Example

The Node.js SDK exports CopilotClient from @github/copilot-sdk. Create agents by defining configurations with scoped tools and descriptions:

import { CopilotClient } from "@github/copilot-sdk";

const client = new CopilotClient();
await client.start();

const session = await client.createSession({
  model: "gpt-4.1",
  customAgents: [
    {
      name: "researcher",
      displayName: "Research Agent",
      description: "Explores codebases with read‑only tools",
      tools: ["grep", "glob", "view"],
      prompt:
        "You are a research assistant. Analyze code and answer questions. Do not modify any files.",
    },
    {
      name: "editor",
      displayName: "Editor Agent",
      description: "Makes targeted code changes",
      tools: ["view", "edit", "bash"],
      prompt:
        "You are a code editor. Make minimal, surgical changes to files as requested.",
    },
  ],
  onPermissionRequest: async () => ({ kind: "approve-once" }),
});

// Listen for sub‑agent events
session.on((event) => {
  if (event.type === "subagent.started") {
    console.log(`▶ Sub‑agent ${event.data.agentDisplayName} started`);
  }
});

const response = await session.sendAndWait({
  prompt: "Explain the authentication flow in this repository",
});
console.log(response);

The runtime automatically delegates to the appropriate sub-agent based on the prompt content and agent descriptions. Full implementation details appear in nodejs/docs/agent-author.md.

Python Example

The Python SDK follows similar patterns using copilot.CopilotClient:

from copilot import CopilotClient, PermissionDecisionApproveOnce

client = CopilotClient()
await client.start()

session = await client.create_session(
    model="gpt-4.1",
    custom_agents=[
        {
            "name": "researcher",
            "display_name": "Research Agent",
            "description": "Read‑only exploration of the codebase",
            "tools": ["grep", "glob", "view"],
            "prompt": "You are a research assistant. Analyze code and answer questions. Do not modify any files.",
        },
        {
            "name": "editor",
            "display_name": "Editor Agent",
            "description": "Makes targeted code changes",
            "tools": ["view", "edit", "bash"],
            "prompt": "You are a code editor. Make minimal, surgical changes to files as requested.",
        },
    ],
    on_permission_request=lambda req, inv: PermissionDecisionApproveOnce(),
)

def handle(event):
    if event.type == "subagent.started":
        print(f"▶ Sub‑agent {event.data.agent_display_name} started")
    elif event.type == "subagent.completed":
        print(f"✅ Sub‑agent {event.data.agent_display_name} completed")

unsubscribe = session.on(handle)

response = await session.send_and_wait("Summarize the CI configuration in this repo")
print(response)

Reference python/README.md for installation instructions and async patterns.

Security and Tool Scoping

Custom agents enforce least-privilege security through explicit tool scoping. By restricting the tools array, you limit what the underlying LLM can execute:

  • Read-only agents: Limit to ["grep", "glob", "view"] for safe code exploration
  • Editor agents: Extend with ["edit", "bash"] for file modification capabilities
  • Domain-specific agents: Attach MCP servers to grant access to private data sources like database schemas or internal APIs

This separation of concerns prevents accidental modifications during research tasks while allowing surgical edits when explicitly requested.

Key Files and Documentation

The github/copilot-sdk repository contains definitive resources for building custom agents:

Summary

  • Yes, you can build custom AI agents using the GitHub Copilot SDK's production-tested runtime across Node.js/TypeScript, Python, Go, .NET, Java, and Rust.
  • Custom agents are configuration objects containing name, description, prompt, and scoped tools that run as isolated sub-agents.
  • Automatic delegation occurs when the runtime matches user prompts to agent descriptions (controlled by the infer parameter).
  • Event streaming provides real-time visibility into sub-agent lifecycle states (subagent.started, subagent.completed, subagent.failed).
  • Tool scoping enforces least-privilege security by restricting which first-party tools each agent may invoke.

Frequently Asked Questions

Can custom agents access external data sources?

Yes. You can attach MCP (Model Context Protocol) servers to custom agent configurations, allowing access to domain-specific data such as database schemas, internal documentation APIs, or proprietary knowledge bases. The MCP integration runs alongside the scoped tools defined in the agent's tools array.

How does the runtime decide which custom agent to use?

The Copilot SDK evaluates the description field of each configured custom agent against the incoming user prompt. If the runtime detects a match and the agent's infer parameter is not explicitly set to false, it automatically spawns that sub-agent. Alternatively, you can explicitly specify an agent by name in the request to bypass automatic inference.

Are custom agents isolated from each other?

Yes. Each custom agent runs as a sub-agent in an isolated context with its own system prompt and restricted tool set. Lifecycle events stream back to the parent session, but the execution environment remains separate, preventing tool access leakage between different agent instances within the same session.

Which programming languages support custom agent development?

The GitHub Copilot SDK supports custom agent development in Node.js/TypeScript, Python, Go, .NET, Java, and Rust. All implementations communicate with the same underlying Copilot CLI via JSON-RPC, ensuring consistent agent behavior and configuration schemas across languages. Each SDK provides equivalent CopilotClient classes and session management APIs.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →