Pular para conteúdo

Parâmetros de cabeçalho

Tradução automática

Esta página foi traduzida automaticamente a partir da documentação em inglês, e a página em inglês é a versão de referência. Se algo parecer errado, Traduções explica como avisar.

A maioria dos servidores nunca precisa disso.

Um gateway ou balanceador de carga na frente do seu servidor só consegue rotear com base no que ele lê sem analisar o corpo. Marque um argumento de uma ferramenta (tool) com x-mcp-header, e os clientes na versão do protocolo 2026-07-28 também enviam o valor dele como um cabeçalho HTTP.

Marque um argumento

A marca é uma chave a mais no JSON Schema do argumento. No MCPServer, o Field a coloca lá:

server.py
from typing import Annotated

from pydantic import Field

from mcp.server import MCPServer

mcp = MCPServer("Bookshop")


@mcp.tool()
def check_stock(
    title: str,
    region: Annotated[str, Field(json_schema_extra={"x-mcp-header": "Region"})],
) -> str:
    """Count the copies of a book in one region's warehouses."""
    return f"{title}: 3 copies in {region}."
  • Por Streamable HTTP na 2026-07-28, o cliente envia Mcp-Param-Region junto com o corpo, e o servidor rejeita uma chamada em que os dois divergem.
  • Um cliente que não listou a ferramenta nunca viu a marca: ele não envia cabeçalho nenhum, e a chamada é rejeitada. Nesse caso, o Client deste SDK lista as ferramentas e reenvia a chamada uma vez, então listar antes só economiza uma ida e volta.
  • Todas as outras conexões ignoram a anotação.

Sua função não muda: region continua chegando como argumento.

O que pode ser marcado

Argumentos str, int e bool. Qualquer outra coisa é recusada no registro da ferramenta, com InvalidSignature.

Isso inclui str | None, que não tem um tipo único. Um argumento opcional precisa ter o schema escrito por extenso, com o WithJsonSchema do pydantic:

region: Annotated[str | None, WithJsonSchema({"type": "string", "x-mcp-header": "Region"})] = None

No Server de baixo nível

Lá você escreve o input_schema à mão, então a chave entra direto:

server.py
from mcp.server import Server, ServerRequestContext
from mcp.types import (
    CallToolRequestParams,
    CallToolResult,
    ListToolsResult,
    PaginatedRequestParams,
    TextContent,
    Tool,
)

CHECK_STOCK = Tool(
    name="check_stock",
    description="Count the copies of a book in one region's warehouses.",
    input_schema={
        "type": "object",
        "properties": {
            "title": {"type": "string"},
            "region": {"type": "string", "x-mcp-header": "Region"},
        },
        "required": ["title", "region"],
    },
)


async def list_tools(ctx: ServerRequestContext, params: PaginatedRequestParams | None) -> ListToolsResult:
    return ListToolsResult(tools=[CHECK_STOCK])


async def call_tool(ctx: ServerRequestContext, params: CallToolRequestParams) -> CallToolResult:
    args = params.arguments or {}
    text = f"{args['title']}: 3 copies in {args['region']}."
    return CallToolResult(content=[TextContent(type="text", text=text)])


server = Server("Bookshop", on_list_tools=list_tools, on_call_tool=call_tool)
app = server.streamable_http_app()
  • Nada verifica a anotação para você: uma anotação inválida é servida, e os clientes 2026-07-28 deixam a ferramenta fora da listagem deles.

Schemas por nome

Para verificar o cabeçalho, o SDK precisa do schema de entrada da ferramenta antes de despachar a chamada. Sem get_tool_input_schema, ele obtém esse schema executando o seu handler on_list_tools em toda chamada que carrega argumentos, haja ou não alguma ferramenta marcada.

server.py
from typing import Any

from mcp.server import Server, ServerRequestContext
from mcp.types import (
    CallToolRequestParams,
    CallToolResult,
    ListToolsResult,
    PaginatedRequestParams,
    TextContent,
    Tool,
)

CHECK_STOCK = Tool(
    name="check_stock",
    description="Count the copies of a book in one region's warehouses.",
    input_schema={
        "type": "object",
        "properties": {
            "title": {"type": "string"},
            "region": {"type": "string", "x-mcp-header": "Region"},
        },
        "required": ["title", "region"],
    },
)

TOOLS = {CHECK_STOCK.name: CHECK_STOCK}


async def list_tools(ctx: ServerRequestContext, params: PaginatedRequestParams | None) -> ListToolsResult:
    return ListToolsResult(tools=list(TOOLS.values()))


async def call_tool(ctx: ServerRequestContext, params: CallToolRequestParams) -> CallToolResult:
    args = params.arguments or {}
    text = f"{args['title']}: 3 copies in {args['region']}."
    return CallToolResult(content=[TextContent(type="text", text=text)])


def tool_input_schema(name: str) -> dict[str, Any] | None:
    tool = TOOLS.get(name)
    return tool.input_schema if tool else None


server = Server(
    "Bookshop",
    on_list_tools=list_tools,
    on_call_tool=call_tool,
    get_tool_input_schema=tool_input_schema,
)
app = server.streamable_http_app()
  • Passe a função para responder a partir do que você já tem.
  • Retorne None para uma ferramenta sem nada a verificar.

Resumo

  • x-mcp-header em um argumento de ferramenta faz os clientes 2026-07-28 repetirem esse argumento como um cabeçalho HTTP Mcp-Param-*.
  • O servidor rejeita uma chamada cujo cabeçalho e corpo divergem.
  • Só argumentos str, int e bool podem ser marcados. O MCPServer lança InvalidSignature para qualquer outra coisa.
  • O Server de baixo nível não verifica nada, e os clientes descartam uma ferramenta cuja anotação é inválida.
  • get_tool_input_schema evita que o Server de baixo nível execute on_list_tools em toda chamada.

O restante da API do Server escrita à mão está em O Server de baixo nível.