Skip to main content

mcp-cli

Call any MCP server tool from the command line with shell composition support.

Install

# As a CLI tool (recommended)
pipx install mcp-cli-skill

# Or run directly without installing
uvx mcp-cli-skill --servers

# As a Claude Code skill
npx skills add wise-toddler/mcp-cli-skill -g

Usage

mcp-call --servers                              # list configured servers
mcp-call <server> --tools                       # discover tools (human-readable)
mcp-call <server> --discover                    # discover tools as JSON with schemas
mcp-call <server> <tool> --schema               # show tool's input schema as JSON
mcp-call <server> <tool> --key=value ...        # call a tool
mcp-call <server> <tool> --input-json '{"k":"v"}' # call with JSON args
echo '{}' | mcp-call <server> <tool>            # call with stdin JSON

Server Management

Config stored at ~/.mcp-cli/servers.json. On first run, auto-seeds from ~/.claude/settings.json and ~/.claude.json. Supports both stdio and HTTP MCP transports.

mcp-call --add myserver uvx some-mcp --env API_KEY=abc123
mcp-call --add-http myapi http://localhost:8010/mcp
mcp-call --remove myserver
mcp-call --sync    # re-sync from Claude configs

OAuth servers

HTTP servers that use MCP OAuth (dynamic client registration + PKCE) need a one-time browser login:

mcp-call --add-http emergent https://mcp.emergent.sh/
mcp-call --login emergent     # opens the browser; approve, then "Logged in to emergent."
mcp-call emergent --tools     # bearer token is sent and refreshed automatically
mcp-call --logout emergent    # forget the local tokens (no server-side revocation)

Multiple accounts on one server: add it under one name per account, and log in with --no-browser, which only prints the URL so you can open it in the browser profile signed in to that account (the default browser may silently approve as whoever is already signed in):

mcp-call --add-http emergent-work https://mcp.emergent.sh/
mcp-call --login emergent-work --no-browser

Tokens live in ~/.mcp-cli/tokens.json (mode 0600), bound to the server's URL. A call to a server that needs login exits with code 4 and says which --login to run. --login waits up to MCP_CALL_LOGIN_TIMEOUT seconds (default 300) for the browser; over SSH it prints the URL instead of opening a browser. A static Authorization header (--header) always wins over OAuth.

Shell completion

Tab completion suggests server names, tool names, and flag names.

One-time setup (required)

The shell needs to know how to ask mcp-call for completions. Same one-time eval pattern as gh, kubectl, aws:

# bash — add to ~/.bashrc
eval "$(mcp-call --completion bash)"

# zsh — add to ~/.zshrc
eval "$(mcp-call --completion zsh)"

# fish — write once
mcp-call --completion fish > ~/.config/fish/completions/mcp-call.fish

After this, mcp-call <TAB> immediately suggests server names (read live from ~/.mcp-cli/servers.json — no cache involved).

Tool-level completion (optional refresh)

mcp-call <server> <TAB> and mcp-call <server> <tool> --<TAB> read from a disk cache at ~/.mcp-cli/cache/tools-<server>.json. The cache exists because fetching a server's tool list takes 200ms–1s (subprocess spawn or HTTP roundtrip) — too slow for TAB.

The cache populates automatically whenever you run --tools, --discover, --help, or --schema. So tool completion "just works" for any server you've used.

For instant completion on every server up front:

mcp-call --refresh-completions   # walks every configured server, caches its tools
mcp-call --clear-cache [server]  # bust a stale entry, or all entries

Environment variables

${VAR} patterns in URLs, headers, command args, and env values are expanded at runtime:

{
  "myapi": {
    "type": "http",
    "url": "https://${API_HOST}/mcp",
    "headers": { "X-API-Key": "${MY_API_KEY}" }
  }
}

Why?

MCP tool calls can't use shell composition. This CLI lets agents (or you) use:

  • File content as args: --query="$(cat /tmp/query.sql)"
  • Pipe output: | jq '.results'
  • Shell variables: --name="$VAR"
  • Chaining: cmd1 && cmd2

Examples

mcp-call redash redash_query \
  --action=adhoc --query="$(cat /tmp/q.sql)" --data_source_id=1

mcp-call slack slack_chat \
  --action=post --channel=C123 --text="$(cat /tmp/msg.txt)"

