Script around mcpal

How to drive mcpal from scripts, shells, and CI. Covers exit codes, machine output, JMESPath filtering, the raw escape hatch, env vars, and a sample GitHub Actions step.

Contract:

  • stdout is data. Informational output goes to stderr.
  • Exit codes are stable per failure class; the wording around them is not.
  • --output json and --query <jmespath> remove most uses of jq.

Exit codes

CodeMeaningError code(s)Common fix
0success
1generic errorE0000check stderr
2usage / invalid argumentsE0002, E0009, E0010mcpal <subcommand> --help
3server reference not foundE0001mcpal server discover
4auth requiredE0003mcpal auth login <ref>
5auth expiredE0004mcpal auth refresh <ref>
6transport / not yet supportedE0005, E0008network unreachable or mcpal raw
7server returned a JSON-RPC errorE0006check args against tool describe
8request timed outE0007retry; with --timeout, raise the value
130interrupted (Ctrl-C)E0011

Each error prints error[E####]: plus hints. mcpal debug explain E#### shows the long form.

--output json

mcpal --output json tool list <ref> | jq -r '.[].name'
mcpal --output json server ping <ref> | jq -r '.peerInfo.serverInfo.version'

YAML is the default for human reading. Set --output json in pipelines.

--query (JMESPath)

For one-liners:

mcpal --query 'content[0].text' tool call ev echo --message hi
mcpal --query '[].name' tool list ev
mcpal --query 'peerInfo.serverInfo.{name:name,version:version}' server ping ev

Standard JMESPath. Tutorial.

Reading args from stdin or files

tool call accepts:

  • --key value flags — typed JSON values (numbers, booleans, JSON literals).
  • --cli-input-json @path/to.json — read a base object from a file.
  • --cli-input-json - — read from stdin.
  • Mix: base from file or stdin, override with --key value.
echo '{"a":1,"b":2}' | mcpal tool call ev some --cli-input-json - --b 99

raw for unmapped methods

mcpal raw <ref> some/method --params '{"k":"v"}'
mcpal raw <ref> some/method --params @payload.json
mcpal raw <ref> some/method --params -

With --query and --output:

mcpal --query 'tools[].name' --output json raw <ref> tools/list

watch

mcpal watch <ref>

One YAML doc per notification (progress, log, resource-updated, list-changed). Run alongside another terminal that drives requests.

Env vars

VarEffect
MCPAL_CONFIGpath to config.toml
MCPAL_PROFILEaccepted but unused (will gate profile selection later)
MCPAL_BEARERone-shot bearer for any HTTP server
MCPAL_SAMPLING_HANDLERshell command for sampling/createMessage
MCPAL_CHILD_STDERR=inheritun-silence the spawned stdio server's stderr
RUST_LOGtracing filter (e.g. info,mcpal=debug)

GitHub Actions

- run: cargo install --path crates/mcpal
- run: |
    mcpal server add api --http $MCP_URL
    mcpal debug doctor --output json
    mcpal --output json tool list api > tools.json
  env:
    MCPAL_BEARER: ${{ secrets.MCP_TOKEN }}
    MCPAL_CONFIG: ${{ runner.temp }}/mcpal.toml

Don't

  • Parse human stderr. mcpal's wording changes; the exit code and the error[E####] prefix don't.
  • Rely on TTY colors in scripts. mcpal already disables ANSI on non-TTY stdout.
  • Rely on argument order beyond positionals. Use --key value throughout.