CLI

Run any GTM Tools tool from the terminal

The gtm-tools CLI is a Commander.js binary that fronts every tool through a single bearer token. Install once, set GTM_TOOLS_API_KEY, and call any tool from the terminal.

Installation

Install with one command — no Node, no dependencies (just curl). It downloads a standalone binary into ~/.gtm-tools/bin:

$curl -fsSL https://api.gtm-tools.sh/cli/install.sh | bash

Then sign in — opens your browser, you log in via WorkOS, the success page closes itself, and you’re done:

$gtm-tools admin login

Credentials are saved to ~/.gtm-tools/config.json (chmod 600) so every subsequent call — and the browser extension via the native helper — picks them up automatically. No export needed, no code to copy. Run gtm-tools admin logout to clear them.

Headless / CI? Use the email + 6-digit code flow: gtm-tools admin auth you@yourcompany.com then … --code 123456.

Prefer npm? npm install -g gtm-tools also works (requires Node). To update the standalone binary, just re-run the curl … | bash command.

Command pattern

gtm-tools <namespace> <command> [args] [flags]
NamespaceWhat it covers
adminAuth + billing
socialsLinkedIn automation
emailEmail finding
signalsBuying-intent detectors
mcpPatch MCP server config into Claude Desktop / Cursor / Windsurf
extensionInstall / update the browser extension
updateUpdate the CLI itself in place (one command, no re-curl)

