A hands-on walkthrough of the Azure Functions serverless agents runtime (public preview, announced at Microsoft Build 2026). We build a tiny “Cloud Study Buddy” agent, deploy it to a real Azure subscription with
azd, and test it end to end — documenting every command, every gotcha, and every fix along the way.
What was announced, and why it matters
At Microsoft Build 2026, Microsoft shipped the public preview of the Azure Functions serverless agents runtime — a markdown-first programming model for building AI agents that run as ordinary Azure Functions apps.
The pitch is simple: production agents need more than a prompt and a model. They need a reliable way to start work (triggers), call external systems (tools/MCP), persist conversation history (sessions), run untrusted code safely (sandbox), authenticate without secrets (managed identity), emit telemetry, and scale on demand. Azure Functions already solves all of those operational concerns – so the runtime layers an agent model on top of it.
Instead of stitching together hosting, model clients, tools, session storage, identity, and observability yourself, you describe an agent in a .agent.md file and deploy it like any other function app. It’s powered by the Microsoft Agent Framework (MAF) and published on PyPI as azurefunctions-agents-runtime.
Key capabilities:
- Build agents with markdown – instructions, trigger config, and tool bindings live in
.agent.mdfiles. - Any Functions trigger starts an agent – HTTP, timer, queue, blob, Event Hub, Service Bus, Cosmos DB, and connector triggers (Teams, Outlook, SharePoint…).
- 1,400+ connectors via connector-backed MCP servers.
- Custom tools in plain Python – drop a file in
tools/, decorate a function with@tool. - Automatic HTTP + MCP endpoints – expose a chat API, a debug chat UI, and an MCP tool with no extra code.
- Serverless with built-in sessions – runs on the Flex Consumption plan, scales to zero, and persists multi-turn conversations in Azure Blob Storage.
- Pluggable model providers – Microsoft Foundry (recommended), Azure OpenAI, or OpenAI.
Reference docs:
- Serverless agents runtime in Azure Functions
- Quickstart: Build serverless agents using Azure Functions (the
azdtemplate quickstart) - Azure/azure-functions-agents-runtime (GitHub)
- Azure-Samples/functions-quickstart-serverless-agents-azd
What we’re going to build
A deliberately small demo – a single chat agent called Cloud Study Buddy – so the runtime concepts stay front and center rather than the app logic:
- It explains Azure / cloud concepts in plain language.
- It uses the sandboxed Python code interpreter (Azure Container Apps dynamic sessions) to do exact calculations instead of guessing.
- It exposes a built-in chat UI, a JSON chat API, and an MCP tool – all for free from one markdown file.
The entire “code” of the agent is this one file, src/main.agent.md:
---
name: Cloud Study Buddy
description: A friendly Azure learning companion that explains cloud concepts and can crunch numbers with sandboxed Python.
builtin_endpoints: true
mcp: false
---
You are **Cloud Study Buddy**, a friendly and concise tutor that helps people learn Microsoft Azure and general cloud computing concepts.
Follow these guidelines:
1. Explain concepts in plain language first, then add a short technical detail for depth. Keep answers skimmable.
2. When a question involves numbers - cost estimates, capacity planning, unit conversions, or quick data analysis - use the sandboxed Python code interpreter to compute the exact answer rather than guessing. Show the key figures you calculated.
3. When useful, give a tiny, copy-pasteable Azure CLI or example snippet.
4. If you are unsure or a topic is outside cloud computing, say so briefly instead of inventing an answer.
5. End non-trivial answers with a one-line "💡 Try next:" suggestion so the learner knows what to explore next.
Keep a warm, encouraging tone. You are here to make cloud concepts click.
The YAML front matter is configuration; the markdown body becomes the agent’s system prompt. builtin_endpoints: true is the magic that gives us the chat UI + chat API + MCP tool.
Anatomy of the project
The runtime expects a small, conventional layout. After scaffolding (next section), our src/ looked like this:
| File | Purpose |
|---|---|
src/main.agent.md | The agent. Front matter + markdown instructions. The filename stem (main) becomes the endpoint slug: /agents/main/. |
src/function_app.py | Bootstrap for the Functions host. Literally three lines. |
src/agents.config.yaml | App-wide runtime defaults (model, timeout, system tools like the code interpreter). |
src/host.json | Standard Functions host config + extension bundle. |
src/requirements.txt | Just azurefunctions-agents-runtime. |
infra/ | Bicep that azd uses to provision everything. |
azure.yaml | Tells azd the src/ folder is a Python function service. |
function_app.py is the entire host wiring:
from azure_functions_agents import create_function_app
app = create_function_app()
agents.config.yaml binds the code interpreter and model app-wide:
system_tools:
dynamic_sessions_code_interpreter:
endpoint: $ACA_SESSION_POOL_ENDPOINT
model: $FOUNDRY_MODEL
timeout: 900
Note the $ACA_SESSION_POOL_ENDPOINT and $FOUNDRY_MODEL placeholders – the runtime substitutes these from app settings (environment variables) at load time. The Bicep populates them for us.
Prerequisites & environment check
Prerequisites list (from the official quickstart):
- Azure Developer CLI (
azd) - Azure CLI (
az) - An Azure subscription with permissions to create resource groups, function apps, managed identities, Microsoft Foundry resources, model deployments, and Azure Container Apps session pools.
- (Optional) A Microsoft 365 account if you want to enable the connector-based email demo. We skipped this to keep the demo minimal.
Scaffolding from the official template
The runtime ships an azd template that provisions the whole supporting cast. I initialized it straight into my repo:
azd init --template Azure-Samples/functions-quickstart-serverless-agents-azd -e serverless-agents
The -e serverless-agents flag names the azd environment (it tracks deployment state and seeds resource names).
Understanding what azd up will provision
Before spending money, I read infra/main.bicep. The template deploys (all into one resource group):
- A user-assigned managed identity (the app’s identity – no secrets).
- A Microsoft Foundry account + project, and a model deployment.
- A Flex Consumption App Service plan (
FC1) + the Function App. - A storage account (deployment package + session history).
- Log Analytics + Application Insights (with local auth disabled).
- An Azure Container Apps dynamic session pool (the Python sandbox).
- RBAC role assignments wiring the identity to Foundry, storage, and the session pool.
The important parameters (from infra/main.parameters.json), and the app settings the Function App receives:
AZURE_FUNCTIONS_AGENTS_PROVIDER = foundryFOUNDRY_PROJECT_ENDPOINT = <project endpoint>FOUNDRY_MODEL = <model deployment name>ACA_SESSION_POOL_ENDPOINT = <session pool endpoint>AZURE_CLIENT_ID = <managed identity client id>
The allowed regions are constrained in Bicep to those that support Flex Consumption + ACA session pools + the Foundry model simultaneously: centralus, eastus, eastus2, northcentralus, southcentralus, westus.
Configuring the deployment
I set the region and a conservative model capacity via the azd environment:
azd env set AZURE_LOCATION eastus2
azd env set FOUNDRY_DEPLOYMENT_CAPACITY 50 # 50K tokens/min - plenty for a demo
Deploy
azd up --no-prompt
The resources that landed in rg-serverless-agents:
| Resource | Name | Notes |
|---|---|---|
| Function App (Flex Consumption) | func-agents-name | Hosts the agent |
| App Service plan | plan-name | SKU FC1 (Flex Consumption) |
| Foundry account / project | acc-name/ …-proj | Model host |
| Model deployment | gpt-5-mini | version 2025-08-07 |
| ACA session pool | session pool name | Python sandbox |
| Storage | stoage | Package + session history |
| Managed identity | id-agents-name | App identity |
| App Insights / Log Analytics | appi-… / log-… | Telemetry |
azd registered four functions from that one markdown file:
agent_main_builtin_chat # POST /agents/main/chat (JSON)agent_main_builtin_chatstream # POST /agents/main/chatstream (SSE)agent_main_builtin_chat_page # GET /agents/main/ (debug chat UI)agent_main_builtin_mcp # MCP tool via /runtime/webhooks/mcp
Test – the browser chat UI
Browse to https://func-name..azurewebsites.net/agents/main/. On first load it prompts for the base URL and the function key (stored in browser local storage), then gives you a full chat experience against the deployed agent – no frontend code written.
How the runtime starts the app (under the hood)
When the Functions host imports function_app.py, create_function_app():
- Resolves the app root (
AzureWebJobsScriptRoot). - Loads
agents.config.yaml. - Loads every
*.agent.mdfile. - Discovers MCP servers (
mcp.json), reusableskills/, and customtools/. - Composes app-wide config and registers one Azure Function per agent trigger, plus any built-in endpoints.
Environment-variable substitution ($VAR / %VAR%) is applied to agents.config.yaml, mcp.json, agent front matter, and the markdown body (outside fenced code blocks) – which is how $ACA_SESSION_POOL_ENDPOINT and $FOUNDRY_MODEL get filled in from app settings.
Cost, cleanup, and iteration
- Cost: Flex Consumption scales to zero, the session pool bills per use, and gpt-5-mini is inexpensive – a demo like this costs cents. The model deployment reserves capacity (I set 50K TPM), so tear it down when done.
- Iterate: Edit
main.agent.mdand runazd deploy(code only) orazd up(infra + code) again. - Tear down everything:
azd down --purge --force # or: az group delete -n rg-serverless-agentsUse--purgeso the Foundry (Cognitive Services) account doesn’t linger in a soft-deleted state and block future re-deploys.
Built and verified on 2026-07-07 against the public preview. Preview APIs and defaults may change before GA.