attach_feed_to_webhook
Attach a feed to a webhook subscription to automatically deliver new entries.
Instructions
[write] Attach a feed to a webhook subscription so its new entries get delivered.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| webhook_id | Yes | Webhook subscriber UUID | |
| feed_id | Yes | Numeric feed id |
Implementation Reference
- src/tools.ts:96-105 (handler)The tool definition for 'attach_feed_to_webhook' including its handler function. The handler destructures webhook_id and feed_id from input and sends a POST request to /api/v1/webhooks/${webhook_id}/feeds with the feed_id in the body.
{ name: "attach_feed_to_webhook", description: "Attach a feed to a webhook subscription so its new entries get delivered.", scope: "write", inputSchema: WebhookIdInput.merge(FeedIdInput), handler: ({ webhook_id, feed_id }: any, c) => c.request("POST", `/api/v1/webhooks/${webhook_id}/feeds`, { feed_id, }), - src/tools.ts:19-25 (schema)FeedIdInput and WebhookIdInput Zod schemas used by the tool. The tool's inputSchema merges both: feed_id (positive integer) and webhook_id (UUID string).
const FeedIdInput = z.object({ feed_id: z.number().int().positive().describe("Numeric feed id"), }); const WebhookIdInput = z.object({ webhook_id: z.string().describe("Webhook subscriber UUID"), }); - src/index.ts:37-43 (registration)The MCP server registers all tools from the TOOLS array. When ListToolsRequestSchema is received, it maps each tool (including attach_feed_to_webhook) to its name, description, and JSON schema. When CallToolRequestSchema is received, it finds the tool by name, validates input, and invokes the handler.
server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS.map((t) => ({ name: t.name, description: `[${t.scope}] ${t.description}`, inputSchema: zodToJsonSchema(t.inputSchema, { target: "openApi3" }), })), })); - src/client.ts:23-56 (helper)The FeedbagelClient.request() helper method that the tool handler calls. It sends an HTTP request with Bearer token auth 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; } }