Spaces:
Running
Running
David Ben Kalifa commited on
feat: Add `--path` Option to CLI for HTTP/SSE Route (#1087)
Browse files* add path to cli
* update cli.mdx
* update test
- docs/patterns/cli.mdx +1 -0
- src/fastmcp/cli/cli.py +9 -0
- src/fastmcp/cli/run.py +4 -0
- tests/cli/test_cli.py +5 -0
docs/patterns/cli.mdx
CHANGED
|
@@ -45,6 +45,7 @@ This command runs the server directly in your current Python environment. You ar
|
|
| 45 |
| Transport | `--transport`, `-t` | Transport protocol to use (`stdio`, `http`, or `sse`) |
|
| 46 |
| Host | `--host` | Host to bind to when using http transport (default: 127.0.0.1) |
|
| 47 |
| Port | `--port`, `-p` | Port to bind to when using http transport (default: 8000) |
|
|
|
|
| 48 |
| Log Level | `--log-level`, `-l` | Log level (DEBUG, INFO, WARNING, ERROR, CRITICAL) |
|
| 49 |
| No Banner | `--no-banner` | Disable the startup banner display |
|
| 50 |
|
|
|
|
| 45 |
| Transport | `--transport`, `-t` | Transport protocol to use (`stdio`, `http`, or `sse`) |
|
| 46 |
| Host | `--host` | Host to bind to when using http transport (default: 127.0.0.1) |
|
| 47 |
| Port | `--port`, `-p` | Port to bind to when using http transport (default: 8000) |
|
| 48 |
+
| Path | `--path` | Path to bind to when using http transport (default: `/mcp/` or `/sse/` for SSE) |
|
| 49 |
| Log Level | `--log-level`, `-l` | Log level (DEBUG, INFO, WARNING, ERROR, CRITICAL) |
|
| 50 |
| No Banner | `--no-banner` | Disable the startup banner display |
|
| 51 |
|
src/fastmcp/cli/cli.py
CHANGED
|
@@ -266,6 +266,13 @@ def run(
|
|
| 266 |
help="Port to bind to when using http transport (default: 8000)",
|
| 267 |
),
|
| 268 |
] = None,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 269 |
log_level: Annotated[
|
| 270 |
Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"] | None,
|
| 271 |
cyclopts.Parameter(
|
|
@@ -305,6 +312,7 @@ def run(
|
|
| 305 |
"transport": transport,
|
| 306 |
"host": host,
|
| 307 |
"port": port,
|
|
|
|
| 308 |
"log_level": log_level,
|
| 309 |
"server_args": server_args,
|
| 310 |
},
|
|
@@ -316,6 +324,7 @@ def run(
|
|
| 316 |
transport=transport,
|
| 317 |
host=host,
|
| 318 |
port=port,
|
|
|
|
| 319 |
log_level=log_level,
|
| 320 |
server_args=server_args,
|
| 321 |
show_banner=not no_banner,
|
|
|
|
| 266 |
help="Port to bind to when using http transport (default: 8000)",
|
| 267 |
),
|
| 268 |
] = None,
|
| 269 |
+
path: Annotated[
|
| 270 |
+
str | None,
|
| 271 |
+
cyclopts.Parameter(
|
| 272 |
+
"--path",
|
| 273 |
+
help="The route path for the server (default: /mcp/ for http transport, /sse/ for sse transport)",
|
| 274 |
+
),
|
| 275 |
+
] = None,
|
| 276 |
log_level: Annotated[
|
| 277 |
Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"] | None,
|
| 278 |
cyclopts.Parameter(
|
|
|
|
| 312 |
"transport": transport,
|
| 313 |
"host": host,
|
| 314 |
"port": port,
|
| 315 |
+
"path": path,
|
| 316 |
"log_level": log_level,
|
| 317 |
"server_args": server_args,
|
| 318 |
},
|
|
|
|
| 324 |
transport=transport,
|
| 325 |
host=host,
|
| 326 |
port=port,
|
| 327 |
+
path=path,
|
| 328 |
log_level=log_level,
|
| 329 |
server_args=server_args,
|
| 330 |
show_banner=not no_banner,
|
src/fastmcp/cli/run.py
CHANGED
|
@@ -171,6 +171,7 @@ def run_command(
|
|
| 171 |
transport: TransportType | None = None,
|
| 172 |
host: str | None = None,
|
| 173 |
port: int | None = None,
|
|
|
|
| 174 |
log_level: LogLevelType | None = None,
|
| 175 |
server_args: list[str] | None = None,
|
| 176 |
show_banner: bool = True,
|
|
@@ -182,6 +183,7 @@ def run_command(
|
|
| 182 |
transport: Transport protocol to use
|
| 183 |
host: Host to bind to when using http transport
|
| 184 |
port: Port to bind to when using http transport
|
|
|
|
| 185 |
log_level: Log level
|
| 186 |
server_args: Additional arguments to pass to the server
|
| 187 |
show_banner: Whether to show the server banner
|
|
@@ -204,6 +206,8 @@ def run_command(
|
|
| 204 |
kwargs["host"] = host
|
| 205 |
if port:
|
| 206 |
kwargs["port"] = port
|
|
|
|
|
|
|
| 207 |
if log_level:
|
| 208 |
kwargs["log_level"] = log_level
|
| 209 |
|
|
|
|
| 171 |
transport: TransportType | None = None,
|
| 172 |
host: str | None = None,
|
| 173 |
port: int | None = None,
|
| 174 |
+
path: str | None = None,
|
| 175 |
log_level: LogLevelType | None = None,
|
| 176 |
server_args: list[str] | None = None,
|
| 177 |
show_banner: bool = True,
|
|
|
|
| 183 |
transport: Transport protocol to use
|
| 184 |
host: Host to bind to when using http transport
|
| 185 |
port: Port to bind to when using http transport
|
| 186 |
+
path: Path to bind to when using http transport
|
| 187 |
log_level: Log level
|
| 188 |
server_args: Additional arguments to pass to the server
|
| 189 |
show_banner: Whether to show the server banner
|
|
|
|
| 206 |
kwargs["host"] = host
|
| 207 |
if port:
|
| 208 |
kwargs["port"] = port
|
| 209 |
+
if path:
|
| 210 |
+
kwargs["path"] = path
|
| 211 |
if log_level:
|
| 212 |
kwargs["log_level"] = log_level
|
| 213 |
|
tests/cli/test_cli.py
CHANGED
|
@@ -181,6 +181,7 @@ class TestRunCommand:
|
|
| 181 |
assert "transport" not in bound.arguments
|
| 182 |
assert "host" not in bound.arguments
|
| 183 |
assert "port" not in bound.arguments
|
|
|
|
| 184 |
assert "log_level" not in bound.arguments
|
| 185 |
assert "no_banner" not in bound.arguments
|
| 186 |
|
|
@@ -196,6 +197,8 @@ class TestRunCommand:
|
|
| 196 |
"localhost",
|
| 197 |
"--port",
|
| 198 |
"8080",
|
|
|
|
|
|
|
| 199 |
"--log-level",
|
| 200 |
"DEBUG",
|
| 201 |
"--no-banner",
|
|
@@ -207,6 +210,7 @@ class TestRunCommand:
|
|
| 207 |
assert bound.arguments["transport"] == "http"
|
| 208 |
assert bound.arguments["host"] == "localhost"
|
| 209 |
assert bound.arguments["port"] == 8080
|
|
|
|
| 210 |
assert bound.arguments["log_level"] == "DEBUG"
|
| 211 |
assert bound.arguments["no_banner"] is True
|
| 212 |
|
|
@@ -230,6 +234,7 @@ class TestRunCommand:
|
|
| 230 |
assert "host" not in bound.arguments
|
| 231 |
assert "port" not in bound.arguments
|
| 232 |
assert "log_level" not in bound.arguments
|
|
|
|
| 233 |
|
| 234 |
|
| 235 |
class TestWindowsSpecific:
|
|
|
|
| 181 |
assert "transport" not in bound.arguments
|
| 182 |
assert "host" not in bound.arguments
|
| 183 |
assert "port" not in bound.arguments
|
| 184 |
+
assert "path" not in bound.arguments
|
| 185 |
assert "log_level" not in bound.arguments
|
| 186 |
assert "no_banner" not in bound.arguments
|
| 187 |
|
|
|
|
| 197 |
"localhost",
|
| 198 |
"--port",
|
| 199 |
"8080",
|
| 200 |
+
"--path",
|
| 201 |
+
"/v1/mcp",
|
| 202 |
"--log-level",
|
| 203 |
"DEBUG",
|
| 204 |
"--no-banner",
|
|
|
|
| 210 |
assert bound.arguments["transport"] == "http"
|
| 211 |
assert bound.arguments["host"] == "localhost"
|
| 212 |
assert bound.arguments["port"] == 8080
|
| 213 |
+
assert bound.arguments["path"] == "/v1/mcp"
|
| 214 |
assert bound.arguments["log_level"] == "DEBUG"
|
| 215 |
assert bound.arguments["no_banner"] is True
|
| 216 |
|
|
|
|
| 234 |
assert "host" not in bound.arguments
|
| 235 |
assert "port" not in bound.arguments
|
| 236 |
assert "log_level" not in bound.arguments
|
| 237 |
+
assert "path" not in bound.arguments
|
| 238 |
|
| 239 |
|
| 240 |
class TestWindowsSpecific:
|