discourse_list_drafts
Retrieve and view all saved drafts for the current user, including keys, sequences, and preview content, to identify existing drafts before making updates.
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:37-109 (registration)Full registration function for the discourse_list_drafts tool, including schema definition, tool metadata, and inline handler implementation.export const registerListDrafts: RegisterFn = (server, ctx, _opts) => { const schema = z.object({ offset: z.number().int().min(0).optional().describe("Pagination offset (default: 0)"), }); 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 }; } } ); };
- src/tools/builtin/drafts.ts:50-107 (handler)Handler function that fetches drafts from /drafts.json API endpoint, processes the response to preview content, formats as Markdown with JSON dump, handles errors.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 for the tool, defining optional offset parameter for pagination.const schema = z.object({ offset: z.number().int().min(0).optional().describe("Pagination offset (default: 0)"), });