modelcontextprotocol / modelcontextprotocol/python-sdk

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

Aperta Adatta ai principianti
#3,473 2 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

v2
Lingua principale
Python
Stelle
24.3k
Fork
4k
Merge medio
1g 1h
PR unite (30g)
31

Descrizione

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

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia in src/mcp/shared/jsonrpc_dispatcher.py, all'interno di JSONRPCDispatcher.send_raw_request, e segui come viene popolato out_meta, incluso inject_trace_context. Esegui la richiesta initialize su un server rigido o sulla riproduzione minima descritta; il lavoro è completato quando le richieste senza metadati di avanzamento o trace omettono completamente _meta, mantenendo i metadati effettivi quando presenti.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
python
Ambito
api
Tipo di issue
Bug
Difficoltà
2/5
Tempo stimato
1-3 ore
Stato di attività
Attiva
Chiarezza
Specificata chiaramente
Idoneità per principianti
78/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.