Skip to main content
Skip to content

Usando servidores MCP com o SDK do GitHub Copilot

O SDK do Copilot pode se integrar aos servidores MCP (Protocolo de Contexto de Modelo) para estender os recursos do assistente com ferramentas externas. Os servidores MCP são executados como processos separados e expõem ferramentas (funções) que Copilot podem invocar durante as conversas.

Observação

Esse é um recurso em evolução. Consulte issue #36 para acompanhar a discussão em andamento.

O que é MCP?

O PROTOCOLO MCP (Model Context Protocol) é um padrão aberto para conectar assistentes de IA a ferramentas externas e fontes de dados. Os servidores MCP podem:

  • Executar código ou scripts
  • Consultar bancos de dados
  • Acessar sistemas de arquivos
  • Chamar APIs externas
  • E muito mais

Tipos de servidores

O SDK dá suporte a dois tipos de servidores MCP:

TipoDescriptionCaso de uso
Local/StdioÉ executado como um subprocesso, comunica-se por meio de stdin/stdoutFerramentas locais, acesso a arquivos, scripts personalizados
HTTP/SSEServidor remoto acessado via HTTPServiços compartilhados, ferramentas hospedadas na nuvem

Configuration

Inspecionar a configuração e o ciclo de vida

session.rpc.mcp.listConfigured() é uma leitura de inventário passiva sem parâmetros. Ele não inicia ou reinicia servidores, autentica, aplica a política de sandbox ou aguarda a inicialização do servidor. A descoberta de configuração e a filtragem de política determinam quais servidores aparecem e os respectivos valores de enabled.

Esse RPC experimental requer uma versão alinhada do SDK/runtime. Sua resposta de pré-lançamento anterior permitia que live fosse omitido; os SDKs que usam o contrato de ciclo de vida necessário não dão suporte a essa forma de resposta mais antiga. Ao fornecer um runtime externo, atualize-o junto com o SDK. A versão geral do protocolo permanece inalterada e não identifica essa revisão experimental do contrato.

Cada entrada inclui live.status. Um servidor configurado sem servidor de runtime materializado mostra o status existente not_configured, mesmo quando enabled é true. Um servidor de runtime que foi explicitamente interrompido relata stopped. Os servidores materializados relatam seu ciclo de vida real, incluindo pending, connected, needs-authe failed; falhas incluem live.error quando disponíveis.

A configuração e o ciclo de vida descrevem fatos diferentes. Se a URL, a autenticação ou a fonte de configuração de um servidor forem alteradas enquanto uma conexão antiga permanecer ativa, o inventário ainda relatará com precisão o ciclo de vida real dessa conexão. Um status connected não significa que a configuração mais recente foi aplicada. O runtime controla esta observação; os clientes não devem substituir o estado armazenado em cache com base apenas no nome do servidor.

Inventory tenta novamente a substituição concorrente do grafo um número limitado de vezes e retorna um erro se não conseguir obter um instantâneo consistente. Ele nunca omite live para ocultar uma condição de corrida no grafo.

Apenas o nome startServer ou restartServer resolve e inicializa apenas o servidor solicitado após a retomada de uma sessão fria sem chamar list primeiro. Isso inclui configurações de usuário e plug-in e o servidor GitHub interno configurado por meio de githubMcpToolConfig. Ele não inicia outros servidores configurados nem substitui o estado desabilitado, os requisitos de autenticação, a política de sandbox ou a precedência da origem da configuração.

Node.js/TypeScript

import { CopilotClient } from "@github/copilot-sdk";

const client = new CopilotClient();
const session = await client.createSession({
    model: "gpt-5",
    mcpServers: {
        // Local MCP server (stdio)
        "my-local-server": {
            type: "local",
            command: "node",
            args: ["./mcp-server.js"],
            env: { DEBUG: "true" },
            cwd: "./servers",
            tools: ["*"],  // "*" = all tools, [] = none, or list specific tools
            timeout: 30000,
        },
        // Remote MCP server (HTTP)
        "github": {
            type: "http",
            url: "https://api.githubcopilot.com/mcp/",
            headers: { "Authorization": "Bearer ${TOKEN}" },
            tools: ["*"],
        },
    },
});

Python

import asyncio
from copilot import CopilotClient
from copilot.session import PermissionHandler

