List campaigns
lob_campaigns_listList Lob campaigns filtered by date or metadata. Answer 'how many campaigns?' in one call by passing include:['total_count'] with limit:1.
Instructions
List campaigns on your Lob account. For 'how many campaigns?' counts, pass include: ['total_count'] with limit: 1. Filter by date_created or metadata.
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/campaigns.ts:63-72 (handler)The handler for lob_campaigns_list tool: calls lob.request with GET /campaigns and compacted query args (limit, before, after, include, date_created, metadata).
registerTool(server, { name: "lob_campaigns_list", annotations: { title: "List campaigns", ...ToolAnnotationPresets.read }, description: "List campaigns on your Lob account. **For 'how many campaigns?' counts, pass " + "`include: ['total_count']` with `limit: 1`.** Filter by `date_created` or `metadata`.", inputSchema: { ...listParamsSchema.shape }, handler: async (args) => lob.request({ method: "GET", path: "/campaigns", query: compact(args) }), }); - src/schemas/common.ts:85-110 (schema)listParamsSchema — the Zod schema used as inputSchema for lob_campaigns_list (spread as { ...listParamsSchema.shape }). Defines limit, before, after, include, date_created, metadata.
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."); - src/tools/campaigns.ts:24-72 (helper)registerCampaignTools — the registration function that wires lob_campaigns_list (and all other campaign/creative tools) into the MCP server. Called by registerAllTools in register.ts.
export function registerCampaignTools(server: McpServer, lob: LobClient): void { // ── Campaigns ────────────────────────────────────────────────────────────── registerTool(server, { name: "lob_campaigns_create", annotations: { title: "Create a campaign", ...ToolAnnotationPresets.mutate }, description: "Create a campaign — a container for batched mail-piece sends with a shared creative, schedule, " + "and audience. Creating a campaign does not by itself send mail; you trigger sends per Lob docs.", inputSchema: { name: z.string().describe("Display name for the campaign."), description: z.string().max(500).optional(), schedule_type: z .enum(["immediate", "scheduled_send_date"]) .optional() .describe("Whether the campaign should send immediately or on a schedule."), send_date: z .string() .optional() .describe("ISO 8601 timestamp for scheduled campaigns."), target_delivery_date: z.string().optional(), cancel_window_campaign_minutes: z .number() .int() .optional() .describe("Minutes before send during which the campaign can still be cancelled."), metadata: metadataSchema, extra: extraParamsSchema, }, handler: async (args) => { const { extra, ...rest } = args; return lob.request({ method: "POST", path: "/campaigns", body: withExtra(rest, extra), }); }, }); registerTool(server, { name: "lob_campaigns_list", annotations: { title: "List campaigns", ...ToolAnnotationPresets.read }, description: "List campaigns on your Lob account. **For 'how many campaigns?' counts, pass " + "`include: ['total_count']` with `limit: 1`.** Filter by `date_created` or `metadata`.", inputSchema: { ...listParamsSchema.shape }, handler: async (args) => lob.request({ method: "GET", path: "/campaigns", query: compact(args) }), }); - src/tools/register.ts:40-46 (registration)Registration entry: registerCampaignTools(server, lob) called from registerAllTools, which wires the campaign tools including lob_campaigns_list into the server.
registerTemplateTools(server, lob); registerCampaignTools(server, lob); registerUploadsTools(server, lob, tokenStore, pieceCounter); registerBankAccountTools(server, lob); registerWebhookTools(server, lob); registerSpecsResources(server); } - src/schemas/common.ts:152-158 (helper)compact() helper used by the handler to strip undefined values from args before sending as query params.
export function compact<T extends object>(obj: T): Partial<T> { const out: Record<string, unknown> = {}; for (const [k, v] of Object.entries(obj)) { if (v !== undefined) out[k] = v; } return out as Partial<T>; }