Skip to content

agentproc CLI

The agentproc command-line tool is the canonical bridge-side runner. It reads a profile YAML, spawns the configured agent process, parses stdout per the protocol spec, and prints the reply. Any conformant agent — from hub profiles to your own — can be driven through this single entry point.

The CLI ships in the same npm package as the Node SDK:

bash
npm install -g agentproc       # global install
# or:
npx agentproc ...              # run without installing

Two ways to invoke

The CLI supports two equivalent entry points:

Entry pointWhen to use
agentproc hub <subcommand>Recommended. Run a profile from the official hub with zero local files. The CLI fetches from GitHub on first use, caches at ~/.agentproc/cache/hub/<name>/ (24h TTL), and defaults the agent's cwd to your current directory.
agentproc --profile <path>Run a profile YAML you already have locally (your own, an installed hub profile, or a repo checkout). Pass --cwd to control where the agent runs.

Quick start

bash
# Smoke test, no API key, no clone:
agentproc hub run echo-agent -p "hello"
# → You said: hello

# Real agent against your project:
cd ~/projects/my-app
agentproc hub run claude-code -p "explain this codebase" --env ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY

For local profiles (no hub fetch):

bash
git clone https://github.com/jeffkit/agentproc
cd agentproc

# echo-agent (uses {{PROFILE_DIR}} so cwd doesn't matter)
agentproc --profile hub/echo-agent/profile.yaml --prompt "hello"

# claude-code — point --cwd at your project so claude works on it
agentproc --profile hub/claude-code/profile.yaml \
          --prompt "explain this codebase" \
          --cwd /path/to/your/project \
          --env ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY

GITHUB_TOKEN raises the rate limit

Anonymous hub fetches are capped at ~60/hour. Raise to 5,000/hour with:

bash
export GITHUB_TOKEN=$(gh auth token)   # or any personal access token

If you'd rather skip the network entirely, use agentproc --profile ./hub/<name>/profile.yaml ... against a local checkout.

Hub subcommands

CommandPurpose
agentproc hub listList all profiles in the hub
agentproc hub show <name>Show a profile's README
agentproc hub run <name> [opts]Fetch (if needed) and run a profile
agentproc hub install <name>Copy a profile to ./<name>/ for local editing

hub run accepts the same runner flags as --profile (see below), with one convenience: if you don't pass --cwd, it defaults to your current directory (so the wrapped CLI operates on whatever project you're in).

Add --refresh to any hub command to force re-fetch from GitHub.

Usage

agentproc --profile <path.yaml> --prompt "hello" [options]

Required (for --profile mode)

FlagDescription
--profile, -p <path>Profile YAML path
--prompt <text>User message (or use --stdin)

About -p

In --profile mode, -p is the short form of --profile. In hub run mode, since the profile is identified by name (positional, not a path), -p is reused as the short form of --prompt instead. This is the only flag whose short form changes between modes — when in doubt, use the long form.

Session

FlagDescription
--session <id>Previous session id for multi-turn continuity
--session-name <name>Human-readable session name (default: default)
--from <user>Sender identifier

Execution

FlagDescription
--cwd <path>Override profile.cwd. Relative paths resolve against the profile's directory. In hub run, defaults to your current directory.
--env KEY=VALUEExtra env var (repeatable)
--timeout <secs>Override profile.timeout_secs
--no-streamDisable streaming (ignore {"type":"partial"} events)

Output

FlagDescription
--verboseForward protocol lines to stderr (default)
--quietSuppress protocol lines on stderr
--rawDon't parse stdout; forward agent output verbatim
--stdinRead prompt from stdin instead of --prompt

Other

FlagDescription
--versionPrint version and exit
--help, -hShow help

Output semantics

Default mode

StreamContent
stderrNDJSON events ({"type":"partial"}, {"type":"result"}, {"type":"error"}; optional session_id on events) in real time
stdoutFinal reply body (from {"type":"result"} / streaming partials), printed after the agent exits
exit0 success · 1 error · 124 timeout (per spec)

The final session id is also printed on stderr as agentproc:session:<id>, so shell scripts can capture it:

bash
output=$(agentproc -p prof.yaml --prompt "hi" 2>/tmp/err.log)
session=$(grep '^agentproc:session:' /tmp/err.log | cut -d: -f3)
agentproc -p prof.yaml --prompt "follow up" --session "$session"

--raw mode

Don't parse stdout at all — forward the agent's stdout verbatim. Useful for piping the agent's raw output to another tool, or for debugging bridge scripts in isolation.

bash
agentproc -p prof.yaml --prompt "hi" --raw | some-other-tool

Examples

Multi-turn with claude-code

bash
# First turn — capture the session id
agentproc -p hub/claude-code/profile.yaml \
          --prompt "what is this codebase?" \
          --cwd ~/projects/myapp \
          --env ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" \
          2>/tmp/err.log
session=$(grep '^agentproc:session:' /tmp/err.log | cut -d: -f3)

# Second turn — continue the session
agentproc -p hub/claude-code/profile.yaml \
          --prompt "tell me more about the auth module" \
          --cwd ~/projects/myapp \
          --env ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" \
          --session "$session"

Prompt from stdin

bash
echo "what files are in this directory?" | \
  agentproc -p hub/claude-code/profile.yaml --cwd . --stdin

Quiet mode (clean stdout for piping)

bash
agentproc -p hub/claude-code/profile.yaml --prompt "summarize" --quiet | jq .

How it implements the spec

The CLI is a thin wrapper over the SDK's run() function in sdk/node/src/runner.js. That module is the canonical reference implementation of the AgentProc bridge-side contract:

  • Profile parsing: accepts both top-level form (command: at root) and hub form (command: nested under agentproc:).
  • Placeholder substitution: , , in command, args, cwd, and env values — no shell involved. is not a placeholder; the message travels via stdin.
  • Relative cwd: when cwd is a relative path and is known (i.e. the CLI was invoked with a profile path), it resolves against the profile's directory rather than the process cwd.
  • Turn input (stdin): writes one {"type":"turn",...} NDJSON line to the agent's stdin (message, session_id, session_name, attachments, permission, protocol_version), then EOF — unless permission: true, in which case stdin stays open for {"type":"permission_response"} frames. The per-turn request does not travel in env vars.
  • Env injection: the profile env block (with ${VAR} expansion gated by env_allowlist) plus a fixed infra set (PATH/HOME/TERM/…). --env KEY=VALUE adds per-run extras.
  • stdout classification: each line is a JSON object dispatched on type{"type":"partial"} (forwarded when streaming: true), {"type":"result"} (terminal reply body; optional session_id / usage), {"type":"error"} (fails the turn). session_id is a field on events (first non-empty persisted; early omit OK; SHOULD attach once known). Non-JSON / unknown type lines are logged and ignored.
  • Timeout handling: SIGTERM → kill_grace_secs (default 5s) → SIGKILL. Exit code 124.
  • Exit codes: 0 success · 1 error (including when {"type":"error"} was emitted) · 124 timeout.

If you're writing your own bridge in another language, runner.js is the spec in code form.

Released under the MIT License.