Skip to content

fix: coerce MCP integer arguments to native Python int - #84

Merged
bensig merged 1 commit into
MemPalace:mainfrom
AlexeySamosadov:fix/mcp-integer-coercion
Apr 7, 2026
Merged

fix: coerce MCP integer arguments to native Python int#84
bensig merged 1 commit into
MemPalace:mainfrom
AlexeySamosadov:fix/mcp-integer-coercion

Conversation

@AlexeySamosadov

Copy link
Copy Markdown

Summary

  • MCP JSON-RPC transport can deliver integer-typed arguments as floats (3.0) or strings ("3") depending on the client
  • ChromaDB's collection.query(n_results=...) requires a native Python int, causing mempalace_search to fail with: "Expected requested number of results to be a int, got 3 in query."
  • This affects all tools with integer params: limit (search), max_hops (traverse), last_n (diary_read)

Fix

Auto-coerce tool arguments in handle_request() based on the declared input_schema types before calling handlers. This is generic — covers all current and future tools without per-handler changes.

schema_props = TOOLS[tool_name]["input_schema"].get("properties", {})
for key, value in list(tool_args.items()):
    declared_type = schema_props.get(key, {}).get("type")
    if declared_type == "integer" and not isinstance(value, int):
        tool_args[key] = int(value)
    elif declared_type == "number" and not isinstance(value, (int, float)):
        tool_args[key] = float(value)

Reproduction

from mempalace.searcher import search_memories
search_memories("test", palace_path, n_results=3.0)
# → "Search error: Expected requested number of results to be a int, got 3.0 in query."

Test plan

  • limit=3 (int) — works before and after
  • limit=3.0 (float from JSON) — fails before, works after
  • limit="3" (string) — fails before, works after
  • No regressions on tools without integer params

Discovered while using MemPalace via Claude Code MCP integration.

🤖 Generated with Claude Code

ChromaDB requires native `int` for `n_results`, but the MCP JSON-RPC
transport can deliver JSON integers as floats or strings depending on
the client implementation. This causes `mempalace_search` (and any
tool with integer params like `max_hops`, `last_n`) to fail with:

  "Expected requested number of results to be a int, got 3 in query."

Fix: auto-coerce tool arguments based on the declared `input_schema`
types before calling handlers. This covers all current and future
tools generically.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
GoodOlClint added a commit to GoodOlClint/mempalace that referenced this pull request Apr 7, 2026
MCP JSON transport delivers numbers as floats/strings. ChromaDB and
Python slicing require native int. Inspects input_schema and coerces
before dispatch.

Upstream: MemPalace#84

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
GoodOlClint added a commit to GoodOlClint/mempalace that referenced this pull request Apr 7, 2026
Adds _validate_tool_args() that checks required params and types
against input_schema, returning JSON-RPC -32602 errors instead of
Python tracebacks. Applied after type coercion from PR MemPalace#84.

Upstream: MemPalace#91

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@bensig
bensig merged commit cea3436 into MemPalace:main Apr 7, 2026
igorls pushed a commit that referenced this pull request Aug 11, 2026
dialect.py: all 11 text-mode open() calls (6 read, 5 write) omitted encoding=, so on a non-UTF-8-locale process (e.g. German Windows / cp1252) UTF-8-written JSON and AAAK text is decoded via the OS codepage, corrupting umlauts. config.py: 4 text opens lacked encoding= (config.json + people_map read paths, two writes); the other json.dump write paths already pinned UTF-8.

Audit findings #51 (dialect.py:360) and #84 (config.py:377). Regression: tests/test_encoding_hardening.py forces cp1252 default open and asserts umlaut round-trips through from_config / config.json read / raw-UTF-8 skip_name.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants