Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Use the Microsoft Agent Framework hosting packages to expose an Agent Framework agent through the protocols for Foundry hosted agents. The hosting packages let you keep your agent logic in code while Foundry manages the hosted runtime, sessions, scale, identity, and protocol endpoints.
In this article, you create a minimal Agent Framework agent, expose it through either the Responses or Invocations protocol, test it through HTTP, and deploy it to Foundry with the Azure Developer CLI.
The Microsoft Foundry Skill can help implement the adapter, test the protocols, and deploy with azd.
Prerequisites
- An Azure subscription. Create one for free.
- A Foundry project.
- A deployed chat model, such as
gpt-4.1orgpt-4o. - The Foundry Project Manager role on the project to deploy a hosted agent. For details, see Deploy a hosted agent.
- Azure CLI signed in (
az login) soDefaultAzureCredentialcan authenticate.
- Python 3.10 or later.
- .NET 10 SDK or later.
Install the packages
Install the Agent Framework and the Foundry hosting package:
pip install -U agent-framework agent-framework-foundry-hosting azure-identity python-dotenv
The agent_framework_foundry_hosting package provides the host servers for the
Foundry protocols:
ResponsesHostServerfor the OpenAI-compatible/responsesendpoint.InvocationsHostServerfor the generic/invocationsendpoint.
Add the Agent Framework and Foundry hosting packages to your project:
dotnet add package Microsoft.Agents.AI
dotnet add package Microsoft.Agents.AI.Foundry.Hosting
dotnet add package Azure.AI.Projects
dotnet add package Azure.Identity
For the Invocations protocol, also add the Invocations server package:
dotnet add package Azure.AI.AgentServer.Invocations
These packages provide the host extensions for the Foundry protocols:
AddFoundryResponsesandMapFoundryResponsesfor the OpenAI-compatible/responsesendpoint.AddInvocationsServerandMapInvocationsServerfor the generic/invocationsendpoint.
Choose a hosting protocol
Hosted agents can expose one or more protocols. Start with Responses for most conversational agents.
| Protocol | Endpoint | Use when |
|---|---|---|
| Responses | /responses |
You want OpenAI-compatible chat, streaming, response history, and conversation threading. |
| Invocations | /invocations |
You want a custom JSON shape, a webhook-style endpoint, or non-conversational processing. |
For background on protocol behavior and sessions, see Hosted agents and Manage hosted agent sessions.
Configure environment variables
Set the project endpoint and model deployment name for local development:
export FOUNDRY_PROJECT_ENDPOINT="https://<resource>.services.ai.azure.com/api/projects/<project>"
export AZURE_AI_MODEL_DEPLOYMENT_NAME="gpt-4.1"
In PowerShell:
$env:FOUNDRY_PROJECT_ENDPOINT="https://<resource>.services.ai.azure.com/api/projects/<project>"
$env:AZURE_AI_MODEL_DEPLOYMENT_NAME="gpt-4.1"
When the same code runs as a hosted agent in Foundry, the platform injects
FOUNDRY_PROJECT_ENDPOINT and AZURE_AI_MODEL_DEPLOYMENT_NAME at runtime.
Responses protocol
Use the Responses protocol when you want an OpenAI-compatible chat endpoint with streaming, response history, and conversation threading.
Create a Responses host
Create a file named main.py with a minimal Agent Framework agent that uses a
Foundry model.
import os
from agent_framework import Agent
from agent_framework.foundry import FoundryChatClient
from agent_framework_foundry_hosting import ResponsesHostServer
from azure.identity import DefaultAzureCredential
from dotenv import load_dotenv
# Load environment variables from a .env file when present.
load_dotenv()
def main() -> None:
client = FoundryChatClient(
project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
credential=DefaultAzureCredential(),
)
agent = Agent(
client=client,
instructions="You are a friendly assistant. Keep your answers brief.",
# The hosting infrastructure manages conversation history, so the
# service doesn't need to store it.
default_options={"store": False},
)
server = ResponsesHostServer(agent)
server.run()
if __name__ == "__main__":
main()
What this snippet does: Creates an Agent Framework agent backed by a Foundry
model through FoundryChatClient, then passes the agent to
ResponsesHostServer. The host starts an HTTP server and exposes the agent
through POST /responses. By default, the server binds to port 8088.
Reference: Microsoft Agent Framework documentation
Run the app locally:
python main.py
Create a Program.cs file with a minimal Agent Framework agent that uses a
Foundry model through the Responses protocol.
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Foundry.Hosting;
var projectEndpoint = new Uri(
Environment.GetEnvironmentVariable("FOUNDRY_PROJECT_ENDPOINT")
?? throw new InvalidOperationException("FOUNDRY_PROJECT_ENDPOINT is not set."));
var deployment =
Environment.GetEnvironmentVariable("AZURE_AI_MODEL_DEPLOYMENT_NAME")
?? "gpt-4o";
// Create the agent via the AI project client using the Responses API.
AIAgent agent = new AIProjectClient(projectEndpoint, new DefaultAzureCredential())
.AsAIAgent(
model: deployment,
instructions: "You are a friendly assistant. Keep your answers brief.",
name: "assistant",
description: "A simple general-purpose AI assistant");
// Host the agent as a Foundry hosted agent using the Responses API.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddFoundryResponses(agent);
var app = builder.Build();
app.MapFoundryResponses();
app.Run();
What this snippet does: Creates an AIAgent from the Foundry project client,
registers it as a Foundry Responses host with AddFoundryResponses, and maps
the POST /responses endpoint with MapFoundryResponses. By default, the host
serves on port 8088.
Reference: AIProjectClient | DefaultAzureCredential
Run the app locally:
dotnet run
Test the Responses endpoint
Send a non-streaming Responses request to the local server.
Bash:
curl -sS -H "Content-Type: application/json" \
-X POST http://localhost:8088/responses \
-d '{"input":"Give me one practical tip for testing hosted agents.","stream":false}'
PowerShell:
$body = @{
input = "Give me one practical tip for testing hosted agents."
stream = $false
} | ConvertTo-Json
Invoke-RestMethod `
-Uri http://localhost:8088/responses `
-Method Post `
-Body $body `
-ContentType "application/json"
The server responds with a JSON object that contains the response text and a
response ID. For streaming responses, set stream to true. The host emits
Responses API server-sent events, such as response.created,
response.output_text.delta, and response.completed.
Multi-turn conversations
To continue a conversation, pass the previous response ID in the
previous_response_id field of the next request:
curl -sS -H "Content-Type: application/json" \
-X POST http://localhost:8088/responses \
-d '{"input":"Can you make that more concise?","previous_response_id":"<previous-response-id>","stream":false}'
When the agent runs in Foundry, the same pattern works through the hosted agent
Responses endpoint. If later turns also need the same hosted sandbox filesystem,
include agent_session_id or use a conversation ID. For details, see
Manage hosted agent sessions.
Invocations protocol
Use the Invocations protocol when your callers can't use the Responses API
request shape or when your scenario isn't a chat conversation. The Invocations
host manages session state through an agent_session_id query parameter and
response header.
Create an Invocations host
Use the same agent setup as the Responses example, but start
InvocationsHostServer instead of ResponsesHostServer.
import os
from agent_framework import Agent
from agent_framework.foundry import FoundryChatClient
from agent_framework_foundry_hosting import InvocationsHostServer
from azure.identity import DefaultAzureCredential
from dotenv import load_dotenv
# Load environment variables from a .env file when present.
load_dotenv()
def main() -> None:
client = FoundryChatClient(
project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
credential=DefaultAzureCredential(),
)
agent = Agent(
client=client,
instructions="You are a friendly assistant. Keep your answers brief.",
default_options={"store": False},
)
server = InvocationsHostServer(agent)
server.run()
if __name__ == "__main__":
main()
What this snippet does: Hosts the Agent Framework agent through POST /invocations. The host manages per-session state through the
agent_session_id query parameter and response header.
Reference: Microsoft Agent Framework documentation
The Invocations protocol uses an InvocationHandler that you implement to
process each request. Register the Invocations server and your handler, then map
the endpoints.
using Azure.AI.AgentServer.Invocations;
using Microsoft.Agents.AI;
var builder = WebApplication.CreateBuilder(args);
// Register your agent and the Invocations server services.
builder.Services.AddInvocationsServer();
builder.Services.AddScoped<InvocationHandler, MyInvocationHandler>();
var app = builder.Build();
// Map the Invocations protocol endpoints:
// POST /invocations - invoke the agent
// GET /invocations/{id} - get result
// POST /invocations/{id}/cancel - cancel
app.MapInvocationsServer();
app.Run();
What this snippet does: Registers the Invocations server services and your
InvocationHandler implementation, then maps the /invocations endpoints. You
implement MyInvocationHandler to define how each request is processed. For a
complete handler example, see the .NET Invocations sample.
Reference: AddInvocationsServer
Test the Invocations endpoint
Send a request to the local server:
curl -sS -X POST http://localhost:8088/invocations \
-H "Content-Type: application/json" \
-d '{"message":"My name is Alice.","stream":false}'
For multi-turn conversations, reuse the agent_session_id value from the
response header as the agent_session_id query parameter on the next request:
curl -sS -X POST "http://localhost:8088/invocations?agent_session_id=<session-id>" \
-H "Content-Type: application/json" \
-d '{"message":"What is my name?"}'
The platform doesn't store conversation history for the Invocations protocol.
Use the agent_session_id query parameter to route later calls to the same
hosted sandbox.
Deploy
Deploy by using the Azure Developer CLI (azd). Initialization requires a full sample azure.yaml, not a parameterized AgentManifest. Choose source-code or container deployment for the hosted runtime.
Hosted agent deployment requires the Foundry Project Manager role on the project. For details, see Deploy a hosted agent.
Install the Azure Developer CLI extension
Install the AI agent extension and sign in before you initialize a sample:
azd ext install azure.ai.agents
azd auth login
azd ai agent run starts your application locally; it doesn't build the deployment container. Docker is required when you choose a container deployment workflow that builds locally. See Run a hosted agent locally.
Initialize from a sample azure.yaml
Use a full azure.yaml sample for your language. --src . adopts the sample in the current directory.
Initialize the Python Responses sample:
mkdir my-agent-framework-agent
cd my-agent-framework-agent
azd ai agent init --src . --template https://github.com/microsoft-foundry/foundry-samples/blob/main/samples/python/hosted-agents/agent-framework/responses/01-basic/azure.yaml
This sample replaces the earlier parameterized Python manifest. It declares a Foundry project and a model deployment. Check model availability and quota for its model, SKU, and region before provisioning.
Initialize the Hosted ChatClient Agent sample against an existing Foundry project:
mkdir my-agent-framework-agent
cd my-agent-framework-agent
azd ai agent init --src . --template https://github.com/microsoft/agent-framework/blob/main/dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-ChatClientAgent/azure.yaml --project-id "<foundry-project-resource-id>"
azd env set AZURE_AI_MODEL_DEPLOYMENT_NAME "<existing-model-deployment-name>"
Install the .NET 10 SDK before running this sample locally. The template uses the dotnet_10 hosted runtime with remote dependency resolution.
To reuse an existing project with either sample, pass its ARM resource ID with --project-id. Set AZURE_AI_MODEL_DEPLOYMENT_NAME to a compatible deployment in that project. Don't pass a legacy agent.manifest.yaml wrapper to init.
Provision Azure resources
If the initialized project uses a new Foundry project and model deployment, provision the Azure resources first:
azd provision
Provisioning creates the resources declared by the template. The Python source-code sample declares a Foundry project and model deployment; it doesn't require a container registry. Additional telemetry infrastructure isn't created automatically.
Run the agent locally
Run the agent host locally through azd:
azd ai agent run
The host serves on http://localhost:8088. In another terminal, invoke the
local protocol endpoint:
azd ai agent invoke --local "Hello!"
You can also call the endpoint directly with curl:
curl -X POST http://localhost:8088/responses \
-H "Content-Type: application/json" \
-d '{"input": "Hello!"}'
Deploy to Foundry
Deploy the agent:
azd deploy
For these source-code samples, deployment uploads a ZIP of the source for remote build, then deploys the agent to the Foundry hosted runtime. It doesn't build and push an image to a project container registry.
The Foundry hosting infrastructure injects runtime environment variables into the agent, including:
FOUNDRY_PROJECT_ENDPOINT: The endpoint URL for the Foundry project where the agent is deployed.AZURE_AI_MODEL_DEPLOYMENT_NAME: The model deployment name selected duringazd ai agent init.APPLICATIONINSIGHTS_CONNECTION_STRING: The connection string when Application Insights is configured for the agent.
For complete deployment concepts, permissions, and management details, see Deploy a hosted agent and Manage hosted agent lifecycle.
Troubleshooting
Use this checklist to diagnose common issues while developing hosted agents with Agent Framework.
The model can't be reached in the hosted container
Confirm that the hosted agent version includes AZURE_AI_MODEL_DEPLOYMENT_NAME,
and that the agent identity has permission to call the Foundry project. The
platform sets FOUNDRY_PROJECT_ENDPOINT; your code should read that variable
when running in Foundry.
Conversation state doesn't continue
For the Responses protocol, pass previous_response_id or a conversation ID
on later turns.
For the Invocations protocol, the platform doesn't store conversation history.
Use an agent_session_id query parameter to route later calls to the same
hosted sandbox.
Protocol version mismatch
If requests fail after an upgrade, confirm that your manifest and hosting package both use protocol version 2.0.0. Protocol version 1.0.0 is no longer supported.