Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
2d8f9d9
feat(outpost): add Outpost API client, schema cache and live tests
leggetter Aug 14, 2026
85ba39c
feat(outpost): add outpost command group and tenant commands
leggetter Aug 14, 2026
a38bfe8
feat(outpost): add destination commands
leggetter Aug 14, 2026
9fce42b
feat(outpost): add destination-type commands and per-type dynamic help
leggetter Aug 14, 2026
ea4ee42
feat(outpost): support dotted paths in --config and --credential
leggetter Aug 14, 2026
000cd7f
feat(outpost): add event, attempt, publish, topic, metrics, config an…
leggetter Aug 14, 2026
c235fd5
test(outpost): add acceptance suite and CI slice
leggetter Aug 14, 2026
1303023
docs(outpost): add REFERENCE.md and README sections
leggetter Aug 14, 2026
640b00f
test(outpost): cover event get, attempt get, tenant token and retry
leggetter Aug 14, 2026
b09cda9
Update package.json version to 2.6.0-beta.1
github-actions[bot] Aug 14, 2026
9445c8a
refactor(mcp): extract product-agnostic MCP server into pkg/mcpcore
leggetter Aug 14, 2026
536935d
feat(outpost): add an MCP server for AI agent access
leggetter Aug 14, 2026
2914526
refactor(mcp): keep login and projects on the hookdeck_ prefix in eve…
leggetter Aug 14, 2026
bf22092
Merge remote-tracking branch 'origin/main' into integrate/outpost-mcp
leggetter Aug 14, 2026
2b4ec87
Merge remote-tracking branch 'origin/main' into feat/outpost-api-client
leggetter Aug 14, 2026
e7cf41a
fix(mcp): resolve project names, and scope the publish credential
leggetter Aug 14, 2026
eb6ca42
docs: regenerate REFERENCE.md for the publish-api-key rename
leggetter Aug 14, 2026
1868d69
fix(outpost): stop publish silently going to the wrong project
leggetter Aug 14, 2026
3b48ac6
test(outpost): update MCP acceptance test for the platform tool prefix
leggetter Aug 17, 2026
f1e1923
Merge remote-tracking branch 'origin/integrate/outpost-mcp' into feat…
leggetter Aug 17, 2026
da683e3
Update package.json version to 2.6.0-beta.2
github-actions[bot] Aug 17, 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
9 changes: 9 additions & 0 deletions .github/workflows/acceptance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,19 @@ jobs:
- slice: "2"
api_key_secret: HOOKDECK_CLI_TESTING_API_KEY_3
tags: "attempt metrics issue transformation destination gateway"
# Outpost needs its own project: every `hookdeck outpost` command
# requires an Outpost project, which the Gateway keys above cannot
# satisfy. The key is a Project API key, used both to authenticate via
# `hookdeck ci` and directly for `outpost publish`, which does not
# accept CLI credentials.
- slice: "3"
api_key_secret: HOOKDECK_CLI_OUTPOST_TESTING_API_KEY
tags: "outpost"
runs-on: ubuntu-latest
env:
ACCEPTANCE_SLICE: ${{ matrix.slice }}
HOOKDECK_CLI_TESTING_API_KEY: ${{ secrets[matrix.api_key_secret] }}
HOOKDECK_CLI_OUTPOST_TESTING_API_KEY: ${{ secrets.HOOKDECK_CLI_OUTPOST_TESTING_API_KEY }}
HOOKDECK_CLI_TELEMETRY_DISABLED: "1"
steps:
- name: Check out code
Expand Down
20 changes: 20 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,26 @@ Summary for code and docs work:
- **Guest** — `listen` without login may call `POST /cli/guest`; separate from `--cli-key` onboarding.
- **`project list`** — Requires a user-associated CLI client key (`hookdeck login` or `hookdeck login --cli-key`). CI keys from `hookdeck ci` and raw Project API keys cannot list or switch projects (acceptance: `HOOKDECK_CLI_TESTING_CLI_KEY`).

- **`outpost publish`** — The publish API requires a **Project API key** sent as a bearer token and does not accept the CLI client key stored by `hookdeck login`. It therefore has its own `--api-key` flag defaulting to `HOOKDECK_API_KEY`, in the same shape as `hookdeck ci --api-key`. Every other `hookdeck outpost` command uses the stored credentials normally. When the key is missing the command fails with its own guidance rather than a bare 401, which the generic handler would otherwise rewrite into "your API key is invalid or expired" — accurate but useless here, since the stored key is never valid for this endpoint.

