Ir para o conteúdo

Resultados das ferramentas

Cada ferramenta da plataforma retorna duas respostas ao mesmo tempo, para dois leitores diferentes:

  • content: texto legível para humanos. É o que o LLM lê para compor sua resposta. Sempre obrigatório.
  • structuredContent: um payload JSON. É o que a UI (o chat gateway) lê para renderizar links de fontes, tabelas e gráficos.

content chega à IA

O gateway devolve content ao modelo, mas renderiza table e charts a partir de structuredContent diretamente na tela, sem passá-los pelo modelo. O que os usuários veem é exatamente o que sua ferramenta calculou. Coloque os números que você quer que sejam confiáveis em structuredContent.

O que vai em structuredContent

Campo Tipo Obrigatório O que faz
sources lista sim Links para os dados originais. Renderizados como links de fontes abaixo da resposta.
table lista de linhas não Dados tabulares (a primeira linha é o cabeçalho). Renderizada como uma tabela HTML.
charts lista não Dados e configuração do Chart.js. Renderizados como gráficos. (Em desenvolvimento.)
force string não Texto mostrado ao usuário exatamente como está, sem passar pelo LLM.

Exemplo com uma tabela

from mcp.types import CallToolResult, TextContent
from mcp_server import DataToolOutput

@registry.tool()
def list_cities() -> DataToolOutput:
    """Return the top 3 cities by population."""
    return CallToolResult(
        content=[TextContent(type="text", text=(
            "The 3 most populated cities are Tokyo (37,400,068), "
            "Delhi (30,290,936) and Shanghai (27,058,479)."
        ))],
        structuredContent={
            "sources": ["https://example.org/cities-data"],
            "table": [
                ["City", "Population"],
                ["Tokyo", "37400068"],
                ["Delhi", "30290936"],
                ["Shanghai", "27058479"],
            ],
        },
    )

Note que content repete os fatos. Isso é de propósito: o modelo escreve sua prosa somente a partir de content.

Como isso é garantido

A anotação -> DataToolOutput amarra o valor de retorno a um esquema (um ValidationModel do Pydantic) publicado como structured output. Na inicialização, @registry.tool() inspeciona a anotação de retorno de cada função. Se não for DataToolOutput, o servidor registra um aviso e devolve a função sem registrá-la. A ferramenta não aparece em tools/list, então nenhum cliente pode chamá-la e o LLM nunca fica sabendo que ela existe.

Isso é mais rígido do que o MCP exige

O Model Context Protocol não tem o conceito de fonte obrigatória. Uma ferramenta MCP perfeitamente conforme pode retornar uma resposta vinda do nada. Nós estreitamos o padrão de propósito: neste servidor, declarar de onde os dados vieram é condição para sequer ser registrada.

Nossas ferramentas continuam compatíveis: qualquer cliente MCP pode chamá-las, ele só recebe um payload mais rico, com fontes incluídas, do que o protocolo garante.