Sisk

Protocolo de Contexto de Modelo

Esta página foi traduzida automaticamente do inglês. Ler o original

É possível criar aplicações que fornecem contexto a modelos de agente usando grandes modelos de linguagem (LLMs) com o pacote Sisk.ModelContextProtocol :

dotnet add package Sisk.ModelContextProtocol --prerelease

Este pacote expõe classes e métodos úteis para construir servidores MCP que operam sobre Streamable HTTP, suportando mensagens de solicitação/resposta única. Desde a versão 1.7.0-rc1, ele suporta solicitações sem estado da versão de protocolo 2026-07-28 e mantém o fluxo de inicialização legado para clientes que utilizam as versões 2025-11-25, 2025-06-18 e 2025-03-26. Ele suporta ferramentas e habilidades.

Nota

Antes de começar, observe que este pacote está em desenvolvimento e pode apresentar comportamentos que não estão em conformidade com a especificação. Leia os detalhes do pacote para saber o que está em desenvolvimento e o que ainda não funciona.

Começando com MCP #

A classe McpProvider é o ponto de entrada para definir um servidor MCP. É um objeto provedor selado que pode ser configurado na inicialização. Sua aplicação Sisk pode ter um ou mais provedores MCP.

C#
McpProvider mcp = new McpProvider(
    serverName: "math-server",
    serverTitle: "Mathematics server",
    serverVersion: new Version(1, 0));

mcp.Tools.Add(new McpTool(
    name: "math_sum",
    description: "Sums one or more numbers.",
    schema: JsonSchema.CreateObjectSchema(
        properties: new Dictionary<string, JsonSchema>()
        {
            { "numbers",
                JsonSchema.CreateArraySchema(
                    itemsSchema: JsonSchema.CreateNumberSchema(),
                    minItems: 1,
                    description: "The numbers to sum.")
            }
        },
        requiredProperties: ["numbers"]),
    executionHandler: async (McpToolContext context) =>
    {
        var numbers = context.Arguments["numbers"].GetJsonArray().ToArray<double>();
        var sum = numbers.Sum();
        return await Task.FromResult(McpToolResult.CreateText($"Sum result: {sum:N4}"));
    }));

Se sua aplicação fornecer apenas um provedor MCP, você pode usar o singleton do construtor:

C#
static void Main(string[] args)
{
    using var host = HttpServer.CreateBuilder()
        .UseMcp(mcp =>
        {
            mcp.ServerName = "math-server";
            mcp.ServerTitle = "Mathematics server";

            mcp.Tools.Add(new McpTool(
                name: "math_sum",
                description: "Sums one or more numbers.",
                schema: JsonSchema.CreateObjectSchema(
                    properties: new Dictionary<string, JsonSchema>()
                    {
                        { "numbers",
                            JsonSchema.CreateArraySchema(
                                itemsSchema: JsonSchema.CreateNumberSchema(),
                                minItems: 1,
                                description: "The numbers to sum.")
                        }
                    },
                    requiredProperties: ["numbers"]),
                executionHandler: async (McpToolContext context) =>
                {
                    var numbers = context.Arguments["numbers"].GetJsonArray().ToArray<double>();
                    var sum = numbers.Sum();
                    return await Task.FromResult(McpToolResult.CreateText($"Sum result: {sum:N4}"));
                }));
        })
        .UseRouter(router =>
        {
            router.MapAny("/mcp", async (HttpRequest req) =>
            {
                return await req.HandleMcpRequestAsync();
            });
        })
        .Build();

    host.Start();
}

O endpoint deve aceitar tanto solicitações GET quanto POST, portanto MapAny é o mapeamento de rota mais simples. HandleMcpRequestAsync devolve um HttpResponse, e sua rota deve retorná‑lo. Se precisar de múltiplos provedores em um único app, ignore o singleton e chame McpProvider.HandleRequestAsync diretamente de cada rota:

C#
var mathProvider = new McpProvider("math-server", "Mathematics server", new Version(1, 0));

router.MapAny("/mcp/math", async request =>
{
    return await mathProvider.HandleRequestAsync(request);
});

Criando Schemas JSON para Funções #

A biblioteca [Sisk.ModelContextProtocol] usa um fork do LightJson para manipulação de JSON e schemas JSON. Esta implementação fornece um construtor fluente de Schema JSON para vários objetos:

  • JsonSchema.CreateObjectSchema
  • JsonSchema.CreateArraySchema
  • JsonSchema.CreateBooleanSchema
  • JsonSchema.CreateNumberSchema
  • JsonSchema.CreateStringSchema
  • JsonSchema.Empty

Exemplo:

