create_miro_board
Transform Learning Hour session content into a Miro board to visualize and collaborate on technical coaching materials, enabling structured deliberate practice.
Instructions
Create a Miro board from Learning Hour session content
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| accessToken | Yes | Miro access token for API authentication | |
| sessionContent | Yes | Session content from generate_session output |
Implementation Reference
- src/index.ts:315-367 (handler)Main handler function for the create_miro_board tool. Parses input schema, checks Miro integration, creates new board or adds to existing one using MiroIntegration, and returns board details.private async createMiroBoard(args: any) { const input = CreateMiroBoardInputSchema.parse(args); try { if (!this.miroIntegration) { throw new Error('Miro integration not initialized. Ensure MIRO_ACCESS_TOKEN is set in the environment.'); } let layout; if (input.existingBoardId) { // Add frames to existing board try { layout = await this.miroIntegration.addFramesToExistingBoard(input.existingBoardId, input.sessionContent); } catch (error) { throw new Error(`Failed to add frames to existing board: ${error instanceof Error ? error.message : String(error)}`); } } else { // Create new board try { layout = await this.miroIntegration.createLearningHourBoard(input.sessionContent); } catch (error) { throw new Error(`Failed to create new Miro board: ${error instanceof Error ? error.message : String(error)}`); } } return { content: [ { type: "text", text: `✅ Miro board created successfully!`, }, { type: "text", text: `Board Name: ${input.sessionContent.miroContent.boardTitle}`, }, { type: "text", text: `Board ID: ${layout.boardId}`, }, { type: "text", text: `View Link: ${layout.viewLink || 'https://miro.com/app/board/' + layout.boardId}`, }, { type: "text", text: `\nThe board includes:\n- Overview section with session description\n- Learning objectives\n- 4C activities (Connect, Concept, Concrete, Conclusion)\n- Discussion prompts\n- Key takeaways`, }, ], }; } catch (error) { throw new Error(`Failed to create Miro board: ${error instanceof Error ? error.message : String(error)}`); } }
- src/index.ts:135-152 (registration)Tool registration in the listTools response, defining name, description, and input schema.{ name: "create_miro_board", description: "Create a new Miro board OR add frames to an existing board. This tool uses the Miro REST API to create boards with frames, sticky notes, text, and code blocks. It can create standalone boards or add content to existing boards.", inputSchema: { type: "object", properties: { sessionContent: { type: "object", description: "Session content from generate_session output", }, existingBoardId: { type: "string", description: "Optional: ID of an existing Miro board to add frames to. If not provided, creates a new board.", }, }, required: ["sessionContent"], }, },
- src/index.ts:39-42 (schema)Zod schema for input validation used in the handler.const CreateMiroBoardInputSchema = z.object({ sessionContent: z.any(), existingBoardId: z.string().optional(), });
- src/MiroIntegration.ts:371-396 (helper)Core helper method that creates a new Miro board and populates it with Learning Hour content using slide or vertical layout.async createLearningHourBoard(sessionContent: SessionContent): Promise<LearningHourMiroLayout> { // Post-process content to replace placeholders const processedContent = this.contentPostProcessor.processSessionContent(sessionContent); const boardName = processedContent.miroContent.boardTitle; const board = await this.createBoard(boardName, processedContent.sessionOverview); const style = processedContent.miroContent.style ?? 'slide'; const layout: LearningHourMiroLayout = { boardId: board.id, viewLink: board.viewLink, sections: { overview: {} as MiroFrame, objectives: [], activities: [], discussions: [], takeaways: [] } }; if (style === 'slide') { return await this.createSlideLayout(board.id, processedContent, layout); } else { return await this.createVerticalLayout(board.id, processedContent, layout); } }
- src/MiroIntegration.ts:423-458 (helper)Helper method to add Learning Hour frames to an existing Miro board.async addFramesToExistingBoard(boardId: string, sessionContent: SessionContent): Promise<LearningHourMiroLayout> { // Post-process content to replace placeholders const processedContent = this.contentPostProcessor.processSessionContent(sessionContent); logger.info('Session content structure:', { hasMiroContent: !!processedContent.miroContent, miroContentKeys: processedContent.miroContent ? Object.keys(processedContent.miroContent) : [], hasSections: processedContent.miroContent?.sections !== undefined, sectionsType: Array.isArray(processedContent.miroContent?.sections) ? 'array' : typeof processedContent.miroContent?.sections, sectionsLength: Array.isArray(processedContent.miroContent?.sections) ? processedContent.miroContent.sections.length : 'N/A' }); const style = processedContent.miroContent?.style ?? 'slide'; // Get board info to find a good position for new content const boardInfo = await this.getBoardInfo(boardId); const layout: LearningHourMiroLayout = { boardId: boardId, viewLink: boardInfo.viewLink, sections: { overview: {} as MiroFrame, objectives: [], activities: [], discussions: [], takeaways: [] } }; // Add frames to the existing board if (style === 'slide') { return await this.createSlideLayout(boardId, processedContent, layout); } else { return await this.createVerticalLayout(boardId, processedContent, layout); } }