Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

Azure Functions GitHub Copilot SDK Extension

Inject GitHub Copilot SDK sessions built from raw Markdown instructions into Python Azure Functions.

Install

pip install azurefunctions-agents-extensions-copilot-sdk

Install Entra authentication for remote MCP servers with the MCP extra:

pip install "azurefunctions-agents-extensions-copilot-sdk[mcp]"

Install Durable Functions support with the durable extra:

pip install "azurefunctions-agents-extensions-copilot-sdk[durable]"

The GitHub Copilot SDK uses a native runtime. Pre-provision it during image or deployment construction so a Function invocation never downloads executable content:

python -m copilot download-runtime

Use a Copilot SDK Agent app

The extension uses these standard Function App settings:

Setting Purpose
COPILOT_GITHUB_TOKEN GitHub token used by the default client.
COPILOT_BASE_DIRECTORY Writable directory for isolated Copilot runtime state.
COPILOT_MODEL Model used by Agent sessions.

Use these exact names in local.settings.json and Azure Function App settings. The extension creates the default CopilotClient in mode="empty", disables SDK telemetry, and does not use interactive logged-in-user authentication:

import azure.functions as func
from copilot.session import CopilotSession
from copilot.session_events import AssistantMessageData
from azurefunctions.agents.extensions.copilot_sdk import AgentFunctionApp

app = AgentFunctionApp()


@app.route(route="orders", methods=["POST"])
@app.markdown_agent(arg_name="agent", agent_name="orders")
async def process_order(
	req: func.HttpRequest,
	agent: CopilotSession,
) -> str:
	response = await agent.send_and_wait(req.get_body().decode())
	if response is None or not isinstance(response.data, AssistantMessageData):
		raise RuntimeError("Copilot did not return a final assistant message")
	return response.data.content

AgentFunctionApp subclasses azure.functions.FunctionApp and pins every Agent binding in the app to this provider. Place the complete instructions at orders.agent.md, orders.md, or the same filename under agents/. The .agent.md suffix is recommended; plain .md is also supported. The file is raw UTF-8 text; no front matter or runtime configuration is interpreted. If multiple candidates exist, lookup fails as ambiguous.

AgentFunctionApp() reads its model from COPILOT_MODEL and defaults on_permission_request to PermissionHandler.approve_all. Pass model= or on_permission_request= only to override those defaults. A markdown_agent() decorator can override client_factory, model, on_permission_request, provider, tools, and any Copilot session option for one binding. app_root can be set only on AgentFunctionApp.

PermissionHandler.approve_all should be used only when every exposed tool is trusted. Supply a restrictive SDK permission handler when tools can access privileged data or perform external actions.

Customize Copilot sessions

Pass Copilot session options directly to markdown_agent():

@app.markdown_agent(
	arg_name="agent",
	agent_name="orders",
	reasoning_effort="high",
	streaming=True,
)
async def process_order(
	req: func.HttpRequest,
	agent: CopilotSession,
) -> str:
	...

The extension forwards these arguments to CopilotClient.create_session() without validating their names or values. The installed Copilot SDK accepts or rejects them. Session options are applied after the extension defaults, so they take precedence. This includes extension-generated values such as system_message, tools, available_tools, mcp_servers, skill_directories, and their enablement flags. Override those values only when intentionally replacing the Agent's instructions or discovered capabilities.

For app-wide defaults, pass a mapping to AgentFunctionApp:

from azurefunctions.agents.extensions.copilot_sdk import AgentFunctionApp

app = AgentFunctionApp(
	session_options={
		"reasoning_effort": "high",
		"streaming": True,
	},
)

Supplying any session option to markdown_agent() replaces the app-wide session_options object for that binding.

Authentication and BYOK

Keep GitHub tokens and model-provider credentials in Function App settings or a secret store. Do not put them in source, .agent.md, or mcp.json files. The default client reads COPILOT_GITHUB_TOKEN and COPILOT_BASE_DIRECTORY when it is first needed.

The optional provider value is passed to the Copilot SDK session for bring your own key (BYOK) scenarios. For example:

import os

from copilot.session import ProviderConfig

provider: ProviderConfig = {
	"type": "openai",
	"wire_api": "responses",
	"base_url": os.environ["MODEL_BASE_URL"],
	"api_key": os.environ["MODEL_API_KEY"],
}

app = AgentFunctionApp(
	provider=provider,
)

The Copilot SDK also supports Azure and Anthropic provider configurations. Use the provider fields supported by the installed SDK version, and keep all credentials outside checked-in configuration.

For advanced client authentication or runtime transports, pass a synchronous zero-argument client_factory. The extension calls it once, validates the result, and caches that CopilotClient:

from copilot import CopilotClient


def create_copilot_client() -> CopilotClient:
	return CopilotClient(...)


app = AgentFunctionApp(
	client_factory=create_copilot_client,
)

App-level bindings share the app's cached client. A decorator-level client_factory override has a separate cache for that binding. Factories must return CopilotClient synchronously; awaitable results are rejected.

Skills and MCP servers