async def main():
    client = CopilotClient()
    await client.start()

    session = await client.create_session(on_permission_request=PermissionHandler.approve_all, model="gpt-5", mcp_servers={
        # Local MCP server (stdio)
        "my-local-server": {
            "type": "local",
            "command": "python",
            "args": ["./mcp_server.py"],
            "env": {"DEBUG": "true"},
            "cwd": "./servers",
            "tools": ["*"],
            "timeout": 30000,
        },
        # Remote MCP server (HTTP)
        "github": {
            "type": "http",
            "url": "https://api.githubcopilot.com/mcp/",
            "headers": {"Authorization": "Bearer ${TOKEN}"},
            "tools": ["*"],
        },
    })

    response = await session.send_and_wait("List my recent GitHub notifications")
    print(response.data.content)

    await client.stop()

asyncio.run(main())

Go

package main

import (
    "context"
    "log"
    copilot "github.com/github/copilot-sdk/go"
)

func main() {
    ctx := context.Background()
    client := copilot.NewClient(nil)
    if err := client.Start(ctx); err != nil {
        log.Fatal(err)
    }
    defer client.Stop()

    session, err := client.CreateSession(ctx, &copilot.SessionConfig{
        Model: "gpt-5",
        MCPServers: map[string]copilot.MCPServerConfig{
            "my-local-server": copilot.MCPStdioServerConfig{
                Command: "node",
                Args:    []string{"./mcp-server.js"},
                Tools:   []string{"*"},
            },
        },
    })
    if err != nil {
        log.Fatal(err)
    }
    defer session.Disconnect()

    // Use the session...
}

.NET

using GitHub.Copilot;

await using var client = new CopilotClient();
await using var session = await client.CreateSessionAsync(new SessionConfig
{
    Model = "gpt-5",
    McpServers = new Dictionary<string, McpServerConfig>
    {
        ["my-local-server"] = new McpStdioServerConfig
        {
            Command = "node",
            Args = new List<string> { "./mcp-server.js" },
            Tools = new List<string> { "*" },
        },
    },
});

Desabilitando servidores configurados por sessão

Defina disabledMcpServers como os nomes exatos do servidor MCP que não devem ser executados em uma sessão. A configuração tem como escopo a solicitação de criação ou retomada individual; ele não modifica as configurações globais do MCP ou a configuração do servidor.

const session = await client.createSession({
    mcpServers: {
        filesystem: { type: "local", command: "npx", args: ["-y", "@modelcontextprotocol/server-filesystem", "."] },
        github: { type: "http", url: "https://api.githubcopilot.com/mcp/" },
    },
    disabledMcpServers: ["github"],
});
SDKPropriedade de configuração
Node.jsdisabledMcpServers
Pythondisabled_mcp_servers
GoDisabledMCPServers
.NETDisabledMcpServers
JavasetDisabledMcpServers(...)
Rustwith_disabled_mcp_servers(...)

Na criação da sessão e em uma retomada a frio, os servidores desabilitados não são iniciados, e o ambiente de execução não inicia o processo de autenticação deles. Uma retomada residente não pode reverter um servidor que o ambiente de execução já iniciou. Os nomes correspondem exatamente.

Listando e recuperando prompts

O namespace de MCP gerado experimentalmente expõe os métodos session.mcp.prompts.list de JSON-RPC de protocolo e session.mcp.prompts.get. Use os acessadores do SDK específicos do idioma abaixo para chamá-los. Esses métodos têm como destino um servidor conectado na sessão atual; eles não combinam resultados de vários servidores.

SDKListar promptsReceber um prompt
Node.jssession.rpc.mcp.prompts.list(...)session.rpc.mcp.prompts.get(...)
Pythonsession.rpc.mcp.prompts.list(...)session.rpc.mcp.prompts.get(...)
Gosession.RPC.MCP.Prompts().List(...)session.RPC.MCP.Prompts().Get(...)
.NETsession.Rpc.Mcp.Prompts.ListAsync(...)session.Rpc.Mcp.Prompts.GetAsync(...)
Javasession.getRpc().mcp.prompts.list(...)session.getRpc().mcp.prompts.get(...)
Rustsession.rpc().mcp().prompts().list(...)session.rpc().mcp().prompts().get(...)

A listagem requer serverName e aceita um opaco cursoropcional. Cada chamada retorna uma página de definições de prompt tipadas e um(a) nextCursor opcional. Passe esse cursor em outra chamada à API de listagem para solicitar a próxima página. As definições incluem nomes, títulos opcionais e descrições e definições de argumento. Um argumento omitido com a flag required permanece distinto de false.

