🪨 why use many token when few token do trick — Claude Code skill that cuts 65% of tokens by talking like caveman
CLI for webhooks, resources, and MCP server
Hookdeck CLI forwards webhook traffic to localhost with permanent event URLs, history, replay, and filters. It also manages sources, destinations, connections, and events from the terminal. For agent workflows, `hookdeck gateway mcp` exposes those same actions through MCP so tools like Cursor and Claude can call them. The repo also includes agent-facing rules and skills for common editors.
Builders who run Claude Code or Cursor and want one CLI for local webhooks and Hookdeck resource management.
You can test webhook flows locally, manage Hookdeck resources from the terminal, and let an agent use Hookdeck through MCP.
What it does
Local webhook forwarding
Forwards events to `localhost` or any URL with permanent event URLs and event history.
Event inspection and replay
Keeps event history between sessions so you can view, retry, open, and inspect requests in the CLI.
Event Gateway resource management
Lets you create, query, and manage sources, destinations, connections, events, and transformations.
MCP server for agents
Runs `hookdeck gateway mcp` so MCP-compatible clients can use Hookdeck tools.
Filtering and routing
Supports body, header, query, and path filters plus fan-out delivery for webhook testing.
Agent and editor support files
Includes Claude, Cursor, and AGENTS files plus skills folders for reusable workflow setup.
How to get it
- 1Hookdeck CLI is distributed as an NPM package
npm install hookdeck-cli -g
- 2To install a beta (pre-release) version
npm install hookdeck-cli@beta -g
- 3Hookdeck CLI is available on macOS via Homebrew in homebrew-core
brew install hookdeck
- 4To install a beta (pre-release) version from our tap
brew install hookdeck/hookdeck/hookdeck-beta
- 5[!NOTE] When HOMEBREW_REQUIRE_TAP_TRUST becomes the default in Homebrew 5.2.0 / 6.0.0,…
brew trust --formula hookdeck/hookdeck/hookdeck-beta
- 6Hookdeck CLI is available on Windows via the Scoop package manager
scoop bucket add hookdeck https://github.com/hookdeck/scoop-hookdeck-cli.git scoop install hookdeck
README
Hookdeck CLI
Using the Hookdeck CLI, you can forward your events (e.g. webhooks) to your local web server with unlimited free and permanent event URLs. Your event history is preserved between sessions and can be viewed, replayed, or used for testing by you and your teammates.
Hookdeck CLI is compatible with most of Hookdeck's features, such as filtering and fan-out delivery. You can use Hookdeck CLI to develop or test your event (e.g. webhook) integration code locally.
You can also manage Hookdeck Event Gateway resources—sources, destinations, connections, events, transformations—from the CLI. For AI and agent workflows, the Event Gateway MCP server (hookdeck gateway mcp) exposes these capabilities as tools in MCP-compatible clients (e.g. Cursor, Claude).
Although it uses a different approach and philosophy, it's a replacement for ngrok and alternative HTTP tunnel solutions.
Hookdeck for development is completely free, and we monetize the platform with our production offering.
For a complete reference of all commands and flags, see REFERENCE.md.
Table of contents
- Installation
- Usage
- Commands
- Configuration files
- Global Flags
- Troubleshooting
- Developing
- Testing
- Releasing
- Repository Setup
- CLI authentication keys
- License
Quick links: Local development (Listen) · Resource management (CLI) / Manage connections · AI / agent integration (Event Gateway MCP)
https://github.com/user-attachments/assets/7a333c5b-e4cb-45bb-8570-29fafd137bd2
Installation
Hookdeck CLI is available for macOS, Windows, and Linux for distros like Ubuntu, Debian, RedHat, and CentOS.
NPM
Hookdeck CLI is distributed as an NPM package:
npm install hookdeck-cli -g
To install a beta (pre-release) version:
npm install hookdeck-cli@beta -g
macOS
Hookdeck CLI is available on macOS via Homebrew in homebrew-core:
brew install hookdeck
New stable versions are picked up automatically by Homebrew's autobump after each release — brew upgrade will pull them in.
To install a beta (pre-release) version from our tap:
brew install hookdeck/hookdeck/hookdeck-beta
[!NOTE] When
HOMEBREW_REQUIRE_TAP_TRUSTbecomes the default in Homebrew 5.2.0 / 6.0.0, installing the beta formula from a third-party tap will require an explicit trust step:brew trust --formula hookdeck/hookdeck/hookdeck-betaThe stable
hookdeckformula lives in homebrew-core and is not affected.
Windows
Hookdeck CLI is available on Windows via the Scoop package manager:
scoop bucket add hookdeck https://github.com/hookdeck/scoop-hookdeck-cli.git
scoop install hookdeck
To install a beta (pre-release) version:
scoop install hookdeck-beta
Linux Or without package managers
To install the Hookdeck CLI on Linux without a package manager:
- Download the latest linux tar.gz file from https://github.com/hookdeck/hookdeck-cli/releases/latest
- Unzip the file: tar -xvf hookdeck_X.X.X_linux_amd64.tar.gz
- Run the executable: ./hookdeck
For beta (pre-release) versions, download the .deb or .rpm packages from the GitHub releases page (look for releases marked as "Pre-release").
Docker
The CLI is also available as a Docker image: hookdeck/hookdeck-cli.
docker run --rm -it hookdeck/hookdeck-cli version
hookdeck version x.y.z (beta)
To use a specific version (including beta releases), specify the version tag:
docker run --rm -it hookdeck/hookdeck-cli:v1.2.3-beta.1 version
Note: Beta releases do not update the latest tag. Only stable releases update latest.
If you want to login to your Hookdeck account with the CLI and persist
credentials, you can bind mount the ~/.config/hookdeck directory:
docker run --rm -it -v $HOME/.config/hookdeck:/root/.config/hookdeck hookdeck/hookdeck-cli login
Then you can listen on any of your sources. Don't forget to use
host.docker.internal to reach a port on your host machine, otherwise
that port will not be accessible from localhost inside the container.
docker run --rm -it -v $HOME/.config/hookdeck:/root/.config/hookdeck hookdeck/hookdeck-cli listen http://host.docker.internal:1234
Usage
Installing the CLI provides access to the hookdeck command.
hookdeck [command]
# Run `--help` for detailed information about CLI commands
hookdeck [command] help
Commands
Login
Login with your Hookdeck account. This will typically open a browser window for authentication.
hookdeck login
If you are in an environment without a browser (e.g., a TTY-only terminal), you can use the --interactive (or -i) flag to log in by pasting your API key:
hookdeck login --interactive
To authenticate with a CLI client key from the Hookdeck product (no browser step when the key is already associated with your account and project):
hookdeck login --cli-key <key>
The CLI validates the key via the API and writes your config, replacing a guest Console profile if one exists. For example, Hookdeck may show this command during Event Gateway onboarding or when authorizing the CLI as a Console destination.
Guest sandbox upgrade (keeping Console data) requires
hookdeck loginwithout--cli-key, not product copy-paste keys. If you do not log in, a temporary guest account is created when you run commands such ashookdeck listen.
Listen
Start a session to forward your events to an HTTP server.
hookdeck listen <port-or-URL> <source-alias?> <connection-query?> [flags]
Flags:
--path string Sets the path to which events are forwarded (e.g., /webhooks or /api/stripe)
--output string Output mode: interactive (full UI), compact (simple logs), quiet (only fatal errors) (default "interactive")
--max-connections int Maximum concurrent connections to local endpoint (default: 50, increase for high-volume testing)
--filter-body string Filter events by request body using Hookdeck filter syntax (JSON)
--filter-headers string Filter events by request headers using Hookdeck filter syntax (JSON)
--filter-query string Filter events by query parameters using Hookdeck filter syntax (JSON)
--filter-path string Filter events by request path using Hookdeck filter syntax (JSON)
--cli-key string Authenticate with a user-scoped CLI key instead of the stored login
--api-key string Authenticate with a project-scoped key instead of the stored login
By default listen uses the credentials saved by hookdeck login. To authenticate a single invocation without logging in first — for example in CI or when switching accounts — pass a key directly:
# User-scoped CLI key (created by `hookdeck login`; can access all your projects)
$ hookdeck listen 3000 stripe --cli-key <your-cli-key>
# Project-scoped key (e.g. a Project API key or a key from `hookdeck ci`)
$ hookdeck listen 3000 stripe --api-key <your-project-api-key>
Both flags are global, so they work with any command. A CLI key is tied to your user account and can navigate across projects; a project API key is scoped to a single project. Within the CLI both are stored and used the same way (see Credential Types).
The Event Gateway routes events received for a given source (e.g. Shopify, GitHub) to a destination via a connection. hookdeck listen is a standalone command that works with whichever product you're authenticated with — Hookdeck Console or the Event Gateway — receiving events for a given connection and forwarding them to your localhost at the specified port or any valid URL.
Each source is assigned an Event URL, which you can use to receive events. When starting with a fresh account, the CLI will prompt you to create your first source. Each CLI process can listen to one source at a time.
The
port-or-URLparam is mandatory, events will be forwarded to http://localhost:$PORT/$DESTINATION_PATH when inputing a valid port or your provided URL.
Interactive Mode
The default interactive mode uses a full-screen TUI (Terminal User Interface) with an alternative screen buffer, meaning your terminal history is preserved when you exit. The interface includes:
- Connection Header: Shows your sources, webhook URLs, and connection routing
- Auto-collapses when the first event arrives to save space
- Toggle with
ito expand/collapse connection details
- Event List: Scrollable history of all received events (up to 1000 events)
- Auto-scrolls to show latest events as they arrive
- Manual navigation pauses auto-scrolling
- Status Bar: Shows event details and available keyboard shortcuts
- Event Details View: Full request/response inspection with headers and body
Interactive Keyboard Shortcuts
While in interactive mode, you can use the following keyboard shortcuts:
↑/↓ork/j- Navigate between events (select different events)i- Toggle connection information (expand/collapse connection details)r- Retry the selected evento- Open the selected event in the Hookdeck dashboardd- Show detailed request/response information for the selected event (pressdorESCto close)- When details view is open:
↑/↓scroll through content,PgUp/PgDownfor page navigation - Press
Cto copy the complete request,Hfor request headers, orBfor the request body; off-screen content is included
- When details view is open:
q- Quit the application (terminal state is restored)Ctrl+C- Also quits the application
The selected event is indicated by a > character at the beginning of the line. All actions (retry, open, details) work on the currently selected event, not just the latest one. These shortcuts are displayed in the status bar at the bottom of the screen.
Note: Copying to the clipboard works out of the box on macOS and Windows. On Linux and other BSD/Unix systems it requires either
xcliporxselto be installed; without one of them the copy shortcuts report an error.
Listen to all your connections for a given source
The second param, source-alias is used to select a specific source to listen on. By default, the CLI will start listening on all eligible connections for that source.
$ hookdeck listen 3000 shopify
●── HOOKDECK CLI ──●
Listening on 1 source • 2 connections • [i] Collapse
Shopify Source
│ Requests to → https://events.hookdeck.com/e/src_DAjaFWyyZXsFdZrTOKpuHnOH
├─ Forwards to → http://localhost:3000/webhooks/shopify/inventory (Inventory Service)
└─ Forwards to → http://localhost:3000/webhooks/shopify/orders (Orders Service)
💡 Open dashboard to inspect, retry & bookmark events: https://dashboard.hookdeck.com/events/cli?team_id=...
Events • [↑↓] Navigate ──────────────────────────────────────────────────────────
2025-10-12 14:32:15 [200] POST http://localhost:3000/webhooks/shopify/orders (23ms) → https://dashboard.hookdeck.com/events/evt_...
> 2025-10-12 14:32:18 [200] POST http://localhost:3000/webhooks/shopify/inventory (45ms) → https://dashboard.hookdeck.com/events/evt_...
───────────────────────────────────────────────────────────────────────────────
> ✓ Last event succeeded with status 200 | [r] Retry • [o] Open in dashboard • [d] Show data
Listen to multiple sources
source-alias can be a comma-separated list of source names (for example, stripe,shopify,twilio) or '*' (with quotes) to listen to all sources.
$ hookdeck listen 3000 '*'
●── HOOKDECK CLI ──●
Listening on 3 sources • 3 connections • [i] Collapse
stripe
│ Requests to → https://events.hookdeck.com/e/src_DAjaFWyyZXsFdZrTOKpuHn01
└─ Forwards to → http://localhost:3000/webhooks/stripe (cli-stripe)
shopify
│ Requests to → https://events.hookdeck.com/e/src_DAjaFWyyZXsFdZrTOKpuHn02
└─ Forwards to → http://localhost:3000/webhooks/shopify (cli-shopify)
twilio
│ Requests to → https://events.hookdeck.com/e/src_DAjaFWyyZXsFdZrTOKpuHn03
└─ Forwards to → http://localhost:3000/webhooks/twilio (cli-twilio)
💡 Open dashboard to inspect, retry & bookmark events: https://dashboard.hookdeck.com/events/cli?team_id=...
Events • [↑↓] Navigate ──────────────────────────────────────────────────────────
2025-10-12 14:35:21 [200] POST http://localhost:3000/webhooks/stripe (12ms) → https://dashboard.hookdeck.com/events/evt_...
2025-10-12 14:35:44 [200] POST http://localhost:3000/webhooks/shopify (31ms) → https://dashboard.hookdeck.com/events/evt_...
> 2025-10-12 14:35:52 [200] POST http://localhost:3000/webhooks/twilio (18ms) → https://dashboard.hookdeck.com/events/evt_...
───────────────────────────────────────────────────────────────────────────────
> ✓ Last event succeeded with status 200 | [r] Retry • [o] Open in dashboard • [d] Show data
Listen to a subset of connections
The 3rd param, connection-query specifies which connection with a CLI destination to adopt for listening. By default, the first connection with a CLI destination type will be used. If a connection with the specified name doesn't exist, a new connection will be created with the passed value. The connection query is checked against the connection name, alias, and the path values.
$ hookdeck listen 3000 shopify orders
●── HOOKDECK CLI ──●
Listening on 1 source • 1 connection • [i] Collapse
Shopify Source
│ Requests to → https://events.hookdeck.com/e/src_DAjaFWyyZXsFdZrTOKpuHnOH
└─ Forwards to → http://localhost:3000/webhooks/shopify/orders (Orders Service)
💡 Open dashboard to inspect, retry & bookmark events: https://dashboard.hookdeck.com/events/cli?team_id=...
Events • [↑↓] Navigate ──────────────────────────────────────────────────────────
> 2025-10-12 14:38:09 [200] POST http://localhost:3000/webhooks/shopify/orders (27ms) → https://dashboard.hookdeck.com/events/evt_...
───────────────────────────────────────────────────────────────────────────────
> ✓ Last event succeeded with status 200 | [r] Retry • [o] Open in dashboard • [d] Show data
Changing the path events are forwarded to
The --path flag sets the path to which events are forwarded.
$ hookdeck listen 3000 shopify orders --path /events/shopify/orders
●── HOOKDECK CLI ──●
Listening on 1 source • 1 connection • [i] Collapse
Shopify Source
│ Requests to → https://events.hookdeck.com/e/src_DAjaFWyyZXsFdZrTOKpuHnOH
└─ Forwards to → http://localhost:3000/events/shopify/orders (Orders Service)
💡 Open dashboard to inspect, retry & bookmark events: https://dashboard.hookdeck.com/events/cli?team_id=...
Events • [↑↓] Navigate ──────────────────────────────────────────────────────────
> 2025-10-12 14:40:23 [200] POST http://localhost:3000/events/shopify/orders (19ms) → https://dashboard.hookdeck.com/events/evt_...
───────────────────────────────────────────────────────────────────────────────
> ✓ Last event succeeded with status 200 | [r] Retry • [o] Open in dashboard • [d] Show data
Controlling output verbosity
The --output flag controls how events are displayed. This is useful for reducing resource usage in high-throughput scenarios or when running in the background.
Available modes:
interactive(default) - Full-screen TUI with alternative screen buffer, event history, navigation, and keyboard shortcuts. Your terminal history is preserved and restored when you exit.compact- Simple one-line logs for all events without interactive features. Events are appended to your terminal history.quiet- Only displays fatal connection errors (network failures, timeouts), not HTTP errors
All modes display connection information at startup and a connection status message.
Examples:
# Default - full interactive UI with keyboard shortcuts
$ hookdeck listen 3000 shopify
# Simple logging mode - prints all events as one-line logs
$ hookdeck listen 3000 shopify --output compact
# Quiet mode - only shows fatal connection errors
$ hookdeck listen 3000 shopify --output quiet
Compact mode output:
Listening on
shopify
└─ Forwards to → http://localhost:3000
Connected. Waiting for events...
2025-10-08 15:56:53 [200] POST http://localhost:3000 (45ms) → https://...
2025-10-08 15:56:54 [422] POST http://localhost:3000 (12ms) → https://...
Quiet mode output:
Listening on
shopify
└─ Forwards to → http://localhost:3000
Connected. Waiting for events...
2025-10-08 15:56:53 [ERROR] Failed to POST: connection refused
Note: In
quietmode, only fatal errors are shown (connection failures, network unreachable, timeouts). HTTP error responses (4xx, 5xx) are not displayed as they are valid HTTP responses.
Filtering events
The CLI supports filtering events using Hookdeck's filter syntax. Filters allow you to receive only events that match specific conditions, reducing noise and focusing on the events you care about during development.
Filter flags:
--filter-body- Filter events by request body content (JSON)--filter-headers- Filter events by request headers (JSON)--filter-query- Filter events by query parameters (JSON)--filter-path- Filter events by request path (JSON)
All filter flags accept JSON using Hookdeck's filter syntax. You can use exact matches or operators like $exist, $gte, $lte, $in, etc.
Examples:
# Filter events by body content (only events with matching data)
hookdeck listen 3000 github --filter-body '{"action": "opened"}'
# Filter events with multiple conditions
hookdeck listen 3000 stripe --filter-body '{"type": "charge.succeeded"}' --filter-headers '{"x-stripe-signature": {"$exist": true}}'
# Filter using operators
hookdeck listen 3000 api --filter-body '{"amount": {"$gte": 100}}'
When filters are active, the CLI will display a warning message indicating which filters are applied. Only events matching all specified filter conditions will be forwarded to your local server.
Viewing and interacting with your events
Event logs for your CLI can be found at https://dashboard.hookdeck.com/cli/events. Events can be replayed or saved at any time.
Logout
Logout of your Hookdeck account and clear your stored credentials.
hookdeck logout
Skip SSL validation
When forwarding events to an HTTPS URL as the first argument to hookdeck listen (e.g., https://localhost:1234/webhook), you might encounter SSL validation errors if the destination is using a self-signed certificate.
For local development scenarios, you can instruct the listen command to bypass this SSL certificate validation by using its --insecure flag. You must provide the full HTTPS URL. This flag also applies to the periodic server health checks that the CLI performs.
This is dangerous and should only be used in trusted local development environments for destinations you control.
Example of skipping SSL validation for an HTTPS destination:
hookdeck listen --insecure https://<your-ssl-url-or-url:port>/ <source-alias?> <connection-query?>
Disable health checks
The CLI periodically checks if your local server is reachable and displays warnings if the connection fails. If these health checks cause issues in your environment, you can disable them with the --no-healthcheck flag:
hookdeck listen --no-healthcheck 3000 <source-alias?>
Version
Print your CLI version and whether or not a new version is available.
hookdeck version
Completion
Generate a shell completion script for the Hookdeck CLI. When installed via Homebrew or Scoop, completions are configured automatically.
To enable completions for the current shell session:
# bash
source <(hookdeck completion --shell bash)
# zsh
source <(hookdeck completion --shell zsh)
To install completions permanently, redirect the output to your shell's completion directory. See hookdeck completion --help for examples.
Running in CI
If you want to use Hookdeck in CI for tests or any other purposes, authenticate with a Project API key from the dashboard. The ci command exchanges it for a CLI client key stored in your config.
$ hookdeck ci --api-key $HOOKDECK_API_KEY
Done! The Hookdeck CLI is configured in project MyProject
$ hookdeck listen 3000 shopify orders
HOOKDECK_API_KEY is read automatically, so you can skip the ci step entirely — if no credentials are stored, listen exchanges the Project API key for CLI credentials and saves them, then connects to your project:
$ export HOOKDECK_API_KEY="your-project-api-key"
$ hookdeck listen 3000 shopify orders
Authentication order is --cli-key, then stored credentials from hookdeck login or hookdeck ci, then HOOKDECK_API_KEY. A real stored login is never repointed by the environment — but a temporary guest profile is, so a machine that once ran listen without credentials still uses your project once the variable is set. Replacing a guest profile is announced on stderr and discards the link to that sandbox; unset HOOKDECK_API_KEY if you want to keep it.
Without a Project API key listen still falls back to a temporary guest account, which is convenient locally but has no delivery history, retries, or issue triggers. If you meant to use your own project, check that HOOKDECK_API_KEY is actually set in the shell running the command — a variable that is unset there expands to an empty string, and values in a .env file are not loaded automatically just because your application reads them.
Output without a terminal
listen defaults to --output interactive, a full-screen UI that needs a terminal. In CI, Docker, nohup, or an AI agent there is no terminal, so it automatically falls back to --output compact — plain, line-based logs suited to a log file:
$ hookdeck listen 3000 shopify orders
⏺ Ready! Forwarding events from Shopify Source to http://localhost:3000/webhooks/shopify/orders
● 2025-10-12 14:42:55 [200] POST /webhooks/shopify/orders (34ms)
Pass --output compact (or --output quiet for warnings and errors only) explicitly if you want the same behaviour on a machine that does have a terminal.
Event Gateway
The hookdeck gateway command provides full access to Hookdeck Event Gateway resources. Use these subcommand
Files in the repo
- .agents
- .claude
- .cursor
- .github
- .goreleaser
- .plans
- bin
- docs
- pkg
- plans
- scripts
- test
- test-scripts
- tools
- .gitignore
- .tool-versions
- AGENTS.md
- CHANGELOG.md
- CLAUDE.md
- Dockerfile
- go.mod
- go.sum
- KNOWN_ISSUES.md
- LICENSE
- main.go
- package-lock.json
- package.json
- README.md
- REFERENCE.md
Discussion (0)
Ask about usage, or say what you built with itSign in to join the discussion.
No comments yet. Be the first to say what this is good for.
More tools
The best-benchmarked open-source AI memory system. And it's free.
Orca is the ADE for working with a fleet of parallel agents. Run any coding agent with your own subscription. Available on desktop, mobile and remote runtime.

A cross-platform desktop All-in-One assistant for Claude Code, Codex, OpenCode, OpenClaw, Grok Build & Hermes Agent. Only official website: ccswitch.io
Never stop coding. Free MIT AI gateway: one endpoint, 352 providers (150+ free), 1200+ models Kimi, Claude, GPT, Gemini, GLM, DeepSeek, MiniMax. Works with Claude Code, Codex, Cursor, OpenCode, Cline & Copilot. Quota-aware auto-fallback, RTK+Caveman compression saves 15-95% tokens, MCP/A2A, Desktop/PWA. Built by 550+ contributors
Compress tool outputs, logs, files, and RAG chunks before they reach the LLM. 20% fewer tokens for coding agents, 60-95% fewer tokens for JSON, same answers. Library, proxy, MCP server.