CLI
The FlurryPORT CLI (npm package: flurryport) is the bridge between captures stored on FlurryPORT and code running on your laptop. It is the only way to forward live webhook traffic — captures or replay sequences — to a localhost dev server, because FlurryPORT itself runs in the cloud and cannot reach your machine.
Use cases
Solo developer forwarding to localhost
You point Stripe (or any provider) at a FlurryPORT capture URL. Captures land in FlurryPORT encrypted. To exercise your local webhook handler with real provider traffic, create a replay target pointing at http://localhost:3000/webhooks (or wherever your dev server listens), then run flurryport listen. Every capture on that endpoint is forwarded to localhost with the original headers, body, and HMAC signature intact. The response your local server returns is recorded back to FlurryPORT so you can see pass/fail in the UI.
Team sharing via Personal Access Tokens
A project owner generates a PAT in Settings → Access Tokens and shares it with a teammate. The teammate runs flurryport login --name alice <token> to store it as a named account. They can now create their own replay target pointing at their localhost (flurryport target create) and flurryport listen to receive forwards. PAT restrictions prevent them from deleting or mutating the owner’s projects, endpoints, or captures — only replay-related writes are allowed.
Install
npm install -g flurryport
The flurryport binary is installed globally. Run flurryport --help for a full command list.
First run
Generate a Personal Access Token in Settings → Access Tokens, then store it:
# Single account on the default (prod) environment flurryport login fp_your_token_here # Named account, useful when you have more than one flurryport login --name alice fp_your_token_here
You only need to do this once per account. The token is stored in ~/.flurryport/config.json.
Commands
| Command | Key flags | What it does |
|---|---|---|
login | --name | Authenticate the CLI to your account. |
account list/use/remove | Manage saved accounts. | |
config show | Print current CLI config. | |
target create [url] | --project --endpoint --name --account --environment | Create a replay target. |
listen | --interval (default 3000) --account --environment | Poll for captures and forward them to local targets. |
echo | [port] --host --path | Local 200-everything receiver that mirrors requests. |
mcp | --allow-lan | Run FlurryPORT as an MCP server for AI editors. See the MCP section below. |
listen
Discover localhost replay targets, attach to one, and forward executions until you press Ctrl+C.
flurryport listen flurryport listen --interval 5000 # custom poll interval (default 3000ms) flurryport listen --account alice # override active account for this run
When the CLI starts, any pending executions created before startup are marked as stale and dead-lettered — it only forwards executions created after it begins listening. This prevents replaying a stale backlog when you restart.
Sequence replays (triggered from the UI via "Run collection") are grouped under a header in the CLI output, so you can visually track multi-item runs.
target create
Create a replay target without leaving the terminal. With no flags, the wizard auto-picks the only project/endpoint or prompts when there are several.
# Interactive wizard flurryport target create # Fully scripted (skip all prompts) flurryport target create \ --project my-project \ --endpoint stripe-webhook \ --url http://localhost:3000/webhooks \ --name "My local"
Targets created via the CLI default to AutoReplay: false. Auto-forward must be enabled in the web UI — the CLI deliberately does not flip that flag because auto-forward to an unverified domain would amplify webhook traffic. (Localhost is exempt from domain verification because the CLI is what delivers it.)
login
flurryport login fp_your_token_here # default account flurryport login --name alice fp_token # named account in the active environment
account
Manage multiple accounts within the active environment. Useful when you contribute to several teams’ projects.
flurryport account list # list accounts in active environment flurryport account use alice # switch active account flurryport account remove alice # delete an account from config
config
flurryport config show
Shows the active account and all configured accounts.
echo
flurryport echo starts a local HTTP server that returns 200 to every request, logs it, and mirrors it straight back. It is the fastest way to confirm a bridge is wired correctly with no backend of your own.

