modelcontextprotocol / modelcontextprotocol/python-sdk
[Bug] Client sends empty _meta:{} on every request; strict servers (Meta Ads MCP) reject with HTTP 400
Ninguém assumiu esta issue ainda.
- 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
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- 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