Skip to main content
Glama

distribute_elements

Evenly space selected elements horizontally or vertically in Excalidraw diagrams to organize layouts and improve visual alignment.

Instructions

Distribute elements evenly (horizontal or vertical)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
elementIdsYes
directionYes

Implementation Reference

  • The actual working handler implementation - the distribute_elements tool is registered with inline logic that distributes elements horizontally or vertically by calculating equal gaps between sorted elements
    server.tool( 'distribute_elements', 'Distribute elements evenly (horizontal or vertical)', { elementIds: z.array(IdZ).min(3).max(LIMITS.MAX_ELEMENT_IDS), direction: z.enum(['horizontal', 'vertical']), }, async ({ elementIds, direction }) => { try { const elements = []; for (const eid of elementIds) { const el = await client.getElement(eid); if (!el) throw new Error(`Element ${eid} not found`); if (el.locked) throw new Error(`Element ${eid} is locked`); elements.push(el); } if (direction === 'horizontal') { const sorted = [...elements].sort((a, b) => a.x - b.x); const first = sorted[0]!; const last = sorted[sorted.length - 1]!; const totalSpan = (last.x + (last.width ?? 0)) - first.x; const totalWidth = sorted.reduce((s, e) => s + (e.width ?? 0), 0); const gap = (totalSpan - totalWidth) / (sorted.length - 1); let currentX = first.x; for (const el of sorted) { await client.updateElement(el.id, { x: currentX }); currentX += (el.width ?? 0) + gap; } } else { const sorted = [...elements].sort((a, b) => a.y - b.y); const first = sorted[0]!; const last = sorted[sorted.length - 1]!; const totalSpan = (last.y + (last.height ?? 0)) - first.y; const totalHeight = sorted.reduce((s, e) => s + (e.height ?? 0), 0); const gap = (totalSpan - totalHeight) / (sorted.length - 1); let currentY = first.y; for (const el of sorted) { await client.updateElement(el.id, { y: currentY }); currentY += (el.height ?? 0) + gap; } } return { content: [{ type: 'text', text: JSON.stringify({ distributed: true, direction, elementIds }, null, 2), }], }; } catch (err) { return { content: [{ type: 'text', text: `Error: ${(err as Error).message}` }], isError: true }; } } );
  • Zod schema definition for distribute_elements input validation - requires elementIds array (min 3, max limit) and direction (horizontal or vertical)
    export const DistributeElementsSchema = z .object({ elementIds: z .array(z.string().max(LIMITS.MAX_ID_LENGTH)) .min(3) .max(LIMITS.MAX_ELEMENT_IDS), direction: z.enum(['horizontal', 'vertical']), }) .strict();
  • Alternative standalone handler implementation with similar logic but using DistributeElementsSchema.parse for validation - appears to be unused by the main MCP server
    export async function distributeElementsTool( args: unknown, client: CanvasClient ) { const { elementIds, direction } = DistributeElementsSchema.parse(args); const elements = await Promise.all( elementIds.map(async (id) => { const el = await client.getElement(id); if (!el) throw new Error(`Element ${id} not found`); return el; }) ); if (direction === 'horizontal') { const sorted = [...elements].sort((a, b) => a.x - b.x); const first = sorted[0]; const last = sorted[sorted.length - 1]; const totalSpan = last.x + (last.width ?? 0) - first.x; const totalElementWidth = sorted.reduce( (sum, el) => sum + (el.width ?? 0), 0 ); const gap = (totalSpan - totalElementWidth) / (sorted.length - 1); let currentX = first.x; for (const el of sorted) { if (el.x !== currentX) { await client.updateElement(el.id, { x: currentX }); } currentX += (el.width ?? 0) + gap; } } else { const sorted = [...elements].sort((a, b) => a.y - b.y); const first = sorted[0]; const last = sorted[sorted.length - 1]; const totalSpan = last.y + (last.height ?? 0) - first.y; const totalElementHeight = sorted.reduce( (sum, el) => sum + (el.height ?? 0), 0 ); const gap = (totalSpan - totalElementHeight) / (sorted.length - 1); let currentY = first.y; for (const el of sorted) { if (el.y !== currentY) { await client.updateElement(el.id, { y: currentY }); } currentY += (el.height ?? 0) + gap; } } return { success: true, distributed: true, direction, elementIds }; }
  • TypeScript type inferred from DistributeElementsSchema for type safety
    export type DistributeElements = z.infer<typeof DistributeElementsSchema>;
  • Sandbox registration for capability scanning - registers the tool with no-op handler
    server.tool('distribute_elements', 'Distribute elements evenly (horizontal or vertical)', { elementIds: z.array(IdZ).min(3).max(LIMITS.MAX_ELEMENT_IDS), direction: z.enum(['horizontal', 'vertical']) }, noop);

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/debu-sinha/excalidraw-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server