discourse_list_drafts
Retrieve all drafts for the current user to find existing content before making updates. Shows draft keys, sequences, and preview content.
Instructions
List all drafts for the current user. Returns draft keys, sequences, and preview content. Use this to find existing drafts before updating them.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| offset | No | Pagination offset (default: 0) |
Implementation Reference
- src/tools/builtin/drafts.ts:50-107 (handler)The handler function that lists all drafts for the current user by calling the Discourse /drafts.json API, formats a markdown summary with previews, and includes a JSON dump of the drafts.async (input: unknown, _extra: unknown) => { const { offset } = schema.parse(input); try { const { base, client } = ctx.siteState.ensureSelectedSite(); const params = new URLSearchParams(); if (typeof offset === "number") params.set("offset", String(offset)); const url = `/drafts.json${params.toString() ? `?${params}` : ""}`; const data = (await client.get(url)) as { drafts?: Array<{ draft_key: string; sequence: number; data?: string; title?: string; category_id?: number; created_at?: string; }>; }; const drafts = data?.drafts || []; if (drafts.length === 0) { return { content: [{ type: "text", text: "No drafts found." }] }; } const lines = ["# Drafts\n"]; for (const draft of drafts) { lines.push(`## Draft: \`${draft.draft_key}\` (sequence: ${draft.sequence})`); if (draft.title) lines.push(`**Title:** ${draft.title}`); if (draft.category_id) lines.push(`**Category ID:** ${draft.category_id}`); if (draft.created_at) lines.push(`**Created:** ${draft.created_at}`); // Parse and show preview of reply content if (draft.data) { try { const parsed = JSON.parse(draft.data); if (parsed.reply) { const preview = parsed.reply.length > 200 ? parsed.reply.slice(0, 200) + "..." : parsed.reply; lines.push(`**Preview:**\n> ${preview.replace(/\n/g, "\n> ")}`); } } catch { // Ignore parse errors } } lines.push(""); } lines.push("\n```json"); lines.push(JSON.stringify(drafts, null, 2)); lines.push("```"); return { content: [{ type: "text", text: lines.join("\n") }] }; } catch (e: unknown) { const msg = e instanceof Error ? e.message : String(e); return { content: [{ type: "text", text: `Failed to list drafts: ${msg}` }], isError: true }; } }
- src/tools/builtin/drafts.ts:38-40 (schema)Zod input schema defining optional 'offset' parameter for pagination.const schema = z.object({ offset: z.number().int().min(0).optional().describe("Pagination offset (default: 0)"), });
- src/tools/builtin/drafts.ts:42-108 (registration)Registration of the 'discourse_list_drafts' tool using server.registerTool, specifying title, description, inputSchema, and handler.server.registerTool( "discourse_list_drafts", { title: "List Drafts", description: "List all drafts for the current user. Returns draft keys, sequences, and preview content. Use this to find existing drafts before updating them.", inputSchema: schema.shape, }, async (input: unknown, _extra: unknown) => { const { offset } = schema.parse(input); try { const { base, client } = ctx.siteState.ensureSelectedSite(); const params = new URLSearchParams(); if (typeof offset === "number") params.set("offset", String(offset)); const url = `/drafts.json${params.toString() ? `?${params}` : ""}`; const data = (await client.get(url)) as { drafts?: Array<{ draft_key: string; sequence: number; data?: string; title?: string; category_id?: number; created_at?: string; }>; }; const drafts = data?.drafts || []; if (drafts.length === 0) { return { content: [{ type: "text", text: "No drafts found." }] }; } const lines = ["# Drafts\n"]; for (const draft of drafts) { lines.push(`## Draft: \`${draft.draft_key}\` (sequence: ${draft.sequence})`); if (draft.title) lines.push(`**Title:** ${draft.title}`); if (draft.category_id) lines.push(`**Category ID:** ${draft.category_id}`); if (draft.created_at) lines.push(`**Created:** ${draft.created_at}`); // Parse and show preview of reply content if (draft.data) { try { const parsed = JSON.parse(draft.data); if (parsed.reply) { const preview = parsed.reply.length > 200 ? parsed.reply.slice(0, 200) + "..." : parsed.reply; lines.push(`**Preview:**\n> ${preview.replace(/\n/g, "\n> ")}`); } } catch { // Ignore parse errors } } lines.push(""); } lines.push("\n```json"); lines.push(JSON.stringify(drafts, null, 2)); lines.push("```"); return { content: [{ type: "text", text: lines.join("\n") }] }; } catch (e: unknown) { const msg = e instanceof Error ? e.message : String(e); return { content: [{ type: "text", text: `Failed to list drafts: ${msg}` }], isError: true }; } } );