From 5374e8cf336680b30f0ab31f8242febec93acee3 Mon Sep 17 00:00:00 2001 From: jp Date: Sun, 12 Apr 2026 00:07:51 -0700 Subject: [PATCH 1/2] fix: skip arg whitelist for handlers accepting **kwargs (#572) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The schema-based argument filter (from #647) strips all kwargs not declared in input_schema. This breaks handlers that accept **kwargs for pass-through to ChromaDB or other backends. Add inspect.Parameter.VAR_KEYWORD check before filtering — handlers with **kwargs receive all arguments unfiltered. Co-Authored-By: Claude Opus 4.6 --- mempalace/mcp_server.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/mempalace/mcp_server.py b/mempalace/mcp_server.py index 30de7619b8..7ae23a7432 100644 --- a/mempalace/mcp_server.py +++ b/mempalace/mcp_server.py @@ -1350,8 +1350,18 @@ def handle_request(request): } # Whitelist arguments to declared schema properties only. # Prevents callers from spoofing internal params like added_by/source_file. + # Skip filtering for handlers that accept **kwargs — they intentionally + # handle arbitrary arguments (e.g., pass-through to ChromaDB). + import inspect + + handler = TOOLS[tool_name]["handler"] + sig = inspect.signature(handler) + accepts_var_keyword = any( + p.kind == inspect.Parameter.VAR_KEYWORD for p in sig.parameters.values() + ) schema_props = TOOLS[tool_name]["input_schema"].get("properties", {}) - tool_args = {k: v for k, v in tool_args.items() if k in schema_props} + if not accepts_var_keyword: + tool_args = {k: v for k, v in tool_args.items() if k in schema_props} # Coerce argument types based on input_schema. # MCP JSON transport may deliver integers as floats or strings; # ChromaDB and Python slicing require native int. From 7096540f99273869363da25d599c893d3e46c28b Mon Sep 17 00:00:00 2001 From: jp Date: Sun, 12 Apr 2026 00:26:55 -0700 Subject: [PATCH 2/2] fix: guard inspect.signature failure, default to filtering MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wrap inspect.signature() in try/except — on failure, default to filtering (safe fallback). Addresses Copilot feedback on fragility. Co-Authored-By: Claude Opus 4.6 --- mempalace/mcp_server.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/mempalace/mcp_server.py b/mempalace/mcp_server.py index 7ae23a7432..2330555ced 100644 --- a/mempalace/mcp_server.py +++ b/mempalace/mcp_server.py @@ -1350,16 +1350,19 @@ def handle_request(request): } # Whitelist arguments to declared schema properties only. # Prevents callers from spoofing internal params like added_by/source_file. - # Skip filtering for handlers that accept **kwargs — they intentionally - # handle arbitrary arguments (e.g., pass-through to ChromaDB). + # Skip filtering if handler explicitly accepts **kwargs (pass-through). + # Default to filtering on inspect failure (safe fallback). import inspect - handler = TOOLS[tool_name]["handler"] - sig = inspect.signature(handler) - accepts_var_keyword = any( - p.kind == inspect.Parameter.VAR_KEYWORD for p in sig.parameters.values() - ) schema_props = TOOLS[tool_name]["input_schema"].get("properties", {}) + try: + handler = TOOLS[tool_name]["handler"] + sig = inspect.signature(handler) + accepts_var_keyword = any( + p.kind == inspect.Parameter.VAR_KEYWORD for p in sig.parameters.values() + ) + except (ValueError, TypeError): + accepts_var_keyword = False if not accepts_var_keyword: tool_args = {k: v for k, v in tool_args.items() if k in schema_props} # Coerce argument types based on input_schema.