convert_markdown
Converts markdown to HTML and plain text for Slack, Google Docs, Word, and more. Returns JSON with html and plain_text fields. For Slack, use plain_text; for other apps, visit unmarkdown.com for paste-ready format.
Instructions
Convert markdown to destination-specific HTML and plain text. Returns JSON with 'html' and 'plain_text' fields. For Slack, present the plain_text to the user. For Google Docs/Word/OneNote, direct users to unmarkdown.com to use the copy button (raw HTML cannot be pasted into these apps). Does not render Chart.js, Mermaid, Graphviz, or KaTeX; use publish_document for documents with diagrams or math.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| markdown | Yes | Markdown content to convert | |
| destination | No | Target format (default: "generic") | |
| template_id | No | Visual template ID (default: "swiss") | |
| theme_mode | No | Color theme (default: "light") |
Implementation Reference
- src/tools.ts:34-80 (registration)The convert_markdown tool is registered via server.tool() with its schema and handler. The handler calls client.request('POST', '/v1/convert', body).
server.tool( "convert_markdown", "Convert markdown to destination-specific HTML and plain text. Returns JSON with 'html' and 'plain_text' fields. For Slack, present the plain_text to the user. For Google Docs/Word/OneNote, direct users to unmarkdown.com to use the copy button (raw HTML cannot be pasted into these apps). Does not render Chart.js, Mermaid, Graphviz, or KaTeX; use publish_document for documents with diagrams or math.", { markdown: z.string().describe("Markdown content to convert"), destination: z .enum([ "google-docs", "word", "slack", "onenote", "email", "plain-text", "generic", "html", ]) .optional() .describe('Target format (default: "generic")'), template_id: z .string() .optional() .describe('Visual template ID (default: "swiss")'), theme_mode: z .enum(["light", "dark"]) .optional() .describe('Color theme (default: "light")'), }, { title: "Convert Markdown", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true, }, async ({ markdown, destination, template_id, theme_mode }) => { try { const body: Record<string, unknown> = { markdown }; if (destination) body.destination = destination; if (template_id) body.template_id = template_id; if (theme_mode) body.theme_mode = theme_mode; const result = await client.request("POST", "/v1/convert", body); return jsonResult(result); } catch (err) { return errorResult(err); } }, ); - src/tools.ts:37-67 (schema)Zod schema defining input parameters: markdown (required), destination (optional enum), template_id (optional), theme_mode (optional).
{ markdown: z.string().describe("Markdown content to convert"), destination: z .enum([ "google-docs", "word", "slack", "onenote", "email", "plain-text", "generic", "html", ]) .optional() .describe('Target format (default: "generic")'), template_id: z .string() .optional() .describe('Visual template ID (default: "swiss")'), theme_mode: z .enum(["light", "dark"]) .optional() .describe('Color theme (default: "light")'), }, { title: "Convert Markdown", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true, }, - src/tools.ts:68-79 (handler)The handler function that executes the tool logic: sends markdown and optional params to the /v1/convert API endpoint.
async ({ markdown, destination, template_id, theme_mode }) => { try { const body: Record<string, unknown> = { markdown }; if (destination) body.destination = destination; if (template_id) body.template_id = template_id; if (theme_mode) body.theme_mode = theme_mode; const result = await client.request("POST", "/v1/convert", body); return jsonResult(result); } catch (err) { return errorResult(err); } }, - src/tools.ts:24-29 (helper)Helper function that wraps the API response in a JSON text MCP content result.
function jsonResult(data: unknown) { return { content: [ { type: "text" as const, text: JSON.stringify(data, null, 2) }, ], }; - src/tools.ts:5-22 (helper)Helper function that formats errors into MCP error content results.
function errorResult(err: unknown) { if (err instanceof ApiError) { return { content: [ { type: "text" as const, text: `Error ${err.status} (${err.code}): ${err.message}`, }, ], isError: true, }; } const message = err instanceof Error ? err.message : String(err); return { content: [{ type: "text" as const, text: `Error: ${message}` }], isError: true, }; }