Skip to content

Commit 5259df7

Browse files
committed
refactor: simplify CLI interface and add direct script entry point
1 parent f591d7d commit 5259df7

File tree

7 files changed

+252
-39
lines changed

7 files changed

+252
-39
lines changed

CONTRIBUTING.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
# Contributing to Python Collab Template
1+
# Contributing to MCP Filesystem
22

33
Thank you for your interest in contributing to this project!
44

55
## Getting Started
66

77
1. Fork the repository
8-
2. Clone your fork: `git clone [email protected]:your-username/python-collab-template.git`
8+
2. Clone your fork: `git clone [email protected]:your-username/mcp-filesystem.git`
99
3. Create a new branch: `git checkout -b feature-name`
1010
4. Make your changes
1111
5. Run quality checks: `make check`

README.md

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,10 @@ Run the server with access to specific directories:
4242

4343
```bash
4444
# Using uv (recommended)
45-
uv run -m mcp_filesystem run /path/to/dir1 /path/to/dir2
45+
uv run run_server.py /path/to/dir1 /path/to/dir2
4646

4747
# Or using standard Python
48-
python -m mcp_filesystem run /path/to/dir1 /path/to/dir2
48+
python run_server.py /path/to/dir1 /path/to/dir2
4949
```
5050

5151
#### Options
@@ -60,13 +60,13 @@ For interactive testing and debugging with the MCP Inspector:
6060

6161
```bash
6262
# Basic usage
63-
npx @modelcontextprotocol/inspector uv run -m mcp_filesystem run /path/to/directory
63+
npx @modelcontextprotocol/inspector uv run run_server.py /path/to/directory
6464

6565
# With SSE transport
66-
npx @modelcontextprotocol/inspector uv run -m mcp_filesystem run /path/to/directory --transport sse --port 8080
66+
npx @modelcontextprotocol/inspector uv run run_server.py /path/to/directory --transport sse --port 8080
6767

6868
# With debug output
69-
npx @modelcontextprotocol/inspector uv run -m mcp_filesystem run /path/to/directory --debug
69+
npx @modelcontextprotocol/inspector uv run run_server.py /path/to/directory --debug
7070
```
7171