C#
JsonSchema.CreateObjectSchema(
    properties: new Dictionary<string, JsonSchema>()
    {
        { "numbers",
            JsonSchema.CreateArraySchema(
                itemsSchema: JsonSchema.CreateNumberSchema(),
                minItems: 1,
                description: "The numbers to sum.")
        }
    },
    requiredProperties: ["numbers"]);

Produz o seguinte schema:

JSON
{
  "type": "object",
  "properties": {
    "numbers": {
      "type": "array",
      "items": {
        "type": "number"
      },
      "minItems": 1,
      "description": "The numbers to sum."
    }
  },
  "required": ["numbers"]
}

Manipulando Chamadas de Função #

A função definida no parâmetro executionHandler de McpTool fornece um JsonObject contendo os argumentos da chamada que podem ser lidos de forma fluente:

C#
mcp.Tools.Add(new McpTool(
    name: "browser_do_action",
    description: "Run an browser action, such as scrolling, refreshing or navigating.",
    schema: JsonSchema.CreateObjectSchema(
        properties: new Dictionary<string, JsonSchema>()
        {
            { "action_name",
                JsonSchema.CreateStringSchema(
                    enums: ["go_back", "refresh", "scroll_bottom", "scroll_top"],
                    description: "The action name.")
            },
            { "action_data",
                JsonSchema.CreateStringSchema(
                    description: "Action parameter."
                ) }
        },
        requiredProperties: ["action_name"]),
    executionHandler: async (McpToolContext context) =>
    {
        // lê o nome da ação. lançará exceção se for nulo ou não for uma string explícita
        string actionName = context.Arguments["action_name"].GetString();
        
        // action_data é definido como não obrigatório, portanto pode ser nulo aqui
        string? actionData = context.Arguments["action_data"].MaybeNull()?.GetString();
        
        // Handle the browser action based on the actionName
        return await Task.FromResult(
            McpToolResult.CreateText($"Performed browser action: {actionName}"));
    }));

Os argumentos da ferramenta são validados contra o schema antes que seu manipulador seja executado. Se a validação falhar, o provedor retorna um resultado de erro ao cliente MCP e não invoca o manipulador da ferramenta.

Resultados de Função #

O objeto McpToolResult fornece três métodos para criar conteúdo para uma resposta de ferramenta:

Além disso, é possível combinar múltiplos conteúdos diferentes em uma única resposta JSON de ferramenta:

C#
mcp.Tools.Add(new McpTool(
    ...
    executionHandler: async (McpToolContext context) =>
    {
        // simulate real work

        byte[] browserScreenshot = await browser.ScreenshotAsync();
        
        return McpToolResult.Combine(
            McpToolResult.CreateText("Heres the screenshot of the browser:"),
            McpToolResult.CreateImage(browserScreenshot, "image/png")
        )
    }));

O provedor atualmente lida com server/discover, os métodos legados initialize e ping, tools/list, tools/call, skills/list, skills/get, resources/list, resources/read e notificações. Métodos JSON‑RPC não suportados retornam uma resposta de erro JSON‑RPC.

Publicando habilidades #

Um provedor MCP também pode publicar Agent Skills através da extensão io.modelcontextprotocol/skills. Adicione objetos McpSkill a McpProvider.Skills antes que o provedor comece a tratar solicitações:

C#
mcp.Skills.Add(new McpSkill(
    path: "acme/refunds",
    frontmatter: new JsonObject
    {
        ["name"] = "refunds",
        ["description"] = "Follow the refund workflow."
    },
    body: "# Refunds\nRead references/policy.md before using the refund tools.",
    files: new Dictionary<string, byte[]>
    {
        ["references/policy.md"] = File.ReadAllBytes("skills/refunds/references/policy.md")
    }));

McpSkill gera o arquivo SKILL.md a partir do frontmatter e do corpo Markdown. O último segmento de path deve ser igual ao campo name do frontmatter. Os arquivos de habilidade são copiados quando a habilidade é criada e nunca são lidos do disco pelo provedor. Clientes listam e leem habilidades com skills/list, skills/get e resources/read, usando a versão de protocolo 2026-07-28. Consulte os detalhes do pacote para limites e regras de validação.

Trabalho em Andamento #

O Model Context Protocol é um protocolo de comunicação para modelos de agente e aplicações que fornecem conteúdo a eles. É um protocolo novo, portanto é comum que sua especificação seja constantemente atualizada com descontinuações, novos recursos e mudanças incompatíveis.

É crucial entender os problemas que o Model Context Protocol resolve antes de começar a construir aplicações de agente.

Também leia a especificação do pacote Sisk.ModelContextProtocol para compreender seu progresso, status e o que pode ser feito com ele.

Digite para pesquisar na documentação e na referência da API.