{"id":5754,"date":"2026-08-04T11:25:35","date_gmt":"2026-08-04T18:25:35","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/agent-framework\/?p=5754"},"modified":"2026-08-04T11:25:35","modified_gmt":"2026-08-04T18:25:35","slug":"build-production-ready-agents-with-the-github-copilot-harness-and-agent-framework","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/agent-framework\/build-production-ready-agents-with-the-github-copilot-harness-and-agent-framework\/","title":{"rendered":"Build Production-Ready Agents with the GitHub Copilot Harness and Agent Framework"},"content":{"rendered":"<p class=\"code-line\" dir=\"auto\" data-line=\"2\">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.<\/p>\n<p class=\"code-line\" dir=\"auto\" data-line=\"4\">The GitHub Copilot integration in Microsoft Agent Framework brings these worlds together. You can now use GitHub Copilot&#8217;s agentic harness as the execution engine for your agents while continuing to leverage Agent Framework&#8217;s extensibility, tooling model, observability, streaming, and human-in-the-loop approval experiences.<\/p>\n<p class=\"code-line\" dir=\"auto\" data-line=\"6\">Today, we&#8217;re excited to announce that the GitHub Copilot Agent is now released and stable for both\u00a0<strong>.NET<\/strong>\u00a0and\u00a0<strong>Python<\/strong>\u00a0making it easier than ever to build production-ready coding agents using familiar Agent Framework abstractions.<\/p>\n<h2 id=\"what-is-the-github-copilot-agent\" class=\"code-line\" dir=\"auto\" data-line=\"6\">What is the GitHub Copilot Agent?<\/h2>\n<p class=\"code-line\" dir=\"auto\" data-line=\"8\">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.<\/p>\n<p class=\"code-line\" dir=\"auto\" data-line=\"10\">The result: an agent with Copilot&#8217;s built-in coding-agent capabilities \u2014 shell execution, file read\/write, URL fetching, and MCP tools \u2014 wired into the same run interface as every other Agent Framework provider.<\/p>\n<p class=\"code-line\" dir=\"auto\" data-line=\"12\"><strong>.NET<\/strong><\/p>\n<pre><code class=\"code-line language-csharp\" dir=\"auto\" data-line=\"14\"><span class=\"hljs-keyword\">using<\/span> GitHub.Copilot;\r\n<span class=\"hljs-keyword\">using<\/span> GitHub.Copilot.Rpc;\r\n<span class=\"hljs-keyword\">using<\/span> Microsoft.Agents.AI;\r\n\r\n<span class=\"hljs-comment\">\/\/ Start a Copilot client and turn it into an AIAgent.<\/span>\r\n<span class=\"hljs-keyword\">await<\/span> <span class=\"hljs-keyword\">using<\/span> CopilotClient copilotClient = <span class=\"hljs-keyword\">new<\/span>();\r\n<span class=\"hljs-keyword\">await<\/span> copilotClient.StartAsync();\r\n\r\nSessionConfig sessionConfig = <span class=\"hljs-keyword\">new<\/span>()\r\n{\r\n    OnPermissionRequest = (request, invocation) =&gt;\r\n        Task.FromResult(PermissionDecision.ApproveOnce()),\r\n};\r\n\r\nAIAgent agent = copilotClient.AsAIAgent(sessionConfig, ownsClient: <span class=\"hljs-literal\">true<\/span>);\r\n\r\nAgentResponse response = <span class=\"hljs-keyword\">await<\/span> agent.RunAsync(<span class=\"hljs-string\">\"Summarize what this project does.\"<\/span>);\r\nConsole.WriteLine(response);\r\n<\/code><\/pre>\n<p class=\"code-line\" dir=\"auto\" data-line=\"35\"><strong>Python<\/strong><\/p>\n<pre><code class=\"code-line language-python\" dir=\"auto\" data-line=\"37\"><span class=\"hljs-keyword\">import<\/span> asyncio\r\n<span class=\"hljs-keyword\">from<\/span> agent_framework.github <span class=\"hljs-keyword\">import<\/span> GitHubCopilotAgent, GitHubCopilotOptions\r\n<span class=\"hljs-keyword\">from<\/span> copilot.session <span class=\"hljs-keyword\">import<\/span> PermissionHandler\r\n\r\n\r\n<span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title function_\">main<\/span>() -&gt; <span class=\"hljs-literal\">None<\/span>:\r\n    <span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-keyword\">with<\/span> GitHubCopilotAgent(\r\n        instructions=<span class=\"hljs-string\">\"You are a helpful assistant.\"<\/span>,\r\n        default_options=GitHubCopilotOptions(\r\n            on_permission_request=PermissionHandler.approve_all,\r\n        ),\r\n    ) <span class=\"hljs-keyword\">as<\/span> agent:\r\n        result = <span class=\"hljs-keyword\">await<\/span> agent.run(<span class=\"hljs-string\">\"Summarize what this project does.\"<\/span>)\r\n        <span class=\"hljs-built_in\">print<\/span>(result)\r\n\r\n\r\n<span class=\"hljs-keyword\">if<\/span> __name__ == <span class=\"hljs-string\">\"__main__\"<\/span>:\r\n    asyncio.run(main())\r\n<\/code><\/pre>\n<p class=\"code-line\" dir=\"auto\" data-line=\"58\">Both give you streaming too: <code>RunStreamingAsync(...)<\/code>\u00a0in .NET,\u00a0<code>run(..., stream=True)<\/code>\u00a0in Python.<\/p>\n<h2 id=\"what-you-can-do-with-it\" class=\"code-line\" dir=\"auto\" data-line=\"60\">What you can do with it<\/h2>\n<h3 id=\"give-an-agent-real-system-capabilities\" class=\"code-line\" dir=\"auto\" data-line=\"62\">Give an agent real system capabilities<\/h3>\n<p class=\"code-line\" dir=\"auto\" data-line=\"64\">Copilot&#8217;s harness comes with the abilities a coding agent needs, and you opt in to each one through the permission handler:<\/p>\n<ul class=\"code-line\" dir=\"auto\" data-line=\"66\">\n<li class=\"code-line\" dir=\"auto\" data-line=\"66\"><strong>Shell execution<\/strong>\u00a0\u2014 run commands, scripts, and system tools.<\/li>\n<li class=\"code-line\" dir=\"auto\" data-line=\"67\"><strong>File operations<\/strong>\u00a0\u2014 read existing files and write new ones.<\/li>\n<li class=\"code-line\" dir=\"auto\" data-line=\"68\"><strong>URL fetching<\/strong>\u00a0\u2014 pull in and process web content.<\/li>\n<\/ul>\n<p class=\"code-line\" dir=\"auto\" data-line=\"70\">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:<\/p>\n<p class=\"code-line\" dir=\"auto\" data-line=\"72\"><strong>.NET<\/strong><\/p>\n<pre><code class=\"code-line language-csharp\" dir=\"auto\" data-line=\"74\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">static<\/span> Task&lt;PermissionDecision&gt; <span class=\"hljs-title\">PromptPermission<\/span>(<span class=\"hljs-params\">PermissionRequest request, PermissionInvocation invocation<\/span>)<\/span>\r\n{\r\n    Console.WriteLine(<span class=\"hljs-string\">$\"[Permission Request: <span class=\"hljs-subst\">{request.Kind}<\/span>]\"<\/span>);\r\n    Console.Write(<span class=\"hljs-string\">\"Approve? (y\/n): \"<\/span>);\r\n    <span class=\"hljs-built_in\">string<\/span>? input = Console.ReadLine()?.Trim().ToUpperInvariant();\r\n    <span class=\"hljs-keyword\">return<\/span> Task.FromResult(input <span class=\"hljs-keyword\">is<\/span> <span class=\"hljs-string\">\"Y\"<\/span> <span class=\"hljs-keyword\">or<\/span> <span class=\"hljs-string\">\"YES\"<\/span>\r\n        ? PermissionDecision.ApproveOnce()\r\n        : PermissionDecision.Reject());\r\n}\r\n<\/code><\/pre>\n<p class=\"code-line\" dir=\"auto\" data-line=\"86\"><strong>Python<\/strong><\/p>\n<pre><code class=\"code-line language-python\" dir=\"auto\" data-line=\"88\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title function_\">approve_and_log<\/span>(<span class=\"hljs-params\">request, context<\/span>):\r\n    <span class=\"hljs-keyword\">if<\/span> request.kind == <span class=\"hljs-string\">\"shell\"<\/span>:\r\n        <span class=\"hljs-built_in\">print<\/span>(<span class=\"hljs-string\">f\"[Permission: <span class=\"hljs-subst\">{request.kind}<\/span>] <span class=\"hljs-subst\">{<span class=\"hljs-built_in\">getattr<\/span>(request, 'full_command_text', '')}<\/span>\"<\/span>)\r\n        <span class=\"hljs-keyword\">return<\/span> PermissionHandler.approve_all(request, context)\r\n    <span class=\"hljs-keyword\">return<\/span> PermissionDecisionUserNotAvailable()\r\n<\/code><\/pre>\n<h3 id=\"extend-it-with-mcp-servers\" class=\"code-line\" dir=\"auto\" data-line=\"96\">Extend it with MCP servers<\/h3>\n<p class=\"code-line\" dir=\"auto\" data-line=\"98\">Configure Model Context Protocol servers \u2014 local (<code>stdio<\/code>) or remote (<code>http<\/code>) \u2014 to give the agent tools and data beyond the built-ins, from a filesystem server to remote services like the Microsoft Learn documentation API.<\/p>\n<p class=\"code-line\" dir=\"auto\" data-line=\"100\"><strong>.NET<\/strong><\/p>\n<pre><code class=\"code-line language-csharp\" dir=\"auto\" data-line=\"102\">SessionConfig sessionConfig = <span class=\"hljs-keyword\">new<\/span>()\r\n{\r\n    OnPermissionRequest = PromptPermission,\r\n    McpServers = <span class=\"hljs-keyword\">new<\/span> Dictionary&lt;<span class=\"hljs-built_in\">string<\/span>, McpServerConfig&gt;\r\n    {\r\n        [<span class=\"hljs-string\">\"filesystem\"<\/span>] = <span class=\"hljs-keyword\">new<\/span> McpStdioServerConfig\r\n        {\r\n            Command = <span class=\"hljs-string\">\"npx\"<\/span>,\r\n            Args = [<span class=\"hljs-string\">\"-y\"<\/span>, <span class=\"hljs-string\">\"@modelcontextprotocol\/server-filesystem\"<\/span>, <span class=\"hljs-string\">\".\"<\/span>],\r\n            Tools = [<span class=\"hljs-string\">\"*\"<\/span>],\r\n        },\r\n        [<span class=\"hljs-string\">\"microsoft-learn\"<\/span>] = <span class=\"hljs-keyword\">new<\/span> McpHttpServerConfig\r\n        {\r\n            Url = <span class=\"hljs-string\">\"https:\/\/learn.microsoft.com\/api\/mcp\"<\/span>,\r\n            Tools = [<span class=\"hljs-string\">\"*\"<\/span>],\r\n        },\r\n    },\r\n};\r\n\r\nAIAgent agent = copilotClient.AsAIAgent(sessionConfig, ownsClient: <span class=\"hljs-literal\">true<\/span>);\r\n<\/code><\/pre>\n<p class=\"code-line\" dir=\"auto\" data-line=\"125\"><strong>Python<\/strong><\/p>\n<pre><code class=\"code-line language-python\" dir=\"auto\" data-line=\"127\">mcp_servers = {\r\n    <span class=\"hljs-string\">\"filesystem\"<\/span>: {\r\n        <span class=\"hljs-string\">\"type\"<\/span>: <span class=\"hljs-string\">\"stdio\"<\/span>,\r\n        <span class=\"hljs-string\">\"command\"<\/span>: <span class=\"hljs-string\">\"npx\"<\/span>,\r\n        <span class=\"hljs-string\">\"args\"<\/span>: [<span class=\"hljs-string\">\"-y\"<\/span>, <span class=\"hljs-string\">\"@modelcontextprotocol\/server-filesystem\"<\/span>, <span class=\"hljs-string\">\".\"<\/span>],\r\n        <span class=\"hljs-string\">\"tools\"<\/span>: [<span class=\"hljs-string\">\"*\"<\/span>],\r\n    },\r\n    <span class=\"hljs-string\">\"microsoft-learn\"<\/span>: {\r\n        <span class=\"hljs-string\">\"type\"<\/span>: <span class=\"hljs-string\">\"http\"<\/span>,\r\n        <span class=\"hljs-string\">\"url\"<\/span>: <span class=\"hljs-string\">\"https:\/\/learn.microsoft.com\/api\/mcp\"<\/span>,\r\n        <span class=\"hljs-string\">\"tools\"<\/span>: [<span class=\"hljs-string\">\"*\"<\/span>],\r\n    },\r\n}\r\n\r\nagent = GitHubCopilotAgent(\r\n    instructions=<span class=\"hljs-string\">\"You are a helpful assistant with filesystem and Microsoft Learn access.\"<\/span>,\r\n    default_options=GitHubCopilotOptions(\r\n        on_permission_request=PermissionHandler.approve_all,\r\n        mcp_servers=mcp_servers,\r\n    ),\r\n)\r\n<\/code><\/pre>\n<h3 id=\"add-your-own-tools\" class=\"code-line\" dir=\"auto\" data-line=\"151\">Add your own tools<\/h3>\n<p class=\"code-line\" dir=\"auto\" data-line=\"153\">Register functions as tools alongside Copilot&#8217;s built-ins. Tools that require approval are gated through Copilot&#8217;s native pre-tool-use hook and routed to your approval handler. Wrap an <code>AIFunction<\/code>\u00a0in\u00a0<code>ApprovalRequiredAIFunction<\/code>\u00a0in .NET, or declare\u00a0<code>approval_mode=\"always_require\"<\/code>\u00a0in Python.<\/p>\n<p class=\"code-line\" dir=\"auto\" data-line=\"155\"><strong>.NET<\/strong><\/p>\n<pre><code class=\"code-line language-csharp\" dir=\"auto\" data-line=\"157\"><span class=\"hljs-comment\">\/\/ Wrap a tool in ApprovalRequiredAIFunction to gate it behind OnPermissionRequest.<\/span>\r\nAIFunction getWeather = AIFunctionFactory.Create(GetWeather);\r\n\r\nAIAgent agent = copilotClient.AsAIAgent(<span class=\"hljs-keyword\">new<\/span> SessionConfig\r\n{\r\n    OnPermissionRequest = PromptPermission,\r\n    Tools = [<span class=\"hljs-keyword\">new<\/span> ApprovalRequiredAIFunction(getWeather)],\r\n    SystemMessage = <span class=\"hljs-keyword\">new<\/span> SystemMessageConfig\r\n    {\r\n        Mode = SystemMessageMode.Append,\r\n        Content = <span class=\"hljs-string\">\"You are a helpful weather assistant.\"<\/span>,\r\n    },\r\n}, ownsClient: <span class=\"hljs-literal\">true<\/span>);\r\n<\/code><\/pre>\n<p class=\"code-line\" dir=\"auto\" data-line=\"173\"><strong>Python<\/strong><\/p>\n<pre><code class=\"code-line language-python\" dir=\"auto\" data-line=\"175\"><span class=\"hljs-keyword\">from<\/span> typing <span class=\"hljs-keyword\">import<\/span> Annotated\r\n<span class=\"hljs-keyword\">from<\/span> agent_framework <span class=\"hljs-keyword\">import<\/span> tool\r\n\r\n\r\n<span class=\"hljs-meta\">@tool(<span class=\"hljs-params\">approval_mode=<span class=\"hljs-string\">\"always_require\"<\/span><\/span>)<\/span>\r\n<span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title function_\">get_weather_detail<\/span>(<span class=\"hljs-params\">\r\n    location: Annotated[<span class=\"hljs-built_in\">str<\/span>, <span class=\"hljs-string\">\"The city and state, e.g. San Francisco, CA\"<\/span>],\r\n<\/span>) -&gt; <span class=\"hljs-built_in\">str<\/span>:\r\n    <span class=\"hljs-string\">\"\"\"Get a detailed weather report for a location.\"\"\"<\/span>\r\n    ...\r\n\r\n\r\nagent = GitHubCopilotAgent(\r\n    instructions=<span class=\"hljs-string\">\"You are a helpful weather assistant.\"<\/span>,\r\n    tools=[get_weather_detail],\r\n    <span class=\"hljs-comment\"># The tool's \"always_require\" decision is routed here to approve or deny.<\/span>\r\n    default_options=GitHubCopilotOptions(on_permission_request=approve_all_requests),\r\n)\r\n<\/code><\/pre>\n<h3 id=\"manage-sessions\" class=\"code-line\" dir=\"auto\" data-line=\"196\">Manage sessions<\/h3>\n<p class=\"code-line\" dir=\"auto\" data-line=\"198\">Copilot sessions are created automatically. Reuse a session to keep context across turns, and resume an earlier conversation by its session ID \u2014 even from a new agent instance.<\/p>\n<p class=\"code-line\" dir=\"auto\" data-line=\"200\"><strong>.NET<\/strong><\/p>\n<pre><code class=\"code-line language-csharp\" dir=\"auto\" data-line=\"202\"><span class=\"hljs-comment\">\/\/ Resume an existing conversation by its session id.<\/span>\r\nAgentSession session = <span class=\"hljs-keyword\">await<\/span> agent.CreateSessionAsync(existingSessionId);\r\nAgentResponse response = <span class=\"hljs-keyword\">await<\/span> agent.RunAsync(<span class=\"hljs-string\">\"What did I ask about first?\"<\/span>, session);\r\n<\/code><\/pre>\n<p class=\"code-line\" dir=\"auto\" data-line=\"208\"><strong>Python<\/strong><\/p>\n<pre><code class=\"code-line language-python\" dir=\"auto\" data-line=\"210\"><span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-keyword\">with<\/span> agent:\r\n    session = agent.create_session()\r\n\r\n    <span class=\"hljs-keyword\">await<\/span> agent.run(<span class=\"hljs-string\">\"What's the weather like in Tokyo?\"<\/span>, session=session)\r\n    <span class=\"hljs-comment\"># Same session -&gt; the agent remembers Tokyo.<\/span>\r\n    <span class=\"hljs-keyword\">await<\/span> agent.run(<span class=\"hljs-string\">\"How about London?\"<\/span>, session=session)\r\n\r\n    <span class=\"hljs-comment\"># Persist this to resume the conversation later.<\/span>\r\n    session_id = session.service_session_id\r\n\r\n<span class=\"hljs-comment\"># Later, in a new agent instance:<\/span>\r\n<span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-keyword\">with<\/span> agent2:\r\n    session = agent2.get_session(service_session_id=session_id)\r\n    <span class=\"hljs-keyword\">await<\/span> agent2.run(<span class=\"hljs-string\">\"Which city did I ask about first?\"<\/span>, session=session)\r\n<\/code><\/pre>\n<h3 id=\"share-project-guidelines\" class=\"code-line\" dir=\"auto\" data-line=\"227\">Share project guidelines<\/h3>\n<p class=\"code-line\" dir=\"auto\" data-line=\"229\">Point the agent at custom instruction directories to load project-specific or team-shared guidelines, keeping the agent&#8217;s behavior consistent across a codebase.<\/p>\n<p class=\"code-line\" dir=\"auto\" data-line=\"231\"><strong>Python<\/strong><\/p>\n<pre><code class=\"code-line language-python\" dir=\"auto\" data-line=\"233\">agent = GitHubCopilotAgent(\r\n    instructions=<span class=\"hljs-string\">\"You are a helpful coding assistant.\"<\/span>,\r\n    default_options=GitHubCopilotOptions(\r\n        on_permission_request=PermissionHandler.approve_all,\r\n        instruction_directories=[\r\n            <span class=\"hljs-string\">\".copilot\/instructions\"<\/span>,\r\n            <span class=\"hljs-string\">\"docs\/agent-guidelines\"<\/span>,\r\n        ],\r\n    ),\r\n)\r\n<\/code><\/pre>\n<h2 id=\"built-for-production\" class=\"code-line\" dir=\"auto\" data-line=\"246\">Built for production<\/h2>\n<p class=\"code-line\" dir=\"auto\" data-line=\"248\">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.<\/p>\n<p class=\"code-line\" dir=\"auto\" data-line=\"250\"><strong>Human-in-the-loop approval.<\/strong>\u00a0Every sensitive action \u2014 shell commands, file writes, URL fetches, MCP calls, and approval-required function tools \u2014 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.<\/p>\n<p class=\"code-line\" dir=\"auto\" data-line=\"252\"><strong>Native tool approval.<\/strong>\u00a0Because the Copilot SDK owns the tool-calling loop, approval for approval-required function tools is enforced through the SDK&#8217;s pre-tool-use hook. The agent installs a sensible default hook that routes those tools to your permission handler \u2014 and warns you if a custom hook would bypass it. This works the same way in both .NET (<code>ApprovalRequiredAIFunction<\/code>) and Python (<code>approval_mode=\"always_require\"<\/code>).<\/p>\n<p class=\"code-line\" dir=\"auto\" data-line=\"254\"><strong>Built-in observability.<\/strong>\u00a0The GitHub Copilot agent participates in Agent Framework&#8217;s OpenTelemetry tracing, so you get the same traces and telemetry as every other agent in your system.<\/p>\n<h2 id=\"why-this-matters\" class=\"code-line\" dir=\"auto\" data-line=\"290\">Why this matters<\/h2>\n<p class=\"code-line\" dir=\"auto\" data-line=\"292\">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.<\/p>\n<p class=\"code-line\" dir=\"auto\" data-line=\"294\">This means you can:<\/p>\n<ul class=\"code-line\" dir=\"auto\" data-line=\"296\">\n<li class=\"code-line\" dir=\"auto\" data-line=\"296\">Build repository-aware agents that leverage GitHub Copilot&#8217;s coding capabilities.<\/li>\n<li class=\"code-line\" dir=\"auto\" data-line=\"297\">Integrate custom tools, MCP servers, and enterprise services through Agent Framework.<\/li>\n<li class=\"code-line\" dir=\"auto\" data-line=\"298\">Apply consistent approval, governance, and observability experiences across different agent providers.<\/li>\n<li class=\"code-line\" dir=\"auto\" data-line=\"299\">Reuse existing Agent Framework investments while taking advantage of GitHub Copilot&#8217;s evolving coding harness.<\/li>\n<\/ul>\n<p class=\"code-line\" dir=\"auto\" data-line=\"301\">Whether you&#8217;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.<\/p>\n<h2 id=\"harness-options\" class=\"code-line\" dir=\"auto\" data-line=\"303\">Harness options<\/h2>\n<p class=\"code-line\" dir=\"auto\" data-line=\"305\">The GitHub Copilot Agent is one of several ways to build agents with Microsoft Agent Framework.<\/p>\n<p class=\"code-line\" dir=\"auto\" data-line=\"307\">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.<\/p>\n<p class=\"code-line\" dir=\"auto\" data-line=\"309\">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 <a href=\"https:\/\/devblogs.microsoft.com\/agent-framework\/build-your-own-claw-and-agent-harness-with-microsoft-agent-framework\/\" data-href=\"https:\/\/devblogs.microsoft.com\/agent-framework\/build-your-own-claw-and-agent-harness-with-microsoft-agent-framework\/\">Build your own claw and agent harness<\/a>\u00a0series for a step-by-step walkthrough in both .NET and Python.<\/p>\n<h2 id=\"getting-started\" class=\"code-line\" dir=\"auto\" data-line=\"256\">Getting started<\/h2>\n<p class=\"code-line\" dir=\"auto\" data-line=\"258\">The agent runs on top of an authenticated GitHub Copilot CLI, so you&#8217;ll need the Copilot CLI installed and an active GitHub Copilot subscription. .NET requires .NET 8+; Python requires 3.11+.<\/p>\n<p class=\"code-line\" dir=\"auto\" data-line=\"260\"><strong>.NET<\/strong><\/p>\n<pre><code class=\"code-line language-bash\" dir=\"auto\" data-line=\"262\">dotnet add package Microsoft.Agents.AI.GitHub.Copilot\r\n<\/code><\/pre>\n<p class=\"code-line\" dir=\"auto\" data-line=\"266\"><strong>Python<\/strong><\/p>\n<pre><code class=\"code-line language-bash\" dir=\"auto\" data-line=\"268\">pip install agent-framework-github-copilot\r\n<\/code><\/pre>\n<p class=\"code-line\" dir=\"auto\" data-line=\"272\">The underlying Copilot CLI is configured through environment variables shared by both languages:<\/p>\n<p dir=\"auto\" data-line=\"272\">These CLI settings default to environment variables, but you can also set them in code. In Python, pass them through\u00a0<code>GitHubCopilotOptions<\/code>\u00a0(<code>cli_path<\/code>,\u00a0<code>model<\/code>,\u00a0<code>timeout<\/code>,\u00a0<code>log_level<\/code>,\u00a0<code>base_directory<\/code>), which override the environment. In .NET, configure the client with\u00a0<code>CopilotClientOptions<\/code>\u00a0(<code>CliPath<\/code>,\u00a0<code>LogLevel<\/code>,\u00a0<code>BaseDirectory<\/code>,\u00a0<code>WorkingDirectory<\/code>) and set the model per session on\u00a0<code>SessionConfig.Model<\/code>.<\/p>\n<table class=\"code-line\" dir=\"auto\" data-line=\"274\">\n<thead class=\"code-line\" dir=\"auto\" data-line=\"274\">\n<tr class=\"code-line\" dir=\"auto\" data-line=\"274\">\n<th>Variable<\/th>\n<th>Description<\/th>\n<th>Default<\/th>\n<\/tr>\n<\/thead>\n<tbody class=\"code-line\" dir=\"auto\" data-line=\"276\">\n<tr class=\"code-line\" dir=\"auto\" data-line=\"276\">\n<td><code>GITHUB_COPILOT_CLI_PATH<\/code><\/td>\n<td>Path to the Copilot CLI executable<\/td>\n<td><code>copilot<\/code><\/td>\n<\/tr>\n<tr class=\"code-line\" dir=\"auto\" data-line=\"277\">\n<td><code>GITHUB_COPILOT_MODEL<\/code><\/td>\n<td>Model to use (e.g.\u00a0<code>gpt-5<\/code>,\u00a0<code>claude-sonnet-4<\/code>)<\/td>\n<td>Server default<\/td>\n<\/tr>\n<tr class=\"code-line\" dir=\"auto\" data-line=\"278\">\n<td><code>GITHUB_COPILOT_TIMEOUT<\/code><\/td>\n<td>Request timeout in seconds<\/td>\n<td><code>60<\/code><\/td>\n<\/tr>\n<tr class=\"code-line\" dir=\"auto\" data-line=\"279\">\n<td><code>GITHUB_COPILOT_BASE_DIRECTORY<\/code><\/td>\n<td>Directory for CLI session state and config<\/td>\n<td><code>~\/.copilot<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\"code-line\" dir=\"auto\" data-line=\"281\">Explore the runnable samples for each language:<\/p>\n<ul class=\"code-line\" dir=\"auto\" data-line=\"283\">\n<li class=\"code-line\" dir=\"auto\" data-line=\"283\"><strong>.NET<\/strong>\u00a0\u2014\u00a0<a href=\"https:\/\/github.com\/microsoft\/agent-framework\/tree\/main\/dotnet\/samples\/02-agents\/AgentProviders\/github-copilot\" data-href=\"https:\/\/github.com\/microsoft\/agent-framework\/tree\/main\/dotnet\/samples\/02-agents\/AgentProviders\/github-copilot\"><code>samples\/02-agents\/AgentProviders\/github-copilot<\/code><\/a><\/li>\n<li class=\"code-line\" dir=\"auto\" data-line=\"284\"><strong>Python<\/strong>\u00a0\u2014\u00a0<a href=\"https:\/\/github.com\/microsoft\/agent-framework\/tree\/main\/python\/samples\/02-agents\/providers\/github_copilot\" data-href=\"https:\/\/github.com\/microsoft\/agent-framework\/tree\/main\/python\/samples\/02-agents\/providers\/github_copilot\"><code>samples\/02-agents\/providers\/github_copilot<\/code><\/a><\/li>\n<\/ul>\n<h2 id=\"join-the-community\" class=\"code-line\" dir=\"auto\" data-line=\"311\">Join the community<\/h2>\n<p class=\"code-line\" dir=\"auto\" data-line=\"313\">Have questions, feedback, or want to discuss your use case with the team? Join the <a href=\"https:\/\/teams.microsoft.com\/meet\/2344899661716?p=bIxbaT1oqHeFsbPqT8\">Microsoft Agent Framework Office Hours<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>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. [&hellip;]<\/p>\n","protected":false},"author":216757,"featured_media":5048,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[78,143,47,144,33],"tags":[79,147,53],"class_list":["post-5754","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-net","category-agent-framework","category-announcement","category-github-copilot-sdk","category-python","tag-net","tag-microsoft-agent-framework","tag-python"],"acf":[],"blog_post_summary":"<p>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. [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/posts\/5754","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/users\/216757"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/comments?post=5754"}],"version-history":[{"count":1,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/posts\/5754\/revisions"}],"predecessor-version":[{"id":5789,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/posts\/5754\/revisions\/5789"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/media\/5048"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/media?parent=5754"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/categories?post=5754"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/tags?post=5754"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}