Tool Reference
Complete reference for all 38 MCP tools available to AI coding agents, plus the sandbox tools for agents without an account. Parameters, return types, and usage examples for endpoint, request, email, forwarding, and webhook operations.
Updated Oct 2026
Endpoint management
create_endpoint
Create a new webhook endpoint. Returns the endpoint slug and full URL.
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | no | Display name for the endpoint |
ephemeral | boolean | no | Auto-delete after 12 hours |
expiresIn | string | no | Custom expiry duration (e.g., "2h", "7d") |
mockResponse | object | no | Mock response config (see fields below) |
responseRules | array | no | Conditional response rules (method/path/header/body conditions + responses) |
notificationUrl | string | no | URL to POST a JSON summary on each request |
signingProvider | string | no | Provider for automatic signature verification (e.g., stripe, github) |
signingSecret | string | no | Signing secret (encrypted server-side). Required when signingProvider is set |
signingHeader | string | no | Custom header name (only for generic-hmac provider) |
mockResponse fields:
| Field | Type | Required | Description |
|---|---|---|---|
status | number | yes | HTTP status code (100-599) |
body | string | no | Response body |
headers | Record<string, string> | no | Response headers |
delay | number | no | Response delay in ms (0-30000) |
create_endpoints
Create 1--20 endpoints in a single call. Returns an array of created endpoints.
| Parameter | Type | Required | Description |
|---|---|---|---|
count | number | yes | Number of endpoints to create (1--20) |
namePrefix | string | no | Prefix for auto-generated names |
ephemeral | boolean | no | Auto-delete after 12 hours |
expiresIn | string | no | Custom expiry duration |
list_endpoints
List the endpoints you own (each with sharedWith) and those shared with you through a subscribed team (each with fromTeam, the oldest share, and fromTeams, every one of your teams it is shared with).
| Parameter | Type | Required | Description |
|---|---|---|---|
team | string | no | Team id or unique name; keeps only endpoints tied to that team via fromTeams, fromTeam, or sharedWith. Ambiguous names are an error |
get_endpoint
Get details for an endpoint by slug.
| Parameter | Type | Required | Description |
|---|---|---|---|
slug | string | yes | Endpoint slug |
update_endpoint
Update an endpoint's name, mock response, notification webhook, signing configuration, or whether codes and links are picked out of its emails.
| Parameter | Type | Required | Description |
|---|---|---|---|
slug | string | yes | Endpoint slug |
name | string | no | New display name |
mockResponse | object | no | Mock response config (see fields above), or null to clear |
responseRules | array | no | Conditional response rules, or null to clear |
notificationUrl | string | no | Notification webhook URL, or null to clear |
signingProvider | string | no | Signing provider (e.g., stripe), or null to disable |
signingSecret | string | no | New signing secret (encrypted server-side), or null to clear |
signingHeader | string | no | Custom header name (only for generic-hmac), or null to clear |
showEmailExtracts | boolean | no | Pick codes and links out of emails (dashboard and forwarded JSON); owner only |
delete_endpoint
Delete an endpoint and all its captured requests.
| Parameter | Type | Required | Description |
|---|---|---|---|
slug | string | yes | Endpoint slug |
delete_endpoints
Delete 1--100 endpoints in a single call.
| Parameter | Type | Required | Description |
|---|---|---|---|
slugs | string[] | yes | Array of endpoint slugs to delete (1--100) |
Sending and testing
send_webhook
Send a test webhook to a hosted webhooks.cc endpoint. Supports manual payloads and provider templates, including signed templates for providers that support shared-secret or token-style signing.
| Parameter | Type | Required | Description |
|---|---|---|---|
slug | string | yes | Endpoint slug |
method | string | no | HTTP method (default: "POST") |
headers | object | no | HTTP headers to include |
body | any | no | Request body |
provider | string | no | Provider template (stripe, github, shopify, twilio, slack, paddle, linear, sendgrid, clerk, discord, vercel, gitlab, typeform, standard-webhooks, meta, lemonsqueezy, coinbase-commerce, razorpay, cal, intercom, telegram, square, hubspot, mailgun, calendly, mux, sentry, bitbucket, docusign, adyen, paypal, plaid, resend, workos) |
template | string | no | Template name (e.g., checkout.session.completed or form_response) |
event | string | no | Event type override |
secret | string | yes (for signed providers) | Template signing input. Required for signed provider templates; sendgrid, discord, and plaid templates are unsigned and need no secret. |
Example provider-template call:
{
"slug": "abc123",
"provider": "typeform",
"template": "form_response",
"secret": "typeform_test_secret"
}send_to
Send a webhook directly to any URL -- localhost, staging, production. Same signing support as send_webhook.
| Parameter | Type | Required | Description |
|---|---|---|---|
url | string | yes | Target URL (http or https) |
method | string | no | HTTP method (default: "POST") |
headers | object | no | HTTP headers to include |
body | any | no | Request body |
provider | string | no | Provider for signing |
template | string | no | Template name |
event | string | no | Event type override |
secret | string | yes (for signed providers) | Signing secret (not needed for sendgrid, discord, plaid) |
preview_webhook
Build a webhook request without sending it. Returns the computed URL, method, headers, and body so you can inspect signatures before delivery.
| Parameter | Type | Required | Description |
|---|---|---|---|
url | string | yes | Target URL |
method | string | no | HTTP method |
headers | object | no | HTTP headers |
body | any | no | Request body |
provider | string | no | Provider for signing |
template | string | no | Template name |
event | string | no | Event type override |
secret | string | yes (for signed providers) | Signing secret (not needed for sendgrid, discord, plaid) |
test_webhook_flow
Run a full end-to-end test: create endpoint, set mock response, send webhook, wait for capture, verify signature, replay to target, clean up.
| Parameter | Type | Required | Description |
|---|---|---|---|
provider | string | no | Provider template to use |
event | string | no | Event type |
secret | string | no | Signing secret |
mockStatus | number | no | HTTP status for mock response |
targetUrl | string | no | URL to replay the captured request to |
verifySignature | boolean | no | Verify the webhook signature after capture |
cleanup | boolean | no | Delete the endpoint after the test (default: true) |
Request management
list_requests
List captured requests for an endpoint, newest first. Emails come back with kind: "email" and the parsed message in email, without the raw message or the HTML part (email.htmlSize gives its length; size is the message size in bytes), and with the text cut at 8,000 characters. An email that is still too big loses its headers (headersOmitted), then sender, address and attachment entries past the first 5, then text, and as a last resort everything but its subject, first sender (fromTotal), tag, date and text (trimmed), so each email fits on its own. The other request tools and the MCP resources return emails the same way; use get_email for the HTML.
| Parameter | Type | Required | Description |
|---|---|---|---|
endpointSlug | string | yes | Endpoint slug |
limit | number | no | Max results to return |
since | number | no | Only return requests after this timestamp in ms |
kind | string | no | http for HTTP requests only, email for emails only |
get_request
Get full details of a captured request, including headers and body.
| Parameter | Type | Required | Description |
|---|---|---|---|
requestId | string | yes | Request ID |
wait_for_request
Poll until a request arrives at an endpoint, then return it.
| Parameter | Type | Required | Description |
|---|---|---|---|
endpointSlug | string | yes | Endpoint slug |
timeout | number | no | Max wait time in milliseconds |
pollInterval | number | no | Interval between polls in milliseconds |
wait_for_requests
Poll until a specified number of requests arrive at an endpoint.
| Parameter | Type | Required | Description |
|---|---|---|---|
endpointSlug | string | yes | Endpoint slug |
count | number | yes | Number of requests to wait for |
timeout | number | no | Max wait time in milliseconds |
pollInterval | number | no | Interval between polls in milliseconds |
method | string | no | Filter by HTTP method |
search_requests
Full-text search across captured requests. Supports time ranges, method filters, and pagination.
| Parameter | Type | Required | Description |
|---|---|---|---|
slug | string | no | Filter by endpoint slug |
method | string | no | Filter by HTTP method |
kind | string | no | http for HTTP requests only, email for emails only |
q | string | no | Search query (searches headers and body) |
from | string | no | Start time -- relative duration like "1h" or ISO timestamp |
to | string | no | End time -- relative duration or ISO timestamp |
limit | number | no | Max results |
offset | number | no | Pagination offset |
order | string | no | "asc" or "desc" |
count_requests
Count requests matching the given filters. Accepts the same filter parameters as search_requests.
| Parameter | Type | Required | Description |
|---|---|---|---|
slug | string | no | Filter by endpoint slug |
method | string | no | Filter by HTTP method |
kind | string | no | http or email |
q | string | no | Search query |
from | string | no | Start time |
to | string | no | End time |
limit | number | no | Max results |
offset | number | no | Pagination offset |
order | string | no | "asc" or "desc" |
clear_requests
Delete captured requests for an endpoint without deleting the endpoint itself.
| Parameter | Type | Required | Description |
|---|---|---|---|
slug | string | yes | Endpoint slug |
before | string | no | Delete only requests before this timestamp |
Emails
Every endpoint on an account receives email at {slug}@mailhooks.cc, and at {slug}+{tag}@mailhooks.cc for any tag, which lands on the same endpoint. Use a fresh tag for each test run so an agent finds its own email. Each email counts as one request. The one-time code and main link come from the same finder as the dashboard; they are left out when the endpoint's owner turned off "Show codes and links found in emails".
list_emails
List the emails an endpoint received, newest first, one line each: id, receivedAt, address, tag, subject, from, code, link, and the number of attachments. A main link over 8,000 characters is left out (linkOmitted).
| Parameter | Type | Required | Description |
|---|---|---|---|
endpointSlug | string | yes | Endpoint slug |
limit | number | no | Max emails to return (1 to 100, default 25). With tag, subject or from, the newest 100 emails are searched |
since | number | no | Only emails received after this timestamp in ms |
tag | string | no | Only emails sent to this +tag (case-sensitive) |
subject | string | no | Only emails whose subject contains this text |
from | string | no | Only emails from this address (case-insensitive) |
get_email
Get one email: by requestId, or the newest at endpointSlug (optionally with a tag). Pass exactly one of the two. Returns the parsed message in the shape of forwarded JSON (subject, from, to, text, attachments, auth, headers, ...) with code and link first. The text is cut at 8,000 characters (textTruncated: true), and the HTML is left out (htmlSize gives its length) unless includeHtml is set. Tool output is capped at 32 KB, so a large email is trimmed to fit and stays valid JSON: first its headers are left out (headersOmitted), then codes and links past the first 10 (codesTruncated, linksTruncated), then address and attachment entries past the first 5 (toTotal, attachmentsTotal, ...); then the HTML and the text are cut (htmlTruncated, textTruncated), and as a last resort only the essentials stay (trimmed), without a main link too long to use (linkOmitted).
| Parameter | Type | Required | Description |
|---|---|---|---|
requestId | string | no | The email's request ID |
endpointSlug | string | no | Get the newest email at this endpoint instead |
tag | string | no | With endpointSlug: only this +tag |
includeHtml | boolean | no | Include the HTML part (default false) |
wait_for_email
Wait for an email to arrive, for example after the agent submitted a signup form, then return it like get_email. Looks back five minutes unless since is given.
| Parameter | Type | Required | Description |
|---|---|---|---|
endpointSlug | string | yes | Endpoint slug |
tag | string | no | Only emails sent to this +tag |
subject | string | no | Only emails whose subject contains this text |
from | string | no | Only emails from this address |
timeout | string | number | no | How long to wait (default "30s"). Keep it under your MCP client's request timeout, often 60 seconds |
since | number | no | Only emails received after this timestamp in ms |
includeHtml | boolean | no | Include the HTML part (default false) |
send_test_email
Deliver a sample email with a 6-digit code and a link, to try the email tools before wiring up a real sender. It counts as one request and skips SMTP, so no sender checks run on it. Returns status, requestId and the address it went to.
| Parameter | Type | Required | Description |
|---|---|---|---|
slug | string | yes | Endpoint slug |
tag | string | no | Deliver to {slug}+{tag}@mailhooks.cc |
Forwarding
Forwarding sends every HTTP request and email an endpoint captures to a URL or a Slack or Discord channel, queued, retried and logged with its timing. Only the endpoint's owner can manage it.
configure_forwarding
Change the forwarding settings; only the arguments passed change. Saving the first URL creates the signing secret, so the agent can send a test delivery before turning forwarding on. Turning forwarding (or a kind) off fails the deliveries still waiting. Returns every forwarding setting, with header values masked.
| Parameter | Type | Required | Description |
|---|---|---|---|
slug | string | yes | Endpoint slug |
url | string | null | no | https URL on a public host name, or null to remove it (when off) |
enabled | boolean | no | Turn forwarding on (needs a URL) or off |
http | boolean | no | Forward HTTP requests |
email | boolean | no | Forward emails |
format | "auto" | "as_received" | "json" | "chat" | no | How deliveries go out; auto picks chat for Slack and Discord URLs |
headers | { name, value | null }[] | no | Your own headers (at most 10); replaces the list, null keeps a stored value |
appendPath | boolean | no | Add the path after the slug to the URL for relayed requests (default true) |
retrySeconds | 0 | 3600 | 86400 | no | How long failed deliveries are retried (default a day) |
keepOrder | boolean | no | One delivery at a time, in capture order |
sentField | string | null | no | JSON body field with the sender's timestamp, such as publishedAt, for timing |
get_forwarding_secret
Read the whsec_ secret deliveries are signed with, or replace it with rotate: true. The value is a credential and ends up in the agent's context: have the agent put it in the handler's environment, not in code.
| Parameter | Type | Required | Description |
|---|---|---|---|
slug | string | yes | Endpoint slug |
rotate | boolean | no | Replace the secret (default false) |
test_forwarding
Send the newest captured request of a kind (or a sample, if none has arrived) to the saved URL once, exactly as a delivery would go out, and report the status, durationMs, the start of the answer (excerpt), error, delivered, the format and target used, and the sender's own timestamp when the request had one. Works with forwarding on or off; nothing is retried or logged.
| Parameter | Type | Required | Description |
|---|---|---|---|
slug | string | yes | Endpoint slug |
kind | "http" | "email" | no | Which kind (default: HTTP when HTTP requests are forwarded) |
list_deliveries
With endpointSlug, return the endpoint's delivery log with its counts: { summary, deliveries, nextCursor }. Rows carry senderAt when the request had the sender's own timestamp, so receivedAt - senderAt is the time to reach webhooks.cc. With requestId, return every delivery and try of one request or email. Pass exactly one.
| Parameter | Type | Required | Description |
|---|---|---|---|
endpointSlug | string | no | The endpoint's delivery log |
requestId | string | no | Every delivery of this request, with each try |
limit | number | no | With endpointSlug: 1 to 100 (default 20) |
status | "all" | "pending" | "failed" | no | With endpointSlug: filter (default all) |
before | string | no | With endpointSlug: nextCursor, for older rows |
redeliver
Forward again with the current settings: one request or email (requestId, which also sends one that was never forwarded), or every request whose latest delivery failed (endpointSlug, oldest first, up to 1,000 at a time). Pass exactly one. Fails while forwarding is off.
| Parameter | Type | Required | Description |
|---|---|---|---|
requestId | string | no | The request or email to send again |
endpointSlug | string | no | Send every failed delivery of this endpoint |
Request analysis
replay_request
Replay a captured request to a target URL. Sends the original method, headers, and body.
| Parameter | Type | Required | Description |
|---|---|---|---|
requestId | string | yes | ID of the captured request |
targetUrl | string | yes | URL to send the replayed request to |
compare_requests
Diff two captured requests. Returns structured differences in method, headers, and body.
| Parameter | Type | Required | Description |
|---|---|---|---|
leftRequestId | string | yes | First request ID |
rightRequestId | string | yes | Second request ID |
ignoreHeaders | string[] | no | Header names to exclude from comparison |
extract_from_request
Extract specific JSON fields from a captured request body using dot-notation paths.
| Parameter | Type | Required | Description |
|---|---|---|---|
requestId | string | yes | Request ID |
jsonPaths | string[] | yes | Dot-notation paths to extract (e.g., ["data.object.id", "type"]) |
verify_signature
Verify the webhook signature on a captured request. Supports two modes:
- Stored result (no provider/secret) — returns the pre-computed server-side verification result when signing is configured on the endpoint
- Client-side (with provider + secret for HMAC providers, or provider + publicKey for Discord) — performs verification on demand
| Parameter | Type | Required | Description |
|---|---|---|---|
requestId | string | yes | Request ID |
provider | string | no | Provider name (stripe, github, shopify, twilio, slack, paddle, linear, discord, clerk, vercel, gitlab, typeform, standard-webhooks, meta, lemonsqueezy, coinbase-commerce, razorpay, cal, intercom, telegram, square, hubspot, mailgun, calendly, mux, sentry, bitbucket, docusign, adyen, paypal). Omit to return stored result |
secret | string | no | Signing secret (required for client-side HMAC-based verification) |
publicKey | string | no | Public key (required for Discord Ed25519 verification) |
url | string | no | Request URL (required for Twilio, Square, and HubSpot signature verification) |
method | string | no | HTTP method used when the signature was generated (used by HubSpot v3; the SDK assumes POST when omitted) |
Teams
An API key carries the team access of the account it belongs to. Shared endpoints already appear in list_endpoints and work with every request tool by slug except clear_requests, which only the owner may call; these tools manage the teams. Invites are not exposed: accepting one claims a paid seat and inviting sends email, so those stay with people (dashboard, whk teams, or the SDK).
list_teams
List the teams you own or belong to: role, seats, requestsUsed and requestLimit of the pooled quota, periodEnd, and whether the team is suspended. No parameters.
list_team_members
List a team's members and pending invites.
| Parameter | Type | Required | Description |
|---|---|---|---|
teamId | string | yes | Team id from list_teams |
share_endpoint
Share an endpoint you own with a team. The team needs an active subscription; the endpoint's requests then draw from the team's pooled quota.
| Parameter | Type | Required | Description |
|---|---|---|---|
slug | string | yes | Slug of an endpoint you own |
teamId | string | yes | Team id from list_teams |
unshare_endpoint
Stop sharing an endpoint you own with a team. Same parameters as share_endpoint.
Utilities
get_usage
Your plan's request usage, remaining quota, and period end, plus a teams array with the pooled quota of every subscribed team you belong to. No parameters.
list_provider_templates
List supported webhook providers, available templates, and signing metadata. Use this before send_webhook when an agent needs to pick a realistic provider payload.
| Parameter | Type | Required | Description |
|---|---|---|---|
provider | string | no | Filter to a single provider |
Example:
{
"provider": "typeform"
}describe
Self-documenting schema of all available operations and their parameters. No parameters.
Without an API key: the agent sandbox
A server started without WHK_API_KEY registers these ten tools instead of the ones above. The seven endpoint and request tools have the same names and arguments as the full tools, but run in the agent sandbox (auth.md): up to 3 endpoints at a time, 25 captured requests each and 100 in all, deleted 24 hours after the sandbox was created. Captures are readable only by this agent.
| Tool | In the sandbox |
|---|---|
create_endpoint | Creates a capture endpoint. The first call registers the sandbox (a few seconds of proof of work). mockResponse, responseRules, notificationUrl and the signing options are refused; name and expiresIn are ignored. |
list_endpoints | This agent's sandbox endpoints; empty before the first create_endpoint. team is refused. |
get_endpoint | One sandbox endpoint, with its limits and usage |
delete_endpoint | Frees a slot; the 100-request budget is not refunded |
list_requests | Captured requests, newest first (HTTP only) |
get_request | One captured request |
wait_for_request | Waits for a capture |
connect_account
Connect the agent to a human's account. Returns verificationUri, a 6-digit userCode and a tellTheHuman line to show them: they sign in or sign up with that email and enter the code. With a sandbox, its endpoints move into the account with what they captured; without one, the agent registers for that human directly. Calling it again gives a new code.
| Parameter | Type | Required | Description |
|---|---|---|---|
email | string | yes | The human's email address; only someone signed in as it can connect |
wait_for_connection
Wait for the human to enter the code. On success the full tools for their account replace the sandbox tools (the server sends notifications/tools/list_changed). Otherwise it returns status waiting (call it again), expired (call connect_account for a new code) or declined. The connection lasts while the server runs; set WHK_API_KEY for a lasting setup.
| Parameter | Type | Required | Description |
|---|---|---|---|
timeoutSeconds | number | no | How long to wait, 1 to 600 seconds (default 45) |
about_sandbox
The sandbox limits, what needs an account, and how to connect one. No parameters and no network call.
For provider templates in send_webhook and send_to, secret is required for every signed
provider. Only sendgrid, discord, and plaid templates are unsigned and need no secret. The
MCP server does not inject a default secret.
MCP Overview
Installation, setup, and getting started with the MCP server.
Agent Workflows
Multi-turn conversation examples for common webhook tasks.