Documentation

Great Clips CLI

greatclips-pp-cli

Install

npx -y @mvanhorn/printing-press-library install greatclips

Installs the CLI binary and the agent skill for Claude Code, Codex, Cursor, Gemini CLI, Copilot, and more. Add --cli-only or --skill-only for one half. Requires Node.

Documentation

First CLI for Great Clips Online Check-In. Drives the Great Clips customer webservices (webservices.greatclips.com) and the ICS Net Check-In wait / check-in service (www.stylewaretouch.net) from one Go binary.

v0.2 status (2026-05-11)

Live and working with a captured Auth0 JWT:

  • salons search --term <zip> — finds salons by zip/city
  • salons get --num <id> — full salon detail
  • hours --salon <id> — 14-day hours forecast
  • geo --query <zip> — resolve zip to lat/lng
  • All dry-run output, JSON serialization, MCP server, doctor, sync, sql, search

Signing implementation verified byte-identical to the SPA's algorithm. Every outbound request to www.stylewaretouch.net is automatically signed with the HMAC ?t=<timestamp>&s=<signature> query parameters that the ICS Net Check-In service requires. Verified by closed-loop golden vector test in internal/icssign/sign_test.go.

Not yet working live, despite correct signing:

  • wait, checkin, status, cancel (all www.stylewaretouch.net endpoints)
  • customer profile (/cmp2/profile/get on webservices)

Both are blocked on per-host JWT audience scope: the GreatClips SPA fetches separate Auth0 access tokens for webservices.greatclips.com/customer, webservices.greatclips.com/cmp2, and www.stylewaretouch.net. v0.2 captures one of these and routes it to every host; the wrong-audience tokens are rejected at the gateway. Closing this gap (v0.3) requires either:

  1. Replicating the SPA's getAccessTokenSilently({audience}) flow against cid.greatclips.com/authorize + /oauth/token using Chrome's HttpOnly cid.greatclips.com/auth0 cookie, or
  2. A auth set-token --audience <name> paste flow that holds three tokens.

The signing port is the load-bearing v0.2 work; once audience scoping is fixed in v0.3, every stylewaretouch endpoint should light up immediately.

Learn more at Great Clips.

Created by @mvanhorn (Matt Van Horn).

Authentication

Great Clips uses HttpOnly session cookies from an Auth0 tenant at cid.greatclips.com. Browser-sniff confirmed all calls succeed via cookies attached by the browser, not via an Authorization header. v0.1 of this CLI ships the request shape and host routing; to make real calls, paste the cookies from a logged-in Chrome session into ~/.config/greatclips-pp-cli/config.toml. Set GREATCLIPS_TOKEN to any placeholder so doctor passes (the env var is kept for v0.2 when bearer support might land).

Quick Start

# Verifies config and base URL reachability (set GREATCLIPS_TOKEN=placeholder first so the env-var check passes; real auth is cookie-based and documented in README)
greatclips-pp-cli doctor

# Confirms profile call shape (GET /cmp2/profile/get)
greatclips-pp-cli customer profile --dry-run

# Wait-time request for one salon (Island Square on Mercer Island)
greatclips-pp-cli wait --store-number 8991 --dry-run --json

# Party-of-four check-in request body; remove --dry-run when cookies are configured
greatclips-pp-cli checkin --first-name Matt --last-name VanHorn --phone-number '(206) 555-0100' --salon-number 8991 --guests 4 --dry-run --json

# Position-in-line endpoint shape
greatclips-pp-cli status --dry-run

Usage

Run greatclips-pp-cli --help for the full command reference and flag list.

Commands

cancel

Cancel your active check-in

  • greatclips-pp-cli cancel submit - Cancel the active check-in for this account

checkin

Submit a check-in for yourself plus a party (1-5 people)

  • greatclips-pp-cli checkin submit - Add yourself and optionally other party members to a salon waitlist

customer

Read your Great Clips customer profile (name, phone, favorites, recent visits)

  • greatclips-pp-cli customer profile - Get the authenticated customer's profile

geo

Resolve a zip code or city term to latitude/longitude

  • greatclips-pp-cli geo postal_code - Resolve a zip/postal code to lat/lng/city/state

hours

