Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Enhance FastMCP server with port override functionality #997

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,17 @@ from mcp.server.fastmcp import FastMCP
mcp = FastMCP("My App")

if __name__ == "__main__":
# Run with default settings
mcp.run()

# Override port
mcp.run(port=3000)

# Specify transport and port
mcp.run(transport="streamable-http", port=8080)

# SSE with custom mount path and port
mcp.run(transport="sse", mount_path="/api", port=9000)
```

Run it with:
Expand All @@ -633,8 +643,12 @@ python server.py
mcp run server.py
```

Note that `mcp run` or `mcp dev` only supports server using FastMCP and not the low-level server variant.
The `run()` method accepts these parameters:
- `transport`: Transport protocol ("stdio", "sse", or "streamable-http")
- `mount_path`: Optional mount path for SSE transport
- `port`: Optional port override (defaults to settings.port or 8000)

Note that `mcp run` or `mcp dev` only supports server using FastMCP and not the low-level server variant.
### Streamable HTTP Transport

> **Note**: Streamable HTTP transport is superseding SSE transport for production deployments.
Expand Down
4 changes: 4 additions & 0 deletions src/mcp/server/fastmcp/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,14 +210,18 @@ def run(
self,
transport: Literal["stdio", "sse", "streamable-http"] = "stdio",
mount_path: str | None = None,
port: int | None = None,
) -> None:
"""Run the FastMCP server. Note this is a synchronous function.

Args:
transport: Transport protocol to use ("stdio", "sse", or "streamable-http")
mount_path: Optional mount path for SSE transport
port: Optional port to run the server on
"""
TRANSPORTS = Literal["stdio", "sse", "streamable-http"]
if port is not None:
self.settings.port = port
if transport not in TRANSPORTS.__args__: # type: ignore
raise ValueError(f"Unknown transport: {transport}")

Expand Down
33 changes: 33 additions & 0 deletions tests/server/fastmcp/test_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -1032,3 +1032,36 @@ def prompt_fn(name: str) -> str:
async with client_session(mcp._mcp_server) as client:
with pytest.raises(McpError, match="Missing required arguments"):
await client.get_prompt("prompt_fn")


@pytest.fixture
def server_port() -> int:
import socket

with socket.socket() as s:
s.bind(("127.0.0.1", 0))
return s.getsockname()[1]


class TestServerTransports:
"""Test port overrides during run."""

@pytest.mark.anyio
async def test_port_override_default_port(self, server_port):
"""Test that the port argument overrides default port."""
mcp = FastMCP()

with patch("anyio.run") as mock_anyio_run:
mcp.run(port=server_port)
assert mcp.settings.port == server_port
mock_anyio_run.assert_called_once_with(mcp.run_stdio_async)

@pytest.mark.anyio
async def test_port_inheritance_without_override(self, server_port):
"""Test that existing settings.port is preserved when no port override is provided."""
mcp = FastMCP(port=server_port)

with patch("anyio.run") as mock_anyio_run:
mcp.run()
assert mcp.settings.port == server_port
mock_anyio_run.assert_called_once_with(mcp.run_stdio_async)
Loading