Microsoft Agent FrameworkAzureDeploymentAI Agents

Hosted Agents in Foundry Agent Service: A .NET Developer's Guide

Hosted agents in Foundry Agent Service are GA: per-session sandboxes, scale-to-zero, and a simple path to deploy Microsoft Agent Framework agents from .NET.

Until now, “deploying an AI agent” on Azure meant the same thing as deploying any other service: build a container, pick Container Apps or AKS, wire up scaling, identity, state, and telemetry yourself. At Build 2026, Microsoft announced a different answer — hosted agents in Foundry Agent Service, a managed runtime built specifically for agents — and as of July 2026 it is generally available, with support for .NET 10 at launch.

This guide covers what hosted agents actually are, how the per-session sandbox model works, how a .NET developer gets a Microsoft Agent Framework agent running there, and — most importantly — when you should choose it over self-hosting on Container Apps or Kubernetes.

What are hosted agents?

Hosted agents are your own agent code, packaged and run on Microsoft-managed infrastructure inside Foundry Agent Service. They sit in contrast to the prompt-based agents you configure entirely in the Foundry portal: with hosted agents, you bring real code — any orchestration logic, any framework — and the platform handles containerization concerns, web serving, scaling, session state, identity, and observability.

Three properties define the offering:

  1. Per-session, VM-isolated sandboxes. Every session gets its own sandbox with dedicated CPU, memory, and a persistent filesystem ($HOME plus a /files endpoint). Sessions are isolated from each other at the hypervisor level, not just the container level.
  2. Framework-agnostic. The runtime doesn’t care how you built the agent. Microsoft Agent Framework, LangGraph, Semantic Kernel, the GitHub Copilot SDK, or plain custom code all work — the protocol libraries that expose your agent over HTTP are decoupled from the agent logic. Supported languages are C# and Python (with dotnet_10, python_3_13, and python_3_14 runtimes for direct code deployment).
  3. Scale-to-zero with stateful resume. When a session goes idle for 15 minutes, the platform deprovisions its compute and persists the session state. When the same session ID comes back, it provisions fresh compute and restores $HOME exactly as it was. You pay nothing while idle.

That last point is the part that genuinely differs from general-purpose platforms. Container Apps can scale to zero too — but it can’t hand you back a per-user filesystem when it scales back up. Hosted agents treat the session, not the replica, as the unit of scaling.

The runtime model: sessions, not replicas

If you’ve operated services on AKS or Container Apps, unlearn the replica mental model for a moment. Hosted agents scale per session:

  • A new session triggers a new sandbox, provisioned on demand.
  • The sandbox lives for the duration of the session — idle timeout of 15 minutes, maximum lifetime of 30 days, permanent deletion after 30 days of inactivity.
  • There is no replica count to configure and no warm pool to size.

The CPU/memory you configure describes one session’s sandbox, not your aggregate footprint. Available sizes at GA:

CPU Memory
0.5 vCPU 1 GiB
1 vCPU 2 GiB
2 vCPU 4 GiB

Each session also gets a disk budget of up to 20 GiB (at 1 vCPU or larger; roughly 20% is reserved for system use), shared between your container image, $HOME, and other writable paths.

Billing follows the same logic: you’re charged for CPU and memory consumed across active sessions. This has a sharp corollary — oversizing the sandbox multiplies cost by your concurrency. If you allocate 2 vCPU “to be safe” and run 200 concurrent sessions, you’re paying for 400 vCPUs. Right-size from real Application Insights data, and revisit the broader levers in cost control for production AI agents.

Protocols: how clients talk to your agent

A hosted agent container exposes one or more protocols, each provided by a lightweight library that handles the HTTP server, health checks, and OpenTelemetry wiring:

  • Responses — an OpenAI-compatible /responses contract. The platform manages conversation history (via conversation IDs), streaming lifecycle events, and background execution (background: true with platform-managed polling). Any OpenAI-compatible SDK — including the C# one — works as a client out of the box. Start here for anything conversational.
  • Invocations — arbitrary JSON in, arbitrary JSON out over /invocations. You define the schema and manage your own session state. Use it for webhook receivers (GitHub, Stripe, Jira), non-conversational processing like classification or extraction, or protocol bridges where the caller’s payload format isn’t yours to change.
  • Invocations (WebSocket) — bidirectional streaming over a persistent connection, aimed at real-time voice agents.
  • Activity and A2A — when you publish a Responses-based agent to Teams or Microsoft 365, the platform automatically bridges to the Activity protocol; A2A (preview) supports agent-to-agent delegation.

A single agent can expose multiple protocols simultaneously, so starting with Responses and adding an Invocations endpoint later is a supported path, not a rewrite.

Deploying a Microsoft Agent Framework agent from .NET

Here’s the developer workflow end to end. Assume you already have a working MAF agent — if not, start with the Agent Framework guide.

1. Host the agent behind the Responses protocol

The Agent Framework ships hosting integration so an ASP.NET Core app can expose an AIAgent over the Responses protocol. Per the Build 2026 announcement, the .NET surface is a pair of extension methods — AddFoundryResponses() and MapFoundryResponses() — that register and map the endpoint. Conceptually:

// Conceptual — verify exact signatures against the
// microsoft-foundry/foundry-samples repo for your package version.
using Microsoft.Agents.AI;
using Azure.AI.OpenAI;
using Azure.Identity;

var builder = WebApplication.CreateBuilder(args);

// The model endpoint and deployment name arrive as environment
// variables injected by the platform per agent version.
var chatClient = new AzureOpenAIClient(
        new Uri(builder.Configuration["FOUNDRY_PROJECT_ENDPOINT"]!),
        new DefaultAzureCredential())
    .GetChatClient(builder.Configuration["MODEL_DEPLOYMENT_NAME"]!);

