Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

mcpcaller

A stateless CLI that turns any MCP server into a native shell experience. Every tool becomes a command with typed flags, auto-discovered help, OAuth handled automatically, and zero JSON-by-hand.

Install

uv tool install mcpcaller
# or
pipx install mcpcaller

Quick start

Add a stdio server (the official filesystem server is a good first target):

mcpcaller add fs -- npx -y @modelcontextprotocol/server-filesystem ~

Add a remote HTTP server. If it requires OAuth, your browser opens once and the token is saved in your OS keychain:

mcpcaller add prod https://mcp.example.com

For headless/CI environments, pass an API token as a static header instead:

mcpcaller add prod https://mcp.example.com --header "Authorization=Bearer $API_TOKEN"

Or use the device-code grant when there's no browser available:

mcpcaller add prod https://mcp.example.com --device-code

List what's available, then call a tool:

mcpcaller tools                          # all tools on the current server
mcpcaller describe read_file             # full schema for one tool
mcpcaller read_file --path ~/notes.md

Resources and prompts are first-class:

mcpcaller resources
mcpcaller read file:///etc/hosts

mcpcaller prompts
mcpcaller prompt summarise --doc file:///etc/hosts

Calling tools

Each tool's inputSchema becomes typed flags automatically. Examples (against a hypothetical issue tracker):

mcpcaller search_issues --query "bug" --status open --limit 20
mcpcaller search_issues --tags backend --tags urgent          # repeated arrays
mcpcaller search_issues --tags backend,urgent                  # comma-split arrays
mcpcaller create_issue --title "x" --filter__env prod          # nested objects via __
mcpcaller create_issue --filter '{"env":"prod","sev":"high"}'  # JSON escape hatch

# Read the value from a file (@-) or stdin (@-)
mcpcaller ingest --body @payload.json
echo '{"a":1}' | mcpcaller ingest --body @-

Run any tool with --help to see its schema-derived flag list:

mcpcaller search_issues --help

Selecting a server

In order of precedence:

  1. Explicit positional: mcpcaller prod search_issues ...
  2. --server flag: mcpcaller search_issues --server prod ...
  3. MCPCALLER_SERVER env var (handy in CI)
  4. The current server (mcpcaller use <name> to switch)

Run mcpcaller help selection for the long version, including how the positional-vs-tool collision rule works.

Output

  • Default: human-readable, status messages on stderr, data on stdout (so pipes work).
  • --json emits the raw tools/call / resources/read / prompts/get result.
  • --raw emits only the first text content block, no framing.
  • --quiet / -q suppresses spinners and status lines.
  • --verbose / -v shows wire-level JSON-RPC for debugging.
  • --no-color disables ANSI colour output (also honours NO_COLOR).

Exit codes

Code Meaning
0 success
1 tool returned isError: true
2 usage error (bad flag, missing required)
3 auth error (token invalid, refresh failed)
4 transport error (server unreachable, schema lock contention)
5 schema mismatch after refresh
≥64 server-defined error mapped from JSON-RPC code

Auth

OAuth 2.1 with discovery, Dynamic Client Registration, and PKCE. mcpcaller add runs the whole flow if it sees a 401 on the first probe; if you skip it with --no-login, the next call that returns 401 triggers it lazily. Tokens live in the OS keychain (macOS Keychain / libsecret on Linux / Windows Credential Manager) with a chmod-600 file fallback for headless setups.

mcpcaller login <name>           # re-run OAuth (e.g. for a scope change)
mcpcaller logout <name>          # wipe tokens
mcpcaller refresh-token <name>   # force a refresh (debugging)

In CI, set MCPCALLER_TOKEN_<NAME>=<token> to bypass the keychain entirely. (The suffix is the server name uppercased with - replaced by _.)

mcpcaller help auth covers the full set of auth modes; mcpcaller help transports covers stdio vs HTTP vs SSE.

Inspecting servers

mcpcaller servers                    # what's configured
mcpcaller current                    # which one is the default
mcpcaller use <name>                 # switch the default
mcpcaller status                     # auth + schema state per server
mcpcaller refresh                    # re-fetch schema cache for the current server
mcpcaller refresh --all              # re-fetch everything
mcpcaller search <pattern>           # grep across tool/resource/prompt names + descriptions

Scripting

# Pipe JSON results through jq:
mcpcaller search_issues --query "bug" --json | jq '.content[0].text'

# Use --raw when you want only the text payload:
mcpcaller get_token --raw | pbcopy

# Pin a server in CI:
MCPCALLER_SERVER=prod mcpcaller list_jobs --json

Develop

uv sync
uv run pytest
uv run ruff check src/ tests/
uv run ruff format src/ tests/

Shell completion:

mcpcaller completion bash    # or zsh / fish / powershell

About

No description, website, or topics provided.

Resources

Security policy

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages