modelcontextprotocol / modelcontextprotocol/python-sdk

[Bug] Client sends empty _meta:{} on every request; strict servers (Meta Ads MCP) reject with HTTP 400

Aberta Para iniciantes
#3,473 2 comentários 0 reações 0 responsáveis Ver no GitHub

Ninguém assumiu esta issue ainda.

v2
Linguagem predominante
Python
Estrelas
24.3k
Forks
4k
Merge médio
1d 1h
PRs com merge (30d)
31

Descrição

Description

JSONRPCDispatcher.send_raw_request attaches _meta to params unconditionally:

out_params = dict(params) if params is not None else {}
out_meta = dict(out_params.get("_meta") or {})
on_progress = opts.get("on_progress")
if on_progress is not None:
    out_meta["progressToken"] = request_id
out_params["_meta"] = out_meta   # <- empty dict goes on the wire

When no progress callback is set and the otel tracer is a no-op (default), out_meta stays {} and every request ships _meta: {}.

Strict JSON-RPC servers reject this: Meta's hosted Ads MCP server (https://mcp.facebook.com/ads) returns HTTP 400 with -32602 "_meta for Request must be a dict or null" on initialize, making it unreachable from any client built on this SDK. _meta: null is rejected identically — the field must be absent.

Other MCP clients Meta documents (Claude Code, ChatGPT) don't emit an empty _meta and connect fine.

Reproduction

Reported downstream from Hermes Agent (NousResearch/hermes-agent#105637), with a minimal curl repro against the real server (400 with _meta:{}}, 200 without). Happy to attach a self-contained repro against a local strict server if preferred.

Proposed fix

if out_meta:
    out_params["_meta"] = out_meta
elif "_meta" in out_params:
    del out_params["_meta"]

after inject_trace_context(out_meta) so a real trace context is still sent.

Environment

  • mcp SDK: current main (src/mcp/shared/jsonrpc_dispatcher.py)
  • Python 3.12

Guia de contribuição

Abrir o guia de contribuição

Primeiros passos

  1. Leia a issue inteira e depois o guia de contribuição do projeto.
  2. Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
  3. Faça um fork do repositório e trabalhe em uma branch.
  4. Abra um pull request que referencie o número da issue.

Direção de pesquisa

Comece em src/mcp/shared/jsonrpc_dispatcher.py, em JSONRPCDispatcher.send_raw_request, e acompanhe como out_meta é preenchido, incluindo inject_trace_context. Execute a solicitação initialize contra um servidor estrito ou a reprodução mínima descrita; está concluído quando as solicitações sem metadados de progresso ou trace omitem _meta completamente, mantendo os metadados reais quando presentes.

Escrita pelo modelo de indexação a partir do texto da issue.

Avaliação

Stack de tecnologia
python
Domínio
api
Tipo de issue
Bug
Dificuldade
2/5
Tempo estimado
1-3 horas
Status de atividade
Ativa
Clareza
Claramente especificada
Facilidade para iniciantes
78/100

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.