create_webhook
Subscribe to receive real-time notifications by creating a webhook. Includes a one-time secret for HMAC validation.
Instructions
[write] Create a webhook subscription. The response includes webhook_secret ONCE; the bot must persist it for HMAC validation. Counts against the subscription cap.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| webhook_url | Yes | ||
| subscriber_name | No | ||
| notes | No |
Implementation Reference
- src/tools.ts:69-69 (handler)The handler function for create_webhook – sends a POST request to /api/v1/webhooks with the input payload (webhook_url, optional subscriber_name, optional notes).
handler: (input, c) => c.request("POST", "/api/v1/webhooks", input), - src/tools.ts:64-68 (schema)Input schema for create_webhook using Zod: requires webhook_url (valid URL string), and optionally accepts subscriber_name (max 120 chars) and notes (max 500 chars).
inputSchema: z.object({ webhook_url: z.string().url(), subscriber_name: z.string().max(120).optional(), notes: z.string().max(500).optional(), }), - src/tools.ts:60-63 (registration)Registration of the create_webhook tool in the TOOLS array with name, description, and write scope. Registered alongside all other tools in src/tools.ts.
name: "create_webhook", description: "Create a webhook subscription. The response includes webhook_secret ONCE; the bot must persist it for HMAC validation. Counts against the subscription cap.", scope: "write", - src/index.ts:45-45 (registration)The MCP CallToolRequestSchema handler looks up the tool by name in the TOOLS array and dispatches to its handler – this is how create_webhook gets invoked at runtime.
server.setRequestHandler(CallToolRequestSchema, async (req) => { - src/client.ts:23-55 (helper)The FeedbagelClient.request() helper method that create_webhook's handler calls – sends an HTTP POST with JSON body to the feedbagel API.
async request( method: string, path: string, body?: unknown, ): Promise<unknown> { const res = await fetch(`${this.baseUrl}${path}`, { method, headers: { Authorization: `Bearer ${this.apiKey}`, ...(body !== undefined ? { "content-type": "application/json" } : {}), }, body: body !== undefined ? JSON.stringify(body) : undefined, }); const text = await res.text(); let json: unknown = undefined; try { json = text ? JSON.parse(text) : undefined; } catch { json = { raw: text }; } if (!res.ok) { // Surface 429 and 4xx details verbatim so the agent sees the cap info. const err: Error & { status?: number; body?: unknown } = new Error( `HTTP ${res.status} ${res.statusText}`, ); err.status = res.status; err.body = json; throw err; } return json; }