mcp-call redash redash_query \
  --action=list --page_size=5 | jq '.results[].name'

Multi-tool workflow example

A bash script that an LLM agent can generate and run via its shell tool — querying a database, reading files, and posting to Slack, all orchestrated through mcp-call:

#!/bin/bash
# Agent-generated script: fetch github issues, read related files, post to slack

# 1. Fetch open bugs from github
mcp-call github list_issues \
  --owner=acme --repo=backend --state=open --labels=bug \
  | jq '.[] | {number, title}' > /tmp/bugs.json

# 2. Read the project README for context
mcp-call filesystem read_file \
  --path=/projects/backend/README.md > /tmp/readme.txt

# 3. Search for related error patterns in code
for title in $(jq -r '.[].title' /tmp/bugs.json | head -5); do
  mcp-call github search_code \
    --query="$title repo:acme/backend" \
    | jq '.items[:2]'
done > /tmp/code_matches.txt

# 4. Post summary to slack
mcp-call slack send_message \
  --channel="#engineering" \
  --text="*Open Bugs Summary*

$(jq length /tmp/bugs.json) open bugs:
$(jq -r '.[] | "• #\(.number): \(.title)"' /tmp/bugs.json)

Related code matches: /tmp/code_matches.txt"

The key insight: an LLM agent writes this script in one shot, runs it via its Bash/shell tool, and gets the result — no need to make 4+ separate MCP tool calls with inline data. The agent can read files, pipe between tools, and use shell logic that MCP tool calls alone can't do.

Requirements

  • Python 3.10+

How it works

Reads MCP server config from ~/.mcp-cli/servers.json (standalone, agent-agnostic). On first run, seeds from ~/.claude/settings.json and ~/.claude.json. For stdio servers, spawns the server as a subprocess and speaks JSON-RPC over stdin/stdout. For HTTP servers, sends JSON-RPC over HTTP with session ID tracking. Zero dependencies — pure Python stdlib.

Releasing

Bump __version__ in src/mcp_cli_skill/__init__.py, sync scripts/mcp_call.py, commit, then push a matching tag:

git tag v0.8.5 && git push origin v0.8.5

CI runs the tests, checks the tag matches __version__, and publishes to PyPI via Trusted Publishing (no token).

Metadata

Release files for mcp-cli-skill 0.8.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mcp-cli-skill 0.8.5
File Size Uploaded
mcp_cli_skill-0.8.5.tar.gz 46.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for mcp-cli-skill 0.8.5
File Interpreter ABI Platform
mcp_cli_skill-0.8.5-py3-none-any.whl Python 3 none any Details

Total release size: 68.5 kB

Release files / mcp_cli_skill-0.8.5.tar.gz

Download URL mcp_cli_skill-0.8.5.tar.gz
Size 46.4 kB
Tags Source
SHA-256 checksum
How to use checksums
7566c1c0f07152aad38ec7e44ebf4d5f1bb23f8f5ccf55fdfde30d30bf330e51
BLAKE2b-256 checksum
How to use checksums
30c2ef5ba2ca7fe64768ab52a7478297ab692ad3b70f940f5c237f2663019f17
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 9, 2026.

Transparency log

Release files / mcp_cli_skill-0.8.5-py3-none-any.whl

Download URL mcp_cli_skill-0.8.5-py3-none-any.whl
Size 22.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
43c3a39184224f98352f52e042cb63790788c5eb264bb6a5f1e3955543fec767
BLAKE2b-256 checksum
How to use checksums
2e7fc20b92dc562b3378a0381784ad805de9b14ad25f485f89f9038bdbb042a4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 9, 2026.

Transparency log

Release history Release notifications | RSS feed

0.12.0

2 release files

0.11.0

2 release files

0.10.0

2 release files

0.9.1

2 release files

0.9.0

2 release files

This release

0.8.5 This release

2 release files

0.8.4

2 release files

0.8.3

2 release files

0.8.2

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.3

2 release files

0.6.2

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.3

2 release files

0.5.2

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.9

2 release files

0.4.8

2 release files

0.4.7

2 release files

0.4.6

2 release files

0.4.5

2 release files

0.4.4

2 release files

0.4.3

1 release file

0.4.2

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page