create-items-in-bulk-using-file
Create multiple items on a Miro board in one operation using a JSON file from your device.
Instructions
Create multiple items on a Miro board in a single operation using a JSON file from device
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| boardId | Yes | Unique identifier (ID) of the board where the items will be created | |
| fileData | Yes | Base64 encoded JSON file data containing items to create |
Implementation Reference
- Main handler function that decodes base64-encoded JSON file data containing items array, validates each item, creates sticky notes, cards, or text items on the Miro board using helper functions, collects results and errors, and returns a JSON summary.fn: async ({ boardId, fileData }) => { try { if (!boardId) { return ServerResponse.error("Board ID is required"); } if (!fileData) { return ServerResponse.error("File data is required"); } // Decode the base64 file data let jsonData; try { const base64Data = fileData.replace(/^data:application\/json;base64,/, ''); const fileBuffer = Buffer.from(base64Data, 'base64'); const fileContent = fileBuffer.toString('utf-8'); jsonData = JSON.parse(fileContent); } catch (error) { return ServerResponse.error(`Error decoding or parsing JSON file data: ${error.message}`); } // Validate that the decoded data contains an 'items' array if (!jsonData.items || !Array.isArray(jsonData.items) || jsonData.items.length === 0) { return ServerResponse.error("JSON file must contain a non-empty 'items' array"); } const items = jsonData.items; const results = []; const errors = []; const createPromises = items.map(async (item, index) => { try { // Validate item structure if (!item.type || !item.data || !item.position) { throw new Error(`Item at index ${index} is missing required fields (type, data, or position)`); } let result; if (item.type === 'sticky_note') { result = await createStickyNote(boardId, item); } else if (item.type === 'card') { result = await createCard(boardId, item); } else if (item.type === 'text') { result = await createText(boardId, item); } else { throw new Error(`Unsupported item type: ${item.type}`); } return { index, result }; } catch (error) { return { index, error: error.message || String(error) }; } }); const promiseResults = await Promise.all(createPromises); for (const promiseResult of promiseResults) { const { index, result, error } = promiseResult; if (error) { errors.push({ index, error }); } else if (result) { results.push({ index, item: result }); } } return ServerResponse.text(JSON.stringify({ created: results.length, failed: errors.length, results, errors }, null, 2)); } catch (error) { return ServerResponse.error(error); } }
- Tool schema definition including name, description, and Zod input schema for boardId and fileData parameters.const createItemsInBulkUsingFileTool: ToolSchema = { name: "create-items-in-bulk-using-file", description: "Create multiple items on a Miro board in a single operation using a JSON file from device", args: { boardId: z.string().describe("Unique identifier (ID) of the board where the items will be created"), fileData: z.string().describe("Base64 encoded JSON file data containing items to create") },
- src/index.ts:185-185 (registration)Registration of the createItemsInBulkUsingFileTool in the ToolBootstrapper chain..register(createItemsInBulkUsingFileTool)
- Helper function to create a sticky note item on the board, validating and setting content, shape, position, and style properties before calling Miro API.async function createStickyNote(boardId: string, item: any) { const createRequest = new StickyNoteCreateRequest(); const stickyNoteData = new StickyNoteData(); stickyNoteData.content = item.data.content; stickyNoteData.shape = item.data.shape || 'square'; createRequest.data = stickyNoteData; createRequest.position = item.position; if (item.style) { const style: Record<string, string> = {}; if (item.style.fillColor) { if (validStickyNoteColors.includes(item.style.fillColor)) { style.fillColor = item.style.fillColor; } else { style.fillColor = 'light_yellow'; } } if (item.style.textAlign) { if (validTextAligns.includes(item.style.textAlign)) { style.textAlign = item.style.textAlign; } else { style.textAlign = 'center'; } } createRequest.style = style; } return await MiroClient.getApi().createStickyNoteItem(boardId, createRequest); }
- Helper function to create a card item on the board, setting title, description, assignee, due date, position, and style.async function createCard(boardId: string, item: any) { const createRequest = new CardCreateRequest(); const cardData = new CardData(); cardData.title = item.data.title; if (item.data.description) { cardData.description = item.data.description; } if (item.data.assigneeId) { cardData.assigneeId = item.data.assigneeId; } if (item.data.dueDate) { cardData.dueDate = new Date(item.data.dueDate); } createRequest.data = cardData; createRequest.position = item.position; if (item.style) { createRequest.style = item.style as Record<string, any>; } return await MiroClient.getApi().createCardItem(boardId, createRequest); }