Obter um prompt requer serverName e promptName, com um dicionário opcional arguments cujos valores são cadeias de caracteres. Omitir arguments deixa os argumentos da solicitação MCP ausentes; passar {} envia um dicionário explicitamente vazio. O runtime preserva essa distinção para o servidor. O resultado contém uma descrição opcional e mensagens ordenadas com papéis tipados e JSON contentopaco. Inspecione cada bloco de conteúdo type antes de interpretá-lo; o conteúdo não é convertido em texto. Recursos aninhados, anotações, metadados, tipos de conteúdo desconhecidos e campos de conteúdo adicionais mantêm sua estrutura JSON. As extensões de servidor em descritores digitados, mensagens e envelopes de resultado estão disponíveis em additionalProperties. Uma extensão de servidor nomeada additionalProperties é preservada como uma entrada dentro desse mapa, não mesclada nele. O discriminador de nível superior do protocolo resultType: "complete" é consumido pelo runtime; ele não é retornado como um campo do SDK nem como uma extensão do servidor. As solicitações falharão explicitamente se o runtime não puder preservar a resposta bruta, incluindo quadros de resposta stdio que excedem o limite de captura de 1 MiB.

As mensagens de prompt retornadas não são enviadas automaticamente para o modelo ou usadas para executar ferramentas ou buscar recursos referenciados. Seu aplicativo decide como usar o resultado. Ao gerar esse resultado, um servidor MCP pode solicitar amostragem ou elicitação por meio de continuações com múltiplas idas e voltas. Essas solicitações usam os mesmos respondentes de host configurados que outras operações mcp; a recuperação de prompt não concede permissão adicional ou ignora a decisão do host. A ausência de manipulador ou um erro de manipulador faz a solicitação falhar, e uma recusa de elicitação é retornada ao servidor inalterada. As continuações somente de estado não invocam qualquer um dos dois respondentes.

Após um evento de sessão existente mcp.prompts.list_changed, liste os prompts do servidor especificado novamente para atualizar a exibição do aplicativo.

Aplicando a política de sandbox antes da inicialização do MCP

Passe sandboxConfig para createSession ou resumeSession para aplicar a política de sandbox durante a construção, antes que os servidores root-config ou de plug-in descobertos, ou os servidores MCP configurados explicitamente, sejam iniciados. Ele aceita a mesma configuração que session.rpc.options.update({ sandboxConfig }).

const sandboxConfig = {
    enabled: true,
    sandboxMcpServers: true,
    userPolicy: { network: { allowOutbound: false } },
};
const session = await client.createSession({
    onPermissionRequest: approveAll,
    sandboxConfig,
});

Forneça novamente a configuração em uma retomada a frio; a omissão preserva a política atual de uma sessão residente. Uma retomada residente não pode desfazer processos que já foram iniciados. A validação de política gerenciada usa a mesma semântica de host direto que uma atualização de opções: uma solicitação conflitante falha ao criar ou retomar em vez de voltar para uma sessão sem sandbox, com data.code definido como managed_sandbox_policy_conflict no erro JSON-RPC. O runtime não atribui um(a) sandboxConfigSource derivado(a) das configurações a essa configuração de host explícita.

Um options.update({ sandboxConfig }) idêntico posterior não reinicia servidores MCP, inclusive quando a política gerenciada normalizou a configuração. Uma política de sandbox MCP eficaz diferente mantém o comportamento de reinicialização habitual.

Verifique o runtime version retornado por server.connect (ConnectResult) em relação à release mínima do runtime que seu aplicativo requer para esse recurso. A versão do protocolo SDK não é um sinal de capacidade por recurso. Os runtimes mais antigos ignoram campos desconhecidos de criação/retomada, de modo que um aplicativo que dá suporte a eles pode enviar sandboxConfig na abertura e repeti-lo em uma atualização de opções de acompanhamento. Essa atualização é inofensiva em runtimes compatíveis, mas os runtimes mais antigos ainda podem iniciar o MCP antes de a atualização chegar; exija uma versão de runtime compatível quando o confinamento desde o primeiro processo for obrigatório.

Ferramenta de configuração

Você pode controlar quais ferramentas estão disponíveis para um servidor MCP usando o tools campo.

Permitir todas as ferramentas

