Scripting
mcp automatically switches to JSON output when piped or redirected, making it easy to use in shell scripts, CI/CD pipelines, and automation. You can also force JSON with --json.
Basics
Output format detection
When piped (non-interactive), mcp outputs JSON by default. In interactive terminals, it shows human-readable tables. Use --json to force JSON in any context:
# These all produce JSON:
mcp sentry search_issues '{"query": "..."}' | jq '.' # piped → JSON
mcp sentry --list > tools.json # redirected → JSON
mcp sentry --list --json # explicit → JSONOutput goes to stdout
All tool results are JSON on stdout:
result=$(mcp sentry search_issues '{"query": "is:unresolved"}')
echo "$result" | jq '.content[0].text'Errors go to stderr
Errors and status messages go to stderr, so they don't pollute your data:
# This captures only the JSON, not auth messages or warnings
mcp sentry search_issues '{"query": "is:unresolved"}' > results.jsonExit codes
0— Success1— Error (connection failed, tool error, bad config, etc.)
Piping input
When no JSON argument is provided on the command line, mcp reads from stdin (if it's not a terminal):
If stdin is a terminal (interactive), mcp uses {} as the default argument. This is why mcp sentry --list works without any input.
Parsing with jq
Get tool names
Extract text content
Check for errors
Common patterns
Loop over results
Build arguments dynamically
Chain multiple servers
Cron job
CI/CD
GitHub Actions
Tips
Always quote JSON arguments — Shell metacharacters in JSON can cause issues
Use
jq -n— When building JSON arguments with variables,jq -nis safer than string interpolationRedirect stderr — Use
2>/dev/nullto suppress auth messages in scriptsSet
MCP_TIMEOUT— Increase for slow servers:MCP_TIMEOUT=120 mcp slack --listNon-interactive stdin — When piping or in cron, stdin is not a terminal, so
mcpreads from it. Pass{}explicitly if the tool needs no arguments:echo '{}' | mcp server tool
Last updated
Was this helpful?