Skills and remote MCP servers are discovered automatically from the app root:

skills/inventory/SKILL.md
mcp.json

The base extension discovers Skill directory paths without reading their contents. The Copilot SDK loads and validates the Skill files for each session.

V1 supports remote HTTP MCP transports only:

{
	"servers": {
		"inventory": {
			"type": "streamable-http",
			"url": "$INVENTORY_MCP_URL",
			"tools": ["lookup_stock"],
			"headers": {"X-Tenant": "%TENANT_ID%"},
			"auth": {
				"scope": "$INVENTORY_MCP_SCOPE",
				"client_id": "%AZURE_CLIENT_ID%"
			}
		}
	}
}

$VAR and %VAR% references are resolved for each invocation. Missing values fail before session creation. Servers with headers or Entra authentication must use HTTPS, except for explicit loopback development endpoints. Entra tokens are acquired through DefaultAzureCredential and held only for the invocation.

Every Agent in the Function App receives all valid Skills and MCP servers under the app root. V1 has no app-level or per-binding capability selectors. Skills, MCP servers, and Python tools= can perform privileged operations; use separate Function Apps when capability sets require isolation.

Invocation lifecycle

The extension creates one client lazily and reuses it across invocations for the lifetime of the Python worker process. Each invocation creates and closes a fresh session. Default ephemeral sessions are deleted after disconnect so they do not accumulate in the cached client's registry. Leave enable_session_store disabled: this binding creates a new session for every invocation and does not expose a session ID or resume workflow. Enabling the store retains each disconnected session in the cached client for the lifetime of the worker. The extension replaces the session system message with the raw Agent instructions and disables ambient Copilot configuration discovery, session persistence, memory, telemetry, built-in Skills, and tool search. Explicit Python tools, discovered Skills, and discovered MCP servers remain available.

Sessions and Entra credentials are closed on success, error, and cancellation. The cached client remains open so later invocations can reuse its runtime connection.

Durable Agents

Use context.call_agent(agent_name, input_) inside a synchronous generator orchestrator. Agent execution runs in the extension's hidden activity, keeping orchestrator replay deterministic:

from azurefunctions.agents.extensions.copilot_sdk import DurableAgentContext


@app.orchestration_trigger(context_name="context")
def order_orchestrator(context: DurableAgentContext):
	assessment = yield context.call_agent(
		"orders",
		{"order": context.get_input()},
	)
	return {"assessment": assessment}

Importing the package remains safe without Durable installed. Using Durable decorators requires the [durable] extra. All Durable Agent calls use the provider and capabilities configured by AgentFunctionApp; an orchestrator cannot select a different provider or capability set in V1.

Current limitations

  • Python 3.13 or later is required.
  • Only remote HTTP MCP servers are supported; local process transports are not.
  • Agent files contain raw instructions only; front matter is not interpreted.
  • Capability filtering within one Function App is not supported in V1.
  • Native runtime provisioning is an application deployment responsibility.

See samples/agent_samples_copilot-sdk for direct HTTP and queue triggers and samples/agent_samples_copilot-sdk_durable for Durable orchestration.

Metadata

Release files for azurefunctions-agents-extensions-copilot-sdk 1.0.0b1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for azurefunctions-agents-extensions-copilot-sdk 1.0.0b1
File Size Uploaded Provenance Actions
azurefunctions_agents_extensions_copilot_sdk-1.0.0b1.tar.gz 21.3 kB Without provenance Details for azurefunctions_agents_extensions_copilot_sdk-1.0.0b1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for azurefunctions-agents-extensions-copilot-sdk 1.0.0b1
File Interpreter ABI Platform Actions
azurefunctions_agents_extensions_copilot_sdk-1.0.0b1-py3-none-any.whl Python 3 none any Details for azurefunctions_agents_extensions_copilot_sdk-1.0.0b1-py3-none-any.whl

Total release size: 34.1 kB

Release files / azurefunctions_agents_extensions_copilot_sdk-1.0.0b1.tar.gz

Download URL azurefunctions_agents_extensions_copilot_sdk-1.0.0b1.tar.gz
Size 21.3 kB
Tags Source
SHA-256 checksum
How to use checksums
30555c4139c4305fa45f0c80023acec7dadeb12159991dd561d89629fbe5f186
BLAKE2b-256 checksum
How to use checksums
f3efc73267c346e7f222085a1310f909e4962267631e86e40dd939f662c8d583
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via RestSharp/106.13.0.0

Release files / azurefunctions_agents_extensions_copilot_sdk-1.0.0b1-py3-none-any.whl

Download URL azurefunctions_agents_extensions_copilot_sdk-1.0.0b1-py3-none-any.whl
Size 12.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d21017a5f1224f136d3a02f0b27a083dedb235590d8961c290048af227795335
BLAKE2b-256 checksum
How to use checksums
a289119446f16ae233231bf255c16b8a6a4fc83745f108644e5c4184f0bf0c49
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via RestSharp/106.13.0.0

Security for azurefunctions-agents-extensions-copilot-sdk 1.0.0b1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page