SIGNAL
Tracking the global AI frontier — labs · research · agents · policy
Frontier Signal
Agents

Build Production-Ready Agents with the GitHub Copilot Harness and Agent Framework

Developers increasingly want to build agents that can reason about code, modify files, execute commands, interact with developer tools, and work across entire repositories. While GitHub Copilot already provides a powerful coding harness for these scenarios, developers often need additional capabilities such as observability, middleware, approval workflows, enterprise governance, and integration with broader agent ecosystems. […] The post Build Production-Ready Agents with the GitHub Copilo

Published August 4, 2026 · Category: AI Agents

Overview

Developers increasingly want to build agents that can reason about code, modify files, execute commands, interact with developer tools, and work across entire repositories. While GitHub Copilot already provides a powerful coding harness for these scenarios, developers often need additional capabilities such as observability, middleware, approval workflows, enterprise governance, and integration with broader agent ecosystems.

The GitHub Copilot integration in Microsoft Agent Framework brings these worlds together. You can now use GitHub Copilot’s agentic harness as the execution engine for your agents while continuing to leverage Agent Framework’s extensibility, tooling model, observability, streaming, and human-in-the-loop approval experiences.

Today, we’re excited to announce that the GitHub Copilot Agent is now released and stable for both .NET and Python making it easier than ever to build production-ready coding agents using familiar Agent Framework abstractions.

What is the GitHub Copilot Agent?

The GitHub Copilot agent is an Agent Framework agent backed by the GitHub Copilot CLI and SDK. Copilot owns the agent loop (model calls, tool invocation, planning, and session state) while Agent Framework gives you a consistent surface for instructions, tools, streaming, middleware, observability, and human-in-the-loop approval.

The result: an agent with Copilot’s built-in coding-agent capabilities — shell execution, file read/write, URL fetching, and MCP tools — wired into the same run interface as every other Agent Framework provider.

.NET

using GitHub.Copilot;
using GitHub.Copilot.Rpc;
using Microsoft.Agents.AI;

// Start a Copilot client and turn it into an AIAgent.
await using CopilotClient copilotClient = new();
await copilotClient.StartAsync();

SessionConfig sessionConfig = new()
{
    OnPermissionRequest = (request, invocation) =>
        Task.FromResult(PermissionDecision.ApproveOnce()),
};

AIAgent agent = copilotClient.AsAIAgent(sessionConfig, ownsClient: true);

AgentResponse response = await agent.RunAsync("Summarize what this project does.");
Console.WriteLine(response);

Python

import asyncio
from agent_framework.github import GitHubCopilotAgent, GitHubCopilotOptions
from copilot.session import PermissionHandler


async def main() -> None:
    async with GitHubCopilotAgent(
        instructions="You are a helpful assistant.",
        default_options=GitHubCopilotOptions(
            on_permission_request=PermissionHandler.approve_all,
        ),
    ) as agent:
        result = await agent.run("Summarize what this project does.")
        print(result)


if __name__ == "__main__":
    asyncio.run(main())

Both give you streaming too: RunStreamingAsync(...) in .NET, run(..., stream=True) in Python.

What you can do with it

Give an agent real system capabilities

Copilot’s harness comes with the abilities a coding agent needs, and you opt in to each one through the permission handler:

  • Shell execution — run commands, scripts, and system tools.
  • File operations — read existing files and write new ones.
  • URL fetching — pull in and process web content.

Because every capability is gated by a permission request, the agent can only do what you explicitly allow. The handler receives each request and returns an approve/deny decision:

.NET

static Task<PermissionDecision> PromptPermission(PermissionRequest request, PermissionInvocation invocation)
{
    Console.WriteLine($"[Permission Request: {request.Kind}]");
    Console.Write("Approve? (y/n): ");
    string? input = Console.ReadLine()?.Trim().ToUpperInvariant();
    return Task.FromResult(input is "Y" or "YES"
        ? PermissionDecision.ApproveOnce()
        : PermissionDecision.Reject());
}

Python

def approve_and_log(request, context):
    if request.kind == "shell":
        print(f"[Permission: {request.kind}] {getattr(request, 'full_command_text', '')}")
        return PermissionHandler.approve_all(request, context)
    return PermissionDecisionUserNotAvailable()

