> ## Content Index
> Fetch the complete content index at: https://www.azurebrasil.cloud/llms.txt
> Use this file to discover other available public pages before exploring further.

# Criando um agente com Microsoft Foundry Toolboxes e .NET
- URL: https://www.azurebrasil.cloud/blog/criando-um-agente-com-microsoft-foundry-toolboxes-e-net/
- Published: 2026-06-12T12:10:40.000Z
- Updated: 2026-06-12T12:10:40.000Z
- Author: Talles Valiatti

O [Microsoft Foundry Agent Service](https://learn.microsoft.com/en-us/azure/foundry/agents/overview?wt.mc%5Fid=MVP%5F407589&ref=azurebrasil.cloud) é uma plataforma gerenciada da Microsoft para criação, implantação e escalabilidade de agentes de IA. Um agente combina três componentes essenciais: um modelo do catálogo do Foundry, instruções que definem o comportamento e ferramentas que dão acesso a dados ou ações externas. O Foundry cuida de toda a infraestrutura, incluindo identidade gerenciada, escalabilidade automática e observabilidade, para que o desenvolvedor foque na lógica do agente.  
Um ponto de entrada central para interagir com esses agentes é a [Responses API](https://learn.microsoft.com/en-us/azure/foundry/openai/how-to/responses?wt.mc%5Fid=MVP%5F407589&ref=azurebrasil.cloud), que unifica recursos das APIs de chat completions e Assistants em uma única interface stateful. Ela permite criar respostas, encadear turnos de conversa via **previous\_response\_id** ou conversations, e integrar ferramentas como MCP servers, Web Search e Code Interpreter diretamente no ciclo de inferência. 

Com o pacote [Azure.AI.Projects.OpenAI](https://learn.microsoft.com/en-us/dotnet/api/overview/azure/ai.projects.openai-readme?view=azure-dotnet-preview&wt.mc%5Fid=MVP%5F407589&ref=azurebrasil.cloud), é possível consumir essa API em .NET com suporte nativo a autenticação via **DefaultAzureCredential**.  
À medida que o número de agentes em uma organização cresce, cada equipe tende a reimplementar as mesmas ferramentas de forma independente, duplicando credenciais e tornando a governança inconsistente. É aqui que os Toolboxes entram. Um [Toolbox](https://learn.microsoft.com/en-us/azure/foundry/agents/how-to/tools/toolbox?wt.mc%5Fid=MVP%5F407589&ref=azurebrasil.cloud) é um recurso gerenciado no Foundry que agrupa ferramentas variadas, como MCP servers, Web Search, Azure AI Search e Code Interpreter, em um único endpoint MCP-compatível. Qualquer agente ou runtime MCP pode consumir esse endpoint, independentemente do framework utilizado.

  
O Toolbox expõe as ferramentas por meio de um endpoint no formato **{project\_endpoint}/toolboxes/{toolbox\_name}/mcp?api-version=v1**. O versionamento é explícito: ao criar uma nova versão do toolbox, a versão anterior continua sendo servida até que você promova a nova como padrão. Isso dá controle total sobre quando as mudanças entram em produção, sem necessidade de redeployment nos agentes consumidores.

  
Neste artigo, construiremos uma .NET Web API que hospeda um agente programaticamente usando o Foundry SDK. O agente será configurado com dois tipos de ferramenta: o [**Microsoft Learn MCP Server**](https://learn.microsoft.com/en-us/training/support/mcp?wt.mc%5Fid=MVP%5F407589&ref=azurebrasil.cloud), que dá ao agente acesso à documentação oficial da Microsoft em tempo real, e a Web Search tool, que permite buscas na internet com grounding via Bing . Todo o ciclo de criação do toolbox, configuração da project connection e criação do agente acontecerá automaticamente no primeiro acesso à nossa API.  

Para executar o projeto, você precisará de uma assinatura Azure ativa, ter o .NET 10 SDK instalado e possuir um projeto no Microsoft Foundry configurado. Na página principal do projeto no portal, localize o endpoint de conexão da API, que será usado na configuração da aplicação.

![](https://storage.ghost.io/c/00/52/0052dced-0017-4d07-b190-1f5c48e0ab59/content/images/2026/06/Screenshot-2026-06-09-at-14.56.10.png)

Para criar o projeto .NET, execute o seguinte comando no terminal:

```bash
dotnet new webapi -n ToolboxesAgent.Api
cd ToolboxesAgent.Api
```

  
Com o projeto criado, instale os pacotes NuGet necessários. O **Azure.AI.Projects** fornece o **AIProjectClient** e as operações administrativas de criação de agentes e toolboxes. O **Azure.AI.Projects.Agents** disponibiliza as APIs como **AgentToolboxes**, **DeclarativeAgentDefinition** e **ProjectsAgentTool**. O **Azure.AI.Projects.OpenAI** expõe a Responses API com suporte a conversações e envio de mensagens via **ProjectResponsesClient**. O **Azure.Identity** provê o **DefaultAzureCredential**, que resolve automaticamente a identidade via Azure CLI em desenvolvimento ou Managed Identity em produção.

```bash
dotnet add package Azure.AI.Projects --prerelease
dotnet add package Azure.AI.Projects.Agents --prerelease
dotnet add package Azure.AI.Projects.OpenAI --prerelease
dotnet add package Azure.Identity
```

O arquivo de projeto final ficará assim:

```xml
<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net10.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <NoWarn>AAIP001;OPENAI001</NoWarn>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Azure.AI.Projects" Version="*-*" />
    <PackageReference Include="Azure.AI.Projects.Agents" Version="*-*" />
    <PackageReference Include="Azure.AI.Projects.OpenAI" Version="*-*" />
    <PackageReference Include="Azure.Identity" Version="*" />
    <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.8" />
  </ItemGroup>

</Project>
```

Os warnings **AAIP001** e **OPENAI001** são suprimidos porque os pacotes ainda estão em preview e emitem avisos por padrão. A versão \`\*-\*\` nos três pacotes Azure AI garante que sempre seja utilizada a versão mais recente de preview disponível no NuGet.

  
Com os pacotes instalados, configure o **appsettings.json**. Cada propriedade será lida pela classe FoundryOptions e tem um papel específico no ciclo de vida do agente.

```json
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "Foundry": {
    "ProjectEndpoint": "<your-project-endpoint>",
    "ProjectResourceId": "<your-project-arm-resource-id>",
    "ModelDeploymentName": "<your-model-deployment-name>",
    "ToolboxName": "<your-toolbox-name>",
    "ToolboxDescription": "<your-toolbox-description>",
    "ToolboxMcpServerLabel": "<your-toolbox-mcp-label>",
    "ToolboxMcpServerUrl": "<your-toolbox-mcp-url>",
    "AgentName": "<your-agent-name>",
    "AgentInstructions": "<your-agent-instructions>",
    "AgentMcpServerLabel": "<your-agent-mcp-label>",
    "ProjectConnectionName": "<your-project-connection-name>",
    "ProjectConnectionAudience": "https://ai.azure.com"
  }
}

```

- `ProjectEndpoint`: endpoint do projeto no Foundry, no formato `https://<account>.services.ai.azure.com/api/projects/<project>`.
- `ProjectResourceId`: ARM Resource ID completo do projeto, seguindo o padrão `/subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>/providers/Microsoft.CognitiveServices/accounts/<accountName>/projects/<projectName>`. É utilizado pela REST API de gerenciamento do Azure para criar a project connection.
- `ModelDeploymentName`: nome do deployment do modelo, como `gpt-5-mini`.
- `ToolboxName`: nome do toolbox que será criado programaticamente.
- `ToolboxDescription`: descrição do toolbox que será criado programaticamente.
- `ToolboxMcpServerLabel`: label do MCP server externo que o toolbox irá expor.
- `ToolboxMcpServerUrl`: URL do MCP server externo que o toolbox irá expor. Para o Microsoft Learn MCP, a URL é `https://learn.microsoft.com/api/mcp`.
- `AgentName`: nome do agente.
- `AgentInstructions`: instruções que definem o comportamento do agente.
- `AgentMcpServerLabel`: label MCP pelo qual o agente se conectará ao endpoint do toolbox.
- `ProjectConnectionName`: nome da connection que o Foundry criará para autenticar o acesso do agente ao toolbox.
- `ProjectConnectionAudience`: escopo de autenticação da connection. Para recursos do Foundry, o valor padrão é `https://ai.azure.com`.

Crie a classe **FoundryOptions** no diretório **Services:**

```csharp
namespace ToolboxesAgent.Api.Services;

public class FoundryOptions
{
    public string ProjectEndpoint { get; set; } = string.Empty;
    public string ProjectResourceId { get; set; } = string.Empty;
    public string ModelDeploymentName { get; set; } = string.Empty;

    public string ToolboxName { get; set; } = string.Empty;
    public string ToolboxDescription { get; set; } = string.Empty;
    public string ToolboxMcpServerLabel { get; set; } = string.Empty;
    public string ToolboxMcpServerUrl { get; set; } = string.Empty;

    public string AgentName { get; set; } = string.Empty;
    public string AgentInstructions { get; set; } = string.Empty;
    public string AgentMcpServerLabel { get; set; } = string.Empty;

    public string ProjectConnectionName { get; set; } = string.Empty;
    public string ProjectConnectionAudience { get; set; } = string.Empty;
}
```

Cada propriedade mapeia diretamente para uma chave da seção Foundry no appsettings.json. O padrão [Options do ASP.NET Core](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/options?view=aspnetcore-10.0&wt.mc%5Fid=MVP%5F407589&ref=azurebrasil.cloud) fará a vinculação automaticamente via **Configure<FoundryOptions>** no **Program.cs**.  

Antes de implementar a lógica principal, crie os [DTOs](https://learn.microsoft.com/pt-br/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-5?wt.mc%5Fid=MVP%5F407589&ref=azurebrasil.cloud) no diretório **Dtos**. Eles definem os contratos de entrada e saída dos endpoints:

```csharp
namespace ToolboxesAgent.Api.Dtos;

public record CreateConversationResponse(string ConversationId);
```

```csharp
namespace ToolboxesAgent.Api.Dtos;

public record SendMessageRequest(string ConversationId, string Message);
```

```csharp
namespace ToolboxesAgent.Api.Dtos;

public record SendMessageResponse(string Response);
```

**CreateConversationResponse** retorna o ID da conversa criada no Foundry. **SendMessageRequest** carrega o ID da conversa e a mensagem do usuário. **SendMessageResponse** encapsula o texto de resposta gerado pelo agente.  
Agora chegamos ao núcleo da solução: a classe **AgentService**. Ela implementa toda a orquestração com o Foundry, desde a criação do toolbox até o envio e recebimento de mensagens. 

Crie o arquivo **AgentService.cs** no diretório **Services**:

```csharp
using System.Net.Http.Headers;
using System.Net.Http.Json;
using Azure.AI.Projects;
using Azure.AI.Projects.Agents;
using Azure.Core;
using Microsoft.Extensions.Options;
using OpenAI.Responses;

namespace ToolboxesAgent.Api.Services;

public class AgentService(
    IOptions<FoundryOptions> options,
    TokenCredential credential,
    IHttpClientFactory httpClientFactory)
{
    private const string ManagementScope = "https://management.azure.com/.default";

    private readonly FoundryOptions _options = options.Value;
    private readonly SemaphoreSlim _initializationLock = new(1, 1);
    private ProjectsAgentVersion? _agentVersion;

    public async Task<string> CreateConversationAsync(CancellationToken cancellationToken = default)
    {
        await EnsureFoundryResourcesAsync(cancellationToken);

        AIProjectClient projectClient = CreateProjectClient();

        Azure.AI.Extensions.OpenAI.ProjectConversation conversation = await projectClient.ProjectOpenAIClient
            .GetProjectConversationsClient()
            .CreateProjectConversationAsync(
                new Azure.AI.Extensions.OpenAI.ProjectConversationCreationOptions(),
                cancellationToken);

        return conversation.Id;
    }

    public async Task<string> SendMessageAsync(
        string conversationId,
        string userMessage,
        CancellationToken cancellationToken = default)
    {
        await EnsureFoundryResourcesAsync(cancellationToken);

        AIProjectClient projectClient = CreateProjectClient();

        Azure.AI.Extensions.OpenAI.AgentReference agentReference = new(name: _options.AgentName, version: null);

        Azure.AI.Extensions.OpenAI.ProjectResponsesClient responsesClient = projectClient.ProjectOpenAIClient
            .GetProjectResponsesClientForAgent(
                defaultAgent: agentReference,
                defaultConversationId: conversationId);

        ResponseResult response = await responsesClient.CreateResponseAsync(
            userInputText: userMessage,
            previousResponseId: null,
            cancellationToken: cancellationToken);

        return response.GetOutputText();
    }

    private async Task EnsureFoundryResourcesAsync(CancellationToken cancellationToken)
    {
        if (_agentVersion is not null)
            return;

        await _initializationLock.WaitAsync(cancellationToken);

        try
        {
            if (_agentVersion is not null)
                return;

            AIProjectClient projectClient = CreateProjectClient();

            ToolboxVersion toolboxVersion = await CreateToolboxVersionAsync(projectClient, cancellationToken);

            string toolboxMcpEndpoint = BuildToolboxMcpEndpoint();

            await CreateProjectConnectionAsync(toolboxMcpEndpoint, cancellationToken);

            _agentVersion = CreateAgentVersion(projectClient, toolboxMcpEndpoint);

            Console.WriteLine($"Toolbox: {toolboxVersion.Name} v{toolboxVersion.Version}");
            Console.WriteLine($"Toolbox MCP endpoint: {toolboxMcpEndpoint}");
            Console.WriteLine($"Project connection: {_options.ProjectConnectionName}");
            Console.WriteLine($"Agent: {_agentVersion.Name} v{_agentVersion.Version}");
        }
        finally
        {
            _initializationLock.Release();
        }
    }

    private AIProjectClient CreateProjectClient() =>
        new(
            endpoint: new Uri(_options.ProjectEndpoint),
            tokenProvider: credential);

    private async Task<ToolboxVersion> CreateToolboxVersionAsync(
        AIProjectClient projectClient,
        CancellationToken cancellationToken)
    {
        AgentToolboxes toolboxClient =
            projectClient.AgentAdministrationClient.GetAgentToolboxes();

        McpTool mcpTool = ResponseTool.CreateMcpTool(
            serverLabel: _options.ToolboxMcpServerLabel,
            serverUri: new Uri(_options.ToolboxMcpServerUrl),
            toolCallApprovalPolicy: new McpToolCallApprovalPolicy(
                GlobalMcpToolCallApprovalPolicy.NeverRequireApproval));

        ProjectsAgentTool mcpProjectTool = ProjectsAgentTool.AsProjectTool(mcpTool);

        ProjectsAgentTool webSearchProjectTool = ProjectsAgentTool.AsProjectTool(
            ResponseTool.CreateWebSearchTool());

        return await toolboxClient.CreateToolboxVersionAsync(
            name: _options.ToolboxName,
            tools: [mcpProjectTool, webSearchProjectTool],
            description: _options.ToolboxDescription,
            cancellationToken: cancellationToken);
    }

    private async Task CreateProjectConnectionAsync(
        string toolboxMcpEndpoint,
        CancellationToken cancellationToken)
    {
        AccessToken managementToken = await credential.GetTokenAsync(
            new TokenRequestContext([ManagementScope]),
            cancellationToken);

        string requestUri =
            $"https://management.azure.com{_options.ProjectResourceId.TrimEnd('/')}/connections/{_options.ProjectConnectionName}?api-version=2025-10-01-preview";

        using HttpClient httpClient = httpClientFactory.CreateClient();
        using HttpRequestMessage request = new(HttpMethod.Put, requestUri);

        request.Headers.Authorization =
            new AuthenticationHeaderValue("Bearer", managementToken.Token);

        request.Content = JsonContent.Create(new
        {
            name = _options.ProjectConnectionName,
            type = "Microsoft.MachineLearningServices/workspaces/connections",
            properties = new
            {
                authType = "ProjectManagedIdentity",
                category = "RemoteTool",
                target = toolboxMcpEndpoint,
                isSharedToAll = true,
                audience = _options.ProjectConnectionAudience,
                metadata = new
                {
                    ApiType = "Azure"
                }
            }
        });

        using HttpResponseMessage response = await httpClient.SendAsync(request, cancellationToken);

        if (!response.IsSuccessStatusCode)
        {
            string body = await response.Content.ReadAsStringAsync(cancellationToken);

            throw new InvalidOperationException(
                $"Failed to create Foundry project connection. Status: {(int)response.StatusCode} {response.ReasonPhrase}. Body: {body}");
        }
    }

    private ProjectsAgentVersion CreateAgentVersion(
        AIProjectClient projectClient,
        string toolboxMcpEndpoint)
    {
        McpTool toolboxMcpTool = ResponseTool.CreateMcpTool(
            serverLabel: _options.AgentMcpServerLabel,
            serverUri: new Uri(toolboxMcpEndpoint),
            toolCallApprovalPolicy: new McpToolCallApprovalPolicy(
                GlobalMcpToolCallApprovalPolicy.NeverRequireApproval));

        toolboxMcpTool.ProjectConnectionId = _options.ProjectConnectionName;

        DeclarativeAgentDefinition agentDefinition = new(_options.ModelDeploymentName)
        {
            Instructions = _options.AgentInstructions,
            Tools =
            {
                toolboxMcpTool
            }
        };

        return projectClient.AgentAdministrationClient.CreateAgentVersion(
            agentName: _options.AgentName,
            options: new(agentDefinition));
    }

    private string BuildToolboxMcpEndpoint() =>
        $"{_options.ProjectEndpoint.TrimEnd('/')}/toolboxes/{_options.ToolboxName}/mcp?api-version=v1";
}

```

O **AgentService** recebe três dependências via Primary Constructor. **IOptions<FoundryOptions>** carrega as configurações do **appsettings.json.** **TokenCredential** é o **DefaultAzureCredential** registrado como singleton, utilizado tanto para autenticar com o Foundry SDK quanto para obter tokens da Azure Management API. **IHttpClientFactory** é usado para chamar a REST API de gerenciamento do Azure ao criar a project connection. O campo **\_agentVersion** guarda a referência do agente após a inicialização, evitando que ele seja recriado a cada requisição. 

**CreateConversationAsync()** Garante que o agente e o toolbox existam chamando **EnsureFoundryResourcesAsync**, cria um **AIProjectClient** e usa o cliente de conversations para criar uma nova conversa no Foundry, retornando seu ID.

**SendMessageAsync() c**ria um **AgentReference** com o nome do agente configurado e obtém um **ProjectResponsesClient** associado ao agente e à conversa. A chamada **CreateResponseAsync** envia a mensagem ao agente, que usa as ferramentas do toolbox para elaborar a resposta, retornando o texto final via **GetOutputText()**.  

O método **EnsureFoundryResourcesAsync** é o ponto central da inicialização lazy. Ele usa double-checked locking com **SemaphoreSlim** para garantir que a criação dos recursos aconteça exatamente uma vez, mesmo sob carga paralela.

  
**EnsureFoundryResourcesAsync()** Implementa o padrão double-checked locking verificando **\_agentVersion** antes e depois de adquirir o semáforo. Coordena toda a sequência de inicialização: criação do toolbox, construção do endpoint MCP, criação da project connection e, por fim, registro do agente.  
**CreateProjectClient() i**nstancia um **AIProjectClient** com o endpoint do projeto e o TokenCredential injetado.

  
**CreateToolboxVersionAsync()** Obtém o cliente **AgentToolboxes** a partir do **AgentAdministrationClient**. Cria um **McpTool** com **NeverRequireApproval** apontando para o Microsoft Learn MCP Server e um **WebSearchTool.** Ambos são convertidos para **ProjectsAgentTool** via **AsProjectTool** antes de serem passados ao **CreateToolboxVersionAsync**, que cria ou atualiza a versão do toolbox no Foundry.

Após a criação do toolbox, o endpoint MCP consumer pode ser construído localmente:

```csharp
private string BuildToolboxMcpEndpoint() =>
        $"{_options.ProjectEndpoint.TrimEnd('/')}/toolboxes/{_options.ToolboxName}/mcp?api-version=v1";
```

**BuildToolboxMcpEndpoint()** compõe a URL do consumer endpoint do toolbox, que sempre aponta para a **default\_version**. Esse é o endereço que o agente usará para invocar as ferramentas em tempo de execução.

O passo seguinte é criar a project connection, que autentica o acesso do agente ao endpoint MCP do toolbox. Essa operação é feita via REST API de gerenciamento do Azure, pois o SDK ainda não expõe essa funcionalidade diretamente.

**CreateProjectConnectionAsync() o**btém um token de acesso com o escopo **https://management.azure.com/.default** e faz um HTTP PUT para a REST API de gerenciamento do Azure, criando uma connection do tipo **RemoteTool** com autenticação via **ProjectManagedIdentity**. O campo **target** aponta para o endpoint MCP do toolbox e **isSharedToAll** garante que a connection seja acessível a todos os agentes do projeto.

**CreateAgentVersion() c**ria um **McpTool** cujo **serverUri** é o endpoint MCP do toolbox e define ProjectConnectionId com o nome da connection criada anteriormente, essa vinculação é o que permite ao agente se autenticar ao invocar as ferramentas em runtime. O **DeclarativeAgentDefinition** combina o modelo, as instruções e a ferramenta MCP para definir o comportamento do agente. 

O método **CreateAgentVersion** registra o agente no Foundry e retorna um **ProjectsAgentVersion** com nome e versão.

Agora crie os endpoints no diretório Endpoints. O primeiro gerencia a criação de conversas:

```csharp
using ToolboxesAgent.Api.Dtos;
using ToolboxesAgent.Api.Services;

namespace ToolboxesAgent.Api.Endpoints;

public static partial class ConversationEndpoints
{
    public static void MapConversationEndpoints(this WebApplication app)
    {
        app.MapPost("/conversations", CreateConversationAsync);
    }

    private static async Task<IResult> CreateConversationAsync(AgentService service)
    {
        var conversationId = await service.CreateConversationAsync();

        return Results.Ok(new CreateConversationResponse(conversationId));
    }
}
```

**MapConversationEndpoints() r**egistra o endpoint \`POST /conversations\` como extension method em **WebApplication**.

**CreateConversationAsync()** delega a criação da conversa ao **AgentService** e retorna um **CreateConversationResponse** com o ID gerado pelo Foundry.  
O segundo endpoint gerencia o envio de mensagens:

```csharp
using ToolboxesAgent.Api.Dtos;
using ToolboxesAgent.Api.Services;

namespace ToolboxesAgent.Api.Endpoints;

public static partial class MessageEndpoints
{
    public static void MapMessageEndpoints(this WebApplication app)
    {
        app.MapPost("/messages", SendMessageAsync);
    }

    private static async Task<IResult> SendMessageAsync(
        SendMessageRequest request,
        AgentService service)
    {
        var response = await service.SendMessageAsync(request.ConversationId, request.Message);

        return Results.Ok(new SendMessageResponse(response));
    }
}
```

**MapMessageEndpoints()** registra o endpoint **POST /messages** como extension method em **WebApplication**.  
**SendMessageAsync()** recebe o **SendMessageRequest** com o ID da conversa e a mensagem do usuário, delega ao **AgentService** e retorna um **SendMessageResponse** com o texto gerado pelo agente.  

Com os endpoints definidos, configure o **Program.cs** para registrar todos os serviços e mapear as rotas:

```csharp
using Azure.Core;
using Azure.Identity;
using ToolboxesAgent.Api.Endpoints;
using ToolboxesAgent.Api.Services;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddOpenApi();
builder.Services.AddHttpClient();

builder.Services.Configure<FoundryOptions>(
    builder.Configuration.GetSection("Foundry"));

builder.Services.AddSingleton<TokenCredential>(new DefaultAzureCredential());
builder.Services.AddSingleton<AgentService>();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.MapOpenApi();
}

app.UseHttpsRedirection();

app.MapConversationEndpoints();
app.MapMessageEndpoints();

app.Run();
```

**AddOpenApi()** adiciona suporte ao OpenAPI para documentação dos endpoints. **AddHttpClient()** registra o IHttpClientFactory utilizado pelo **AgentService** para chamar a REST API do Azure. **Configure<FoundryOptions>** vincula a seção **Foundry** do **appsettings.json** ao tipo **FoundryOptions**. O **DefaultAzureCredential** é registrado como singleton do tipo **TokenCredential**, ele tenta resolver a identidade automaticamente via Azure CLI em desenvolvimento e via Managed Identity em produção. 

O **AgentService** também é singleton para que a inicialização lazy ocorra exatamente uma vez durante o ciclo de vida da aplicação.

Para testar a API, crie o arquivo **ToolboxesAgent.Api.http** na raiz do projeto:

```http
@host = http://localhost:5011

### Create Conversation
POST {{host}}/conversations
Content-Type: application/json

### Send Message
POST {{host}}/messages
Content-Type: application/json

{
  "conversationId": "<conversation-id>",
  "message": "<user-message>"
}
```

Antes de executar a API, autentique-se no Azure via CLI. O **DefaultAzureCredential** usará essa sessão automaticamente em ambiente de desenvolvimento:

```bash
az login

```

Com a autenticação configurada, inicie a aplicação:

```bash
dotnet run
```

Agora execute o primeiro request chamando **POST /conversations**. O response terá o seguinte formato:

```json
{
  "conversationId": "conv_339afda4b162a68a00eeXUo4lXo8yPgHSTpduWTmq3ZXUcZ4jh"
}
```

Obs: o id retornado será diferente a cada execução, pois é gerado dinamicamente pelo Foundry.

Copie o **conversationId** retornado e substitua o valor no request de envio de mensagem.

Note que na primeira chamada, o AgentService irá criar o toolbox, a project connection e o agente no Foundry antes de criar a conversa. Nas chamadas subsequentes, esses recursos já existirão e a inicialização será ignorada. 

![](https://storage.ghost.io/c/00/52/0052dced-0017-4d07-b190-1f5c48e0ab59/content/images/2026/06/Screenshot-2026-06-11-at-10.09.28.png)

![](https://storage.ghost.io/c/00/52/0052dced-0017-4d07-b190-1f5c48e0ab59/content/images/2026/06/Screenshot-2026-06-11-at-10.10.32.png)

![](https://storage.ghost.io/c/00/52/0052dced-0017-4d07-b190-1f5c48e0ab59/content/images/2026/06/Screenshot-2026-06-11-at-10.10.59.png)

Para o primeiro teste, envie a mensagem: "Explain how Azure Functions TimerTrigger works and provide a short C# example. It is required to consume this info using the MCP. If no answer is received, respond 'I could not find the answer to your question.'" 

O agente irá consultar o Microsoft Learn MCP Server, buscar a documentação oficial sobre Azure Functions TimerTrigger e retornar uma resposta fundamentada com exemplo de código.

![](https://storage.ghost.io/c/00/52/0052dced-0017-4d07-b190-1f5c48e0ab59/content/images/2026/06/test1.png)

Para o segundo teste, envie a mensagem: "Explain me https://devblogs.microsoft.com/foundry/introducing-toolboxes-in-foundry. Use the MCP. If no answer is received, respond 'I could not find the answer to your question.'" 

Nesse caso, o agente usará as ferramentas disponíveis (web search) no toolbox para buscar e sintetizar as informações do blog post sobre Toolboxes no Foundry.

![](https://storage.ghost.io/c/00/52/0052dced-0017-4d07-b190-1f5c48e0ab59/content/images/2026/06/Screenshot-2026-06-09-at-09.48.37.png)

Ao longo deste artigo, construímos uma .NET Web API que orquestra agentes com Microsoft Foundry Toolboxes. 

A arquitetura inicializa programaticamente o toolbox com o Microsoft Learn MCP Server e o Web Search, registra a project connection para autenticação via Managed Identity, cria o agente por meio da Responses API e expõe dois endpoints simples para gerenciar conversas e mensagens. 

Você já pode baixar o projeto por esse [link](https://github.com/TallesValiatti/MicrosoftFoundryToolBoxDotnetApp?ref=azurebrasil.cloud), e não esquece de me seguir no [LinkedIn](https://www.linkedin.com/in/tallesvaliatti/?ref=azurebrasil.cloud)!

Até a próxima, abraços!