From 2ea012ead4570d690c61c5d59c2824b406dd64d8 Mon Sep 17 00:00:00 2001 From: Jeremiah Lowin <153965+jlowin@users.noreply.github.com> Date: Sun, 5 Jul 2026 18:11:04 -0400 Subject: [PATCH] Adopt snake_case SDK type constructor kwargs --- fastmcp_slim/fastmcp/cli/apps_dev.py | 2 +- fastmcp_slim/fastmcp/client/client.py | 2 +- .../fastmcp/client/mixins/task_management.py | 6 +-- .../client/sampling/handlers/anthropic.py | 2 +- .../client/sampling/handlers/google_genai.py | 2 +- .../client/sampling/handlers/openai.py | 2 +- fastmcp_slim/fastmcp/client/tasks.py | 10 ++-- .../bulk_tool_caller/bulk_tool_caller.py | 6 +-- fastmcp_slim/fastmcp/resources/base.py | 6 +-- fastmcp_slim/fastmcp/resources/template.py | 4 +- fastmcp_slim/fastmcp/server/context.py | 2 +- .../fastmcp/server/mixins/mcp_operations.py | 10 ++-- .../fastmcp/server/providers/proxy.py | 2 +- fastmcp_slim/fastmcp/server/sampling/run.py | 28 +++++------ .../fastmcp/server/sampling/sampling_tool.py | 2 +- .../fastmcp/server/tasks/elicitation.py | 2 +- fastmcp_slim/fastmcp/server/tasks/handlers.py | 8 +-- fastmcp_slim/fastmcp/server/tasks/requests.py | 26 +++++----- .../server/transforms/resources_as_tools.py | 2 +- fastmcp_slim/fastmcp/tools/base.py | 10 ++-- fastmcp_slim/fastmcp/utilities/types.py | 8 +-- tests/cli/test_client_commands.py | 4 +- tests/cli/test_generate_cli.py | 50 +++++++++---------- tests/client/client/test_error_handling.py | 12 ++--- .../handlers/test_anthropic_handler.py | 22 ++++---- .../handlers/test_google_genai_handler.py | 22 ++++---- .../sampling/handlers/test_openai_handler.py | 28 +++++------ .../tasks/test_client_task_notifications.py | 8 +-- tests/client/test_sampling_result_types.py | 30 +++++------ tests/client/test_sampling_tool_loop.py | 40 +++++++-------- tests/conformance/server.py | 12 ++--- tests/conftest.py | 6 ++- tests/contrib/test_bulk_tool_caller.py | 18 +++---- .../experimental/transforms/test_code_mode.py | 2 +- tests/prompts/test_prompt.py | 18 +++---- .../resources/test_resource_template_meta.py | 4 +- .../auth/test_enhanced_error_responses.py | 2 +- .../middleware/test_response_limiting.py | 2 +- .../providers/proxy/test_proxy_server.py | 14 +++--- .../tasks/test_context_background_task.py | 2 +- tests/server/tasks/test_task_config.py | 2 +- tests/server/tasks/test_task_mount.py | 4 +- tests/server/tasks/test_task_return_types.py | 4 +- .../server/telemetry/test_sampling_tracing.py | 4 +- tests/server/test_icons.py | 14 +++--- tests/server/test_tool_annotations.py | 36 ++++++------- tests/tools/tool/test_content.py | 22 ++++---- tests/tools/tool/test_tool.py | 10 ++-- .../openapi/test_circular_references.py | 8 +-- tests/utilities/test_inspect_icons.py | 22 ++++---- 50 files changed, 283 insertions(+), 281 deletions(-) diff --git a/fastmcp_slim/fastmcp/cli/apps_dev.py b/fastmcp_slim/fastmcp/cli/apps_dev.py index 8a7e0ba46..2bfa5f1dc 100644 --- a/fastmcp_slim/fastmcp/cli/apps_dev.py +++ b/fastmcp_slim/fastmcp/cli/apps_dev.py @@ -791,7 +791,7 @@ _LOG_PANEL_HTML = """\ function renderEntry(entry) { var div = document.createElement("div"); - var isError = entry.direction === "response" && entry.body + var is_error = entry.direction === "response" && entry.body && (entry.body.error || (entry.body.result && entry.body.result.is_error)); div.className = "log-entry" + (isError ? " error" : ""); var dirClass = isError ? "error" : entry.direction; diff --git a/fastmcp_slim/fastmcp/client/client.py b/fastmcp_slim/fastmcp/client/client.py index 0cb91c40e..805365ec4 100644 --- a/fastmcp_slim/fastmcp/client/client.py +++ b/fastmcp_slim/fastmcp/client/client.py @@ -816,7 +816,7 @@ class Client( root=mcp_types.CancelledNotification( method="notifications/cancelled", params=mcp_types.CancelledNotificationParams( - requestId=request_id, + request_id=request_id, reason=reason, ), ) diff --git a/fastmcp_slim/fastmcp/client/mixins/task_management.py b/fastmcp_slim/fastmcp/client/mixins/task_management.py index 9ca9057ed..9b9f3e329 100644 --- a/fastmcp_slim/fastmcp/client/mixins/task_management.py +++ b/fastmcp_slim/fastmcp/client/mixins/task_management.py @@ -45,7 +45,7 @@ class ClientTaskManagementMixin: RuntimeError: If client not connected MCPError: If the request results in a TimeoutError | JSONRPCError """ - request = GetTaskRequest(params=GetTaskRequestParams(taskId=task_id)) + request = GetTaskRequest(params=GetTaskRequestParams(task_id=task_id)) return await self._await_with_session_monitoring( self.session.send_request( request=request, # type: ignore[arg-type] # ty:ignore[invalid-argument-type] @@ -70,7 +70,7 @@ class ClientTaskManagementMixin: MCPError: If the request results in a TimeoutError | JSONRPCError """ request = GetTaskPayloadRequest( - params=GetTaskPayloadRequestParams(taskId=task_id) + params=GetTaskPayloadRequestParams(task_id=task_id) ) # Return raw result - Task classes handle type-specific parsing result = await self._await_with_session_monitoring( @@ -148,7 +148,7 @@ class ClientTaskManagementMixin: RuntimeError: If task doesn't exist MCPError: If the request results in a TimeoutError | JSONRPCError """ - request = CancelTaskRequest(params=CancelTaskRequestParams(taskId=task_id)) + request = CancelTaskRequest(params=CancelTaskRequestParams(task_id=task_id)) return await self._await_with_session_monitoring( self.session.send_request( request=request, # type: ignore[invalid-argument-type] # ty:ignore[invalid-argument-type] diff --git a/fastmcp_slim/fastmcp/client/sampling/handlers/anthropic.py b/fastmcp_slim/fastmcp/client/sampling/handlers/anthropic.py index 537e162b4..88eb132ee 100644 --- a/fastmcp_slim/fastmcp/client/sampling/handlers/anthropic.py +++ b/fastmcp_slim/fastmcp/client/sampling/handlers/anthropic.py @@ -449,5 +449,5 @@ class AnthropicSamplingHandler: content=content, role="assistant", model=message.model, - stopReason=stop_reason, + stop_reason=stop_reason, ) diff --git a/fastmcp_slim/fastmcp/client/sampling/handlers/google_genai.py b/fastmcp_slim/fastmcp/client/sampling/handlers/google_genai.py index 50f41db8e..0013b611d 100644 --- a/fastmcp_slim/fastmcp/client/sampling/handlers/google_genai.py +++ b/fastmcp_slim/fastmcp/client/sampling/handlers/google_genai.py @@ -399,5 +399,5 @@ def _response_to_result_with_tools( content=content, role="assistant", model=model, - stopReason=stop_reason, + stop_reason=stop_reason, ) diff --git a/fastmcp_slim/fastmcp/client/sampling/handlers/openai.py b/fastmcp_slim/fastmcp/client/sampling/handlers/openai.py index afffbc16f..0c9b4b94b 100644 --- a/fastmcp_slim/fastmcp/client/sampling/handlers/openai.py +++ b/fastmcp_slim/fastmcp/client/sampling/handlers/openai.py @@ -509,5 +509,5 @@ class OpenAISamplingHandler: content=content, # type: ignore[arg-type] # ty:ignore[invalid-argument-type] role="assistant", model=chat_completion.model, - stopReason=stop_reason, + stop_reason=stop_reason, ) diff --git a/fastmcp_slim/fastmcp/client/tasks.py b/fastmcp_slim/fastmcp/client/tasks.py index d1fcd07a1..7d214a59b 100644 --- a/fastmcp_slim/fastmcp/client/tasks.py +++ b/fastmcp_slim/fastmcp/client/tasks.py @@ -181,12 +181,12 @@ class Task(abc.ABC, Generic[TaskResultT]): # Return synthetic completed status now = datetime.now(timezone.utc) return GetTaskResult( - taskId=self._task_id, + task_id=self._task_id, status="completed", - createdAt=now, - lastUpdatedAt=now, + created_at=now, + last_updated_at=now, ttl=None, - pollInterval=1000, + poll_interval=1000, ) # Return cached status if available (from notification) @@ -409,7 +409,7 @@ class ToolTask(Task["CallToolResult"]): ): mcp_result = mcp_types.CallToolResult( content=raw_result.content, - structuredContent=raw_result.structured_content, + structured_content=raw_result.structured_content, _meta=raw_result.meta, # type: ignore[call-arg] # _meta is Pydantic alias for meta field ) result = await self._client._parse_call_tool_result( diff --git a/fastmcp_slim/fastmcp/contrib/bulk_tool_caller/bulk_tool_caller.py b/fastmcp_slim/fastmcp/contrib/bulk_tool_caller/bulk_tool_caller.py index 677f3c8ef..ab7c20e71 100644 --- a/fastmcp_slim/fastmcp/contrib/bulk_tool_caller/bulk_tool_caller.py +++ b/fastmcp_slim/fastmcp/contrib/bulk_tool_caller/bulk_tool_caller.py @@ -43,7 +43,7 @@ class CallToolRequestResult(CallToolResult): return cls( tool=tool, arguments=arguments, - isError=result.is_error, + is_error=result.is_error, content=result.content, ) @@ -128,7 +128,7 @@ class BulkToolCaller(MCPMixin): return CallToolRequestResult( tool=tool, arguments=arguments, - isError=True, + is_error=True, content=[ TextContent( type="text", @@ -146,6 +146,6 @@ class BulkToolCaller(MCPMixin): return CallToolRequestResult( tool=tool, arguments=arguments, - isError=result.is_error, + is_error=result.is_error, content=result.content, ) diff --git a/fastmcp_slim/fastmcp/resources/base.py b/fastmcp_slim/fastmcp/resources/base.py index 4ac2c3186..4f47d0c32 100644 --- a/fastmcp_slim/fastmcp/resources/base.py +++ b/fastmcp_slim/fastmcp/resources/base.py @@ -106,14 +106,14 @@ class ResourceContent(pydantic.BaseModel): return mcp_types.TextResourceContents( uri=AnyUrl(uri) if isinstance(uri, str) else uri, text=self.content, - mimeType=self.mime_type or "text/plain", + mime_type=self.mime_type or "text/plain", _meta=self.meta, # type: ignore[call-arg] # _meta is Pydantic alias for meta field ) else: return mcp_types.BlobResourceContents( uri=AnyUrl(uri) if isinstance(uri, str) else uri, blob=base64.b64encode(self.content).decode(), - mimeType=self.mime_type or "application/octet-stream", + mime_type=self.mime_type or "application/octet-stream", _meta=self.meta, # type: ignore[call-arg] # _meta is Pydantic alias for meta field ) @@ -412,7 +412,7 @@ class Resource(FastMCPComponent): name=overrides.get("name", self.name), uri=overrides.get("uri", self.uri), description=overrides.get("description", self.description), - mimeType=overrides.get("mimeType", self.mime_type), + mime_type=overrides.get("mimeType", self.mime_type), title=overrides.get("title", self.title), icons=overrides.get("icons", self.icons), annotations=overrides.get("annotations", self.annotations), diff --git a/fastmcp_slim/fastmcp/resources/template.py b/fastmcp_slim/fastmcp/resources/template.py index 91d0df52c..7cd7b244e 100644 --- a/fastmcp_slim/fastmcp/resources/template.py +++ b/fastmcp_slim/fastmcp/resources/template.py @@ -323,9 +323,9 @@ class ResourceTemplate(FastMCPComponent): return SDKResourceTemplate( name=overrides.get("name", self.name), - uriTemplate=overrides.get("uriTemplate", self.uri_template), + uri_template=overrides.get("uriTemplate", self.uri_template), description=overrides.get("description", self.description), - mimeType=overrides.get("mimeType", self.mime_type), + mime_type=overrides.get("mimeType", self.mime_type), title=overrides.get("title", self.title), icons=overrides.get("icons", self.icons), annotations=overrides.get("annotations", self.annotations), diff --git a/fastmcp_slim/fastmcp/server/context.py b/fastmcp_slim/fastmcp/server/context.py index ae04e3dd7..06597e27e 100644 --- a/fastmcp_slim/fastmcp/server/context.py +++ b/fastmcp_slim/fastmcp/server/context.py @@ -1189,7 +1189,7 @@ class Context: # Standard request mode: use session.elicit directly result = await self.session.elicit( message=message, - requestedSchema=config.schema, + requested_schema=config.schema, related_request_id=self.request_id, ) diff --git a/fastmcp_slim/fastmcp/server/mixins/mcp_operations.py b/fastmcp_slim/fastmcp/server/mixins/mcp_operations.py index b972ac7ff..98cddaa1c 100644 --- a/fastmcp_slim/fastmcp/server/mixins/mcp_operations.py +++ b/fastmcp_slim/fastmcp/server/mixins/mcp_operations.py @@ -115,7 +115,7 @@ class MCPOperationsMixin: request.params.cursor if request is not None and request.params else None ) page, next_cursor = _apply_pagination(sdk_tools, cursor, server._list_page_size) - return mcp_types.ListToolsResult(tools=page, nextCursor=next_cursor) + return mcp_types.ListToolsResult(tools=page, next_cursor=next_cursor) async def _list_resources_mcp( self, request: mcp_types.ListResourcesRequest @@ -138,7 +138,7 @@ class MCPOperationsMixin: page, next_cursor = _apply_pagination( sdk_resources, cursor, server._list_page_size ) - return mcp_types.ListResourcesResult(resources=page, nextCursor=next_cursor) + return mcp_types.ListResourcesResult(resources=page, next_cursor=next_cursor) async def _list_resource_templates_mcp( self, request: mcp_types.ListResourceTemplatesRequest @@ -154,7 +154,7 @@ class MCPOperationsMixin: list(await server.list_resource_templates()), lambda t: t.uri_template ) sdk_templates = [ - template.to_mcp_template(uriTemplate=template.uri_template) + template.to_mcp_template(uri_template=template.uri_template) for template in templates ] cursor = request.params.cursor if request.params else None @@ -162,7 +162,7 @@ class MCPOperationsMixin: sdk_templates, cursor, server._list_page_size ) return mcp_types.ListResourceTemplatesResult( - resourceTemplates=page, nextCursor=next_cursor + resource_templates=page, next_cursor=next_cursor ) async def _list_prompts_mcp( @@ -183,7 +183,7 @@ class MCPOperationsMixin: page, next_cursor = _apply_pagination( sdk_prompts, cursor, server._list_page_size ) - return mcp_types.ListPromptsResult(prompts=page, nextCursor=next_cursor) + return mcp_types.ListPromptsResult(prompts=page, next_cursor=next_cursor) async def _call_tool_mcp( self, key: str, arguments: dict[str, Any] diff --git a/fastmcp_slim/fastmcp/server/providers/proxy.py b/fastmcp_slim/fastmcp/server/providers/proxy.py index 3583eb997..b757b6f2b 100644 --- a/fastmcp_slim/fastmcp/server/providers/proxy.py +++ b/fastmcp_slim/fastmcp/server/providers/proxy.py @@ -979,7 +979,7 @@ async def default_proxy_elicitation_handler( ) result = await ctx.session.elicit( message=message, - requestedSchema=requested_schema, + requested_schema=requested_schema, related_request_id=ctx.request_id, ) return ElicitResult(action=result.action, content=result.content) diff --git a/fastmcp_slim/fastmcp/server/sampling/run.py b/fastmcp_slim/fastmcp/server/sampling/run.py index 7dbcadcfd..506d445e2 100644 --- a/fastmcp_slim/fastmcp/server/sampling/run.py +++ b/fastmcp_slim/fastmcp/server/sampling/run.py @@ -222,13 +222,13 @@ async def call_sampling_handler( result = context.fastmcp.sampling_handler( messages, SamplingParams( - systemPrompt=system_prompt, + system_prompt=system_prompt, messages=messages, temperature=temperature, - maxTokens=max_tokens, - modelPreferences=_parse_model_preferences(model_preferences), + max_tokens=max_tokens, + model_preferences=_parse_model_preferences(model_preferences), tools=sdk_tools, - toolChoice=tool_choice, + tool_choice=tool_choice, ), context.request_context, ) @@ -244,7 +244,7 @@ async def call_sampling_handler( role="assistant", content=TextContent(type="text", text=result), model="unknown", - stopReason="endTurn", + stop_reason="endTurn", ) return result @@ -287,14 +287,14 @@ async def execute_tools( if tool is None: return ToolResultContent( type="tool_result", - toolUseId=tool_use.id, + tool_use_id=tool_use.id, content=[ TextContent( type="text", text=f"Error: Unknown tool '{tool_use.name}'", ) ], - isError=True, + is_error=True, ) tracer = get_tracer() @@ -309,7 +309,7 @@ async def execute_tools( result_value = await tool.run(tool_use.input) return ToolResultContent( type="tool_result", - toolUseId=tool_use.id, + tool_use_id=tool_use.id, content=[TextContent(type="text", text=str(result_value))], ) except ToolError as e: @@ -324,9 +324,9 @@ async def execute_tools( ) return ToolResultContent( type="tool_result", - toolUseId=tool_use.id, + tool_use_id=tool_use.id, content=[TextContent(type="text", text=str(e))], - isError=True, + is_error=True, ) except Exception as e: if span.is_recording(): @@ -340,9 +340,9 @@ async def execute_tools( error_text = f"Error executing tool '{tool_use.name}': {e}" return ToolResultContent( type="tool_result", - toolUseId=tool_use.id, + tool_use_id=tool_use.id, content=[TextContent(type="text", text=error_text)], - isError=True, + is_error=True, ) # Check if any tool requires sequential execution @@ -718,7 +718,7 @@ async def sample_impl( content=[ ToolResultContent( type="tool_result", - toolUseId=tool_call.id, + tool_use_id=tool_call.id, content=[ TextContent( type="text", @@ -728,7 +728,7 @@ async def sample_impl( ), ) ], - isError=True, + is_error=True, ) ], ) diff --git a/fastmcp_slim/fastmcp/server/sampling/sampling_tool.py b/fastmcp_slim/fastmcp/server/sampling/sampling_tool.py index 4e925c0f2..05063dc53 100644 --- a/fastmcp_slim/fastmcp/server/sampling/sampling_tool.py +++ b/fastmcp_slim/fastmcp/server/sampling/sampling_tool.py @@ -77,7 +77,7 @@ class SamplingTool(FastMCPBaseModel): return SDKTool( name=self.name, description=self.description, - inputSchema=self.parameters, + input_schema=self.parameters, ) @classmethod diff --git a/fastmcp_slim/fastmcp/server/tasks/elicitation.py b/fastmcp_slim/fastmcp/server/tasks/elicitation.py index dfafe940b..d9a6e6df2 100644 --- a/fastmcp_slim/fastmcp/server/tasks/elicitation.py +++ b/fastmcp_slim/fastmcp/server/tasks/elicitation.py @@ -257,7 +257,7 @@ async def relay_elicitation( try: result = await session.elicit( message=elicitation["message"], - requestedSchema=elicitation["requestedSchema"], + requested_schema=elicitation["requestedSchema"], ) await handle_task_input( task_id=task_id, diff --git a/fastmcp_slim/fastmcp/server/tasks/handlers.py b/fastmcp_slim/fastmcp/server/tasks/handlers.py index 11e19b073..9aacf2027 100644 --- a/fastmcp_slim/fastmcp/server/tasks/handlers.py +++ b/fastmcp_slim/fastmcp/server/tasks/handlers.py @@ -226,11 +226,11 @@ async def submit_to_docket( # Tasks MUST begin in "working" status per SEP-1686 final spec (line 381) return mcp_types.CreateTaskResult( task=mcp_types.Task( - taskId=server_task_id, + task_id=server_task_id, status="working", - createdAt=created_at, - lastUpdatedAt=created_at, + created_at=created_at, + last_updated_at=created_at, ttl=ttl_ms, - pollInterval=poll_interval_ms, + poll_interval=poll_interval_ms, ) ) diff --git a/fastmcp_slim/fastmcp/server/tasks/requests.py b/fastmcp_slim/fastmcp/server/tasks/requests.py index 112908796..672ad6465 100644 --- a/fastmcp_slim/fastmcp/server/tasks/requests.py +++ b/fastmcp_slim/fastmcp/server/tasks/requests.py @@ -198,13 +198,13 @@ async def tasks_get_handler(server: FastMCP, params: dict[str, Any]) -> GetTaskR created_at_dt = datetime.now(timezone.utc) return GetTaskResult( - taskId=client_task_id, + task_id=client_task_id, status=mcp_state, - createdAt=created_at_dt, - lastUpdatedAt=datetime.now(timezone.utc), + created_at=created_at_dt, + last_updated_at=datetime.now(timezone.utc), ttl=DEFAULT_TTL_MS, - pollInterval=poll_interval_ms, - statusMessage=status_message, + poll_interval=poll_interval_ms, + status_message=status_message, ) @@ -277,7 +277,7 @@ async def tasks_result_handler(server: FastMCP, params: dict[str, Any]) -> Any: # Task failed - return error result return mcp_types.CallToolResult( content=[mcp_types.TextContent(type="text", text=str(error))], - isError=True, + is_error=True, _meta={ # type: ignore[call-arg] # _meta is Pydantic alias for meta field "io.modelcontextprotocol/related-task": { "taskId": client_task_id, @@ -337,7 +337,7 @@ async def tasks_result_handler(server: FastMCP, params: dict[str, Any]) -> Any: content, structured_content = mcp_result mcp_result = mcp_types.CallToolResult( content=content, - structuredContent=structured_content, + structured_content=structured_content, _meta=related_task_meta, # type: ignore[call-arg] # _meta is Pydantic alias for meta field ) else: @@ -390,7 +390,7 @@ async def tasks_list_handler( ListTasksResult: Response with tasks list and pagination """ # Return empty list - client tracks tasks locally - return ListTasksResult(tasks=[], nextCursor=None) + return ListTasksResult(tasks=[], next_cursor=None) async def tasks_cancel_handler( @@ -438,13 +438,13 @@ async def tasks_cancel_handler( # createdAt is REQUIRED per SEP-1686 final spec (line 430) # Per spec lines 447-448: SHOULD NOT include related-task metadata in tasks/cancel return CancelTaskResult( - taskId=client_task_id, + task_id=client_task_id, status="cancelled", - createdAt=datetime.fromisoformat(created_at) + created_at=datetime.fromisoformat(created_at) if created_at else datetime.now(timezone.utc), - lastUpdatedAt=datetime.now(timezone.utc), + last_updated_at=datetime.now(timezone.utc), ttl=DEFAULT_TTL_MS, - pollInterval=poll_interval_ms, - statusMessage="Task cancelled", + poll_interval=poll_interval_ms, + status_message="Task cancelled", ) diff --git a/fastmcp_slim/fastmcp/server/transforms/resources_as_tools.py b/fastmcp_slim/fastmcp/server/transforms/resources_as_tools.py index 8c3af00a5..9861fc6c9 100644 --- a/fastmcp_slim/fastmcp/server/transforms/resources_as_tools.py +++ b/fastmcp_slim/fastmcp/server/transforms/resources_as_tools.py @@ -32,7 +32,7 @@ from fastmcp.server.transforms import GetToolNext, Transform from fastmcp.tools.base import Tool from fastmcp.utilities.versions import VersionSpec -_DEFAULT_ANNOTATIONS = ToolAnnotations(readOnlyHint=True) +_DEFAULT_ANNOTATIONS = ToolAnnotations(read_only_hint=True) if TYPE_CHECKING: from fastmcp.server.providers.base import Provider diff --git a/fastmcp_slim/fastmcp/tools/base.py b/fastmcp_slim/fastmcp/tools/base.py index a3cc0e11a..879a5050f 100644 --- a/fastmcp_slim/fastmcp/tools/base.py +++ b/fastmcp_slim/fastmcp/tools/base.py @@ -167,9 +167,9 @@ class ToolResult(BaseModel): # reaches the client; the plain content/tuple returns can't carry it. if self.meta is not None or self.is_error: return CallToolResult( - structuredContent=self.structured_content, + structured_content=self.structured_content, content=self.content, - isError=self.is_error, + is_error=self.is_error, _meta=self.meta, # type: ignore[call-arg] # _meta is Pydantic alias for meta field ) if self.structured_content is None: @@ -235,8 +235,8 @@ class Tool(FastMCPComponent): name=overrides.get("name", self.name), title=overrides.get("title", title), description=overrides.get("description", self.description), - inputSchema=overrides.get("inputSchema", self.parameters), - outputSchema=overrides.get("outputSchema", self.output_schema), + input_schema=overrides.get("inputSchema", self.parameters), + output_schema=overrides.get("outputSchema", self.output_schema), icons=overrides.get("icons", self.icons), annotations=overrides.get("annotations", self.annotations), execution=overrides.get("execution", self.execution), @@ -250,7 +250,7 @@ class Tool(FastMCPComponent): and "execution" not in overrides and not self.execution ): - mcp_tool.execution = ToolExecution(taskSupport=self.task_config.mode) + mcp_tool.execution = ToolExecution(task_support=self.task_config.mode) return mcp_tool diff --git a/fastmcp_slim/fastmcp/utilities/types.py b/fastmcp_slim/fastmcp/utilities/types.py index 565ed31dc..b6a286e35 100644 --- a/fastmcp_slim/fastmcp/utilities/types.py +++ b/fastmcp_slim/fastmcp/utilities/types.py @@ -297,7 +297,7 @@ class Image: return mcp_types.ImageContent( type="image", data=data, - mimeType=mime_type or self._mime_type, + mime_type=mime_type or self._mime_type, annotations=annotations or self.annotations, ) @@ -360,7 +360,7 @@ class Audio: return mcp_types.AudioContent( type="audio", data=data, - mimeType=mime_type or self._mime_type, + mime_type=mime_type or self._mime_type, annotations=annotations or self.annotations, ) @@ -433,14 +433,14 @@ class File: text = raw_data.decode("latin-1") resource = mcp_types.TextResourceContents( text=text, - mimeType=mime, + mime_type=mime, uri=uri, ) else: data = base64.b64encode(raw_data).decode() resource = mcp_types.BlobResourceContents( blob=data, - mimeType=mime, + mime_type=mime, uri=uri, ) diff --git a/tests/cli/test_client_commands.py b/tests/cli/test_client_commands.py index 8e43b6f4e..d2083d1db 100644 --- a/tests/cli/test_client_commands.py +++ b/tests/cli/test_client_commands.py @@ -170,8 +170,8 @@ class TestFormatToolSignature: return mcp_types.Tool( name=name, description=description, - inputSchema=input_schema, - outputSchema=output_schema, + input_schema=input_schema, + output_schema=output_schema, ) def test_no_params(self): diff --git a/tests/cli/test_generate_cli.py b/tests/cli/test_generate_cli.py index e22930123..63cd23bab 100644 --- a/tests/cli/test_generate_cli.py +++ b/tests/cli/test_generate_cli.py @@ -150,7 +150,7 @@ class TestToolFunctionSource: def test_required_param(self): tool = mcp_types.Tool( name="greet", - inputSchema={ + input_schema={ "properties": {"name": {"type": "string", "description": "Who"}}, "required": ["name"], }, @@ -164,7 +164,7 @@ class TestToolFunctionSource: def test_optional_param(self): tool = mcp_types.Tool( name="search", - inputSchema={ + input_schema={ "properties": { "query": {"type": "string", "description": "Search query"}, "limit": {"type": "integer", "description": "Max results"}, @@ -180,7 +180,7 @@ class TestToolFunctionSource: def test_param_with_default(self): tool = mcp_types.Tool( name="fetch", - inputSchema={ + input_schema={ "properties": { "url": {"type": "string", "description": "URL"}, "timeout": { @@ -199,7 +199,7 @@ class TestToolFunctionSource: def test_no_params(self): tool = mcp_types.Tool( name="ping", - inputSchema={"properties": {}}, + input_schema={"properties": {}}, ) source = _tool_function_source(tool) assert "async def ping(" in source @@ -208,7 +208,7 @@ class TestToolFunctionSource: def test_preserves_underscores(self): tool = mcp_types.Tool( name="get_forecast", - inputSchema={ + input_schema={ "properties": {"city": {"type": "string"}}, "required": ["city"], }, @@ -219,7 +219,7 @@ class TestToolFunctionSource: def test_sanitizes_tool_name(self): tool = mcp_types.Tool( name="my.tool/v2", - inputSchema={"properties": {}}, + input_schema={"properties": {}}, ) source = _tool_function_source(tool) assert "async def my_tool_v2(" in source @@ -228,7 +228,7 @@ class TestToolFunctionSource: def test_sanitizes_param_name(self): tool = mcp_types.Tool( name="fetch", - inputSchema={ + input_schema={ "properties": {"content-type": {"type": "string", "description": "CT"}}, "required": ["content-type"], }, @@ -241,7 +241,7 @@ class TestToolFunctionSource: tool = mcp_types.Tool( name="greet", description="Say hello to someone.", - inputSchema={ + input_schema={ "properties": {"name": {"type": "string"}}, "required": ["name"], }, @@ -253,7 +253,7 @@ class TestToolFunctionSource: tool = mcp_types.Tool( name="fetch", description="Fetch data from 'source' API.", - inputSchema={ + input_schema={ "properties": {"url": {"type": "string"}}, "required": ["url"], }, @@ -268,7 +268,7 @@ class TestToolFunctionSource: tool = mcp_types.Tool( name="tag_items", description="Tag multiple items.", - inputSchema={ + input_schema={ "properties": { "item_id": {"type": "string"}, "tags": {"type": "array", "items": {"type": "string"}}, @@ -288,7 +288,7 @@ class TestToolFunctionSource: tool = mcp_types.Tool( name="create_user", description="Create a user.", - inputSchema={ + input_schema={ "properties": { "name": {"type": "string"}, "metadata": { @@ -321,7 +321,7 @@ class TestToolFunctionSource: tool = mcp_types.Tool( name="batch_process", description="Process batches.", - inputSchema={ + input_schema={ "properties": { "batches": { "type": "array", @@ -348,7 +348,7 @@ class TestToolFunctionSource: """Test that complex types with defaults are JSON-serialized.""" tool = mcp_types.Tool( name="configure", - inputSchema={ + input_schema={ "properties": { "options": { "type": "object", @@ -369,7 +369,7 @@ class TestToolFunctionSource: """Test that parameter name collisions are detected.""" tool = mcp_types.Tool( name="test", - inputSchema={ + input_schema={ "properties": { "content-type": {"type": "string"}, "content_type": {"type": "string"}, @@ -414,7 +414,7 @@ class TestGenerateCliScript: mcp_types.Tool( name="greet", description="Say hello", - inputSchema={ + input_schema={ "properties": { "name": {"type": "string", "description": "Who to greet"}, }, @@ -424,7 +424,7 @@ class TestGenerateCliScript: mcp_types.Tool( name="add_numbers", description="Add two numbers", - inputSchema={ + input_schema={ "properties": { "a": {"type": "integer", "description": "First number"}, "b": {"type": "integer", "description": "Second number"}, @@ -510,7 +510,7 @@ class TestGenerateCliScript: mcp_types.Tool( name="my.tool/v2", description="A tool with dots and slashes", - inputSchema={ + input_schema={ "properties": { "content-type": {"type": "string", "description": "CT"}, }, @@ -774,7 +774,7 @@ class TestGenerateSkillContent: mcp_types.Tool( name="greet", description="Say hello", - inputSchema={ + input_schema={ "type": "object", "properties": { "name": {"type": "string", "description": "Who to greet"} @@ -796,7 +796,7 @@ class TestGenerateSkillContent: tools = [ mcp_types.Tool( name="greet", - inputSchema={"type": "object", "properties": {}}, + input_schema={"type": "object", "properties": {}}, ), ] content = generate_skill_content("weather", "cli.py", tools) @@ -807,7 +807,7 @@ class TestGenerateSkillContent: mcp_types.Tool( name="search", description="Search things", - inputSchema={ + input_schema={ "type": "object", "properties": { "query": {"type": "string"}, @@ -827,7 +827,7 @@ class TestGenerateSkillContent: mcp_types.Tool( name="create", description="Create item", - inputSchema={ + input_schema={ "type": "object", "properties": { "data": { @@ -847,7 +847,7 @@ class TestGenerateSkillContent: mcp_types.Tool( name="ping", description="Ping the server", - inputSchema={"type": "object", "properties": {}}, + input_schema={"type": "object", "properties": {}}, ), ] content = generate_skill_content("test", "cli.py", tools) @@ -866,7 +866,7 @@ class TestGenerateSkillContent: mcp_types.Tool( name="test", description="Test", - inputSchema={ + input_schema={ "type": "object", "properties": { "mode": {"type": "string", "description": "a|b|c"}, @@ -882,7 +882,7 @@ class TestGenerateSkillContent: mcp_types.Tool( name="test", description="Test", - inputSchema={ + input_schema={ "type": "object", "properties": { "val": {"type": ["string", "null"]}, @@ -899,7 +899,7 @@ class TestGenerateSkillContent: mcp_types.Tool( name="run", description="Run something", - inputSchema={ + input_schema={ "type": "object", "properties": { "verbose": {"type": "boolean", "description": "Verbose output"}, diff --git a/tests/client/client/test_error_handling.py b/tests/client/client/test_error_handling.py index ee8161690..aa1ed61d1 100644 --- a/tests/client/client/test_error_handling.py +++ b/tests/client/client/test_error_handling.py @@ -207,7 +207,7 @@ class TestParseToolResultEdgeCases: """ async def test_error_with_empty_content_raises_with_fallback_message(self): - result = mcp_types.CallToolResult(content=[], isError=True) + result = mcp_types.CallToolResult(content=[], is_error=True) with pytest.raises(ToolError, match="Tool 'my_tool' returned an error"): await _parse_call_tool_result( @@ -221,9 +221,9 @@ class TestParseToolResultEdgeCases: async def test_error_with_non_text_content_raises_with_fallback_message(self): result = mcp_types.CallToolResult( content=[ - mcp_types.ImageContent(type="image", data="abc", mimeType="image/png") + mcp_types.ImageContent(type="image", data="abc", mime_type="image/png") ], - isError=True, + is_error=True, ) with pytest.raises(ToolError, match="Tool 'my_tool' returned an error"): @@ -238,7 +238,7 @@ class TestParseToolResultEdgeCases: async def test_error_with_text_content_raises_with_message(self): result = mcp_types.CallToolResult( content=[mcp_types.TextContent(type="text", text="custom error msg")], - isError=True, + is_error=True, ) with pytest.raises(ToolError, match="custom error msg"): @@ -253,8 +253,8 @@ class TestParseToolResultEdgeCases: async def test_error_with_structured_content_does_not_parse_data(self): result = mcp_types.CallToolResult( content=[mcp_types.TextContent(type="text", text="error happened")], - isError=True, - structuredContent={"key": "value"}, + is_error=True, + structured_content={"key": "value"}, ) parsed = await _parse_call_tool_result( diff --git a/tests/client/sampling/handlers/test_anthropic_handler.py b/tests/client/sampling/handlers/test_anthropic_handler.py index a0497ffff..733f72085 100644 --- a/tests/client/sampling/handlers/test_anthropic_handler.py +++ b/tests/client/sampling/handlers/test_anthropic_handler.py @@ -46,7 +46,7 @@ def test_convert_sampling_messages_to_anthropic_messages(): def test_image_content_to_anthropic_block(): block = _image_content_to_anthropic_block( - ImageContent(type="image", data="YWJj", mimeType="image/png") + ImageContent(type="image", data="YWJj", mime_type="image/png") ) assert block == { @@ -62,7 +62,7 @@ def test_image_content_to_anthropic_block(): def test_image_content_unsupported_mime_type_raises(): with pytest.raises(ValueError, match="Unsupported image MIME type"): _image_content_to_anthropic_block( - ImageContent(type="image", data="YWJj", mimeType="image/bmp") + ImageContent(type="image", data="YWJj", mime_type="image/bmp") ) @@ -71,7 +71,7 @@ def test_convert_single_image_content_to_anthropic_message(): messages=[ SamplingMessage( role="user", - content=ImageContent(type="image", data="YWJj", mimeType="image/png"), + content=ImageContent(type="image", data="YWJj", mime_type="image/png"), ) ], ) @@ -99,7 +99,7 @@ def test_convert_single_audio_content_raises(): SamplingMessage( role="user", content=AudioContent( - type="audio", data="YWJj", mimeType="audio/wav" + type="audio", data="YWJj", mime_type="audio/wav" ), ) ], @@ -113,7 +113,7 @@ def test_convert_list_content_with_image_and_text(): role="user", content=[ TextContent(type="text", text="Describe this image"), - ImageContent(type="image", data="YWJj", mimeType="image/jpeg"), + ImageContent(type="image", data="YWJj", mime_type="image/jpeg"), ], ) ], @@ -144,7 +144,7 @@ def test_convert_list_content_with_audio_raises(): role="user", content=[ TextContent(type="text", text="Listen to this"), - AudioContent(type="audio", data="YWJj", mimeType="audio/wav"), + AudioContent(type="audio", data="YWJj", mime_type="audio/wav"), ], ) ], @@ -158,7 +158,7 @@ def test_convert_image_in_assistant_message_raises(): SamplingMessage( role="assistant", content=ImageContent( - type="image", data="YWJj", mimeType="image/png" + type="image", data="YWJj", mime_type="image/png" ), ) ], @@ -173,7 +173,7 @@ def test_convert_list_image_in_assistant_message_raises(): role="assistant", content=[ TextContent(type="text", text="Here's the image"), - ImageContent(type="image", data="YWJj", mimeType="image/png"), + ImageContent(type="image", data="YWJj", mime_type="image/png"), ], ) ], @@ -302,7 +302,7 @@ def test_convert_tools_to_anthropic(): Tool( name="get_weather", description="Get the current weather", - inputSchema={ + input_schema={ "type": "object", "properties": {"location": {"type": "string"}}, "required": ["location"], @@ -358,7 +358,7 @@ def test_convert_messages_with_tool_result_content(): role="user", content=ToolResultContent( type="tool_result", - toolUseId="toolu_123", + tool_use_id="toolu_123", content=[TextContent(type="text", text="72F and sunny")], ), ), @@ -387,7 +387,7 @@ def test_convert_messages_raises_on_unsupported_content_type(): embedded = EmbeddedResource( type="resource", resource=TextResourceContents( - uri=AnyUrl("file:///test.txt"), text="hello", mimeType="text/plain" + uri=AnyUrl("file:///test.txt"), text="hello", mime_type="text/plain" ), ) # Must be inside a list content — single-content messages hit a diff --git a/tests/client/sampling/handlers/test_google_genai_handler.py b/tests/client/sampling/handlers/test_google_genai_handler.py index 9a401f2f9..dd610c91a 100644 --- a/tests/client/sampling/handlers/test_google_genai_handler.py +++ b/tests/client/sampling/handlers/test_google_genai_handler.py @@ -66,7 +66,7 @@ def test_convert_sampling_messages_to_google_genai_content(): def test_convert_single_image_content_to_google_genai(): part = _sampling_content_to_google_genai_part( - ImageContent(type="image", data="YWJj", mimeType="image/png") + ImageContent(type="image", data="YWJj", mime_type="image/png") ) assert part.inline_data is not None @@ -76,7 +76,7 @@ def test_convert_single_image_content_to_google_genai(): def test_convert_single_audio_content_to_google_genai(): part = _sampling_content_to_google_genai_part( - AudioContent(type="audio", data="YWJj", mimeType="audio/wav") + AudioContent(type="audio", data="YWJj", mime_type="audio/wav") ) assert part.inline_data is not None @@ -89,7 +89,7 @@ def test_convert_image_message_to_google_genai_content(): messages=[ SamplingMessage( role="user", - content=ImageContent(type="image", data="YWJj", mimeType="image/jpeg"), + content=ImageContent(type="image", data="YWJj", mime_type="image/jpeg"), ) ], ) @@ -105,7 +105,7 @@ def test_convert_audio_message_to_google_genai_content(): messages=[ SamplingMessage( role="user", - content=AudioContent(type="audio", data="YWJj", mimeType="audio/mp3"), + content=AudioContent(type="audio", data="YWJj", mime_type="audio/mp3"), ) ], ) @@ -123,7 +123,7 @@ def test_convert_list_content_with_image_and_text(): role="user", content=[ TextContent(type="text", text="What is in this image?"), - ImageContent(type="image", data="YWJj", mimeType="image/png"), + ImageContent(type="image", data="YWJj", mime_type="image/png"), ], ) ], @@ -144,7 +144,7 @@ def test_convert_list_content_with_audio_and_text(): role="user", content=[ TextContent(type="text", text="Transcribe this audio"), - AudioContent(type="audio", data="YWJj", mimeType="audio/wav"), + AudioContent(type="audio", data="YWJj", mime_type="audio/wav"), ], ) ], @@ -243,7 +243,7 @@ def test_sampling_content_to_google_genai_part_tool_result(): """Test converting ToolResultContent to Google GenAI Part with FunctionResponse.""" content = ToolResultContent( type="tool_result", - toolUseId="get_weather_abc123", + tool_use_id="get_weather_abc123", content=[TextContent(type="text", text="Weather is sunny")], ) @@ -259,7 +259,7 @@ def test_sampling_content_to_google_genai_part_tool_result_empty(): """Test converting empty ToolResultContent to Google GenAI Part.""" content = ToolResultContent( type="tool_result", - toolUseId="my_tool_xyz789", + tool_use_id="my_tool_xyz789", content=[], ) @@ -274,7 +274,7 @@ def test_sampling_content_to_google_genai_part_tool_result_no_underscore(): """Test ToolResultContent when toolUseId has no underscore (fallback).""" content = ToolResultContent( type="tool_result", - toolUseId="simplefunction", + tool_use_id="simplefunction", content=[TextContent(type="text", text="Result")], ) @@ -320,7 +320,7 @@ def test_convert_messages_with_tool_result(): role="user", content=ToolResultContent( type="tool_result", - toolUseId="get_weather_123", + tool_use_id="get_weather_123", content=[TextContent(type="text", text="Sunny, 72F")], ), ), @@ -343,7 +343,7 @@ def test_convert_messages_with_multiple_content_blocks(): TextContent(type="text", text="I need weather info."), ToolResultContent( type="tool_result", - toolUseId="get_weather_xyz", + tool_use_id="get_weather_xyz", content=[TextContent(type="text", text="Cloudy")], ), ], diff --git a/tests/client/sampling/handlers/test_openai_handler.py b/tests/client/sampling/handlers/test_openai_handler.py index 584aeaeea..e50be7349 100644 --- a/tests/client/sampling/handlers/test_openai_handler.py +++ b/tests/client/sampling/handlers/test_openai_handler.py @@ -58,7 +58,7 @@ def test_convert_sampling_messages_to_openai_messages(): def test_image_content_to_openai_part(): part = _image_content_to_openai_part( - ImageContent(type="image", data="YWJj", mimeType="image/png") + ImageContent(type="image", data="YWJj", mime_type="image/png") ) assert part == ChatCompletionContentPartImageParam( @@ -69,7 +69,7 @@ def test_image_content_to_openai_part(): def test_audio_content_to_openai_part_wav(): part = _audio_content_to_openai_part( - AudioContent(type="audio", data="YWJj", mimeType="audio/wav") + AudioContent(type="audio", data="YWJj", mime_type="audio/wav") ) assert part == ChatCompletionContentPartInputAudioParam( @@ -80,7 +80,7 @@ def test_audio_content_to_openai_part_wav(): def test_audio_content_to_openai_part_mp3(): part = _audio_content_to_openai_part( - AudioContent(type="audio", data="YWJj", mimeType="audio/mpeg") + AudioContent(type="audio", data="YWJj", mime_type="audio/mpeg") ) assert part["input_audio"]["format"] == "mp3" @@ -89,14 +89,14 @@ def test_audio_content_to_openai_part_mp3(): def test_audio_content_to_openai_part_unsupported_raises(): with pytest.raises(ValueError, match="Unsupported audio MIME type"): _audio_content_to_openai_part( - AudioContent(type="audio", data="YWJj", mimeType="audio/ogg") + AudioContent(type="audio", data="YWJj", mime_type="audio/ogg") ) def test_image_content_to_openai_part_unsupported_raises(): with pytest.raises(ValueError, match="Unsupported image MIME type"): _image_content_to_openai_part( - ImageContent(type="image", data="YWJj", mimeType="image/bmp") + ImageContent(type="image", data="YWJj", mime_type="image/bmp") ) @@ -106,7 +106,7 @@ def test_convert_single_image_content_to_openai_message(): messages=[ SamplingMessage( role="user", - content=ImageContent(type="image", data="YWJj", mimeType="image/png"), + content=ImageContent(type="image", data="YWJj", mime_type="image/png"), ) ], ) @@ -129,7 +129,7 @@ def test_convert_single_audio_content_to_openai_message(): messages=[ SamplingMessage( role="user", - content=AudioContent(type="audio", data="YWJj", mimeType="audio/wav"), + content=AudioContent(type="audio", data="YWJj", mime_type="audio/wav"), ) ], ) @@ -154,7 +154,7 @@ def test_convert_list_content_with_image_and_text(): role="user", content=[ TextContent(type="text", text="What is in this image?"), - ImageContent(type="image", data="YWJj", mimeType="image/jpeg"), + ImageContent(type="image", data="YWJj", mime_type="image/jpeg"), ], ) ], @@ -183,7 +183,7 @@ def test_convert_image_in_assistant_message_raises(): SamplingMessage( role="assistant", content=ImageContent( - type="image", data="YWJj", mimeType="image/png" + type="image", data="YWJj", mime_type="image/png" ), ) ], @@ -198,7 +198,7 @@ def test_convert_audio_in_assistant_message_raises(): SamplingMessage( role="assistant", content=AudioContent( - type="audio", data="YWJj", mimeType="audio/wav" + type="audio", data="YWJj", mime_type="audio/wav" ), ) ], @@ -215,7 +215,7 @@ def test_convert_list_image_in_assistant_message_raises(): role="assistant", content=[ TextContent(type="text", text="Here's the image"), - ImageContent(type="image", data="YWJj", mimeType="image/png"), + ImageContent(type="image", data="YWJj", mime_type="image/png"), ], ) ], @@ -237,7 +237,7 @@ def test_convert_list_tool_calls_with_image_raises(): name="my_tool", input={"arg": "val"}, ), - ImageContent(type="image", data="YWJj", mimeType="image/png"), + ImageContent(type="image", data="YWJj", mime_type="image/png"), ], ) ], @@ -284,7 +284,7 @@ async def test_handler_passes_max_completion_tokens(): messages = [ SamplingMessage(role="user", content=TextContent(type="text", text="hello")) ] - params = CreateMessageRequestParams(messages=messages, maxTokens=300) + params = CreateMessageRequestParams(messages=messages, max_tokens=300) await handler(messages, params, context=None) # type: ignore[arg-type] # ty:ignore[invalid-argument-type] call_kwargs = mock_client.chat.completions.create.call_args @@ -331,7 +331,7 @@ def test_convert_messages_raises_on_unsupported_content_type(): embedded = EmbeddedResource( type="resource", resource=TextResourceContents( - uri=AnyUrl("file:///test.txt"), text="hello", mimeType="text/plain" + uri=AnyUrl("file:///test.txt"), text="hello", mime_type="text/plain" ), ) msg = SamplingMessage.model_construct( diff --git a/tests/client/tasks/test_client_task_notifications.py b/tests/client/tasks/test_client_task_notifications.py index 728306264..b4debe115 100644 --- a/tests/client/tasks/test_client_task_notifications.py +++ b/tests/client/tasks/test_client_task_notifications.py @@ -218,11 +218,11 @@ async def test_wait_returns_on_input_required(task_notification_server): # Directly inject an input_required status into the cache and signal the event now = datetime.now(timezone.utc) input_required_status = GetTaskResult( - taskId=task._task_id, + task_id=task._task_id, status="input_required", - statusMessage="Waiting for user input", - createdAt=now, - lastUpdatedAt=now, + status_message="Waiting for user input", + created_at=now, + last_updated_at=now, ttl=None, ) task._status_cache = input_required_status diff --git a/tests/client/test_sampling_result_types.py b/tests/client/test_sampling_result_types.py index fc4df87c0..e581e2582 100644 --- a/tests/client/test_sampling_result_types.py +++ b/tests/client/test_sampling_result_types.py @@ -36,7 +36,7 @@ class TestSamplingResultType: ) ], model="test-model", - stopReason="toolUse", + stop_reason="toolUse", ) mcp = FastMCP(sampling_handler=sampling_handler) @@ -96,7 +96,7 @@ class TestSamplingResultType: ) ], model="test-model", - stopReason="toolUse", + stop_reason="toolUse", ) else: # Second call: call final_response @@ -115,7 +115,7 @@ class TestSamplingResultType: ) ], model="test-model", - stopReason="toolUse", + stop_reason="toolUse", ) mcp = FastMCP(sampling_handler=sampling_handler) @@ -168,7 +168,7 @@ class TestSamplingResultType: ) ], model="test-model", - stopReason="toolUse", + stop_reason="toolUse", ) else: # Second call: valid type after seeing error @@ -183,7 +183,7 @@ class TestSamplingResultType: ) ], model="test-model", - stopReason="toolUse", + stop_reason="toolUse", ) mcp = FastMCP(sampling_handler=sampling_handler) @@ -237,7 +237,7 @@ class TestSamplingResultType: role="assistant", content=[TextContent(type="text", text="Hello world")], model="test-model", - stopReason="endTurn", + stop_reason="endTurn", ) mcp = FastMCP(sampling_handler=sampling_handler) @@ -271,7 +271,7 @@ class TestSampleStep: role="assistant", content=[TextContent(type="text", text="Hello from step")], model="test-model", - stopReason="endTurn", + stop_reason="endTurn", ) mcp = FastMCP(sampling_handler=sampling_handler) @@ -316,14 +316,14 @@ class TestSampleStep: ) ], model="test-model", - stopReason="toolUse", + stop_reason="toolUse", ) else: return CreateMessageResultWithTools( role="assistant", content=[TextContent(type="text", text="Done")], model="test-model", - stopReason="endTurn", + stop_reason="endTurn", ) mcp = FastMCP(sampling_handler=sampling_handler) @@ -373,7 +373,7 @@ class TestSampleStep: ) ], model="test-model", - stopReason="toolUse", + stop_reason="toolUse", ) mcp = FastMCP(sampling_handler=sampling_handler) @@ -416,7 +416,7 @@ class TestSampleStep: ) ], model="test-model", - stopReason="toolUse", + stop_reason="toolUse", ) mcp = FastMCP(sampling_handler=sampling_handler) @@ -454,7 +454,7 @@ class TestTextResponseRetry: role="assistant", content=[TextContent(type="text", text=text)], model="m", - stopReason="endTurn", + stop_reason="endTurn", ) @staticmethod @@ -472,7 +472,7 @@ class TestTextResponseRetry: ) ], model="m", - stopReason="toolUse", + stop_reason="toolUse", ) async def test_text_response_then_success(self): @@ -562,7 +562,7 @@ def _final_response(call_id: str, input_data: dict) -> CreateMessageResultWithTo ) ], model="test-model", - stopReason="toolUse", + stop_reason="toolUse", ) @@ -576,7 +576,7 @@ def _tool_call( ToolUseContent(type="tool_use", id=call_id, name=name, input=input_data) ], model="test-model", - stopReason="toolUse", + stop_reason="toolUse", ) diff --git a/tests/client/test_sampling_tool_loop.py b/tests/client/test_sampling_tool_loop.py index 4bf5faf02..809e58ed8 100644 --- a/tests/client/test_sampling_tool_loop.py +++ b/tests/client/test_sampling_tool_loop.py @@ -42,7 +42,7 @@ class TestAutomaticToolLoop: ) ], model="test-model", - stopReason="toolUse", + stop_reason="toolUse", ) else: # Second call: return final response @@ -50,7 +50,7 @@ class TestAutomaticToolLoop: role="assistant", content=[TextContent(type="text", text="The weather is sunny!")], model="test-model", - stopReason="endTurn", + stop_reason="endTurn", ) mcp = FastMCP(sampling_handler=sampling_handler) @@ -110,14 +110,14 @@ class TestAutomaticToolLoop: ), ], model="test-model", - stopReason="toolUse", + stop_reason="toolUse", ) else: return CreateMessageResultWithTools( role="assistant", content=[TextContent(type="text", text="Done!")], model="test-model", - stopReason="endTurn", + stop_reason="endTurn", ) mcp = FastMCP(sampling_handler=sampling_handler) @@ -165,14 +165,14 @@ class TestAutomaticToolLoop: ) ], model="test-model", - stopReason="toolUse", + stop_reason="toolUse", ) else: return CreateMessageResultWithTools( role="assistant", content=[TextContent(type="text", text="Handled error")], model="test-model", - stopReason="endTurn", + stop_reason="endTurn", ) mcp = FastMCP(sampling_handler=sampling_handler) @@ -239,14 +239,14 @@ class TestAutomaticToolLoop: ) ], model="test-model", - stopReason="toolUse", + stop_reason="toolUse", ) else: return CreateMessageResultWithTools( role="assistant", content=[TextContent(type="text", text="Handled error")], model="test-model", - stopReason="endTurn", + stop_reason="endTurn", ) mcp = FastMCP(sampling_handler=sampling_handler) @@ -333,14 +333,14 @@ class TestAutomaticToolLoop: ), ], model="test-model", - stopReason="toolUse", + stop_reason="toolUse", ) else: return CreateMessageResultWithTools( role="assistant", content=[TextContent(type="text", text="Done!")], model="test-model", - stopReason="endTurn", + stop_reason="endTurn", ) mcp = FastMCP(sampling_handler=sampling_handler) @@ -411,14 +411,14 @@ class TestAutomaticToolLoop: ), ], model="test-model", - stopReason="toolUse", + stop_reason="toolUse", ) else: return CreateMessageResultWithTools( role="assistant", content=[TextContent(type="text", text="Done!")], model="test-model", - stopReason="endTurn", + stop_reason="endTurn", ) mcp = FastMCP(sampling_handler=sampling_handler) @@ -491,14 +491,14 @@ class TestAutomaticToolLoop: ), ], model="test-model", - stopReason="toolUse", + stop_reason="toolUse", ) else: return CreateMessageResultWithTools( role="assistant", content=[TextContent(type="text", text="Done!")], model="test-model", - stopReason="endTurn", + stop_reason="endTurn", ) mcp = FastMCP(sampling_handler=sampling_handler) @@ -577,14 +577,14 @@ class TestAutomaticToolLoop: ), ], model="test-model", - stopReason="toolUse", + stop_reason="toolUse", ) else: return CreateMessageResultWithTools( role="assistant", content=[TextContent(type="text", text="Done!")], model="test-model", - stopReason="endTurn", + stop_reason="endTurn", ) mcp = FastMCP(sampling_handler=sampling_handler) @@ -651,14 +651,14 @@ class TestAutomaticToolLoop: ), ], model="test-model", - stopReason="toolUse", + stop_reason="toolUse", ) else: return CreateMessageResultWithTools( role="assistant", content=[TextContent(type="text", text="Handled errors")], model="test-model", - stopReason="endTurn", + stop_reason="endTurn", ) mcp = FastMCP(sampling_handler=sampling_handler) @@ -732,14 +732,14 @@ class TestAutomaticToolLoop: ), ], model="test-model", - stopReason="toolUse", + stop_reason="toolUse", ) else: return CreateMessageResultWithTools( role="assistant", content=[TextContent(type="text", text="Done!")], model="test-model", - stopReason="endTurn", + stop_reason="endTurn", ) mcp = FastMCP(sampling_handler=sampling_handler) diff --git a/tests/conformance/server.py b/tests/conformance/server.py index 2c0072ea4..d92b22dd7 100644 --- a/tests/conformance/server.py +++ b/tests/conformance/server.py @@ -78,7 +78,7 @@ async def test_embedded_resource() -> list: type="resource", resource=mcp_types.TextResourceContents( uri=AnyUrl("test://embedded-resource"), - mimeType="text/plain", + mime_type="text/plain", text="This is an embedded resource content.", ), ) @@ -93,13 +93,13 @@ async def test_multiple_content_types() -> list: ImageContent( type="image", data=base64.b64encode(_1X1_PNG).decode(), - mimeType="image/png", + mime_type="image/png", ), EmbeddedResource( type="resource", resource=mcp_types.TextResourceContents( uri=AnyUrl("test://mixed-content-resource"), - mimeType="application/json", + mime_type="application/json", text='{"test":"data","value":123}', ), ), @@ -185,7 +185,7 @@ async def test_elicitation_sep1330_enums(ctx: Context) -> str: """Tests elicitation with enum schema improvements per SEP-1330.""" result = await ctx.session.elicit( message="Please select options from the enum fields", - requestedSchema={ + requested_schema={ "type": "object", "properties": { "untitledSingle": { @@ -349,7 +349,7 @@ async def test_prompt_with_embedded_resource(resourceUri: str) -> list: type="resource", resource=mcp_types.TextResourceContents( uri=AnyUrl(resourceUri), - mimeType="text/plain", + mime_type="text/plain", text=f"Content of resource {resourceUri}", ), ) @@ -365,7 +365,7 @@ async def test_prompt_with_image() -> list: ImageContent( type="image", data=base64.b64encode(_1X1_PNG).decode(), - mimeType="image/png", + mime_type="image/png", ) ), Message("Please analyze the image above."), diff --git a/tests/conftest.py b/tests/conftest.py index 952cecc4a..a89ba028b 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -239,12 +239,14 @@ def tool_server(): def mixed_content_tool() -> list[TextContent | ImageContent | EmbeddedResource]: return [ TextContent(type="text", text="Hello"), - ImageContent(type="image", data="abc", mimeType="application/octet-stream"), + ImageContent( + type="image", data="abc", mime_type="application/octet-stream" + ), EmbeddedResource( type="resource", resource=BlobResourceContents( blob=base64.b64encode(b"abc").decode(), - mimeType="application/octet-stream", + mime_type="application/octet-stream", uri=AnyUrl("file:///test.bin"), ), ), diff --git a/tests/contrib/test_bulk_tool_caller.py b/tests/contrib/test_bulk_tool_caller.py index b7378ace4..97ee6a12e 100644 --- a/tests/contrib/test_bulk_tool_caller.py +++ b/tests/contrib/test_bulk_tool_caller.py @@ -31,7 +31,7 @@ def error_tool_result_factory(arg1: str) -> CallToolRequestResult: "Error calling tool 'error_tool': Error in tool with arg1: " + arg1 ) return CallToolRequestResult( - isError=True, + is_error=True, content=[TextContent(text=formatted_error_text, type="text")], tool="error_tool", arguments={"arg1": arg1}, @@ -46,7 +46,7 @@ async def echo_tool(arg1: str) -> str: def echo_tool_result_factory(arg1: str) -> CallToolRequestResult: """A tool that returns a result based on the input arguments.""" return CallToolRequestResult( - isError=False, + is_error=False, content=[TextContent(text=f"{arg1}", type="text")], tool="echo_tool", arguments={"arg1": arg1}, @@ -60,7 +60,7 @@ async def no_return_tool(arg1: str) -> None: def no_return_tool_result_factory(arg1: str) -> CallToolRequestResult: """A tool that returns a result based on the input arguments.""" return CallToolRequestResult( - isError=False, + is_error=False, content=[], tool="no_return_tool", arguments={"arg1": arg1}, @@ -147,7 +147,7 @@ async def test_call_tool_bulk_error_stops(bulk_caller_live: BulkToolCaller): text="Error calling tool 'error_tool': Error in tool with arg1: error_value", ) ], - isError=True, + is_error=True, tool="error_tool", arguments={"arg1": "error_value"}, ) @@ -174,7 +174,7 @@ async def test_call_tool_bulk_error_continues(bulk_caller_live: BulkToolCaller): text="Error calling tool 'error_tool': Error in tool with arg1: error_value", ) ], - isError=True, + is_error=True, tool="error_tool", arguments={"arg1": "error_value"}, ), @@ -249,7 +249,7 @@ async def test_call_tools_bulk_error_stops(bulk_caller_live: BulkToolCaller): text="Error calling tool 'error_tool': Error in tool with arg1: error_value", ) ], - isError=True, + is_error=True, tool="error_tool", arguments={"arg1": "error_value"}, ) @@ -275,7 +275,7 @@ async def test_call_tools_bulk_error_continues(bulk_caller_live: BulkToolCaller) text="Error calling tool 'error_tool': Error in tool with arg1: error_value", ) ], - isError=True, + is_error=True, tool="error_tool", arguments={"arg1": "error_value"}, ), @@ -309,7 +309,7 @@ async def test_call_tools_bulk_blocks_self_invocation(bulk_caller_live: BulkTool ), ) ], - isError=True, + is_error=True, tool="call_tools_bulk", arguments={"tool_calls": []}, ), @@ -341,7 +341,7 @@ async def test_call_tool_bulk_blocks_self_invocation(bulk_caller_live: BulkToolC ), ) ], - isError=True, + is_error=True, tool="call_tool_bulk", arguments={"arg1": "value1"}, ) diff --git a/tests/experimental/transforms/test_code_mode.py b/tests/experimental/transforms/test_code_mode.py index fc920f9a3..557f33c8b 100644 --- a/tests/experimental/transforms/test_code_mode.py +++ b/tests/experimental/transforms/test_code_mode.py @@ -656,7 +656,7 @@ async def test_code_mode_execute_non_text_content_stringified() -> None: @mcp.tool def image_tool() -> ImageContent: - return ImageContent(type="image", data="base64data", mimeType="image/png") + return ImageContent(type="image", data="base64data", mime_type="image/png") mcp.add_transform(CodeMode(sandbox_provider=_UnsafeTestSandboxProvider())) diff --git a/tests/prompts/test_prompt.py b/tests/prompts/test_prompt.py index 62fd416a7..6d692f264 100644 --- a/tests/prompts/test_prompt.py +++ b/tests/prompts/test_prompt.py @@ -114,7 +114,7 @@ class TestRenderPrompt: resource=TextResourceContents( uri=FileUrl("file://file.txt"), text="File contents", - mimeType="text/plain", + mime_type="text/plain", ), ), role="user", @@ -130,7 +130,7 @@ class TestRenderPrompt: resource=TextResourceContents( uri=FileUrl("file://file.txt"), text="File contents", - mimeType="text/plain", + mime_type="text/plain", ), ), role="user", @@ -149,7 +149,7 @@ class TestRenderPrompt: resource=TextResourceContents( uri=FileUrl("file://file.txt"), text="File contents", - mimeType="text/plain", + mime_type="text/plain", ), ), role="user", @@ -167,7 +167,7 @@ class TestRenderPrompt: resource=TextResourceContents( uri=FileUrl("file://file.txt"), text="File contents", - mimeType="text/plain", + mime_type="text/plain", ), ), role="user", @@ -186,7 +186,7 @@ class TestRenderPrompt: resource=TextResourceContents( uri=FileUrl("file://file.txt"), text="File contents", - mimeType="text/plain", + mime_type="text/plain", ), ), role="user", @@ -202,7 +202,7 @@ class TestRenderPrompt: resource=TextResourceContents( uri=FileUrl("file://file.txt"), text="File contents", - mimeType="text/plain", + mime_type="text/plain", ), ), role="user", @@ -628,7 +628,7 @@ class TestMessage: """Test Message passes through ImageContent without JSON serialization.""" from mcp_types import ImageContent - img = ImageContent(type="image", data="base64data", mimeType="image/png") + img = ImageContent(type="image", data="base64data", mime_type="image/png") msg = Message(img, role="user") assert isinstance(msg.content, ImageContent) assert msg.content.data == "base64data" @@ -638,7 +638,7 @@ class TestMessage: """Test Message passes through AudioContent without JSON serialization.""" from mcp_types import AudioContent - audio = AudioContent(type="audio", data="base64audio", mimeType="audio/wav") + audio = AudioContent(type="audio", data="base64audio", mime_type="audio/wav") msg = Message(audio, role="user") assert isinstance(msg.content, AudioContent) assert msg.content.data == "base64audio" @@ -648,7 +648,7 @@ class TestMessage: """Test that ImageContent round-trips through to_mcp_prompt_message.""" from mcp_types import ImageContent - img = ImageContent(type="image", data="base64data", mimeType="image/png") + img = ImageContent(type="image", data="base64data", mime_type="image/png") msg = Message(img, role="user") mcp_msg = msg.to_mcp_prompt_message() assert isinstance(mcp_msg.content, ImageContent) diff --git a/tests/resources/test_resource_template_meta.py b/tests/resources/test_resource_template_meta.py index ed603e46b..3b65f9c4e 100644 --- a/tests/resources/test_resource_template_meta.py +++ b/tests/resources/test_resource_template_meta.py @@ -46,7 +46,7 @@ class TestResourceTemplateFieldPreservation: name="t", title="Human Title", meta={"owner": "team-a"}, - icons=[Icon(src="https://example.com/icon.png", mimeType="image/png")], + icons=[Icon(src="https://example.com/icon.png", mime_type="image/png")], annotations=Annotations(priority=0.5, audience=["user"]), ) @@ -84,7 +84,7 @@ class TestResourceTemplateFieldPreservation: "data://{param}", title="Sub Title", meta={"owner": "team-b"}, - icons=[Icon(src="https://example.com/s.png", mimeType="image/png")], + icons=[Icon(src="https://example.com/s.png", mime_type="image/png")], annotations=Annotations(priority=0.9), tags={"alpha"}, ) diff --git a/tests/server/auth/test_enhanced_error_responses.py b/tests/server/auth/test_enhanced_error_responses.py index 1caa15f20..4d7a2ac34 100644 --- a/tests/server/auth/test_enhanced_error_responses.py +++ b/tests/server/auth/test_enhanced_error_responses.py @@ -157,7 +157,7 @@ class TestEnhancedAuthorizationHandler: # Create FastMCP server with custom branding mcp = FastMCP( "My Custom Server", - icons=[Icon(src="https://example.com/icon.png", mimeType="image/png")], + icons=[Icon(src="https://example.com/icon.png", mime_type="image/png")], ) # Create app with OAuth routes diff --git a/tests/server/middleware/test_response_limiting.py b/tests/server/middleware/test_response_limiting.py index 8ce1f7a55..b1586a744 100644 --- a/tests/server/middleware/test_response_limiting.py +++ b/tests/server/middleware/test_response_limiting.py @@ -127,7 +127,7 @@ class TestResponseLimitingMiddleware: def binary_tool() -> ToolResult: return ToolResult( content=[ - ImageContent(type="image", data="x" * 10_000, mimeType="image/png") + ImageContent(type="image", data="x" * 10_000, mime_type="image/png") ] ) diff --git a/tests/server/providers/proxy/test_proxy_server.py b/tests/server/providers/proxy/test_proxy_server.py index 58fc1a7cc..765c21aec 100644 --- a/tests/server/providers/proxy/test_proxy_server.py +++ b/tests/server/providers/proxy/test_proxy_server.py @@ -147,7 +147,7 @@ def fastmcp_server(): content=mcp_types.ImageContent( type="image", data="iVBORw0KGgoAAAANSUhEUg==", - mimeType="image/png", + mime_type="image/png", ), role="user", ), @@ -389,10 +389,10 @@ class TestTools: error_result = mcp_types.CallToolResult( content=[ mcp_types.ImageContent( - type="image", data="abc123", mimeType="image/png" + type="image", data="abc123", mime_type="image/png" ) ], - isError=True, + is_error=True, ) with patch.object( Client, "call_tool_mcp", new_callable=AsyncMock, return_value=error_result @@ -405,7 +405,7 @@ class TestTools: """Error responses with empty content should not crash.""" error_result = mcp_types.CallToolResult( content=[], - isError=True, + is_error=True, ) with patch.object( Client, "call_tool_mcp", new_callable=AsyncMock, return_value=error_result @@ -419,11 +419,11 @@ class TestTools: error_result = mcp_types.CallToolResult( content=[ mcp_types.ImageContent( - type="image", data="abc123", mimeType="image/png" + type="image", data="abc123", mime_type="image/png" ) ], - structuredContent={"detail": "boom"}, - isError=True, + structured_content={"detail": "boom"}, + is_error=True, ) with patch.object( Client, "call_tool_mcp", new_callable=AsyncMock, return_value=error_result diff --git a/tests/server/tasks/test_context_background_task.py b/tests/server/tasks/test_context_background_task.py index dbbe9ae57..e5a1e59f8 100644 --- a/tests/server/tasks/test_context_background_task.py +++ b/tests/server/tasks/test_context_background_task.py @@ -303,7 +303,7 @@ class TestBackgroundTaskIntegration: role="assistant", content=TextContent(type="text", text="hello from background"), model="test-model", - stopReason="endTurn", + stop_reason="endTurn", ) async with Client(mcp, sampling_handler=sampling_handler) as client: diff --git a/tests/server/tasks/test_task_config.py b/tests/server/tasks/test_task_config.py index f1f3eaf9e..d4667a298 100644 --- a/tests/server/tasks/test_task_config.py +++ b/tests/server/tasks/test_task_config.py @@ -283,7 +283,7 @@ class TestToolExecutionMetadata: assert tool.execution.task_support == "optional" async def test_required_tool_exposes_task_support(self): - """Tools with mode=required should expose taskSupport='required'.""" + """Tools with mode=required should expose task_support='required'.""" mcp = FastMCP("test", tasks=False) @mcp.tool(task=TaskConfig(mode="required")) diff --git a/tests/server/tasks/test_task_mount.py b/tests/server/tasks/test_task_mount.py index e85a3c27a..06d9acb9d 100644 --- a/tests/server/tasks/test_task_mount.py +++ b/tests/server/tasks/test_task_mount.py @@ -582,8 +582,8 @@ class TestMountedTaskMetadata: mcp_tool = MCPTool( name="remote_task_tool", description="A remote tool that supports tasks", - inputSchema={"type": "object", "properties": {}}, - execution=ToolExecution(taskSupport="optional"), + input_schema={"type": "object", "properties": {}}, + execution=ToolExecution(task_support="optional"), ) proxy = ProxyTool.from_mcp_tool(lambda: None, mcp_tool) # ty: ignore[invalid-argument-type] diff --git a/tests/server/tasks/test_task_return_types.py b/tests/server/tasks/test_task_return_types.py index 697eb4ae6..c4a5831d0 100644 --- a/tests/server/tasks/test_task_return_types.py +++ b/tests/server/tasks/test_task_return_types.py @@ -581,7 +581,7 @@ async def mcp_content_server(tmp_path): return ImageContent( type="image", data=base64.b64encode(test_image.read_bytes()).decode(), - mimeType="image/png", + mime_type="image/png", ) @mcp.tool(task=True) @@ -606,7 +606,7 @@ async def mcp_content_server(tmp_path): ImageContent( type="image", data=base64.b64encode(test_image.read_bytes()).decode(), - mimeType="image/png", + mime_type="image/png", ), TextContent(type="text", text="Third block"), ] diff --git a/tests/server/telemetry/test_sampling_tracing.py b/tests/server/telemetry/test_sampling_tracing.py index 59bd6d8cd..db02b13bc 100644 --- a/tests/server/telemetry/test_sampling_tracing.py +++ b/tests/server/telemetry/test_sampling_tracing.py @@ -121,13 +121,13 @@ class TestSamplingToolSpan: ) ], model="test-model", - stopReason="toolUse", + stop_reason="toolUse", ) return CreateMessageResultWithTools( role="assistant", content=[TextContent(type="text", text="done")], model="test-model", - stopReason="endTurn", + stop_reason="endTurn", ) mcp = FastMCP(sampling_handler=sampling_handler) diff --git a/tests/server/test_icons.py b/tests/server/test_icons.py index 2d60e66ef..9fba37b9b 100644 --- a/tests/server/test_icons.py +++ b/tests/server/test_icons.py @@ -17,12 +17,12 @@ class TestServerIcons: icons = [ Icon( src="https://example.com/icon.png", - mimeType="image/png", + mime_type="image/png", sizes=["48x48"], ), Icon( src="data:image/svg+xml;base64,PHN2Zz48L3N2Zz4=", - mimeType="image/svg+xml", + mime_type="image/svg+xml", sizes=["any"], ), ] @@ -58,7 +58,7 @@ class TestToolIcons: mcp = FastMCP("TestServer") icons = [ - Icon(src="https://example.com/tool-icon.png", mimeType="image/png"), + Icon(src="https://example.com/tool-icon.png", mime_type="image/png"), ] @mcp.tool(icons=icons) @@ -272,17 +272,17 @@ class TestIconTypes: icons = [ Icon( src="https://example.com/icon-48.png", - mimeType="image/png", + mime_type="image/png", sizes=["48x48"], ), Icon( src="https://example.com/icon-96.png", - mimeType="image/png", + mime_type="image/png", sizes=["96x96"], ), Icon( src="https://example.com/icon.svg", - mimeType="image/svg+xml", + mime_type="image/svg+xml", sizes=["any"], ), ] @@ -299,7 +299,7 @@ class TestIconTypes: # Simple SVG data URI data_uri = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCI+PHBhdGggZD0iTTEyIDJDNi40OCAyIDIgNi40OCAyIDEyczQuNDggMTAgMTAgMTAgMTAtNC40OCAxMC0xMFMxNy41MiAyIDEyIDJ6Ii8+PC9zdmc+" - icons = [Icon(src=data_uri, mimeType="image/svg+xml")] + icons = [Icon(src=data_uri, mime_type="image/svg+xml")] mcp = FastMCP("TestServer") diff --git a/tests/server/test_tool_annotations.py b/tests/server/test_tool_annotations.py index e95a08b42..917f76a17 100644 --- a/tests/server/test_tool_annotations.py +++ b/tests/server/test_tool_annotations.py @@ -15,8 +15,8 @@ async def test_tool_annotations_in_tool_manager(): @mcp.tool( annotations=ToolAnnotations( title="Echo Tool", - readOnlyHint=True, - openWorldHint=False, + read_only_hint=True, + open_world_hint=False, ) ) def echo(message: str) -> str: @@ -39,8 +39,8 @@ async def test_tool_annotations_in_mcp_protocol(): @mcp.tool( annotations=ToolAnnotations( title="Echo Tool", - readOnlyHint=True, - openWorldHint=False, + read_only_hint=True, + open_world_hint=False, ) ) def echo(message: str) -> str: @@ -63,8 +63,8 @@ async def test_tool_annotations_in_client_api(): @mcp.tool( annotations=ToolAnnotations( title="Echo Tool", - readOnlyHint=True, - openWorldHint=False, + read_only_hint=True, + open_world_hint=False, ) ) def echo(message: str) -> str: @@ -114,10 +114,10 @@ async def test_direct_tool_annotations_in_tool_manager(): annotations = ToolAnnotations( title="Direct Tool", - readOnlyHint=False, - destructiveHint=True, - idempotentHint=False, - openWorldHint=True, + read_only_hint=False, + destructive_hint=True, + idempotent_hint=False, + open_world_hint=True, ) @mcp.tool(annotations=annotations) @@ -142,10 +142,10 @@ async def test_direct_tool_annotations_in_client_api(): annotations = ToolAnnotations( title="Direct Tool", - readOnlyHint=False, - destructiveHint=True, - idempotentHint=False, - openWorldHint=True, + read_only_hint=False, + destructive_hint=True, + idempotent_hint=False, + open_world_hint=True, ) @mcp.tool(annotations=annotations) @@ -177,8 +177,8 @@ async def test_add_tool_method_annotations(): name="create_item", annotations=ToolAnnotations( title="Create Item", - readOnlyHint=False, - destructiveHint=False, + read_only_hint=False, + destructive_hint=False, ), ) @@ -206,8 +206,8 @@ async def test_tool_functionality_with_annotations(): name="create_item", annotations=ToolAnnotations( title="Create Item", - readOnlyHint=False, - destructiveHint=False, + read_only_hint=False, + destructive_hint=False, ), ) mcp.add_tool(tool) diff --git a/tests/tools/tool/test_content.py b/tests/tools/tool/test_content.py index d4026c835..580a6edc2 100644 --- a/tests/tools/tool/test_content.py +++ b/tests/tools/tool/test_content.py @@ -104,8 +104,8 @@ class TestConvertResultToContent: argnames="content_block", argvalues=[ (TextContent(type="text", text="hello")), - (ImageContent(type="image", data="fakeimagedata", mimeType="image/png")), - (AudioContent(type="audio", data="fakeaudiodata", mimeType="audio/mpeg")), + (ImageContent(type="image", data="fakeimagedata", mime_type="image/png")), + (AudioContent(type="audio", data="fakeaudiodata", mime_type="audio/mpeg")), ( ResourceLink( type="resource_link", @@ -118,7 +118,7 @@ class TestConvertResultToContent: type="resource", resource=TextResourceContents( uri=AnyUrl("resource://test"), - mimeType="text/plain", + mime_type="text/plain", text="resource content", ), ) @@ -140,7 +140,7 @@ class TestConvertResultToContent: Image(data=b"fakeimagedata"), [ ImageContent( - type="image", data="ZmFrZWltYWdlZGF0YQ==", mimeType="image/png" + type="image", data="ZmFrZWltYWdlZGF0YQ==", mime_type="image/png" ) ], ), @@ -148,7 +148,7 @@ class TestConvertResultToContent: Audio(data=b"fakeaudiodata"), [ AudioContent( - type="audio", data="ZmFrZWF1ZGlvZGF0YQ==", mimeType="audio/wav" + type="audio", data="ZmFrZWF1ZGlvZGF0YQ==", mime_type="audio/wav" ) ], ), @@ -160,7 +160,7 @@ class TestConvertResultToContent: resource=BlobResourceContents( uri=AnyUrl("file:///resource.octet-stream"), blob="ZmlsZWRhdGE=", - mimeType="application/octet-stream", + mime_type="application/octet-stream", ), ) ], @@ -193,7 +193,7 @@ class TestConvertResultToContent: type="resource", resource=TextResourceContents( uri=AnyUrl("resource://test"), - mimeType="text/plain", + mime_type="text/plain", text="resource content", ), ), @@ -209,10 +209,10 @@ class TestConvertResultToContent: TextContent(type="text", text='{"key":"value"}'), TextContent(type="text", text='{"x":1,"y":"hello"}'), ImageContent( - type="image", data="ZmFrZWltYWdlZGF0YQ==", mimeType="image/png" + type="image", data="ZmFrZWltYWdlZGF0YQ==", mime_type="image/png" ), AudioContent( - type="audio", data="ZmFrZWF1ZGlvZGF0YQ==", mimeType="audio/wav" + type="audio", data="ZmFrZWF1ZGlvZGF0YQ==", mime_type="audio/wav" ), ResourceLink( name="test resource", @@ -223,7 +223,7 @@ class TestConvertResultToContent: type="resource", resource=TextResourceContents( uri=AnyUrl("resource://test"), - mimeType="text/plain", + mime_type="text/plain", text="resource content", ), ), @@ -475,7 +475,7 @@ class TestAutomaticStructuredContent: assert result.content == snapshot( [ AudioContent( - type="audio", data="ZmFrZWF1ZGlvZGF0YQ==", mimeType="audio/wav" + type="audio", data="ZmFrZWF1ZGlvZGF0YQ==", mime_type="audio/wav" ) ] ) diff --git a/tests/tools/tool/test_tool.py b/tests/tools/tool/test_tool.py index f40860d07..828d0eaff 100644 --- a/tests/tools/tool/test_tool.py +++ b/tests/tools/tool/test_tool.py @@ -542,7 +542,7 @@ class TestToolExecutionField: name="my_tool", description="A tool with execution", parameters={"type": "object", "properties": {}}, - execution=ToolExecution(taskSupport="optional"), + execution=ToolExecution(task_support="optional"), ) mcp_tool = tool.to_mcp_tool() @@ -566,10 +566,10 @@ class TestToolExecutionField: name="my_tool", description="A tool", parameters={"type": "object", "properties": {}}, - execution=ToolExecution(taskSupport="optional"), + execution=ToolExecution(task_support="optional"), ) - override_execution = ToolExecution(taskSupport="required") + override_execution = ToolExecution(task_support="required") mcp_tool = tool.to_mcp_tool(execution=override_execution) assert mcp_tool.execution is not None assert mcp_tool.execution.task_support == "required" @@ -593,7 +593,7 @@ class TestToolExecutionField: name="my_tool", description="A tool with required execution", parameters={"type": "object", "properties": {}}, - execution=ToolExecution(taskSupport="required"), + execution=ToolExecution(task_support="required"), ) mcp_tool = tool.to_mcp_tool() @@ -606,7 +606,7 @@ class TestToolExecutionField: name="my_tool", description="A tool with forbidden execution", parameters={"type": "object", "properties": {}}, - execution=ToolExecution(taskSupport="forbidden"), + execution=ToolExecution(task_support="forbidden"), ) mcp_tool = tool.to_mcp_tool() diff --git a/tests/utilities/openapi/test_circular_references.py b/tests/utilities/openapi/test_circular_references.py index 480711c76..ed08d5e06 100644 --- a/tests/utilities/openapi/test_circular_references.py +++ b/tests/utilities/openapi/test_circular_references.py @@ -107,8 +107,8 @@ class TestCircularReferencesSerialization: tool = MCPTool( name="get_node", description="Get a node", - inputSchema={"type": "object", "properties": {}}, - outputSchema=output_schema, + input_schema={"type": "object", "properties": {}}, + output_schema=output_schema, ) # This must not raise ValueError: Circular reference detected tool.model_dump(by_alias=True, mode="json", exclude_none=True) @@ -153,8 +153,8 @@ class TestCircularReferencesSerialization: tool = MCPTool( name="get_pr", description="Get a pull request", - inputSchema={"type": "object", "properties": {}}, - outputSchema=output_schema, + input_schema={"type": "object", "properties": {}}, + output_schema=output_schema, ) tool.model_dump(by_alias=True, mode="json", exclude_none=True) diff --git a/tests/utilities/test_inspect_icons.py b/tests/utilities/test_inspect_icons.py index 79b10cda4..425164c53 100644 --- a/tests/utilities/test_inspect_icons.py +++ b/tests/utilities/test_inspect_icons.py @@ -29,7 +29,7 @@ class TestIconExtraction: icons=[ Icon( src="https://example.com/icon.png", - mimeType="image/png", + mime_type="image/png", sizes=["48x48"], ) ], @@ -63,7 +63,7 @@ class TestIconExtraction: icons=[ Icon( src="https://example.com/calculator.png", - mimeType="image/png", + mime_type="image/png", ) ] ) @@ -98,7 +98,7 @@ class TestIconExtraction: @mcp.resource( "resource://data", - icons=[Icon(src="https://example.com/data.png", mimeType="image/png")], + icons=[Icon(src="https://example.com/data.png", mime_type="image/png")], ) def get_data() -> str: """Get data.""" @@ -131,7 +131,7 @@ class TestIconExtraction: @mcp.resource( "resource://user/{id}", - icons=[Icon(src="https://example.com/user.png", mimeType="image/png")], + icons=[Icon(src="https://example.com/user.png", mime_type="image/png")], ) def get_user(id: str) -> str: """Get user by ID.""" @@ -167,7 +167,7 @@ class TestIconExtraction: mcp = FastMCP("PromptIconServer") @mcp.prompt( - icons=[Icon(src="https://example.com/analyze.png", mimeType="image/png")] + icons=[Icon(src="https://example.com/analyze.png", mime_type="image/png")] ) def analyze(data: str) -> list: """Analyze data.""" @@ -201,12 +201,12 @@ class TestIconExtraction: icons=[ Icon( src="https://example.com/icon-48.png", - mimeType="image/png", + mime_type="image/png", sizes=["48x48"], ), Icon( src="https://example.com/icon-96.png", - mimeType="image/png", + mime_type="image/png", sizes=["96x96"], ), ], @@ -245,7 +245,7 @@ class TestIconExtraction: mcp = FastMCP("DataURIServer") - @mcp.tool(icons=[Icon(src=data_uri, mimeType="image/png")]) + @mcp.tool(icons=[Icon(src=data_uri, mime_type="image/png")]) def data_uri_tool() -> str: """Tool with data URI icon.""" return "data" @@ -264,7 +264,7 @@ class TestIconExtraction: mcp = FastMCP1x("Icon1xServer") @mcp.tool( - icons=[Icon(src="https://example.com/v1-tool.png", mimeType="image/png")] + icons=[Icon(src="https://example.com/v1-tool.png", mime_type="image/png")] ) def v1_tool() -> str: """Tool in v1 server.""" @@ -284,11 +284,11 @@ class TestIconExtraction: mcp = FastMCP( "FormattedIconServer", website_url="https://example.com", - icons=[Icon(src="https://example.com/server.png", mimeType="image/png")], + icons=[Icon(src="https://example.com/server.png", mime_type="image/png")], ) @mcp.tool( - icons=[Icon(src="https://example.com/tool.png", mimeType="image/png")] + icons=[Icon(src="https://example.com/tool.png", mime_type="image/png")] ) def icon_tool() -> str: """Tool with icon."""