update_element
Modify existing elements in Excalidraw diagrams by updating properties like position, size, colors, text, and styling attributes to refine visual content.
Instructions
Update an existing Excalidraw element
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ||
| type | No | ||
| x | No | ||
| y | No | ||
| width | No | ||
| height | No | ||
| backgroundColor | No | ||
| strokeColor | No | ||
| strokeWidth | No | ||
| roughness | No | ||
| opacity | No | ||
| text | No | ||
| fontSize | No | ||
| fontFamily | No |
Implementation Reference
- src/index.js:367-404 (handler)Switch case handler that executes the 'update_element' tool: validates input using Zod schemas, retrieves the existing element, applies updates (handling fontFamily and opacity specially), increments version, stores the updated element, and returns confirmation.
case 'update_element': { const rawParams = ElementSchema.partial().extend({ id: ElementIdSchema.shape.id }).passthrough().parse(args); const { id, ...updates } = rawParams; if (!id) throw new Error('Element ID is required'); const existingElement = elements.get(id); if (!existingElement) throw new Error(`Element with ID ${id} not found`); if (typeof updates.fontFamily === 'string') { const fontMap = { "virgil": 1, "helvetica": 2, "cascadia": 3 }; updates.fontFamily = fontMap[updates.fontFamily.toLowerCase()] ?? existingElement.fontFamily; } if (updates.opacity !== undefined) { updates.opacity = Math.max(0, Math.min(100, updates.opacity * 100)); } const potentialNewElement = { ...existingElement, ...updates, version: (existingElement.version || 0) + 1, versionNonce: Math.floor(Math.random() * 2 ** 31), updated: Date.now() }; Object.keys(potentialNewElement).forEach(key => { if (key === 'createdAt' || key === 'updatedAt') delete potentialNewElement[key]; }); elements.set(id, potentialNewElement); logger.info(`Element ${id} updated.`); logger.debug('Stored element data after update:', potentialNewElement); return { content: [{ type: 'text', text: JSON.stringify({ id: potentialNewElement.id, updated: true, version: potentialNewElement.version }, null, 2) }] }; } - src/index.js:119-144 (schema)JSON schema for 'update_element' tool input parameters, registered in the MCP server's capabilities.tools, defining properties like id (required), type, position, styling, etc.
update_element: { description: 'Update an existing Excalidraw element', inputSchema: { type: 'object', properties: { id: { type: 'string' }, 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: ['id'] } }, - src/index.js:30-46 (schema)Zod schema for Excalidraw element properties, used in the handler for partial parsing and validation of update parameters.
const ElementSchema = z.object({ type: z.enum(Object.values(EXCALIDRAW_ELEMENT_TYPES)), 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.number().optional(), locked: z.boolean().optional() // ADDED: Make sure locked status is saved }); - src/index.js:684-708 (registration)Tool registration in the ListToolsRequestHandler response, duplicating the schema for tool listing.
name: 'update_element', description: 'Update an existing Excalidraw element', inputSchema: { type: 'object', properties: { id: { type: 'string' }, 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: ['id'] }