AIAgent agent = chatClient.CreateAIAgent(
    name: "SupportTriageAgent",
    instructions: "Triage support tickets. Classify severity and suggest a first response.");

// Register the agent with the Foundry Responses protocol library
builder.AddFoundryResponses(agent);

var app = builder.Build();
app.MapFoundryResponses();   // exposes the /responses contract + health checks + OTel

app.Run();

Notice what’s absent: no custom session store, no conversation-history table, no streaming plumbing, no OpenTelemetry exporter configuration. The protocol library and the platform own those. MAF’s OpenTelemetry traces flow straight into the Application Insights resource that the platform links automatically — the connection string is injected into your container as an environment variable. (For what those traces should contain and how to read them, see observability for AI agents with OpenTelemetry.)

2. Deploy with azd

Deployment is two commands via the Azure Developer CLI:

azd ai agent init --agent-name support-triage --deploy-mode code --runtime dotnet_10
azd deploy

--deploy-mode is the interesting flag. Code mode zips your .NET project and lets the platform handle the build — no Dockerfile at all. Container mode gives you full control: you build the image, push it to Azure Container Registry, and the platform pulls it at deploy time. Use container mode when you need OS-level dependencies; use code mode for everything else.

At deploy time, the platform automatically:

  • provisions a dedicated Microsoft Entra agent identity for the agent (used at runtime to call models, tools, and downstream Azure services — you grant it RBAC roles like any principal),
  • exposes a dedicated endpoint: {project_endpoint}/agents/{name}/endpoint/protocols/openai/responses,
  • creates an immutable agent version — a snapshot of image, resources, environment variables, and protocol config. Updates mean new versions, and you can split traffic between versions with weighted rollouts for canary or blue-green deployments.

Tail logs with azd ai agent monitor --tail 100.

3. Call it

Because the Responses protocol is OpenAI-compatible, the client side is any OpenAI SDK pointed at your agent’s endpoint with an Entra token — including from another .NET service. Conversation history is platform-managed via conversation IDs, and the platform hands back a session ID your client can use to upload files to the session’s sandbox via /files.

One more integration detail worth knowing before you design tools: hosted agents do not get tools injected into their definition. Foundry-managed tools (Code Interpreter, Web Search, Azure AI Search, OpenAPI, custom MCP connections) are reached through a Toolbox MCP endpoint in your project, which your agent code connects to with a standard MCP client. Your MAF agent’s own C# function tools work exactly as they always did.

Hosted agents vs Container Apps vs AKS/GKE

The obvious question for anyone who has already shipped an agent to Azure Container Apps or Kubernetes: is this just another compute tier? Not quite — the trade-offs are real in both directions.

Foundry hosted agents Azure Container Apps AKS / GKE
Unit of scale Session (per-user sandbox) Replica Pod
Session state Automatic — persistent $HOME per session, restored on resume DIY (Redis, Cosmos DB, blob) DIY (StatefulSets, PVCs, external stores)
Isolation VM-isolated per session Shared replicas serve all users Shared pods; namespace/node isolation is on you
Scale-to-zero Yes, with stateful resume Yes, stateless resume Not natively (KEDA gets close)
Identity Dedicated Entra agent identity, auto-provisioned Managed identity you configure Workload Identity you configure
Protocol/serving Responses/Invocations libraries provided You write the API You write the API
Observability App Insights + OTel wired automatically You wire exporters You wire exporters + collectors
Compute ceiling 2 vCPU / 4 GiB per session Larger workload profiles, GPU options Anything, including GPUs
Control Low — managed runtime, 15-min idle policy fixed Medium Full
Multi-cloud Azure only Azure only Portable
Billing CPU + memory across active sessions Per replica-second (+ idle discounts) Per node, always-on

Choose hosted agents when: the agent is conversational or session-oriented, per-user isolation matters (agents that write files, run untrusted-ish code, or hold sensitive per-customer context), traffic is spiky or low-volume, and your team would rather not own serving infrastructure. The VM-per-session model is a security posture that is genuinely expensive to replicate yourself.

Stay on Container Apps when: you need bigger compute or GPUs, you want Dapr or existing microservice patterns around the agent, or the agent is stateless request/response where per-session sandboxes buy you nothing and replica-based scaling is cheaper at sustained high concurrency.

Stay on AKS/GKE when: you need multi-cloud portability, custom networking/service mesh, co-location with existing clusters, or fine-grained control over the runtime that a managed platform will never expose. A fixed 15-minute idle timeout and a 2 vCPU ceiling are exactly the kind of constraints self-hosting exists to escape.

The honest summary: hosted agents replace the undifferentiated parts of agent hosting. They do not replace Kubernetes for teams whose requirements are the differentiated parts.

Gotchas and fine print

  • GA is fresh. Preview label came off in July 2026; the Build-era preview SDKs had breaking changes on the way to GA (on the Python side, the standalone azure-ai-agents package was retired in favor of AIProjectClient in azure-ai-projects). Pin versions and re-check samples before upgrading.
  • Secrets don’t belong in images or env vars. Use the agent identity plus Key Vault connections — env vars are per-version and immutable, which makes them the wrong place for rotation anyway.
  • Region availability is broad but not universal — about 20 regions at GA, including East US 2, Sweden Central, Japan East, and South India. Check the list before committing an architecture.
  • Cost scales with concurrency. Per-session billing is wonderful for spiky workloads and punishing for oversized sandboxes at high concurrency. Measure in App Insights, then right-size.

Where to go next

If you’re weighing the alternatives concretely, the Container Apps deployment walkthrough and the GKE deployment guide show what the self-hosted path actually costs you in setup — which is the best way to decide whether a managed runtime earns its constraints.


Have a correction or a topic you want covered? Email mani.bc72@gmail.com.