Skip to content
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
13 changes: 12 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -105,4 +105,15 @@ self-signed-cert.pem
self-signed-key.pem
*.mcpb
invalid-json.json
**/server/lib/**
**/*/lib/**

# Python
__pycache__/
*.py[cod]
*.egg-info

# Python virtual environments
.venv/

# VS Code
.vscode/PythonImportHelper-v2-Completion.json
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,21 @@ bundle.mcpb (ZIP file)
└── icon.png # Optional: Bundle icon
```

### Example: Python Package Bundle

```
bundle.mcpb (ZIP file)
├── manifest.json # Required: Bundle metadata and configuration
├── server_package/ # Server files
│ ├── __init__.py # Package initializer
│ ├── __main__.py # Main entry point
│ ├── server.py # MCP server
│ └── utils.py # Additional modules
├── lib/ # Bundled Python packages (must server_package)
├── pyproject.toml # Optional: Python configuration
└── icon.png # Optional: Bundle icon
```

### Example: Binary Bundle

```
Expand Down
11 changes: 6 additions & 5 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ But, the MCP servers themselves are not robust secure production ready servers a

## Examples Included

| Example | Type | Demonstrates |
| --------------------- | ------- | ---------------------------------------- |
| `hello-world-node` | Node.js | Basic MCP server with simple time tool |
| `chrome-applescript` | Node.js | Browser automation via AppleScript |
| `file-manager-python` | Python | File system operations and path handling |
| Example | Type | Demonstrates |
| ----------------------------- | ------- | ---------------------------------------- |
| `hello-world-node` | Node.js | Basic MCP server with simple time tool |
| `chrome-applescript` | Node.js | Browser automation via AppleScript |
| `file-manager-python` | Python | File system operations and path handling |
| `file-manager-python-package` | Python | Same as above but shipping as Python package and featuring an MCPB manifest using module invocation instead of direct script execution |

## Usage

Expand Down
6 changes: 6 additions & 0 deletions examples/file-manager-python-package/.mcpbignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.venv/
*.egg-info/
*.toml
build/
dist/
mcp_server_file_manager/__pycache__/
69 changes: 69 additions & 0 deletions examples/file-manager-python-package/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
{
"$schema": "../../dist/mcpb-manifest.schema.json",
"dxt_version": "0.1",
"name": "file-manager-python-package",
"display_name": "Python Package File Manager MCP",
"version": "0.1.0",
"description": "A Python Package MCP server for file operations",
"long_description": "This extension provides file management capabilities through a Python Package MCP server. It demonstrates Python package-based MCP Bundle development, including file operations, directory management, and proper MCP protocol implementation.",
"author": {
"name": "Anthropic",
"email": "support@anthropic.com",
"url": "https://github.com/anthropics"
},
"server": {
"type": "python",
"entry_point": "mcp_server_file_manager/__main__.py",
"mcp_config": {
"command": "python",
"args": [
"-m",
"mcp_server_file_manager",
"--workspace=${user_config.workspace_directory}"
],
"env": {
"DEBUG": "${user_config.debug_mode}",
"PYTHONPATH": "${__dirname}/mcp_server_file_manager/lib"
}
}
},
"tools": [
{
"name": "list_files",
"description": "List files in a directory"
},
{
"name": "read_file",
"description": "Read file contents"
},
{
"name": "get_file_info",
"description": "Get information about a file"
}
],
"keywords": ["file", "directory", "python", "management", "filesystem"],
"license": "MIT",
"user_config": {
"workspace_directory": {
"type": "directory",
"title": "Workspace Directory",
"description": "Directory to use as workspace",
"default": "${HOME}/Documents",
"required": false
},
"debug_mode": {
"type": "boolean",
"title": "Debug Mode",
"description": "Enable debug output",
"default": false,
"required": false
}
},
"compatibility": {
"claude_desktop": ">=0.10.0",
"platforms": ["darwin", "win32", "linux"],
"runtimes": {
"python": ">=3.8.0 <4"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""File Manager MCP server."""
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/usr/bin/env python3

import os
import sys
import argparse

def main():
# Parse command line arguments
parser = argparse.ArgumentParser(description="File Manager MCP Server")
parser.add_argument(
"--workspace", default=os.path.expanduser("~/Documents"), help="Workspace directory"
)
parser.add_argument("--debug", action="store_true", help="Enable debug mode")
args = parser.parse_args()

# Debug output if enabled
if args.debug:
print("Starting File Manager MCP Server...", file=sys.stderr)
print(f"Workspace: {args.workspace}", file=sys.stderr)

# Import and run the server
from .server import mcp
mcp.run()

if __name__ == "__main__":
main()
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
from pathlib import Path
from mcp.server.fastmcp import FastMCP

# Initialize server
mcp = FastMCP("file-manager-python")


@mcp.tool()
def list_files(path: str) -> str:
"""List files in a directory"""
path_obj = Path(path)

if not path_obj.exists():
return f"Directory not found: {path}"

if not path_obj.is_dir():
return f"Path is not a directory: {path}"

try:
files = []
for item in path_obj.iterdir():
file_type = "directory" if item.is_dir() else "file"
files.append(f"{item.name} ({file_type})")

if not files:
return f"Directory is empty: {path}"

file_list = "\n".join(files)
return f"Files in {path}:\n{file_list}"

except PermissionError:
return f"Permission denied accessing: {path}"
except Exception as e:
return f"Error listing directory: {str(e)}"


@mcp.tool()
def read_file(path: str) -> str:
"""Read file contents"""
path_obj = Path(path)

if not path_obj.exists():
return f"File not found: {path}"

if not path_obj.is_file():
return f"Path is not a file: {path}"

try:
with path_obj.open("r", encoding="utf-8") as f:
content = f.read()

return f"Contents of {path}:\n{content}"

except UnicodeDecodeError:
return f"File is not text or uses unsupported encoding: {path}"
except PermissionError:
return f"Permission denied reading: {path}"
except Exception as e:
return f"Error reading file: {str(e)}"


@mcp.tool()
def get_file_info(path: str) -> str:
"""Get information about a file"""
path_obj = Path(path)

if not path_obj.exists():
return f"Path not found: {path}"

try:
stat_info = path_obj.stat()
file_type = "directory" if path_obj.is_dir() else "file"

info = [
f"Path: {path}",
f"Type: {file_type}",
f"Size: {stat_info.st_size} bytes",
f"Modified: {stat_info.st_mtime}",
f"Created: {stat_info.st_ctime}",
]

info_text = "\n".join(info)
return f"File Info:\n{info_text}"

except PermissionError:
return f"Permission denied accessing: {path}"
except Exception as e:
return f"Error getting file info: {str(e)}"


31 changes: 31 additions & 0 deletions examples/file-manager-python-package/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
[build-system]
requires = ["setuptools>=42", "wheel"]
build-backend = "setuptools.build_meta"

[project]
name = "file-manager-python-package"
version = "0.1.0"
description = "A Python Package MCP server for file operations"
authors = [
{name = "Anthropic", email = "support@anthropic.com"}
]
license = {text = "MIT"}
classifiers = [
"Private :: Do Not Upload" # Prevents accidental uploads to PyPI
]
dependencies = [
"mcp>=1.0.0",
"trio>=0.22.0"
]

[tool.setuptools]
packages = ["mcp_server_file_manager"]

[project.scripts]
mcp-server-file-manager = "mcp_server_file_manager.__main__:main"

# Custom scripts section for MCPB development
[tool.mcpb]
bundle = "pip install . --target mcp_server_file_manager/lib --upgrade"
test = "python -m mcp_server_file_manager --help"
pack = "npx @anthropic-ai/mcpb pack . dist\file-manager.mcpb"