firecrawl-access
v0.1.0
Published
Run the Firecrawl CLI against a Cloudflare Access protected origin from one command. Bundles a header-injecting shim + the Firecrawl CLI into a single self-contained binary.
Maintainers
Readme
firecrawl-access (fca)
Run the Firecrawl CLI against a Cloudflare Access protected origin (e.g. fc.synthswarm.com) from a single command.
The Firecrawl CLI exposes --api-url / FIRECRAWL_API_URL but has no way to attach the CF-Access-Client-Id / CF-Access-Client-Secret service-token headers that an Access-gated hostname requires. fca closes that gap: it runs a tiny local reverse-proxy shim that injects those headers, points the Firecrawl CLI at the shim, and runs the CLI, all in one process. No second install, no manual port wiring.
fca scrape ... -> http://127.0.0.1:<ephemeral> -> shim (adds CF-Access-* headers)
-> https://fc.synthswarm.com (Access gate)
-> Firecrawl originWhy this shape
firecrawl-cli is a third-party package we don't own, so forking it to add header support would mean chasing every upstream release. Instead this package depends on firecrawl-cli and embeds it: bun build --compile bundles the shim and the entire Firecrawl CLI into one self-contained executable that runs the CLI in-process with FIRECRAWL_API_URL pointed at the shim. One artefact, both jobs.
Install
From npm (recommended)
npm i -g firecrawl-access
fca config --hostname fc.synthswarm.com --client-id <id>.access --client-secret <secret>
fca scrape https://example.com -f markdownThe npm package bundles pre-compiled, self-contained binaries (one per Linux arch). At runtime it needs neither Bun nor Firecrawl installed - a tiny Node launcher execs the matching binary. Supported platforms: Linux x64 and arm64. macOS/Windows aren't shipped yet; on those, build from source with Bun (below).
From source (for development / other platforms)
Requires Bun (curl -fsSL https://bun.sh/install | bash).
git clone https://github.com/SynthSwarm/firecrawl-access && cd firecrawl-access
bun installConfigure
The quickest way is the built-in config command, which writes ~/.config/firecrawl-access/.env (mode 0600), no .env file to manage:
fca config \
--hostname fc.synthswarm.com \
--client-id <id>.access \
--client-secret <secret>
# optional: --listen-host 127.0.0.1 --listen-port 3999(Short flags: -H, -i, -s. Run fca config --help for the full list.)
Alternatively, copy .env.example to .env and fill it in:
cp .env.example .env
$EDITOR .envConfig is read (in ascending priority, live env always wins) from:
~/.config/firecrawl-access/.env(written byfca config)./.env./.env.access$FCA_ENV_FILE(explicit override)
| Variable | Required | Default | Meaning |
|---|---|---|---|
| CF_ACCESS_CLIENT_ID | yes | | Access service-token client id |
| CF_ACCESS_CLIENT_SECRET | yes | | Access service-token secret |
| CF_ACCESS_HOSTNAME | yes | | Access-gated hostname to forward to (e.g. fc.synthswarm.com) |
| SHIM_LISTEN_HOST | no | 127.0.0.1 | Shim bind host (standalone / pinned mode) |
| SHIM_LISTEN_PORT | no | 3999 | Pin the shim port; unset means an ephemeral port in wrapper mode |
| FCA_VERBOSE | no | | 1 to log shim requests to stderr |
FIRECRAWL_API_KEY (if your origin needs one) is passed through untouched.
Use
# Any Firecrawl command/args, transparently gated:
bun run bin/fca.ts scrape https://example.com -f markdown
bun run bin/fca.ts crawl https://example.com
bun run bin/fca.ts --statusInstall globally from this repo (no npm)
./install.sh # builds the binaries and installs to ~/.local/bin
./install.sh --prefix ~/bin # custom location
./install.sh --uninstall # removeThe script runs bun install, compiles the binaries, copies them onto your PATH, and warns if the target dir isn't on $PATH.
Build the single binary (recommended distribution)
bun run build # cross-compiles dist/fca-linux-x64 and dist/fca-linux-arm64Each binary is fully self-contained (no Bun, Node, or node_modules needed at runtime). Drop the one for your arch on your PATH:
install -m 0755 dist/fca-linux-$(uname -m | sed 's/aarch64/arm64/;s/x86_64/x64/') ~/.local/bin/fca
fca scrape https://example.com -f markdownStandalone shim
If you'd rather run a long-lived proxy (a systemd user unit, or for other clients that also need the gated origin), use the built-in shim subcommand. It listens on SHIM_LISTEN_HOST:SHIM_LISTEN_PORT and forwards with the Access headers attached:
fca shim # long-lived proxy on the pinned port
# then point anything at it:
FIRECRAWL_API_URL=http://127.0.0.1:3999 firecrawl scrape https://example.comAlternatives worth knowing
For your own roaming machines, a Cloudflare WARP / private-network route reaches the origin with no per-request headers at all and is the better long-term option. Keep this shim for clients (like the Firecrawl CLI) that can't do that, or where you don't want to enrol the device.
Notes / gotchas
- Bun's
fetchtransparently decompresses responses, so the shim stripscontent-encodingandcontent-lengthwhen relaying (otherwise the Firecrawl SDK double-decompresses and throwsZstdDecompressionError). - On a self-hosted Firecrawl,
--statusmay printCould not fetch account info/ a 500 on/v2/team/credit-usage. That's the self-hosted API not implementing the hosted billing endpoints; scrape/crawl/map/search still work. fca configandfca shimare intercepted by the wrapper, so they shadow any same-named Firecrawl CLI subcommand. Everything else is passed straight through to Firecrawl.- In wrapper mode the shim's listening socket is
unref()ed so the process exits as soon as the Firecrawl command finishes.
