Skip to content

Commit f4ab90d

Browse files
committed
fix
1 parent 792babb commit f4ab90d

File tree

2 files changed

+34
-7
lines changed

2 files changed

+34
-7
lines changed

packages/gg_api_core/src/gg_api_core/mcp_server.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -225,30 +225,44 @@ async def _parameter_preprocessing_middleware(self, context: MiddlewareContext,
225225
params = context.params
226226
arguments = params.get("arguments", {})
227227

228+
# Log what we received for debugging
229+
logger.debug(f"Middleware received arguments: {arguments} (type: {type(arguments)})")
230+
228231
# If arguments is empty or not a dict, nothing to preprocess
229232
if not isinstance(arguments, dict):
233+
logger.debug(f"Arguments is not a dict, skipping preprocessing")
230234
return await call_next(context)
231235

232236
# Look for stringified JSON in parameter values
233237
preprocessed_arguments = {}
238+
modified = False
239+
234240
for key, value in arguments.items():
241+
logger.debug(f"Processing parameter '{key}': {repr(value)} (type: {type(value)})")
235242
if isinstance(value, str) and value.strip().startswith("{"):
236243
# Looks like stringified JSON, try to parse it
237244
try:
238245
parsed = json.loads(value)
239246
if isinstance(parsed, dict):
240-
logger.debug(f"Preprocessing parameter '{key}': converted JSON string to dict")
247+
logger.info(f"Preprocessed parameter '{key}': converted JSON string to dict")
241248
preprocessed_arguments[key] = parsed
249+
modified = True
242250
else:
243251
preprocessed_arguments[key] = value
244-
except (json.JSONDecodeError, ValueError):
252+
except (json.JSONDecodeError, ValueError) as e:
245253
# Not valid JSON, keep original value
254+
logger.debug(f"Failed to parse '{key}' as JSON: {e}")
246255
preprocessed_arguments[key] = value
247256
else:
248257
preprocessed_arguments[key] = value
249258

250-
# Update context with preprocessed arguments
251-
context.params["arguments"] = preprocessed_arguments
259+
# Update context with preprocessed arguments if we modified anything
260+
if modified:
261+
context.params["arguments"] = preprocessed_arguments
262+
# Also update context.message.arguments which FastMCP uses
263+
if hasattr(context, "message") and hasattr(context.message, "arguments"):
264+
context.message.arguments = preprocessed_arguments
265+
logger.debug(f"Updated arguments: {preprocessed_arguments}")
252266

253267
return await call_next(context)
254268

tests/test_middleware_preprocessing.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,29 @@ def test_middleware_converts_stringified_json_params(self):
5252

5353
mcp = GitGuardianPATEnvMCP("test", personal_access_token="test_token")
5454

55-
# Create a mock context with stringified JSON parameters
55+
# Create a mock context with stringified JSON parameters that mirrors FastMCP structure
56+
class MockMessage:
57+
def __init__(self):
58+
self.name = "list_repo_occurrences"
59+
self.arguments = {"params": '{"source_id": 9036019, "get_all": true}'}
60+
5661
class MockContext:
5762
method = "tools/call"
58-
params = {"arguments": {"params": '{"source_id": 9036019, "get_all": true}'}}
63+
64+
def __init__(self):
65+
self.message = MockMessage()
66+
self.params = {"arguments": {"params": '{"source_id": 9036019, "get_all": true}'}}
5967

6068
async def mock_call_next(ctx):
61-
# Verify the params were preprocessed
69+
# Verify both context.params and context.message.arguments were preprocessed
6270
assert isinstance(ctx.params["arguments"]["params"], dict)
6371
assert ctx.params["arguments"]["params"]["source_id"] == 9036019
6472
assert ctx.params["arguments"]["params"]["get_all"] is True
73+
74+
# FastMCP uses context.message.arguments, so verify that's updated too
75+
assert isinstance(ctx.message.arguments["params"], dict)
76+
assert ctx.message.arguments["params"]["source_id"] == 9036019
77+
assert ctx.message.arguments["params"]["get_all"] is True
6578
return "success"
6679

6780
context = MockContext()

0 commit comments

Comments
 (0)