
Drive your Gorgias support inbox from the terminal — ticket triage, agent replies, customer lookup, and bulk operations across all 108 endpoints, plus a local SQLite mirror for instant search and analytics.
The helpdesk for e-commerce support teams. This CLI gives you (or an AI agent) full control over a Gorgias tenant from a single binary: list, create, update, and reply to tickets via tickets list / get / update / messages-create; sweep stuck work with stale and orphans; query locally with sync + sql for SQL-grade analytics the live API doesn't expose; full-text search across synced data with search; and a sibling gorgias-pp-mcp server that lets Claude Desktop, Cursor, or Claude Code drive the surface natively.
The MCP server runs in code-orchestration mode: ~15 tools (a gorgias_search + gorgias_execute gateway over all 108 endpoints, plus typed local-mirror surfaces). Measured tool descriptions + JSON schemas together total ~9K tokens for the full surface — vs. roughly 5× that if every endpoint shipped its own typed tool. See MCP.md for the protocol-level design.
Learn more at Gorgias.
Authentication
Gorgias uses HTTP Basic auth: your account email is the username, an API key is the password.
- In Gorgias: Settings → Account → REST API → Create API key. Copy the key once — Gorgias won't show it again.
- Set three environment variables:
export GORGIAS_USERNAME="account-email-placeholder"
export GORGIAS_API_KEY="<your-api-key>"
export GORGIAS_BASE_URL="https://<tenant>.gorgias.com/api"
- Verify with
gorgias-pp-cli doctor — Credentials: valid means the values authenticate against /account. Alternatively, gorgias-pp-cli auth set-token <email> <api-key> persists them to $XDG_CONFIG_HOME/gorgias-pp-cli/config.toml.
Quick Start
# 1. Confirm credentials authenticate against the live tenant.
gorgias-pp-cli doctor --json
# 2. Sync the last 7 days into the local SQLite mirror.
gorgias-pp-cli sync --resources tickets,customers,tags --since 7d --agent
# 3. Today's queue — open tickets, oldest first.
gorgias-pp-cli tickets list --view-id <view-id> --limit 20 --agent
# 4. Full-text search the synced mirror (FTS5).
gorgias-pp-cli search refund --agent
# 5. Pull the full message thread on a specific ticket.
gorgias-pp-cli tickets messages-list <ticket-id> --agent
# 6. Stale-ticket sweep — open tickets with no activity for 7+ days.
gorgias-pp-cli stale --days 7 --agent
# 7. Workload distribution across the team.
gorgias-pp-cli load --agent
Unique Features
These capabilities are designed for agent-driven work and don't exist in the Gorgias web app or in a raw curl-against-the-API workflow.
Local state that compounds
gorgias-pp-cli sync — Mirror Gorgias resources into local SQLite. Incremental by default (each resource records a cursor and resumes from there); --full clears the cursor; --since 7d constrains the window. For tickets, --since uses documented order_by=updated_datetime:desc plus a local cutoff because Gorgias does not expose a documented ticket datetime filter. Mirror lives at $XDG_DATA_HOME/gorgias-pp-cli/data.db.
gorgias-pp-cli search <query> — FTS5 full-text search across the local mirror. Subsecond against tens of thousands of tickets/customers/messages once synced.
gorgias-pp-cli sql "SELECT ..." — Read-only SQL escape hatch over the mirror. SELECT/WITH only; comment-prefix bypass gated. Answers analytical questions the Gorgias API doesn't expose (cohort, group-by, top-N, joins).
gorgias-pp-cli stale --days N — Tickets with no activity in N days. Sources from the local mirror; never hammers the API.
gorgias-pp-cli orphans — Tickets missing required fields (assignee, team, priority, tags). Pipeline-hygiene check for managers.
gorgias-pp-cli load — Ticket workload distribution per assignee. Sources from the local mirror.
Agent-native plumbing
gorgias-pp-cli doctor --json — Probes /account with configured credentials. Reports credentials: valid only when an authenticated call actually succeeds. Exits non-zero on failure by default so CI gates work as expected. Saves the first-five-minutes credential-debug cycle when wiring up an agent.
gorgias-pp-cli agent-context --json — Machine-readable descriptor of the CLI: commands, global flags, env vars, MCP surface, capability count. Let an agent introspect the CLI without parsing --help text.
gorgias-pp-cli which "<capability>" — Fuzzy match a natural-language capability to the best command. Curated index (35+ entries) ranked with stopword-aware scoring.
gorgias-pp-cli api — Browse all 108 endpoints with their HTTP method and path. Discovery for the long tail.
--deliver file:./out.json / --deliver webhook:https://... — Route command output to a file (atomic write) or POST it to a webhook. No piping or shell redirection required.
GORGIAS_AUTO_REFRESH_TTL=15m — Every read syncs first if the mirror is older than the TTL. Trust local without losing freshness.
gorgias-pp-cli profile save <name> — Capture the current non-default flags as a named profile reusable via --profile <name>. Cuts repetition for agents that always reach for --agent --view-id 123456789 --limit 50.
Code-orchestration MCP
The sibling gorgias-pp-mcp exposes two gateway tools (gorgias_search + gorgias_execute) covering all 108 endpoints, plus typed tools for the local-mirror capabilities (sync, search, sql, stale, orphans, load, tail, export, import) and the compound workflows. The full tool surface (description + JSON schemas) measures ~9K context tokens, vs. roughly 5× that if every endpoint shipped its own typed tool. See MCP.md.
Cookbook
# Open tickets in a saved view.
gorgias-pp-cli tickets list --view-id <view-id> --limit 50 --agent
# Customer record by email.
gorgias-pp-cli customers list --channel-type email --channel-address customer-lookup-placeholder --agent
# Apply a tag to a ticket (find the tag id first with `tags list`).
gorgias-pp-cli tickets update 12345 --tags '[{"id": 67890}]' --agent
# Reply to a ticket as a specific support agent. The from-address MUST match
# the dispatching integration's meta.address or the email won't actually send.
gorgias-pp-cli tickets messages-create 12345 --stdin --agent <<'JSON'
{"channel":"email","via":"email","from_agent":true,"public":true,
"sender":{"id":111111111},
"receiver":{"email":"customer-email-placeholder"},
"source":{"from":{"address":"support-address-placeholder"},
"to":[{"address":"customer-email-placeholder"}]},
"body_html":"<p>Hi …</p><p>Best,<br>Agent Name</p>",
"integration_id":22222}
JSON
# Stream live ticket changes (polling every 30s).
gorgias-pp-cli tail --resource tickets --interval 30s --agent
# Export the local mirror to JSONL for downstream tooling.
gorgias-pp-cli export --format jsonl --output tickets.jsonl tickets
# Save a named profile of global defaults, then opt in per-call.
gorgias-pp-cli profile save agent-defaults --agent --compact
gorgias-pp-cli --profile agent-defaults tickets list
Commands
Run gorgias-pp-cli --help for the full reference. Grouped here by use case:
Daily workflow
| Command | What it does |
|---|
tickets list | List tickets, scoped by view/customer/rule/external_id/ticket_ids |
tickets get <id> | Fetch one ticket (status, assignee, customer, tags) |
tickets update <id> | Change status, assignee, tags, priority |
tickets messages-create <id> | Post a reply or internal note |
customers list | Look up a customer by email or external id |
stale --days N | Tickets with no activity in N days |
orphans | Tickets missing assignee/team/priority/tags |
load | Workload per assignee |
Local mirror + analytics
| Command | What it does |
|---|
sync | Mirror API data to local SQLite |
search <query> | FTS5 full-text search over synced data |
sql "<query>" | Read-only SQL over the mirror |
analytics | Pre-built metrics over the mirror |
tail <resource> | Stream live changes by polling |
export | Dump a resource to JSON/CSV/JSONL |
import | Bulk-create from a JSON/CSV file |
Resources
account custom-fields customers events gorgias-jobs integrations macros messages phone pickups reporting rules satisfaction-surveys tags teams ticket-search tickets users views widgets — every resource has list, get, create, update, delete (where the Gorgias API exposes them). Run gorgias-pp-cli <resource> --help for the full list.
Utilities
| Command | What it does |
|---|
doctor | Health check: config + auth + API reachability |
auth setup / auth set-token / auth status | Credential management |
which "<capability>" | Fuzzy-match a capability to a command |
api | Browse all 108 endpoints by resource |
agent-context --json | Machine-readable CLI descriptor |
version | Print the CLI version (add --json for the envelope) |
Output formats
# Human-readable table (default in terminal, JSON when piped).
gorgias-pp-cli account get
# JSON for scripting and agents.
gorgias-pp-cli account get --json
# Filter to specific fields.
gorgias-pp-cli account get --json --select id,name,status
# Preview the request without sending.
gorgias-pp-cli account get --dry-run
# Agent mode: JSON + compact + no prompts + no color, in one flag.
gorgias-pp-cli account get --agent
Agent usage
Built for AI-agent consumption:
- Non-interactive — never prompts; every input is a flag.
- Pipeable —
--json to stdout, errors to stderr.
- Filterable —
--select id,name returns only the named fields.
- Previewable —
--dry-run shows the request without sending.
- Explicit retries —
--idempotent (creates), --ignore-missing (deletes).
- Confirmable —
--yes skips destructive-action prompts.
- Stdin-capable —
--stdin accepts a full JSON body for create/update commands.
- Offline-friendly — sync/search/sql work against the local mirror.
- No color by default —
--human-friendly opts in to color and tables.
Exit codes: 0 success, 2 usage error, 3 not found, 4 auth error, 5 API error, 7 rate limited, 10 config error.
Error envelope
Under --json (or --agent), failures emit a single JSON document on stderr:
{"error": {"message": "<human-readable cause>", "exit_code": <int>}}
Commands that already carry status in their own JSON body (e.g. doctor --json) embed the failure inside the report instead, so jq always sees a single JSON document per stream.
Claude Code
See SKILL.md for the Claude Code skill descriptor. Quick wiring:
claude mcp add gorgias gorgias-pp-mcp \
-e GORGIAS_USERNAME=<your-email> \
-e GORGIAS_API_KEY=<your-api-key> \
-e GORGIAS_BASE_URL=https://<tenant>.gorgias.com/api
Claude Desktop
Install gorgias-pp-mcp (see Install), then add it to your Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"gorgias": {
"command": "gorgias-pp-mcp",
"env": {
"GORGIAS_USERNAME": "<your-email>",
"GORGIAS_API_KEY": "<your-api-key>",
"GORGIAS_BASE_URL": "https://<tenant>.gorgias.com/api"
}
}
}
}
Restart Claude Desktop. The full config schema and secret-manager wrapper guidance is in MCP.md.
Cursor
See CURSOR.md.
Configuration
| Variable | Description |
|---|
GORGIAS_USERNAME | Your Gorgias account email; the username half of HTTP Basic auth. |
GORGIAS_API_KEY | Your Gorgias API key; the password half. Generated in Settings → Account → REST API. |
GORGIAS_BASE_URL | Your tenant's API URL, e.g. https://<tenant>.gorgias.com/api. Gorgias is multi-tenant — there is no default. |
GORGIAS_CONFIG | Override path to the TOML config file (default $XDG_CONFIG_HOME/gorgias-pp-cli/config.toml). |
GORGIAS_AUTO_REFRESH_TTL | When set, reads sync first if the local mirror is older than this duration (e.g. 15m). |
XDG paths are honored on Unix; on Windows the CLI falls back to os.UserConfigDir / os.UserCacheDir.
Troubleshooting
Authentication errors (exit 4) — run gorgias-pp-cli doctor. Verify env vars are set (printenv GORGIAS_USERNAME GORGIAS_API_KEY GORGIAS_BASE_URL).
404 Not Found on every command — GORGIAS_BASE_URL isn't picked up, or points at the wrong tenant. The doctor warns when the slug looks like app or your-company.
MCP server exposes ~15 tools but I expected one per endpoint — by design. Two of those tools (gorgias_search + gorgias_execute) are the gateway that reaches every Gorgias endpoint; the rest (context, search, sql, sync, analytics, orphans, stale, load, tail, export, import, workflow_archive, workflow_status) are typed surfaces for local-mirror queries and compound workflows. Call context for the live count + manifest.
search <query> returns nothing live — Gorgias's /search indexes customers/agents/tags/teams/integrations, not tickets or messages. For ticket text search, sync first: gorgias-pp-cli sync --resources tickets --since 30d && gorgias-pp-cli search <query> --data-source local.
sync --resources tickets --since 7d scans more pages than expected — Ticket --since is intentionally a local cutoff over documented order_by=updated_datetime:desc. Do not "fix" this by adding undocumented filters like updated_datetime__gte; a live test on May 23, 2026 returned HTTP 400 Unknown field for that parameter. If the API ever returns tickets out of newest-first order, the CLI emits a sync_warning and continues scanning/filtering locally rather than stopping early.
HTTP 400 "Must be at most 100" on a list — Gorgias caps --limit at 100. Paginate via --cursor <meta.next_cursor>.
HTTP 400 on customers list --language en --cursor ... — Gorgias rejects language/timezone filters when combined with cursor/limit/order-by. Drop the pagination flags or use --name/--email instead.
HTTP 400 on events list --object-type Ticket — Gorgias requires --object-id alongside --object-type.
Rate limited (exit 7) — slow down with --rate-limit 2 or fetch from the local mirror after sync.
Local data feels stale — set GORGIAS_AUTO_REFRESH_TTL=15m, or run gorgias-pp-cli sync --full to wipe and rebuild.
Gorgias API gotchas
Non-obvious behaviors of the Gorgias API itself that you'll hit if you exercise these endpoints directly:
POST /views requires slug, which is also marked DEPRECATED. The deprecation label means the field is on its way out, not that it's optional today — omit it and you get 400 "Missing data for required field". Pass any URL-safe string.
POST /views filter DSL only accepts a fixed allowlist of ticket.* paths, not arbitrary ticket.<anything>. Supported: assignee_team.id, assignee_user.id, customer.id, messages.integration_id, channel, language, status, priority, store_id, custom_fields, customer.custom_fields. Anything else returns 400 with the full list in the error.
POST /integrations with type: "http" requires http.url, http.method, http.request_content_type, and http.response_content_type. The docs treat http as an opaque object; these requirements are visible only in an example body.
POST /rules rejects the code field unless it matches Gorgias's internal AST grammar. Plain JavaScript is rejected even when syntactically complete. Pass code_ast (a pre-parsed AST) and confirm the shape with Gorgias support.
POST /tickets requires messages[0].source.from even when from_agent: true. Omitting it returns 400 "From field is missing or empty".
GET /tickets has no documented server-side updated-time cutoff. Use sync --resources tickets --since ... for local mirroring; it requests documented order_by=updated_datetime:desc and filters locally. Avoid updated_datetime__gte unless Gorgias documents it and a live smoke confirms it for the tenant.
DELETE /custom-fields/{id} returns 405. The Gorgias API has no path to delete custom fields. Archive via the admin UI; plan create-once-and-keep accordingly.
POST /tickets outbound dispatch fails silently if source.from.address doesn't match the integration's meta.address. The create returns 201 and the message is processed, but sent_datetime stays null and last_sending_error records "No integration was found to send this email." Always pair integration_id with a source.from.address that matches GET /integrations/{id}.meta.address. A 201 does not mean the email was delivered.
Known gaps
See KNOWN_GAPS.md for the long form. The short version: write endpoints have dry-run request-shape coverage and confirmation guards, but tenant-specific live validation should be run against a sandbox tenant before production mutation. Phone/voice endpoints haven't been exercised against a tenant with a voice integration.
Sources & inspiration
This CLI was scaffolded end-to-end by CLI Printing Press from the upstream Gorgias OpenAPI spec, then hardened across seven rounds of adversarial review focused on the patterns top-10% PP CLIs share: tenant-agnostic install, single-emission JSON error envelopes, XDG paths, dynamic MCP tool count, doctor exits non-zero on failure. The local-mirror design (sync + FTS5 + sql) mirrors what the Linear PP CLI pioneered for compounding agent context.
Generated by CLI Printing Press.