fix(http): serialize object and boolean query parameters to prevent TypeError

SO
4d ago
+130-3

Fixes #107.

Problem

When calling call_tool with object/dict query arguments (e.g. content-form parameters like tool_args={"filter": {"status": "open"}}), remaining_args was passed directly into aiohttp's params=. Since aiohttp/yarl only accepts primitives or lists for repeated parameters, any object or boolean raised an unhandled TypeError before sending the HTTP request.

Solution

  • Added _encode_query_params helper across HttpCommunicationProtocol, SseCommunicationProtocol, and StreamableHttpCommunicationProtocol:
    • Dicts and sets are JSON-encoded (using compact separators=(",", ":")).
    • Booleans are converted to 'true' / 'false'.
    • Sequences (lists, tuples) are recursively encoded so aiohttp preserves repeated query parameters (?k=v1&k=v2).
    • Primitives (str, int, float) are preserved as-is.
  • Added regression unit test in plugins/communication_protocols/http/tests/test_http_communication_protocol.py to verify serialization of objects, lists, booleans, and integers.

Testing

  • Ran pytest plugins/communication_protocols/http/tests/ (310 passed, 0 failures).

Summary by cubic

Fixes #107. Calling call_tool with object or boolean query arguments raised an unhandled TypeError because aiohttp only accepts primitives or lists for query params. Query values are now serialized with a shared encode_query_params helper before being passed to aiohttp:

  • Dicts and sets are JSON-encoded with compact separators; sets are sorted for deterministic output, nested sets become sorted lists, non-string dict keys are normalized to strings, and non-JSON values fall back to str().
  • Booleans become 'true'/'false'; lists and tuples are recursively encoded so repeated parameters are preserved (?tag=a&tag=b); primitives pass through unchanged, and None values are dropped.
  • Raises a descriptive ValueError when distinct dictionary keys normalize to the same string (e.g. 100 and '100') instead of silently overwriting.
  • Applied to HttpCommunicationProtocol, SseCommunicationProtocol, and StreamableHttpCommunicationProtocol, with regression tests added for objects, sets, nested sequences, booleans, None dropping, non-string keys, and key collisions.