Fix: Only include updatedInput when explicitly provided in permission callbacks

Fixes #1063

When a permission callback returns `PermissionResultAllow()` without
the `updated_input` parameter, the SDK should not include `updatedInput`
in the control_response. Previously, the SDK always included this field,
either with the modified input or falling back to the original input,
which caused MCP tools to receive empty {} arguments instead of Claude's
original arguments.

Changes:
- Modified query.py to only include updatedInput when explicitly set
- Added regression test to verify updatedInput is omitted when not provided
- Existing test for input modification still passes

Before this fix:
```json
{
  "behavior": "allow",
  "updatedInput": {}  // Bug: Always included even when not set
}
```

After this fix:
```json
{
  "behavior": "allow"  // updatedInput only included when explicitly provided
}
```
This commit is contained in:
Yashwant Bezawada 2025-11-15 16:35:42 -06:00
parent ff425b293d
commit 03d4837616
2 changed files with 11 additions and 8 deletions

View file

@ -233,14 +233,10 @@ class Query:
# Convert PermissionResult to expected dict format
if isinstance(response, PermissionResultAllow):
response_data = {
"behavior": "allow",
"updatedInput": (
response.updated_input
if response.updated_input is not None
else original_input
),
}
response_data = {"behavior": "allow"}
# Only include updatedInput if explicitly provided by the user
if response.updated_input is not None:
response_data["updatedInput"] = response.updated_input
if response.updated_permissions is not None:
response_data["updatedPermissions"] = [
permission.to_dict()

View file

@ -96,6 +96,13 @@ class TestToolPermissionCallbacks:
response = transport.written_messages[0]
assert '"behavior": "allow"' in response
# IMPORTANT: Verify updatedInput is NOT included when not provided
# This is the regression test for issue #1063
assert '"updatedInput"' not in response, (
"updatedInput should not be included when PermissionResultAllow() "
"is returned without updated_input parameter"
)
@pytest.mark.asyncio
async def test_permission_callback_deny(self):
"""Test callback that denies tool execution."""