fix: accept null for expected_replacements in edit_note (#606)

MCP clients may send explicit `null` for unused optional fields.
`expected_replacements: int = 1` caused FastMCP's JSON Schema validation
to reject null before the function body ran. Changed to `Optional[int] = None`
with an effective default resolved inside the function body.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
This commit is contained in:
phernandez
2026-02-25 14:18:53 -06:00
parent 1856d4b462
commit aa635b8a8b
2 changed files with 40 additions and 4 deletions
+7 -4
View File
@@ -135,7 +135,7 @@ async def edit_note(
workspace: Optional[str] = None,
section: Optional[str] = None,
find_text: Optional[str] = None,
expected_replacements: int = 1,
expected_replacements: Optional[int] = None,
output_format: Literal["text", "json"] = "text",
context: Context | None = None,
) -> str | dict:
@@ -216,6 +216,9 @@ async def edit_note(
search_notes() first to find the correct identifier. The tool provides detailed
error messages with suggestions if operations fail.
"""
# Resolve effective default: allow MCP clients to send null for optional int field
effective_replacements = expected_replacements if expected_replacements is not None else 1
async with get_project_client(project, workspace, context) as (client, active_project):
logger.info("MCP tool call", tool="edit_note", identifier=identifier, operation=operation)
@@ -254,8 +257,8 @@ async def edit_note(
edit_data["section"] = section
if find_text:
edit_data["find_text"] = find_text
if expected_replacements != 1: # Only send if different from default
edit_data["expected_replacements"] = str(expected_replacements)
if effective_replacements != 1: # Only send if different from default
edit_data["expected_replacements"] = str(effective_replacements)
# Call the PATCH endpoint
result = await knowledge_client.patch_entity(entity_id, edit_data, fast=False)
@@ -339,5 +342,5 @@ async def edit_note(
"error": str(e),
}
return _format_error_response(
str(e), operation, identifier, find_text, expected_replacements, active_project.name
str(e), operation, identifier, find_text, effective_replacements, active_project.name
)