MCP server for HookSense — the webhook & callback layer for AI agents. Create a callback URL, wait_for_callback instead of polling, and verify signatures, from any MCP client.
HookSense MCP demonstrates solid definition quality with clear, action-verb naming conventions and comprehensive parameter descriptions. All 8 tools are properly registered with complete input schemas (JSON Schema with type and property definitions). Descriptions are consistently above the 20-char minimum (average ~180 chars) and explain WHEN to use each tool and what it returns. However, output schemas are entirely undocumented, the code shows tool definitions but no response schema specifications. This is a critical gap: LLMs cannot plan downstream calls or extract chaining IDs (e.g., requestId returned by wait_for_callback is used by get_callback_payload and verify_signature) without knowing the response structure. Additionally, error handling is minimal, no explicit guidance on retryability, user-fixable errors, or recovery paths. The composition is sound (each tool has one responsibility; naming is distinct and verb-driven), but the lack of output documentation and error recovery patterns prevent a higher score.
Create a callback endpoint and return its URL. Hand this URL to a long-running/async job (or another agent) as its webhook/callback target, then await the result with wait_for_callback. Also works as a plain webhook capture URL for any provider (Stripe, GitHub, …).
Fetch a single received callback with full headers, decrypted body, and metadata. Use this to read the result of an async job after wait_for_callback or list_callbacks gives you a callback id.
Get details about a specific endpoint — its full URL, signature provider config, and custom response settings.
List callbacks received by an endpoint, newest first. Returns a summary (method, status, provider, received_at). Use `get_callback_payload` for the full body. Tip: read the newest `received_at` and pass it as `after` to wait_for_callback to wait only for what comes next.
List all webhook endpoints owned by the authenticated user. Returns slug, created_at, and request counts.
Output schemas are entirely undocumented. No response structure defined for any tool. LLMs cannot know what fields (e.g., requestId, receivedAt, endpoint URL) will be returned, preventing them from chaining tools and extracting necessary IDs for follow-up calls.
No error recovery guidance. Tools throw generic API errors (e.g., 'HTTP 401') with no actionable next steps. LLMs don't know whether to retry, ask for credentials, or try an alternative tool. Error handling should categorize failures as retryable (token expired → re-authenticate), user-fixable (invalid slug format), or fatal (resource permanently deleted).
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 65 | 2026-07-28+ | v2 |
Replay a received callback to a target URL. The original headers and body are re-sent unchanged — useful to re-drive your handler against a known payload without re-triggering the upstream event.
Verify the HMAC signature of a received callback against the endpoint's configured secret (Stripe, GitHub, Shopify, or custom), using a timing-safe comparison. Returns whether the callback is authentic and untampered — call this before your agent acts on a payload. Requires the endpoint to have a webhook secret configured and a paid plan.
Block until the next webhook (callback) arrives at an endpoint, then return it — instead of polling. Use this for async/long-running work: kick off the job with the endpoint URL as its callback, then call wait_for_callback to receive the result the moment it lands (signature-verified, decrypted). Returns { status: 'received', request } on delivery, or { status: 'pending' } if `timeoutMs` elapses first (just call again to keep waiting). Pass `after` (the receivedAt of the last callback you saw) so a callback that arrived between calls is returned immediately rather than missed.
Parameter constraint documentation incomplete. 'slug' is described as '3-32 chars, letters/numbers/hyphens' but lacks enum or pattern constraint in schema. 'limit' in list_callbacks is described as '1-100, default 20' but schema has no minimum/maximum fields. Constraints should appear in both description AND schema.
No pagination support documented. list_endpoints and list_callbacks accept a 'limit' but there's no 'offset'/'next_cursor' or 'total_count' in the descriptions. Large result sets could exceed context windows; pagination mechanism should be explicit.
Missing context on tool interdependencies. 'create_callback_endpoint' returns an endpoint URL, but the description doesn't specify that the 'slug' from the response is what you pass to 'list_callbacks' and 'wait_for_callback'. Similarly, 'wait_for_callback' returns a requestId used by 'get_callback_payload' and 'verify_signature', this chaining is not documented.