Use "*" para habilitar todas as ferramentas fornecidas pelo servidor MCP:

tools: ["*"]

Permitir ferramentas específicas

Forneça uma lista de nomes de ferramentas para restringir o acesso:

tools: ["bash", "edit"]

Somente as ferramentas listadas estarão disponíveis para o agente.

Desabilitar todas as ferramentas

Use uma matriz vazia para desabilitar todas as ferramentas:

tools: []

Notes

  • O tools campo define quais ferramentas são permitidas.
  • Não há nenhuma configuração separada allowou disallow—o acesso à ferramenta é controlado diretamente por meio desta lista.

Início rápido: servidor MCP do sistema de arquivos

Aqui está um exemplo de trabalho completo usando o servidor MCP oficial @modelcontextprotocol/server-filesystem :

import { CopilotClient } from "@github/copilot-sdk";

async function main() {
    const client = new CopilotClient();

    // Create session with filesystem MCP server
    const session = await client.createSession({
        mcpServers: {
            filesystem: {
                type: "local",
                command: "npx",
                args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"],
                tools: ["*"],
            },
        },
    });

    console.log("Session created:", session.sessionId);

    // The model can now use filesystem tools
    const result = await session.sendAndWait({
        prompt: "List the files in the allowed directory",
    });

    console.log("Response:", result?.data?.content);

    await session.disconnect();
    await client.stop();
}

main();

Saída:

Session created: 18b3482b-bcba-40ba-9f02-ad2ac949a59a
Response: The allowed directory is `/tmp`, which contains various files
and subdirectories including temporary system files, log files, and
directories for different applications.

Dica

Você pode usar qualquer servidor MCP do Diretório de Servidores MCP. As opções populares incluem @modelcontextprotocol/server-github, @modelcontextprotocol/server-sqlitee @modelcontextprotocol/server-puppeteer.

Opções de configuração

Servidor local/stdio

PropriedadeTipoObrigatórioDescription
type
"local" ou "stdio"NoTipo de servidor (padrão é local)
commandstringYesComando a ser executado
argsstring[]YesArgumentos de comando
envobjectNoVariáveis de ambiente
cwdstringNoDiretório de trabalho
toolsstring[]NoFerramentas para habilitar (["*"] para todos, [] para nenhum)
timeoutnumberNoTempo limite em milissegundos

Servidor remoto (HTTP/SSE)

PropriedadeTipoObrigatórioDescription
type
"http" ou "sse"YesTipo de servidor
urlstringYesURL do servidor
headersobjectNoCabeçalhos HTTP (por exemplo, para autenticação)
oauthClientIdstringNoID de cliente não vazio para um cliente OAuth configurado estaticamente
oauthScopesstring[]NoMatriz não vazia de tokens de escopo RFC 6749 válidos. Requer oauthClientId; usado quando o desafio do servidor omite o escopo ou fornece um escopo vazio, antes do fallback de metadados de recurso protegido
oauthPublicClientbooleanNoSe o cliente OAuth configurado é público e não requer um segredo do cliente
oauthGrantTypestringNoTipo de concessão OAuth para o cliente configurado, como client_credentials
toolsstring[]NoFerramentas para habilitar
timeoutnumberNoTempo limite em milissegundos

Titularidade do OAuth para servidores remotos

Escolha um modelo de propriedade OAuth para cada tentativa de autenticação:

  1. Loopback gerenciado por runtime: chamada session.mcp.oauth.login sem um URI de redirecionamento. O runtime abre um ouvinte de retorno de chamada local e possui descoberta, PKCE, validação de estado, troca de tokens, persistência, atualização e reconexão.
  2. Callback hospedado gerenciado pelo runtime: Chame session.mcp.oauth.login com um URI de redirecionamento HTTPS público confiável. Seu host recebe o retorno de chamada, mas o runtime continua sendo proprietário do protocolo OAuth e das credenciais.
  3. OAuth gerenciado pelo host: use o manipulador de solicitação de autenticação MCP do SDK e retorne um token de acesso adquirido pelo host. Seu host possui autorização e refresh.

Não registre um manipulador OAuth gerenciado pelo host para uma tentativa de autenticação que usa um callback hospedado gerenciado pelo runtime. Aguarde até que o servidor remoto entre no estado needs-auth e chame o método gerado session.rpc.mcp.oauth.login diretamente com o nome do servidor e o URI de retorno de chamada:

