List webhooks
lob_webhooks_listList webhook subscriptions on your account, with optional date and metadata filters, and paginate results using before/after cursors.
Instructions
List webhook subscriptions on your account. Note: Lob's /webhooks does NOT support include: ['total_count'] — for a count, just inspect data.length (webhook lists are small).
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | How many results to return (default 10, max 100). | |
| before | No | Cursor for the previous page. | |
| after | No | Cursor for the next page. | |
| include | No | Response add-ons. Pass ['total_count'] alongside any filters and limit:1 to answer 'how many?' questions in a single call — far cheaper than paginating to count. Not accepted on nested order endpoints (buckslip/card orders) or /webhooks. | |
| date_created | No | ISO8601 date filter object with gt/gte/lt/lte keys, e.g. { gt: '2026-04-23T00:00:00Z' } for 'last 7 days'. Combine with include:['total_count'] and limit:1 for date-bounded counts. | |
| metadata | No | Filter by metadata key/value pairs. |
Implementation Reference
- src/tools/webhooks.ts:54-56 (handler)The handler for lob_webhooks_list: makes a GET request to /webhooks with compacted query args (dropping undefined fields).
handler: async (args) => lob.request({ method: "GET", path: "/webhooks", query: compact(args) }), }); - src/tools/webhooks.ts:53-53 (schema)Input schema for lob_webhooks_list: spreads listParamsSchema.shape (limit, before, after, include, date_created, metadata).
inputSchema: { ...listParamsSchema.shape }, - src/tools/webhooks.ts:47-56 (registration)Registration of lob_webhooks_list tool via registerTool() with name, annotations (read), description, inputSchema, and handler.
registerTool(server, { name: "lob_webhooks_list", annotations: { title: "List webhooks", ...ToolAnnotationPresets.read }, description: "List webhook subscriptions on your account. Note: Lob's `/webhooks` does NOT support " + "`include: ['total_count']` — for a count, just inspect `data.length` (webhook lists are small).", inputSchema: { ...listParamsSchema.shape }, handler: async (args) => lob.request({ method: "GET", path: "/webhooks", query: compact(args) }), }); - src/tools/helpers.ts:85-117 (helper)The registerTool helper function that wraps the handler with consistent error handling and registers it with the MCP server.
export function registerTool<TShape extends ZodRawShape>( server: McpServer, def: ToolDefinition<TShape>, ): void { const a = def.annotations ?? {}; server.registerTool( def.name, { title: a.title ?? def.name, description: def.description, inputSchema: def.inputSchema, annotations: { ...a, // Lob is always external; default the hint accordingly. openWorldHint: a.openWorldHint ?? true, }, }, // The SDK's ToolCallback type is parameterised over the exact ZodRawShape and // resists the generic erasure here. The runtime contract (validated args in, // CallToolResult out) is correct, so we bridge the type boundary with `as never`. (async (args: unknown, serverCtx: unknown): Promise<CallToolResult> => { try { const result = await def.handler(args as never, serverCtx); return { content: [{ type: "text", text: stringifyResult(result) }] }; } catch (err) { return { isError: true, content: [{ type: "text", text: formatErrorForTool(err) }], }; } }) as never, ); } - src/schemas/common.ts:85-110 (helper)listParamsSchema definition used as the input schema for lob_webhooks_list. Provides limit, before, after, include, date_created, metadata fields.
export const listParamsSchema = z .object({ limit: z .number() .int() .min(1) .max(100) .optional() .describe("How many results to return (default 10, max 100)."), before: z.string().optional().describe("Cursor for the previous page."), after: z.string().optional().describe("Cursor for the next page."), include: z .array(z.string()) .optional() .describe( "Response add-ons. Pass ['total_count'] alongside any filters and limit:1 to answer 'how many?' " + "questions in a single call — far cheaper than paginating to count. " + "Not accepted on nested order endpoints (buckslip/card orders) or /webhooks.", ), date_created: dateFilterSchema.optional(), metadata: z .record(z.string()) .optional() .describe("Filter by metadata key/value pairs."), }) .describe("Common Lob list/pagination parameters.");