diff --git a/docs/development/v3-notes/v3-features.mdx b/docs/development/v3-notes/v3-features.mdx
index ae6bfc27d..fb3cb8ad0 100644
--- a/docs/development/v3-notes/v3-features.mdx
+++ b/docs/development/v3-notes/v3-features.mdx
@@ -988,9 +988,9 @@ Implementation (`src/fastmcp/cli/run.py`):
- stdio: Full MCP features including elicitation
- HTTP: Limited bidirectional features during reload
-Also available with `fastmcp dev`:
+Also available with `fastmcp dev inspector`:
```bash
-fastmcp dev server.py # Includes --reload by default
+fastmcp dev inspector server.py # Includes --reload by default
```
---
diff --git a/docs/patterns/cli.mdx b/docs/patterns/cli.mdx
index 8ccf9d01f..fe32bdd75 100644
--- a/docs/patterns/cli.mdx
+++ b/docs/patterns/cli.mdx
@@ -345,10 +345,14 @@ This will run all the servers defined in the file.
## `fastmcp dev`
+The `dev` command group contains development tools for MCP servers.
+
+### `fastmcp dev inspector`
+
Run a MCP server with the [MCP Inspector](https://github.com/modelcontextprotocol/inspector) for testing. Auto-reload is enabled by default, so your server automatically restarts when you save changes to source files.
```bash
-fastmcp dev server.py
+fastmcp dev inspector server.py
```
@@ -361,7 +365,7 @@ When using `fastmcp.json`, the dev command automatically uses the configured dep
-The `dev` command is a shortcut for testing a server over STDIO only. When the Inspector launches, you may need to:
+The `dev inspector` command is a shortcut for testing a server over STDIO only. When the Inspector launches, you may need to:
1. Select "STDIO" from the transport dropdown
2. Connect manually
@@ -377,7 +381,7 @@ This command does not support HTTP testing. To test a server over Streamable HTT
2. Open the MCP Inspector separately and connect to your running server
-### Options
+#### Options
| Option | Flag | Description |
| ------ | ---- | ----------- |
@@ -392,39 +396,39 @@ This command does not support HTTP testing. To test a server over Streamable HTT
| Project Directory | `--project` | Run the command within the given project directory |
| Requirements File | `--with-requirements` | Requirements file to install dependencies from |
-### Entrypoints
+#### Entrypoints
-The `dev` command supports local FastMCP server files and configuration:
+The `dev inspector` command supports local FastMCP server files and configuration:
1. **Inferred server instance**: `server.py` - imports the module and looks for a FastMCP server instance named `mcp`, `server`, or `app`. Errors if no such object is found.
-2. **Explicit server entrypoint**: `server.py:custom_name` - imports and uses the specified server entrypoint
+2. **Explicit server entrypoint**: `server.py:custom_name` - imports and uses the specified server entrypoint
3. **Factory function**: `server.py:create_server` - calls the specified function (sync or async) to create a server instance
4. **FastMCP configuration**: `fastmcp.json` - uses FastMCP's declarative configuration (auto-detects in current directory)
-The `dev` command **only supports local files and fastmcp.json** - no URLs, remote servers, or standard MCP configuration files.
+The `dev inspector` command **only supports local files and fastmcp.json** - no URLs, remote servers, or standard MCP configuration files.
**Examples**
```bash
# Run dev server with editable mode and additional packages
-fastmcp dev server.py -e . --with pandas --with matplotlib
+fastmcp dev inspector server.py -e . --with pandas --with matplotlib
# Run dev server with fastmcp.json configuration (auto-detects)
-fastmcp dev
+fastmcp dev inspector
# Run dev server with explicit fastmcp.json file
-fastmcp dev dev.fastmcp.json
+fastmcp dev inspector dev.fastmcp.json
# Run dev server with specific Python version
-fastmcp dev server.py --python 3.11
+fastmcp dev inspector server.py --python 3.11
# Run dev server with requirements file
-fastmcp dev server.py --with-requirements requirements.txt
+fastmcp dev inspector server.py --with-requirements requirements.txt
# Run dev server within a specific project directory
-fastmcp dev server.py --project /path/to/project
+fastmcp dev inspector server.py --project /path/to/project
```
## `fastmcp install`
diff --git a/docs/python-sdk/fastmcp-cli-cli.mdx b/docs/python-sdk/fastmcp-cli-cli.mdx
index fca179c65..2f6a5e651 100644
--- a/docs/python-sdk/fastmcp-cli-cli.mdx
+++ b/docs/python-sdk/fastmcp-cli-cli.mdx
@@ -37,10 +37,10 @@ version()
Display version information and platform details.
-### `dev`
+### `inspector`
```python
-dev(server_spec: str | None = None) -> None
+inspector(server_spec: str | None = None) -> None
```
@@ -50,7 +50,7 @@ Run an MCP server with the MCP Inspector for development.
- `server_spec`: Python file to run, optionally with \:object suffix, or None to auto-detect fastmcp.json
-### `run`
+### `run`
```python
run(server_spec: str | None = None, *server_args: str) -> None
@@ -74,7 +74,7 @@ fastmcp run server.py -- --config config.json --debug
- `server_spec`: Python file, object specification (file\:obj), config file, URL, or None to auto-detect
-### `inspect`
+### `inspect`
```python
inspect(server_spec: str | None = None) -> None
@@ -105,7 +105,7 @@ fastmcp inspect # auto-detect fastmcp.json
- `server_spec`: Python file to inspect, optionally with \:object suffix, or fastmcp.json
-### `prepare`
+### `prepare`
```python
prepare(config_path: Annotated[str | None, cyclopts.Parameter(help='Path to fastmcp.json configuration file')] = None, output_dir: Annotated[str | None, cyclopts.Parameter(help='Directory to create the persistent environment in')] = None, skip_source: Annotated[bool, cyclopts.Parameter(help='Skip source preparation (e.g., git clone)')] = False) -> None
diff --git a/src/fastmcp/cli/cli.py b/src/fastmcp/cli/cli.py
index 5b9c24e4a..07b2ddb5b 100644
--- a/src/fastmcp/cli/cli.py
+++ b/src/fastmcp/cli/cli.py
@@ -134,8 +134,12 @@ def version(
console.print("[dim]Run: pip install --upgrade fastmcp[/dim]")
-@app.command
-async def dev(
+# Create dev subcommand group
+dev_app = cyclopts.App(name="dev", help="Development tools for MCP servers")
+
+
+@dev_app.command
+async def inspector(
server_spec: str | None = None,
*,
with_editable: Annotated[
@@ -946,6 +950,9 @@ async def prepare(
sys.exit(1)
+# Add dev subcommand group
+app.command(dev_app)
+
# Add project subcommand group
app.command(project_app)
diff --git a/tests/cli/test_cli.py b/tests/cli/test_cli.py
index 703771dff..eecc4300c 100644
--- a/tests/cli/test_cli.py
+++ b/tests/cli/test_cli.py
@@ -91,10 +91,10 @@ class TestVersionCommand:
class TestDevCommand:
"""Test the dev command."""
- def test_dev_command_parsing(self):
- """Test that dev command can be parsed with various options."""
+ def test_dev_inspector_command_parsing(self):
+ """Test that dev inspector command can be parsed with various options."""
# Test basic parsing
- command, bound, _ = app.parse_args(["dev", "server.py"])
+ command, bound, _ = app.parse_args(["dev", "inspector", "server.py"])
assert command is not None
assert bound.arguments["server_spec"] == "server.py"
@@ -102,6 +102,7 @@ class TestDevCommand:
command, bound, _ = app.parse_args(
[
"dev",
+ "inspector",
"server.py",
"--with",
"package1",
@@ -115,11 +116,12 @@ class TestDevCommand:
assert bound.arguments["inspector_version"] == "1.0.0"
assert bound.arguments["ui_port"] == 3000
- def test_dev_command_parsing_with_new_options(self):
- """Test dev command parsing with new uv options."""
+ def test_dev_inspector_command_parsing_with_new_options(self):
+ """Test dev inspector command parsing with new uv options."""
command, bound, _ = app.parse_args(
[
"dev",
+ "inspector",
"server.py",
"--python",
"3.10",