{
    "serverName": "remote-mcp",
    "redirectUri": "https://agent.example.com/oauth/callback"
}

O cliente OAuth estático, CIMD ou registrado dinamicamente deve anunciar esse URI exato. O URI deve usar HTTPS e não deve conter uma query string ou fragmento. Quando a interação com o navegador é necessária, o resultado contém authorizationUrl e authorizationId. Abra authorizationUrl no navegador do usuário e mantenha authorizationId com a sessão de destino.

Depois que o servidor de autorização redirecionar para o ponto de extremidade, chame o método gerado session.rpc.mcp.oauth.complete :

{
    "authorizationId": "<opaque-state>",
    "callbackUrl": "https://agent.example.com/oauth/callback?code=...&state=..."
}

Construa callbackUrl a partir da origem e do caminho de redirecionamento público configurados mais a consulta original do retorno de chamada. Não passe uma URL de serviço interna nem confie em cabeçalhos X-Forwarded-* ou Forwarded fornecidos pelo cliente. O runtime valida a origem, a porta, o caminho, o estado e a resposta OAuth antes de aceitar a entrega. A troca de tokens, a persistência e a reconexão do MCP depois continuam de forma assíncrona.

Entregando um token de acesso rejeitado de volta ao runtime

Para uma solicitação OAuth de host com reason: "refresh" e runtimeRefreshSupported: true, seu manipulador pode retornar { "kind": "runtimeRefresh" } em vez de adquirir um token de acesso de substituição. O runtime executa a renovação não interativa usando seu grant salvo existente dentro da operação de autorização original. Ele não inicia um novo fluxo de consentimento ou chama o RPC de atualização independente authenticationStateChanged . A substituição mantém sua origem da concessão salva, portanto, a adoção posterior de token armazenado com escopo permanece disponível. Um token fornecido diretamente por um host não é marcado como um token armazenado e não pode ser substituído por esse caminho de adoção.

Retorne essa resposta somente quando a solicitação pendente indicar que há suporte. Uma funcionalidade ausente tem o valor false e retém o contrato herdado de token/cancelamento. Se um manipulador retornar o handoff para uma solicitação sem a capacidade, o SDK enviará cancelled em vez disso, portanto, a solicitação pendente não permanecerá aberta. Um token fornecido tem precedência sobre a transferência, e um cancelamento permanece um cancelamento.

SDKCapabilityResultado da transferência
Node.jsrequest.runtimeRefreshSupported{ kind: "runtimeRefresh" }
Pythonrequest["runtimeRefreshSupported"]{"kind": "runtimeRefresh"}
Go
MCPAuthRuntimeRefreshHandler argumento de capacidadeMCPAuthResultRuntimeRefresh()
.NETMcpAuthContext.RuntimeRefreshSupportedMcpAuthResult.RefreshInRuntime()
Java
McpAuthHandler.handleWithRuntimeRefresh argumento de capacidadeMcpAuthResponse.runtimeRefresh()
RustMcpAuthHandler::handle_with_runtime_refreshMcpAuthResponse::RuntimeRefresh

A aceitação da resposta reconhece a transferência, não a atualização, a reconexão ou a conclusão da execução da ferramenta. Para uma entrega aceita, mcp.oauth_completed é emitida uma vez, quando a reserva de autorização original atinge seu resultado terminal. Seu outcome usa apenas os valores existentes: token quando a recuperação foi bem-sucedida e cancelled quando foi cancelada ou falhou. O evento persistente mcp.oauth_recovery_completed carrega o mesmo requestId e o mesmo serverName e distingue o resultado terminal, incluindo reconexão: succeeded, cancelled, ou failed. As versões do SDK que antecedem esse evento recebem-no como um tipo de evento desconhecido.

Até que o runtime aceite uma runtimeRefresh resposta, as respostas existentes mantêm seu significado anterior. Uma resposta de host { kind: "cancelled" } recusa a solicitação; para uma refresh solicitação, o runtime pode solicitar a reautorização. Se nenhum host responder, o runtime retornará ao tratamento OAuth local comum, incluindo credenciais armazenadas em cache e não emitirá nenhum mcp.oauth_recovery_completed evento. Essa alteração não reclassifica uma resposta do host cancelled como Parada. A invocação original é preservada somente por meio de uma transferência aceita runtimeRefresh.