7272
This server has been built with the FastMCP SDK for better alignment with current MCP best practices. It uses an efficient component caching system and direct decorator pattern.
@@ -85,10 +85,10 @@ Edit your Claude Desktop config file to integrate MCP-Filesystem:
8585
"mcp-filesystem": {
8686
"command": "uv",
8787
"args": [
88+
"--directory",
89+
"/path/to/mcp-filesystem/repo",
8890
"run",
89-
"-m",
90-
"mcp_filesystem",
91-
"run"
91+
"run_server.py"
9292
]
9393
}
9494
}
@@ -103,10 +103,10 @@ To allow access to specific directories, add them as additional arguments:
103103
"mcp-filesystem": {
104104
"command": "uv",
105105
"args": [
106+
"--directory",
107+
"/path/to/mcp-filesystem/repo",
106108
"run",
107-
"-m",
108-
"mcp_filesystem",
109-
"run",
109+
"run_server.py",
110110
"/Users/yourusername/Projects",
111111
"/Users/yourusername/Documents"
112112
]
@@ -115,7 +115,7 @@ To allow access to specific directories, add them as additional arguments:
115115
}
116116
```
117117

118-
Note: The `run` command at the end is required as it specifies the subcommand to execute.
118+
> Note: The `--directory` flag is important as it tells uv where to find the repository containing run_server.py. Replace `/path/to/mcp-filesystem/repo` with the actual path to where you cloned the repository on your system.
119119
120120
## Development
121121

mcp_filesystem/__init__.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,21 @@
77

88
from .server import mcp
99

10-
__all__ = ["mcp"]
10+
11+
def main() -> None:
12+
"""Main entry point for the package."""
13+
try:
14+
mcp.run()
15+
except KeyboardInterrupt:
16+
import sys
17+
18+
print("\nShutting down...", file=sys.stderr)
19+
sys.exit(0)
20+
except Exception as e:
21+
import sys
22+
23+
print(f"Error: {e}", file=sys.stderr)
24+
sys.exit(1)
25+
26+
27+
__all__ = ["mcp", "main"]

mcp_filesystem/__main__.py

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@
1616
)
1717

1818

19-
@app.command()
20-
def run(
21-
directory: Annotated[
19+
@app.callback(invoke_without_command=True)
20+
def main(
21+
directories: Annotated[
2222
Optional[List[str]],
2323
typer.Argument(
2424
help="Allowed directories (defaults to current directory if none provided)",
@@ -49,33 +49,32 @@ def run(
4949
help="Enable debug logging",
5050
),
5151
] = False,
52-
name: Annotated[
53-
Optional[str],
52+
version: Annotated[
53+
bool,
5454
typer.Option(
55-
"--name",
56-
"-n",
57-
help="Server name",
55+
"--version",
56+
"-v",
57+
help="Show version information",
5858
),
59-
] = None,
59+
] = False,
6060
) -> None:
6161
"""Run the MCP Filesystem Server.
6262
6363
By default, the server will only allow access to the current directory.
6464
You can specify one or more allowed directories as arguments.
6565
"""
66+
if version:
67+
show_version()
68+
return
69+
6670
# Set allowed directories in environment for the server to pick up
67-
if directory:
68-
os.environ["MCP_ALLOWED_DIRS"] = os.pathsep.join(directory)
71+
if directories:
72+
os.environ["MCP_ALLOWED_DIRS"] = os.pathsep.join(directories)
6973

7074
# Set debug mode if requested
7175
if debug:
7276
os.environ["FASTMCP_LOG_LEVEL"] = "DEBUG"
7377

74-
# Setting custom name is not supported with FastMCP
75-
# Just log the name for now
76-
if name:
77-
print(f"Using server name: {name}")
78-
7978
try:
8079
if transport.lower() == "sse":
8180
os.environ["FASTMCP_PORT"] = str(port)
@@ -90,8 +89,7 @@ def run(
9089
sys.exit(1)
9190

9291

93-
@app.command()
94-
def version() -> None:
92+
def show_version() -> None:
9593
"""Show version information."""
9694
try:
9795
from importlib.metadata import version as get_version

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ dependencies = [
2828

2929
[project.scripts]
3030
mcp-filesystem = "mcp_filesystem.__main__:app"
31+
mcp-fs = "mcp_filesystem:main"
3132

3233
[project.optional-dependencies]
3334
dev = [

run_server.py

Lines changed: 102 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,113 @@
11
#!/usr/bin/env python
22
"""
3-
Simple entry point to run the MCP filesystem server.
4-
Usage: uv run run_server.py [dir1] [dir2] ...
3+
Primary entry point to run the MCP filesystem server.
4+
Usage: uv run run_server.py [dir1] [dir2] ... [options]
55
66
For use with MCP Inspector or Claude Desktop:
77
- Command: uv
8-
- Arguments: --directory /path/to/mcp-filesystem run mcp-filesystem run
8+
- Arguments: --directory /path/to/mcp-filesystem run run_server.py [dir1] [dir2]
99
10-
Note: The trailing 'run' is required as it specifies the subcommand to execute.
10+
This simplified approach eliminates the need for module invocation with -m flag.
1111
"""
1212

1313
import sys
14-
from mcp_filesystem.__main__ import app
14+
import os
15+
import typer
16+
from typing import List, Optional
17+
from typing_extensions import Annotated
18+
19+
from mcp_filesystem.server import mcp
20+
21+
app = typer.Typer(
22+
name="mcp-filesystem",
23+
help="MCP Filesystem Server",
24+
add_completion=False,
25+
)
26+
27+
@app.callback(invoke_without_command=True)
28+
def main(
29+
directories: Annotated[
30+
Optional[List[str]],
31+
typer.Argument(
32+
help="Allowed directories (defaults to current directory if none provided)",
33+
show_default=False,
34+
),
35+
] = None,
36+
transport: Annotated[
37+
str,
38+
typer.Option(
39+
"--transport",
40+
"-t",
41+
help="Transport protocol to use",
42+
),
43+
] = "stdio",
44+
port: Annotated[
45+
int,
46+
typer.Option(
47+
"--port",
48+
"-p",
49+
help="Port for SSE transport",
50+
),
51+
] = 8000,
52+
debug: Annotated[
53+
bool,
54+
typer.Option(
55+
"--debug",
56+
"-d",
57+
help="Enable debug logging",
58+
),
59+
] = False,
60+
version: Annotated[
61+
bool,
62+
typer.Option(
63+
"--version",
64+
"-v",
65+
help="Show version information",
66+
),
67+
] = False,
68+
) -> None:
69+
"""Run the MCP Filesystem Server.
70+
71+
By default, the server will only allow access to the current directory.
72+
You can specify one or more allowed directories as arguments.
73+
"""
74+
if version:
75+
show_version()
76+
return
77+
78+
# Set allowed directories in environment for the server to pick up
79+
if directories:
80+
os.environ["MCP_ALLOWED_DIRS"] = os.pathsep.join(directories)
81+
82+
# Set debug mode if requested
83+
if debug:
84+
os.environ["FASTMCP_LOG_LEVEL"] = "DEBUG"
85+
86+
try:
87+
if transport.lower() == "sse":
88+
os.environ["FASTMCP_PORT"] = str(port)
89+
mcp.run(transport="sse")
90+
else:
91+
mcp.run(transport="stdio")
92+
except KeyboardInterrupt:
93+
print("\nShutting down...", file=sys.stderr)
94+
sys.exit(0)
95+
except Exception as e:
96+
print(f"Error: {e}", file=sys.stderr)
97+
sys.exit(1)
98+
99+
100+
def show_version() -> None:
101+
"""Show version information."""
102+
try:
103+
from importlib.metadata import version as get_version
104+
version = get_version("mcp-filesystem")
105+
except ImportError:
106+
version = "unknown"
107+
108+
print(f"MCP Filesystem Server v{version}")
109+
print("A Model Context Protocol server for filesystem operations")
110+
15111

16112
if __name__ == "__main__":
17-
sys.exit(app())
113+
app()

0 commit comments

Comments
 (0)