nahook-mcp
Official# nahook-mcp
The official **Model Context Protocol** server for [Nahook](https://nahook.com) — drive webhook deliveries, endpoints, and event triggers from Claude Desktop, Cursor, Cline, and any other MCP-compatible AI assistant.
> The MCP server ships as a subcommand of the [`nahook` CLI](https://github.com/getnahook/nahook-cli). One binary, one credentials file, one install path.
[](https://glama.ai/mcp/servers/getnahook/nahook-mcp)
## What it does
Once installed and authenticated, your AI assistant can:
- **Inspect** endpoints, deliveries, and per-attempt logs to debug failed webhooks.
- **Retry** failed or dead-lettered deliveries.
- **Trigger** events and fan them out to every subscribed endpoint.
- **Send** webhooks directly to a single endpoint.
- **Manage** endpoints (create, update, pause, resume) — never delete, by design.
Write operations are tagged with the MCP `destructiveHint`/`readOnlyHint` annotations so MCP clients surface a per-call human-approval prompt before anything mutates state.
## Security guardrails
Webhook payloads are third-party data, so the server treats everything that flows back into the model's context as a potential prompt-injection channel:
- **Untrusted content is fenced.** Every producer- or receiver-authored value that reaches the model — webhook payloads (`get_delivery` with `include_payload`), delivery idempotency keys, and receiver error messages (`list_attempts`) — is wrapped in explicit `<<<UNTRUSTED CONTENT ...>>>` delimiters with embedded fence markers neutralized, and the server instructions tell the model to treat fenced content as inert data, never as instructions.
- **Payloads are capped.** Bodies over 256 KB are truncated (flagged via `payload_truncated`) so a hostile producer can't stuff the model's context. Tune the cap with `NAHOOK_MCP_PAYLOAD_CAP=<bytes>` in the MCP client's environment.
- **No delete tools, by design.** Nothing in the tool surface can destroy data.
- **`update_endpoint` is marked destructive.** It overwrites live endpoint config (repointing its URL is the primitive an injection would target), so its `destructiveHint` is `true` and clients surface a prominent approval prompt.
- **Write tools rely on human approval.** Per the MCP spec, annotations are advisory hints, not access control — the security boundary is the client's per-call approval prompt, which applies to every non-read tool. The additive write tools (`create_endpoint`, `send_to_endpoint`, `trigger_event`) are annotated `destructiveHint: false` per their spec semantics; keep human-in-the-loop approval enabled in your MCP client and don't blanket-allow them. If you want a hard guarantee of no writes, run the server without an ingestion key (disables sending) and treat management tools as approval-gated.
- **Secrets never reach the model.** Endpoint signing secrets and auth tokens are omitted from every tool output; `whoami` returns only the token's public id.
- **Split credentials.** Sending (`trigger_event`, `send_to_endpoint`) requires a separate ingestion key — omit it and the server is management/read-only for ingestion.
Client-side measures can't make prompt injection impossible — pair them with your MCP client's tool-approval prompts.
## Install
The MCP server is a subcommand of the `nahook` CLI. Install the CLI, then add it to your AI client.
### 1. Install the CLI
**macOS / Linux (Homebrew):**
```sh
brew install getnahook/tap/nahook
```
**Linux / macOS (install script):**
```sh
curl -fsSL https://cli.nahook.com/install.sh | sh
```
See [getnahook/nahook-cli](https://github.com/getnahook/nahook-cli) for other install options.
### 2. Log in once
```sh
nahook login
```
This opens your browser, walks you through device-grant authentication, and writes credentials to `~/.nahook/config.toml`.
### 3. Wire the MCP server into your AI client
**Claude Desktop & Claude Code CLI:**
```sh
claude mcp add nahook -- nahook mcp serve
```
**Cursor** — edit `~/.cursor/mcp.json`:
```json
{
"mcpServers": {
"nahook": {
"command": "nahook",
"args": ["mcp", "serve"]
}
}
}
```
**Cline (VS Code)** — Cline → Settings → MCP Servers → add:
```json
{
"nahook": {
"command": "nahook",
"args": ["mcp", "serve"]
}
}
```
**Zed** — add to `settings.json`:
```json
{
"assistant": {
"mcp_servers": {
"nahook": {
"command": "nahook",
"args": ["mcp", "serve"]
}
}
}
}
```
Other MCP-compatible clients (Continue, Windsurf, Goose, …) follow the same `command + args` shape.
## Tools
| Tool | What it does |
|------|--------------|
| `whoami` | Local config sanity check — workspace, region, token id, expiry. |
| `list_endpoints` | List every endpoint in the current workspace. |
| `get_endpoint` | Fetch one endpoint by `ep_xxx`. |
| `create_endpoint` | Create a new endpoint. Defaults to the workspace's default environment; also accepts slugs like `production`. |
| `update_endpoint` | Partial patch — pause/resume, change URL, update description. |
| `list_environments` | List every environment in the workspace. |
| `list_deliveries` | Page through an endpoint's deliveries, newest-first. |
| `get_delivery` | Fetch one delivery by `del_xxx`. Pass `include_payload: true` to also fetch the original webhook body — critical for debugging. |
| `list_attempts` | List every attempt against a delivery (useful for debugging failures). |
| `retry_delivery` | Re-enqueue a failed or dead-lettered delivery. |
| `trigger_event` | Fire an event by type — the backend fans it out to every subscriber. |
| `send_to_endpoint` | Send a webhook directly to one endpoint. |
## Authentication model
The MCP server uses two separate credentials:
- **CLI login token** (`nhc_…`) — written by `nahook login`. Powers read tools and management operations on endpoints / deliveries / environments.
- **Ingestion key** (`nhk_…`) — the same key your SDKs use. Powers `trigger_event` and `send_to_endpoint`. Set it via `NAHOOK_INGESTION_KEY=nhk_...` in the MCP client's environment, or add `ingestion_key = "nhk_..."` to `~/.nahook/config.toml`. The server fails loudly if a write tool is called without one configured.
Permissions are evaluated **per request** against your workspace role — the MCP token has exactly the permissions you have in the dashboard, nothing more.
## Where the code lives
The MCP server implementation is part of the [`nahook` CLI source tree](https://github.com/getnahook/nahook-cli/tree/main/internal/commands/mcp). This repo exists as a discoverability surface — README, MCP directory entries, and packaging metadata. There is no separate codebase to maintain.
If you want to file a bug, request a tool, or contribute: please open the issue at [getnahook/nahook-cli](https://github.com/getnahook/nahook-cli/issues).
## License
[MIT](./LICENSE) — same as the CLI.
TDQS
Scored across 12 tools
Each tool targets a distinct resource and action. There is no ambiguity between tools like create_endpoint vs update_endpoint, or list_deliveries vs list_attempts. send_to_endpoint and trigger_event are clearly differentiated by direct vs fan-out behavior.
Tools consistently use verb_noun naming in snake_case. The only outlier is 'whoami', which follows a common convention but deviates from the pattern. Overall, the naming is predictable and readable.
12 tools provide a well-scoped set for managing webhook endpoints, deliveries, and events. The count is neither too small nor too large, covering essential operations without being overwhelming.
The tool set is missing critical operations such as deleting an endpoint and managing subscriptions (which are implied by trigger_event). There is no way to list, add, or remove event subscriptions, which would be necessary for a complete webhook management system.