flurryport echo [port] [--host <host>] [--path <path>]
| Argument | Default | Description |
|---|---|---|
[port] | 3000 | Port to listen on. |
--host <host> | localhost | Interface to bind. IPv6 addresses are auto-bracketed in output. |
--path <path> | (all paths) | If set, only that exact path returns 200. Everything else returns 404. A leading / is added automatically and query strings are ignored when matching. |
Every incoming request header is echoed back prefixed with X-Echo-. A request Authorization: Bearer abc comes back as X-Echo-Authorization: Bearer abc. The response body is JSON:
{
"ok": true,
"hit": 1,
"method": "POST",
"path": "/webhooks",
"query": {},
"headers": { "...": "..." },
"body": "...",
"received": 482
}hit is the request counter for this run and received is the body size in bytes. The console logs a timestamp, request number, method, URL, status, all headers, and a body preview for each request.
Startup output:
Echo server listening on http://localhost:3000 [filtering on /webhooks] Every matching request gets 200 + full mirror of headers and body. Press Ctrl+C to stop.
Worked example: secret substitution and redaction
Pair echo with listen to dogfood a full bridge with no backend, and to watch a secret get injected and then redacted.
# 1. Add a secret in the UI (Secrets > Add secret): STRIPE_KEY # 2. On a replay target, set a header: X-Api-Key: $secrets.STRIPE_KEY # 3. Start a local receiver: flurryport echo 3000 # 4. In another terminal, forward captures to it: flurryport listen # 5. Send a test webhook to your FlurryPORT endpoint.
FlurryPORT substitutes the real key into X-Api-Key on the way out. echo mirrors it back as X-Echo-X-Api-Key. Because the destination echoed a secret, FlurryPORT scrubs it before storing, so the recorded response in the UI shows:
X-Echo-X-Api-Key: [REDACTED:STRIPE_KEY]
The real secret reached the destination. The stored response never contains it. That single run exercises secrets, substitution, redaction, and forwarding together. See Secrets for the full secrets workflow.
MCP server (AI editors)
flurryport mcp runs FlurryPORT as an MCP server over stdio, so Claude Code, Cursor, or any MCP-capable editor can capture, inspect, and forward webhooks without leaving the conversation. Your AI gets tools; you keep control.
# Claude Code claude mcp add flurryport -- npx -y flurryport mcp # Any other MCP client: command "npx", args ["-y", "flurryport", "mcp"]
Try it without an account
With no token configured, the server starts in anonymous mode with thirteen tools. The core loop is get_capture_url, list_captures, get_capture, and forward_to_localhost: ask your AI for a capture URL, point Stripe at it, and debug the payload in-editor. Around that loop: get_capture_digest summarizes traffic as grouped facts when events pile up, send_test_event and capture_count generate and pace provider-shaped test traffic, start_echo_server gives forwarding an instant local target, and register_watch stores standing event watches that sleep until you claim the session (see below). Anonymous sessions are honest about their limits: 250 captures, about an hour of idle life, 24 hours maximum, and plaintext storage. Do not send real production data; claim the session (free) for encryption at rest. The session survives editor restarts.
Forwarding is loopback-only by default (--allow-lan opts in) and delivers the raw bytes with original headers, so provider signatures verify on your app exactly as they would in production.
Sign in from the editor
When you claim the anonymous session in the browser, the CLI completes a device-code hand-off: a read-only token is minted for you and the toolset flips to authenticated mode live, no restart, nothing to paste. Already have an account? Mint a token under Settings → Access Tokens, run flurryport login <token>, and restart the MCP server. Token scope is read at startup, so the restart matters.
Token scopes
Two checkboxes at mint time, both ON by default. Least privilege is the default because the most common reason to mint a token is handing it to an AI.
| Scope | Default | What it enforces |
|---|---|---|
| Read-only | On | Inspect and forward to your own machine only. No server-side replays, no changes. Server-enforced, not a client hint. |
| Redact PII | On | Capture reads come back with emails, cards, SSNs, phones, and IPs masked, best effort. Forwards to your own local target stay untouched so signatures keep verifying. |
Authenticated tools
Twenty-five tools: reads across projects, endpoints, captures, targets, executions, and plans, the digest and watch tools below, plus forward_to_localhost, replay_to_target, and get_upgrade_options. Server-side replay works only against replay targets you registered in the web UI; the AI can never supply an arbitrary URL, retries are idempotent, and editors treat it as a destructive action that needs your confirmation. It also requires a read-write token, so the default mint refuses it.
Pricing your AI quotes is always live: get_upgrade_options pulls the current plan catalog, yearly pricing, and day passes straight from the billing API. Purchases only ever happen in the web app, signed in as you.
The digest and standing watches
get_capture_digest answers "what came in?" with grouped facts instead of payload dumps: totals plus counts by endpoint, event type, provider, label, and hour, with a retention nudge from your real plan. Your AI drills into the group that matters instead of paging through everything.
register_watch sets a standing JSONata predicate over $body, $headers, and $query that the server evaluates against every future capture on an endpoint, for example $body.type = "charge.failed". Matches are counted and, when the watch has a label, tagged onto the capture so the digest and list filters pick them up. list_watches shows the facts (match counts, last match, and the last predicate error, so a broken watch is visible instead of silent) and set_watch_enabled pauses one without losing its history. Watch predicates never see secrets, and every tier has a bounded per-endpoint watch limit. In anonymous mode, registered watches are stored and validated but sleep until you claim the session; claiming wakes them on your real endpoint, enabled up to your plan limit.
Recipe catalog
search_recipes and get_recipe query the public FlurryPORT recipe catalog: signed webhook pipes (Slack posts, GitHub issues, Telegram sends, and more) your AI can look up by service or keyword and read in full, including the content hash shown on the recipe page. Available in both anonymous and authenticated modes. Browse the catalog yourself at flurryport.io/recipes.
Configuration file
Config lives at ~/.flurryport/config.json and is rewritten on every command. Direct editing is supported.
{
"activeEnvironment": "prod",
"environments": {
"prod": {
"apiUrl": "https://api.flurryport.io",
"activeAccount": "me",
"accounts": {
"me": { "apiKey": "fp_..." },
"alice": { "apiKey": "fp_..." }
}
}
}
}Pre-existing flat configs ({ apiUrl, apiKey }) from earlier CLI versions are auto-migrated to the new shape on first load.
Authentication & PAT restrictions
The CLI authenticates via fp_ Personal Access Tokens passed as Authorization: Bearer fp_.... The Users and Billing APIs reject PAT auth entirely — only the Core API accepts it, and only for these operations:
This means a teammate with your PAT can forward your captures to their localhost and create their own replay targets, but cannot delete your projects, modify your billing, or extend their own access. Lost or leaked tokens can be revoked individually from Settings.