| name | mcp-cli-tool |
| description | Lightweight CLI for interacting with MCP (Model Context Protocol) servers - discover, inspect, and execute MCP tools from the command line |
| triggers | ["how do I use mcp-cli to call MCP servers","list available MCP tools with mcp-cli","configure mcp-cli for MCP servers","call an MCP tool from the command line","discover MCP server capabilities","chain mcp-cli commands with jq","set up mcp servers config file","troubleshoot mcp-cli connection issues"] |
mcp-cli Tool
Skill by ara.so — MCP Skills collection.
Overview
mcp-cli is a lightweight, Bun-based CLI for interacting with MCP (Model Context Protocol) servers. It provides:
- On-demand schema loading - Only fetch tool schemas when needed, saving AI context tokens
- Shell composability - JSON output for piping with
jq, chaining, and scripting
- Connection pooling - Lazy-spawn daemon keeps connections warm (60s idle timeout)
- Universal support - Works with both stdio and HTTP MCP servers
- Tool filtering - Allow/disable specific tools per server via config
Use cases:
- AI agents accessing MCP tools without loading full schemas into context
- Shell scripts automating MCP server interactions
- Discovering and exploring available MCP capabilities
Installation
Quick Install (Recommended)
curl -fsSL https://raw.githubusercontent.com/philschmid/mcp-cli/main/install.sh | bash
Manual Install (Requires Bun)
bun install -g https://github.com/philschmid/mcp-cli
Verify Installation
mcp-cli --version
Configuration
Config File Location
Create mcp_servers.json in one of these locations (searched in order):
- Path from
MCP_CONFIG_PATH environment variable
- Path from
-c/--config CLI argument
./mcp_servers.json (current directory)
~/.mcp_servers.json
~/.config/mcp/mcp_servers.json
Basic Config Format
Compatible with Claude Desktop, Gemini, and VS Code:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"."
]
},
"github": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-github"
],
"env": {
"GITHUB_TOKEN": "${GITHUB_TOKEN}"
}
},
"deepwiki": {
"url": "https://mcp.deepwiki.com/mcp"
}
}
}
Advanced Config Options
{
"mcpServers": {
"local-server": {
"command": "node",
"args": ["./server.js"],
"env": {
"API_KEY": "${API_KEY}"
},
"cwd": "/path/to/directory",
"allowedTools": ["read_*", "list_*"],
"disabledTools": ["delete_*"]
},
"remote-server": {
"url": "https://mcp.example.com",
"headers": {
"Authorization": "Bearer ${TOKEN}"
Environment Variable Substitution
Use ${VAR_NAME} syntax anywhere in config:
{
"mcpServers": {
"api-server": {
"command": "node",
"args": ["server.js"],
"env": {
"DATABASE_URL": "${DATABASE_URL}",
"API_KEY": "${API_KEY}"
}
}
}
}
Control behavior:
MCP_STRICT_ENV=true (default): Error on missing variables
MCP_STRICT_ENV=false: Use empty values with warning
Tool Filtering
Restrict available tools using glob patterns:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "."],
"allowedTools": ["read_file", "list_directory"],
"disabledTools": ["delete_file"]
}
}
}
Rules:
allowedTools: Whitelist (supports *, ? glob patterns)
disabledTools: Blacklist (takes precedence over allowedTools)
- Applies to all operations (info, grep, call)
Examples:
"allowedTools": ["read_*", "list_*", "search_*"]
"disabledTools": ["delete_*", "write_*", "create_*"]
"allowedTools": ["*file*"],
"disabledTools": ["delete_file"]
Core Commands
List All Servers and Tools
mcp-cli
mcp-cli -d
Output:
github
• search_repositories
• get_file_contents
• create_or_update_file
filesystem
• read_file
• write_file
• list_directory
Search Tools by Pattern
mcp-cli grep "*file*"
mcp-cli grep "*search*" -d
Output:
github/get_file_contents
github/create_or_update_file
filesystem/read_file
filesystem/write_file
View Server Details
mcp-cli info <server>
Example:
mcp-cli info github
Output:
Server: github
Transport: stdio
Command: npx -y @modelcontextprotocol/server-github
Tools (12):
search_repositories
Search for GitHub repositories
Parameters:
• query (string, required) - Search query
• page (number, optional) - Page number
...
View Tool Schema
Both formats work:
mcp-cli info <server> <tool>
mcp-cli info <server>/<tool>
Example:
mcp-cli info github search_repositories
Output:
Tool: search_repositories
Server: github
Description:
Search for GitHub repositories
Input Schema:
{
"type": "object",
"properties": {
"query": { "type": "string", "description": "Search query" },
"page": { "type": "number" }
},
"required": ["query"]
}
Call a Tool
mcp-cli call <server> <tool> '{"key": "value"}'
echo '{"path": "./file"}' | mcp-cli call <server> <tool>
mcp-cli call <server> <tool> <<EOF
{"content": "Text with 'quotes' and \"escapes\""}
EOF
Example:
mcp-cli call github search_repositories '{"query": "mcp server", "per_page": 5}'
Output (JSON):
{
"content": [
{
"type": "text",
"text": "{\"items\": [{\"name\": \"mcp-cli\", \"url\": \"...\"}]}"
}
]
}
Practical Usage Patterns
1. Discover → Inspect → Execute Workflow
mcp-cli
mcp-cli info filesystem
mcp-cli info filesystem read_file
mcp-cli call filesystem read_file '{"path": "./README.md"}'
2. Pipe JSON with jq
mcp-cli call github search_repositories '{"query": "mcp"}' | jq '.content[0].text'
mcp-cli call github search_repositories '{"query": "mcp"}' \
| jq -r '.content[0].text | fromjson | .items[].html_url'
mcp-cli call filesystem list_directory '{"path": "."}' \
| jq -r '.content[0].text | split("\n")[] | select(endswith(".md"))'
3. Chain Multiple MCP Calls
mcp-cli call filesystem search_files '{"path": "src/", "pattern": "*.ts"}' \
| jq -r '.content[0].text | split("\n")[0]' \
| xargs -I {} mcp-cli call filesystem read_file '{"path": "{}"}'
mcp-cli call filesystem search_files '{"path": ".", "pattern": "*.md"}' \
| jq -r '.content[0].text | split("\n")[]' \
| while read file; do
echo "=== $file ==="
mcp-cli call filesystem read_file "{\"path\": \"$file\"}" | jq -r '.content[0].text'
done
4. Error Handling in Scripts
mcp-cli call filesystem list_directory '{"path": "."}' \
| jq -e '.content[0].text | contains("README.md")' \
&& mcp-cli call filesystem read_file '{"path": "./README.md"}'
if result=$(mcp-cli call filesystem read_file '{"path": "./config.json"}' 2>/dev/null); then
echo "$result" | jq '.content[0].text | fromjson'
else
echo "File not found, using defaults"
fi
5. Save Output to File
mcp-cli call github get_file_contents '{"owner": "user", "repo": "project", "path": "src/main.ts"}' \
| jq -r '.content[0].text' > main.ts
6. Aggregate Results from Multiple Servers
{
mcp-cli call github search_repositories '{"query": "mcp", "per_page": 3}'
mcp-cli call filesystem list_directory '{"path": "./src"}'
} | jq -s '.'
7. Complex JSON Arguments
For JSON with special characters, use stdin to avoid shell escaping:
mcp-cli call server tool <<EOF
{
"content": "Text with 'single quotes' and \"double quotes\"",
"metadata": {
"nested": "value"
}
}
EOF
cat args.json | mcp-cli call server tool
jq -n '{query: "mcp", filters: ["active", "starred"]}' | mcp-cli call github search
Environment Variables
| Variable | Description | Default |
|---|
MCP_CONFIG_PATH | Path to config file | (none) |
MCP_DEBUG | Enable debug output | false |
MCP_TIMEOUT | Request timeout (seconds) | 1800 |
MCP_CONCURRENCY | Servers processed in parallel | 5 |
MCP_MAX_RETRIES | Retry attempts for transient errors | 3 |
MCP_RETRY_DELAY | Base retry delay (milliseconds) | 1000 |
MCP_STRICT_ENV | Error on missing ${VAR} in config | true |
MCP_NO_DAEMON | Disable connection caching | false |
MCP_DAEMON_TIMEOUT | Idle timeout for cached connections (seconds) | 60 |
Example:
export MCP_DEBUG=true
mcp-cli info github
export MCP_CONFIG_PATH=/path/to/config.json
mcp-cli
export MCP_NO_DAEMON=true
mcp-cli call server tool '{}'
CLI Options
| Option | Description |
|---|
-h, --help | Show help message |
-v, --version | Show version number |
-d, --with-descriptions | Include tool descriptions |
-c, --config <path> | Path to config file |
Example:
mcp-cli -d
mcp-cli -c ./my-config.json info github
mcp-cli --help
Common MCP Server Setups
Filesystem Server
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/path/to/directory"
],
"allowedTools": ["read_file", "list_directory", "search_files"],
"disabledTools": ["delete_file"]
}
}
}
Usage:
mcp-cli call filesystem read_file '{"path": "./README.md"}'
mcp-cli call filesystem list_directory '{"path": "."}'
GitHub Server
{
"mcpServers": {
"github": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-github"
],
"env": {
"GITHUB_TOKEN": "${GITHUB_TOKEN}"
}
}
}
}
Usage:
mcp-cli call github search_repositories '{"query": "mcp server"}'
mcp-cli call github get_file_contents '{"owner": "user", "repo": "repo", "path": "README.md"}'
HTTP Server
{
"mcpServers": {
"api": {
"url": "https://mcp.example.com",
"headers": {
"Authorization": "Bearer ${API_TOKEN}"
}
}
}
}
Usage:
mcp-cli info api
mcp-cli call api tool_name '{"param": "value"}'
Custom Local Server
{
"mcpServers": {
"custom": {
"command": "node",
"args": ["./my-server.js"],
"cwd": "/path/to/project",
"env": {
"PORT": "3000",
"API_KEY": "${API_KEY}"
}
}
}
}
Troubleshooting
Config File Not Found
Error:
Error: No MCP configuration found
Solution:
- Create
mcp_servers.json in current directory or ~/.config/mcp/
- Or set
MCP_CONFIG_PATH environment variable
- Or use
-c flag: mcp-cli -c /path/to/config.json
Server Not Starting
Error:
Error: Failed to connect to server 'github'
Solution:
- Check command is installed:
npx @modelcontextprotocol/server-github --version
- Verify environment variables are set
- Enable debug mode:
MCP_DEBUG=true mcp-cli info github
- Check server logs in stderr
Missing Environment Variable
Error:
Error: Environment variable GITHUB_TOKEN not found
Solution:
- Set the variable:
export GITHUB_TOKEN=your_token
- Or use
MCP_STRICT_ENV=false to allow empty values (not recommended)
Tool Not Found
Error:
Error: Tool 'invalid_tool' not found on server 'github'
Solution:
- List available tools:
mcp-cli info github
- Check for typos in tool name
- Verify tool isn't disabled in config (
disabledTools)
Tool Filtered Out
Error:
Error: Tool 'write_file' is disabled by configuration
Solution:
- Check config
allowedTools and disabledTools
- Update config to allow the tool
- Remove or modify filtering rules
JSON Parsing Error
Error:
Error: Invalid JSON arguments
Solution:
- Use stdin for complex JSON:
echo '{}' | mcp-cli call server tool
- Escape quotes properly:
'{"key": "value"}'
- Use heredoc for multi-line JSON
Connection Timeout
Error:
Error: Request timeout after 1800 seconds
Solution:
- Increase timeout:
export MCP_TIMEOUT=3600
- Check server responsiveness
- Disable daemon for fresh connection:
export MCP_NO_DAEMON=true
Permission Denied
Error:
Error: EACCES: permission denied
Solution:
- Check file permissions in
cwd directory
- Verify user has permission to execute command
- For filesystem server, ensure paths are accessible
AI Agent Integration
System Prompt Template
Add this to your AI agent's system prompt:
## MCP Servers
You have access to MCP servers via the `mcp-cli` CLI.
Commands:
- `mcp-cli info` - List all servers
- `mcp-cli info <server>` - Show server tools
- `mcp-cli info <server> <tool>` - Get tool schema
- `mcp-cli grep "<pattern>"` - Search tools
- `mcp-cli call <server> <tool> '{}'` - Call with JSON args
- `echo '{}' | mcp-cli call <server> <tool>` - Call from stdin
Workflow:
1. Discover: `mcp-cli info` to see available servers
2. Inspect: `mcp-cli info <server> <tool>` to get schema
3. Execute: `mcp-cli call <server> <tool> '{}'` with arguments
Use stdin for complex JSON to avoid shell escaping issues.
Token-Efficient Workflow
Instead of loading all tool schemas:
mcp-cli -d
mcp-cli
mcp-cli info github
mcp-cli info github search_repositories
mcp-cli call github search_repositories '{"query": "mcp"}'
Script Generation Example
AI can generate shell scripts combining multiple MCP calls:
#!/bin/bash
repos=$(mcp-cli call github search_repositories '{"query": "mcp server", "per_page": 5}')
urls=$(echo "$repos" | jq -r '.content[0].text | fromjson | .items[].html_url')
for url in $urls; do
owner=$(echo "$url" | cut -d'/' -f4)
repo=$(echo "$url" | cut -d'/' -f5)
echo "=== $owner/$repo ==="
mcp-cli call github get_file_contents "{\"owner\": \"$owner\", \"repo\": \"$repo\", \"path\": \"README.md\"}" \
| jq -r '.content[0].text'
done
Best Practices
- Use stdin for complex JSON - Avoid shell escaping issues
- Enable descriptions sparingly - Use
-d only when needed to save tokens
- Filter tools in config - Reduce attack surface and simplify discovery
- Set environment variables - Use
${VAR} substitution for secrets
- Pipe to jq - Process JSON output efficiently
- Check schemas first - Use
info before call to validate arguments
- Handle errors - Check exit codes and stderr in scripts
- Use connection pooling - Default daemon keeps connections warm
- Search before listing - Use
grep for specific tools instead of listing all