Compartilhar via


Criar um agente openai .NET usando um servidor MCP no Azure Container Apps

Este artigo mostra como criar um agente do PROTOCOLO MCP usando .NET. Neste exemplo, o cliente MCP (escrito em C#/.NET) conecta-se a um servidor MCP (escrito em TypeScript) para gerenciar uma lista de tarefas pendentes. O cliente encontra as ferramentas disponíveis do servidor e as envia para um modelo Azure OpenAI. Os usuários podem então conversar com o sistema todo usando o idioma cotidiano.

Acessar o código

Confira o modelo de IA do Bloco de Construção de Agente MCP da OpenAI. Este exemplo mostra como criar um agente OpenAI que usa um cliente MCP para consumir um servidor MCP existente.

Vá para a seção passo a passo do código para entender como esse exemplo funciona.

Visão geral da arquitetura

O diagrama a seguir mostra a arquitetura simples do aplicativo de exemplo: Diagrama mostrando a arquitetura de Visual Studio Code hospedando o agente e o cliente MCP para o MCP Server.

  • Cliente MCP: conecta-se ao servidor MCP e localiza as ferramentas disponíveis
  • Chat Client: funciona com Azure OpenAI para entender o idioma natural
  • Interface do usuário do Blazor: fornece uma interface da Web em que os usuários podem conversar
  • Camada de transporte: usa eventos enviados pelo servidor (SSE) para enviar mensagens em tempo real
  • Autenticação: usa tokens JWT para manter a conexão segura

O servidor MCP é executado como um aplicativo em contêineres no Azure Container Apps (ACA). Ele usa um back-end TypeScript para fornecer ferramentas ao cliente MCP por meio do Protocolo de Contexto de Modelo. Todas as ferramentas funcionam com um banco de dados SQLite de back-end.

Observação

Visite Como construir um servidor MCP TypeScript usando Azure Container Apps para ver o passo a passo do código do servidor MCP TypeScript descrito neste artigo.

Custo

Para manter os custos baixos, este exemplo usa tipos de preço básicos ou de consumo para a maioria dos recursos. Ajuste o nível conforme necessário e exclua os recursos quando terminar para evitar custos.

Pré-requisitos

Um contêiner de desenvolvimento inclui todas as dependências necessárias para este artigo. Você pode executá-lo em GitHub Codespaces (em um navegador) ou localmente usando Visual Studio Code.

Para seguir este artigo, verifique se você atende a estes pré-requisitos:

Implantar um modelo gpt-5-mini do Foundry utilizando a extensão Foundry para VS Code

Implante um modelo gpt-5-mini usando a Extensão Foundry no Visual Studio Code seguindo estas etapas:

Criar um projeto do Foundry e implantar o modelo

Criar a string de conexão do modelo OpenAI

  1. Depois que o gpt-5-mini modelo for implantado, clique com o botão direito do mouse no modelo na extensão Foundry e selecione Copiar chave de API para copiar a chave de API do modelo para a área de transferência.

  2. Em seguida, clique com o botão direito do mouse no modelo implantado gpt-5-mini na extensão Foundry e selecione Copiar endpoint para copiar o endpoint do modelo para sua área de transferência, conforme mostrado na captura de tela a seguir.

    Captura de tela mostrando o menu de contexto do modelo implantado com as opções Copiar Endpoint e Copiar Chave de API realçadas.

  3. Por fim, crie um connection string para o modelo gpt-5-mini implantado usando o ponto de extremidade copiado e a chave de API no seguinte formato: Endpoint=<AZURE_OPENAI_ENDPOINT>;Key=<AZURE_OPENAI_API_KEY>. Você precisará desse connection string mais adiante no artigo.

Abrir o ambiente de desenvolvimento

Siga estas etapas para configurar um ambiente de desenvolvimento pré-configurado com todas as dependências necessárias.

GitHub Codespaces executa um contêiner de desenvolvimento gerenciado por GitHub com Visual Studio Code para a Web como a interface. Use GitHub Codespaces para a configuração mais simples, pois ele vem com as ferramentas e dependências necessárias pré-instaladas para este artigo.

Importante

Todas as contas GitHub podem usar codespaces por até 60 horas gratuitas por mês com duas instâncias principais. Para obter mais informações, consulte armazenamento e horas principais incluídos mensalmente no GitHub Codespaces.

Use as etapas a seguir para criar um novo GitHub Codespace no branch main do repositório Azure-Samples/openai-mcp-agent-dotnet GitHub.

  1. Clique com o botão direito do mouse no botão a seguir e selecione Abrir link em uma nova janela. Essa ação permite que você tenha o ambiente de desenvolvimento e a documentação aberta lado a lado.

    Open em GitHub Codespaces

  2. Na página Criar codespace, analise e selecione Criar novo codespace.

  3. Aguarde o inicio do codespace. Pode levar alguns minutos.

  4. Verifique se o nome do modelo implantado é gpt-5-mini. Se o modelo implantado for diferente, atualize src/McpTodo.ClientApp/appsettings.json com o nome de implantação correto.

    {
      "OpenAI": {
        // Make sure this is the right deployment name.
        "DeploymentName": "gpt-5-mini"
      }
    }
    
  5. Entre em Azure com a CLI do Desenvolvedor do Azure no terminal na parte inferior da tela.

    azd auth login
    
  6. Copie o código do terminal e cole-o em um navegador. Siga as instruções para autenticar com sua conta Azure.

Você faz o restante das tarefas neste contêiner de desenvolvimento.

Observação

Para rodar o agente MCP localmente:

  1. Configure seu ambiente conforme descrito na seção Getting started no repositório de exemplo.
  2. Instale o servidor MCP seguindo as instruções na seção Get MCP Server App no repositório de exemplo.
  3. Execute o agente MCP localmente seguindo as instruções na seção Run localmente no repositório de exemplo.
  4. Vá para a seção Usar o agente TODO MCP para prosseguir.

Implantar e executar

O repositório de exemplo contém todos os arquivos de código e configuração para a implantação do agente MCP no Azure. As etapas a seguir orientam você pelo processo de implantação de Azure do agente MCP de exemplo.

Implantar no Azure

Importante

Os recursos do Azure desta seção começam a gerar custo imediatamente, mesmo se você interromper o comando antes que ele seja concluído.

Definir o token JWT

  • Defina o token JWT para o servidor MCP executando o seguinte comando no terminal na parte inferior da tela:

    # zsh/bash
    ./scripts/set-jwttoken.sh
    
    # PowerShell
    ./scripts/Set-JwtToken.ps1
    

Adicionar token JWT à configuração do ambiente azd

  1. Adicione o token JWT à configuração do ambiente azd executando o seguinte comando no terminal na parte inferior da tela:

    # zsh/bash
    env_dir=".azure/$(azd env get-value AZURE_ENV_NAME)"
    mkdir -p "$env_dir"
    cat ./src/McpTodo.ServerApp/.env >> "$env_dir/.env"
    
    # PowerShell
    $dotenv = Get-Content ./src/McpTodo.ServerApp/.env
    $dotenv | Add-Content -Path ./.azure/$(azd env get-value AZURE_ENV_NAME)/.env -Encoding utf8 -Force
    

    Observação

    Por padrão, o aplicativo cliente MCP é protegido pelo recurso de autenticação interna da ACA. Você pode desativar esse recurso antes de executar azd up definindo:

    azd env set USE_LOGIN false
    
  2. Execute o seguinte comando Azure Developer CLI para provisionamento de recursos do Azure e implantação de código:

    azd up
    
  3. Use a tabela a seguir para responder aos prompts:

    Rápido Resposta
    Nome do ambiente Use um nome curto e minúsculo. Adicione seu nome ou alias. Por exemplo, my-mcp-agent. O nome do ambiente torna-se parte do nome do grupo de recursos.
    Subscription Escolha a assinatura na qual você deseja criar recursos.
    Local (para hospedagem) Escolha o local de implantação do modelo na lista.
    Cadeia de conexão da OpenAI Cole a string de conexão do modelo OpenAI que você criou anteriormente na seção Criar a string de conexão do modelo OpenAI.
  4. A implantação do aplicativo leva de 5 a 10 minutos.

  5. Após a conclusão da implantação, você pode acessar o agente MCP usando a URL na saída. A URL tem esta aparência:

    https://<env-name>.<container-id>.<region>.azurecontainerapps.io
    
  6. Abra a URL em um navegador da Web para usar o agente MCP.

Usar o agente TODO MCP

Depois que o agente MCP estiver em execução, você poderá usar as ferramentas que ele fornece no modo de agente. Para usar ferramentas MCP no modo de agente:

  1. Navegue até a URL do aplicativo cliente e entre no aplicativo.

    Observação

    se você definir o valor USE_LOGIN como false, talvez você não precise fazer login.

  2. Insira um prompt como "Preciso enviar um email ao meu gerente na quarta-feira" na caixa de entrada do chat e observe como as ferramentas são automaticamente invocadas conforme necessário.

  3. O agente MCP usa as ferramentas fornecidas pelo servidor MCP para atender à solicitação e retornar uma resposta na interface de chat.

  4. Experimente outros prompts como:

    Give me a list of to dos.
    Set "meeting at 1pm".
    Give me a list of to dos.
    Mark #1 as completed.
    Delete #1 from the to-do list.
    

Explore o código

O repositório de exemplo contém todos os arquivos de código e configuração para a implantação do agente MCP no Azure. As seções a seguir orientam você pelos principais componentes do código do agente MCP.

Configuração e configuração do cliente MCP

O aplicativo configura o cliente MCP em Program.cs. Essa configuração define como se conectar e quais opções usar. O código usa vários padrões avançados, incluindo a integração do .NET Aspire e padrões-padrão de serviço:

builder.Services.AddSingleton<IMcpClient>(sp =>
{
    var config = sp.GetRequiredService<IConfiguration>();
    var loggerFactory = sp.GetRequiredService<ILoggerFactory>();

    var uri = new Uri(config["McpServers:TodoList"]!);

    var clientTransportOptions = new SseClientTransportOptions()
    {
        Endpoint = new Uri($"{uri.AbsoluteUri.TrimEnd('/')}/mcp"),
        AdditionalHeaders = new Dictionary<string, string>
        {
            { "Authorization", $"Bearer {config["McpServers:JWT:Token"]!}" }
        }
    };
    var clientTransport = new SseClientTransport(clientTransportOptions, loggerFactory);

    var clientOptions = new McpClientOptions()
    {
        ClientInfo = new Implementation()
        {
            Name = "MCP Todo Client",
            Version = "1.0.0",
        }
    };

    return McpClientFactory.CreateAsync(clientTransport, clientOptions, loggerFactory).GetAwaiter().GetResult();
});

Principais detalhes de implementação:

  • Configuração de Transporte: SseClientTransportOptions dá suporte ao SSE (Eventos Server-Sent) e ao transporte HTTP que pode ser transmitido. O método de transporte depende da URL do ponto de extremidade – aqueles que terminam com /sse usam Server-Sent Events, enquanto os que terminam com /mcp usam HTTP transmitido. Essa abordagem permite a comunicação em tempo real entre o cliente e o servidor
  • Cabeçalhos de autenticação: os tokens JWT são inseridos no AdditionalHeaders para manter a comunicação do servidor segura
  • Informações do cliente: McpClientOptions informa ao servidor o nome e a versão do cliente
  • Padrão de Fábrica: McpClientFactory.CreateAsync() conecta e conclui o handshake de protocolo

Integração de configurações padrão do serviço .NET Aspire

O aplicativo usa o padrão de serviços do .NET Aspire para preocupações transversais.

// McpTodo.ServiceDefaults/Extensions.cs
public static TBuilder AddServiceDefaults<TBuilder>(this TBuilder builder) where TBuilder : IHostApplicationBuilder
{
    builder.ConfigureOpenTelemetry();
    builder.AddDefaultHealthChecks();
    builder.Services.AddServiceDiscovery();
    
    builder.Services.ConfigureHttpClientDefaults(http =>
    {
        // Turn on resilience by default
        http.AddStandardResilienceHandler();
        // Turn on service discovery by default
        http.AddServiceDiscovery();
    });
    
    return builder;
}

Os benefícios padrão do serviço:

  • Métodos de extensão composable: o sistema usa um padrão de construtor limpo para adicionar recursos compartilhados
  • Manipuladores de resiliência padrão: o sistema adiciona regras internas de repetição, disjuntor e tempo limite para você
  • Integração de descoberta de serviço: o sistema localiza serviços automaticamente em ambientes de contêiner
  • OpenTelemetry por padrão: o sistema obtém o monitoramento completo sem nenhum trabalho de instalação

O diagrama a seguir mostra a relação entre interesses transversais e serviços de aplicação.

Diagrama mostrando a relação entre aspectos transversais e serviços de aplicação.

Resolução de URL de configuração

O exemplo inclui uma resolução de URL sofisticada para ambientes diferentes:

// AspireUrlParserExtensions.cs
public static Uri Resolve(this Uri uri, IConfiguration config)
{
    var absoluteUrl = uri.ToString();
    if (absoluteUrl.StartsWith("https+http://"))
    {
        var appname = absoluteUrl.Substring("https+http://".Length).Split('/')[0];
        var https = config[$"services:{appname}:https:0"]!;
        var http = config[$"services:{appname}:http:0"]!;
        
        return string.IsNullOrWhiteSpace(https) ? new Uri(http) : new Uri(https);
    }
    // Handle other URL formats...
}

Recursos de Gerenciamento de Configuração:

  • Abstração da Descoberta de Serviços: o sistema lida com as URLs de desenvolvimento e produção de forma limpa
  • Negociação de protocolo: o sistema escolhe HTTPS primeiro e, em seguida, volta para HTTP
  • Configuration Convention: o sistema usa padrões de configuração de serviço .NET Aspire padrão

Implementação de autenticação

Este exemplo usa a autenticação JWT (Token Web JSON) para proteger a conexão entre o cliente MCP e o servidor.

dotnet user-secrets --project ./src/McpTodo.ClientApp set McpServers:JWT:Token "$TOKEN"

Observação

Os scripts criaram a variável $TOKEN automaticamente quando você executou o script Bash (set-jwttoken.sh) ou PowerShell (Set-JwtToken.ps1) anteriormente na seção Deploy para Azure. Esses scripts executam as seguintes etapas:

  1. Executar npm run generate-token no aplicativo do servidor MCP para criar um token JWT
  2. Analisar o arquivo gerado .env para extrair o valor JWT_TOKEN
  3. Armazene automaticamente nos segredos do usuário do .NET para o MCPClient

O cliente MCP recupera o token JWT da configuração e o inclui nos cabeçalhos HTTP para autenticação ao se conectar ao servidor MCP:

AdditionalHeaders = new Dictionary<string, string>
{
    { "Authorization", $"Bearer {config["McpServers:JWT:Token"]!}" }
}

Essa abordagem garante:

  • Comunicação Segura: o sistema só permite que clientes com tokens válidos se conectem ao servidor MCP
  • Autorização Baseada em Token: os tokens JWT permitem que o sistema verifique os usuários sem armazenar dados de sessão
  • Gerenciamento de Configuração: o sistema armazena tokens confidenciais com segurança em segredos do usuário durante o desenvolvimento

Integração de Autenticação para Azure Container Apps

A infraestrutura mostra padrões avançados de autenticação usando Azure Container Apps recursos internos de autenticação e autorização ("Autenticação Fácil"):

// containerapps-authconfigs.bicep
resource containerappAuthConfig 'Microsoft.App/containerApps/authConfigs@2024-10-02-preview' = {
  properties: {
    identityProviders: {
      azureActiveDirectory: {
        enabled: true
        registration: {
          clientId: clientId
          openIdIssuer: openIdIssuer
        }
      }
    }
    login: {
      tokenStore: {
        enabled: true
        azureBlobStorage: {
          blobContainerUri: '${storageAccount.properties.primaryEndpoints.blob}/token-store'
          managedIdentityResourceId: userAssignedIdentity.id
        }
      }
    }
  }
}

Recursos avançados de autenticação:

  • Zero-Code Authentication: Azure Container Apps fornece autenticação interna
  • Identidade Gerenciada para Armazenamento: o sistema armazena tokens com segurança sem cadeias de conexão
  • Credenciais de identidade federadas: o sistema habilita a identidade da carga de trabalho para autenticação no estilo Kubernetes

O diagrama a seguir mostra o handshake de segurança entre os componentes.

Diagrama mostrando o handshake de segurança entre componentes.

Descoberta e registro de ferramentas

O cliente MCP descobre as ferramentas disponíveis do servidor durante a inicialização do componente em Chat.razor:

protected override async Task OnInitializedAsync()
{
    messages.Add(new(ChatRole.System, SystemPrompt));
    tools = await McpClient.ListToolsAsync();
    chatOptions.Tools = [.. tools];
}

Como funciona a descoberta de ferramentas:

  1. Consulta de servidor: McpClient.ListToolsAsync() envia uma solicitação ao servidor MCP para listar as ferramentas disponíveis
  2. Recuperação de esquema: o servidor envia definições de ferramenta de volta com nomes, descrições e esquemas de entrada
  3. Registro da ferramenta: o sistema registra ferramentas com o ChatOptions objeto, disponibilizando-as para o cliente OpenAI
  4. Segurança de Tipo: a classe McpClientTool herda de AIFunction, proporcionando uma integração suave com Microsoft.Extensions.AI

O diagrama a seguir mostra como os esquemas de ferramentas são analisados e registrados:

Diagrama mostrando o fluxo de descoberta e registro da ferramenta.

Integração do OpenAI e invocação de função

A configuração do cliente de chat demonstra como as ferramentas MCP se integram ao Azure OpenAI:

var chatClient = openAIClient.GetChatClient(config["OpenAI:DeploymentName"]).AsIChatClient();

builder.Services.AddChatClient(chatClient)
                .UseFunctionInvocation()
                .UseLogging();

Benefícios da integração:

  • Chamada automática de função: A .UseFunctionInvocation() extensão ativa a execução automática da ferramenta com base nas decisões do LLM
  • Acesso fácil à ferramenta: as ferramentas MCP funcionam como funções internas para o modelo OpenAI
  • Processamento de resposta: o sistema adiciona automaticamente os resultados da ferramenta ao fluxo de conversa

Implementação de chat em tempo real

A interface de chat em Chat.razor demonstra respostas de streaming e execução de ferramentas com padrões Blazor avançados.

private async Task AddUserMessageAsync(ChatMessage userMessage)
{
    CancelAnyCurrentResponse();

    // Add the user message to the conversation
    messages.Add(userMessage);
    chatSuggestions?.Clear();
    await chatInput!.FocusAsync();

    // Stream and display a new response from the IChatClient
    var responseText = new TextContent("");
    currentResponseMessage = new ChatMessage(ChatRole.Assistant, [responseText]);
    currentResponseCancellation = new();
    await foreach (var update in ChatClient.GetStreamingResponseAsync([.. messages], chatOptions, currentResponseCancellation.Token))
    {
        messages.AddMessages(update, filter: c => c is not TextContent);
        responseText.Text += update.Text;
        ChatMessageItem.NotifyChanged(currentResponseMessage);
    }

    // Store the final response in the conversation, and begin getting suggestions
    messages.Add(currentResponseMessage!);
    currentResponseMessage = null;
    chatSuggestions?.Update(messages);
}

Recursos de implementação de streaming:

  • Atualizações em Tempo Real: GetStreamingResponseAsync() envia atualizações de resposta gradativamente
  • Execução da ferramenta: o sistema processa chamadas de função automaticamente durante o streaming
  • Capacidade de resposta da interface do usuário: ChatMessageItem.NotifyChanged() atualiza a interface do usuário em tempo real
  • Suporte ao cancelamento: os usuários podem cancelar operações de execução prolongada

Padrões avançados de interface do usuário do Blazor

A implementação usa padrões avançados de interface do usuário para atualizações em tempo real:

Memory-Safe tratamento de eventos:

// ChatMessageItem.razor
private static readonly ConditionalWeakTable<ChatMessage, ChatMessageItem> SubscribersLookup = new();

public static void NotifyChanged(ChatMessage source)
{
    if (SubscribersLookup.TryGetValue(source, out var subscriber))
    {
        subscriber.StateHasChanged();
    }
}

Integração personalizada de componentes da Web:

// ChatMessageList.razor.js
window.customElements.define('chat-messages', class ChatMessages extends HTMLElement {
    connectedCallback() {
        this._observer = new MutationObserver(mutations => this._scheduleAutoScroll(mutations));
        this._observer.observe(this, { childList: true, attributes: true });
    }
    
    _scheduleAutoScroll(mutations) {
        // Debounce the calls and handle smart auto-scrolling
        cancelAnimationFrame(this._nextAutoScroll);
        this._nextAutoScroll = requestAnimationFrame(() => {
            const addedUserMessage = mutations.some(m => 
                Array.from(m.addedNodes).some(n => 
                    n.parentElement === this && n.classList?.contains('user-message')));
            // Smart scrolling logic...
        });
    }
});

Gerenciamento de estado avançado:

// Chat.razor
private void CancelAnyCurrentResponse()
{
    // If a response was cancelled while streaming, include it in the conversation so it's not lost
    if (currentResponseMessage is not null)
    {
        messages.Add(currentResponseMessage);
    }
    
    currentResponseCancellation?.Cancel();
    currentResponseMessage = null;
}

Benefícios da interface do usuário do Blazor:

  • Componentes web híbridos: o sistema combina o Blazor Server com elementos personalizados para melhorar o desempenho
  • Tratamento de Eventos Seguro para Memória: o sistema usa ConditionalWeakTable para evitar vazamentos de memória
  • Rolagem Automática Inteligente: o sistema fornece um comportamento de chat amigável com o debouncing
  • Cancelamento normal: o sistema salva o trabalho parcial quando os usuários cancelam operações

Fluxo de solicitação/resposta

Veja como uma interação típica do usuário flui pelo sistema:

  1. Entrada do usuário: O usuário digita uma mensagem como "Adicionar 'Comprar mantimentos' para minha lista de tarefas"
  2. Processamento de Mensagens: O sistema adiciona a mensagem ao histórico de conversas
  3. LLM Analysis: Azure OpenAI analisa a solicitação e decide quais ferramentas usar
  4. Descoberta de Ferramentas: o modelo localiza a ferramenta MCP certa (por exemplo, addTodo)
  5. Execução da ferramenta: o cliente MCP chama o servidor com os parâmetros necessários
  6. Processamento de resposta: o sistema adiciona a resposta do servidor à conversa
  7. Atualização da interface do usuário: o sistema mostra o resultado para o usuário em tempo real

O diagrama a seguir mostra como as mensagens fluem da entrada do usuário por meio do OpenAI para a execução da ferramenta e de volta para a interface do usuário:

Diagrama mostrando o fluxo de solicitação/resposta.

Gerenciamento de padrões assíncronos

O aplicativo demonstra padrões assíncronos sofisticados para operações em segundo plano:

// ChatSuggestions.razor
public void Update(IReadOnlyList<ChatMessage> messages)
{
    // Runs in the background and handles its own cancellation/errors
    _ = UpdateSuggestionsAsync(messages);
}

private async Task UpdateSuggestionsAsync(IReadOnlyList<ChatMessage> messages)
{
    cancellation?.Cancel();
    cancellation = new CancellationTokenSource();
    
    try
    {
        var response = await ChatClient.GetResponseAsync<string[]>(
            [.. ReduceMessages(messages), new(ChatRole.User, Prompt)],
            cancellationToken: cancellation.Token);
        // Handle response...
    }
    catch (Exception ex) when (ex is not OperationCanceledException)
    {
        await DispatchExceptionAsync(ex);
    }
}

Benefícios da tarefa em segundo plano:

  • Fire-and-Forget com Segurança: o sistema usa o padrão _ = com tratamento de exceção adequado
  • Redução de Contexto Inteligente: o sistema limita o histórico de conversas para evitar o excesso de tokens
  • Cancelamento inteligente: o sistema limpa corretamente as operações concorrentes

Tratamento de erros e resiliência

A implementação inclui vários padrões de resiliência:

private void CancelAnyCurrentResponse()
{
    // If a response was cancelled while streaming, include it in the conversation so it's not lost
    if (currentResponseMessage is not null)
    {
        messages.Add(currentResponseMessage);
    }

    currentResponseCancellation?.Cancel();
    currentResponseMessage = null;
}

Recursos de resiliência:

  • Cancelamento normal: o sistema salva respostas em andamento quando os usuários as cancelam
  • Recuperação de Conexão: o transporte SSE lida automaticamente com quedas de conexão.
  • Gerenciamento de Estado: o estado da interface do usuário permanece consistente durante erros
  • Integração de log: o sistema fornece log completo para depuração e monitoramento

Verificações de observabilidade e saúde

O aplicativo inclui padrões de observabilidade sofisticados:

Configuração de Verificação de Saúde Inteligente:

// Extensions.cs
public static WebApplication MapDefaultEndpoints(this WebApplication app)
{
    if (app.Environment.IsDevelopment())
    {
        // All health checks must pass for app to be considered ready
        app.MapHealthChecks(HealthEndpointPath);
        
        // Only health checks tagged with "live" must pass for app to be considered alive
        app.MapHealthChecks(AlivenessEndpointPath, new HealthCheckOptions
        {
            Predicate = r => r.Tags.Contains("live")
        });
    }
    return app;
}

OpenTelemetry com filtragem inteligente:

// Extensions.cs
.AddAspNetCoreInstrumentation(tracing =>
    // Exclude health check requests from tracing
    tracing.Filter = context =>
        !context.Request.Path.StartsWithSegments(HealthEndpointPath)
        && !context.Request.Path.StartsWithSegments(AlivenessEndpointPath)
)

Benefícios de observabilidade:

  • Endpoints cientes do ambiente: exposição de verificação de integridade com consciência de segurança
  • Liveness vs Readiness: padrões de verificação de saúde no estilo Kubernetes
  • Redução de ruído de telemetria: filtrando verificações rotineiras de integridade nos rastreamentos

Configuração e preparação do ambiente

O aplicativo dá suporte a vários ambientes por meio da configuração:

var openAIClient = Constants.GitHubModelEndpoints.Contains(endpoint.TrimEnd('/'))
                   ? new OpenAIClient(credential, openAIOptions)
                   : new AzureOpenAIClient(new Uri(endpoint), credential);

Opções de configuração:

  • Azure OpenAI: as implantações de produção normalmente usam Azure OpenAI Service
  • GitHub Models: cenários de desenvolvimento podem usar modelos de GitHub
  • Desenvolvimento Local: suporte para instâncias de servidor MCP locais
  • Container Deployment: Azure Container Apps para hospedagem de produção

Limpar os recursos

Depois de terminar de usar o agente MCP, limpe os recursos criados para evitar incorrer em custos desnecessários.

Para limpar recursos, siga estas etapas:

  • Exclua os recursos de Azure criados pela CLI do Desenvolvedor do Azure executando o seguinte comando no terminal na parte inferior da tela:

    azd down --purge --force
    

Limpar GitHub Codespaces

Exclua o ambiente GitHub Codespaces para maximizar suas horas gratuitas por núcleo.

Importante

Para obter mais informações sobre o armazenamento gratuito da sua conta GitHub e as horas de processamento, consulte Armazenamento e horas de núcleo mensais incluídos no GitHub Codespaces.

  1. Faça login no painel GitHub Codespaces.

  2. Localize seus Codespaces ativos criados a partir do repositório Azure-Samples/openai-mcp-agent-dotnet GitHub.

  3. Abra o menu de contexto do codespace e selecione Excluir.

Obter ajuda

Registre seu problema no Issues do repositório.

  • Construa um servidor TypeScript MCP usando Azure Container Apps