create_element
Generate and customize Excalidraw elements (shapes, text, lines) with precise positioning, dimensions, colors, and styles via a structured API for diagram creation and modification.
Instructions
Create a new Excalidraw element
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| backgroundColor | No | ||
| fontFamily | No | ||
| fontSize | No | ||
| height | No | ||
| opacity | No | ||
| roughness | No | ||
| strokeColor | No | ||
| strokeWidth | No | ||
| text | No | ||
| type | Yes | ||
| width | No | ||
| x | Yes | ||
| y | Yes |
Implementation Reference
- src/index.ts:530-565 (handler)Main handler for the 'create_element' MCP tool: parses input with ElementSchema, generates ID, converts text to label format, calls createElementOnCanvas to sync to the canvas server, and returns success response.case 'create_element': { const params = ElementSchema.parse(args); logger.info('Creating element via MCP', { type: params.type }); const id = generateId(); const element: ServerElement = { id, ...params, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), version: 1 }; // Convert text to label format for Excalidraw const excalidrawElement = convertTextToLabel(element); // Create element directly on HTTP server (no local storage) const canvasElement = await createElementOnCanvas(excalidrawElement); if (!canvasElement) { throw new Error('Failed to create element: HTTP server unavailable'); } logger.info('Element created via MCP and synced to canvas', { id: excalidrawElement.id, type: excalidrawElement.type, synced: !!canvasElement }); return { content: [{ type: 'text', text: `Element created successfully!\n\n${JSON.stringify(canvasElement, null, 2)}\n\n✅ Synced to canvas` }] }; }
- src/index.ts:233-258 (registration)Tool registration in the tools array: defines name 'create_element', description, and JSON inputSchema, used in server capabilities for MCP tool discovery.{ name: 'create_element', description: 'Create a new Excalidraw element', inputSchema: { type: 'object', properties: { type: { type: 'string', enum: Object.values(EXCALIDRAW_ELEMENT_TYPES) }, x: { type: 'number' }, y: { type: 'number' }, width: { type: 'number' }, height: { type: 'number' }, backgroundColor: { type: 'string' }, strokeColor: { type: 'string' }, strokeWidth: { type: 'number' }, roughness: { type: 'number' }, opacity: { type: 'number' }, text: { type: 'string' }, fontSize: { type: 'number' }, fontFamily: { type: 'string' } }, required: ['type', 'x', 'y'] } },
- src/index.ts:181-198 (schema)Zod schema (ElementSchema) used to parse and validate input arguments in the create_element handler.const ElementSchema = z.object({ type: z.enum(Object.values(EXCALIDRAW_ELEMENT_TYPES) as [ExcalidrawElementType, ...ExcalidrawElementType[]]), x: z.number(), y: z.number(), width: z.number().optional(), height: z.number().optional(), points: z.array(z.object({ x: z.number(), y: z.number() })).optional(), backgroundColor: z.string().optional(), strokeColor: z.string().optional(), strokeWidth: z.number().optional(), roughness: z.number().optional(), opacity: z.number().optional(), text: z.string().optional(), fontSize: z.number().optional(), fontFamily: z.string().optional(), groupIds: z.array(z.string()).optional(), locked: z.boolean().optional() });
- src/index.ts:121-124 (helper)Helper function called by the handler to perform the actual canvas sync for element creation via POST to /api/elements.async function createElementOnCanvas(elementData: ServerElement): Promise<ServerElement | null> { const result = await syncToCanvas('create', elementData); return result?.element || elementData; }
- src/index.ts:507-521 (helper)Helper function used in handler to convert 'text' property to Excalidraw-compatible 'label' format for non-text elements.function convertTextToLabel(element: ServerElement): ServerElement { const { text, ...rest } = element; if (text) { // For standalone text elements, keep text as direct property if (element.type === 'text') { return element; // Keep text as direct property } // For other elements (rectangle, ellipse, diamond), convert to label format return { ...rest, label: { text } } as ServerElement; } return element; }