MCP Command Server Documentation
January 30, 2025 ยท View on GitHub
Overview
MCP Command Server is a secure Model Context Protocol (MCP) server implementation that allows controlled execution of system commands through Large Language Models (LLMs) like Claude.
Table of Contents
Installation
Prerequisites
- Python 3.10 or higher
- pip or uv package manager
- Claude Desktop (for integration)
- Visual Studio Code (recommended for development)
Quick Install
# Using uv (recommended)
uv pip install mcp-command-server
# Using pip
pip install mcp-command-server
Development Setup
- Clone the repository:
git clone https://github.com/yourusername/mcp-command-server.git
cd mcp-command-server
- Create and activate virtual environment:
# Using uv
uv venv
source .venv/bin/activate # On Unix/macOS
.venv\Scripts\activate # On Windows
- Install dependencies:
uv pip install -e ".[dev]"
Claude Desktop Integration
- Open Claude Desktop configuration:
code ~/Library/Application\ Support/Claude/claude_desktop_config.json
- Add server configuration:
{
"mcpServers": {
"command-server": {
"command": "uv",
"args": ["run", "python", "-m", "mcp_command_server"],
"env": {
"ALLOWED_COMMANDS": "ls,pwd,echo"
}
}
}
}
Security Guidelines
Command Execution Safety
-
Whitelist Commands
- Only explicitly allowed commands can be executed
- Configure through
ALLOWED_COMMANDSenvironment variable - Separate multiple commands with commas
-
Input Sanitization
- All command inputs are sanitized
- Special characters are escaped
- Path traversal is prevented
-
User Confirmation
- Commands require explicit user approval
- Clear display of command to be executed
- Timeout for confirmation requests
-
Audit Logging
- All command executions are logged
- Includes timestamp, command, and result
- Logs stored in
~/Library/Logs/Claude/mcp-command-server.log
Environment Variables
| Variable | Description | Required | Default |
|---|---|---|---|
| ALLOWED_COMMANDS | Comma-separated list of allowed commands | Yes | None |
| LOG_LEVEL | Logging verbosity (DEBUG, INFO, WARNING, ERROR) | No | INFO |
| CONFIRMATION_TIMEOUT | Seconds to wait for user confirmation | No | 30 |
API Reference
Tools
execute_command
Executes a system command from the allowed list.
@mcp.tool()
async def execute_command(command: str, args: list[str]) -> str:
"""Execute a system command.
Args:
command: The command to execute (must be in whitelist)
args: List of command arguments
Returns:
Command output as string
Raises:
SecurityError: If command not in whitelist
ValidationError: If arguments invalid
"""
list_allowed_commands
Returns the list of allowed commands.
@mcp.tool()
def list_allowed_commands() -> list[str]:
"""Get list of allowed commands.
Returns:
List of command names that can be executed
"""
Resources
audit_log
Access the command execution audit log.
@mcp.resource("audit://log")
def get_audit_log() -> str:
"""Get the command execution audit log.
Returns:
Formatted audit log entries
"""
Usage Examples
Basic Command Execution
# List directory contents
response = await client.call_tool(
"execute_command",
{
"command": "ls",
"args": ["-la"]
}
)
# Print working directory
response = await client.call_tool(
"execute_command",
{
"command": "pwd",
"args": []
}
)
Claude Desktop Interaction
Example conversation with Claude:
Human: What files are in the current directory?
Claude: I'll help you list the files in the current directory using the command server.
[Tool call: execute_command with args: ["ls", "-la"]]
Awaiting your confirmation to run: ls -la
[Output after confirmation]
total 56
drwxr-xr-x 10 user staff 320 Mar 14 15:30 .
drwxr-xr-x 5 user staff 160 Mar 14 15:30 ..
-rw-r--r-- 1 user staff 2516 Mar 14 15:30 README.md
drwxr-xr-x 4 user staff 128 Mar 14 15:30 src
drwxr-xr-x 4 user staff 128 Mar 14 15:30 tests
Here's a breakdown of the files and directories in your current location:
1. README.md - Documentation file
2. src/ - Source code directory
3. tests/ - Test files directory
Would you like me to examine any of these files or directories in more detail?
### Error Handling
When using the command server, you may encounter these common errors:
1. **Command Not Allowed**
Error: Command 'rm' is not in the allowed commands list Solution: Add the command to ALLOWED_COMMANDS or use an allowed alternative
2. **Invalid Arguments**
Error: Invalid argument format: contains unsafe characters Solution: Remove special characters or properly escape them
3. **Timeout**
Error: User confirmation timeout after 30 seconds Solution: Respond to the confirmation prompt more quickly or adjust CONFIRMATION_TIMEOUT
## Troubleshooting
### Common Issues
#### Server Not Starting
**Problem**: Claude Desktop can't start the command server.
**Solutions**:
1. Verify Python installation:
```bash
python --version # Should be 3.10 or higher
- Check configuration path:
ls ~/Library/Application\ Support/Claude/claude_desktop_config.json
- Validate environment setup:
echo $ALLOWED_COMMANDS # Should show allowed commands
Permission Errors
Problem: Commands fail with permission errors.
Solutions:
- Check file permissions:
ls -l /path/to/directory
- Verify user permissions:
whoami
groups
- Update file permissions if needed:
chmod +r /path/to/file # Add read permission
Logging Issues
Problem: Can't find command execution logs.
Solutions:
- Check log file location:
ls ~/Library/Logs/Claude/mcp-command-server.log
- Verify logging configuration:
echo $LOG_LEVEL
- Enable debug logging:
export LOG_LEVEL=DEBUG
Getting Help
- Check Logs:
tail -f ~/Library/Logs/Claude/mcp-command-server.log
- Issue Reporting:
- Visit our GitHub Issues page
- Include log output
- Describe your environment
- List steps to reproduce
- Community Support:
- Join our Discord server
- Post in GitHub Discussions
- Check Stack Overflow tags
Extending Commands
Adding New Commands
There are two ways to extend the available commands:
- Environment Configuration (Basic)
Add commands to the ALLOWED_COMMANDS environment variable:
# In your shell or .env file
export ALLOWED_COMMANDS="ls,pwd,echo,cat,grep,find"
# Or in claude_desktop_config.json
{
"mcpServers": {
"command-server": {
"command": "uv",
"args": ["run", "python", "-m", "mcp_command_server"],
"env": {
"ALLOWED_COMMANDS": "ls,pwd,echo,cat,grep,find"
}
}
}
}
- Custom Command Configuration (Advanced)
Create a command configuration file (commands.yaml):
commands:
ls:
allowed_flags: ["-l", "-a", "-h", "-t"]
allowed_paths: ["~/Documents", "~/Downloads"]
description: "List directory contents"
grep:
allowed_flags: ["-i", "-v", "-n"]
max_file_size: "10MB"
description: "Search file contents"
find:
allowed_flags: ["-name", "-type"]
excluded_paths: ["/etc", "/var"]
description: "Search for files"
Then reference it in your configuration:
{
"mcpServers": {
"command-server": {
"command": "uv",
"args": ["run", "python", "-m", "mcp_command_server"],
"env": {
"COMMAND_CONFIG": "/path/to/commands.yaml"
}
}
}
}
Security Considerations
When adding new commands:
-
Risk Assessment
- Evaluate what the command can access
- Consider potential misuse scenarios
- Review command flags and options
-
Access Control
- Limit commands to specific directories
- Restrict dangerous flags
- Consider read-only vs write operations
-
Resource Limits
- Set timeouts for long-running commands
- Limit output size
- Restrict file size for operations
Command Categories
Here are common command categories you might want to add:
-
File Operations
cat, less, head, tail, grep, find -
Directory Operations
ls, pwd, cd, tree, du -
System Information
df, top, ps, free, uptime -
Network Tools
ping, curl, wget, netstat -
Text Processing
grep, sed, awk, sort, uniq
Example: Adding Git Commands
To add Git support:
- Add commands to allowlist:
export ALLOWED_COMMANDS="git-status,git-log,git-branch"
- Create command configurations:
commands:
git-status:
allowed_flags: ["--short", "--branch"]
working_dir: "~/projects"
description: "Show working tree status"
git-log:
allowed_flags: ["--oneline", "--graph", "-n"]
max_entries: 100
description: "Show commit logs"
- Implement custom validation:
@mcp.tool()
async def execute_git_command(command: str, args: list[str]) -> str:
"""Execute git commands safely.
Args:
command: Git subcommand (status, log, etc.)
args: Command arguments
Returns:
Command output
"""
# Your implementation here
Testing New Commands
Always test new commands thoroughly:
- Unit Tests
def test_git_command_validation():
# Test command validation
assert validate_git_command("status", ["--short"]) is True
assert validate_git_command("push", []) is False # Dangerous command
- Integration Tests
async def test_git_command_execution():
# Test actual execution
result = await execute_git_command("status", ["--short"])
assert result.startswith("## main")
Common Issues
-
Permission Errors
- Make sure the server has necessary permissions
- Check file/directory ownership
- Verify user permissions
-
Command Not Found
- Verify command is in system PATH
- Check command spelling
- Confirm command installation
-
Configuration Issues
- Validate YAML syntax
- Check file paths
- Verify environment variables
License
This project is licensed under the MIT License. See the LICENSE file for details.