list_themes
Browse the complete catalog of available slide themes without starting a new project. Returns all primary and secondary themes for use in presentations and carousels.
Instructions
Idempotent read-only listing of all available themes (8+). Unlike discover_themes, this does NOT start a slide-creation workflow — call it any time the user asks "what themes are there?" mid-conversation. Returns the same tiered theme catalog (primary/secondary). Models MUST present every theme returned, never truncate.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Implementation Reference
- Handler function for the list_themes tool. Loads the theme catalog and returns a JSON response with all themes (id, name, emoji, style, palette, tier), theme count, primary/secondary theme lists, and an instruction for the model to present all themes.
export async function handleListThemes() { const themes = await loadThemeCatalog(); return { content: [{ type: "text" as const, text: JSON.stringify({ themes: themes.map(t => ({ id: t.id, name: t.name, emoji: t.emoji, style: t.style, palette: t.palette, tier: t.tier, })), themeCount: themes.length, primaryThemes: themes.filter(t => t.tier === "primary").map(t => t.id), secondaryThemes: themes.filter(t => t.tier === "secondary").map(t => t.id), instruction: `Present ALL ${themes.length} themes to the user. This is a read-only listing — calling this tool does NOT advance the slide-creation workflow. If the user wants to switch themes, they should re-invoke discover_themes or pass theme=<id> directly to create_slides.`, }), }], }; } - Schema definition for list_themes input. Empty object because the tool takes no input parameters.
// ── Tool: list_themes (idempotent) ── export const ListThemesInputSchema = {}; - packages/mcp-server/src/server.ts:44-50 (registration)Registration of the list_themes tool on the MCP server with its description, empty input schema, hints (read-only, idempotent), and handler binding.
server.tool( "list_themes", `Idempotent read-only listing of all available themes (8+). Unlike discover_themes, this does NOT start a slide-creation workflow — call it any time the user asks "what themes are there?" mid-conversation. Returns the same tiered theme catalog (primary/secondary). Models MUST present every theme returned, never truncate.`, ListThemesInputSchema, { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false }, async () => handleListThemes(), ); - Helper function that loads themes by first trying to fetch from the remote catalog, then merging with any missing fallback themes, and falling back entirely to the hardcoded THEME_CATALOG_FALLBACK array.
async function loadThemeCatalog(): Promise<TieredTheme[]> { try { const fetched = await fetchCatalog(); if (fetched && fetched.length > 0) { const tiered = withTier(fetched); const fetchedIds = new Set(tiered.map((t) => t.id)); const missing = THEME_CATALOG_FALLBACK.filter((t) => !fetchedIds.has(t.id)); return [...tiered, ...missing]; } } catch { // fall through to fallback } return THEME_CATALOG_FALLBACK; } - Alias of the schema (same location as schema line 21) -- ListThemesInputSchema is the empty input schema used for the list_themes tool.
export const ListThemesInputSchema = {}; // ── Tool: edit_slides (token-efficient partial edits) ── export const EditInputSchema = { htmlPath: z.string().optional().describe("Path to HTML to edit. Falls back to cached HTML from last create_slides call."), operation: z.enum(["replace_slide", "patch_css", "swap_token", "patch_class"]).describe("Edit operation: replace_slide swaps one slide block; patch_css appends CSS rules to <style>; swap_token replaces a CSS variable's value; patch_class adds/removes a class on a slide."), slideIndex: z.number().int().positive().optional().describe("1-indexed slide position. Required for replace_slide and patch_class. Omit for global ops (patch_css, swap_token)."), payload: z.union([z.string(), z.record(z.string())]).describe("For replace_slide: the new <div class=\"slide\">...</div> HTML string. For patch_css: a CSS rules string. For swap_token: an object {tokenName: newValue}, e.g. {\"--coral\": \"#FF0000\"}. For patch_class: an object {add?: string, remove?: string}."), }; // ── Tool 2: create_slides ──