### Diagnosing a key before you debug anything else

The config file cannot tell you which credential you hold — `api_key` is the field name for every CLI client key regardless of origin. When a command fails with a permission or project error, establish the key's scope first:

- `hookdeck whoami` — the active project and its type. Does **not** reveal the key's scope.
- `hookdeck project list` — succeeds only with a user-associated key. A "scoped to a single project" error means the key came from `hookdeck ci`.

A project-scoped key is bound to one project, so it also ignores any attempt to target another project. Do not chase a project-selection bug before ruling this out.

### Keys used by acceptance tests

| Env var | Kind | Used for |
|---|---|---|
| `HOOKDECK_CLI_TESTING_API_KEY` (`_2`, `_3`) | Project API key, one per slice | The default runner; exchanged via `hookdeck ci` (`getAcceptanceAPIKey` in `test/acceptance/helpers.go`) |
| `HOOKDECK_CLI_TESTING_CLI_KEY` | User-associated CLI key | Only `project list` / `project use` tests, via `NewCLIRunnerWithKey` |

Each slice's key belongs to a **different project**, which is why tests must use unique resource names rather than assuming an empty project.

---

## Agent skills
Expand Down
134 changes: 134 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ For a complete reference of all commands and flags, see [REFERENCE.md](REFERENCE
- [Running in CI](#running-in-ci)
- [Event Gateway](#event-gateway)
- [Event Gateway MCP](#event-gateway-mcp)
- [Outpost](#outpost)
- [Outpost MCP](#outpost-mcp)
- [Manage connections](#manage-connections)
- [Transformations](#transformations)
- [Requests, events, and attempts](#requests-events-and-attempts)
Expand Down Expand Up @@ -663,6 +665,113 @@ Once the MCP server is configured, you can ask your agent questions like:
→ Agent uses hookdeck_events list with status FAILED and last_attempt_after set to yesterday's ISO datetime.
```

### Outpost

Manage [Hookdeck Outpost](https://hookdeck.com/docs/outpost) — your users (tenants), the destinations they own, and the events delivered to them.

These commands require an Outpost project. Switch with `hookdeck project use`; pointing them at an Event Gateway project reports which type the project is rather than failing obscurely.

```sh
hookdeck outpost [command]

# Available commands
hookdeck outpost tenant # Manage tenants
hookdeck outpost destination # Manage a tenant's destinations
hookdeck outpost destination-type # Inspect available destination types and their fields
hookdeck outpost event # Inspect published events, and retry delivery
hookdeck outpost attempt # Inspect delivery attempts
hookdeck outpost publish # Publish an event
hookdeck outpost topic # Inspect available topics
hookdeck outpost metrics # Query aggregate metrics
hookdeck outpost config # Manage project configuration and the portal domain
hookdeck outpost status # Show the deployment status
```

#### Destination config

Config and credential fields differ per destination type, and are defined by the Outpost deployment rather than the CLI, so they are passed as repeatable `key=value` pairs:

```sh
hookdeck outpost tenant upsert acme

hookdeck outpost destination create --tenant-id acme --type webhook \
--config url=https://example.com/hooks --topics user.created
```

To find out what a type accepts, either ask for it directly or add `--type` to `--help`:

```sh
hookdeck outpost destination-type get kafka
hookdeck outpost destination create --type kafka --help
```

Both list every field with whether it is required, whether it is sensitive, and any values or format it is constrained to. `--config-file` accepts a JSON object, and nested values — should a type ever need them — use dotted paths (`--config a.b=c`).

#### Publishing

`hookdeck outpost publish` is the one command that does **not** use the credentials stored by `hookdeck login`. The publish API requires a Hookdeck **Project API key**, so pass `--api-key` or set `HOOKDECK_API_KEY`:

```sh
hookdeck outpost publish --tenant-id acme --topic user.created \
--data '{"user_id":"123"}' --api-key $HOOKDECK_API_KEY
```

Create a Project API key in the Hookdeck dashboard under your project's settings. See [CLI authentication keys](#cli-authentication-keys) for how the key types differ.

Publishing is asynchronous: a successful response means the event was accepted, not delivered. Use `hookdeck outpost attempt list` to see the outcome.

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

### Outpost MCP

`hookdeck outpost mcp` starts an [MCP](https://modelcontextprotocol.io/) server exposing your Outpost project to AI agents: tenants, their destinations, the events published to them, and every delivery attempt. Tools are prefixed `outpost_`, so this server and [Event Gateway MCP](#event-gateway-mcp) can be configured in the same client.

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

The client starts `hookdeck outpost mcp` as a stdio subprocess. If you haven't authenticated yet, the `outpost_login` tool logs in via the browser. The active project must be an Outpost project; `outpost_projects` lists the Outpost projects available to you and switches between them.

#### Read-only by default

The server starts read-only. Each tool advertises only the actions that read data, so an agent is never offered an action it cannot perform. Add `--allow-write` (or set `HOOKDECK_MCP_ALLOW_WRITE=true`; the flag wins) to enable the rest:

```json
"args": ["outpost", "mcp", "--allow-write"]
```

`--read-only` is accepted as an explicit way to ask for the default, and wins if both are passed.

Two actions that only read are gated with the writes, because both return a reusable credential: `outpost_tenants` `token` mints a tenant-scoped access token, and `outpost_tenants` `portal` returns a URL granting access to a tenant's portal.

Publishing needs a Hookdeck **Project API key**, which the credentials stored by `hookdeck login` cannot substitute for. Without one the `outpost_publish` tool is not registered at all; pass `--api-key` or set `HOOKDECK_API_KEY` to enable it.

#### Available tools

| Tool | Description |
|------|-------------|
| `outpost_projects` | List Outpost projects or switch the active one for this session |
| `outpost_tenants` | Inspect tenants (list, get) and manage them (upsert, delete, token, portal) |
| `outpost_destinations` | Inspect a tenant's destinations (list, get) and manage them (create, update, delete, enable, disable) |
| `outpost_events` | Query published events (list, get) and retry delivery |
| `outpost_attempts` | Query delivery attempts — status, response codes, retry history |
| `outpost_publish` | Publish an event to a topic |
| `outpost_topics` | List the topics available in the project |
| `outpost_destination_types` | Inspect destination types and the config and credential fields each accepts |
| `outpost_metrics` | Query aggregate publish and delivery metrics |
| `outpost_config` | Read and change project configuration, including the portal's custom domain |
| `outpost_status` | Show the deployment status |
| `outpost_help` | Discover the available tools, their actions, and the current mode |

Call `outpost_help` at any time to see which mode the session is in and which actions it can perform.

### 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 @@ -1622,6 +1731,31 @@ These settings ensure that all changes to `main` go through proper review and te

Reference for how Hookdeck credentials relate to CLI commands. After any successful login or `hookdeck ci`, the CLI stores a **CLI client key** in your config file as `api_key` (see [Configuration files](#configuration-files)). The same field name is used regardless of how the key was obtained.

> **The `api_key` field in your config is not a Project API key.** It holds whichever CLI client key the last login produced. The field name is historical, so you cannot tell from the config file alone which kind of credential you have, or what it is allowed to do.

### Which key can do what

| | `hookdeck login`<br>`hookdeck login --cli-key` | `hookdeck ci --api-key` | Project API key<br>(dashboard) |
|---|---|---|---|
| What it is | CLI client key, tied to your user | CLI client key, tied to one project | Long-lived key from project settings |
| Stored in config as `api_key` | Yes | Yes | No — exchanged, never stored |
| `hookdeck listen`, `hookdeck gateway …` | Yes | Yes | No |
| `hookdeck project list` / `project use` | **Yes** | **No** — single project, no user | No |
| Accepted by `hookdeck ci --api-key` | No | No | **Yes** |

The distinction that catches people out is the middle column: a key from `hookdeck ci` works fine for everyday commands but is pinned to one project, so anything that spans projects fails.

### Check which key you have

`hookdeck whoami` shows the active project but not the key's scope. To tell the two CLI client keys apart, ask for something only a user-associated key can do:

```sh
hookdeck project list
```

- **A list of projects** — you have a user-associated key and can switch projects.
- **An error saying the credential is scoped to a single project** — you have a project-scoped key from `hookdeck ci`. Run `hookdeck login` (or `hookdeck login --cli-key <key>`) for account-wide access.

### CLI client keys (what the CLI runs as)

A **CLI client key** identifies the Hookdeck CLI to the API (`cli` authentication). It powers `hookdeck listen`, `hookdeck gateway …`, and most other commands after you are configured.
Expand Down
Loading
Loading