Extend it with MCP servers

Configure Model Context Protocol servers — local (stdio) or remote (http) — to give the agent tools and data beyond the built-ins, from a filesystem server to remote services like the Microsoft Learn documentation API.

.NET

SessionConfig sessionConfig = new()
{
    OnPermissionRequest = PromptPermission,
    McpServers = new Dictionary<string, McpServerConfig>
    {
        ["filesystem"] = new McpStdioServerConfig
        {
            Command = "npx",
            Args = ["-y", "@modelcontextprotocol/server-filesystem", "."],
            Tools = ["*"],
        },
        ["microsoft-learn"] = new McpHttpServerConfig
        {
            Url = "https://learn.microsoft.com/api/mcp",
            Tools = ["*"],
        },
    },
};

AIAgent agent = copilotClient.AsAIAgent(sessionConfig, ownsClient: true);

Python

mcp_servers = {
    "filesystem": {
        "type": "stdio",
        "command": "npx",
        "args": ["-y", "@modelcontextprotocol/server-filesystem", "."],
        "tools": ["*"],
    },
    "microsoft-learn": {
        "type": "http",
        "url": "https://learn.microsoft.com/api/mcp",
        "tools": ["*"],
    },
}

agent = GitHubCopilotAgent(
    instructions="You are a helpful assistant with filesystem and Microsoft Learn access.",
    default_options=GitHubCopilotOptions(
        on_permission_request=PermissionHandler.approve_all,
        mcp_servers=mcp_servers,
    ),
)

Add your own tools

Register functions as tools alongside Copilot’s built-ins. Tools that require approval are gated through Copilot’s native pre-tool-use hook and routed to your approval handler. Wrap an AIFunction in ApprovalRequiredAIFunction in .NET, or declare approval_mode="always_require" in Python.

.NET

// Wrap a tool in ApprovalRequiredAIFunction to gate it behind OnPermissionRequest.
AIFunction getWeather = AIFunctionFactory.Create(GetWeather);

AIAgent agent = copilotClient.AsAIAgent(new SessionConfig
{
    OnPermissionRequest = PromptPermission,
    Tools = [new ApprovalRequiredAIFunction(getWeather)],
    SystemMessage = new SystemMessageConfig
    {
        Mode = SystemMessageMode.Append,
        Content = "You are a helpful weather assistant.",
    },
}, ownsClient: true);

Python

from typing import Annotated
from agent_framework import tool


@tool(approval_mode="always_require")
def get_weather_detail(
    location: Annotated[str, "The city and state, e.g. San Francisco, CA"],
) -> str:
    """Get a detailed weather report for a location."""
    ...


agent = GitHubCopilotAgent(
    instructions="You are a helpful weather assistant.",
    tools=[get_weather_detail],
    # The tool's "always_require" decision is routed here to approve or deny.
    default_options=GitHubCopilotOptions(on_permission_request=approve_all_requests),
)

Manage sessions

Copilot sessions are created automatically. Reuse a session to keep context across turns, and resume an earlier conversation by its session ID — even from a new agent instance.

.NET

// Resume an existing conversation by its session id.
AgentSession session = await agent.CreateSessionAsync(existingSessionId);
AgentResponse response = await agent.RunAsync("What did I ask about first?", session);

Python

async with agent:
    session = agent.create_session()

    await agent.run("What's the weather like in Tokyo?", session=session)
    # Same session -> the agent remembers Tokyo.
    await agent.run("How about London?", session=session)

    # Persist this to resume the conversation later.
    session_id = session.service_session_id

# Later, in a new agent instance:
async with agent2:
    session = agent2.get_session(service_session_id=session_id)
    await agent2.run("Which city did I ask about first?", session=session)

Share project guidelines

Point the agent at custom instruction directories to load project-specific or team-shared guidelines, keeping the agent’s behavior consistent across a codebase.

Python

agent = GitHubCopilotAgent(
    instructions="You are a helpful coding assistant.",
    default_options=GitHubCopilotOptions(
        on_permission_request=PermissionHandler.approve_all,
        instruction_directories=[
            ".copilot/instructions",
            "docs/agent-guidelines",
        ],
    ),
)

Built for production

