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_path, model, timeout, log_level, base_directory), which override the environment. In .NET, configure the client with CopilotClientOptions (CliPath, LogLevel, BaseDirectory, WorkingDirectory) 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-5, claude-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:
- .NET —Â
samples/02-agents/AgentProviders/github-copilot - Python —Â
samples/02-agents/providers/github_copilot
Join the community
Have questions, feedback, or want to discuss your use case with the team? Join the Microsoft Agent Framework Office Hours.
0 comments
Be the first to start the discussion.