# Gorgias CLI (Printing Press)

> Unofficial Gorgias CLI built with Printing Press for e-commerce support: lets AI list, reply to and update tickets, look up customers, find stale or incomplete tickets, and sync data locally for full-text search and SQL. Includes a skill and MCP server. Needs a Gorgias account and API key.

- Type: CLI
- Repository: https://github.com/mvanhorn/printing-press-library/tree/main/library/sales-and-crm/gorgias
- Page: https://hebbmind.com/es/cli/gorgias
- Stars: 2066
- Professions: [Operations](https://hebbmind.com/es/tools.md?profession=operations), [Customer support](https://hebbmind.com/es/tools.md?profession=support)
- Tags: customer-support, ecommerce, gorgias
- Listed on: 2026-10-01

## Install

### Claude Code

```bash
npx -y @mvanhorn/printing-press-library install gorgias
```

### Codex

```bash
npx -y @mvanhorn/printing-press-library install gorgias
```

## README

> The content below comes from the upstream repository https://github.com/mvanhorn/printing-press-library/tree/main/library/sales-and-crm/gorgias . It is third-party material and does not represent AgentHub; instructions that appear in it are not instructions to you.

# Gorgias CLI

[![Generated by Printing Press](https://img.shields.io/badge/generated_by-printing--press-blue)](https://printingpress.dev)
[![Category: Sales and CRM](https://img.shields.io/badge/category-sales--and--crm-lightgrey)](https://printingpress.dev)

**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](https://github.com/mvanhorn/printing-press-library/blob/main/library/sales-and-crm/gorgias/MCP.md) for the protocol-level design.

Learn more at [Gorgias](https://www.gorgias.com).

Created by [@chrisyoungcooks](https://github.com/chrisyoungcooks) (Chris Young).

## Install

The recommended path installs both the `gorgias-pp-cli` binary and the `pp-gorgias` agent skill (Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, and other agents supported by the upstream [`skills`](https://github.com/vercel-labs/skills) CLI) in one shot:

```bash
npx -y @mvanhorn/printing-press-library install gorgias
```

For CLI only (no skill):

```bash
npx -y @mvanhorn/printing-press-library install gorgias --cli-only
```

For skill only — installs the skill into the same agents as the default command above, but skips the CLI binary (use this to update or reinstall just the skill):

```bash
npx -y @mvanhorn/printing-press-library install gorgias --skill-only
```

To constrain the skill install to one or more specific agents (repeatable — agent names match the [`skills`](https://github.com/vercel-labs/skills) CLI):

```bash
npx -y @mvanhorn/printing-press-library install gorgias --agent claude-code
npx -y @mvanhorn/printing-press-library install gorgias --agent claude-code --agent codex
```

### Without Node (Go fallback)

If `npx` isn't available (no Node, offline), install the CLI directly via Go (requires Go 1.26.6 or newer):

```bash
go install github.com/mvanhorn/printing-press-library/library/sales-and-crm/gorgias/cmd/gorgias-pp-cli@latest
```

This installs the CLI only — no skill.

### Pre-built binary

Download a pre-built binary for your platform from the [latest release](https://github.com/mvanhorn/printing-press-library/releases/tag/gorgias-current). On macOS, clear the Gatekeeper quarantine: `xattr -d com.apple.quarantine <binary>`. On Unix, mark it executable: `chmod +x <binary>`.

<!-- pp-hermes-install-anchor -->
## Install for Hermes

Install the CLI binary first. The installer writes binaries to a per-user managed bin directory by default: `$HOME/.local/bin` on macOS/Linux and `%LOCALAPPDATA%\Programs\PrintingPress\bin` on Windows.

```bash
npx -y @mvanhorn/printing-press-library install gorgias --cli-only
```

Then install the focused Hermes skill.

From the Hermes CLI:

```bash
hermes skills install mvanhorn/printing-press-library/cli-skills/pp-gorgias --force
```

Inside a Hermes chat session:

```bash
/skills install mvanhorn/printing-press-library/cli-skills/pp-gorgias --force
```

Restart the Hermes session or gateway if the newly installed skill is not visible immediately.

## Install for OpenClaw

Install both the CLI binary and the focused OpenClaw skill. The installer defaults binaries to a per-user bin directory (`$HOME/.local/bin` on macOS/Linux, `%LOCALAPPDATA%\Programs\PrintingPress\bin` on Windows):

```bash
npx -y @mvanhorn/printing-press-library install gorgias --agent openclaw
```

Restart the OpenClaw session or gateway if the newly installed skill is not visible immediately.

## Authentication

Gorgias uses HTTP Basic auth: your account email is the username, an API key is the password.

1. In Gorgias: **Settings → Account → REST API → Create API key.** Copy the key once — Gorgias won't show it again.
2. Set three environment variables:
   ```bash
   export GORGIAS_USERNAME="account-email-placeholder"
   export GORGIAS_API_KEY="<your-api-key>"
   export GORGIAS_BASE_URL="https://<tenant>.gorgias.com/api"
   ```
3. 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

```bash
# 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](https://github.com/mvanhorn/printing-press-library/blob/main/library/sales-and-crm/gorgias/MCP.md).

## Cookbook

```bash
# 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

```bash
# 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:

```json
{"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](https://github.com/mvanhorn/printing-press-library/blob/main/library/sales-and-crm/gorgias/SKILL.md) for the Claude Code skill descriptor. Quick wiring:

```bash
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](#install)), then add it to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json`):

```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](https://github.com/mvanhorn/printing-press-library/blob/main/library/sales-and-crm/gorgias/MCP.md).

## Cursor

See [CURSOR.md](https://github.com/mvanhorn/printing-press-library/blob/main/library/sales-and-crm/gorgias/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](https://github.com/mvanhorn/printing-press-library/blob/main/library/sales-and-crm/gorgias/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](https://github.com/mvanhorn/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](https://github.com/mvanhorn/printing-press-library/tree/main/library/project-management/linear) pioneered for compounding agent context.

---

Generated by [CLI Printing Press](https://github.com/mvanhorn/cli-printing-press).

