generate_diagram_from_ascii
Convert ASCII art diagrams into polished visual diagrams for system architecture, flowcharts, and workflows. Get a browser link to view and edit the generated diagram.
Instructions
Convert an ASCII art diagram into a polished visual diagram. Use this tool when the user has an existing ASCII art representation of a system, flow, or architecture and wants it rendered as a proper diagram. Accepts box-drawing characters, arrow representations (-->, ==>), and plain text layouts. Returns a link to view and edit the generated diagram in the browser.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| content | Yes | Raw ASCII art diagram to convert into a polished visual diagram. Include the full ASCII art as-is, with box-drawing characters, arrows, or plain text layout. Example: +--------+ +--------+ | Client | --> | Server | +--------+ +--------+ | |
| prompt | No | Additional instruction for rendering. Example: "Use a dark theme and add icons" | |
| diagramType | No | Preferred diagram type. Leave blank to let the AI infer from the ASCII layout. | |
| isIconEnabled | No | Set to true when the user asks to include icons in the diagram. |
Implementation Reference
- src/tools/generate-ascii.ts:38-54 (registration)Registration of the generate_diagram_from_ascii tool.
export function registerGenerateAsciiTool(server: McpServer): void { registerAppTool( server, "generate_diagram_from_ascii", { description: "Convert an ASCII art diagram into a polished visual diagram. " + "Use this tool when the user has an existing ASCII art representation of a system, " + "flow, or architecture and wants it rendered as a proper diagram. " + "Accepts box-drawing characters, arrow representations (-->, ==>), and plain text layouts. " + "Returns a link to view and edit the generated diagram in the browser.", inputSchema, _meta: { ui: { resourceUri: DIAGRAM_APP_RESOURCE_URI } }, }, async (args) => generateDiagram("ascii", args) ); } - src/tools/generate-ascii.ts:6-36 (schema)Input schema definition for the generate_diagram_from_ascii tool.
const inputSchema = { content: z .string() .min(1) .describe( "Raw ASCII art diagram to convert into a polished visual diagram. " + "Include the full ASCII art as-is, with box-drawing characters, arrows, or plain text layout. " + "Example:\n" + " +--------+ +--------+\n" + " | Client | --> | Server |\n" + " +--------+ +--------+" ), prompt: z .string() .optional() .describe( 'Additional instruction for rendering. Example: "Use a dark theme and add icons"' ), diagramType: z .enum(DIAGRAM_TYPES) .optional() .describe( "Preferred diagram type. Leave blank to let the AI infer from the ASCII layout." ), isIconEnabled: z .boolean() .optional() .describe( "Set to true when the user asks to include icons in the diagram." ), }; - src/tools/shared.ts:158-273 (handler)Core handler logic for generating diagrams via the AI Diagram Maker API.
export async function generateDiagram( inputType: GenerateDiagramV2Request["inputType"], params: DiagramParams ): Promise<CallToolResult> { debugLog("Tool called:", { inputType, params: paramsForLog(params) }); const apiKey = getApiKey(); if (!apiKey) { const hint = process.env.PORT != null ? "Send your API key in the Authorization header (Bearer <key>) or X-ADM-API-Key header." : "Set the ADM_API_KEY environment variable."; return { isError: true, content: [ { type: "text", text: `AI Diagram Maker API key is required. ${hint}`, }, ], }; } const requestBody: GenerateDiagramV2Request = { inputType, content: params.content, // Request SVG, then rasterize to PNG in this MCP server so icons render in chat. format: "svg", ...(params.prompt !== undefined && { prompt: params.prompt }), ...(params.diagramType !== undefined && { diagramType: params.diagramType, }), options: { saveDiagramEnabled: true, colorTheme: "pastel-layers", ...(isMock() && { useMock: true }), ...(isDebug() && { debug: true }), ...(params.isIconEnabled && { isIconEnabled: true }), }, }; debugLog("Request payload to AI Diagram Maker API:", payloadForLog(requestBody)); const response = await postApiV2DiagramsGenerate(requestBody); const responseForLog = { status: response.status, data: { ...response.data, ...(typeof (response.data as { svg?: string })?.svg === "string" && { svg: truncateForLog((response.data as { svg: string }).svg), }), }, }; debugLog("Generate diagram API response:", responseForLog); if (response.status === 200) { const { svg, text, diagramUrl } = response.data; const content: CallToolResult["content"] = []; let textContent = text ?? ""; if (diagramUrl) { const baseUrl = (process.env.ADM_BASE_URL ?? "https://app.aidiagrammaker.com").replace( /\/$/, "" ); const fullDiagramUrl = diagramUrl.startsWith("/") ? `${baseUrl}${diagramUrl}` : diagramUrl; textContent += `\n\nEdit diagram: ${fullDiagramUrl} (open in browser to view and edit)`; if (svg) { try { const diagramId = new URL(fullDiagramUrl).pathname.split("/").filter(Boolean).pop(); if (diagramId) { const inlined = await inlineSvgImages(svg, baseUrl); storeSvg(diagramId, inlined); } } catch { // URL parsing failed; image unavailable in App } } } if (textContent) { content.push({ type: "text", text: textContent }); } return { content }; } // Handle error responses const errorData = response.data as { error?: string; details?: string; rateLimitError?: { retryAfter?: number }; }; let errorMessage = `API request failed with status ${response.status}`; if (errorData?.error) { errorMessage = errorData.error; if (errorData.details) { errorMessage += `: ${errorData.details}`; } } if (response.status === 429 && errorData?.rateLimitError?.retryAfter) { errorMessage += ` (retry after ${errorData.rateLimitError.retryAfter} seconds)`; } return { isError: true, content: [{ type: "text", text: errorMessage }], }; }