diff --git a/src/fastmcp/cli/cli.py b/src/fastmcp/cli/cli.py index 876da5826..3c11fa35f 100644 --- a/src/fastmcp/cli/cli.py +++ b/src/fastmcp/cli/cli.py @@ -521,13 +521,13 @@ async def run( # Warn about options that are ignored in module mode ignored_options: list[str] = [] - if transport: + if transport is not None: ignored_options.append("--transport") - if host: + if host is not None: ignored_options.append("--host") - if port: + if port is not None: ignored_options.append("--port") - if path: + if path is not None: ignored_options.append("--path") if ignored_options: logger.warning( @@ -601,11 +601,15 @@ async def run( sys.exit(1) # Get effective values (CLI overrides take precedence) - final_transport = transport or config.deployment.transport - final_host = host or config.deployment.host - final_port = port or config.deployment.port - final_path = path or config.deployment.path - final_log_level = log_level or config.deployment.log_level + final_transport = ( + transport if transport is not None else config.deployment.transport + ) + final_host = host if host is not None else config.deployment.host + final_port = port if port is not None else config.deployment.port + final_path = path if path is not None else config.deployment.path + final_log_level = ( + log_level if log_level is not None else config.deployment.log_level + ) final_server_args = server_args or config.deployment.args # Use CLI override if provided, otherwise use settings # no_banner CLI flag overrides the show_server_banner setting @@ -642,11 +646,11 @@ async def run( if final_transport: reload_cmd.extend(["--transport", final_transport]) if final_transport != "stdio": - if final_host: + if final_host is not None: reload_cmd.extend(["--host", final_host]) - if final_port: + if final_port is not None: reload_cmd.extend(["--port", str(final_port)]) - if final_path: + if final_path is not None: reload_cmd.extend(["--path", final_path]) if final_log_level: reload_cmd.extend(["--log-level", final_log_level]) @@ -691,11 +695,11 @@ async def run( inner_cmd.extend(["--transport", final_transport]) # Only add HTTP-specific options for non-stdio transports if final_transport != "stdio": - if final_host: + if final_host is not None: inner_cmd.extend(["--host", final_host]) - if final_port: + if final_port is not None: inner_cmd.extend(["--port", str(final_port)]) - if final_path: + if final_path is not None: inner_cmd.extend(["--path", final_path]) if final_log_level: inner_cmd.extend(["--log-level", final_log_level]) diff --git a/src/fastmcp/cli/run.py b/src/fastmcp/cli/run.py index 36b029c38..9adedf657 100644 --- a/src/fastmcp/cli/run.py +++ b/src/fastmcp/cli/run.py @@ -181,11 +181,15 @@ async def run_command( config = load_mcp_server_config(config_path) # Merge deployment config with CLI arguments (CLI takes precedence) - transport = transport or config.deployment.transport - host = host or config.deployment.host - port = port or config.deployment.port - path = path or config.deployment.path - log_level = log_level or config.deployment.log_level + transport = ( + transport if transport is not None else config.deployment.transport + ) + host = host if host is not None else config.deployment.host + port = port if port is not None else config.deployment.port + path = path if path is not None else config.deployment.path + log_level = ( + log_level if log_level is not None else config.deployment.log_level + ) server_args = ( server_args if server_args is not None else config.deployment.args ) @@ -234,15 +238,17 @@ async def run_command( return kwargs = {} - if transport: + if transport is not None: kwargs["transport"] = transport - if host: - kwargs["host"] = host - if port: - kwargs["port"] = port - if path: - kwargs["path"] = path - if log_level: + # Only pass HTTP-specific options for non-stdio transports + if transport != "stdio": + if host is not None: + kwargs["host"] = host + if port is not None: + kwargs["port"] = port + if path is not None: + kwargs["path"] = path + if log_level is not None: kwargs["log_level"] = log_level if stateless: kwargs["stateless"] = True @@ -310,9 +316,9 @@ async def run_v1_server_async( port: Port to bind to transport: Transport protocol to use """ - if host: + if host is not None: server.settings.host = host - if port: + if port is not None: server.settings.port = port match transport: diff --git a/src/fastmcp/prompts/function_prompt.py b/src/fastmcp/prompts/function_prompt.py index a63167454..63545cb90 100644 --- a/src/fastmcp/prompts/function_prompt.py +++ b/src/fastmcp/prompts/function_prompt.py @@ -152,7 +152,11 @@ class FunctionPrompt(Prompt): if param.kind == inspect.Parameter.VAR_KEYWORD: raise ValueError("Functions with **kwargs are not supported as prompts") - description = metadata.description or inspect.getdoc(fn) + description = ( + metadata.description + if metadata.description is not None + else inspect.getdoc(fn) + ) # Normalize task to TaskConfig and validate task_value = metadata.task diff --git a/src/fastmcp/resources/function_resource.py b/src/fastmcp/resources/function_resource.py index b141a68bf..df542fcce 100644 --- a/src/fastmcp/resources/function_resource.py +++ b/src/fastmcp/resources/function_resource.py @@ -196,7 +196,9 @@ class FunctionResource(Resource): name=func_name, version=str(metadata.version) if metadata.version is not None else None, title=metadata.title, - description=metadata.description or inspect.getdoc(fn), + description=metadata.description + if metadata.description is not None + else inspect.getdoc(fn), icons=metadata.icons, mime_type=resolved_mime or "text/plain", tags=metadata.tags or set(), diff --git a/src/fastmcp/resources/template.py b/src/fastmcp/resources/template.py index c9bc91f98..265e88f91 100644 --- a/src/fastmcp/resources/template.py +++ b/src/fastmcp/resources/template.py @@ -553,7 +553,7 @@ class FunctionResourceTemplate(ResourceTemplate): f"URI parameters {all_uri_params} must be a subset of the function arguments: {func_params}" ) - description = description or inspect.getdoc(fn) + description = description if description is not None else inspect.getdoc(fn) # Normalize task to TaskConfig and validate if task is None: diff --git a/src/fastmcp/server/mixins/transport.py b/src/fastmcp/server/mixins/transport.py index 10223f38a..3c87a23e2 100644 --- a/src/fastmcp/server/mixins/transport.py +++ b/src/fastmcp/server/mixins/transport.py @@ -263,9 +263,11 @@ class TransportMixin: if stateless_http and transport == "sse": raise ValueError("SSE transport does not support stateless mode") - host = host or fastmcp.settings.host - port = port or fastmcp.settings.port - default_log_level_to_use = (log_level or fastmcp.settings.log_level).lower() + host = host if host is not None else fastmcp.settings.host + port = port if port is not None else fastmcp.settings.port + default_log_level_to_use = ( + log_level if log_level is not None else fastmcp.settings.log_level + ).lower() app = self.http_app( path=path, @@ -335,7 +337,9 @@ class TransportMixin: if transport in ("streamable-http", "http"): return create_streamable_http_app( server=self, - streamable_http_path=path or fastmcp.settings.streamable_http_path, + streamable_http_path=path + if path is not None + else fastmcp.settings.streamable_http_path, event_store=event_store, retry_interval=retry_interval, auth=self.auth, @@ -356,7 +360,7 @@ class TransportMixin: return create_sse_app( server=self, message_path=fastmcp.settings.message_path, - sse_path=path or fastmcp.settings.sse_path, + sse_path=path if path is not None else fastmcp.settings.sse_path, auth=self.auth, debug=fastmcp.settings.debug, middleware=middleware, diff --git a/src/fastmcp/server/sampling/sampling_tool.py b/src/fastmcp/server/sampling/sampling_tool.py index 7f9354bbb..217d2f21f 100644 --- a/src/fastmcp/server/sampling/sampling_tool.py +++ b/src/fastmcp/server/sampling/sampling_tool.py @@ -116,7 +116,7 @@ class SamplingTool(FastMCPBaseModel): return cls( name=name or parsed.name, - description=description or parsed.description, + description=description if description is not None else parsed.description, parameters=parsed.input_schema, fn=parsed.fn, sequential=sequential, diff --git a/src/fastmcp/tools/function_tool.py b/src/fastmcp/tools/function_tool.py index cb79b72cc..94e7a0b3e 100644 --- a/src/fastmcp/tools/function_tool.py +++ b/src/fastmcp/tools/function_tool.py @@ -222,7 +222,9 @@ class FunctionTool(Tool): name=metadata.name or parsed_fn.name, version=str(metadata.version) if metadata.version is not None else None, title=metadata.title, - description=metadata.description or parsed_fn.description, + description=metadata.description + if metadata.description is not None + else parsed_fn.description, icons=metadata.icons, parameters=parsed_fn.input_schema, output_schema=final_output_schema,