Global flags: --json (raw JSON output), --api-key <key> (override env var), --url <url> (override https://api.gtm-tools.sh).

admin

Auth, billing, and key management.

$# Sign in — opens your browser, success page auto-closes
$gtm-tools admin login
$
$# Sign out (clears ~/.gtm-tools/config.json; existing key keeps working server-side until revoked)
$gtm-tools admin logout
$
$# Balance + per-tool costs
$gtm-tools admin balance
$
$# Top up ($1 = 100 tokens, min $5)
$gtm-tools admin buy 25
$
$# Auto-reload — charge the saved card when balance dips
$gtm-tools admin auto-reload --enabled true --threshold 200 --reload-to 1000
$
$# Invoice history (default last 10)
$gtm-tools admin invoices --limit 25
$
$# Health check
$gtm-tools admin ping

Key management

Every admin login mints a fresh API key and (for safety) revokes any prior CLI-named keys for the workspace. Inspect or revoke other keys explicitly:

$# List all API keys for your workspace (id, name, obfuscated value)
$gtm-tools admin keys list
$
$# Revoke a specific key by id (find the id with 'keys list')
$gtm-tools admin keys revoke apikey_01...

The revoke endpoint includes a belongs-to check — a key can only revoke keys in its own workspace. Use this to clean up old MCP Access Key entries that get_api_key accumulates (it doesn’t auto-revoke, since those keys are often embedded in MCP configs / CI / webhooks).

Headless / CI auth (legacy)

For boxes that can’t open a browser, the email + 6-digit code flow still works:

$gtm-tools admin auth you@yourcompany.com # sends the code
$gtm-tools admin auth you@yourcompany.com --code 123456 # completes + saves

socials

LinkedIn automation. All commands either use a positional argument or named flags depending on the underlying tool.

Lookups

$# Domain → company URL (2 tokens)
$gtm-tools socials company-url siena.cx
$
$# Name + domain → profile URL (5 tokens)
$gtm-tools socials profile-url "Andrei Negrau" siena.cx
$
$# Get a LinkedIn profile by username — or by name + domain (2 tokens)
$gtm-tools socials profile --username rauchg
$gtm-tools socials profile --name "Andrei Negrau" --domain siena.cx --location "Bucharest"
$
$# Get a LinkedIn company by domain (1 token)
$gtm-tools socials company siena.cx

Posts and jobs

$# Single post (2 tokens)
$gtm-tools socials post https://www.linkedin.com/posts/...
$
$# Single job (2 tokens)
$gtm-tools socials job 4012345678
$
$# Recent posts from a profile (5 tokens)
$gtm-tools socials user-posts rauchg --limit 10
$
$# Open jobs at a company (5 tokens) — optional title filter
$gtm-tools socials jobs vercel.com --filter "(staff OR senior) NOT intern"
$
$# Recent posts from a company page (2 tokens)
$gtm-tools socials company-posts vercel
$
$# Recent posts from a company's employees (80 tokens)
>gtm-tools socials employee-posts vercel --max-employees 5 --days-back 7
>
># Reactions on a post (5 tokens)
>gtm-tools socials reactions https://www.linkedin.com/posts/... --count 25
>
># Comments on a post (5 tokens)
>gtm-tools socials comments https://www.linkedin.com/posts/... --sort RELEVANCE
>
># Saved posts on a connected account (10 tokens)
>gtm-tools socials saved-posts rauchg --limit 20

Employees

$# Verified employee list via Sales Navigator (30 tokens)
$gtm-tools socials employees gorgias.com \
> --filter "(CEO OR CTO OR Founder) NOT intern" \
> --limit 25 \
> --page 1
$
$# If you already have the LinkedIn numeric company ID, skip the domain lookup:
$gtm-tools socials employees gorgias.com --company-id 6402068
$
$# Cheaper SERP-only variant — same args, no Sales Navigator, slimmer payload (5 tokens)
$gtm-tools socials search-employees gorgias.com \
> --filter "(CEO OR CTO OR Founder) NOT intern" \
> --limit 25

Outreach

$# Send a DM (5 tokens)
$gtm-tools socials send-message \
> --from your-username \
> --to recipient-username \
> --text "Hey — saw your post on CX agents."
$
$# Send a connection invitation (5 tokens)
$gtm-tools socials invite \
> --from your-username \
> --to recipient-username \
> --message "Hi — short intro."
$
$# List recent conversations on a connected account (5 tokens)
$gtm-tools socials conversations your-username

Account management

$# List connected accounts (free)
$gtm-tools socials accounts

The LinkedIn session is shared via the browser extension — install it, press Connect, and stay logged into LinkedIn in that browser.

reddit

Reddit automation — read threads, post + comment, vote, DM via Reddit Chat. All write tools (and reddit post, which Reddit gates from cloud IPs) run on a pooled session from the browser extension.

$# List connected Reddit accounts (free)
$gtm-tools reddit accounts
$
$# Read a post and its full comment tree (1 token)
$gtm-tools reddit post "https://www.reddit.com/r/SaaS/comments/1abcde/some_slug/"
$
$# Reply to a post or comment — URL shape decides top-level vs threaded (5 tokens)
$gtm-tools reddit comment \
> --from arnaudjnn \
> --url "https://www.reddit.com/r/SaaS/comments/1abcde/some_slug/abc123/" \
> --body "Agreed — and the Tailscale piece is the real lock-in."
$
$# Submit a text post to a subreddit (5 tokens)
$gtm-tools reddit submit \
> --from arnaudjnn \
> --subreddit SaaS \
> --title "Reddit Chat is built on Matrix" \
> --body "Found this while wiring up our agent's Reddit tools."
$
$# Submit a link post
$gtm-tools reddit submit \
> --from arnaudjnn \
> --subreddit SaaS \
> --title "GTM Tools Reddit reference" \
> --link-url "https://gtm-tools.sh/documentation/core-concepts/reddit-tools"
$
$# Upvote / downvote / clear (1 token)
$gtm-tools reddit vote \
> --from arnaudjnn \
> --url "https://www.reddit.com/r/SaaS/comments/1abcde/some_slug/abc123/" \
> --direction up
$
$# Read the inbox — peek without marking read (1 token)
$gtm-tools reddit inbox arnaudjnn --filter comment_replies --limit 20
$
$# DM via Reddit Chat — works for every account (5 tokens)
$gtm-tools reddit send-message \
> --from arnaudjnn --to SienaCX \
> --text "Hey — saw your post on agent gateways. Worth a chat?"

Discovery

$# Search posts by keyword (2 tokens) — optionally restricted to a subreddit
$gtm-tools reddit search "matrix self hosted" --subreddit selfhosted --sort relevance --time month --limit 25
$
$# Daily monitoring scan — `rising` finds threads with momentum (1 token)
$gtm-tools reddit posts selfhosted --sort rising --limit 25
$
$# Shortlist subreddits (1 token)
$gtm-tools reddit search-subreddits "agent automation" --limit 25
$
$# Compliance gate — ALWAYS call before posting in a new subreddit (1 token)
$gtm-tools reddit subreddit-about selfhosted

Evaluate

$# Credibility: karma, account age, verified email (1 token)
$gtm-tools reddit user rlnerd
$
$# Posting history — is this user your ICP? (1 token)
$gtm-tools reddit user-posts rlnerd --type overview --limit 25

Follow up

$# Follow a post for new-comment notifications (1 token)
$gtm-tools reddit follow --from arnaudjnn --url "https://www.reddit.com/r/.../"
$
$# Save with a CRM-style category (1 token)
$gtm-tools reddit save \
> --from arnaudjnn \
> --url "https://www.reddit.com/r/.../" \
> --category "p0-reply"
$
$# Read the engagement queue (1 token)
$gtm-tools reddit saved arnaudjnn --limit 50

Organize

$# Bulk subscribe (1 token)
$gtm-tools reddit subscribe selfhosted privacy Matrix HomeNetworking --from arnaudjnn
$
$# Audit current subscriptions (1 token)
$gtm-tools reddit subscriptions arnaudjnn --limit 100
$
$# List your custom feeds (multireddits) (1 token)
$gtm-tools reddit feeds arnaudjnn
$
$# Create a monitoring feed (5 tokens)
$gtm-tools reddit create-feed \
> --from arnaudjnn \
> --name selfhost_infra \
> --subreddits "selfhosted,homelab,Matrix,privacy" \
> --description "Self-hosted infra monitoring"
$
$# Read the merged stream (1 token)
$gtm-tools reddit feed-posts --from arnaudjnn --name selfhost_infra --sort rising --limit 50

Pair this with the Results Ranking Optimization guide — it covers the should-I-reply gate, anti-AI-spam style rules, and the engagement-queue pattern.

email

SMTP-verified email finding.

$gtm-tools email find --name "Justin Mares" --domain kettleandfire.com

signals

Buying-intent detection.

$# Run every detector at once (free dispatch + 5 per detector that fires)
$gtm-tools signals detect gymshark.com
$
$# Individual detectors (5 tokens each)
$gtm-tools signals socials-spike gymshark.com
$gtm-tools signals hiring gymshark.com --role "(cx OR support) NOT intern"
$gtm-tools signals hiring-support gymshark.com
$gtm-tools signals hiring-sales-rep gymshark.com
$gtm-tools signals hiring-sales-leadership gymshark.com
$gtm-tools signals hiring-sales-rep-repost gymshark.com
$gtm-tools signals trustpilot-negative mammaly.de
$gtm-tools signals trustpilot-negative-support mammaly.de
$gtm-tools signals trustpilot-positive gymshark.com
$gtm-tools signals technologies siena.cx --techs zendesk.com,intercom.com
$
$# Configure detector order
$gtm-tools signals get-order
$gtm-tools signals set-order \
> --signals "signal_hiring_sales_rep_repost,signal_trustpilot_negative_support_reviews,signal_socials_spike"

mcp

Patch the GTM Tools MCP server into a client config.

$gtm-tools mcp add --client claude-desktop # or cursor / windsurf
$gtm-tools mcp add --client cursor --with-api-key sk_... # skip OAuth
$gtm-tools mcp add --client cursor --name gtm --url https://api.gtm-tools.sh/mcp

Without --with-api-key, the client opens a browser to authenticate via OAuth on first use.

extension

Install or update the browser extension (required by get_email and the LinkedIn write/personal tools). It writes to a stable folder, ~/GTM Tools/extension, so you Load-unpacked once and every update reuses the same path.

$# Download/update the extension into ~/GTM Tools/extension
$gtm-tools extension install
$
$# Custom location
$gtm-tools extension install --dir /path/to/extension
$
$# Print the install path
$gtm-tools extension path

Re-run gtm-tools extension install to update, then reload the extension in chrome://extensions. (This is the same download as the standalone extension/install.sh installer.)

To update: npm install -g gtm-tools@latest, re-run gtm-tools extension install, then click the reload icon on the extension in chrome://extensions.

update

The CLI updates itself in place — no need to re-run the curl installer when a new version ships.

$gtm-tools update

Every command also kicks off a background version check (cached 6 hours, 1.5s timeout); if the server’s version is newer than your binary you’ll see a one- line notice on stderr after the command finishes:

[ gtm-tools update available: v0.3.0 → v0.4.0 — run 'gtm-tools update' ]

The update mechanism only swaps the standalone binary (the curl-installed one in ~/.gtm-tools/bin/). If you installed via npm, use npm install -g gtm-tools@latest.

Using with jq

The CLI defaults to JSON, so it pipes cleanly into jq:

$# Get just the LinkedIn URL
$gtm-tools socials company-url siena.cx | jq -r '.url'
$
$# Pull email addresses for a small list of employees
$gtm-tools socials employees vercel.com --limit 5 | \
> jq -r '.results[].name' | \
> while read name; do
$ gtm-tools email find --name "$name" --domain vercel.com | jq -r '.email'
$ done

Scripting example

$#!/bin/bash
$# Detect signals across a list of target domains.
$
$DOMAINS=(gymshark.com mammaly.de kettleandfire.com)
$
$for domain in "${DOMAINS[@]}"; do
$ echo "=== $domain ==="
$ gtm-tools signals detect "$domain" | \
> jq '.signals[] | select(.fired == true) | {name, evidence: (.evidence // []) | length}'
$ echo
$done

Next steps