batch_create_qurls
Create multiple qURLs in a single request. Returns per-item results with error details for any failures, enabling handling of partial failures without manual parsing.
Instructions
Create multiple qURLs in a single request. Returns per-item results including any errors for partial failures. The response sets isError=true when one or more items fail so agents can branch on partial failure without parsing the JSON.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| items | Yes | Array of qURL creation requests (1-100 items) |
Implementation Reference
- src/tools/batch-create.ts:13-61 (handler)The main handler function for batch_create_qurls. Calls client.batchCreate(input), validates response shape with defense-in-depth checks, and returns per-item results with isError flag set when failed > 0.
export function batchCreateTool(client: IQURLClient) { return { name: "batch_create_qurls", description: "Create multiple qURLs in a single request. " + "Returns per-item results including any errors for partial failures. " + "The response sets isError=true when one or more items fail so agents can branch on partial failure without parsing the JSON.", inputSchema: batchCreateSchema, handler: async (input: z.infer<typeof batchCreateSchema>) => { const result = await client.batchCreate(input); // Defense-in-depth: batchCreate passes through HTTP 400, which is // contracted to carry a BatchCreateResponse body with per-item errors. // If the API ever returns 400 with a different shape (e.g., a // top-level malformed-request error), the downstream `failed > 0` // access would be meaningless — surface the raw response as an error // so agents get a real signal instead of silent mis-interpretation. const data = result.data as Partial<typeof result.data> | undefined; if ( !data || typeof data.failed !== "number" || typeof data.succeeded !== "number" || !Array.isArray(data.results) ) { return { content: [ { type: "text" as const, text: `Unexpected batchCreate response shape: ${JSON.stringify(result).slice(0, 500)}`, }, ], isError: true, }; } const payload = { ...data, request_id: result.meta?.request_id, }; return { content: [ { type: "text" as const, text: JSON.stringify(payload), }, ], isError: data.failed > 0, }; }, }; } - src/tools/batch-create.ts:5-11 (schema)Input schema: an array of 1-100 create-qurl schemas, reused from create-qurl.ts.
export const batchCreateSchema = z.object({ items: z .array(createQurlSchema) .min(1) .max(100) .describe("Array of qURL creation requests (1-100 items)"), }); - src/server.ts:39-54 (registration)Registration: batchCreateTool is included in the toolFactories array and registered via server.tool() at runtime.
const toolFactories = [ createQurlTool, resolveQurlTool, listQurlsTool, getQurlTool, deleteQurlTool, extendQurlTool, updateQurlTool, mintLinkTool, batchCreateTool, ] satisfies ToolFactory[]; for (const factory of toolFactories) { const tool = factory(client); server.tool(tool.name, tool.description, tool.inputSchema.shape, tool.handler); } - src/tools/create-qurl.ts:44-71 (helper)Reused schema for each item in the batch. Defines the per-qURL creation fields (target_url, label, expires_in, etc.) imported into batch-create.ts.
export const createQurlSchema = z.object({ target_url: z.string().url().describe("The URL to protect with qURL"), label: z .string() .max(500) .optional() .describe("Human-readable label identifying who this qURL is for (max 500 chars)"), expires_in: z .string() .min(1) .optional() .describe('Duration string (e.g., "1h", "24h", "7d")'), one_time_use: z.boolean().optional().describe("Whether the link can only be used once"), max_sessions: z .number() .int() .min(0) .max(1000) .optional() .describe("Maximum concurrent sessions (0 = unlimited, max 1000)"), session_duration: z .string() .min(1) .optional() .describe('How long access lasts after clicking (e.g., "1h")'), custom_domain: z.string().optional().describe("Custom domain to assign to the auto-created resource"), access_policy: accessPolicySchema.optional().describe("Access control policy for the qURL"), });