Revert "Add CLI banner"

This commit is contained in:
Jeremiah Lowin 2025-07-02 00:53:20 -04:00 committed by GitHub
commit 41359ec99d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 7 additions and 179 deletions

View file

@ -46,7 +46,6 @@ This command runs the server directly in your current Python environment. You ar
| Host | `--host` | Host to bind to when using http transport (default: 127.0.0.1) |
| Port | `--port`, `-p` | Port to bind to when using http transport (default: 8000) |
| Log Level | `--log-level`, `-l` | Log level (DEBUG, INFO, WARNING, ERROR, CRITICAL) |
| No Banner | `--no-banner` | Disable the startup banner display |
#### Server Specification

View file

@ -64,7 +64,6 @@ def _build_uv_command(
server_spec: str,
with_editable: Path | None = None,
with_packages: list[str] | None = None,
no_banner: bool = False,
) -> list[str]:
"""Build the uv run command that runs a MCP server through mcp run."""
cmd = ["uv"]
@ -81,10 +80,6 @@ def _build_uv_command(
# Add mcp run command
cmd.extend(["fastmcp", "run", server_spec])
if no_banner:
cmd.append("--no-banner")
return cmd
@ -197,9 +192,7 @@ def dev(
if inspector_version:
inspector_cmd += f"@{inspector_version}"
uv_cmd = _build_uv_command(
server_spec, with_editable, with_packages, no_banner=True
)
uv_cmd = _build_uv_command(server_spec, with_editable, with_packages)
# Run the MCP Inspector command with shell=True on Windows
shell = sys.platform == "win32"
@ -268,13 +261,6 @@ def run(
help="Log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)",
),
] = None,
no_banner: Annotated[
bool,
typer.Option(
"--no-banner",
help="Don't show the server banner",
),
] = False,
) -> None:
"""Run a MCP server or connect to a remote one.
@ -311,7 +297,6 @@ def run(
port=port,
log_level=log_level,
server_args=server_args,
show_banner=not no_banner,
)
except Exception as e:
logger.error(

View file

@ -169,7 +169,6 @@ def run_command(
port: int | None = None,
log_level: str | None = None,
server_args: list[str] | None = None,
show_banner: bool = True,
) -> None:
"""Run a MCP server or connect to a remote one.
@ -202,9 +201,6 @@ def run_command(
if log_level:
kwargs["log_level"] = log_level
if not show_banner:
kwargs["show_banner"] = False
try:
server.run(**kwargs)
except Exception as e:

View file

@ -60,7 +60,6 @@ from fastmcp.settings import Settings
from fastmcp.tools import ToolManager
from fastmcp.tools.tool import FunctionTool, Tool, ToolResult
from fastmcp.utilities.cache import TimedCache
from fastmcp.utilities.cli import print_server_banner
from fastmcp.utilities.components import FastMCPComponent
from fastmcp.utilities.logging import get_logger
from fastmcp.utilities.mcp_config import MCPConfig
@ -286,7 +285,6 @@ class FastMCP(Generic[LifespanResultT]):
async def run_async(
self,
transport: Transport | None = None,
show_banner: bool = True,
**transport_kwargs: Any,
) -> None:
"""Run the FastMCP server asynchronously.
@ -300,23 +298,15 @@ class FastMCP(Generic[LifespanResultT]):
raise ValueError(f"Unknown transport: {transport}")
if transport == "stdio":
await self.run_stdio_async(
show_banner=show_banner,
**transport_kwargs,
)
await self.run_stdio_async(**transport_kwargs)
elif transport in {"http", "sse", "streamable-http"}:
await self.run_http_async(
transport=transport,
show_banner=show_banner,
**transport_kwargs,
)
await self.run_http_async(transport=transport, **transport_kwargs)
else:
raise ValueError(f"Unknown transport: {transport}")
def run(
self,
transport: Transport | None = None,
show_banner: bool = True,
**transport_kwargs: Any,
) -> None:
"""Run the FastMCP server. Note this is a synchronous function.
@ -325,14 +315,7 @@ class FastMCP(Generic[LifespanResultT]):
transport: Transport protocol to use ("stdio", "sse", or "streamable-http")
"""
anyio.run(
partial(
self.run_async,
transport,
show_banner=show_banner,
**transport_kwargs,
)
)
anyio.run(partial(self.run_async, transport, **transport_kwargs))
def _setup_handlers(self) -> None:
"""Set up core MCP protocol handlers."""
@ -1338,16 +1321,8 @@ class FastMCP(Generic[LifespanResultT]):
enabled=enabled,
)
async def run_stdio_async(self, show_banner: bool = True) -> None:
async def run_stdio_async(self) -> None:
"""Run the server using stdio transport."""
# Display server banner
if show_banner:
print_server_banner(
server=self,
transport="stdio",
)
async with stdio_server() as (read_stream, write_stream):
logger.info(f"Starting MCP server {self.name!r} with transport 'stdio'")
await self._mcp_server.run(
@ -1360,7 +1335,6 @@ class FastMCP(Generic[LifespanResultT]):
async def run_http_async(
self,
show_banner: bool = True,
transport: Literal["http", "streamable-http", "sse"] = "http",
host: str | None = None,
port: int | None = None,
@ -1379,7 +1353,6 @@ class FastMCP(Generic[LifespanResultT]):
path: Path for the endpoint (defaults to settings.streamable_http_path or settings.sse_path)
uvicorn_config: Additional configuration for the Uvicorn server
"""
host = host or self._deprecated_settings.host
port = port or self._deprecated_settings.port
default_log_level_to_use = (
@ -1388,23 +1361,6 @@ class FastMCP(Generic[LifespanResultT]):
app = self.http_app(path=path, transport=transport, middleware=middleware)
# Get the path for the server URL
server_path = (
app.state.path.lstrip("/")
if hasattr(app, "state") and hasattr(app.state, "path")
else path or ""
)
# Display server banner
if show_banner:
print_server_banner(
server=self,
transport=transport,
host=host,
port=port,
path=server_path,
)
_uvicorn_config_from_user = uvicorn_config or {}
config_kwargs: dict[str, Any] = {
@ -1422,7 +1378,6 @@ class FastMCP(Generic[LifespanResultT]):
logger.info(
f"Starting MCP server {self.name!r} with transport {transport!r} on http://{host}:{port}/{path}"
)
await server.serve()
async def run_sse_async(

View file

@ -1,106 +0,0 @@
from __future__ import annotations
from importlib.metadata import version
from typing import TYPE_CHECKING, Any
from rich.console import Console, Group
from rich.panel import Panel
from rich.table import Table
from rich.text import Text
import fastmcp
if TYPE_CHECKING:
from typing import Literal
from fastmcp import FastMCP
LOGO_ASCII = r"""
_ __ ___ ______ __ __ _____________ ____ ____
_ __ ___ / ____/___ ______/ /_/ |/ / ____/ __ \ |___ \ / __ \
_ __ ___ / /_ / __ `/ ___/ __/ /|_/ / / / /_/ / ___/ / / / / /
_ __ ___ / __/ / /_/ (__ ) /_/ / / / /___/ ____/ / __/_/ /_/ /
_ __ ___ /_/ \__,_/____/\__/_/ /_/\____/_/ /_____(_)____/
""".lstrip("\n")
def print_server_banner(
server: FastMCP[Any],
transport: Literal["stdio", "http", "sse", "streamable-http"],
*,
host: str | None = None,
port: int | None = None,
path: str | None = None,
) -> None:
"""Print a formatted banner with server information and logo.
Args:
transport: The transport protocol being used
server_name: Optional server name to display
host: Host address (for HTTP transports)
port: Port number (for HTTP transports)
path: Server path (for HTTP transports)
"""
console = Console()
# Create the logo text
logo_text = Text(LOGO_ASCII, style="bold green")
# Create the information table
info_table = Table.grid(padding=(0, 1))
info_table.add_column(style="bold cyan", justify="left")
info_table.add_column(style="white", justify="left")
match transport:
case "http" | "streamable-http":
display_transport = "Streamable-HTTP"
case "sse":
display_transport = "SSE"
case "stdio":
display_transport = "STDIO"
info_table.add_row("Transport:", display_transport)
# Show connection info based on transport
if transport in ("http", "streamable-http", "sse"):
if host and port:
server_url = f"http://{host}:{port}"
if path:
server_url += f"/{path.lstrip('/')}"
info_table.add_row("Server URL:", server_url)
# Add documentation link
info_table.add_row()
info_table.add_row("Docs:", "https://gofastmcp.com")
info_table.add_row("Hosting:", "https://fastmcp.cloud")
# Add version information with explicit style overrides
info_table.add_row()
info_table.add_row(
"FastMCP version:",
Text(fastmcp.__version__, style="dim white", no_wrap=True),
)
info_table.add_row(
"MCP version:",
Text(version("mcp"), style="dim white", no_wrap=True),
)
# Create panel with logo and information using Group
panel_content = Group(logo_text, "", info_table)
# Use server name in title if provided
title = "FastMCP 2.0"
if server.name != "FastMCP":
title += f" - {server.name}"
panel = Panel(
panel_content,
title=title,
title_align="left",
border_style="dim",
padding=(2, 10),
expand=False,
)
console.print(panel)

View file

@ -209,9 +209,9 @@ class TestDevCommand:
assert result.exit_code == 0
mock_run.assert_called_once()
# Check dependencies were passed correctly with no_banner=True
# Check dependencies were passed correctly
mock_build_uv.assert_called_once_with(
str(temp_python_file), None, ["extra_dep"], no_banner=True
str(temp_python_file), None, ["extra_dep"]
)
def test_dev_command_with_ui_port(self, temp_python_file):
@ -468,5 +468,4 @@ class TestRunCommand:
port=None,
log_level=None,
server_args=["--config", "config.json"],
show_banner=True,
)