Start Debugging

MCP C# SDK 2.3: McpClient.ServerInfo agora é anulável, e o seu build pode perceber

O ModelContextProtocol 2.3.0, lançado em 20 de outubro de 2026, muda McpClient.ServerInfo de Implementation para Implementation? porque servidores 2026-07-28 podem omitir a própria identidade em server/discover. Veja o motivo, o que quebra com warnings como erros e a correção de uma linha.

O MCP C# SDK 2.3.0 foi lançado em 20 de outubro de 2026 e traz uma mudança que uma versão minor normalmente não traria: McpClient.ServerInfo agora é anotado como Implementation? em vez de Implementation. A assinatura no CLR é idêntica, então nada quebra em runtime nem para chamadores já compilados. O que quebra é qualquer projeto com <Nullable>enable</Nullable> e <TreatWarningsAsErrors>true</TreatWarningsAsErrors> que acesse a propriedade diretamente.

Por que um servidor conectado pode não ter identidade

Na revisão 2026-07-28 do protocolo, o handshake é server/discover em vez do initialize legado. Na descoberta, o metadado io.modelcontextprotocol/serverInfo é opcional. Um servidor pode responder à descoberta, anunciar suas ferramentas e atender chamadas sem nunca dizer quem é.

Antes da 2.3.0, o SDK não modelava isso. Conectar a um servidor assim funcionava, mas ler ServerInfo depois lançava InvalidOperationException, a mesma exceção que você recebe quando o cliente nem está conectado. Um servidor perfeitamente válido parecia uma conexão quebrada. O PR #1903 corrigiu isso retornando null:

public override Implementation? ServerInfo => _serverCapabilities is null
    ? throw new InvalidOperationException("The client is not connected.")
    : _serverInfo;

Disso saem três regras:

Metadados malformados ainda fazem a conexão falhar com uma JsonException, então null realmente significa “não informado”, não “lixo”.

A correção no código do cliente

Código como este agora gera CS8602 no acesso a .Name:

await using var client = await McpClient.CreateAsync(transport);

logger.LogInformation("Connected to {Server} {Version}",
    client.ServerInfo.Name, client.ServerInfo.Version);

Trate o caso nulo explicitamente:

await using var client = await McpClient.CreateAsync(transport);

var name = client.ServerInfo?.Name ?? "Unknown server";
var version = client.ServerInfo?.Version ?? "n/a";

logger.LogInformation("Connected to {Server} {Version}", name, version);

Resista ao operador !. Ele silencia o aviso e traz de volta uma NullReferenceException na primeira vez que alguém apontar seu cliente para um servidor que só faz descoberta. As notas de versão também são diretas ao dizer que essa identidade autodeclarada “não deve ser usada para decisões de segurança”. Se o seu código libera acesso a ferramentas com base em ServerInfo.Name, isso já estava errado, e um null aqui é um bom momento para trocar por uma configuração que você controla.

O restante da 2.3.0

A versão traz principalmente trabalho de interoperabilidade e confiabilidade que vale a pena adotar de qualquer forma:

Atualizar é só trocar a versão do pacote:

dotnet add package ModelContextProtocol --version 2.3.0

Se você ainda está na 1.x, faça primeiro a migração da 1.x para a 2.x, depois compile com warnings como erros e deixe o compilador mostrar cada acesso a ServerInfo.

Comments

Sign in with GitHub to comment. Reactions and replies thread back to the comments repo.

< Voltar