cli-mcp-mapper
v1.0.5
Published
mcp server for mapping cli commands to mcp tools
Readme
CLI MCP Mapper
Transform any CLI command into a Model Context Protocol (MCP) tool with simple JSON configuration.
CLI MCP Mapper is a powerful MCP server that dynamically exposes command-line tools as MCP tools. This allows AI assistants and other MCP clients to safely execute system commands, scripts, and tools through a declarative JSON configuration—no code required.
Table of Contents
- Why CLI MCP Mapper?
- Features
- Installation
- Configuration
- JSON Specification
- Usage Examples
- MCP Client Configuration
- Example Configuration Files
- Troubleshooting
- Security Considerations
- Contributing
- License
Why CLI MCP Mapper?
The Model Context Protocol (MCP) enables AI assistants to interact with external tools and systems. However, creating MCP servers for every command-line tool can be time-consuming and requires coding expertise. CLI MCP Mapper solves this by:
- No Coding Required: Define tools using simple JSON configuration
- Universal Compatibility: Works with any CLI tool (git, npm, docker, custom scripts, etc.)
- Type Safety: JSON schema validation ensures configuration correctness
- Flexible Parameter Handling: Supports positional arguments, named flags, booleans, enums, and more
- Reusable Configurations: Share and version control your tool definitions
- Rapid Prototyping: Test MCP tool ideas without writing server code
Use Cases
- DevOps Automation: Expose docker, kubectl, terraform commands to AI assistants
- Development Workflows: Make build tools, linters, and test runners available as MCP tools
- System Administration: Safely expose system commands with controlled parameters
- Custom Scripts: Wrap your own scripts and make them AI-accessible
- Git Operations: Provide version control capabilities to AI assistants
- File Management: Enable AI to perform file operations with safety guardrails
Features
✨ Dynamic Tool Generation: Automatically creates MCP tools from JSON definitions
🎯 Flexible Parameters: Supports positional args, named flags, booleans, enums, and required/optional parameters
📝 Type System: String, boolean, and number parameter types with validation
🔒 Schema Validation: JSON schema for validating your command configurations
✅ Configuration Validation: Built-in dry-run mode to verify configurations before deployment
🚀 Zero Dependencies: Minimal runtime footprint (only @modelcontextprotocol/sdk)
🔧 Easy Configuration: Environment variable or default path configuration
📚 Rich Examples: Comprehensive example configurations included
Installation
Install CLI MCP Mapper globally from NPM:
npm i -g cli-mcp-mapperVerify the installation:
which cli-mcp-mapperConfiguration
CLI MCP Mapper requires a JSON configuration file that defines which commands to expose as MCP tools.
Environment Variable
You can specify a custom configuration path using the CLI_MCP_MAPPER_CONFIG environment variable:
export CLI_MCP_MAPPER_CONFIG=/path/to/your/commands.jsonFor persistent configuration, add this to your shell profile (~/.bashrc, ~/.zshrc, etc.):
# Add to ~/.bashrc or ~/.zshrc
export CLI_MCP_MAPPER_CONFIG="$HOME/my-mcp-configs/commands.json"Default Location
If no environment variable is set, CLI MCP Mapper looks for the configuration at:
~/.config/cli-mcp-mapper/commands.jsonOn different systems:
- Linux/macOS:
~/.config/cli-mcp-mapper/commands.json - Windows:
%USERPROFILE%\.config\cli-mcp-mapper\commands.json
To create the default configuration directory:
mkdir -p ~/.config/cli-mcp-mapperThen copy one of the example configurations or create your own:
# Copy a basic example
cp examples/basic-commands.json ~/.config/cli-mcp-mapper/commands.json
# Or create your own
cat > ~/.config/cli-mcp-mapper/commands.json << 'EOF'
{
"commands": {
"hello": {
"description": "Say hello",
"command": "echo",
"baseArgs": [],
"parameters": {
"name": {
"type": "string",
"description": "Name to greet",
"required": true,
"position": 0
}
}
}
}
}
EOFConfiguration File Format
The configuration file is a JSON object with a single commands property containing a map of command definitions:
{
"commands": {
"command_name": {
"description": "What this command does",
"command": "base-command",
"baseArgs": ["--static", "args"],
"parameters": {
"param_name": {
"type": "string",
"description": "Parameter description",
"required": false,
"position": 0
}
}
}
}
}Validating Configuration (Dry-Run)
Before deploying CLI MCP Mapper in production or in CI/CD pipelines, you can validate your configuration file using the --dry-run flag. This performs a "flight check" by loading and parsing your configuration without starting the MCP server.
Basic Usage:
cli-mcp-mapper --dry-runWith Custom Configuration Path:
CLI_MCP_MAPPER_CONFIG=/path/to/commands.json cli-mcp-mapper --dry-runWhat Dry-Run Does:
- ✅ Loads the configuration file from the specified path
- ✅ Validates JSON syntax
- ✅ Verifies the configuration structure (presence of
commandsobject) - ✅ Validates each command definition (required fields, parameter schemas)
- ✅ Exits with appropriate status code (0 for success, 1 for errors)
- ✅ Outputs detailed error messages to stderr for debugging
Example Output (Success):
Configuration loaded successfully from /home/user/.config/cli-mcp-mapper/commands.json
Found 9 command(s):
✓ ls: List directory contents
✓ cat: Display contents of a file
✓ mkdir: Create a new directory
✓ echo: Display a line of text
✓ find: Search for files in a directory hierarchy
...
Dry-run completed successfully. Configuration is valid.Example Output (Error):
Error: Configuration file not found at /path/to/commands.json
Please create a configuration file or set CLI_MCP_MAPPER_CONFIG environment variable.Use Cases:
CI/CD Pipelines: Add validation as a build step to catch configuration errors before deployment
# In GitHub Actions or similar CI - name: Validate MCP Configuration run: cli-mcp-mapper --dry-run env: CLI_MCP_MAPPER_CONFIG: ./config/commands.jsonPre-deployment Checks: Verify configuration files before pushing to production
# In deployment script if ! cli-mcp-mapper --dry-run; then echo "Configuration validation failed!" exit 1 fiConfiguration Development: Quick validation during configuration file editing
# Edit config and validate immediately vim ~/.config/cli-mcp-mapper/commands.json cli-mcp-mapper --dry-runAutomated Testing: Integrate into test suites to ensure configuration integrity
# Test script for config in configs/*.json; do CLI_MCP_MAPPER_CONFIG="$config" cli-mcp-mapper --dry-run || exit 1 done
Exit Codes:
0: Configuration is valid and ready to use1: Configuration error (missing file, invalid JSON, structural issues)
JSON Specification
Schema Reference
A JSON Schema is provided for validating your configuration files. Reference it in your JSON:
{
"$schema": "./commands.schema.json",
"commands": { ... }
}This enables autocompletion and validation in editors that support JSON Schema (VS Code, IntelliJ, etc.).
Command Definition
Each command in the commands object has the following structure:
| Property | Type | Required | Description |
|----------|------|----------|-------------|
| description | string | ✅ Yes | Human-readable description shown to MCP clients |
| command | string | ✅ Yes | Base command to execute (e.g., "git", "npm", "docker") |
| baseArgs | string[] | No | Static arguments always passed to the command (e.g., ["build", "--quiet"]) |
| parameters | object | No | Map of parameter names to parameter definitions |
Example:
{
"git_status": {
"description": "Show the working tree status",
"command": "git",
"baseArgs": ["status"],
"parameters": {
"short": {
"type": "boolean",
"description": "Give output in short format",
"argName": "-s"
}
}
}
}Parameter Definition
Each parameter in the parameters object defines how the parameter is passed to the command:
| Property | Type | Required | Description |
|----------|------|----------|-------------|
| type | string | ✅ Yes | Parameter type: "string", "boolean", or "number" |
| description | string | ✅ Yes | Human-readable parameter description |
| required | boolean | No | Whether the parameter must be provided (default: false) |
| position | number | No | For positional arguments: 0-based position in command line |
| argName | string | No | For named arguments: the flag to use (e.g., "--output", "-v") |
| argValue | string | No | Static value to pass after argName (rarely used) |
| enum | string[] | No | List of allowed values |
| default | any | No | Default value if not provided |
Parameter Processing Rules:
Positional Parameters (
positionis set):- Added to command line in position order (0, 1, 2, ...)
- No
argNameneeded - If parameter is not provided and not required, it's omitted
Named Parameters (
argNameis set):- For
booleantype: Iftrue, addsargNameto command - For
stringornumbertype: AddsargNamefollowed by the value - If parameter is not provided, it's omitted
- For
Required Parameters (
required: true):- MCP clients must provide these parameters
- Validation happens before command execution
Parameter Types
String Parameters
Used for text values, file paths, URLs, etc.
{
"file_path": {
"type": "string",
"description": "Path to the file",
"required": true,
"position": 0
}
}With enum for limited choices:
{
"log_level": {
"type": "string",
"description": "Logging level",
"enum": ["debug", "info", "warn", "error"],
"argName": "--log-level"
}
}Boolean Parameters
Used for flags/switches. When true, the argName is added to the command.
{
"verbose": {
"type": "boolean",
"description": "Enable verbose output",
"argName": "-v"
}
}Multiple boolean flags can be combined:
{
"force": {
"type": "boolean",
"description": "Force operation",
"argName": "-f"
},
"recursive": {
"type": "boolean",
"description": "Recursive operation",
"argName": "-r"
}
}When both are true, command becomes: command -f -r
Number Parameters
Used for numeric values (counts, limits, sizes, etc.).
{
"max_count": {
"type": "number",
"description": "Maximum number of results",
"argName": "-n"
}
}Usage Examples
Basic Commands Example
Simple file system operations:
{
"commands": {
"ls": {
"description": "List directory contents",
"command": "ls",
"baseArgs": ["-lah"],
"parameters": {
"path": {
"type": "string",
"description": "Directory path",
"position": 0
}
}
},
"mkdir": {
"description": "Create a directory",
"command": "mkdir",
"baseArgs": [],
"parameters": {
"path": {
"type": "string",
"description": "Directory to create",
"required": true,
"position": 0
},
"parents": {
"type": "boolean",
"description": "Create parent directories",
"argName": "-p"
}
}
}
}
}Usage in MCP client:
ls()→ executesls -lahls({ path: "/tmp" })→ executesls -lah /tmpmkdir({ path: "/tmp/test", parents: true })→ executesmkdir -p /tmp/test
Git Operations Example
Version control commands:
{
"commands": {
"git_commit": {
"description": "Commit changes with a message",
"command": "git",
"baseArgs": ["commit"],
"parameters": {
"message": {
"type": "string",
"description": "Commit message",
"required": true,
"argName": "-m"
},
"all": {
"type": "boolean",
"description": "Stage all modified files",
"argName": "-a"
}
}
},
"git_status": {
"description": "Show repository status",
"command": "git",
"baseArgs": ["status"],
"parameters": {}
}
}
}Usage in MCP client:
git_status()→ executesgit statusgit_commit({ message: "Fix bug", all: true })→ executesgit commit -m "Fix bug" -a
Complex Parameters Example
Advanced parameter handling with mixed positional and named arguments:
{
"commands": {
"find_files": {
"description": "Search for files",
"command": "find",
"baseArgs": [],
"parameters": {
"path": {
"type": "string",
"description": "Starting directory",
"position": 0,
"default": "."
},
"name": {
"type": "string",
"description": "File name pattern",
"argName": "-name"
},
"type": {
"type": "string",
"description": "File type",
"enum": ["f", "d", "l"],
"argName": "-type"
},
"max_depth": {
"type": "number",
"description": "Maximum search depth",
"argName": "-maxdepth"
}
}
}
}
}Usage in MCP client:
find_files({ name: "*.js", type: "f" })→ executesfind . -name "*.js" -type ffind_files({ path: "/src", name: "*.ts", max_depth: 3 })→ executesfind /src -name "*.ts" -maxdepth 3
MCP Client Configuration
Claude Desktop
To use CLI MCP Mapper with Claude Desktop, add it to your MCP configuration file.
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
Linux: ~/.config/Claude/claude_desktop_config.json
Add the following to the mcpServers section:
{
"mcpServers": {
"cli-mcp-mapper": {
"type": "local",
"command": "cli-mcp-mapper",
"args": [],
"tools": ["*"]
}
}
}With custom configuration path:
{
"mcpServers": {
"cli-mcp-mapper": {
"type": "local",
"command": "cli-mcp-mapper",
"args": [],
"env": {
"CLI_MCP_MAPPER_CONFIG": "/path/to/your/commands.json"
},
"tools": ["*"]
}
}
}After updating the configuration:
- Save the file
- Restart Claude Desktop
- Your configured commands will appear as available tools
Other MCP Clients
For other MCP clients, refer to their documentation for adding MCP servers. The general pattern is:
{
"command": "cli-mcp-mapper",
"args": [],
"env": {
"CLI_MCP_MAPPER_CONFIG": "/path/to/commands.json"
}
}Example Configuration Files
The repository includes several example configuration files in the examples/ directory:
basic-commands.json
Common Unix/Linux commands: ls, cat, mkdir, rm, pwd, echo, find, grep
Use this to give AI assistants basic file system capabilities.
git-commands.json
Git operations: git status, git commit, git push, git pull, git log, etc.
Enable version control operations for AI-assisted development.
file-operations.json
File manipulation: cp, mv, touch, chmod, chown, tar, wc
Advanced file and archive operations.
Using Examples
To use an example configuration:
# Copy to default location
cp examples/basic-commands.json ~/.config/cli-mcp-mapper/commands.json
# Or use with environment variable
export CLI_MCP_MAPPER_CONFIG="$PWD/examples/git-commands.json"You can also merge multiple examples into a single configuration:
# Combine multiple configurations
jq -s '{"commands": (map(.commands) | add)}' \
examples/basic-commands.json \
examples/git-commands.json \
> ~/.config/cli-mcp-mapper/commands.jsonTroubleshooting
Configuration File Not Found
Error: Cannot find module '/path/to/commands.json'
Solutions:
- Verify the file exists:
ls -la ~/.config/cli-mcp-mapper/commands.json - Create the directory:
mkdir -p ~/.config/cli-mcp-mapper - Check environment variable:
echo $CLI_MCP_MAPPER_CONFIG - Ensure JSON file is valid:
cat ~/.config/cli-mcp-mapper/commands.json | jq
Invalid JSON Syntax
Error: Unexpected token or JSON Parse error
Solutions:
- Validate JSON syntax:
cat commands.json | jq - Use an editor with JSON validation (VS Code, etc.)
- Check for missing commas, brackets, or quotes
- Validate against schema: Use the provided
commands.schema.json
Command Not Executing
Error: Command returns error or unexpected output
Solutions:
- Test command manually: Run the generated command in your terminal
- Check
baseArgs: Ensure they're valid for your command - Verify
argNamematches command's expected flags - Check positional argument order
- Review command's help:
command --help
Permission Denied
Error: EACCES or Permission denied
Solutions:
- Ensure command is in PATH:
which command-name - Check file permissions:
ls -la $(which command-name) - Use absolute path in
commandfield - For scripts, ensure execute permission:
chmod +x script.sh
Tool Not Appearing in MCP Client
Solutions:
- Restart MCP client (e.g., Claude Desktop)
- Check MCP client logs for errors
- Verify
commands.jsonis valid - Ensure CLI MCP Mapper is installed:
which cli-mcp-mapper - Check client configuration file syntax
Commands Execute but Return No Output
Issue: Command executes successfully but returns empty string
Explanation: Some commands output to stderr instead of stdout. CLI MCP Mapper captures both but only returns stdout by default on success.
Solutions:
- Check if command writes to stderr
- Use command flags to redirect output to stdout
- This is often expected behavior for commands that only show errors
Security Considerations
⚠️ Important Security Notes:
Command Injection Protection: CLI MCP Mapper uses Node.js
spawnwithout shell interpretation to prevent command injection attacks. While we have comprehensive tests to validate this protection, you should always run agents with shell access in containerized or sandboxed environments (e.g., Docker, VM, or other isolation mechanisms) to minimize potential security risks. This provides an additional layer of defense in case of unforeseen vulnerabilities.Containerization Best Practice: When deploying CLI MCP Mapper in production or exposing it to AI agents, strongly consider running it within:
- Docker containers with limited privileges
- Virtual machines with restricted network access
- Sandboxed environments with filesystem restrictions
- Isolated user accounts with minimal permissions
Access Control: MCP clients that connect to CLI MCP Mapper will have the same permissions as the user running it. Run the server with the least privileged user account necessary.
Validate Parameters: Use
enumto restrict parameter values when possible to prevent unexpected inputs.Avoid Dangerous Commands: Be cautious about exposing commands like:
rm -rfwithout proper constraintschmodwith unrestricted modes- Commands that can execute arbitrary code
- Network commands that could expose sensitive data
- System administration commands
Read-Only Operations: Consider starting with read-only commands (ls, cat, git status) before exposing write operations.
Configuration Security:
- Don't commit sensitive configurations to version control
- Use environment-specific configuration files
- Review configurations before deploying
- Regularly audit which commands are exposed
Least Privilege: Only grant the minimum necessary commands for your use case.
Best Practices:
{
"commands": {
"safe_delete": {
"description": "Delete files (safe - no recursive)",
"command": "rm",
"baseArgs": ["-i"], // Interactive mode for safety
"parameters": {
"file": {
"type": "string",
"description": "Single file to delete",
"required": true,
"position": 0
}
}
}
}
}Contributing
Contributions are welcome! Here's how you can help:
- Report Issues: Found a bug? Open an issue on GitHub
- Submit PRs: Fix bugs, add features, improve documentation
- Share Examples: Create and share useful command configurations
- Improve Documentation: Help make the docs clearer and more comprehensive
Development Setup
# Clone the repository
git clone https://github.com/SteffenBlake/cli-mcp-mapper.git
cd cli-mcp-mapper
# Install dependencies
npm install
# Test locally
node index.jsLicense
MIT License - see LICENSE file for details.
Made with ❤️ for the MCP community
For issues, questions, or contributions, visit: https://github.com/SteffenBlake/cli-mcp-mapper