Giving an agent system-level abilities is only safe if you can govern how it uses them. This release includes the controls you need to run it in production.

Human-in-the-loop approval. Every sensitive action — shell commands, file writes, URL fetches, MCP calls, and approval-required function tools — flows through a permission handler you provide. Approve, deny, or prompt per request; by default nothing runs without oversight, and you relax it selectively for trusted operations.

Native tool approval. Because the Copilot SDK owns the tool-calling loop, approval for approval-required function tools is enforced through the SDK’s pre-tool-use hook. The agent installs a sensible default hook that routes those tools to your permission handler — and warns you if a custom hook would bypass it. This works the same way in both .NET (ApprovalRequiredAIFunction) and Python (approval_mode="always_require").

Built-in observability. The GitHub Copilot agent participates in Agent Framework’s OpenTelemetry tracing, so you get the same traces and telemetry as every other agent in your system.

Why this matters

Many organizations are already using GitHub Copilot to accelerate developer productivity. With the GitHub Copilot Agent integration, developers can now bring those same coding capabilities into larger agent-driven workflows without having to choose between GitHub Copilot and Microsoft Agent Framework.

This means you can:

  • Build repository-aware agents that leverage GitHub Copilot’s coding capabilities.
  • Integrate custom tools, MCP servers, and enterprise services through Agent Framework.
  • Apply consistent approval, governance, and observability experiences across different agent providers.
  • Reuse existing Agent Framework investments while taking advantage of GitHub Copilot’s evolving coding harness.

Whether you’re building code review assistants, repository maintenance agents, developer copilots, or software engineering workflows, the GitHub Copilot harness enables these experiences using the same Agent Framework programming model.

Harness options

The GitHub Copilot Agent is one of several ways to build agents with Microsoft Agent Framework.

GitHub Copilot provides a powerful coding-focused harness with built-in support for planning, tool execution, shell access, file manipulation, URL retrieval, and MCP integration. For many software engineering scenarios, this provides an excellent out-of-the-box agent runtime experience.

If you want a more configurable harness that you assemble yourself (wiring up tools, planning, memory, approvals, and observability piece by piece), Agent Framework supports that too. See the Build your own claw and agent harness series for a step-by-step walkthrough in both .NET and Python.

Getting started

The agent runs on top of an authenticated GitHub Copilot CLI, so you’ll need the Copilot CLI installed and an active GitHub Copilot subscription. .NET requires .NET 8+; Python requires 3.11+.

.NET

dotnet add package Microsoft.Agents.AI.GitHub.Copilot

Python

pip install agent-framework-github-copilot

The underlying Copilot CLI is configured through environment variables shared by both languages:

These CLI settings default to environment variables, but you can also set them in code. In Python, pass them through GitHubCopilotOptions (cli_pathmodeltimeoutlog_levelbase_directory), which override the environment. In .NET, configure the client with CopilotClientOptions (CliPathLogLevelBaseDirectoryWorkingDirectory) and set the model per session on SessionConfig.Model.

Variable Description Default
GITHUB_COPILOT_CLI_PATH Path to the Copilot CLI executable copilot
GITHUB_COPILOT_MODEL Model to use (e.g. gpt-5claude-sonnet-4) Server default
GITHUB_COPILOT_TIMEOUT Request timeout in seconds 60
GITHUB_COPILOT_BASE_DIRECTORY Directory for CLI session state and config ~/.copilot

Explore the runnable samples for each language:

Join the community

Have questions, feedback, or want to discuss your use case with the team? Join the Microsoft Agent Framework Office Hours.

Details

The post Build Production-Ready Agents with the GitHub Copilot Harness and Agent Framework appeared first on Microsoft Agent Framework.

Source

Originally published at devblogs.microsoft.com.

Related Articles

F
Frontier Signal Desk

Frontier Signal tracks the global AI frontier — labs, research, agents, creation tools and real-world practice — straight from primary sources. Tip the desk: editorial@news.tunx.ai

Email the desk →
From our network: explore the AI assistant platform behind this site. Visit tunx.ai →
Note: This story is aggregated and summarized from the primary source linked above; the original publisher retains all rights. Details may evolve after publication — always confirm against the source. Nothing here is professional, legal or investment advice.

Related Stories

More from Agents →