Skip to main content
The CLI is intentionally dumb — Claude (or another agent) running in your terminal does the natural-language parsing and constructs structured upstack calls. No LLM ever runs server-side in Upstack.

Example session

The agent picks measure ids using upstack measures, then issues a single build call. Same result as the API quickstart, in one structured command.

Filters: discover before you construct

When the user asks for a scoped query — “MER for new customers only”, “spend on Meta campaigns containing ‘spring’”, etc. — the agent should call upstack filters first to enumerate valid filter fields, operators, and contexts before guessing field ids:
The field id (orders.customer_type), its supported operators, and the set of applicable contexts all come from the discovery endpoint — no hard-coding.

Why this works

  • Discovery is free. upstack measures and upstack filters require only analytics:read. An agent can introspect what’s available before constructing a request.
  • The CLI is structured input for the agent’s structured output. Flags are JSON-shaped (--measures m1,m2,m3, --from-file payload.json). No shell-quoting gymnastics for natural-language prompts.
  • Every command can be replayed. Pass --from-file to load a JSON body, then iterate via flags. The agent doesn’t need to remember state — it can re-issue.

What the agent should NOT do

  • Don’t ask the user for their API key over chat. Credentials are already in ~/.upstackrc; the CLI handles auth automatically.
  • Don’t hand-construct API request bodies in chat. Use the CLI as the structured interface — it’s already typed and validated.