Skip to content

MCP bridge: JSON-RPC dispatcher raises TypeError instead of 400 on non-object body #790

@kovtcharov

Description

@kovtcharov

Summary

src/gaia/mcp/mcp_bridge.py's JSON-RPC dispatcher assumes the body parsed to a dict. A client that sends a top-level JSON integer, string, or list (all valid JSON) triggers TypeError from the in operator, which surfaces to the client as HTTP 500 instead of the spec-correct HTTP 400 / JSON-RPC -32600 Invalid Request.

Location

src/gaia/mcp/mcp_bridge.py:623-635

def handle_jsonrpc(self, data):
    # Validate JSON-RPC
    if \"jsonrpc\" not in data or data[\"jsonrpc\"] != \"2.0\":   # ← TypeError if data is int/null
        self.send_json(400, {
            \"jsonrpc\": \"2.0\",
            \"error\": {\"code\": -32600, \"message\": \"Invalid Request\"},
            \"id\": data.get(\"id\"),                             # ← AttributeError if data is list/str
        })
        return

Reproduce

curl -X POST http://localhost:8765/ -H 'Content-Type: application/json' -d '42'
# Expected: HTTP 400, JSON-RPC error envelope
# Actual:   HTTP 500 (Python stack trace in logs)

Suggested Fix

Add a one-line type guard at the top of handle_jsonrpc:

if not isinstance(data, dict):
    self.send_json(400, {
        \"jsonrpc\": \"2.0\",
        \"error\": {\"code\": -32600, \"message\": \"Invalid Request\"},
        \"id\": None,
    })
    return

Same guard is worth applying in do_POST right after json.loads to enforce dict-shape for the /chat, /jira, /llm, /summarize endpoints that downstream .get() on data.

Impact

  • Low severity (external integrators only); purely a spec-compliance / polish issue.
  • Fits v0.18.2 API readiness scope.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingmcpMCP integration changesrobustnessReliability, error handling, and hardening

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions