feat: stamp the coding agent in the request origin

ER
10h ago
+340-39

Summary

The CLI now stamps the coding agent that runs it into the request origin: cli.<agent>@<cli version> when an agent is detected, cli@<cli version> otherwise. integration: 'cli' is unchanged everywhere, and the keyless X-Origin: cli header is kept as is.

  • New src/utils/agent-origin.ts computes the origin once per process from environment variables that agents set in the processes they spawn (no config files on disk).
  • FIRECRAWL_CLI_DISABLE_AGENT_ORIGIN=1 sends plain cli@<version>. Documented in the README.
  • Detection order puts Claude Code last: its variables are the most widely inherited (IDE terminals, tmux), so a more specific agent wins when both are set.

Where the origin is sent

PathHow
Keyless POSTs (scrape, search)body origin
interact, feedback, search-feedback, parsebody / options origin
monitor create and updatebody origin
research, developer, gov GETsorigin query parameter next to integration=cli
SDK-routed callsorigin client option

SDK-routed calls (firecrawl@4.44.0, the version the CLI pins) carry the agent only after the SDK bump: that version has no origin client option and its HTTP client overwrites a body origin unless it contains "mcp". The CLI passes origin as a client option now; SDKs without it ignore the option, so nothing changes until the SDK ships support. The direct fetch paths above carry the agent immediately. Requests that have no origin field (credit usage, status, doctor, exchange calls) are unchanged.

Detected agents and sources

SlugVariablesSource
claude-codeCLAUDECODE, CLAUDE_CODE_ENTRYPOINThttps://code.claude.com/docs/en/plugin-hints (CLAUDECODE set for Bash tool commands); https://github.com/anthropics/claude-code-action/commit/c9ec2b02b40ac0444c6716e51d5e19ef2e0b8d00 (CLAUDE_CODE_ENTRYPOINT)
codexCODEX_SANDBOX, CODEX_SANDBOX_NETWORK_DISABLED, CODEX_THREAD_ID, CODEX_MANAGED_BY_NPM/BUN/PNPM/VITE_PLUShttps://github.com/openai/codex/blob/main/codex-rs/core/src/spawn.rs ; https://github.com/openai/codex/blob/main/codex-rs/protocol/src/shell_environment.rs ; https://github.com/openai/codex/blob/main/codex-cli/bin/codex.js
cursorCURSOR_AGENThttps://cursor.com/docs/agent/tools/terminal
gemini-cliGEMINI_CLIhttps://github.com/google-gemini/gemini-cli/blob/main/docs/tools/shell.md
opencodeOPENCODEprocess.env.OPENCODE = "1" in https://github.com/anomalyco/opencode/blob/dev/packages/opencode/src/index.ts
gooseGOOSE_TERMINALhttps://github.com/block/goose/blob/main/documentation/docs/guides/environment-variables.md ; https://github.com/block/goose/pull/7017
clineCLINE_ACTIVEhttps://docs.cline.bot/features/customization/disable-terminal-pagers

Dropped because they could not be verified from public docs or source:

  • CURSOR_TRACE_ID: no public documentation, and it is likely present in every Cursor terminal, including ones a person types in.
  • Amp: the AMP_* variables are user configuration, not a runtime marker, and AGENT=amp only appears in third-party reports.

Testing

  • pnpm type-check, pnpm format:check, pnpm test pass (716 tests).
  • New unit tests cover detection, precedence, falsy values, the opt-out, once-per-process caching and the keyless body origin.
  • Existing tests that asserted origin: 'cli' or the bare integration=cli query now build the expected value with getCliOrigin(), so they pass when run inside an agent.
  • Not verified against a live API.

Open in Capy


Summary by cubic

The CLI now stamps the coding agent that runs it into the API request origin: cli.<agent>@<version> when an agent is detected, cli@<version> otherwise. integration: 'cli' and the keyless X-Origin: cli header are unchanged.

Details

  • Agent detection reads environment variables agents set in the processes they spawn (no config files on disk) and is computed once per process.
  • FIRECRAWL_CLI_DISABLE_AGENT_ORIGIN=1 (or true, yes, on) restores plain cli@<version> and is documented in the README.
  • The origin is stamped into keyless POST bodies, GET query params for developer, research, and gov, and the body origin in interact, feedback, search-feedback, parse, and monitor create/update; the API now accepts origin on monitor create and update.
  • SDK-routed calls pass origin as a client option; SDKs without support ignore it, so those requests carry the agent only after the matching SDK release.
  • Detection is ordered innermost agent first, with Claude Code last since its variables are the most widely inherited.
  • Tests pin the origin to a mock value, cover every Codex marker, and isolate the cache test from the host environment, so assertions hold regardless of the agent that runs them.