Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
d4b4865
docs: add detailed MCP server implementation plan
claude Mar 5, 2026
1b5e7ad
docs: update MCP plan with Issues backfill, metrics consolidation, an…
claude Mar 5, 2026
240e55e
Add Phase 1 progress tracker to implementation plan
claude Mar 5, 2026
6f5494b
Phase 1 Part 1: Issues CLI backfill — complete
claude Mar 5, 2026
6f438e1
Add acceptance tests for issue commands
claude Mar 5, 2026
7d0298a
test(acceptance): consolidate issue tests, skip flaky real-data tests
leggetter Mar 5, 2026
130bf23
Add acceptance test requirements for CLI changes to implementation plan
claude Mar 6, 2026
5cc6c1d
Expand Part 2 to cover all 4 metrics subcommands, not just events
claude Mar 6, 2026
ba1f7b1
Consolidate metrics CLI from 7 subcommands to 4 resource-aligned ones
claude Mar 6, 2026
06913a7
fix(metrics): help text, pending API measure, per-issue validation; e…
leggetter Mar 6, 2026
0b07e2b
Update plan: mark Parts 1 and 2 as complete
claude Mar 6, 2026
489dd22
Add MCP server skeleton (Part 3): command, server, tools, error trans…
claude Mar 9, 2026
b990401
Update plan: mark Part 3 as complete
claude Mar 9, 2026
5b7db32
fix(mcp): add required input schema for all tools
leggetter Mar 9, 2026
c7f3afa
docs: update MCP plan with current status and next steps
claude Mar 9, 2026
20e866c
feat(mcp): implement all 11 tool handlers with real API calls (Part 4)
claude Mar 9, 2026
24ed1d9
docs(mcp): add Section 1.7 — MCP authentication & login flow design
claude Mar 9, 2026
105d41c
feat(mcp): implement hookdeck_login tool for in-band browser auth
claude Mar 9, 2026
ee4bbe7
Fix metrics measures requirement and help topic error message
claude Mar 9, 2026
aa3f103
Document auth design decision: no API key param on hookdeck_login
claude Mar 9, 2026
dee9134
test(mcp): add integration tests for MCP server (Part 5)
claude Mar 9, 2026
943605a
docs: README TOC, intro rebalance, Event Gateway MCP section, quick l…
leggetter Mar 9, 2026
3164e67
Update package.json version to 1.10.0-beta.1
github-actions[bot] Mar 9, 2026
1f1939b
docs: clarify MCP is client-started, config-first in README
leggetter Mar 9, 2026
23713b8
test(mcp): expand to comprehensive coverage of all tools and actions
claude Mar 9, 2026
2d2491e
refactor(mcp): remove write operations to align with RFC read-only pr…
claude Mar 9, 2026
3fad452
docs(mcp): rewrite tool descriptions for investigation focus and expa…
claude Mar 9, 2026
2d8dd61
docs(mcp): use event-centric terminology instead of webhook-heavy lan…
claude Mar 9, 2026
b6a10d1
docs(mcp): update destination description to mention HTTP, CLI, MOCK …
claude Mar 9, 2026
7e446fa
Update package.json version to 1.10.0-beta.2
github-actions[bot] Mar 9, 2026
ac7fc64
docs: add acceptance test setup to AGENTS.md, mark Part 5 complete in…
claude Mar 10, 2026
a439d2e
docs(mcp): add high-level plan for MCP investigation and operations
leggetter Mar 10, 2026
4a7ab7b
Merge branch 'claude/hookdeck-gateway-mcp-Xe6WQ' of https://github.co…
leggetter Mar 10, 2026
b757301
Update v2 plan: reflect implemented features and add missing features…
claude Mar 10, 2026
484e66a
chore: add CLAUDE.md to .gitignore
claude Mar 10, 2026
f01fedc
test(mcp): add tests for server info, all help topics, and cross-tool…
claude Mar 10, 2026
0d9c6ff
Update package.json version to 1.10.0-beta.3
github-actions[bot] Mar 10, 2026
03a1e2e
fix(mcp): make hookdeck_login non-blocking so browser URL is shown im…
claude Mar 10, 2026
c1488da
Update package.json version to 1.10.0-beta.4
github-actions[bot] Mar 10, 2026
ca20e80
docs: add telemetry instrumentation plan for CLI and MCP usage tracking
claude Mar 10, 2026
b2da75e
Add Phase 5: telemetry opt-out via config and CI detection strategy
claude Mar 10, 2026
34ba04f
Separate source and environment as orthogonal telemetry dimensions
claude Mar 10, 2026
c5ab581
Move telemetry plan to plans/ with descriptive name
claude Mar 10, 2026
9f18ea1
Restructure telemetry plan: move to plans/, reorder sections
claude Mar 10, 2026
e3f7b26
feat: Add CLI telemetry instrumentation and remove deprecated SDK (#233)
leggetter Mar 11, 2026
c4b5f72
Rename telemetry command arguments and environment variable (#235)
leggetter Mar 11, 2026
8c8ad17
mcp: clarify event payload via raw_body, not request tool
leggetter Mar 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 18 additions & 4 deletions .github/workflows/test-acceptance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,24 @@ on:
- main

jobs:
test:
acceptance:
strategy:
fail-fast: false
matrix:
include:
- slice: "0"
api_key_secret: HOOKDECK_CLI_TESTING_API_KEY
tags: "basic connection source destination gateway mcp listen project_use connection_list connection_upsert connection_error_hints connection_oauth_aws connection_update"
- slice: "1"
api_key_secret: HOOKDECK_CLI_TESTING_API_KEY_2
tags: "request event"
- slice: "2"
api_key_secret: HOOKDECK_CLI_TESTING_API_KEY_3
tags: "attempt metrics issue transformation"
runs-on: ubuntu-latest
env:
HOOKDECK_CLI_TESTING_API_KEY: ${{ secrets.HOOKDECK_CLI_TESTING_API_KEY }}
ACCEPTANCE_SLICE: ${{ matrix.slice }}
HOOKDECK_CLI_TESTING_API_KEY: ${{ secrets[matrix.api_key_secret] }}
steps:
- name: Check out code
uses: actions/checkout@v3
Expand All @@ -20,5 +34,5 @@ jobs:
with:
go-version: "1.24.9"

- name: Run Go Acceptance Tests
run: go test ./test/acceptance/... -v -timeout 20m
- name: Run Go Acceptance Tests (slice ${{ matrix.slice }})
run: go test -tags="${{ matrix.tags }}" ./test/acceptance/... -v -timeout 12m
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,14 @@ default_cassette.yaml
__debug_bin
node_modules/
.env
test/acceptance/logs/
test-scripts/.install-test/

# Temporary OpenAPI spec download (large; do not commit)
.plans/openapi-2025-07-01.json

# Claude Code temporary worktrees
.claude/worktrees/

# Claude Code project notes (local only)
CLAUDE.md
6 changes: 6 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,12 @@ if apiErr, ok := err.(*hookdeck.APIError); ok {
- **Always run tests** when changing code. Run unit tests (`go test ./pkg/...`) and, for CLI-facing changes, acceptance tests (`go test ./test/acceptance/...`). If tests fail due to TLS/network/sandbox (e.g. `x509`, `operation not permitted`), prompt the user and re-run with elevated permissions (e.g. `required_permissions: ["all"]`) so tests can pass.
- **Create tests for new functionality.** Add unit tests for validation and business logic; add acceptance tests for flows that use the CLI as a user or agent would (success and failure paths). Acceptance tests must pass or fail—no skipping to avoid failures.

### Acceptance Test Setup
Acceptance tests require a Hookdeck API key. See [`test/acceptance/README.md`](test/acceptance/README.md) for full details. Quick setup: create `test/acceptance/.env` with `HOOKDECK_CLI_TESTING_API_KEY=<key>`. The `.env` file is git-ignored and must never be committed.

### Acceptance tests and feature tags
Acceptance tests in `test/acceptance/` are partitioned by **feature build tags** so they can run in parallel (two slices in CI and locally). Each test file must have exactly one feature tag (e.g. `//go:build connection`, `//go:build request`). The runner (CI workflow or `run_parallel.sh`) maps features to slices and passes the corresponding `-tags="..."`; see [test/acceptance/README.md](test/acceptance/README.md) for slice mapping and setup. **Every new acceptance test file must have a feature tag**; otherwise it is included in every build and runs in both slices (duplicated). Use tags to balance and parallelize; same commands and env for local and CI.

### Unit Testing
- Test validation logic thoroughly
- Mock API calls for command tests
Expand Down
154 changes: 142 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,50 @@ Using the Hookdeck CLI, you can forward your events (e.g. webhooks) to your loca

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](REFERENCE.md).

## Table of contents

- [Installation](#installation)
- [NPM](#npm)
- [macOS](#macos)
- [Windows](#windows)
- [Linux Or without package managers](#linux-or-without-package-managers)
- [Docker](#docker)
- [Usage](#usage)
- [Commands](#commands)
- [Login](#login)
- [Listen](#listen)
- [Logout](#logout)
- [Skip SSL validation](#skip-ssl-validation)
- [Disable health checks](#disable-health-checks)
- [Version](#version)
- [Completion](#completion)
- [Running in CI](#running-in-ci)
- [Event Gateway](#event-gateway)
- [Event Gateway MCP](#event-gateway-mcp)
- [Manage connections](#manage-connections)
- [Transformations](#transformations)
- [Requests, events, and attempts](#requests-events-and-attempts)
- [Manage active project](#manage-active-project)
- [Telemetry](#telemetry)
- [Configuration files](#configuration-files)
- [Global Flags](#global-flags)
- [Troubleshooting](#troubleshooting)
- [Developing](#developing)
- [Testing](#testing)
- [Releasing](#releasing)
- [Repository Setup](#repository-setup)
- [License](#license)

**Quick links:** [Local development (Listen)](#listen) · [Resource management (CLI)](#event-gateway) / [Manage connections](#manage-connections) · [AI / agent integration (Event Gateway MCP)](#event-gateway-mcp)

https://github.com/user-attachments/assets/7a333c5b-e4cb-45bb-8570-29fafd137bd2


Expand Down Expand Up @@ -491,6 +529,83 @@ hookdeck gateway transformation run --code "addHandler(\"transform\", (request,

For complete command and flag reference, see [REFERENCE.md](REFERENCE.md).

### Event Gateway MCP

The CLI includes an [MCP](https://modelcontextprotocol.io/) (Model Context Protocol) server for investigating event traffic in production. It exposes read-only tools that let AI agents query your Hookdeck Event Gateway — inspect connections, trace requests through events and delivery attempts, review issues, and pull aggregate metrics.

**Configure your MCP client** (Cursor, Claude Desktop, or any MCP-compatible host):

Cursor (`~/.cursor/mcp.json`):

```json
{
"mcpServers": {
"hookdeck": {
"command": "hookdeck",
"args": ["gateway", "mcp"]
}
}
}
```

Claude Desktop (`claude_desktop_config.json`):

```json
{
"mcpServers": {
"hookdeck": {
"command": "hookdeck",
"args": ["gateway", "mcp"]
}
}
}
```

The client starts `hookdeck gateway mcp` as a stdio subprocess. If you haven't authenticated yet, the `hookdeck_login` tool is available to log in via the browser.

#### Available tools

| Tool | Description |
|------|-------------|
| `hookdeck_projects` | List projects or switch the active project for this session |
| `hookdeck_connections` | Inspect connections and control delivery flow (list, get, pause, unpause) |
| `hookdeck_sources` | Inspect inbound sources (HTTP endpoints that receive events) |
| `hookdeck_destinations` | Inspect delivery destinations (HTTP endpoints where events are sent) |
| `hookdeck_transformations` | Inspect JavaScript transformations applied to event payloads |
| `hookdeck_requests` | Query inbound requests — list, get details, raw body, linked events |
| `hookdeck_events` | Query processed events — list, get details, raw payload body |
| `hookdeck_attempts` | Query delivery attempts — retry history, response codes, errors |
| `hookdeck_issues` | Inspect aggregated failure signals (delivery failures, transform errors, backpressure) |
| `hookdeck_metrics` | Query aggregate metrics — counts, failure rates, queue depth over time |
| `hookdeck_help` | Discover available tools and their actions |

#### Example prompts

Once the MCP server is configured, you can ask your agent questions like:

```
"Are any of my events failing right now?"
→ Agent uses hookdeck_issues to list open issues, then hookdeck_events to inspect recent failures.

"Show me the last 10 events for my Stripe source and check if any failed."
→ Agent uses hookdeck_sources to find the Stripe source, then hookdeck_events filtered by source and status.

"What's the error rate for my API destination over the last 24 hours?"
→ Agent uses hookdeck_metrics with measures like failed_count and count, grouped by destination.

"Trace request req_abc123 — what events did it produce, and did they all deliver successfully?"
→ Agent uses hookdeck_requests to get the request, then the events action to list generated events.

"Why is my checkout endpoint returning 500s? Show me the latest attempt details."
→ Agent uses hookdeck_events filtered by status FAILED, then hookdeck_attempts to inspect delivery details.

"Pause the connection between Stripe and my staging endpoint while I debug."
→ Agent uses hookdeck_connections to find and pause the connection.

"Compare failure rates across all my destinations this week."
→ Agent uses hookdeck_metrics with dimensions set to destination_id and measures like error_rate.
```

### Manage connections

Create and manage webhook connections between sources and destinations with inline resource creation, authentication, processing rules, and lifecycle management. Use `hookdeck gateway connection` (or the backward-compatible alias `hookdeck connection`). For detailed examples with authentication, filters, retry rules, and rate limiting, see the complete [connection management](#manage-connections) section below.
Expand Down Expand Up @@ -617,7 +732,7 @@ By default, `project use` saves your selection to the **global configuration** (

The CLI uses exactly one configuration file based on this precedence:

1. **Custom config** (via `--config` flag) - highest priority
1. **Custom config** (via `--hookdeck-config` flag) - highest priority
2. **Local config** - `${PWD}/.hookdeck/config.toml` (if exists)
3. **Global config** - `~/.config/hookdeck/config.toml` (default)

Expand Down Expand Up @@ -667,11 +782,11 @@ This ensures your directory-specific configuration is preserved when it exists.
hookdeck project use my-org my-project
hookdeck project use my-org my-project --local

# ❌ Invalid (cannot combine --config with --local)
hookdeck --config custom.toml project use my-org my-project --local
Error: --local and --config flags cannot be used together
# ❌ Invalid (cannot combine --hookdeck-config with --local)
hookdeck --hookdeck-config custom.toml project use my-org my-project --local
Error: --local and --hookdeck-config flags cannot be used together
--local creates config at: .hookdeck/config.toml
--config uses custom path: custom.toml
--hookdeck-config uses custom path: custom.toml
```

#### Benefits of local project pinning
Expand Down Expand Up @@ -980,6 +1095,20 @@ $ hookdeck gateway connection delete conn_123abc --force

For complete flag documentation and all examples, see [REFERENCE.md](REFERENCE.md).

### Telemetry

The Hookdeck CLI collects anonymous telemetry to help improve the tool. You can opt out at any time:

```sh
# Disable telemetry
hookdeck telemetry disabled

# Re-enable telemetry
hookdeck telemetry enabled
```

You can also disable telemetry by setting the `HOOKDECK_CLI_TELEMETRY_DISABLED` environment variable to `1` or `true`.

## Configuration files

The Hookdeck CLI uses configuration files to store the your keys, project settings, profiles, and other configurations.
Expand All @@ -988,9 +1117,10 @@ The Hookdeck CLI uses configuration files to store the your keys, project settin

The CLI will look for the configuration file in the following order:

1. The `--config` flag, which allows you to specify a custom configuration file name and path per command.
2. The local directory `.hookdeck/config.toml`.
3. The default global configuration file location.
1. The `--hookdeck-config` flag, which allows you to specify a custom configuration file path per command.
2. The `HOOKDECK_CONFIG_FILE` environment variable (path to the config file).
3. The local directory `.hookdeck/config.toml`.
4. The default global configuration file location.

### Default configuration Location

Expand Down Expand Up @@ -1065,7 +1195,7 @@ The following flags can be used with any command:

- `--api-key`: Your API key to use for the command.
- `--color`: Turn on/off color output (on, off, auto).
- `--config`: Path to a specific configuration file.
- `--hookdeck-config`: Path to the CLI configuration file. You can also set the `HOOKDECK_CONFIG_FILE` environment variable to the config file path.
- `--device-name`: A unique name for your device.
- `--insecure`: Allow invalid TLS certificates.
- `--log-level`: Set the logging level (debug, info, warn, error).
Expand Down Expand Up @@ -1107,16 +1237,16 @@ go run main.go

### Generating REFERENCE.md

The [REFERENCE.md](REFERENCE.md) file is generated from Cobra command metadata. After changing commands, flags, or help text, regenerate it:
The [REFERENCE.md](REFERENCE.md) file is generated from Cobra command metadata. After changing commands, flags, or help text, regenerate it in place:

```sh
go run ./tools/generate-reference --input REFERENCE.template.md --output REFERENCE.md
go run ./tools/generate-reference
```

To validate that REFERENCE.md is up to date (useful in CI):

```sh
go run ./tools/generate-reference --input REFERENCE.template.md --output REFERENCE.md --check
go run ./tools/generate-reference --check
```

Build from source by running:
Expand Down
16 changes: 12 additions & 4 deletions REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ The Hookdeck CLI provides comprehensive webhook infrastructure management includ
- [Events](#events)
- [Requests](#requests)
- [Attempts](#attempts)
- [Metrics](#metrics)
- [Utilities](#utilities)
<!-- GENERATE_END -->
## Global Options
Expand All @@ -30,8 +29,8 @@ All commands support these global options:
| Flag | Type | Description |
|------|------|-------------|
| `--color` | `string` | turn on/off color output (on, off, auto) |
| `--config` | `string` | config file (default is $HOME/.config/hookdeck/config.toml) |
| `--device-name` | `string` | device name |
| `--hookdeck-config` | `string` | path to CLI config file (default is $HOME/.config/hookdeck/config.toml) |
| `--insecure` | `bool` | Allow invalid TLS certificates |
| `--log-level` | `string` | log level (debug, info, warn, error) (default "info") |
| `-p, --profile` | `string` | profile name (default "default") |
Expand Down Expand Up @@ -206,7 +205,7 @@ hookdeck listen [port or forwarding URL] [source] [connection] [flags]
## Gateway

Commands for managing Event Gateway sources, destinations, connections,
transformations, events, requests, and metrics.
transformations, events, requests, metrics, and MCP server.

The gateway command group provides full access to all Event Gateway resources.

Expand All @@ -227,6 +226,9 @@ hookdeck gateway source create --name my-source --type WEBHOOK

# Query event metrics
hookdeck gateway metrics events --start 2026-01-01T00:00:00Z --end 2026-02-01T00:00:00Z

# Start the MCP server for AI agent access
hookdeck gateway mcp
```
<!-- GENERATE_END -->
## Connections
Expand Down Expand Up @@ -544,7 +546,7 @@ hookdeck gateway connection upsert <name> [flags]
| `--destination-basic-auth-pass` | `string` | Password for destination Basic authentication |
| `--destination-basic-auth-user` | `string` | Username for destination Basic authentication |
| `--destination-bearer-token` | `string` | Bearer token for destination authentication |
| `--destination-cli-path` | `string` | CLI path for CLI destinations (default: /) (default "/") |
| `--destination-cli-path` | `string` | CLI path for CLI destinations (default: / for new connections) |
| `--destination-custom-signature-key` | `string` | Key/header name for custom signature |
| `--destination-custom-signature-secret` | `string` | Signing secret for custom signature |
| `--destination-description` | `string` | Destination description |
Expand Down Expand Up @@ -725,6 +727,7 @@ hookdeck gateway source create [flags]
| `--api-key` | `string` | API key for source authentication |
| `--basic-auth-pass` | `string` | Password for Basic authentication |
| `--basic-auth-user` | `string` | Username for Basic authentication |
| `--config` | `string` | JSON object for source config (overrides individual flags if set) |
| `--config-file` | `string` | Path to JSON file for source config (overrides individual flags if set) |
| `--custom-response-body` | `string` | Custom response body (max 1000 chars) |
| `--custom-response-content-type` | `string` | Custom response content type (json, text, xml) |
Expand Down Expand Up @@ -785,6 +788,7 @@ hookdeck gateway source update <source-id> [flags]
| `--api-key` | `string` | API key for source authentication |
| `--basic-auth-pass` | `string` | Password for Basic authentication |
| `--basic-auth-user` | `string` | Username for Basic authentication |
| `--config` | `string` | JSON object for source config (overrides individual flags if set) |
| `--config-file` | `string` | Path to JSON file for source config (overrides individual flags if set) |
| `--custom-response-body` | `string` | Custom response body (max 1000 chars) |
| `--custom-response-content-type` | `string` | Custom response content type (json, text, xml) |
Expand Down Expand Up @@ -843,6 +847,7 @@ hookdeck gateway source upsert <name> [flags]
| `--api-key` | `string` | API key for source authentication |
| `--basic-auth-pass` | `string` | Password for Basic authentication |
| `--basic-auth-user` | `string` | Username for Basic authentication |
| `--config` | `string` | JSON object for source config (overrides individual flags if set) |
| `--config-file` | `string` | Path to JSON file for source config (overrides individual flags if set) |
| `--custom-response-body` | `string` | Custom response body (max 1000 chars) |
| `--custom-response-content-type` | `string` | Custom response content type (json, text, xml) |
Expand Down Expand Up @@ -971,6 +976,7 @@ hookdeck gateway destination create [flags]
| `--basic-auth-user` | `string` | Username for Basic auth |
| `--bearer-token` | `string` | Bearer token for destination auth |
| `--cli-path` | `string` | Path for CLI destinations (default "/") |
| `--config` | `string` | JSON object for destination config (overrides individual flags if set) |
| `--config-file` | `string` | Path to JSON file for destination config (overrides individual flags if set) |
| `--custom-signature-key` | `string` | Key/header name for custom signature |
| `--custom-signature-secret` | `string` | Signing secret for custom signature |
Expand Down Expand Up @@ -1037,6 +1043,7 @@ hookdeck gateway destination update <destination-id> [flags]
| `--basic-auth-user` | `string` | Username for Basic auth |
| `--bearer-token` | `string` | Bearer token for destination auth |
| `--cli-path` | `string` | Path for CLI destinations |
| `--config` | `string` | JSON object for destination config (overrides individual flags if set) |
| `--config-file` | `string` | Path to JSON file for destination config (overrides individual flags if set) |
| `--custom-signature-key` | `string` | Key/header name for custom signature |
| `--custom-signature-secret` | `string` | Signing secret for custom signature |
Expand Down Expand Up @@ -1100,6 +1107,7 @@ hookdeck gateway destination upsert <name> [flags]
| `--basic-auth-user` | `string` | Username for Basic auth |
| `--bearer-token` | `string` | Bearer token for destination auth |
| `--cli-path` | `string` | Path for CLI destinations |
| `--config` | `string` | JSON object for destination config (overrides individual flags if set) |
| `--config-file` | `string` | Path to JSON file for destination config (overrides individual flags if set) |
| `--custom-signature-key` | `string` | Key/header name for custom signature |
| `--custom-signature-secret` | `string` | Signing secret for custom signature |
Expand Down
Loading
Loading