Read salon hours (today plus 14-day forecast with special hours)

  • greatclips-pp-cli hours upcoming - Get 14-day hours forecast for one salon

salons

Search and look up Great Clips salons

  • greatclips-pp-cli salons get - Get a single salon by its salon number
  • greatclips-pp-cli salons search - Search salons by zip code, city, or coordinates within a radius

status

Check your current position in line for an active check-in

  • greatclips-pp-cli status get - Get your active check-in status (position in line, estimated wait)

wait

Read estimated wait times from the ICS Net Check-In service

  • greatclips-pp-cli wait one - Get wait time for one salon (body is a single-element array of {storeNumber})

Output Formats

# Human-readable table (default in terminal, JSON when piped)
greatclips-pp-cli salons get --num example-value

# JSON for scripting and agents
greatclips-pp-cli salons get --num example-value --json

# Filter to specific fields
greatclips-pp-cli salons get --num example-value --json --select id,name,status

# Dry run — show the request without sending
greatclips-pp-cli salons get --num example-value --dry-run

# Agent mode — JSON + compact + no prompts in one flag
greatclips-pp-cli salons get --num example-value --agent

Agent Usage

This CLI is designed for AI agent consumption:

  • Non-interactive - never prompts, every input is a flag
  • Pipeable - --json output to stdout, errors to stderr
  • Filterable - --select id,name returns only fields you need
  • Previewable - --dry-run shows the request without sending
  • Explicit retries - add --idempotent to create retries when a no-op success is acceptable
  • Confirmable - --yes for explicit confirmation of destructive actions
  • Piped input - write commands can accept structured input when their help lists --stdin
  • Agent-safe by default - no colors or formatting unless --human-friendly is set

Exit codes: 0 success, 2 usage error, 3 not found, 4 auth error, 5 API error, 7 rate limited, 10 config error.

Health Check

greatclips-pp-cli doctor

Verifies configuration, credentials, and connectivity to the API.

Configuration

Config file: ~/.config/greatclips-pp-cli/config.toml

Static request headers can be configured under headers; per-command header overrides take precedence.

Environment variables:

NameKindRequiredDescription
GREATCLIPS_TOKENper_callYesSet to your API credential.

Troubleshooting

Authentication errors (exit code 4)

  • Run greatclips-pp-cli doctor to check credentials
  • Verify the environment variable is set: echo $GREATCLIPS_TOKEN Not found errors (exit code 3)
  • Check the resource ID is correct
  • Run the list command to see available items

API-specific

  • doctor reports 'missing required: GREATCLIPS_TOKEN' — Set GREATCLIPS_TOKEN to any non-empty value (the upstream uses cookies, not a Bearer; v0.1 keeps the env var so doctor passes).
  • checkin returns 401 or 403 against the real API — v0.1 does not yet attach Chrome cookies. Open https://app.greatclips.com, log in, copy the auth0 session cookies for both webservices.greatclips.com and www.stylewaretouch.net, paste into ~/.config/greatclips-pp-cli/config.toml under cookie keys (cookie auth integration is a v0.2 gap).
  • wait returns object body but the API wants an array — The waitTime endpoint expects a JSON array of {storeNumber}. v0.1 emits the object form; patch internal/client.go to wrap the body in [] or use --stdin and pipe the array shape.

HTTP Transport

This CLI uses Chrome-compatible HTTP transport for browser-facing endpoints. It does not require a resident browser process for normal API calls.

Discovery Signals

This CLI was generated with browser-captured traffic analysis.

  • Target observed: https://app.greatclips.com/
  • Capture coverage: 9 API entries from 22 total network entries
  • Reachability: standard_http (90% confidence)
  • Protocols: (0% confidence), (0% confidence), (0% confidence)
  • Generation hints: Two-host single-auth: emit one bearer-token client that handles both webservices.greatclips.com and www.stylewaretouch.net., POST /api/store/waitTime takes a JSON array body of {storeNumber} objects, not a single object. Single-salon call sends an array of length 1., Auth captured live via Claude-in-Chrome MCP from a logged-in Chrome session; the printed CLI should ship a auth login --chrome helper command for the equivalent flow.

Generated by CLI Printing Press

For agents: pass /documentation/greatclips/agents.md to install this CLI from a prompt.