pipeline-gtm
v1.1.0
Published
Deterministic, zero-token CLI for Pipeline. Mirrors the hosted MCP server, but cron-safe, pipe-friendly, and exit-code-correct.
Downloads
393
Maintainers
Readme
Pipeline CLI
Deterministic, zero-token command-line interface for Pipeline — the AI GTM engineer.
Talk to it like a teammate (MCP). Bake it into your stack (API). Run it on cron at 3am (CLI).
This CLI is the third surface. It mirrors the same tools as the hosted MCP server at https://pipeline.help/api/mcp-server, but with no AI in the loop. Use it for cron jobs, CI pipelines, bash scripts, or anywhere you want predictable exit codes and zero token spend.
Why a CLI when there's already an MCP server and REST API?
| Surface | Customer | When to reach for it | |---|---|---| | REST API | Developers integrating Pipeline into their own backend | Embedding Pipeline inside another product. Language-agnostic. Server-to-server. | | MCP server | Anyone using an LLM agent (Claude Desktop, ChatGPT, Cursor) | Conversational, exploratory, real-time. The LLM picks the tool from intent. Burns tokens. | | CLI (this) | Operators in terminals, cron jobs, CI | Scheduled, deterministic, pipeable, scriptable. No LLM. Zero tokens. Cron-safe. |
Each surface owns a different time-and-context dimension. The CLI is what you use once your workflow is stable and you want to run it at 3am without watching it.
Install
npm install -g pipeline-gtmThe package is pipeline-gtm, but the binary is pipeline — typed dozens of times a day, kept short on purpose.
Quick start
pipeline initThis is the one-shot setup: it prompts for your API key, validates it against the MCP server, and caches the latest tool catalog locally. Get an API key from pipeline.help → Settings → API Keys.
After that:
pipeline help # browse all tools, grouped by category
pipeline list-campaigns --json # your first callUsing with Claude Code (or any LLM in your terminal)
This is the killer use case. You don't need to memorize 90 tool names — your LLM does that.
After pipeline init, just say to Claude Code:
"Use the pipeline CLI to find me 50 fintech founders raising Series A and start a campaign with my default template."
Claude reads the tool catalog with one command:
pipeline help --json…and figures out the right chain (search-people-database → create-campaign → start-campaign) and runs each as a Bash command. You see the results. No MCP setup, no token cost on the catalog, no integration work — just npm install and talk.
This is why the CLI complements the hosted MCP server rather than replacing it:
- Hosted MCP — you configure an MCP server connection in Claude Desktop / Cursor / Claude Code. Tokens burn on every tool call.
- CLI in Claude Code —
npm i -g pipeline-gtmonce, Claude shells out for free. Zero MCP plumbing.
For LLM-driven workflows, pipeline help --json is the discovery primitive: it emits the entire 90-tool surface (names, descriptions, JSON schemas, invocation patterns) in one machine-readable blob. Drop it into any agent's context and you're done.
Usage
Every tool on the hosted MCP server is available as a subcommand. Flags are derived directly from each tool's JSON input schema, so pipeline <tool> --help always reflects the current arguments.
List campaigns
pipeline list-campaigns --status active --limit 20Start a campaign
pipeline start-campaign --campaign-id cmp_01hf4...Add a prospect
pipeline add-prospect \
--campaign-id cmp_01hf4... \
--linkedin-url https://linkedin.com/in/jane-doe \
--first-name Jane \
--last-name DoeResearch a prospect
pipeline research-prospect --prospect-id pr_01... --jsonFetch campaign analytics
pipeline get-campaign-analytics --campaign-id cmp_01hf4... --jsonKick off a full outreach pipeline
For complex nested args, use the *-json flags or the run escape hatch:
pipeline zero-to-outreach \
--workspace-id ws_01... \
--mode signal \
--signal-json '{"type":"keyword","name":"fundraising","keywords":["Series A","raised"]}' \
--campaign-config-json '{"templateId":"tpl_default","name":"Funded founders","linkedinAccountIds":["li_01..."]}' \
--auto-startScripting recipes
CLI output is designed to pipe. Use --json for machine-readable, --csv for arrays.
Pause every active campaign on Friday at 5pm (cron)
# crontab: 0 17 * * 5
for id in $(pipeline list-campaigns --status active --json | jq -r '.[].id'); do
pipeline pause-campaign --campaign-id "$id"
doneNightly CSV export of high-intent prospects
# crontab: 0 2 * * *
pipeline list-prospects \
--campaign-id cmp_01... \
--min-icp-score 80 \
--csv > /backups/prospects-$(date +%Y%m%d).csvBulk stop campaigns whose reply rate dropped below 1%
pipeline list-campaigns --status active --json \
| jq -r '.[] | select(.replyRate < 0.01) | .id' \
| xargs -I {} pipeline pause-campaign --campaign-id {}CI guard: fail the build if a campaign has >5% bounce rate
bounce=$(pipeline get-campaign-analytics --campaign-id $CMP --json | jq -r '.bounceRate')
[ "$(echo "$bounce > 0.05" | bc)" -eq 1 ] && exit 1 || exit 0Commands
Sugar (hand-written)
| Command | What it does |
|---|---|
| pipeline init | First-run wizard: login + refresh tool catalog. |
| pipeline login [--api-key <k>] | Prompt for and validate an API key. |
| pipeline logout | Clear the stored API key. |
| pipeline whoami | Show masked API key, base URL, default workspace. |
| pipeline update | Refetch tools/list from the MCP server. |
| pipeline config list\|get <k>\|set <k> <v> | Manage config. Keys: apiKey, baseUrl, defaultWorkspace, format. |
| pipeline help [tool] | Grouped catalog of all tools, or inputSchema for one tool. |
| pipeline run <tool> <json> | Escape hatch: call any tool with raw JSON args. |
| pipeline import-prospects --campaign-id X --file leads.csv | Bulk-import prospects from a JSON or CSV file. Auto-chunks at 1000/request, reuses one prospect list across all chunks, dedupes against the workspace. Handles imports of any size. |
Dynamic
Every Pipeline MCP tool is exposed as pipeline <tool-name>. Browse them with:
pipeline helpEnvironment variables
| Variable | Purpose |
|---|---|
| PIPELINE_API_KEY | Override the stored API key. Useful for CI. |
| PIPELINE_BASE_URL | Override the MCP endpoint. Defaults to https://pipeline.help/api/mcp-server. |
| PIPELINE_TIMEOUT_MS | Request timeout in ms. Defaults to 30000. |
Output formats
- human (default) — table for arrays, key/value list for single objects. Booleans render as ✓/✗.
--json— raw JSON result from the tool.--csv— flat CSV (requires an array of objects).
Change the global default:
pipeline config set format jsonReliability
The CLI auto-retries on transient server errors (429, 502, 503, 504) and network failures with exponential backoff (up to 2 retries, 0.5s → 1s). Auth errors (401, 403) and tool-level errors fail immediately with a clear message.
Every request times out after 30 seconds (configurable via PIPELINE_TIMEOUT_MS).
Tool reliability tiers
All 90 tools are advertised, routable, and workspace-isolated. They split into two tiers based on how their server-side handler is implemented:
- UI-shared (~37 tools). Routed to the same
/api/...endpoints that power the Pipeline web app. Every customer interaction in the UI exercises this code daily, so behavior is well-trodden. Includes most write actions:create-campaign,start-campaign,add-prospects-bulk,send-message,publish-post,score-prospect, agent endpoints, analytics, and search. - MCP-only (~53 tools). Handled by a CLI/MCP-specific router. Less daily traffic than the UI-shared tier but actively used by the CLI itself. Includes most read-only listings:
list-campaigns,list-prospects,list-tables,list-signals,list-blocklist,list-drafts, etc.
To verify your install end-to-end against the live MCP, run the smoke test:
PIPELINE_API_KEY=pipeline_pk_... npm run smokeIt calls 18 read-only tools across both tiers and reports PASS/FAIL with timing. Use this as your "is the server healthy and is my key working" gate.
Exit codes
| Code | Meaning | |---|---| | 0 | Success | | 1 | User error (missing flag, unknown tool, bad JSON) | | 2 | API error (non-2xx, RPC error from server) | | 3 | Auth error (401/403) | | 4 | Network error |
Where credentials are stored
The API key is stored in plaintext at the conf default path:
- macOS:
~/Library/Preferences/pipeline-nodejs/config.json - Linux:
~/.config/pipeline-nodejs/config.json - Windows:
%APPDATA%\pipeline-nodejs\Config\config.json
This matches the convention used by gh, vercel, and most npm CLIs. If you'd rather not persist the key on disk, set PIPELINE_API_KEY in your shell environment instead — it overrides the stored value.
Development
npm install
npm run snapshot # regenerate src/tools.snapshot.json from dmand-v2
npm run verify-snapshot # check snapshot is in sync with source-of-truth
npm run build # compile + copy snapshot to dist/
node dist/index.js --helpThe bundled snapshot (src/tools.snapshot.json) ships with the package so the CLI works before the first pipeline update. At runtime the CLI merges it with ~/.pipeline/tools.json, the cache written by pipeline update. The newest catalog wins.
prepublishOnly runs snapshot + verify + build to guarantee no stale-snapshot ships ever again.
License
MIT — see LICENSE.
