Skip to main content
Glama

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
NameRequiredDescriptionDefault
boardIdYesUnique identifier (ID) of the board where the items will be created
fileDataYesBase64 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); }

Other Tools

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/k-jarzyna/mcp-miro'

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