Após a aceitação, a invocação original pode tentar novamente após a instalação da credencial e se reconectar, superando as barreiras existentes de sessão, configuração, política e permissão. Parar o turno principal ou encerrar a sessão cancela a reserva de autorização original; a invocação interrompida não pode tentar novamente ou publicar um resultado posteriormente. Uma troca rotativa de grant já emitida pode terminar de persistir sua substituição após o cancelamento, mas não pode instalar credenciais obsoletas, reconectar ou retomar a invocação cancelada.

Uma autorização salva indisponível ou uma atualização com falha encerra a invocação original sem solicitar a reautorização interativa. Uma reconexão com falha também encerra a invocação; Obter um token com êxito não é um resultado de ferramenta bem-sucedido.

Invocações simultâneas ingressam na tentativa exata de autorização em andamento e recebem o resultado final. Um servidor conectado, um token de acesso retido ou uma tentativa bem-sucedida posterior não é evidência de que sua tentativa foi bem-sucedida. Cada invocação sobrevivente ainda verifica novamente seu próprio catálogo e permissão de ferramenta antes de tentar novamente; a falha combinada não inicia outra autorização interativa.

Os prazos HTTP do OAuth se aplicam a solicitações individuais, não à transferência completa nem à conclusão do armazenamento da concessão. O cancelamento pode retornar antes que um exchange emitido seja liquidado, e a liberação da sessão aguarda os workers de liquidação rastreados. Não há um prazo geral para conclusão, portanto, os hosts não devem tratar o cancelamento, a aceitação da transferência ou um tempo limite HTTP como prova de que todo o trabalho de armazenamento foi concluído.

Diagnóstico de MCP no escopo da sessão

Defina diagnostics: { sources: { mcp: { level: "debug" } } } quando você criar ou retomar uma sessão para ativar os diagnósticos do MCP. Cada origem tem off como padrão. Os níveis habilitados são error, warning, info, debug e trace. Essa configuração é separada do nível de processo do cliente logLevel.

Aviso

As entradas de diagnóstico podem conter conteúdo fornecido pelo usuário ou pelo servidor em todos os níveis habilitados: warning e acima podem incluir stderr do servidor, enquanto debug e trace também podem incluir cargas úteis do MCP, argumentos de ferramenta e caminhos. Trate cada entrada como confidencial. Não carregue automaticamente as entradas como telemetria ou exporte-as sem ação de host deliberada.

A API gerada session.rpc.diagnostics permite que os hosts configurem e leiam diagnósticos em memória com tamanho limitado e escopo de sessão. O MCP é a primeira e, no momento, a única fonte com suporte. Selecione-o explicitamente com sources: ["mcp"] ao ler; a leitura não habilita a captura. Use um loop de leitura interrompível por superfície de saída e mantenha seu cursor. Um loop de leitura possui seu cursor e apresentação; o runtime possui captura, filtragem, retenção, expiração do cursor e despertares.

import { approveAll, CopilotClient } from "@github/copilot-sdk";

const client = new CopilotClient();
const stop = new AbortController();
const appendLine = (line: string) => console.log(line);

await client.start();
const session = await client.createSession({
    onPermissionRequest: approveAll,
    diagnostics: { sources: { mcp: { level: "debug" } } },
});

try {
    let cursor: string | undefined;
    while (!stop.signal.aborted) {
        const page = await session.rpc.diagnostics.read({
            sources: ["mcp"],
            cursor,
            max: 100,
            waitMs: 30_000,
        });
        if (page.cursorStatus === "expired") {
            appendLine("MCP diagnostic entries were dropped.");
        }
        for (const entry of page.entries) {
            const detail = entry.details.data ? ` ${entry.details.data}` : "";
            appendLine(
                `${entry.timestamp} [${entry.level}] [${entry.source}:${entry.details.serverName}] ${entry.message}${detail}`,
            );
        }
        cursor = page.cursor;
    }
} finally {
    await session.disconnect();
    await client.stop();
}

O sinal de anulação interrompe o loop após a conclusão da leitura limitada atual; ele não é passado para a chamada RPC. Desabilitar a captura desperta uma leitura pendente.

A inicialização do MCP é sob demanda: habilitar ou ler o diagnóstico não inicia um servidor. Configure mcpServers na criação da sessão e use a sessão normalmente ou chame session.rpc.mcp.startServer({ serverName }) para um servidor instalado para solucionar problemas de inicialização sem fazer uma solicitação de modelo.

Cada registro tem source: "mcp", carimbo de data/hora, severidade, mensagem e opcional agentId para agentes não raiz. Seu details tipado contém o ciclo de vida, protocolo, HTTP ou categoria stderr, nome do servidor, um novo connectionId para cada tentativa de conexão e direção de protocolo opcional e dados de diagnóstico. A retenção do MCP é limitada a 1.024 registros e 4 MiB por sessão. Registros codificados individuais são limitados a 16 KiB e contêm truncated quando reduzidos. As leituras têm padrão de 100 registros, aceitam no máximo 500 e não consomem dados de outros leitores. Use droppedCount, quando presente em um cursor expirado, para mostrar a perda conhecida. Cada leitura bem-sucedida retorna um cursor e o status do cursor, incluindo leituras vazias. Mantenha o cursor retornado mesmo quando nenhum registro chegar. Um cursor pertence à seleção de origem do cursor; comece sem um cursor ao alterar essa seleção. Fontes ausentes, vazias, duplicadas ou sem suporte são rejeitadas, assim como cursores malformados e limites numéricos inválidos. Nem registros nem configurações de captura são salvos no histórico de sessão.

Chame session.rpc.diagnostics.configure({ sources: { mcp: { level: "off" } } }) para desabilitar a captura do MCP e limpar seu buffer retido. A configuração atualiza apenas as origens explicitamente nomeadas e retorna os níveis de origem efetivos. A configuração de origem vazia ou desconhecida é rejeitada; adicionar outra fonte com suporte no futuro não incluirá implicitamente um chamador existente nela.

Pare o loop de leitura do host também; as leituras, quando o registro em log está desativado, retornam imediatamente em vez de esperar. Um long poll pendente é ativado quando o registro em log está desabilitado. Omitir diagnostics durante uma retomada residente preserva sua configuração atual; uma sessão carregada a frio requer uma nova adesão. Habilitar o diagnóstico no estado inicial off pode iniciar a captura para uma conexão MCP já ativa. Depois que o diagnóstico tiver sido desabilitado com configure({ sources: { mcp: { level: "off" } } }), a reabilitação poderá retomar a captura para a mesma conexão ativa e sua ID de conexão existente. Registros que já estavam em processamento quando os diagnósticos foram desabilitados são descartados.

O ambiente de execução remove credenciais configuradas e reconhecidas estruturalmente dos diagnósticos HTTP antes que as entradas cheguem a essa API, mas isso não é uma garantia de que segredos arbitrários fornecidos pelo servidor estejam ausentes. Ele não expõe mapas de cabeçalho de solicitação ou resposta. Somente os metadados selecionados, como Content-Type, Accepte MCP-Protocol-Version, são elegíveis para captura, mas seus valores ainda não são confiáveis e podem conter conteúdo confidencial. Cabeçalhos de autenticação, cookies, IDs de sessão, valores de consulta, userinfo de URL e fragmentos são omitidos. Os caminhos de URL são mantidos para solução de problemas, portanto, não coloque credenciais em segmentos de caminho. Os payloads de protocolo e stderr também podem conter conteúdo do usuário ou segredos arbitrários fornecidos pelo servidor.

Troubleshooting

Ferramentas que não aparecem ou não estão sendo invocadas

  1. Verificar se o servidor MCP é iniciado corretamente

    • Verifique se o comando e os args estão corretos
    • Verifique se o processo do servidor não falha na inicialização
    • Procure por mensagens de erro no stderr
  2. Verificar a configuração da ferramenta

    • Certifique-se de que tools esteja definido como ["*"] ou liste as ferramentas específicas necessárias
    • Uma matriz [] vazia significa que nenhuma ferramenta está habilitada
  3. Verificar a conectividade para servidores remotos

    • Verifique se a URL está acessível
    • Verifique se os cabeçalhos de autenticação estão corretos

Problemas comuns

IssueSolução
"Servidor MCP não encontrado"Verifique se o caminho do comando está correto e executável
"Conexão recusada" (HTTP)Verifique a URL e verifique se o servidor está em execução
Erros de "tempo limite"Aumente o valor do timeout ou verifique o desempenho do servidor
As ferramentas funcionam, mas não são chamadasVerifique se o prompt exige claramente a funcionalidade da ferramenta

Para obter diretrizes detalhadas de depuração, consulte o Guia de depuração do servidor MCP.

Consulte também