The canvas_* tools enable the agent to read, create, and update Miro boards using Canvas Composer SVG, Miro's unified interaction/representation protocol for the canvas. To understand how to use the canvas_* tools in the appropiate way, please refer to the canvas_composer_skill tool first to understand the guidelines and protocol.
Protocol
Pass100/10016 / 16 pts
Connection, authentication, and protocol compatibility.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description70/100
Returns the identity of the current authenticated user.
Describe the returned information so the agent knows whether it will answer the request.
Inputs88/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Clear enough to supply this argument.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
{
"name": "user_who_am_i",
"title": "Who Am I",
"description": "Returns the identity of the current authenticated user.",
"inputSchema": {
"type": "object",
"properties": {
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"required": [
"user_id",
"team_id",
"workspace_id",
"org_id"
],
"properties": {
"org_id": {
"type": "string",
"description": "Organization identifier."
},
"team_id": {
"type": "string",
"description": "Team identifier."
},
"user_id": {
"type": "string",
"description": "Unique user identifier."
},
"workspace_id": {
"type": "string",
"description": "Workspace identifier."
}
},
"description": "Identity of the currently authenticated user."
},
"annotations": {
"title": "Who Am I",
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Search and list boards accessible to the current user, scoped to their team. Returns board metadata — name and URL — suitable for navigating to a specific board or discovering relevant boards before operating on them. Use this tool when the user wants to find a board by name or description, or discover which boards are available before using other board tools. Supports offset-based pagination.
The description explains the capability, when to use it, and what to expect.
Inputs82/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
query
Text to search for in board names and descriptions. Examples: 'product roadmap', 'Q4 planning', 'design review'. Leave empty to list all accessible boards.
Clear enough to supply this argument.
limit
Maximum number of boards to return per page. Range: 1-50. Default: 20.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
offset
Zero-based index of the first board to return. Use with limit for pagination. Example: offset=20 with limit=20 returns the second page.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
owned_by_me
When true, restricts results to boards owned by the current user. Useful when the user asks to see 'my boards' or 'boards I own'.
Clear enough to supply this argument.
include_content
Controls whether to search inside board content or only board name and description. Set to true ONLY when the user explicitly says they are looking for something written inside a board (e.g. 'find the board that has X in it', 'search inside boards for Y'). Default is false. Do not set to true just because the user provided a search query.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
{
"type": "object",
"title": "ListBoardsResponse",
"required": [
"data",
"total",
"has_more"
],
"properties": {
"data": {
"type": "array",
"items": {
"type": "object",
"title": "BoardSummary",
"required": [
"name",
"miro_url"
],
"properties": {
"name": {
"type": "string",
"title": "Name",
"description": "Name of the board"
},
"owner": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Owner",
"default": null,
"description": "Name of the board owner"
},
"miro_url": {
"type": "string",
"title": "Miro Url",
"description": "Full Miro URL to open the board"
},
"team_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Team Name",
"default": null,
"description": "Name of the team that owns the board"
},
"created_at": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Created At",
"default": null,
"description": "ISO 8601 UTC timestamp of when the board was created"
},
"description": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Description",
"default": null,
"description": "Board description"
},
"modified_at": {
"anyOf": [
{
"type": "string",
"format": "date-time"
},
{
"type": "null"
}
],
"title": "Modified At",
"default": null,
"description": "Date and time the board was last modified (UTC)"
}
},
"description": "Board metadata returned by search."
},
"title": "Data",
"description": "List of minimal board records"
},
"total": {
"type": "integer",
"title": "Total",
"description": "Total number of boards matching the query"
},
"has_more": {
"type": "boolean",
"title": "Has More",
"description": "Whether there are more results available"
},
"nextCursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Nextcursor",
"default": null,
"description": "Opaque cursor token for fetching the next page (MCP nextCursor)"
}
},
"description": "Response model for board listing using plain dict structures."
}
Original tool metadata
{
"name": "board_search_boards",
"title": "Search Boards",
"description": "Search and list boards accessible to the current user, scoped to their team. Returns board metadata — name and URL — suitable for navigating to a specific board or discovering relevant boards before operating on them. Use this tool when the user wants to find a board by name or description, or discover which boards are available before using other board tools. Supports offset-based pagination.",
"inputSchema": {
"type": "object",
"properties": {
"limit": {
"type": "integer",
"default": 20,
"maximum": 50,
"minimum": 1,
"description": "Maximum number of boards to return per page. Range: 1-50. Default: 20."
},
"query": {
"type": "string",
"default": "",
"description": "Text to search for in board names and descriptions. Examples: 'product roadmap', 'Q4 planning', 'design review'. Leave empty to list all accessible boards."
},
"offset": {
"type": "integer",
"default": 0,
"minimum": 0,
"description": "Zero-based index of the first board to return. Use with limit for pagination. Example: offset=20 with limit=20 returns the second page."
},
"owned_by_me": {
"type": "boolean",
"default": false,
"description": "When true, restricts results to boards owned by the current user. Useful when the user asks to see 'my boards' or 'boards I own'."
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"include_content": {
"type": "boolean",
"default": false,
"description": "Controls whether to search inside board content or only board name and description. Set to true ONLY when the user explicitly says they are looking for something written inside a board (e.g. 'find the board that has X in it', 'search inside boards for Y'). Default is false. Do not set to true just because the user provided a search query."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"title": "ListBoardsResponse",
"required": [
"data",
"total",
"has_more"
],
"properties": {
"data": {
"type": "array",
"items": {
"type": "object",
"title": "BoardSummary",
"required": [
"name",
"miro_url"
],
"properties": {
"name": {
"type": "string",
"title": "Name",
"description": "Name of the board"
},
"owner": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Owner",
"default": null,
"description": "Name of the board owner"
},
"miro_url": {
"type": "string",
"title": "Miro Url",
"description": "Full Miro URL to open the board"
},
"team_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Team Name",
"default": null,
"description": "Name of the team that owns the board"
},
"created_at": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Created At",
"default": null,
"description": "ISO 8601 UTC timestamp of when the board was created"
},
"description": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Description",
"default": null,
"description": "Board description"
},
"modified_at": {
"anyOf": [
{
"type": "string",
"format": "date-time"
},
{
"type": "null"
}
],
"title": "Modified At",
"default": null,
"description": "Date and time the board was last modified (UTC)"
}
},
"description": "Board metadata returned by search."
},
"title": "Data",
"description": "List of minimal board records"
},
"total": {
"type": "integer",
"title": "Total",
"description": "Total number of boards matching the query"
},
"has_more": {
"type": "boolean",
"title": "Has More",
"description": "Whether there are more results available"
},
"nextCursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Nextcursor",
"default": null,
"description": "Opaque cursor token for fetching the next page (MCP nextCursor)"
}
},
"description": "Response model for board listing using plain dict structures."
},
"annotations": {
"title": "Search Boards",
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description92/100
Create a new Miro board. To place the board inside a space, pass parent_space_url - either the space URL or the space content item id. Creating it in the space directly saves the extra board_move call that creating it at the team root would need. IMPORTANT: Always confirm with the user before creating a board. This action creates a new board and cannot be undone.
The description explains the capability, when to use it, and what to expect.
Inputs79/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
name
Name of the new board
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
description
Optional description for the board
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
parent_space_url
Space to create the content inside, given either as a full Miro space URL (e.g., 'https://miro.com/app/dashboard/space/0VM5RHCprOu2MnOHXLqp3f') or as the space content item id on its own (e.g., '0VM5RHCprOu2MnOHXLqp3f'). Omit to create at the team root instead.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
icon_emoji
Optional single emoji to use as the board icon, e.g. "🚀". Set it when the user asks for an icon; otherwise leave it unset.
Clear enough to supply this argument.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Explain what happens when this optional value is omitted.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
{
"name": "board_create",
"title": "Create New Board",
"description": "Create a new Miro board. To place the board inside a space, pass parent_space_url - either the space URL or the space content item id. Creating it in the space directly saves the extra board_move call that creating it at the team root would need. IMPORTANT: Always confirm with the user before creating a board. This action creates a new board and cannot be undone.",
"inputSchema": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"maxLength": 60,
"minLength": 1,
"description": "Name of the new board"
},
"icon_emoji": {
"type": "string",
"default": null,
"nullable": true,
"description": "Optional single emoji to use as the board icon, e.g. \"🚀\". Set it when the user asks for an icon; otherwise leave it unset."
},
"description": {
"type": "string",
"default": null,
"nullable": true,
"maxLength": 2000,
"description": "Optional description for the board"
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"parent_space_url": {
"type": "string",
"default": null,
"nullable": true,
"minLength": 1,
"description": "Space to create the content inside, given either as a full Miro space URL (e.g., 'https://miro.com/app/dashboard/space/0VM5RHCprOu2MnOHXLqp3f') or as the space content item id on its own (e.g., '0VM5RHCprOu2MnOHXLqp3f'). Omit to create at the team root instead."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"additionalProperties": true
},
"annotations": {
"title": "Create New Board",
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description90/100
Create a new Miro space. A space organizes related content together (Boards; Documents; Tables; Diagrams; etc). Always give the space an icon: use the emoji the user asked for, and when they did not name one, pick a fitting emoji yourself from the space name. IMPORTANT: Always confirm with the user before creating a space. This action creates a new space and cannot be undone.
The description explains the capability, when to use it, and what to expect.
Inputs80/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
name
Name of the new space
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
description
Optional description for the space
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
icon_emoji
Single emoji to use as the space icon, e.g. "🚀". Pass the emoji the user asked for; if they did not name one, choose a fitting emoji yourself based on the space name rather than leaving this empty.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Clear enough to supply this argument.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
{
"name": "space_create",
"title": "Create New Space",
"description": "Create a new Miro space. A space organizes related content together (Boards; Documents; Tables; Diagrams; etc). Always give the space an icon: use the emoji the user asked for, and when they did not name one, pick a fitting emoji yourself from the space name. IMPORTANT: Always confirm with the user before creating a space. This action creates a new space and cannot be undone.",
"inputSchema": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"maxLength": 60,
"minLength": 1,
"description": "Name of the new space"
},
"icon_emoji": {
"type": "string",
"default": null,
"nullable": true,
"description": "Single emoji to use as the space icon, e.g. \"🚀\". Pass the emoji the user asked for; if they did not name one, choose a fitting emoji yourself based on the space name rather than leaving this empty."
},
"description": {
"type": "string",
"default": null,
"nullable": true,
"maxLength": 2000,
"description": "Optional description for the space"
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"additionalProperties": true
},
"annotations": {
"title": "Create New Space",
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description79/100
Create a new section inside a space to group related boards and content. A section must live inside a space, so provide the space URL. If no title is given, a short one is generated from the user's goal. IMPORTANT: Always confirm with the user before creating a section.
The description explains the capability, when to use it, and what to expect.
Inputs80/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
space_url
A space, given either as a full Miro space URL (e.g., 'https://miro.com/app/dashboard/space/0VM5RHCprOu2MnOHXLqp3f') or as the space content item id on its own (e.g., '0VM5RHCprOu2MnOHXLqp3f'). Both the URL returned when a space is created and the content_item_id from a space listing are accepted.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
title
Title for the new section
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
order
Optional position among sibling sections; higher values are ordered first. When omitted, the section is placed on top.
Clear enough to supply this argument.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Explain what happens when this optional value is omitted.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"required": [
"content_item_id"
],
"properties": {
"content_item_id": {
"type": "string",
"description": "Content item ID of the created folder"
}
},
"description": "Response from creating a folder."
}
Original tool metadata
{
"name": "section_create",
"title": "Create Section",
"description": "Create a new section inside a space to group related boards and content. A section must live inside a space, so provide the space URL. If no title is given, a short one is generated from the user's goal. IMPORTANT: Always confirm with the user before creating a section.",
"inputSchema": {
"type": "object",
"required": [
"space_url"
],
"properties": {
"order": {
"type": "integer",
"default": null,
"nullable": true,
"description": "Optional position among sibling sections; higher values are ordered first. When omitted, the section is placed on top."
},
"title": {
"type": "string",
"default": null,
"nullable": true,
"maxLength": 60,
"description": "Title for the new section"
},
"space_url": {
"type": "string",
"minLength": 1,
"description": "A space, given either as a full Miro space URL (e.g., 'https://miro.com/app/dashboard/space/0VM5RHCprOu2MnOHXLqp3f') or as the space content item id on its own (e.g., '0VM5RHCprOu2MnOHXLqp3f'). Both the URL returned when a space is created and the content_item_id from a space listing are accepted."
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"required": [
"content_item_id"
],
"properties": {
"content_item_id": {
"type": "string",
"description": "Content item ID of the created folder"
}
},
"description": "Response from creating a folder."
},
"annotations": {
"title": "Create Section",
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description95/100
Delete a section. Boards inside the section are not deleted; they are moved up to the parent space. IMPORTANT: Always confirm with the user before deleting a section.
The description explains the capability, when to use it, and what to expect.
Inputs75/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
section_content_item_id
Identifier of the section to delete
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
{
"name": "section_delete",
"title": "Delete Section",
"description": "Delete a section. Boards inside the section are not deleted; they are moved up to the parent space. IMPORTANT: Always confirm with the user before deleting a section.",
"inputSchema": {
"type": "object",
"required": [
"section_content_item_id"
],
"properties": {
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
},
"section_content_item_id": {
"type": "string",
"minLength": 1,
"description": "Identifier of the section to delete"
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"additionalProperties": true
},
"annotations": {
"title": "Delete Section",
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description75/100
Rename a section or change its position among sibling sections. Provide at least one of a new title or a new order.
The description explains the capability, when to use it, and what to expect.
Inputs70/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
section_content_item_id
Identifier of the section to update
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
title
New section title
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
order
New position among sibling sections; lower values are ordered first.
Clear enough to supply this argument.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Resolve the mismatch between this description and its schema constraints.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
{
"name": "section_update_metadata",
"title": "Update Section Metadata",
"description": "Rename a section or change its position among sibling sections. Provide at least one of a new title or a new order.",
"inputSchema": {
"type": "object",
"required": [
"section_content_item_id"
],
"properties": {
"order": {
"type": "integer",
"default": null,
"nullable": true,
"description": "New position among sibling sections; lower values are ordered first."
},
"title": {
"type": "string",
"default": null,
"nullable": true,
"maxLength": 60,
"description": "New section title"
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
},
"section_content_item_id": {
"type": "string",
"minLength": 1,
"description": "Identifier of the section to update"
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"additionalProperties": true
},
"annotations": {
"title": "Update Section Metadata",
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description91/100
Create a typed board format, such as a table, timeline, kanban, document, diagram, prototyping container, slide container, activities board, or embed. Use this tool when the user asks for the document/table/diagram itself as a standalone piece of content (e.g. 'create a doc in Miro about X', 'make me a table of Y'). Prefer it over adding a doc, table or diagram widget to an existing board: those tools are for adding content onto a board the user is already working on. To place the format inside a space, pass parent_space_url - either the space URL or the space content item id. Creating it in the space directly saves the extra board_move call that creating it at the team root would need. IMPORTANT: Always confirm with the user before creating content. This action cannot be undone.
The description explains the capability, when to use it, and what to expect.
Inputs75/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
name
Name of the new format
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
format_type
The kind of format to create
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
parent_space_url
Space to create the content inside, given either as a full Miro space URL (e.g., 'https://miro.com/app/dashboard/space/0VM5RHCprOu2MnOHXLqp3f') or as the space content item id on its own (e.g., '0VM5RHCprOu2MnOHXLqp3f'). Omit to create at the team root instead.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
embed_url
Source URL to embed (only used when format_type is 'embed')
Clear enough to supply this argument.
icon_emoji
Optional single emoji to use as the icon, e.g. "🚀". Set it when the user asks for an icon; otherwise leave it unset.
Clear enough to supply this argument.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Resolve the mismatch between this description and its schema constraints.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
{
"name": "board_create_format",
"title": "Create Board Format",
"description": "Create a typed board format, such as a table, timeline, kanban, document, diagram, prototyping container, slide container, activities board, or embed. Use this tool when the user asks for the document/table/diagram itself as a standalone piece of content (e.g. 'create a doc in Miro about X', 'make me a table of Y'). Prefer it over adding a doc, table or diagram widget to an existing board: those tools are for adding content onto a board the user is already working on. To place the format inside a space, pass parent_space_url - either the space URL or the space content item id. Creating it in the space directly saves the extra board_move call that creating it at the team root would need. IMPORTANT: Always confirm with the user before creating content. This action cannot be undone.",
"inputSchema": {
"type": "object",
"required": [
"name",
"format_type"
],
"properties": {
"name": {
"type": "string",
"maxLength": 255,
"minLength": 1,
"description": "Name of the new format"
},
"embed_url": {
"type": "string",
"default": null,
"nullable": true,
"description": "Source URL to embed (only used when format_type is 'embed')"
},
"icon_emoji": {
"type": "string",
"default": null,
"nullable": true,
"description": "Optional single emoji to use as the icon, e.g. \"🚀\". Set it when the user asks for an icon; otherwise leave it unset."
},
"format_type": {
"enum": [
"embed",
"table",
"timeline",
"kanban",
"document",
"diagram",
"prototyping_container",
"slide_container",
"activities"
],
"type": "string",
"description": "The kind of format to create"
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"parent_space_url": {
"type": "string",
"default": null,
"nullable": true,
"minLength": 1,
"description": "Space to create the content inside, given either as a full Miro space URL (e.g., 'https://miro.com/app/dashboard/space/0VM5RHCprOu2MnOHXLqp3f') or as the space content item id on its own (e.g., '0VM5RHCprOu2MnOHXLqp3f'). Omit to create at the team root instead."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"additionalProperties": true
},
"annotations": {
"title": "Create Board Format",
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description81/100
Move an existing Miro board under a space or folder. Use this tool when a user asks to move a board into a space or under a folder. Provide the board and the content item id of the destination space or folder.
The description explains the capability, when to use it, and what to expect.
Inputs93/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
miro_url
Full Miro board URL (e.g., 'https://miro.com/app/board/uXjVOakxTk0='). To target a specific parent frame, include ?moveToWidget=<frame_id>.
Clear enough to supply this argument.
target_parent_content_item_id
Content item id of the destination space or folder.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Clear enough to supply this argument.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
{
"name": "board_move",
"title": "Move Board",
"description": "Move an existing Miro board under a space or folder. Use this tool when a user asks to move a board into a space or under a folder. Provide the board and the content item id of the destination space or folder.",
"inputSchema": {
"type": "object",
"required": [
"miro_url",
"target_parent_content_item_id"
],
"properties": {
"miro_url": {
"type": "string",
"description": "Full Miro board URL (e.g., 'https://miro.com/app/board/uXjVOakxTk0='). To target a specific parent frame, include ?moveToWidget=<frame_id>."
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
},
"target_parent_content_item_id": {
"type": "string",
"minLength": 1,
"description": "Content item id of the destination space or folder."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"additionalProperties": true
},
"annotations": {
"title": "Move Board",
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description65/100
Move a board to a different team.
Describe the concrete operation and its scope instead of restating the tool name.
Inputs87/100
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
miro_url
Full Miro board URL (e.g., 'https://miro.com/app/board/uXjVOakxTk0='). To target a specific parent frame, include ?moveToWidget=<frame_id>.
Clear enough to supply this argument.
target_team_id
Numeric identifier of the destination team
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Clear enough to supply this argument.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
{
"name": "board_move_to_team",
"title": "Move Board To Team",
"description": "Move a board to a different team.",
"inputSchema": {
"type": "object",
"required": [
"miro_url",
"target_team_id"
],
"properties": {
"miro_url": {
"type": "string",
"description": "Full Miro board URL (e.g., 'https://miro.com/app/board/uXjVOakxTk0='). To target a specific parent frame, include ?moveToWidget=<frame_id>."
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"target_team_id": {
"type": "integer",
"description": "Numeric identifier of the destination team"
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"additionalProperties": true
},
"annotations": {
"title": "Move Board To Team",
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description87/100
Update a board's title, description and/or icon emoji. Omitted fields are left unchanged. To remove the board's icon, pass an empty string as icon_emoji.
The description explains the capability, when to use it, and what to expect.
Inputs92/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
miro_url
Full Miro board URL (e.g., 'https://miro.com/app/board/uXjVOakxTk0='). To target a specific parent frame, include ?moveToWidget=<frame_id>.
Clear enough to supply this argument.
title
New board title
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
description
New board description
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
icon_emoji
New single-emoji icon for the board, e.g. "🚀". Omit to leave the icon unchanged; pass an empty string to remove it.
Clear enough to supply this argument.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Clear enough to supply this argument.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
{
"name": "board_update_metadata",
"title": "Update Board Metadata",
"description": "Update a board's title, description and/or icon emoji. Omitted fields are left unchanged. To remove the board's icon, pass an empty string as icon_emoji.",
"inputSchema": {
"type": "object",
"required": [
"miro_url"
],
"properties": {
"title": {
"type": "string",
"default": null,
"nullable": true,
"maxLength": 255,
"description": "New board title"
},
"miro_url": {
"type": "string",
"description": "Full Miro board URL (e.g., 'https://miro.com/app/board/uXjVOakxTk0='). To target a specific parent frame, include ?moveToWidget=<frame_id>."
},
"icon_emoji": {
"type": "string",
"default": null,
"nullable": true,
"description": "New single-emoji icon for the board, e.g. \"🚀\". Omit to leave the icon unchanged; pass an empty string to remove it."
},
"description": {
"type": "string",
"default": null,
"nullable": true,
"maxLength": 2000,
"description": "New board description"
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"additionalProperties": true
},
"annotations": {
"title": "Update Board Metadata",
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description61/100
Find which space a board belongs to.
Describe the returned information so the agent knows whether it will answer the request.
Inputs92/100
Input documentation gives an agent enough context to populate the arguments.
miro_url
Full Miro board URL (e.g., 'https://miro.com/app/board/uXjVOakxTk0='). To target a specific parent frame, include ?moveToWidget=<frame_id>.
Clear enough to supply this argument.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Clear enough to supply this argument.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
{
"name": "board_get_space",
"title": "Get Board Space",
"description": "Find which space a board belongs to.",
"inputSchema": {
"type": "object",
"required": [
"miro_url"
],
"properties": {
"miro_url": {
"type": "string",
"description": "Full Miro board URL (e.g., 'https://miro.com/app/board/uXjVOakxTk0='). To target a specific parent frame, include ?moveToWidget=<frame_id>."
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"additionalProperties": true
},
"annotations": {
"title": "Get Board Space",
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description68/100
Restore one or more boards from trash.
Explain mutations, irreversible effects, or prerequisites that matter before calling this tool.
Inputs89/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
board_urls
Full Miro board URLs to restore from trash
Clear enough to supply this argument.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Clear enough to supply this argument.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
{
"name": "board_restore",
"title": "Restore Boards",
"description": "Restore one or more boards from trash.",
"inputSchema": {
"type": "object",
"required": [
"board_urls"
],
"properties": {
"board_urls": {
"type": "array",
"items": {
"type": "string"
},
"maxItems": 100,
"minItems": 1,
"description": "Full Miro board URLs to restore from trash"
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"additionalProperties": true
},
"annotations": {
"title": "Restore Boards",
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description87/100
Update a space's title, description and/or icon emoji. Omitted fields are left unchanged. A space icon can be replaced but not removed.
The description explains the capability, when to use it, and what to expect.
Inputs88/100
Explain what happens when this optional value is omitted.
space_url
A space, given either as a full Miro space URL (e.g., 'https://miro.com/app/dashboard/space/0VM5RHCprOu2MnOHXLqp3f') or as the space content item id on its own (e.g., '0VM5RHCprOu2MnOHXLqp3f'). Both the URL returned when a space is created and the content_item_id from a space listing are accepted.
Clear enough to supply this argument.
title
New space title
Explain what happens when this optional value is omitted.
description
New space description
Explain the meaning of this value, not just its name.
icon_emoji
New single-emoji icon for the space, e.g. "🚀". Omit to leave the icon unchanged. A space icon cannot be removed, only replaced.
Clear enough to supply this argument.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Clear enough to supply this argument.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
{
"name": "space_update_metadata",
"title": "Update Space Metadata",
"description": "Update a space's title, description and/or icon emoji. Omitted fields are left unchanged. A space icon can be replaced but not removed.",
"inputSchema": {
"type": "object",
"required": [
"space_url"
],
"properties": {
"title": {
"type": "string",
"default": null,
"nullable": true,
"maxLength": 60,
"description": "New space title"
},
"space_url": {
"type": "string",
"minLength": 1,
"description": "A space, given either as a full Miro space URL (e.g., 'https://miro.com/app/dashboard/space/0VM5RHCprOu2MnOHXLqp3f') or as the space content item id on its own (e.g., '0VM5RHCprOu2MnOHXLqp3f'). Both the URL returned when a space is created and the content_item_id from a space listing are accepted."
},
"icon_emoji": {
"type": "string",
"default": null,
"nullable": true,
"description": "New single-emoji icon for the space, e.g. \"🚀\". Omit to leave the icon unchanged. A space icon cannot be removed, only replaced."
},
"description": {
"type": "string",
"default": null,
"nullable": true,
"maxLength": 2000,
"description": "New space description"
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"additionalProperties": true
},
"annotations": {
"title": "Update Space Metadata",
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description77/100
List the boards inside one specific space. Requires the identifier or URL of that space, so use it only when the user names a particular space (e.g. 'boards in the Design space'). For team-level requests (e.g. 'list boards in my team'), list the team's spaces first with the list spaces tool.
The description explains the capability, when to use it, and what to expect.
Inputs92/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
space_url
A space, given either as a full Miro space URL (e.g., 'https://miro.com/app/dashboard/space/0VM5RHCprOu2MnOHXLqp3f') or as the space content item id on its own (e.g., '0VM5RHCprOu2MnOHXLqp3f'). Both the URL returned when a space is created and the content_item_id from a space listing are accepted.
Clear enough to supply this argument.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Clear enough to supply this argument.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
{
"type": "object",
"required": [
"boards"
],
"properties": {
"boards": {
"type": "array",
"items": {
"type": "object",
"required": [
"name",
"miro_url"
],
"properties": {
"name": {
"type": "string",
"description": "Name of the board"
},
"miro_url": {
"type": "string",
"description": "Full Miro URL to open the board"
}
},
"description": "A board contained within a space."
},
"description": "Boards in the space"
}
},
"description": "Boards contained within a space."
}
Original tool metadata
{
"name": "space_list_boards",
"title": "List Space Boards",
"description": "List the boards inside one specific space. Requires the identifier or URL of that space, so use it only when the user names a particular space (e.g. 'boards in the Design space'). For team-level requests (e.g. 'list boards in my team'), list the team's spaces first with the list spaces tool.",
"inputSchema": {
"type": "object",
"required": [
"space_url"
],
"properties": {
"space_url": {
"type": "string",
"minLength": 1,
"description": "A space, given either as a full Miro space URL (e.g., 'https://miro.com/app/dashboard/space/0VM5RHCprOu2MnOHXLqp3f') or as the space content item id on its own (e.g., '0VM5RHCprOu2MnOHXLqp3f'). Both the URL returned when a space is created and the content_item_id from a space listing are accepted."
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"required": [
"boards"
],
"properties": {
"boards": {
"type": "array",
"items": {
"type": "object",
"required": [
"name",
"miro_url"
],
"properties": {
"name": {
"type": "string",
"description": "Name of the board"
},
"miro_url": {
"type": "string",
"description": "Full Miro URL to open the board"
}
},
"description": "A board contained within a space."
},
"description": "Boards in the space"
}
},
"description": "Boards contained within a space."
},
"annotations": {
"title": "List Space Boards",
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
List the direct children of a space or section, one level deep. Provide the content item id of a space or a section, and it returns each immediate child's content item id, type (e.g. board, folder, doc, diagram) and title, plus a board URL when the child is a board. Use it to explore what sits directly inside a space or section (e.g. its boards and sub-sections). The id must belong to a space or a section; other content items are rejected. Results are paginated: pass the returned cursor to fetch the next page.
The description explains the capability, when to use it, and what to expect.
Inputs60/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
content_item_id
Content item id of the space or section whose direct children to list
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
limit
Maximum number of children to return per page
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
cursor
Opaque cursor token for fetching the next page
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Resolve the mismatch between this description and its schema constraints.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
{
"title": "List Space Or Section Children",
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
Output schema53/100
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"required": [
"children",
"has_more"
],
"properties": {
"children": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
},
"description": "Direct children, one level deep"
},
"has_more": {
"type": "boolean",
"description": "Whether there are more results available"
},
"nextCursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Opaque cursor token for fetching the next page (MCP nextCursor)"
}
},
"description": "Paginated direct children of a space or section."
}
Original tool metadata
{
"name": "space_list_children",
"title": "List Space Or Section Children",
"description": "List the direct children of a space or section, one level deep. Provide the content item id of a space or a section, and it returns each immediate child's content item id, type (e.g. board, folder, doc, diagram) and title, plus a board URL when the child is a board. Use it to explore what sits directly inside a space or section (e.g. its boards and sub-sections). The id must belong to a space or a section; other content items are rejected. Results are paginated: pass the returned cursor to fetch the next page.",
"inputSchema": {
"type": "object",
"required": [
"content_item_id"
],
"properties": {
"limit": {
"type": "integer",
"default": 50,
"maximum": 100,
"minimum": 1,
"description": "Maximum number of children to return per page"
},
"cursor": {
"type": "string",
"default": null,
"nullable": true,
"description": "Opaque cursor token for fetching the next page"
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"content_item_id": {
"type": "string",
"minLength": 1,
"description": "Content item id of the space or section whose direct children to list"
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"required": [
"children",
"has_more"
],
"properties": {
"children": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
},
"description": "Direct children, one level deep"
},
"has_more": {
"type": "boolean",
"description": "Whether there are more results available"
},
"nextCursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Opaque cursor token for fetching the next page (MCP nextCursor)"
}
},
"description": "Paginated direct children of a space or section."
},
"annotations": {
"title": "List Space Or Section Children",
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description88/100
List the spaces in the current user's team. Spaces are the top-level containers that organize a team's boards and other content, so this is the primary entry point for exploring what a team has. Prefer this tool for any team-level listing request, including phrasings like 'list boards in my team', 'what's in my Miro team', 'show my team's content', or 'get team spaces'. To then list the boards inside a particular space, use the space boards tool.
The description explains the capability, when to use it, and what to expect.
Inputs69/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
limit
Maximum number of spaces to return per page
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
cursor
Opaque cursor token for fetching the next page
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
Describe the returned fields so an agent can interpret the result.
View output schema
{
"type": "object",
"required": [
"data",
"has_more"
],
"properties": {
"data": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
},
"description": "List of spaces"
},
"has_more": {
"type": "boolean",
"description": "Whether there are more results available"
},
"nextCursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Opaque cursor token for fetching the next page (MCP nextCursor)"
}
},
"description": "Paginated list of team spaces."
}
Original tool metadata
{
"name": "space_list",
"title": "List Team Spaces",
"description": "List the spaces in the current user's team. Spaces are the top-level containers that organize a team's boards and other content, so this is the primary entry point for exploring what a team has. Prefer this tool for any team-level listing request, including phrasings like 'list boards in my team', 'what's in my Miro team', 'show my team's content', or 'get team spaces'. To then list the boards inside a particular space, use the space boards tool.",
"inputSchema": {
"type": "object",
"properties": {
"limit": {
"type": "integer",
"default": 20,
"maximum": 100,
"minimum": 1,
"description": "Maximum number of spaces to return per page"
},
"cursor": {
"type": "string",
"default": null,
"nullable": true,
"description": "Opaque cursor token for fetching the next page"
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"required": [
"data",
"has_more"
],
"properties": {
"data": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
},
"description": "List of spaces"
},
"has_more": {
"type": "boolean",
"description": "Whether there are more results available"
},
"nextCursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Opaque cursor token for fetching the next page (MCP nextCursor)"
}
},
"description": "Paginated list of team spaces."
},
"annotations": {
"title": "List Team Spaces",
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
List who can access a board or space and the role each of them holds. Use this to answer who a board or space is shared with, or what access somebody has. Each entry names the subject, its kind, the role it holds and, for users, their email address. User groups have no email, so identify them by their subject id. Entries whose kind is 'user' or 'user_group' and whose role is one of owner, coowner, editor, commenter or viewer can be fed straight into board_role_update or space_role_update. Access granted by other means is still listed, under its own kind or role name such as 'team' or 'private', and cannot be changed with those tools. Results are paginated: pass the returned cursor back to fetch the next page.
The description explains the capability, when to use it, and what to expect.
Inputs75/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
content_item_url
The board or space to inspect. Give a full Miro board URL (e.g., 'https://miro.com/app/board/uXjVOakxTk0='), a full Miro space URL (e.g., 'https://miro.com/app/dashboard/space/0VM5RHCprOu2MnOHXLqp3f'), or the content item id of either on its own (e.g., '0VM5RHCprOu2MnOHXLqp3f') - a content item id identifies a board just as well as a space. A board key on its own is not accepted; use the board URL for that.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
limit
Maximum entries per page (1-100)
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
cursor
Opaque cursor token for fetching the next page
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Describe the returned fields so an agent can interpret the result.
View output schema
{
"type": "object",
"required": [
"entries",
"has_more"
],
"properties": {
"entries": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
},
"description": "Subjects with access, one entry per role assignment"
},
"has_more": {
"type": "boolean",
"description": "Whether there are more results available"
},
"nextCursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Opaque cursor token for fetching the next page (MCP nextCursor)"
}
},
"description": "Paginated view of who can access a content item."
}
Original tool metadata
{
"name": "content_item_list_roles",
"title": "List Content Item Roles",
"description": "List who can access a board or space and the role each of them holds. Use this to answer who a board or space is shared with, or what access somebody has. Each entry names the subject, its kind, the role it holds and, for users, their email address. User groups have no email, so identify them by their subject id. Entries whose kind is 'user' or 'user_group' and whose role is one of owner, coowner, editor, commenter or viewer can be fed straight into board_role_update or space_role_update. Access granted by other means is still listed, under its own kind or role name such as 'team' or 'private', and cannot be changed with those tools. Results are paginated: pass the returned cursor back to fetch the next page.",
"inputSchema": {
"type": "object",
"required": [
"content_item_url"
],
"properties": {
"limit": {
"type": "integer",
"default": null,
"maximum": 100,
"minimum": 1,
"nullable": true,
"description": "Maximum entries per page (1-100)"
},
"cursor": {
"type": "string",
"default": null,
"nullable": true,
"description": "Opaque cursor token for fetching the next page"
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"content_item_url": {
"type": "string",
"minLength": 1,
"description": "The board or space to inspect. Give a full Miro board URL (e.g., 'https://miro.com/app/board/uXjVOakxTk0='), a full Miro space URL (e.g., 'https://miro.com/app/dashboard/space/0VM5RHCprOu2MnOHXLqp3f'), or the content item id of either on its own (e.g., '0VM5RHCprOu2MnOHXLqp3f') - a content item id identifies a board just as well as a space. A board key on its own is not accepted; use the board URL for that."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"required": [
"entries",
"has_more"
],
"properties": {
"entries": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
},
"description": "Subjects with access, one entry per role assignment"
},
"has_more": {
"type": "boolean",
"description": "Whether there are more results available"
},
"nextCursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Opaque cursor token for fetching the next page (MCP nextCursor)"
}
},
"description": "Paginated view of who can access a content item."
},
"annotations": {
"title": "List Content Item Roles",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description88/100
Grant a user or user group access to a board with a specific role. Use to share a board with someone who does not yet have access. If they already have a role, use board_role_update instead. IMPORTANT: Always confirm with the user before changing who can access a board.
The description explains the capability, when to use it, and what to expect.
Inputs71/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
miro_url
Full Miro board URL (e.g., 'https://miro.com/app/board/uXjVOakxTk0='). To target a specific parent frame, include ?moveToWidget=<frame_id>.
Clear enough to supply this argument.
subject_id
Identifier of the user or user group. For a user this can be the user's email or user id; for a user group this is the group id.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
subject_type
Whether the subject is an individual user or a user group
Clear enough to supply this argument.
role
Role to assign: owner, coowner, editor, commenter, or viewer (from most to least access).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Resolve the mismatch between this description and its schema constraints.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
{
"name": "board_share",
"title": "Share Board",
"description": "Grant a user or user group access to a board with a specific role. Use to share a board with someone who does not yet have access. If they already have a role, use board_role_update instead. IMPORTANT: Always confirm with the user before changing who can access a board.",
"inputSchema": {
"type": "object",
"required": [
"miro_url",
"subject_id",
"subject_type",
"role"
],
"properties": {
"role": {
"enum": [
"owner",
"coowner",
"editor",
"commenter",
"viewer"
],
"type": "string",
"description": "Role to assign: owner, coowner, editor, commenter, or viewer (from most to least access)."
},
"miro_url": {
"type": "string",
"description": "Full Miro board URL (e.g., 'https://miro.com/app/board/uXjVOakxTk0='). To target a specific parent frame, include ?moveToWidget=<frame_id>."
},
"subject_id": {
"type": "string",
"minLength": 1,
"description": "Identifier of the user or user group. For a user this can be the user's email or user id; for a user group this is the group id."
},
"subject_type": {
"enum": [
"user",
"user_group"
],
"type": "string",
"description": "Whether the subject is an individual user or a user group"
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"additionalProperties": true
},
"annotations": {
"title": "Share Board",
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description84/100
Change the role of a user or user group that already has access to a board. If they do not yet have access, use board_share instead. IMPORTANT: Always confirm with the user before changing who can access a board.
The description explains the capability, when to use it, and what to expect.
Inputs79/100
Resolve the mismatch between this description and its schema constraints.
miro_url
Full Miro board URL (e.g., 'https://miro.com/app/board/uXjVOakxTk0='). To target a specific parent frame, include ?moveToWidget=<frame_id>.
Clear enough to supply this argument.
subject_id
Identifier of the user or user group. For a user this can be the user's email or user id; for a user group this is the group id.
Clear enough to supply this argument.
subject_type
Whether the subject is an individual user or a user group
Clear enough to supply this argument.
role
Role to assign: owner, coowner, editor, commenter, or viewer (from most to least access).
Clear enough to supply this argument.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Resolve the mismatch between this description and its schema constraints.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
{
"name": "board_role_update",
"title": "Update Board Role",
"description": "Change the role of a user or user group that already has access to a board. If they do not yet have access, use board_share instead. IMPORTANT: Always confirm with the user before changing who can access a board.",
"inputSchema": {
"type": "object",
"required": [
"miro_url",
"subject_id",
"subject_type",
"role"
],
"properties": {
"role": {
"enum": [
"owner",
"coowner",
"editor",
"commenter",
"viewer"
],
"type": "string",
"description": "Role to assign: owner, coowner, editor, commenter, or viewer (from most to least access)."
},
"miro_url": {
"type": "string",
"description": "Full Miro board URL (e.g., 'https://miro.com/app/board/uXjVOakxTk0='). To target a specific parent frame, include ?moveToWidget=<frame_id>."
},
"subject_id": {
"type": "string",
"minLength": 1,
"description": "Identifier of the user or user group. For a user this can be the user's email or user id; for a user group this is the group id."
},
"subject_type": {
"enum": [
"user",
"user_group"
],
"type": "string",
"description": "Whether the subject is an individual user or a user group"
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"additionalProperties": true
},
"annotations": {
"title": "Update Board Role",
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description89/100
Grant a user or user group access to a space with a specific role. Use to share a space with someone who does not yet have access. If they already have a role, use space_role_update instead. IMPORTANT: Always confirm with the user before changing who can access a space.
The description explains the capability, when to use it, and what to expect.
Inputs79/100
Resolve the mismatch between this description and its schema constraints.
space_url
A space, given either as a full Miro space URL (e.g., 'https://miro.com/app/dashboard/space/0VM5RHCprOu2MnOHXLqp3f') or as the space content item id on its own (e.g., '0VM5RHCprOu2MnOHXLqp3f'). Both the URL returned when a space is created and the content_item_id from a space listing are accepted.
Clear enough to supply this argument.
subject_id
Identifier of the user or user group. For a user this can be the user's email or user id; for a user group this is the group id.
Clear enough to supply this argument.
subject_type
Whether the subject is an individual user or a user group
Clear enough to supply this argument.
role
Role to assign: owner, coowner, editor, commenter, or viewer (from most to least access).
Clear enough to supply this argument.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Resolve the mismatch between this description and its schema constraints.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
{
"name": "space_share",
"title": "Share Space",
"description": "Grant a user or user group access to a space with a specific role. Use to share a space with someone who does not yet have access. If they already have a role, use space_role_update instead. IMPORTANT: Always confirm with the user before changing who can access a space.",
"inputSchema": {
"type": "object",
"required": [
"space_url",
"subject_id",
"subject_type",
"role"
],
"properties": {
"role": {
"enum": [
"owner",
"coowner",
"editor",
"commenter",
"viewer"
],
"type": "string",
"description": "Role to assign: owner, coowner, editor, commenter, or viewer (from most to least access)."
},
"space_url": {
"type": "string",
"minLength": 1,
"description": "A space, given either as a full Miro space URL (e.g., 'https://miro.com/app/dashboard/space/0VM5RHCprOu2MnOHXLqp3f') or as the space content item id on its own (e.g., '0VM5RHCprOu2MnOHXLqp3f'). Both the URL returned when a space is created and the content_item_id from a space listing are accepted."
},
"subject_id": {
"type": "string",
"minLength": 1,
"description": "Identifier of the user or user group. For a user this can be the user's email or user id; for a user group this is the group id."
},
"subject_type": {
"enum": [
"user",
"user_group"
],
"type": "string",
"description": "Whether the subject is an individual user or a user group"
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"additionalProperties": true
},
"annotations": {
"title": "Share Space",
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description84/100
Change the role of a user or user group that already has access to a space. If they do not yet have access, use space_share instead. IMPORTANT: Always confirm with the user before changing who can access a space.
The description explains the capability, when to use it, and what to expect.
Inputs75/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
space_url
A space, given either as a full Miro space URL (e.g., 'https://miro.com/app/dashboard/space/0VM5RHCprOu2MnOHXLqp3f') or as the space content item id on its own (e.g., '0VM5RHCprOu2MnOHXLqp3f'). Both the URL returned when a space is created and the content_item_id from a space listing are accepted.
Clear enough to supply this argument.
subject_id
Identifier of the user or user group. For a user this can be the user's email or user id; for a user group this is the group id.
Clear enough to supply this argument.
subject_type
Whether the subject is an individual user or a user group
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
role
Role to assign: owner, coowner, editor, commenter, or viewer (from most to least access).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Resolve the mismatch between this description and its schema constraints.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
{
"name": "space_role_update",
"title": "Update Space Role",
"description": "Change the role of a user or user group that already has access to a space. If they do not yet have access, use space_share instead. IMPORTANT: Always confirm with the user before changing who can access a space.",
"inputSchema": {
"type": "object",
"required": [
"space_url",
"subject_id",
"subject_type",
"role"
],
"properties": {
"role": {
"enum": [
"owner",
"coowner",
"editor",
"commenter",
"viewer"
],
"type": "string",
"description": "Role to assign: owner, coowner, editor, commenter, or viewer (from most to least access)."
},
"space_url": {
"type": "string",
"minLength": 1,
"description": "A space, given either as a full Miro space URL (e.g., 'https://miro.com/app/dashboard/space/0VM5RHCprOu2MnOHXLqp3f') or as the space content item id on its own (e.g., '0VM5RHCprOu2MnOHXLqp3f'). Both the URL returned when a space is created and the content_item_id from a space listing are accepted."
},
"subject_id": {
"type": "string",
"minLength": 1,
"description": "Identifier of the user or user group. For a user this can be the user's email or user id; for a user group this is the group id."
},
"subject_type": {
"enum": [
"user",
"user_group"
],
"type": "string",
"description": "Whether the subject is an individual user or a user group"
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"additionalProperties": true
},
"annotations": {
"title": "Update Space Role",
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description95/100
Create a table on a Miro board with specified columns. Supports text, select, multiselect, date, link, person, and number column types. This always creates a plain grid table. To produce a timeline, kanban, or tree, first create the table here, then call table_update_view to switch its layout. For a request like 'create a timeline/kanban/tree', do BOTH steps in sequence. Coordinates: when the URL has no item target, x/y are board-absolute (board center is (0, 0)). When the URL targets a frame via moveToWidget, the table is created INSIDE that frame and x/y are relative to the frame's top-left corner; (0, 0) is the frame's top-left and the table must fit within the frame's width and height. If no board URL is provided, a new board will be created. IMPORTANT: Always confirm with the user before creating a new board.
The description explains the capability, when to use it, and what to expect.
Inputs64/100
19 of 26 inputs have descriptions. Add descriptions to the missing inputs, including where to obtain IDs and how to supply values.
table_title
The title/name of the table
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
columns › items › oneOf › 0 › column_type
Not provided
Missing description. Explain what this value means and how to supply it.
columns › items › oneOf › 0 › column_title
Column name (e.g., 'Title', 'Description', 'Notes')
Clear enough to supply this argument.
columns › items › oneOf › 0 › isTitle
Set true to make this the table's primary title column. Every table has exactly one, and it cannot be deleted. Mark the most identifying text column (a name or short summary). If no text column is marked, the first text column is used; if there is no text column, a 'Title' column is added automatically.
Clear enough to supply this argument.
columns › items › oneOf › 1 › column_type
Not provided
Missing description. Explain what this value means and how to supply it.
columns › items › oneOf › 1 › column_title
Column name (e.g., 'Status', 'Priority')
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Hex color code for this option (e.g., '#FF0000' for red, '#00FF00' for green)
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
columns › items › oneOf › 3 › column_type
Not provided
Missing description. Explain what this value means and how to supply it.
columns › items › oneOf › 3 › column_title
Column name (e.g., 'Due Date', 'Start Date')
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
columns › items › oneOf › 4 › column_type
Not provided
Missing description. Explain what this value means and how to supply it.
columns › items › oneOf › 4 › column_title
Column name (e.g., 'Reference', 'Source URL')
Clear enough to supply this argument.
columns › items › oneOf › 5 › column_type
Not provided
Missing description. Explain what this value means and how to supply it.
columns › items › oneOf › 5 › column_title
Column name (e.g., 'Assignee', 'Owner')
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
columns › items › oneOf › 6 › column_type
Not provided
Missing description. Explain what this value means and how to supply it.
columns › items › oneOf › 6 › column_title
Column name (e.g., 'Estimate', 'Quantity', 'Price')
Clear enough to supply this argument.
columns › items › oneOf › 6 › decimals
Number of decimal places to display
Clear enough to supply this argument.
x
X-axis coordinate for table placement. Without a frame target: board-absolute, board center is x=0. With a frame target via moveToWidget: relative to the frame's top-left corner (frame top-left is x=0). Use different x values to prevent overlap when creating multiple items.
Clear enough to supply this argument.
y
Y-axis coordinate for table placement. Without a frame target: board-absolute, board center is y=0. With a frame target via moveToWidget: relative to the frame's top-left corner (frame top-left is y=0). Use different y values to prevent overlap when creating multiple items.
Clear enough to supply this argument.
miro_url
Full Miro board URL (e.g., 'https://miro.com/app/board/uXjVOakxTk0='). If not provided, a new board will be created (requires user confirmation). To target a specific parent frame, include ?moveToWidget=<frame_id>.
Clear enough to supply this argument.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Clear enough to supply this argument.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
{
"name": "table_create",
"title": "Create Table",
"description": "Create a table on a Miro board with specified columns. Supports text, select, multiselect, date, link, person, and number column types. This always creates a plain grid table. To produce a timeline, kanban, or tree, first create the table here, then call table_update_view to switch its layout. For a request like 'create a timeline/kanban/tree', do BOTH steps in sequence. Coordinates: when the URL has no item target, x/y are board-absolute (board center is (0, 0)). When the URL targets a frame via moveToWidget, the table is created INSIDE that frame and x/y are relative to the frame's top-left corner; (0, 0) is the frame's top-left and the table must fit within the frame's width and height. If no board URL is provided, a new board will be created. IMPORTANT: Always confirm with the user before creating a new board.",
"inputSchema": {
"type": "object",
"required": [
"table_title",
"columns"
],
"properties": {
"x": {
"type": "number",
"default": null,
"nullable": true,
"description": "X-axis coordinate for table placement. Without a frame target: board-absolute, board center is x=0. With a frame target via moveToWidget: relative to the frame's top-left corner (frame top-left is x=0). Use different x values to prevent overlap when creating multiple items."
},
"y": {
"type": "number",
"default": null,
"nullable": true,
"description": "Y-axis coordinate for table placement. Without a frame target: board-absolute, board center is y=0. With a frame target via moveToWidget: relative to the frame's top-left corner (frame top-left is y=0). Use different y values to prevent overlap when creating multiple items."
},
"columns": {
"type": "array",
"items": {
"oneOf": [
{
"type": "object",
"required": [
"column_title",
"column_type"
],
"properties": {
"isTitle": {
"type": "boolean",
"default": false,
"description": "Set true to make this the table's primary title column. Every table has exactly one, and it cannot be deleted. Mark the most identifying text column (a name or short summary). If no text column is marked, the first text column is used; if there is no text column, a 'Title' column is added automatically."
},
"column_type": {
"type": "string",
"const": "text",
"default": "text"
},
"column_title": {
"type": "string",
"maxLength": 255,
"minLength": 1,
"description": "Column name (e.g., 'Title', 'Description', 'Notes')"
}
},
"description": "Input specification for a text column."
},
{
"type": "object",
"required": [
"column_title",
"options",
"column_type"
],
"properties": {
"options": {
"type": "array",
"items": {
"type": "object",
"required": [
"displayValue",
"color"
],
"properties": {
"color": {
"type": "string",
"pattern": "^#[0-9A-Fa-f]{6}$",
"description": "Hex color code for this option (e.g., '#FF0000' for red, '#00FF00' for green)"
},
"displayValue": {
"type": "string",
"maxLength": 100,
"minLength": 1,
"description": "Display text for this option (e.g., 'To Do', 'In Progress', 'Done')"
}
},
"description": "Input for select column option."
},
"maxItems": 50,
"minItems": 1,
"description": "List of options for the select dropdown"
},
"column_type": {
"type": "string",
"const": "select",
"default": "select"
},
"column_title": {
"type": "string",
"maxLength": 255,
"minLength": 1,
"description": "Column name (e.g., 'Status', 'Priority')"
}
},
"description": "Input specification for a select column."
},
{
"type": "object",
"required": [
"column_title",
"options",
"column_type"
],
"properties": {
"options": {
"type": "array",
"items": {
"type": "object",
"required": [
"displayValue",
"color"
],
"properties": {
"color": {
"type": "string",
"pattern": "^#[0-9A-Fa-f]{6}$",
"description": "Hex color code for this option (e.g., '#FF0000' for red, '#00FF00' for green)"
},
"displayValue": {
"type": "string",
"maxLength": 100,
"minLength": 1,
"description": "Display text for this option (e.g., 'To Do', 'In Progress', 'Done')"
}
},
"description": "Input for select column option."
},
"maxItems": 50,
"minItems": 1,
"description": "List of options for the multiselect dropdown"
},
"column_type": {
"type": "string",
"const": "multiselect",
"default": "multiselect"
},
"column_title": {
"type": "string",
"maxLength": 255,
"minLength": 1,
"description": "Column name (e.g., 'Tags', 'Labels')"
}
},
"description": "Input specification for a multiselect column."
},
{
"type": "object",
"required": [
"column_title",
"column_type"
],
"properties": {
"column_type": {
"type": "string",
"const": "date",
"default": "date"
},
"column_title": {
"type": "string",
"maxLength": 255,
"minLength": 1,
"description": "Column name (e.g., 'Due Date', 'Start Date')"
}
},
"description": "Input specification for a date column."
},
{
"type": "object",
"required": [
"column_title",
"column_type"
],
"properties": {
"column_type": {
"type": "string",
"const": "link",
"default": "link"
},
"column_title": {
"type": "string",
"maxLength": 255,
"minLength": 1,
"description": "Column name (e.g., 'Reference', 'Source URL')"
}
},
"description": "Input specification for a link column."
},
{
"type": "object",
"required": [
"column_title",
"column_type"
],
"properties": {
"column_type": {
"type": "string",
"const": "person",
"default": "person"
},
"column_title": {
"type": "string",
"maxLength": 255,
"minLength": 1,
"description": "Column name (e.g., 'Assignee', 'Owner')"
}
},
"description": "Input specification for a person column."
},
{
"type": "object",
"required": [
"column_title",
"column_type"
],
"properties": {
"decimals": {
"type": "integer",
"default": 0,
"maximum": 10,
"minimum": 0,
"description": "Number of decimal places to display"
},
"column_type": {
"type": "string",
"const": "number",
"default": "number"
},
"column_title": {
"type": "string",
"maxLength": 255,
"minLength": 1,
"description": "Column name (e.g., 'Estimate', 'Quantity', 'Price')"
}
},
"description": "Input specification for a number column."
}
]
},
"maxItems": 50,
"minItems": 1,
"description": "List of columns to create. At least one column must be provided.\n\n Column types:\n 1. Text columns: Simple text fields\n\n 2. Select columns: Dropdown menus with predefined options, single value per row\n - Each option needs a displayValue and color (hex code)\n - column_type \"select\" is required whenever \"options\" is supplied\n\n 3. Multiselect columns: Like select, but a row can hold multiple options\n - Each option needs a displayValue and color (hex code)\n - column_type \"multiselect\" is required whenever \"options\" is supplied\n\n 4. Date columns: Date/time values in ISO 8601 format\n\n 5. Link columns: URLs with optional display text\n\n 6. Person columns: Assign Miro users by their user ID\n\n 7. Number columns: Numeric values with configurable decimal places\n - Optional \"decimals\" (int, default 0) sets displayed decimal places\n\n Examples:\n [\n {\"column_type\": \"text\", \"column_title\": \"Name\", \"isTitle\": true},\n {\"column_type\": \"text\", \"column_title\": \"Description\"},\n {\"column_type\": \"date\", \"column_title\": \"Due Date\"},\n {\"column_type\": \"link\", \"column_title\": \"Reference\"},\n {\"column_type\": \"person\", \"column_title\": \"Assignee\"},\n {\"column_type\": \"number\", \"column_title\": \"Estimate\", \"decimals\": 1},\n {\n \"column_type\": \"select\",\n \"column_title\": \"Status\",\n \"options\": [\n {\"displayValue\": \"To Do\", \"color\": \"#FF0000\"},\n {\"displayValue\": \"In Progress\", \"color\": \"#FFA500\"},\n {\"displayValue\": \"Done\", \"color\": \"#00FF00\"}\n ]\n },\n {\n \"column_type\": \"multiselect\",\n \"column_title\": \"Tags\",\n \"options\": [\n {\"displayValue\": \"Frontend\", \"color\": \"#FF0000\"},\n {\"displayValue\": \"Backend\", \"color\": \"#FFA500\"}\n ]\n }\n ]"
},
"miro_url": {
"type": "string",
"default": null,
"nullable": true,
"description": "Full Miro board URL (e.g., 'https://miro.com/app/board/uXjVOakxTk0='). If not provided, a new board will be created (requires user confirmation). To target a specific parent frame, include ?moveToWidget=<frame_id>."
},
"table_title": {
"type": "string",
"maxLength": 255,
"minLength": 1,
"description": "The title/name of the table"
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"additionalProperties": true
},
"annotations": {
"title": "Create Table",
"readOnlyHint": false,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description94/100
Get rows from a Miro table with column metadata. Each row includes a stable rowId that uniquely identifies it within the table. rowIds persist across sorting, insertion, and deletion — use them to target specific rows in table_sync_rows. Supports filtering by column value. Returns text, select, multiselect, and latest_update columns.
Best practice: always use filter_by and limit when possible.Examples: next item that is not done: {"filter_by": {"Status":["To do", "In progress"]}, "limit": 1}top 5 high priority tasks: {"filter_by": {"Priority":["High"]}, "limit": 5}
Response includes for each row: rowId (stable row identifier), cells (array of columnTitle, valueType, content, options, latest_update_text, latest_update_author_id).
Pagination: Use 'limit' to control page size (default 10) and 'next_cursor' to fetch subsequent pages. The cursor is opaque and encodes pagination state.
IMPORTANT: Do not change 'filter_by' when using a cursor from a previous response, as this will result in an error. To apply a different filter, start a new pagination sequence (no cursor).
The description explains the capability, when to use it, and what to expect.
Inputs67/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
miro_url
Full Miro URL to a specific item (e.g., 'https://miro.com/app/board/uXjVOakxTk0=/?moveToWidget=3458764516062720430'). Must include moveToWidget or focusWidget query parameter.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
filter_by
Filter rows by column value(s) in JSON format (case-insensitive). Only select and multiselect columns are supported. Format: JSON object mapping column names to arrays of display values. Example: {"Status": ["In Progress", "Done"]} matches rows where Status is either 'In Progress' OR 'Done'
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
next_cursor
Pagination cursor for the next set of results
Clear enough to supply this argument.
limit
Maximum rows to return (minimum 1)
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Resolve the mismatch between this description and its schema constraints.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"required": [
"miro_url",
"rows",
"total"
],
"properties": {
"rows": {
"type": "array",
"items": {
"type": "object",
"required": [
"rowId",
"cells"
],
"properties": {
"cells": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
},
"description": "Array of cells in this row"
},
"rowId": {
"type": "string",
"description": "Unique identifier of the row"
}
},
"description": "Single table row."
},
"description": "Array of table rows"
},
"total": {
"type": "integer",
"description": "Total number of rows matching the filter (before pagination)"
},
"cursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Pagination cursor for the next page of results"
},
"columns": {
"anyOf": [
{
"type": "array",
"items": {
"type": "object",
"required": [
"id",
"column_title",
"column_type"
],
"properties": {
"id": {
"type": "string",
"description": "Unique identifier of the column"
},
"column_type": {
"type": "string",
"description": "Column type: 'text', 'select', 'multiselect', 'date', 'link', 'person', or 'number'"
},
"column_title": {
"type": "string",
"description": "Display title of the column"
},
"selectOptions": {
"anyOf": [
{
"type": "array",
"items": {
"type": "object",
"required": [
"id",
"displayValue",
"color"
],
"properties": {
"id": {
"type": "string",
"description": "Unique identifier of the select option"
},
"color": {
"type": "string",
"description": "Color code for this option"
},
"displayValue": {
"type": "string",
"description": "Display text for this option"
}
},
"description": "Option for select-type columns (response)."
}
},
{
"type": "null"
}
],
"default": null,
"description": "Available options (only for select/multiselect columns)"
}
},
"description": "Information about a created table column."
}
},
{
"type": "null"
}
],
"default": null,
"description": "Column metadata including titles, types, and select options"
},
"miro_url": {
"type": "string",
"description": "Full Miro URL to the table"
}
},
"description": "Response from list_rows tool."
}
Original tool metadata
{
"name": "table_list_rows",
"title": "Read Table",
"description": "Get rows from a Miro table with column metadata. Each row includes a stable rowId that uniquely identifies it within the table. rowIds persist across sorting, insertion, and deletion — use them to target specific rows in table_sync_rows. Supports filtering by column value. Returns text, select, multiselect, and latest_update columns.\n\nBest practice: always use filter_by and limit when possible.Examples: next item that is not done: {\"filter_by\": {\"Status\":[\"To do\", \"In progress\"]}, \"limit\": 1}top 5 high priority tasks: {\"filter_by\": {\"Priority\":[\"High\"]}, \"limit\": 5}\n\nResponse includes for each row: rowId (stable row identifier), cells (array of columnTitle, valueType, content, options, latest_update_text, latest_update_author_id).\n\nPagination: Use 'limit' to control page size (default 10) and 'next_cursor' to fetch subsequent pages. The cursor is opaque and encodes pagination state.\n\nIMPORTANT: Do not change 'filter_by' when using a cursor from a previous response, as this will result in an error. To apply a different filter, start a new pagination sequence (no cursor).",
"inputSchema": {
"type": "object",
"required": [
"miro_url"
],
"properties": {
"limit": {
"type": "integer",
"default": null,
"minimum": 1,
"nullable": true,
"description": "Maximum rows to return (minimum 1)"
},
"miro_url": {
"type": "string",
"minLength": 1,
"description": "Full Miro URL to a specific item (e.g., 'https://miro.com/app/board/uXjVOakxTk0=/?moveToWidget=3458764516062720430'). Must include moveToWidget or focusWidget query parameter."
},
"filter_by": {
"type": "string",
"default": null,
"nullable": true,
"description": "Filter rows by column value(s) in JSON format (case-insensitive). Only select and multiselect columns are supported. Format: JSON object mapping column names to arrays of display values. Example: {\"Status\": [\"In Progress\", \"Done\"]} matches rows where Status is either 'In Progress' OR 'Done'"
},
"next_cursor": {
"type": "string",
"default": null,
"nullable": true,
"description": "Pagination cursor for the next set of results"
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"required": [
"miro_url",
"rows",
"total"
],
"properties": {
"rows": {
"type": "array",
"items": {
"type": "object",
"required": [
"rowId",
"cells"
],
"properties": {
"cells": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
},
"description": "Array of cells in this row"
},
"rowId": {
"type": "string",
"description": "Unique identifier of the row"
}
},
"description": "Single table row."
},
"description": "Array of table rows"
},
"total": {
"type": "integer",
"description": "Total number of rows matching the filter (before pagination)"
},
"cursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Pagination cursor for the next page of results"
},
"columns": {
"anyOf": [
{
"type": "array",
"items": {
"type": "object",
"required": [
"id",
"column_title",
"column_type"
],
"properties": {
"id": {
"type": "string",
"description": "Unique identifier of the column"
},
"column_type": {
"type": "string",
"description": "Column type: 'text', 'select', 'multiselect', 'date', 'link', 'person', or 'number'"
},
"column_title": {
"type": "string",
"description": "Display title of the column"
},
"selectOptions": {
"anyOf": [
{
"type": "array",
"items": {
"type": "object",
"required": [
"id",
"displayValue",
"color"
],
"properties": {
"id": {
"type": "string",
"description": "Unique identifier of the select option"
},
"color": {
"type": "string",
"description": "Color code for this option"
},
"displayValue": {
"type": "string",
"description": "Display text for this option"
}
},
"description": "Option for select-type columns (response)."
}
},
{
"type": "null"
}
],
"default": null,
"description": "Available options (only for select/multiselect columns)"
}
},
"description": "Information about a created table column."
}
},
{
"type": "null"
}
],
"default": null,
"description": "Column metadata including titles, types, and select options"
},
"miro_url": {
"type": "string",
"description": "Full Miro URL to the table"
}
},
"description": "Response from list_rows tool."
},
"annotations": {
"title": "Read Table",
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description95/100
Get the history of a row's Latest Update field. The Latest Update field accumulates the text updates submitted for that row over time; this returns those entries ordered chronologically. Provide the table via its Miro URL and the target row via rowId (get rowIds from table_list_rows).
Response includes for each entry: text, author_id (Miro user ID of the author), created_at and modified_at (ISO 8601 timestamps), plus the total number of entries.
The description explains the capability, when to use it, and what to expect.
Inputs56/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
miro_url
Full Miro URL to a specific item (e.g., 'https://miro.com/app/board/uXjVOakxTk0=/?moveToWidget=3458764516062720430'). Must include moveToWidget or focusWidget query parameter.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
row_id
Stable identifier of the row whose Latest Update field history to fetch. Get rowIds from table_list_rows.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Resolve the mismatch between this description and its schema constraints.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
{
"type": "object",
"required": [
"miro_url",
"entries",
"total"
],
"properties": {
"total": {
"type": "integer",
"description": "Total number of entries in the Latest Update field history"
},
"entries": {
"type": "array",
"items": {
"type": "object",
"properties": {
"text": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Text content of this update"
},
"author_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Miro user ID of the author of this update. May be null when the author is unknown (e.g. system-generated or anonymous updates)."
},
"created_at": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "ISO 8601 timestamp when this update was first created"
},
"modified_at": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "ISO 8601 timestamp when this update was last modified"
}
},
"description": "A single entry in a Latest Update field's history."
},
"description": "Entries from the row's Latest Update field history, ordered chronologically"
},
"miro_url": {
"type": "string",
"description": "Full Miro URL to the table"
}
},
"description": "Response from get_latest_update_history tool."
}
Original tool metadata
{
"name": "table_get_latest_update_history",
"title": "Read Latest Update History",
"description": "Get the history of a row's Latest Update field. The Latest Update field accumulates the text updates submitted for that row over time; this returns those entries ordered chronologically. Provide the table via its Miro URL and the target row via rowId (get rowIds from table_list_rows). \n\nResponse includes for each entry: text, author_id (Miro user ID of the author), created_at and modified_at (ISO 8601 timestamps), plus the total number of entries.",
"inputSchema": {
"type": "object",
"required": [
"miro_url",
"row_id"
],
"properties": {
"row_id": {
"type": "string",
"pattern": "^[0-9a-zA-Z_-]{1,64}$",
"description": "Stable identifier of the row whose Latest Update field history to fetch. Get rowIds from table_list_rows."
},
"miro_url": {
"type": "string",
"minLength": 1,
"description": "Full Miro URL to a specific item (e.g., 'https://miro.com/app/board/uXjVOakxTk0=/?moveToWidget=3458764516062720430'). Must include moveToWidget or focusWidget query parameter."
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"required": [
"miro_url",
"entries",
"total"
],
"properties": {
"total": {
"type": "integer",
"description": "Total number of entries in the Latest Update field history"
},
"entries": {
"type": "array",
"items": {
"type": "object",
"properties": {
"text": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Text content of this update"
},
"author_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Miro user ID of the author of this update. May be null when the author is unknown (e.g. system-generated or anonymous updates)."
},
"created_at": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "ISO 8601 timestamp when this update was first created"
},
"modified_at": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "ISO 8601 timestamp when this update was last modified"
}
},
"description": "A single entry in a Latest Update field's history."
},
"description": "Entries from the row's Latest Update field history, ordered chronologically"
},
"miro_url": {
"type": "string",
"description": "Full Miro URL to the table"
}
},
"description": "Response from get_latest_update_history tool."
},
"annotations": {
"title": "Read Latest Update History",
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description76/100
Add or update rows in a Miro table.
To update existing rows, include rowId in the row object. rowId precisely targets a single row. Get rowIds from table_list_rows. Rows without rowId are inserted as new.
Examples:
Update a specific row by rowId: {"rows": [{"rowId": "3", "cells": [{"columnTitle": "Status", "value": "Complete"}]}]}
Insert new rows: {"rows": [{"cells": [{"columnTitle": "Task", "value": "New task"}, {"columnTitle": "Status", "value": "Not Started"}]}]}
Explain mutations, irreversible effects, or prerequisites that matter before calling this tool.
Inputs79/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
miro_url
Full Miro URL to a specific item (e.g., 'https://miro.com/app/board/uXjVOakxTk0=/?moveToWidget=3458764516062720430'). Must include moveToWidget or focusWidget query parameter.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
rows › items › rowId
Stable row identifier for targeting a specific row to update. Get rowIds from table_list_rows. Rows without rowId are inserted as new.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
rows › items › cells › items › columnTitle
Title of the column this cell belongs to
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
rows › items › cells › items › value
Cell value. For text columns: string. For select columns: displayValue string. For multiselect columns: displayValue string or list of displayValue strings. For date columns: ISO 8601 date string (e.g., '2025-07-30T22:00:00Z'). For link columns: URL string or list of link objects [{"url": "...", "text": "..."}]For person columns: Miro user ID string or list of Miro user ID strings. For number columns: number or numeric string (e.g., 42 or '3.14').
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Clear enough to supply this argument.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
{
"name": "table_sync_rows",
"title": "Update Table",
"description": "Add or update rows in a Miro table.\n\nTo update existing rows, include rowId in the row object. rowId precisely targets a single row. Get rowIds from table_list_rows. Rows without rowId are inserted as new.\n\nExamples:\nUpdate a specific row by rowId: {\"rows\": [{\"rowId\": \"3\", \"cells\": [{\"columnTitle\": \"Status\", \"value\": \"Complete\"}]}]}\nInsert new rows: {\"rows\": [{\"cells\": [{\"columnTitle\": \"Task\", \"value\": \"New task\"}, {\"columnTitle\": \"Status\", \"value\": \"Not Started\"}]}]}",
"inputSchema": {
"type": "object",
"required": [
"miro_url",
"rows"
],
"properties": {
"rows": {
"type": "array",
"items": {
"type": "object",
"required": [
"cells"
],
"properties": {
"cells": {
"type": "array",
"items": {
"type": "object",
"required": [
"columnTitle",
"value"
],
"properties": {
"value": {
"anyOf": [
{
"type": "string",
"maxLength": 5000
},
{
"type": "number"
},
{
"type": "integer"
},
{
"type": "array",
"items": {
"type": "string"
},
"maxItems": 5000
},
{
"type": "array",
"items": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"maxItems": 5000
}
],
"description": "Cell value. For text columns: string. For select columns: displayValue string. For multiselect columns: displayValue string or list of displayValue strings. For date columns: ISO 8601 date string (e.g., '2025-07-30T22:00:00Z'). For link columns: URL string or list of link objects [{\"url\": \"...\", \"text\": \"...\"}]For person columns: Miro user ID string or list of Miro user ID strings. For number columns: number or numeric string (e.g., 42 or '3.14')."
},
"columnTitle": {
"type": "string",
"maxLength": 255,
"minLength": 1,
"description": "Title of the column this cell belongs to"
}
},
"description": "Input for a single cell value.\n\nThe type is inferred from the column schema during processing."
},
"description": "Array of cells in this row"
},
"rowId": {
"type": "string",
"default": null,
"pattern": "^[0-9a-zA-Z_-]{1,64}$",
"nullable": true,
"description": "Stable row identifier for targeting a specific row to update. Get rowIds from table_list_rows. Rows without rowId are inserted as new."
}
},
"description": "Input for a single table row."
},
"minItems": 1,
"description": "Array of rows to add or update. Include rowId to update an existing row.\n Rows without rowId are inserted as new.\n\n [{\"rowId\": \"3\", \"cells\": [{\"columnTitle\": \"Status\", \"value\": \"Complete\"}]}]\n [{\"cells\": [{\"columnTitle\": \"Task\", \"value\": \"Write tests\"}, {\"columnTitle\": \"Status\", \"value\": \"To Do\"}]}]"
},
"miro_url": {
"type": "string",
"minLength": 1,
"description": "Full Miro URL to a specific item (e.g., 'https://miro.com/app/board/uXjVOakxTk0=/?moveToWidget=3458764516062720430'). Must include moveToWidget or focusWidget query parameter."
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"additionalProperties": true
},
"annotations": {
"title": "Update Table",
"readOnlyHint": false,
"openWorldHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description86/100
Update a Miro table widget's view: switch it to a grid table, timeline, or kanban board. The table keeps its data; only how it is displayed changes.
Choose layout:
- table: plain grid (use to revert from another layout)
- timeline: lays records out on a time axis; optionally set the visible window with timeline_start_date and timeline_end_date
- kanban: groups records into columns; set group_by_column to the name of a select column to group by (omit for an ungrouped board)
Only provide config that matches the chosen layout. Examples: switch to kanban grouped by Status: {"layout": "kanban", "group_by_column": "Status"}. Switch to a timeline for 2026: {"layout": "timeline", "timeline_start_date": "2026-01-01T00:00:00Z", "timeline_end_date": "2026-12-31T00:00:00Z"}.
Resolve contradictions between the description, input schema, and annotations.
Inputs71/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
miro_url
Full Miro URL to a specific item (e.g., 'https://miro.com/app/board/uXjVOakxTk0=/?moveToWidget=3458764516062720430'). Must include moveToWidget or focusWidget query parameter.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
layout
The layout to apply: 'table', 'timeline', 'kanban', or 'tree'.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
group_by_column
KANBAN only: name of the select column to group cards into columns. Omit for an ungrouped board.
Clear enough to supply this argument.
timeline_start_date
TIMELINE only: visible start of the timeline window in UTC format YYYY-MM-DDThh:mm:ssZ. This is the viewport, not a per-record date.
Clear enough to supply this argument.
timeline_end_date
TIMELINE only: visible end of the timeline window in UTC format YYYY-MM-DDThh:mm:ssZ. This is the viewport, not a per-record date.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
tree_direction
TREE only: direction the tree grows.
Explain the meaning of this value, not just its name.
view_name
Optional new display name for the view. Applies to any layout.
Clear enough to supply this argument.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Resolve the mismatch between this description and its schema constraints.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
Resolve the mismatch between this description and its schema constraints.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
{
"type": "object",
"required": [
"miro_url",
"layout"
],
"properties": {
"layout": {
"enum": [
"table",
"timeline",
"kanban",
"tree"
],
"type": "string",
"description": "The layout now applied to the table"
},
"miro_url": {
"type": "string",
"description": "Board item URL of the table whose layout changed"
}
},
"description": "Response from update_view tool."
}
Original tool metadata
{
"name": "table_update_view",
"title": "Update Table View",
"description": "Update a Miro table widget's view: switch it to a grid table, timeline, or kanban board. The table keeps its data; only how it is displayed changes.\n\nChoose layout:\n- table: plain grid (use to revert from another layout)\n- timeline: lays records out on a time axis; optionally set the visible window with timeline_start_date and timeline_end_date\n- kanban: groups records into columns; set group_by_column to the name of a select column to group by (omit for an ungrouped board)\n\nOnly provide config that matches the chosen layout. Examples: switch to kanban grouped by Status: {\"layout\": \"kanban\", \"group_by_column\": \"Status\"}. Switch to a timeline for 2026: {\"layout\": \"timeline\", \"timeline_start_date\": \"2026-01-01T00:00:00Z\", \"timeline_end_date\": \"2026-12-31T00:00:00Z\"}.",
"inputSchema": {
"type": "object",
"required": [
"miro_url",
"layout"
],
"properties": {
"layout": {
"enum": [
"table",
"timeline",
"kanban",
"tree"
],
"type": "string",
"description": "The layout to apply: 'table', 'timeline', 'kanban', or 'tree'."
},
"miro_url": {
"type": "string",
"minLength": 1,
"description": "Full Miro URL to a specific item (e.g., 'https://miro.com/app/board/uXjVOakxTk0=/?moveToWidget=3458764516062720430'). Must include moveToWidget or focusWidget query parameter."
},
"view_name": {
"type": "string",
"default": null,
"nullable": true,
"description": "Optional new display name for the view. Applies to any layout."
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"tree_direction": {
"enum": [
"top_to_bottom",
"left_to_right"
],
"type": "string",
"default": null,
"nullable": true,
"description": "TREE only: direction the tree grows."
},
"group_by_column": {
"type": "string",
"default": null,
"nullable": true,
"description": "KANBAN only: name of the select column to group cards into columns. Omit for an ungrouped board."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
},
"timeline_end_date": {
"type": "string",
"default": null,
"nullable": true,
"description": "TIMELINE only: visible end of the timeline window in UTC format YYYY-MM-DDThh:mm:ssZ. This is the viewport, not a per-record date."
},
"timeline_date_unit": {
"enum": [
"day",
"week",
"month",
"quarter",
"year"
],
"type": "string",
"default": null,
"nullable": true,
"description": "TIMELINE only: time-axis granularity."
},
"timeline_start_date": {
"type": "string",
"default": null,
"nullable": true,
"description": "TIMELINE only: visible start of the timeline window in UTC format YYYY-MM-DDThh:mm:ssZ. This is the viewport, not a per-record date."
},
"table_nesting_enabled": {
"type": "boolean",
"default": null,
"nullable": true,
"description": "TABLE only: enable nested (hierarchical parent/child) rows."
},
"timeline_nesting_enabled": {
"type": "boolean",
"default": null,
"nullable": true,
"description": "TIMELINE only: enable nested (hierarchical parent/child) rows."
},
"timeline_dependencies_enabled": {
"type": "boolean",
"default": null,
"nullable": true,
"description": "TIMELINE only: show dependency links between records."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"required": [
"miro_url",
"layout"
],
"properties": {
"layout": {
"enum": [
"table",
"timeline",
"kanban",
"tree"
],
"type": "string",
"description": "The layout now applied to the table"
},
"miro_url": {
"type": "string",
"description": "Board item URL of the table whose layout changed"
}
},
"description": "Response from update_view tool."
},
"annotations": {
"title": "Update Table View",
"readOnlyHint": false,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description63/100
Get image download URL for an image item from a Miro board.
Resolve contradictions between the description, input schema, and annotations.
Inputs92/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
miro_url
Full Miro URL to a specific item (e.g., 'https://miro.com/app/board/uXjVOakxTk0=/?moveToWidget=3458764516062720430'). Must include moveToWidget or focusWidget query parameter.
Clear enough to supply this argument.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Clear enough to supply this argument.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"required": [
"miro_url",
"download_url"
],
"properties": {
"x": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"default": null,
"description": "X-axis coordinate of the image on the board"
},
"y": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"default": null,
"description": "Y-axis coordinate of the image on the board"
},
"miro_url": {
"type": "string",
"description": "Full Miro URL to the image item on the board"
},
"download_url": {
"type": "string",
"description": "Direct download URL for the image file"
},
"parent_miro_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Full Miro URL of parent frame, if placed inside a frame"
}
},
"description": "Get image download URL for an image item from a Miro board by boardID and item ID."
}
Original tool metadata
{
"name": "image_get_url",
"title": "Download Image",
"description": "Get image download URL for an image item from a Miro board.",
"inputSchema": {
"type": "object",
"required": [
"miro_url"
],
"properties": {
"miro_url": {
"type": "string",
"minLength": 1,
"description": "Full Miro URL to a specific item (e.g., 'https://miro.com/app/board/uXjVOakxTk0=/?moveToWidget=3458764516062720430'). Must include moveToWidget or focusWidget query parameter."
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"required": [
"miro_url",
"download_url"
],
"properties": {
"x": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"default": null,
"description": "X-axis coordinate of the image on the board"
},
"y": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"default": null,
"description": "Y-axis coordinate of the image on the board"
},
"miro_url": {
"type": "string",
"description": "Full Miro URL to the image item on the board"
},
"download_url": {
"type": "string",
"description": "Direct download URL for the image file"
},
"parent_miro_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Full Miro URL of parent frame, if placed inside a frame"
}
},
"description": "Get image download URL for an image item from a Miro board by boardID and item ID."
},
"annotations": {
"title": "Download Image",
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description92/100
Get the pixels of an image item on a Miro board. Use this when a layout shows an image (by its properties and source URL) and you need to see what the image actually depicts. Returns the image content directly.
Describe the returned information so the agent knows whether it will answer the request.
Inputs83/100
Explain what happens when this optional value is omitted.
miro_url
Full Miro URL to a specific item (e.g., 'https://miro.com/app/board/uXjVOakxTk0=/?moveToWidget=3458764516062720430'). Must include moveToWidget or focusWidget query parameter.
Clear enough to supply this argument.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Explain what happens when this optional value is omitted.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "image_get_data",
"title": "Image Data",
"description": "Get the pixels of an image item on a Miro board. Use this when a layout shows an image (by its properties and source URL) and you need to see what the image actually depicts. Returns the image content directly.",
"inputSchema": {
"type": "object",
"required": [
"miro_url"
],
"properties": {
"miro_url": {
"type": "string",
"minLength": 1,
"description": "Full Miro URL to a specific item (e.g., 'https://miro.com/app/board/uXjVOakxTk0=/?moveToWidget=3458764516062720430'). Must include moveToWidget or focusWidget query parameter."
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
}
},
"additionalProperties": false
},
"annotations": {
"title": "Image Data",
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Get a single-use upload URL for a local image. Returns upload_url and a token. PUT the raw image bytes as the request body; set Content-Type to the image MIME type; no auth header. curl: curl -X PUT -H 'Content-Type: image/png' --data-binary @image.png '<upload_url>'. If the image only exists as in-memory bytes, write it to a local file first, then PUT that file. After upload, pass the returned token to any tool that accepts an image_token / image_tokens parameter — see each consumer tool's description for what it does with the upload. Max size: 6,000,000 bytes. Accepted types: image/bmp, image/gif, image/jpeg, image/png, image/svg+xml, image/vnd.adobe.photoshop.
The description explains the capability, when to use it, and what to expect.
Inputs97/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
miro_url
Full Miro board URL (e.g., 'https://miro.com/app/board/uXjVOakxTk0='). To target a specific parent frame, include ?moveToWidget=<frame_id>.
Clear enough to supply this argument.
content_type
MIME type of the image to upload. Accepted: image/bmp, image/gif, image/jpeg, image/png, image/svg+xml, image/vnd.adobe.photoshop. When provided, the upload request Content-Type must match this value exactly. If omitted, content type is verified at image_create time.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
title
Optional title label for the image widget.
Clear enough to supply this argument.
x
X-axis coordinate. Without a frame target: board-absolute, board center is x=0. With a frame target via moveToWidget: relative to the frame's top-left corner (frame top-left is x=0).
Clear enough to supply this argument.
y
Y-axis coordinate. Without a frame target: board-absolute, board center is y=0. With a frame target via moveToWidget: relative to the frame's top-left corner (frame top-left is y=0).
Clear enough to supply this argument.
width
Image width in pixels. Height scales proportionally.
Clear enough to supply this argument.
src
Only consumed by tools that rewrite HTML by src — currently prototype_create's and slides_create_html's image_tokens (i.e. a local file referenced from HTML). Set this to the EXACT string that appears as the src attribute in the HTML (e.g. './logo.png', 'assets/icon.svg') — matching is literal. The server rewrites every <img src=...> equal to this value with the uploaded board resource. Other consumers (image_create) ignore this field.
Clear enough to supply this argument.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Clear enough to supply this argument.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
{
"type": "object",
"required": [
"upload_url",
"token",
"expires_in"
],
"properties": {
"token": {
"type": "string",
"description": "Single-use token to pass to image_create after the upload completes."
},
"expires_in": {
"type": "integer",
"description": "Seconds until this URL expires"
},
"upload_url": {
"type": "string",
"description": "Upload endpoint URL. PUT the image file as the raw request body; set Content-Type to the image MIME type; no auth header. curl: curl -X PUT -H 'Content-Type: image/png' --data-binary @image.png '<url>'."
}
},
"description": "Response from get_upload_url — single-use upload URL and creation token."
}
Original tool metadata
{
"name": "image_get_upload_url",
"title": "Get Upload URL",
"description": "Get a single-use upload URL for a local image. Returns upload_url and a token. PUT the raw image bytes as the request body; set Content-Type to the image MIME type; no auth header. curl: curl -X PUT -H 'Content-Type: image/png' --data-binary @image.png '<upload_url>'. If the image only exists as in-memory bytes, write it to a local file first, then PUT that file. After upload, pass the returned token to any tool that accepts an image_token / image_tokens parameter — see each consumer tool's description for what it does with the upload. Max size: 6,000,000 bytes. Accepted types: image/bmp, image/gif, image/jpeg, image/png, image/svg+xml, image/vnd.adobe.photoshop.",
"inputSchema": {
"type": "object",
"required": [
"miro_url"
],
"properties": {
"x": {
"type": "number",
"default": null,
"nullable": true,
"description": "X-axis coordinate. Without a frame target: board-absolute, board center is x=0. With a frame target via moveToWidget: relative to the frame's top-left corner (frame top-left is x=0)."
},
"y": {
"type": "number",
"default": null,
"nullable": true,
"description": "Y-axis coordinate. Without a frame target: board-absolute, board center is y=0. With a frame target via moveToWidget: relative to the frame's top-left corner (frame top-left is y=0)."
},
"src": {
"type": "string",
"default": null,
"nullable": true,
"description": "Only consumed by tools that rewrite HTML by src — currently prototype_create's and slides_create_html's image_tokens (i.e. a local file referenced from HTML). Set this to the EXACT string that appears as the src attribute in the HTML (e.g. './logo.png', 'assets/icon.svg') — matching is literal. The server rewrites every <img src=...> equal to this value with the uploaded board resource. Other consumers (image_create) ignore this field."
},
"title": {
"type": "string",
"default": null,
"nullable": true,
"description": "Optional title label for the image widget."
},
"width": {
"type": "number",
"default": null,
"nullable": true,
"description": "Image width in pixels. Height scales proportionally."
},
"miro_url": {
"type": "string",
"description": "Full Miro board URL (e.g., 'https://miro.com/app/board/uXjVOakxTk0='). To target a specific parent frame, include ?moveToWidget=<frame_id>."
},
"content_type": {
"type": "string",
"default": null,
"nullable": true,
"description": "MIME type of the image to upload. Accepted: image/bmp, image/gif, image/jpeg, image/png, image/svg+xml, image/vnd.adobe.photoshop. When provided, the upload request Content-Type must match this value exactly. If omitted, content type is verified at image_create time."
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"required": [
"upload_url",
"token",
"expires_in"
],
"properties": {
"token": {
"type": "string",
"description": "Single-use token to pass to image_create after the upload completes."
},
"expires_in": {
"type": "integer",
"description": "Seconds until this URL expires"
},
"upload_url": {
"type": "string",
"description": "Upload endpoint URL. PUT the image file as the raw request body; set Content-Type to the image MIME type; no auth header. curl: curl -X PUT -H 'Content-Type: image/png' --data-binary @image.png '<url>'."
}
},
"description": "Response from get_upload_url — single-use upload URL and creation token."
},
"annotations": {
"title": "Get Upload URL",
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description83/100
Create an image item on a Miro board. Accepts either an upload token (from image_get_upload_url after the upload completes) or a publicly accessible image URL. Exactly one of image_token or image_url must be provided. When image_token is provided, title/x/y/width from the token (set at upload time) are used; any values supplied here for those fields are ignored. Coordinates: when the URL has no item target, x/y are board-absolute (board center is (0, 0)). When the URL targets a frame via moveToWidget, the image is created INSIDE that frame and x/y are relative to the frame's top-left corner; (0, 0) is the frame's top-left and the image must fit within the frame's width and height.
The description explains the capability, when to use it, and what to expect.
Inputs91/100
Input documentation gives an agent enough context to populate the arguments.
miro_url
Full Miro board URL (e.g., 'https://miro.com/app/board/uXjVOakxTk0='). To target a specific parent frame, include ?moveToWidget=<frame_id>.
Clear enough to supply this argument.
image_token
Token returned by image_get_upload_url after the upload completes. Mutually exclusive with image_url.
Clear enough to supply this argument.
image_url
Publicly accessible URL of the image to add to the board. Mutually exclusive with image_token.
Clear enough to supply this argument.
title
Optional title label for the image widget.
Clear enough to supply this argument.
x
X-axis coordinate. Without a frame target: board-absolute, board center is x=0. With a frame target via moveToWidget: relative to the frame's top-left corner (frame top-left is x=0).
Clear enough to supply this argument.
y
Y-axis coordinate. Without a frame target: board-absolute, board center is y=0. With a frame target via moveToWidget: relative to the frame's top-left corner (frame top-left is y=0).
Clear enough to supply this argument.
width
Image width in pixels. Height scales proportionally.
Clear enough to supply this argument.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Clear enough to supply this argument.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
{
"type": "object",
"required": [
"miro_url",
"success",
"message"
],
"properties": {
"x": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"default": null,
"description": "X-axis coordinate of the image on the board"
},
"y": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"default": null,
"description": "Y-axis coordinate of the image on the board"
},
"item_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The data-miro-id of the newly created image item"
},
"message": {
"type": "string",
"description": "Human-readable status message"
},
"success": {
"type": "boolean",
"description": "Whether the image was created successfully"
},
"miro_url": {
"type": "string",
"description": "Full Miro URL to the newly created image item on the board"
},
"parent_miro_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Full Miro URL of parent frame, if placed inside a frame"
}
},
"description": "Response returned after creating an image item on a Miro board."
}
Original tool metadata
{
"name": "image_create",
"title": "Create Image",
"description": "Create an image item on a Miro board. Accepts either an upload token (from image_get_upload_url after the upload completes) or a publicly accessible image URL. Exactly one of image_token or image_url must be provided. When image_token is provided, title/x/y/width from the token (set at upload time) are used; any values supplied here for those fields are ignored. Coordinates: when the URL has no item target, x/y are board-absolute (board center is (0, 0)). When the URL targets a frame via moveToWidget, the image is created INSIDE that frame and x/y are relative to the frame's top-left corner; (0, 0) is the frame's top-left and the image must fit within the frame's width and height.",
"inputSchema": {
"type": "object",
"required": [
"miro_url"
],
"properties": {
"x": {
"type": "number",
"default": null,
"nullable": true,
"description": "X-axis coordinate. Without a frame target: board-absolute, board center is x=0. With a frame target via moveToWidget: relative to the frame's top-left corner (frame top-left is x=0)."
},
"y": {
"type": "number",
"default": null,
"nullable": true,
"description": "Y-axis coordinate. Without a frame target: board-absolute, board center is y=0. With a frame target via moveToWidget: relative to the frame's top-left corner (frame top-left is y=0)."
},
"title": {
"type": "string",
"default": null,
"nullable": true,
"description": "Optional title label for the image widget."
},
"width": {
"type": "number",
"default": null,
"nullable": true,
"description": "Image width in pixels. Height scales proportionally."
},
"miro_url": {
"type": "string",
"description": "Full Miro board URL (e.g., 'https://miro.com/app/board/uXjVOakxTk0='). To target a specific parent frame, include ?moveToWidget=<frame_id>."
},
"image_url": {
"type": "string",
"default": null,
"nullable": true,
"description": "Publicly accessible URL of the image to add to the board. Mutually exclusive with image_token."
},
"image_token": {
"type": "string",
"default": null,
"nullable": true,
"description": "Token returned by image_get_upload_url after the upload completes. Mutually exclusive with image_url."
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"required": [
"miro_url",
"success",
"message"
],
"properties": {
"x": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"default": null,
"description": "X-axis coordinate of the image on the board"
},
"y": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"default": null,
"description": "Y-axis coordinate of the image on the board"
},
"item_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The data-miro-id of the newly created image item"
},
"message": {
"type": "string",
"description": "Human-readable status message"
},
"success": {
"type": "boolean",
"description": "Whether the image was created successfully"
},
"miro_url": {
"type": "string",
"description": "Full Miro URL to the newly created image item on the board"
},
"parent_miro_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Full Miro URL of parent frame, if placed inside a frame"
}
},
"description": "Response returned after creating an image item on a Miro board."
},
"annotations": {
"title": "Create Image",
"readOnlyHint": false,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description77/100
List comments from a Miro board or a specific item on the board. Comments include author information, messages (original comment and replies), reactions, resolved status, and position. Use limit and offset for pagination. Use from_date and to_date to filter by creation time. Use resolved to filter by resolved status.
The description explains the capability, when to use it, and what to expect.
Inputs78/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
miro_url
Miro board URL. Can be a plain board URL (e.g., 'https://miro.com/app/board/uXjVGeTCXKY=/') to get a board overview, or include moveToWidget/focusWidget parameter (e.g., 'https://miro.com/app/board/uXjVGeTCXKY=/?moveToWidget=3458764654510025479') to get detailed content for a specific item.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
limit
Maximum number of comments to return per page. Range: 1-50. Default: 20.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
offset
Zero-based offset for pagination. Default: 0.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
from_date
Return only comments created at or after this date. Format: ISO 8601 with optional time component, e.g. 2024-01-01T00:00:00Z or 2024-01-01.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
to_date
Return only comments created at or before this date. Format: ISO 8601 with optional time component, e.g. 2024-12-31T23:59:59Z or 2024-12-31.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
resolved
Filter by resolved status. true returns only resolved comments, false returns only unresolved. Omit to return all comments.
Clear enough to supply this argument.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
{
"type": "object",
"title": "ListCommentsResponse",
"required": [
"data",
"total",
"offset",
"limit",
"board_id",
"board_url"
],
"properties": {
"data": {
"type": "array",
"items": {
"type": "object",
"title": "CommentItem",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"title": "Id",
"description": "Unique identifier of the comment."
},
"messages": {
"type": "array",
"items": {
"type": "object",
"title": "MessageItem",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"title": "Id",
"description": "Unique identifier of the message."
},
"content": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Content",
"default": null,
"description": "Text content of the message."
},
"createdAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Createdat",
"default": null,
"description": "When the message was created."
},
"createdBy": {
"anyOf": [
{
"type": "object",
"additionalProperties": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "Createdby",
"default": null,
"description": "User who created the message."
},
"reactions": {
"type": "array",
"items": {
"type": "object",
"title": "Reaction",
"required": [
"emoji",
"userIds"
],
"properties": {
"emoji": {
"type": "string",
"title": "Emoji",
"description": "Emoji used as the reaction."
},
"userIds": {
"type": "array",
"items": {
"type": "string"
},
"title": "Userids",
"description": "IDs of users who reacted with this emoji."
},
"createdAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Createdat",
"default": null,
"description": "When the reaction was first added."
}
},
"description": "An emoji reaction on a comment or message."
},
"title": "Reactions",
"description": "Reactions on the message."
},
"modifiedAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Modifiedat",
"default": null,
"description": "When the message was last modified."
}
},
"description": "A message in a comment thread (original comment or reply)."
},
"title": "Messages",
"description": "Messages in the comment thread. The first message is the original comment; subsequent messages are replies."
},
"position": {
"anyOf": [
{
"type": "object",
"title": "CommentPosition",
"required": [
"type"
],
"properties": {
"x": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"title": "X",
"default": null,
"description": "X-axis coordinate (canvas and attached types)."
},
"y": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"title": "Y",
"default": null,
"description": "Y-axis coordinate (canvas and attached types)."
},
"type": {
"type": "string",
"title": "Type",
"description": "Position type: canvas, attached, table, or doc."
},
"rowId": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Rowid",
"default": null,
"description": "ID of the data table row the comment is attached to (table type)."
},
"itemId": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Itemid",
"default": null,
"description": "ID of the item the comment is attached to (attached, table, and doc types)."
}
},
"description": "Position of a comment on the board."
},
{
"type": "null"
}
],
"default": null,
"description": "Position of the comment on the board."
},
"resolved": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "Resolved",
"default": null,
"description": "Whether the comment thread has been resolved."
},
"createdAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Createdat",
"default": null,
"description": "When the comment was created."
},
"createdBy": {
"anyOf": [
{
"type": "object",
"additionalProperties": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "Createdby",
"default": null,
"description": "User who created the comment."
},
"reactions": {
"type": "array",
"items": {
"type": "object",
"title": "Reaction",
"required": [
"emoji",
"userIds"
],
"properties": {
"emoji": {
"type": "string",
"title": "Emoji",
"description": "Emoji used as the reaction."
},
"userIds": {
"type": "array",
"items": {
"type": "string"
},
"title": "Userids",
"description": "IDs of users who reacted with this emoji."
},
"createdAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Createdat",
"default": null,
"description": "When the reaction was first added."
}
},
"description": "An emoji reaction on a comment or message."
},
"title": "Reactions",
"description": "Reactions on the comment."
},
"modifiedAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Modifiedat",
"default": null,
"description": "When the comment was last modified."
},
"mentionedUsers": {
"type": "array",
"items": {
"type": "object",
"title": "MentionedUser",
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "string",
"title": "Id",
"description": "Unique identifier of the user."
},
"name": {
"type": "string",
"title": "Name",
"description": "Display name of the user."
}
},
"description": "A user mentioned in a comment thread by an `@[<userId>]` token, with the\nuser's resolved name so the client can render `@<name>` without an extra\nlookup. The upstream `type` field is dropped - clients don't need to\ndistinguish user types here."
},
"title": "Mentionedusers",
"description": "Users mentioned by `@[<userId>]` tokens across all messages in the thread, with their resolved name. Aggregated and deduplicated. Users that cannot be resolved are omitted; clients fall back to showing the raw id."
}
},
"description": "A comment thread on a Miro board."
},
"title": "Data",
"description": "List of comments."
},
"limit": {
"type": "integer",
"title": "Limit",
"description": "Maximum number of items returned."
},
"total": {
"type": "integer",
"title": "Total",
"description": "Total number of comments available."
},
"offset": {
"type": "integer",
"title": "Offset",
"description": "Zero-based index of the first item returned."
},
"board_id": {
"type": "string",
"title": "Board Id",
"description": "ID of the Miro board the comments belong to."
},
"board_url": {
"type": "string",
"title": "Board Url",
"description": "Canonical Miro board URL; used to build per-comment deep-links."
}
},
"description": "Paginated response for listing comments."
}
Original tool metadata
{
"name": "comment_list_comments",
"title": "Read Comments",
"description": "List comments from a Miro board or a specific item on the board. Comments include author information, messages (original comment and replies), reactions, resolved status, and position. Use limit and offset for pagination. Use from_date and to_date to filter by creation time. Use resolved to filter by resolved status.",
"inputSchema": {
"type": "object",
"required": [
"miro_url"
],
"properties": {
"limit": {
"type": "integer",
"default": 20,
"maximum": 50,
"minimum": 1,
"description": "Maximum number of comments to return per page. Range: 1-50. Default: 20."
},
"offset": {
"type": "integer",
"default": 0,
"minimum": 0,
"description": "Zero-based offset for pagination. Default: 0."
},
"to_date": {
"type": "string",
"default": null,
"nullable": true,
"description": "Return only comments created at or before this date. Format: ISO 8601 with optional time component, e.g. 2024-12-31T23:59:59Z or 2024-12-31."
},
"miro_url": {
"type": "string",
"minLength": 1,
"description": "Miro board URL. Can be a plain board URL (e.g., 'https://miro.com/app/board/uXjVGeTCXKY=/') to get a board overview, or include moveToWidget/focusWidget parameter (e.g., 'https://miro.com/app/board/uXjVGeTCXKY=/?moveToWidget=3458764654510025479') to get detailed content for a specific item."
},
"resolved": {
"type": "boolean",
"default": null,
"nullable": true,
"description": "Filter by resolved status. true returns only resolved comments, false returns only unresolved. Omit to return all comments."
},
"from_date": {
"type": "string",
"default": null,
"nullable": true,
"description": "Return only comments created at or after this date. Format: ISO 8601 with optional time component, e.g. 2024-01-01T00:00:00Z or 2024-01-01."
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"title": "ListCommentsResponse",
"required": [
"data",
"total",
"offset",
"limit",
"board_id",
"board_url"
],
"properties": {
"data": {
"type": "array",
"items": {
"type": "object",
"title": "CommentItem",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"title": "Id",
"description": "Unique identifier of the comment."
},
"messages": {
"type": "array",
"items": {
"type": "object",
"title": "MessageItem",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"title": "Id",
"description": "Unique identifier of the message."
},
"content": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Content",
"default": null,
"description": "Text content of the message."
},
"createdAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Createdat",
"default": null,
"description": "When the message was created."
},
"createdBy": {
"anyOf": [
{
"type": "object",
"additionalProperties": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "Createdby",
"default": null,
"description": "User who created the message."
},
"reactions": {
"type": "array",
"items": {
"type": "object",
"title": "Reaction",
"required": [
"emoji",
"userIds"
],
"properties": {
"emoji": {
"type": "string",
"title": "Emoji",
"description": "Emoji used as the reaction."
},
"userIds": {
"type": "array",
"items": {
"type": "string"
},
"title": "Userids",
"description": "IDs of users who reacted with this emoji."
},
"createdAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Createdat",
"default": null,
"description": "When the reaction was first added."
}
},
"description": "An emoji reaction on a comment or message."
},
"title": "Reactions",
"description": "Reactions on the message."
},
"modifiedAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Modifiedat",
"default": null,
"description": "When the message was last modified."
}
},
"description": "A message in a comment thread (original comment or reply)."
},
"title": "Messages",
"description": "Messages in the comment thread. The first message is the original comment; subsequent messages are replies."
},
"position": {
"anyOf": [
{
"type": "object",
"title": "CommentPosition",
"required": [
"type"
],
"properties": {
"x": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"title": "X",
"default": null,
"description": "X-axis coordinate (canvas and attached types)."
},
"y": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"title": "Y",
"default": null,
"description": "Y-axis coordinate (canvas and attached types)."
},
"type": {
"type": "string",
"title": "Type",
"description": "Position type: canvas, attached, table, or doc."
},
"rowId": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Rowid",
"default": null,
"description": "ID of the data table row the comment is attached to (table type)."
},
"itemId": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Itemid",
"default": null,
"description": "ID of the item the comment is attached to (attached, table, and doc types)."
}
},
"description": "Position of a comment on the board."
},
{
"type": "null"
}
],
"default": null,
"description": "Position of the comment on the board."
},
"resolved": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "Resolved",
"default": null,
"description": "Whether the comment thread has been resolved."
},
"createdAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Createdat",
"default": null,
"description": "When the comment was created."
},
"createdBy": {
"anyOf": [
{
"type": "object",
"additionalProperties": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "Createdby",
"default": null,
"description": "User who created the comment."
},
"reactions": {
"type": "array",
"items": {
"type": "object",
"title": "Reaction",
"required": [
"emoji",
"userIds"
],
"properties": {
"emoji": {
"type": "string",
"title": "Emoji",
"description": "Emoji used as the reaction."
},
"userIds": {
"type": "array",
"items": {
"type": "string"
},
"title": "Userids",
"description": "IDs of users who reacted with this emoji."
},
"createdAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Createdat",
"default": null,
"description": "When the reaction was first added."
}
},
"description": "An emoji reaction on a comment or message."
},
"title": "Reactions",
"description": "Reactions on the comment."
},
"modifiedAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Modifiedat",
"default": null,
"description": "When the comment was last modified."
},
"mentionedUsers": {
"type": "array",
"items": {
"type": "object",
"title": "MentionedUser",
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "string",
"title": "Id",
"description": "Unique identifier of the user."
},
"name": {
"type": "string",
"title": "Name",
"description": "Display name of the user."
}
},
"description": "A user mentioned in a comment thread by an `@[<userId>]` token, with the\nuser's resolved name so the client can render `@<name>` without an extra\nlookup. The upstream `type` field is dropped - clients don't need to\ndistinguish user types here."
},
"title": "Mentionedusers",
"description": "Users mentioned by `@[<userId>]` tokens across all messages in the thread, with their resolved name. Aggregated and deduplicated. Users that cannot be resolved are omitted; clients fall back to showing the raw id."
}
},
"description": "A comment thread on a Miro board."
},
"title": "Data",
"description": "List of comments."
},
"limit": {
"type": "integer",
"title": "Limit",
"description": "Maximum number of items returned."
},
"total": {
"type": "integer",
"title": "Total",
"description": "Total number of comments available."
},
"offset": {
"type": "integer",
"title": "Offset",
"description": "Zero-based index of the first item returned."
},
"board_id": {
"type": "string",
"title": "Board Id",
"description": "ID of the Miro board the comments belong to."
},
"board_url": {
"type": "string",
"title": "Board Url",
"description": "Canonical Miro board URL; used to build per-comment deep-links."
}
},
"description": "Paginated response for listing comments."
},
"annotations": {
"title": "Read Comments",
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description78/100
Create a new comment on the Miro board canvas. The comment appears at the specified canvas coordinates and is attributed to the current user. To attach the comment to an existing board item, pass a URL that targets that item. Use list_comments to read existing comments and their positions.
Describe the returned information so the agent knows whether it will answer the request.
Inputs54/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
miro_url
Miro board URL. Can be a plain board URL (e.g., 'https://miro.com/app/board/uXjVGeTCXKY=/') to get a board overview, or include moveToWidget/focusWidget parameter (e.g., 'https://miro.com/app/board/uXjVGeTCXKY=/?moveToWidget=3458764654510025479') to get detailed content for a specific item.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
content
Text content of the comment.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
x
X-axis coordinate of the comment on the canvas.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
y
Y-axis coordinate of the comment on the canvas.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Resolve the mismatch between this description and its schema constraints.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"description": "Unique identifier of the comment."
},
"messages": {
"type": "array",
"items": {
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"description": "Unique identifier of the message."
},
"content": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Text content of the message."
},
"createdAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the message was created."
},
"createdBy": {
"anyOf": [
{
"type": "object",
"additionalProperties": {
"type": "string"
}
},
{
"type": "null"
}
],
"default": null,
"description": "User who created the message."
},
"reactions": {
"type": "array",
"items": {
"type": "object",
"required": [
"emoji",
"userIds"
],
"properties": {
"emoji": {
"type": "string",
"description": "Emoji used as the reaction."
},
"userIds": {
"type": "array",
"items": {
"type": "string"
},
"description": "IDs of users who reacted with this emoji."
},
"createdAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the reaction was first added."
}
},
"description": "An emoji reaction on a comment or message."
},
"description": "Reactions on the message."
},
"modifiedAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the message was last modified."
}
},
"description": "A message in a comment thread (original comment or reply)."
},
"description": "Messages in the comment thread. The first message is the original comment; subsequent messages are replies."
},
"position": {
"anyOf": [
{
"type": "object",
"required": [
"type"
],
"properties": {
"x": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"default": null,
"description": "X-axis coordinate (canvas and attached types)."
},
"y": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"default": null,
"description": "Y-axis coordinate (canvas and attached types)."
},
"type": {
"type": "string",
"description": "Position type: canvas, attached, table, or doc."
},
"rowId": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "ID of the data table row the comment is attached to (table type)."
},
"itemId": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "ID of the item the comment is attached to (attached, table, and doc types)."
}
},
"description": "Position of a comment on the board."
},
{
"type": "null"
}
],
"default": null,
"description": "Position of the comment on the board."
},
"resolved": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"default": null,
"description": "Whether the comment thread has been resolved."
},
"createdAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the comment was created."
},
"createdBy": {
"anyOf": [
{
"type": "object",
"additionalProperties": {
"type": "string"
}
},
{
"type": "null"
}
],
"default": null,
"description": "User who created the comment."
},
"reactions": {
"type": "array",
"items": {
"type": "object",
"required": [
"emoji",
"userIds"
],
"properties": {
"emoji": {
"type": "string",
"description": "Emoji used as the reaction."
},
"userIds": {
"type": "array",
"items": {
"type": "string"
},
"description": "IDs of users who reacted with this emoji."
},
"createdAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the reaction was first added."
}
},
"description": "An emoji reaction on a comment or message."
},
"description": "Reactions on the comment."
},
"modifiedAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the comment was last modified."
},
"mentionedUsers": {
"type": "array",
"items": {
"type": "object",
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "string",
"description": "Unique identifier of the user."
},
"name": {
"type": "string",
"description": "Display name of the user."
}
},
"description": "A user mentioned in a comment thread by an `@[<userId>]` token, with the\nuser's resolved name so the client can render `@<name>` without an extra\nlookup. The upstream `type` field is dropped - clients don't need to\ndistinguish user types here."
},
"description": "Users mentioned by `@[<userId>]` tokens across all messages in the thread, with their resolved name. Aggregated and deduplicated. Users that cannot be resolved are omitted; clients fall back to showing the raw id."
}
},
"description": "A comment thread on a Miro board."
}
Original tool metadata
{
"name": "comment_create",
"title": "Create Canvas Comment",
"description": "Create a new comment on the Miro board canvas. The comment appears at the specified canvas coordinates and is attributed to the current user. To attach the comment to an existing board item, pass a URL that targets that item. Use list_comments to read existing comments and their positions.",
"inputSchema": {
"type": "object",
"required": [
"miro_url",
"content",
"x",
"y"
],
"properties": {
"x": {
"type": "number",
"description": "X-axis coordinate of the comment on the canvas."
},
"y": {
"type": "number",
"description": "Y-axis coordinate of the comment on the canvas."
},
"content": {
"type": "string",
"maxLength": 2000,
"minLength": 1,
"description": "Text content of the comment."
},
"miro_url": {
"type": "string",
"minLength": 1,
"description": "Miro board URL. Can be a plain board URL (e.g., 'https://miro.com/app/board/uXjVGeTCXKY=/') to get a board overview, or include moveToWidget/focusWidget parameter (e.g., 'https://miro.com/app/board/uXjVGeTCXKY=/?moveToWidget=3458764654510025479') to get detailed content for a specific item."
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"description": "Unique identifier of the comment."
},
"messages": {
"type": "array",
"items": {
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"description": "Unique identifier of the message."
},
"content": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Text content of the message."
},
"createdAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the message was created."
},
"createdBy": {
"anyOf": [
{
"type": "object",
"additionalProperties": {
"type": "string"
}
},
{
"type": "null"
}
],
"default": null,
"description": "User who created the message."
},
"reactions": {
"type": "array",
"items": {
"type": "object",
"required": [
"emoji",
"userIds"
],
"properties": {
"emoji": {
"type": "string",
"description": "Emoji used as the reaction."
},
"userIds": {
"type": "array",
"items": {
"type": "string"
},
"description": "IDs of users who reacted with this emoji."
},
"createdAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the reaction was first added."
}
},
"description": "An emoji reaction on a comment or message."
},
"description": "Reactions on the message."
},
"modifiedAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the message was last modified."
}
},
"description": "A message in a comment thread (original comment or reply)."
},
"description": "Messages in the comment thread. The first message is the original comment; subsequent messages are replies."
},
"position": {
"anyOf": [
{
"type": "object",
"required": [
"type"
],
"properties": {
"x": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"default": null,
"description": "X-axis coordinate (canvas and attached types)."
},
"y": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"default": null,
"description": "Y-axis coordinate (canvas and attached types)."
},
"type": {
"type": "string",
"description": "Position type: canvas, attached, table, or doc."
},
"rowId": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "ID of the data table row the comment is attached to (table type)."
},
"itemId": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "ID of the item the comment is attached to (attached, table, and doc types)."
}
},
"description": "Position of a comment on the board."
},
{
"type": "null"
}
],
"default": null,
"description": "Position of the comment on the board."
},
"resolved": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"default": null,
"description": "Whether the comment thread has been resolved."
},
"createdAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the comment was created."
},
"createdBy": {
"anyOf": [
{
"type": "object",
"additionalProperties": {
"type": "string"
}
},
{
"type": "null"
}
],
"default": null,
"description": "User who created the comment."
},
"reactions": {
"type": "array",
"items": {
"type": "object",
"required": [
"emoji",
"userIds"
],
"properties": {
"emoji": {
"type": "string",
"description": "Emoji used as the reaction."
},
"userIds": {
"type": "array",
"items": {
"type": "string"
},
"description": "IDs of users who reacted with this emoji."
},
"createdAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the reaction was first added."
}
},
"description": "An emoji reaction on a comment or message."
},
"description": "Reactions on the comment."
},
"modifiedAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the comment was last modified."
},
"mentionedUsers": {
"type": "array",
"items": {
"type": "object",
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "string",
"description": "Unique identifier of the user."
},
"name": {
"type": "string",
"description": "Display name of the user."
}
},
"description": "A user mentioned in a comment thread by an `@[<userId>]` token, with the\nuser's resolved name so the client can render `@<name>` without an extra\nlookup. The upstream `type` field is dropped - clients don't need to\ndistinguish user types here."
},
"description": "Users mentioned by `@[<userId>]` tokens across all messages in the thread, with their resolved name. Aggregated and deduplicated. Users that cannot be resolved are omitted; clients fall back to showing the raw id."
}
},
"description": "A comment thread on a Miro board."
},
"annotations": {
"title": "Create Canvas Comment",
"readOnlyHint": false,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description89/100
Add a reply message to an existing comment thread on a Miro board. Use list_comments to find comment IDs. The reply appears as the last message in the thread and is attributed to the current user.
The description explains the capability, when to use it, and what to expect.
Inputs87/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
miro_url
Miro board URL. Can be a plain board URL (e.g., 'https://miro.com/app/board/uXjVGeTCXKY=/') to get a board overview, or include moveToWidget/focusWidget parameter (e.g., 'https://miro.com/app/board/uXjVGeTCXKY=/?moveToWidget=3458764654510025479') to get detailed content for a specific item.
Clear enough to supply this argument.
comment_id
ID of the comment thread to reply to. Obtain from list_comments.
Clear enough to supply this argument.
content
Text content of the reply message.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Clear enough to supply this argument.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"description": "Unique identifier of the comment."
},
"messages": {
"type": "array",
"items": {
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"description": "Unique identifier of the message."
},
"content": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Text content of the message."
},
"createdAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the message was created."
},
"createdBy": {
"anyOf": [
{
"type": "object",
"additionalProperties": {
"type": "string"
}
},
{
"type": "null"
}
],
"default": null,
"description": "User who created the message."
},
"reactions": {
"type": "array",
"items": {
"type": "object",
"required": [
"emoji",
"userIds"
],
"properties": {
"emoji": {
"type": "string",
"description": "Emoji used as the reaction."
},
"userIds": {
"type": "array",
"items": {
"type": "string"
},
"description": "IDs of users who reacted with this emoji."
},
"createdAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the reaction was first added."
}
},
"description": "An emoji reaction on a comment or message."
},
"description": "Reactions on the message."
},
"modifiedAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the message was last modified."
}
},
"description": "A message in a comment thread (original comment or reply)."
},
"description": "Messages in the comment thread. The first message is the original comment; subsequent messages are replies."
},
"position": {
"anyOf": [
{
"type": "object",
"required": [
"type"
],
"properties": {
"x": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"default": null,
"description": "X-axis coordinate (canvas and attached types)."
},
"y": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"default": null,
"description": "Y-axis coordinate (canvas and attached types)."
},
"type": {
"type": "string",
"description": "Position type: canvas, attached, table, or doc."
},
"rowId": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "ID of the data table row the comment is attached to (table type)."
},
"itemId": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "ID of the item the comment is attached to (attached, table, and doc types)."
}
},
"description": "Position of a comment on the board."
},
{
"type": "null"
}
],
"default": null,
"description": "Position of the comment on the board."
},
"resolved": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"default": null,
"description": "Whether the comment thread has been resolved."
},
"createdAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the comment was created."
},
"createdBy": {
"anyOf": [
{
"type": "object",
"additionalProperties": {
"type": "string"
}
},
{
"type": "null"
}
],
"default": null,
"description": "User who created the comment."
},
"reactions": {
"type": "array",
"items": {
"type": "object",
"required": [
"emoji",
"userIds"
],
"properties": {
"emoji": {
"type": "string",
"description": "Emoji used as the reaction."
},
"userIds": {
"type": "array",
"items": {
"type": "string"
},
"description": "IDs of users who reacted with this emoji."
},
"createdAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the reaction was first added."
}
},
"description": "An emoji reaction on a comment or message."
},
"description": "Reactions on the comment."
},
"modifiedAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the comment was last modified."
},
"mentionedUsers": {
"type": "array",
"items": {
"type": "object",
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "string",
"description": "Unique identifier of the user."
},
"name": {
"type": "string",
"description": "Display name of the user."
}
},
"description": "A user mentioned in a comment thread by an `@[<userId>]` token, with the\nuser's resolved name so the client can render `@<name>` without an extra\nlookup. The upstream `type` field is dropped - clients don't need to\ndistinguish user types here."
},
"description": "Users mentioned by `@[<userId>]` tokens across all messages in the thread, with their resolved name. Aggregated and deduplicated. Users that cannot be resolved are omitted; clients fall back to showing the raw id."
}
},
"description": "A comment thread on a Miro board."
}
Original tool metadata
{
"name": "comment_reply",
"title": "Reply to Comment",
"description": "Add a reply message to an existing comment thread on a Miro board. Use list_comments to find comment IDs. The reply appears as the last message in the thread and is attributed to the current user.",
"inputSchema": {
"type": "object",
"required": [
"miro_url",
"comment_id",
"content"
],
"properties": {
"content": {
"type": "string",
"maxLength": 2000,
"minLength": 1,
"description": "Text content of the reply message."
},
"miro_url": {
"type": "string",
"minLength": 1,
"description": "Miro board URL. Can be a plain board URL (e.g., 'https://miro.com/app/board/uXjVGeTCXKY=/') to get a board overview, or include moveToWidget/focusWidget parameter (e.g., 'https://miro.com/app/board/uXjVGeTCXKY=/?moveToWidget=3458764654510025479') to get detailed content for a specific item."
},
"comment_id": {
"type": "string",
"description": "ID of the comment thread to reply to. Obtain from list_comments."
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"description": "Unique identifier of the comment."
},
"messages": {
"type": "array",
"items": {
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"description": "Unique identifier of the message."
},
"content": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Text content of the message."
},
"createdAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the message was created."
},
"createdBy": {
"anyOf": [
{
"type": "object",
"additionalProperties": {
"type": "string"
}
},
{
"type": "null"
}
],
"default": null,
"description": "User who created the message."
},
"reactions": {
"type": "array",
"items": {
"type": "object",
"required": [
"emoji",
"userIds"
],
"properties": {
"emoji": {
"type": "string",
"description": "Emoji used as the reaction."
},
"userIds": {
"type": "array",
"items": {
"type": "string"
},
"description": "IDs of users who reacted with this emoji."
},
"createdAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the reaction was first added."
}
},
"description": "An emoji reaction on a comment or message."
},
"description": "Reactions on the message."
},
"modifiedAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the message was last modified."
}
},
"description": "A message in a comment thread (original comment or reply)."
},
"description": "Messages in the comment thread. The first message is the original comment; subsequent messages are replies."
},
"position": {
"anyOf": [
{
"type": "object",
"required": [
"type"
],
"properties": {
"x": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"default": null,
"description": "X-axis coordinate (canvas and attached types)."
},
"y": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"default": null,
"description": "Y-axis coordinate (canvas and attached types)."
},
"type": {
"type": "string",
"description": "Position type: canvas, attached, table, or doc."
},
"rowId": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "ID of the data table row the comment is attached to (table type)."
},
"itemId": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "ID of the item the comment is attached to (attached, table, and doc types)."
}
},
"description": "Position of a comment on the board."
},
{
"type": "null"
}
],
"default": null,
"description": "Position of the comment on the board."
},
"resolved": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"default": null,
"description": "Whether the comment thread has been resolved."
},
"createdAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the comment was created."
},
"createdBy": {
"anyOf": [
{
"type": "object",
"additionalProperties": {
"type": "string"
}
},
{
"type": "null"
}
],
"default": null,
"description": "User who created the comment."
},
"reactions": {
"type": "array",
"items": {
"type": "object",
"required": [
"emoji",
"userIds"
],
"properties": {
"emoji": {
"type": "string",
"description": "Emoji used as the reaction."
},
"userIds": {
"type": "array",
"items": {
"type": "string"
},
"description": "IDs of users who reacted with this emoji."
},
"createdAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the reaction was first added."
}
},
"description": "An emoji reaction on a comment or message."
},
"description": "Reactions on the comment."
},
"modifiedAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the comment was last modified."
},
"mentionedUsers": {
"type": "array",
"items": {
"type": "object",
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "string",
"description": "Unique identifier of the user."
},
"name": {
"type": "string",
"description": "Display name of the user."
}
},
"description": "A user mentioned in a comment thread by an `@[<userId>]` token, with the\nuser's resolved name so the client can render `@<name>` without an extra\nlookup. The upstream `type` field is dropped - clients don't need to\ndistinguish user types here."
},
"description": "Users mentioned by `@[<userId>]` tokens across all messages in the thread, with their resolved name. Aggregated and deduplicated. Users that cannot be resolved are omitted; clients fall back to showing the raw id."
}
},
"description": "A comment thread on a Miro board."
},
"annotations": {
"title": "Reply to Comment",
"readOnlyHint": false,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description90/100
Resolve or unresolve a comment thread on a Miro board. Resolving marks the thread as addressed; unresolving reopens it. Use list_comments with resolved=false to find open threads.
The description explains the capability, when to use it, and what to expect.
Inputs87/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
miro_url
Miro board URL. Can be a plain board URL (e.g., 'https://miro.com/app/board/uXjVGeTCXKY=/') to get a board overview, or include moveToWidget/focusWidget parameter (e.g., 'https://miro.com/app/board/uXjVGeTCXKY=/?moveToWidget=3458764654510025479') to get detailed content for a specific item.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
comment_id
ID of the comment thread to resolve or unresolve. Obtain from list_comments.
Clear enough to supply this argument.
resolved
Set to true to resolve the thread, false to unresolve it.
Clear enough to supply this argument.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Clear enough to supply this argument.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
{
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"description": "Unique identifier of the comment."
},
"messages": {
"type": "array",
"items": {
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"description": "Unique identifier of the message."
},
"content": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Text content of the message."
},
"createdAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the message was created."
},
"createdBy": {
"anyOf": [
{
"type": "object",
"additionalProperties": {
"type": "string"
}
},
{
"type": "null"
}
],
"default": null,
"description": "User who created the message."
},
"reactions": {
"type": "array",
"items": {
"type": "object",
"required": [
"emoji",
"userIds"
],
"properties": {
"emoji": {
"type": "string",
"description": "Emoji used as the reaction."
},
"userIds": {
"type": "array",
"items": {
"type": "string"
},
"description": "IDs of users who reacted with this emoji."
},
"createdAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the reaction was first added."
}
},
"description": "An emoji reaction on a comment or message."
},
"description": "Reactions on the message."
},
"modifiedAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the message was last modified."
}
},
"description": "A message in a comment thread (original comment or reply)."
},
"description": "Messages in the comment thread. The first message is the original comment; subsequent messages are replies."
},
"position": {
"anyOf": [
{
"type": "object",
"required": [
"type"
],
"properties": {
"x": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"default": null,
"description": "X-axis coordinate (canvas and attached types)."
},
"y": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"default": null,
"description": "Y-axis coordinate (canvas and attached types)."
},
"type": {
"type": "string",
"description": "Position type: canvas, attached, table, or doc."
},
"rowId": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "ID of the data table row the comment is attached to (table type)."
},
"itemId": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "ID of the item the comment is attached to (attached, table, and doc types)."
}
},
"description": "Position of a comment on the board."
},
{
"type": "null"
}
],
"default": null,
"description": "Position of the comment on the board."
},
"resolved": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"default": null,
"description": "Whether the comment thread has been resolved."
},
"createdAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the comment was created."
},
"createdBy": {
"anyOf": [
{
"type": "object",
"additionalProperties": {
"type": "string"
}
},
{
"type": "null"
}
],
"default": null,
"description": "User who created the comment."
},
"reactions": {
"type": "array",
"items": {
"type": "object",
"required": [
"emoji",
"userIds"
],
"properties": {
"emoji": {
"type": "string",
"description": "Emoji used as the reaction."
},
"userIds": {
"type": "array",
"items": {
"type": "string"
},
"description": "IDs of users who reacted with this emoji."
},
"createdAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the reaction was first added."
}
},
"description": "An emoji reaction on a comment or message."
},
"description": "Reactions on the comment."
},
"modifiedAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the comment was last modified."
},
"mentionedUsers": {
"type": "array",
"items": {
"type": "object",
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "string",
"description": "Unique identifier of the user."
},
"name": {
"type": "string",
"description": "Display name of the user."
}
},
"description": "A user mentioned in a comment thread by an `@[<userId>]` token, with the\nuser's resolved name so the client can render `@<name>` without an extra\nlookup. The upstream `type` field is dropped - clients don't need to\ndistinguish user types here."
},
"description": "Users mentioned by `@[<userId>]` tokens across all messages in the thread, with their resolved name. Aggregated and deduplicated. Users that cannot be resolved are omitted; clients fall back to showing the raw id."
}
},
"description": "A comment thread on a Miro board."
}
Original tool metadata
{
"name": "comment_resolve",
"title": "Resolve Comment",
"description": "Resolve or unresolve a comment thread on a Miro board. Resolving marks the thread as addressed; unresolving reopens it. Use list_comments with resolved=false to find open threads.",
"inputSchema": {
"type": "object",
"required": [
"miro_url",
"comment_id",
"resolved"
],
"properties": {
"miro_url": {
"type": "string",
"minLength": 1,
"description": "Miro board URL. Can be a plain board URL (e.g., 'https://miro.com/app/board/uXjVGeTCXKY=/') to get a board overview, or include moveToWidget/focusWidget parameter (e.g., 'https://miro.com/app/board/uXjVGeTCXKY=/?moveToWidget=3458764654510025479') to get detailed content for a specific item."
},
"resolved": {
"type": "boolean",
"description": "Set to true to resolve the thread, false to unresolve it."
},
"comment_id": {
"type": "string",
"description": "ID of the comment thread to resolve or unresolve. Obtain from list_comments."
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"description": "Unique identifier of the comment."
},
"messages": {
"type": "array",
"items": {
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"description": "Unique identifier of the message."
},
"content": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Text content of the message."
},
"createdAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the message was created."
},
"createdBy": {
"anyOf": [
{
"type": "object",
"additionalProperties": {
"type": "string"
}
},
{
"type": "null"
}
],
"default": null,
"description": "User who created the message."
},
"reactions": {
"type": "array",
"items": {
"type": "object",
"required": [
"emoji",
"userIds"
],
"properties": {
"emoji": {
"type": "string",
"description": "Emoji used as the reaction."
},
"userIds": {
"type": "array",
"items": {
"type": "string"
},
"description": "IDs of users who reacted with this emoji."
},
"createdAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the reaction was first added."
}
},
"description": "An emoji reaction on a comment or message."
},
"description": "Reactions on the message."
},
"modifiedAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the message was last modified."
}
},
"description": "A message in a comment thread (original comment or reply)."
},
"description": "Messages in the comment thread. The first message is the original comment; subsequent messages are replies."
},
"position": {
"anyOf": [
{
"type": "object",
"required": [
"type"
],
"properties": {
"x": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"default": null,
"description": "X-axis coordinate (canvas and attached types)."
},
"y": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"default": null,
"description": "Y-axis coordinate (canvas and attached types)."
},
"type": {
"type": "string",
"description": "Position type: canvas, attached, table, or doc."
},
"rowId": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "ID of the data table row the comment is attached to (table type)."
},
"itemId": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "ID of the item the comment is attached to (attached, table, and doc types)."
}
},
"description": "Position of a comment on the board."
},
{
"type": "null"
}
],
"default": null,
"description": "Position of the comment on the board."
},
"resolved": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"default": null,
"description": "Whether the comment thread has been resolved."
},
"createdAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the comment was created."
},
"createdBy": {
"anyOf": [
{
"type": "object",
"additionalProperties": {
"type": "string"
}
},
{
"type": "null"
}
],
"default": null,
"description": "User who created the comment."
},
"reactions": {
"type": "array",
"items": {
"type": "object",
"required": [
"emoji",
"userIds"
],
"properties": {
"emoji": {
"type": "string",
"description": "Emoji used as the reaction."
},
"userIds": {
"type": "array",
"items": {
"type": "string"
},
"description": "IDs of users who reacted with this emoji."
},
"createdAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the reaction was first added."
}
},
"description": "An emoji reaction on a comment or message."
},
"description": "Reactions on the comment."
},
"modifiedAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the comment was last modified."
},
"mentionedUsers": {
"type": "array",
"items": {
"type": "object",
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "string",
"description": "Unique identifier of the user."
},
"name": {
"type": "string",
"description": "Display name of the user."
}
},
"description": "A user mentioned in a comment thread by an `@[<userId>]` token, with the\nuser's resolved name so the client can render `@<name>` without an extra\nlookup. The upstream `type` field is dropped - clients don't need to\ndistinguish user types here."
},
"description": "Users mentioned by `@[<userId>]` tokens across all messages in the thread, with their resolved name. Aggregated and deduplicated. Users that cannot be resolved are omitted; clients fall back to showing the raw id."
}
},
"description": "A comment thread on a Miro board."
},
"annotations": {
"title": "Resolve Comment",
"readOnlyHint": false,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Create board items from a canvas-composer SVG document. Parses the SVG into Miro widgets -- shapes, stickies, text, connectors, frames, tables, docs, images, slide decks, AND structured Mermaid diagrams (flowchart, ERD, UML class/sequence, authored as a <foreignObject data-type="diagram"> with a Mermaid body). This is the primary tool for creating ANY board content, diagrams and presentations included: 'create a diagram' / 'draw a flowchart' are handled here, NOT by the legacy diagram_* tools, and 'build a slide deck' / 'make a presentation' are handled here too. Returns a result_svg with data-miro-id stamped on every svg element for the next iteration.
The description explains the capability, when to use it, and what to expect.
Inputs88/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
miro_url
Full Miro board URL (e.g., 'https://miro.com/app/board/uXjVOakxTk0='). To target a specific parent frame, include ?moveToWidget=<frame_id>.
Clear enough to supply this argument.
svg
A board written in the Canvas Composer SVG format.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Clear enough to supply this argument.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
{
"name": "canvas_create_from_svg",
"title": "Create Board from SVG",
"description": "Create board items from a canvas-composer SVG document. Parses the SVG into Miro widgets -- shapes, stickies, text, connectors, frames, tables, docs, images, slide decks, AND structured Mermaid diagrams (flowchart, ERD, UML class/sequence, authored as a <foreignObject data-type=\"diagram\"> with a Mermaid body). This is the primary tool for creating ANY board content, diagrams and presentations included: 'create a diagram' / 'draw a flowchart' are handled here, NOT by the legacy diagram_* tools, and 'build a slide deck' / 'make a presentation' are handled here too. Returns a result_svg with data-miro-id stamped on every svg element for the next iteration.",
"inputSchema": {
"type": "object",
"required": [
"miro_url",
"svg"
],
"properties": {
"svg": {
"type": "string",
"maxLength": 200000,
"description": "A board written in the Canvas Composer SVG format."
},
"miro_url": {
"type": "string",
"description": "Full Miro board URL (e.g., 'https://miro.com/app/board/uXjVOakxTk0='). To target a specific parent frame, include ?moveToWidget=<frame_id>."
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"required": [
"success",
"message",
"created_count",
"miro_url"
],
"properties": {
"message": {
"type": "string"
},
"skipped": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
}
},
"success": {
"type": "boolean"
},
"miro_url": {
"type": "string"
},
"result_svg": {
"type": "string",
"default": ""
},
"created_ids": {
"type": "array",
"items": {
"type": "string"
}
},
"failed_items": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
}
},
"created_count": {
"type": "integer"
},
"created_items": {
"type": "array",
"items": {
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string"
},
"type": {
"type": "string",
"default": "widget"
},
"title": {
"type": "string",
"default": ""
}
}
}
}
}
},
"annotations": {
"title": "Create Board from SVG",
"readOnlyHint": false,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description94/100
Get the board-authoring workflow instructions and the DSL (Domain-Specific Language) format specification for creating board items. REQUIRED and FIRST: call this before canvas_create_from_svg, and before canvas_load_format_skill. The first call (no arguments) routes you to the right workflow step; follow the returned instructions and call again with the step value they name. This is the foundational skill -- every use-case skill from canvas_load_format_skill (e.g. diagramming) layers on top of it and assumes you already have it, so never load a format skill before this one. In a conversation, reuse each step's returned instructions instead of re-fetching them.
The description explains the capability, when to use it, and what to expect.
Inputs75/100
3 of 4 inputs have descriptions. Add descriptions to the missing inputs, including where to obtain IDs and how to supply values.
step
Workflow step selector. Omit on the first call; each response names the valid value for the next call.
Clear enough to supply this argument.
miro_url
Not provided
Missing description. Explain what this value means and how to supply it.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Clear enough to supply this argument.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
{
"name": "canvas_get_canvas_composer_skill",
"title": "Canvas Composer",
"description": "Get the board-authoring workflow instructions and the DSL (Domain-Specific Language) format specification for creating board items. REQUIRED and FIRST: call this before canvas_create_from_svg, and before canvas_load_format_skill. The first call (no arguments) routes you to the right workflow step; follow the returned instructions and call again with the step value they name. This is the foundational skill -- every use-case skill from canvas_load_format_skill (e.g. diagramming) layers on top of it and assumes you already have it, so never load a format skill before this one. In a conversation, reuse each step's returned instructions instead of re-fetching them.",
"inputSchema": {
"type": "object",
"properties": {
"step": {
"type": "string",
"default": null,
"nullable": true,
"description": "Workflow step selector. Omit on the first call; each response names the valid value for the next call."
},
"miro_url": {
"type": "string",
"default": null,
"nullable": true
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"required": [
"skill"
],
"properties": {
"step": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null
},
"skill": {
"type": "string"
},
"message": {
"type": "string",
"default": ""
},
"success": {
"type": "boolean",
"default": true
}
}
},
"annotations": {
"title": "Canvas Composer",
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description89/100
Load supplementary authoring guidance (a skill) for a specific composition format, layered ON TOP OF the general canvas format. PREREQUISITE: call canvas_get_canvas_composer_skill FIRST -- this tool assumes you already know the SVG board format and only adds format-specific styling and examples. Do not call it as your first step, and never in place of the composer skill. Content is still created with canvas_create_from_svg / canvas_update_from_svg. Available formats: 'diagramming' (styling and worked examples for Mermaid diagram widgets), 'presentation' (design guidance for slide decks; available where the composer skill lists the SLIDE_CONTAINER widget) and 'prototyping' (HTML authoring contract and design guidance for prototype screens; available where it lists the PROTOTYPING_CONTAINER widget). For 'diagramming', pass the notation you are drawing to get that notation's color defaults and worked example. Call once per format/notation in a conversation and reuse the guidance.
The description explains the capability, when to use it, and what to expect.
Inputs75/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
format_name
The composition format to load guidance for. 'diagramming' for styling and worked examples of Mermaid diagram widgets; 'presentation' for slide decks; 'prototyping' for HTML prototype screens.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
notation
For format_name='diagramming', the diagram notation you are drawing: 'flowchart', 'entity_relationship', 'uml_class', or 'uml_sequence' for a Mermaid diagram widget, or 'free_form' for a hand-assembled diagram from shapes and connectors (use only when no Mermaid notation and no native widget fits, e.g. a mind map). Returns that notation's guidance. Omit to get the shared color contract plus the list of supported notations.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Explain what happens when this optional value is omitted.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
{
"name": "canvas_load_format_skill",
"title": "Load Format Skill",
"description": "Load supplementary authoring guidance (a skill) for a specific composition format, layered ON TOP OF the general canvas format. PREREQUISITE: call canvas_get_canvas_composer_skill FIRST -- this tool assumes you already know the SVG board format and only adds format-specific styling and examples. Do not call it as your first step, and never in place of the composer skill. Content is still created with canvas_create_from_svg / canvas_update_from_svg. Available formats: 'diagramming' (styling and worked examples for Mermaid diagram widgets), 'presentation' (design guidance for slide decks; available where the composer skill lists the SLIDE_CONTAINER widget) and 'prototyping' (HTML authoring contract and design guidance for prototype screens; available where it lists the PROTOTYPING_CONTAINER widget). For 'diagramming', pass the notation you are drawing to get that notation's color defaults and worked example. Call once per format/notation in a conversation and reuse the guidance.",
"inputSchema": {
"type": "object",
"required": [
"format_name"
],
"properties": {
"notation": {
"enum": [
"flowchart",
"entity_relationship",
"uml_class",
"uml_sequence",
"free_form"
],
"type": "string",
"default": null,
"nullable": true,
"description": "For format_name='diagramming', the diagram notation you are drawing: 'flowchart', 'entity_relationship', 'uml_class', or 'uml_sequence' for a Mermaid diagram widget, or 'free_form' for a hand-assembled diagram from shapes and connectors (use only when no Mermaid notation and no native widget fits, e.g. a mind map). Returns that notation's guidance. Omit to get the shared color contract plus the list of supported notations."
},
"format_name": {
"enum": [
"diagramming",
"flows",
"presentation",
"prototyping"
],
"type": "string",
"description": "The composition format to load guidance for. 'diagramming' for styling and worked examples of Mermaid diagram widgets; 'presentation' for slide decks; 'prototyping' for HTML prototype screens."
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"required": [
"format_name",
"notation",
"skill"
],
"properties": {
"skill": {
"type": "string"
},
"notation": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"format_name": {
"type": "string"
}
}
},
"annotations": {
"title": "Load Format Skill",
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description76/100
Read one board area or specific items as a canvas-composer SVG document. Provide either widget_ids or all four scope fields but not both simultaneously. Use canvas_search to find a scope. Use widget_ids only for specific items; selecting a container (a frame, slide deck, or prototype) includes everything nested inside it. Has no target_id parameter (that belongs to canvas_search): name items with widget_ids and restrict to an area with the scope fields.
Describe the returned information so the agent knows whether it will answer the request.
Inputs66/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
miro_url
Full Miro board URL (e.g., 'https://miro.com/app/board/uXjVOakxTk0='). To target a specific parent frame, include ?moveToWidget=<frame_id>.
Clear enough to supply this argument.
widget_ids
Required unless all four scope fields are set. Return only the items with these data-miro-id values. Ancestor frames are added automatically so positions stay correct, and selecting a container (a frame, slide deck, or prototype) pulls in everything nested inside it. Unknown ids are skipped.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
scope_x
Working area left edge.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
scope_y
Working area top edge.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
scope_width
Working area width.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
scope_height
Working area height.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Explain what happens when this optional value is omitted.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
{
"name": "canvas_read_as_svg",
"title": "Read Board as SVG",
"description": "Read one board area or specific items as a canvas-composer SVG document. Provide either widget_ids or all four scope fields but not both simultaneously. Use canvas_search to find a scope. Use widget_ids only for specific items; selecting a container (a frame, slide deck, or prototype) includes everything nested inside it. Has no target_id parameter (that belongs to canvas_search): name items with widget_ids and restrict to an area with the scope fields.",
"inputSchema": {
"type": "object",
"required": [
"miro_url"
],
"properties": {
"scope_x": {
"type": "integer",
"default": null,
"nullable": true,
"description": "Working area left edge."
},
"scope_y": {
"type": "integer",
"default": null,
"nullable": true,
"description": "Working area top edge."
},
"miro_url": {
"type": "string",
"description": "Full Miro board URL (e.g., 'https://miro.com/app/board/uXjVOakxTk0='). To target a specific parent frame, include ?moveToWidget=<frame_id>."
},
"widget_ids": {
"type": "array",
"items": {
"type": "string"
},
"default": null,
"nullable": true,
"description": "Required unless all four scope fields are set. Return only the items with these data-miro-id values. Ancestor frames are added automatically so positions stay correct, and selecting a container (a frame, slide deck, or prototype) pulls in everything nested inside it. Unknown ids are skipped."
},
"scope_width": {
"type": "integer",
"default": null,
"nullable": true,
"description": "Working area width."
},
"scope_height": {
"type": "integer",
"default": null,
"nullable": true,
"description": "Working area height."
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"required": [
"success",
"message",
"svg",
"item_count",
"skipped_count",
"miro_url"
],
"properties": {
"svg": {
"type": "string"
},
"message": {
"type": "string"
},
"scope_x": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null
},
"scope_y": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null
},
"success": {
"type": "boolean"
},
"miro_url": {
"type": "string"
},
"item_count": {
"type": "integer"
},
"scope_width": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null
},
"scope_height": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null
},
"skipped_count": {
"type": "integer"
}
}
},
"annotations": {
"title": "Read Board as SVG",
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description73/100
Search and navigate board content on top of the canvas-composer SVG representation to find relevant items and areas. Use canvas search beforehand to narrow down scope of a read.
The description explains the capability, when to use it, and what to expect.
Inputs94/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
miro_url
Full Miro board URL (e.g., 'https://miro.com/app/board/uXjVOakxTk0='). To target a specific parent frame, include ?moveToWidget=<frame_id>.
Clear enough to supply this argument.
result_mode
Use overview without patterns for container titles and a small sample of board regions. Use areas to rank sections from related signals. Use matches for exact items, occurrences, IDs, attributes, or captures.
Clear enough to supply this argument.
patterns
Required for areas and matches. Omit for overview. Send related patterns together. Values are case-insensitive literal text by default. Prefix structural SVG regex with re:. Prefix literal text with text:. The prefix is consumed, so use text:text:budget to find the literal text:budget.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
target_id
Limit areas or matches to one result from an earlier search. Omit for overview.
Clear enough to supply this argument.
cursor
Continue areas or matches from next_cursor only when the earlier result was truncated. Omit for overview.
Clear enough to supply this argument.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Clear enough to supply this argument.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Apply a canvas-composer SVG document to the board by diffing it against the live board (matched on data-miro-id) and applying only the deltas: it creates new elements, updates existing ones, and deletes elements explicitly marked with data-deleted="true" (which must carry the element's data-miro-id). Removing an element from the SVG does NOT delete it, deletion is explicit per element, so a partial document is always safe. Deletion is destructive and not undoable here: confirm the specific items with the user before sending any data-deleted="true". Feed the result_svg from a previous canvas_create_from_svg or canvas_update_from_svg call back in to iterate. Returns a result_svg with data-miro-id stamped on every element for the next iteration.
The description explains the capability, when to use it, and what to expect.
Inputs91/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
miro_url
Full Miro board URL (e.g., 'https://miro.com/app/board/uXjVOakxTk0='). To target a specific parent frame, include ?moveToWidget=<frame_id>.
Clear enough to supply this argument.
svg
A board written in the Canvas Composer SVG format.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Clear enough to supply this argument.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
{
"name": "canvas_update_from_svg",
"title": "Update Board from SVG",
"description": "Apply a canvas-composer SVG document to the board by diffing it against the live board (matched on data-miro-id) and applying only the deltas: it creates new elements, updates existing ones, and deletes elements explicitly marked with data-deleted=\"true\" (which must carry the element's data-miro-id). Removing an element from the SVG does NOT delete it, deletion is explicit per element, so a partial document is always safe. Deletion is destructive and not undoable here: confirm the specific items with the user before sending any data-deleted=\"true\". Feed the result_svg from a previous canvas_create_from_svg or canvas_update_from_svg call back in to iterate. Returns a result_svg with data-miro-id stamped on every element for the next iteration.",
"inputSchema": {
"type": "object",
"required": [
"miro_url",
"svg"
],
"properties": {
"svg": {
"type": "string",
"maxLength": 200000,
"description": "A board written in the Canvas Composer SVG format."
},
"miro_url": {
"type": "string",
"description": "Full Miro board URL (e.g., 'https://miro.com/app/board/uXjVOakxTk0='). To target a specific parent frame, include ?moveToWidget=<frame_id>."
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"required": [
"success",
"message",
"miro_url"
],
"properties": {
"message": {
"type": "string"
},
"skipped": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
}
},
"success": {
"type": "boolean"
},
"miro_url": {
"type": "string"
},
"result_svg": {
"type": "string",
"default": ""
},
"created_ids": {
"type": "array",
"items": {
"type": "string"
}
},
"updated_ids": {
"type": "array",
"items": {
"type": "string"
}
},
"failed_items": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
}
},
"created_count": {
"type": "integer",
"default": 0
},
"created_items": {
"type": "array",
"items": {
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string"
},
"type": {
"type": "string",
"default": "widget"
},
"title": {
"type": "string",
"default": ""
}
}
}
},
"deleted_count": {
"type": "integer",
"default": 0
},
"updated_count": {
"type": "integer",
"default": 0
},
"updated_items": {
"type": "array",
"items": {
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string"
},
"type": {
"type": "string",
"default": "widget"
},
"title": {
"type": "string",
"default": ""
}
}
}
}
}
},
"annotations": {
"title": "Update Board from SVG",
"readOnlyHint": false,
"openWorldHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Read prototype screens from a Miro board. Returns prototype screens with metadata (position, dimensions, device type) and HTML markup representing each screen's UI layout. Useful for AI tools to understand the design, structure, and navigation flow of interactive prototypes. Provide screen_id to read a specific screen, or omit to list all screens on the board. Recommended workflow: first list all screens with include_html=false (default) to get metadata, then read a specific screen with include_html=true to get its HTML markup.
The description explains the capability, when to use it, and what to expect.
Inputs89/100
Input documentation gives an agent enough context to populate the arguments.
miro_url
Full Miro board URL (e.g., 'https://miro.com/app/board/uXjVOakxTk0='). To target a specific parent frame, include ?moveToWidget=<frame_id>.
Clear enough to supply this argument.
screen_id
Widget ID of a specific prototype screen to read. When omitted, all prototype screens on the board are returned.
Clear enough to supply this argument.
include_html
Whether to include HTML markup for each screen. Defaults to false. Set to true only when HTML is needed for a specific screen to avoid large context payloads.
Clear enough to supply this argument.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Clear enough to supply this argument.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
{
"type": "object",
"required": [
"screens",
"total_screens"
],
"properties": {
"screens": {
"type": "array",
"items": {
"type": "object",
"required": [
"id",
"miro_url"
],
"properties": {
"x": {
"type": "number",
"default": 0,
"description": "X-axis position on the board"
},
"y": {
"type": "number",
"default": 0,
"description": "Y-axis position on the board"
},
"id": {
"type": "string",
"description": "Widget ID of the prototype screen"
},
"html": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "HTML markup representing the UI layout of this screen"
},
"name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Screen name or title"
},
"width": {
"type": "number",
"default": 0,
"description": "Screen width in pixels"
},
"height": {
"type": "number",
"default": 0,
"description": "Screen height in pixels"
},
"summary": {
"type": "object",
"properties": {
"sections": {
"type": "array",
"items": {
"type": "string"
},
"description": "Semantic sections (header, nav, main, footer, etc.)"
},
"components": {
"type": "array",
"items": {
"type": "string"
},
"description": "UI components detected (button, card, modal, etc.)"
},
"interactive_elements": {
"type": "array",
"items": {
"type": "string"
},
"description": "Interactive elements (buttons, inputs, links, etc.)"
}
},
"description": "Structural summary of the screen layout"
},
"miro_url": {
"type": "string",
"description": "Miro URL to navigate to this screen"
},
"connectors": {
"type": "array",
"items": {
"type": "object",
"required": [
"source_widget_id",
"target_screen_id"
],
"properties": {
"source_widget_id": {
"type": "string",
"description": "Widget ID of the source interactive element"
},
"target_screen_id": {
"type": "string",
"description": "Widget ID of the target screen"
}
},
"description": "Navigation connector between prototype screens."
},
"description": "Navigation connectors leading from this screen to other screens"
},
"device_type": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Target device type (mobile, tablet, desktop)"
},
"device_orientation": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Device orientation (portrait, landscape)"
}
},
"description": "Information about a single prototype screen."
},
"description": "List of prototype screens with their content"
},
"total_screens": {
"type": "integer",
"description": "Total number of prototype screens found"
}
},
"description": "Response from prototype_read tool."
}
Original tool metadata
{
"name": "prototype_read",
"title": "Read Prototype Screens",
"description": "Read prototype screens from a Miro board. Returns prototype screens with metadata (position, dimensions, device type) and HTML markup representing each screen's UI layout. Useful for AI tools to understand the design, structure, and navigation flow of interactive prototypes. Provide screen_id to read a specific screen, or omit to list all screens on the board. Recommended workflow: first list all screens with include_html=false (default) to get metadata, then read a specific screen with include_html=true to get its HTML markup.",
"inputSchema": {
"type": "object",
"required": [
"miro_url"
],
"properties": {
"miro_url": {
"type": "string",
"description": "Full Miro board URL (e.g., 'https://miro.com/app/board/uXjVOakxTk0='). To target a specific parent frame, include ?moveToWidget=<frame_id>."
},
"screen_id": {
"type": "string",
"default": null,
"nullable": true,
"description": "Widget ID of a specific prototype screen to read. When omitted, all prototype screens on the board are returned."
},
"include_html": {
"type": "boolean",
"default": false,
"description": "Whether to include HTML markup for each screen. Defaults to false. Set to true only when HTML is needed for a specific screen to avoid large context payloads."
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"required": [
"screens",
"total_screens"
],
"properties": {
"screens": {
"type": "array",
"items": {
"type": "object",
"required": [
"id",
"miro_url"
],
"properties": {
"x": {
"type": "number",
"default": 0,
"description": "X-axis position on the board"
},
"y": {
"type": "number",
"default": 0,
"description": "Y-axis position on the board"
},
"id": {
"type": "string",
"description": "Widget ID of the prototype screen"
},
"html": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "HTML markup representing the UI layout of this screen"
},
"name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Screen name or title"
},
"width": {
"type": "number",
"default": 0,
"description": "Screen width in pixels"
},
"height": {
"type": "number",
"default": 0,
"description": "Screen height in pixels"
},
"summary": {
"type": "object",
"properties": {
"sections": {
"type": "array",
"items": {
"type": "string"
},
"description": "Semantic sections (header, nav, main, footer, etc.)"
},
"components": {
"type": "array",
"items": {
"type": "string"
},
"description": "UI components detected (button, card, modal, etc.)"
},
"interactive_elements": {
"type": "array",
"items": {
"type": "string"
},
"description": "Interactive elements (buttons, inputs, links, etc.)"
}
},
"description": "Structural summary of the screen layout"
},
"miro_url": {
"type": "string",
"description": "Miro URL to navigate to this screen"
},
"connectors": {
"type": "array",
"items": {
"type": "object",
"required": [
"source_widget_id",
"target_screen_id"
],
"properties": {
"source_widget_id": {
"type": "string",
"description": "Widget ID of the source interactive element"
},
"target_screen_id": {
"type": "string",
"description": "Widget ID of the target screen"
}
},
"description": "Navigation connector between prototype screens."
},
"description": "Navigation connectors leading from this screen to other screens"
},
"device_type": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Target device type (mobile, tablet, desktop)"
},
"device_orientation": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Device orientation (portrait, landscape)"
}
},
"description": "Information about a single prototype screen."
},
"description": "List of prototype screens with their content"
},
"total_screens": {
"type": "integer",
"description": "Total number of prototype screens found"
}
},
"description": "Response from prototype_read tool."
},
"annotations": {
"title": "Read Prototype Screens",
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Reserve one or more single-use upload slots for HTML screens. Set count to the number of screens in the prototype to reserve all slots in a single call instead of calling this once per screen. Returns one entry per slot, each with its own upload_url and token; uploads can run in parallel.
PUT the raw HTML as the request body with Content-Type: text/html; no auth header.
curl: curl -X PUT -H 'Content-Type: text/html' --data-binary @page.html '<upload_url>'. If the HTML only exists as a string in your context, write it to a local file first (e.g. page.html), then PUT that file — not already having a file is not a reason to fall back to html_contents.
Max size: 1,048,576 bytes per screen. External http/https image URLs are fine; the server fetches them. Only local file references need pre-upload (see prototype_create's image_tokens).
After each upload, pass its token to prototype_create, in the same order.
The description explains the capability, when to use it, and what to expect.
Inputs93/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
miro_url
Full Miro board URL (e.g., 'https://miro.com/app/board/uXjVOakxTk0='). To target a specific parent frame, include ?moveToWidget=<frame_id>.
Clear enough to supply this argument.
count
Number of upload slots to reserve, one per screen. Request all slots needed for a prototype in a single call so uploads can run in parallel.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Clear enough to supply this argument.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
{
"type": "object",
"required": [
"result"
],
"properties": {
"result": {
"type": "array",
"items": {
"type": "object",
"required": [
"upload_url",
"token",
"expires_in"
],
"properties": {
"token": {
"type": "string",
"description": "Single-use token to pass to prototype_create after the upload completes."
},
"expires_in": {
"type": "integer",
"description": "Seconds until this URL expires"
},
"upload_url": {
"type": "string",
"description": "Upload endpoint URL. Send the HTML file as the raw request body. Set Content-Type: text/html. No Authorization header needed. curl usage: curl -X PUT -H 'Content-Type: text/html' --data-binary @page.html '<url>'."
}
},
"description": "Response from prototype_get_upload_url — presigned S3 PUT URL and a single-use token."
}
}
},
"x-fastmcp-wrap-result": true
}
Original tool metadata
{
"name": "prototype_get_upload_url",
"title": "Get HTML Upload URL",
"description": "Reserve one or more single-use upload slots for HTML screens. Set count to the number of screens in the prototype to reserve all slots in a single call instead of calling this once per screen. Returns one entry per slot, each with its own upload_url and token; uploads can run in parallel.\nPUT the raw HTML as the request body with Content-Type: text/html; no auth header.\ncurl: curl -X PUT -H 'Content-Type: text/html' --data-binary @page.html '<upload_url>'. If the HTML only exists as a string in your context, write it to a local file first (e.g. page.html), then PUT that file — not already having a file is not a reason to fall back to html_contents.\nMax size: 1,048,576 bytes per screen. External http/https image URLs are fine; the server fetches them. Only local file references need pre-upload (see prototype_create's image_tokens).\nAfter each upload, pass its token to prototype_create, in the same order.",
"inputSchema": {
"type": "object",
"required": [
"miro_url"
],
"properties": {
"count": {
"type": "integer",
"default": 1,
"maximum": 20,
"minimum": 1,
"description": "Number of upload slots to reserve, one per screen. Request all slots needed for a prototype in a single call so uploads can run in parallel."
},
"miro_url": {
"type": "string",
"description": "Full Miro board URL (e.g., 'https://miro.com/app/board/uXjVOakxTk0='). To target a specific parent frame, include ?moveToWidget=<frame_id>."
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"required": [
"result"
],
"properties": {
"result": {
"type": "array",
"items": {
"type": "object",
"required": [
"upload_url",
"token",
"expires_in"
],
"properties": {
"token": {
"type": "string",
"description": "Single-use token to pass to prototype_create after the upload completes."
},
"expires_in": {
"type": "integer",
"description": "Seconds until this URL expires"
},
"upload_url": {
"type": "string",
"description": "Upload endpoint URL. Send the HTML file as the raw request body. Set Content-Type: text/html. No Authorization header needed. curl usage: curl -X PUT -H 'Content-Type: text/html' --data-binary @page.html '<url>'."
}
},
"description": "Response from prototype_get_upload_url — presigned S3 PUT URL and a single-use token."
}
}
},
"x-fastmcp-wrap-result": true
},
"annotations": {
"title": "Get HTML Upload URL",
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description83/100
Create a Miro prototype from one or more HTML screens.
Images: leave external http/https URLs in the HTML untouched — the server fetches and uploads them for you. ONLY local file references (e.g. './logo.png', 'assets/x.svg') need pre-upload: call image_get_upload_url with src set to the EXACT in-HTML reference, PUT the bytes, then pass the returned tokens via image_tokens below. The server rewrites matching <img src=...> attributes and attaches data-board-resource — do NOT rewrite the HTML yourself.
IMPORTANT: ONLY local file references (e.g. './logo.png', 'assets/x.svg') in any part of the HTML like inline, url(), srcset, etc... REQUIRES pre-upload: call image_get_upload_url with src set to the EXACT in-HTML reference, PUT the bytes, then pass the returned tokens via image_tokens below.
Fonts: CDN URL only.
Author static HTML + CSS only — <script> elements and inline event handlers (onclick etc.) are stripped, so any scripted behavior is silently lost; use CSS states (:hover, :focus) for visual interactivity.
Max per screen: 1,048,576 bytes. Max screens per call: 20 — split larger prototypes across multiple prototype_create calls.
Provide exactly one input — PREFER html_tokens (HTML stays out of context). html_contents is a last-resort fallback only when the runtime cannot issue an HTTP PUT at all; HTML size, image count, multi-screen, or not yet having the HTML saved to a file are NOT valid reasons — write it to a file yourself, then PUT it.
Placement: no item target → x/y are board-absolute (center is (0, 0)); moveToWidget on a frame → prototype is created inside, x/y are relative to frame top-left and must fit within frame width/height. All screens in one call share device_type, orientation, and placement; order is preserved.
The description explains the capability, when to use it, and what to expect.
Inputs90/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
miro_url
Full Miro board URL (e.g., 'https://miro.com/app/board/uXjVOakxTk0='). To target a specific parent frame, include ?moveToWidget=<frame_id>.
Clear enough to supply this argument.
html_tokens
Preferred input. Ordered list of tokens from prototype_get_upload_url, one per screen. Use whenever the runtime can issue an HTTP PUT. Max 20 tokens per call.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
html_contents
Last-resort fallback. Use ONLY when the runtime cannot issue an HTTP PUT at all (sandboxed agent with no network/curl/fetch). HTML size, image count, multi-screen, or not yet having the HTML saved to a file are NOT valid reasons — write the HTML to a file yourself and PUT it; html_tokens handles size/complexity by keeping the HTML out of context. Ordered list of raw HTML strings, one per screen; each at most 1,048,576 bytes. Max 20 screens per call.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
image_tokens
REQUIRED whenever the HTML references images by a non-http(s) path (e.g. './logo.png', 'assets/x.svg', '/var/...'). Omitting tokens for such refs leaves broken images. External http/https URLs are fetched server-side and do NOT belong here. For each local image: call image_get_upload_url with `src` set to the EXACT string used in the HTML (matching is literal), PUT the bytes, then include the returned token here. The server rewrites every <img src=...> matching the stored src and attaches data-board-resource — do NOT rewrite the HTML yourself. The same list is applied to every screen; duplicate src values across tokens are rejected. May be omitted only when the HTML has zero local image refs.
Clear enough to supply this argument.
device_type
Target device type for the prototype. Applies to every screen. Accepted values: 'desktop' (default), 'mobile', or 'tablet'.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
orientation
Screen orientation for the prototype. Applies to every screen. Accepted values: 'landscape' (default) or 'portrait'.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
x
X-axis coordinate. Without a frame target: board-absolute, board center is x=0. With a frame target via moveToWidget: relative to the frame's top-left corner (frame top-left is x=0).
Clear enough to supply this argument.
y
Y-axis coordinate. Without a frame target: board-absolute, board center is y=0. With a frame target via moveToWidget: relative to the frame's top-left corner (frame top-left is y=0).
Clear enough to supply this argument.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Clear enough to supply this argument.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
{
"type": "object",
"required": [
"miro_url",
"success",
"message"
],
"properties": {
"x": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"default": null
},
"y": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"default": null
},
"message": {
"type": "string"
},
"success": {
"type": "boolean"
},
"miro_url": {
"type": "string"
},
"parent_miro_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null
},
"failed_image_count": {
"type": "integer",
"default": 0,
"description": "Number of image refs that could not be uploaded during HTML processing and were stripped from the prototype HTML."
},
"failed_image_reason": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Representative reason for image upload failures when failed_image_count > 0 (e.g. validation rejection or platform error). Null when no images failed."
},
"successful_image_count": {
"type": "integer",
"default": 0,
"description": "Number of image refs successfully uploaded to board resources during HTML processing. Pairs with failed_image_count to give the agent the full picture."
}
},
"description": "Response model for prototype creation."
}
Original tool metadata
{
"name": "prototype_create",
"title": "Create Prototype",
"description": "Create a Miro prototype from one or more HTML screens.\n\nImages: leave external http/https URLs in the HTML untouched — the server fetches and uploads them for you. ONLY local file references (e.g. './logo.png', 'assets/x.svg') need pre-upload: call image_get_upload_url with src set to the EXACT in-HTML reference, PUT the bytes, then pass the returned tokens via image_tokens below. The server rewrites matching <img src=...> attributes and attaches data-board-resource — do NOT rewrite the HTML yourself.\nIMPORTANT: ONLY local file references (e.g. './logo.png', 'assets/x.svg') in any part of the HTML like inline, url(), srcset, etc... REQUIRES pre-upload: call image_get_upload_url with src set to the EXACT in-HTML reference, PUT the bytes, then pass the returned tokens via image_tokens below.\nFonts: CDN URL only.\nAuthor static HTML + CSS only — <script> elements and inline event handlers (onclick etc.) are stripped, so any scripted behavior is silently lost; use CSS states (:hover, :focus) for visual interactivity.\nMax per screen: 1,048,576 bytes. Max screens per call: 20 — split larger prototypes across multiple prototype_create calls.\n\nProvide exactly one input — PREFER html_tokens (HTML stays out of context). html_contents is a last-resort fallback only when the runtime cannot issue an HTTP PUT at all; HTML size, image count, multi-screen, or not yet having the HTML saved to a file are NOT valid reasons — write it to a file yourself, then PUT it.\n\nPlacement: no item target → x/y are board-absolute (center is (0, 0)); moveToWidget on a frame → prototype is created inside, x/y are relative to frame top-left and must fit within frame width/height. All screens in one call share device_type, orientation, and placement; order is preserved.",
"inputSchema": {
"type": "object",
"required": [
"miro_url"
],
"properties": {
"x": {
"type": "number",
"default": null,
"nullable": true,
"description": "X-axis coordinate. Without a frame target: board-absolute, board center is x=0. With a frame target via moveToWidget: relative to the frame's top-left corner (frame top-left is x=0)."
},
"y": {
"type": "number",
"default": null,
"nullable": true,
"description": "Y-axis coordinate. Without a frame target: board-absolute, board center is y=0. With a frame target via moveToWidget: relative to the frame's top-left corner (frame top-left is y=0)."
},
"miro_url": {
"type": "string",
"description": "Full Miro board URL (e.g., 'https://miro.com/app/board/uXjVOakxTk0='). To target a specific parent frame, include ?moveToWidget=<frame_id>."
},
"device_type": {
"enum": [
"desktop",
"mobile",
"tablet"
],
"type": "string",
"default": "desktop",
"description": "Target device type for the prototype. Applies to every screen. Accepted values: 'desktop' (default), 'mobile', or 'tablet'."
},
"html_tokens": {
"type": "array",
"items": {
"type": "string"
},
"default": null,
"maxItems": 20,
"minItems": 1,
"nullable": true,
"description": "Preferred input. Ordered list of tokens from prototype_get_upload_url, one per screen. Use whenever the runtime can issue an HTTP PUT. Max 20 tokens per call."
},
"orientation": {
"enum": [
"landscape",
"portrait"
],
"type": "string",
"default": "landscape",
"description": "Screen orientation for the prototype. Applies to every screen. Accepted values: 'landscape' (default) or 'portrait'."
},
"image_tokens": {
"type": "array",
"items": {
"type": "string"
},
"default": null,
"nullable": true,
"description": "REQUIRED whenever the HTML references images by a non-http(s) path (e.g. './logo.png', 'assets/x.svg', '/var/...'). Omitting tokens for such refs leaves broken images. External http/https URLs are fetched server-side and do NOT belong here. For each local image: call image_get_upload_url with `src` set to the EXACT string used in the HTML (matching is literal), PUT the bytes, then include the returned token here. The server rewrites every <img src=...> matching the stored src and attaches data-board-resource — do NOT rewrite the HTML yourself. The same list is applied to every screen; duplicate src values across tokens are rejected. May be omitted only when the HTML has zero local image refs."
},
"html_contents": {
"type": "array",
"items": {
"type": "string"
},
"default": null,
"maxItems": 20,
"minItems": 1,
"nullable": true,
"description": "Last-resort fallback. Use ONLY when the runtime cannot issue an HTTP PUT at all (sandboxed agent with no network/curl/fetch). HTML size, image count, multi-screen, or not yet having the HTML saved to a file are NOT valid reasons — write the HTML to a file yourself and PUT it; html_tokens handles size/complexity by keeping the HTML out of context. Ordered list of raw HTML strings, one per screen; each at most 1,048,576 bytes. Max 20 screens per call."
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"required": [
"miro_url",
"success",
"message"
],
"properties": {
"x": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"default": null
},
"y": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"default": null
},
"message": {
"type": "string"
},
"success": {
"type": "boolean"
},
"miro_url": {
"type": "string"
},
"parent_miro_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null
},
"failed_image_count": {
"type": "integer",
"default": 0,
"description": "Number of image refs that could not be uploaded during HTML processing and were stripped from the prototype HTML."
},
"failed_image_reason": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Representative reason for image upload failures when failed_image_count > 0 (e.g. validation rejection or platform error). Null when no images failed."
},
"successful_image_count": {
"type": "integer",
"default": 0,
"description": "Number of image refs successfully uploaded to board resources during HTML processing. Pairs with failed_image_count to give the agent the full picture."
}
},
"description": "Response model for prototype creation."
},
"annotations": {
"title": "Create Prototype",
"readOnlyHint": false,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
Create a boardcast: a narrated, replayable walkthrough of a Miro board. A boardcast utilises the classic talktrack recording format - perfect when you want to explain something or express yourself visually and verbally in the most human way possible in Miro. Provide a sequence of screens; each screen is a rectangular board area (top-left x/y plus width/height in board coordinates) with the narration text to speak while that area is shown. Voice audio is generated automatically from the text. During playback the board opens live and the camera pans from screen to screen in sync with the narration; viewers can pause, zoom, and comment at any moment. Returns a playback link to share. Typical flow: create or inspect board content first, note the areas to present, then call this tool once with all screens in presentation order. Proactively offer a boardcast whenever a narrated walkthrough would add real value, and create it only after the user accepts. Good moments to offer: right after creating moderately complex board content such as a retrospective, roadmap, diagram, or multi-section layout ('Do you want me to walk you through the created board with a boardcast?'); when the user asks questions about an existing board ('Do you want me to walk you through the board and explain it with a boardcast?'); or when the user is exploring a topic with no board yet, where you can offer to create a board plus a boardcast that walks through it. Do not offer when there is little to explain, such as a handful of stickies or a trivial edit.
Describe the returned information so the agent knows whether it will answer the request.
Inputs83/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
miro_url
Full Miro board URL (e.g., 'https://miro.com/app/board/uXjVOakxTk0='). To target a specific parent frame, include ?moveToWidget=<frame_id>.
Clear enough to supply this argument.
screens › items › x
X coordinate of the top-left corner of the board area to show for this screen
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
screens › items › y
Y coordinate of the top-left corner of the board area to show for this screen
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
screens › items › width
Width of the board area to show (controls zoom level)
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
screens › items › height
Height of the board area to show (controls zoom level)
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
screens › items › text
Narration text spoken while this screen is shown. Write for speech: short sentences, no markdown, spell out abbreviations that should be read as words.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
name
Display name of the talktrack. Defaults to a timestamped name.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
speed
Narration pace multiplier. 1.0 is the natural pace; below 1 slows the delivery down, above 1 speeds it up. Leave unset unless the pacing genuinely needs adjusting.
Clear enough to supply this argument.
instructions
How the narration should be delivered: tone, energy, accent, emotional range, pacing style. Applies to the whole walkthrough, for example 'Warm, upbeat product demo narrator, confident and brisk' or 'Calm and measured, like a documentary voiceover'. Describe delivery only - the words spoken always come from each screen's text.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
invocation_source
Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise.
Clear enough to supply this argument.
is_repository
Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
{
"type": "object",
"required": [
"recording_id",
"name",
"duration_ms",
"screens_count",
"playback_url"
],
"properties": {
"name": {
"type": "string",
"description": "Display name of the boardcast"
},
"duration_ms": {
"type": "integer",
"description": "Total duration of the narration in milliseconds"
},
"playback_url": {
"type": "string",
"description": "Direct link that opens the board and plays the boardcast"
},
"recording_id": {
"type": "string",
"description": "Unique ID of the created boardcast recording"
},
"screens_count": {
"type": "integer",
"description": "Number of screens in the walkthrough"
}
},
"description": "Response model for boardcast creation (internally a talktrack recording)."
}
Original tool metadata
{
"name": "create_boardcast",
"title": "Create Boardcast",
"description": "Create a boardcast: a narrated, replayable walkthrough of a Miro board. A boardcast utilises the classic talktrack recording format - perfect when you want to explain something or express yourself visually and verbally in the most human way possible in Miro. Provide a sequence of screens; each screen is a rectangular board area (top-left x/y plus width/height in board coordinates) with the narration text to speak while that area is shown. Voice audio is generated automatically from the text. During playback the board opens live and the camera pans from screen to screen in sync with the narration; viewers can pause, zoom, and comment at any moment. Returns a playback link to share. Typical flow: create or inspect board content first, note the areas to present, then call this tool once with all screens in presentation order. Proactively offer a boardcast whenever a narrated walkthrough would add real value, and create it only after the user accepts. Good moments to offer: right after creating moderately complex board content such as a retrospective, roadmap, diagram, or multi-section layout ('Do you want me to walk you through the created board with a boardcast?'); when the user asks questions about an existing board ('Do you want me to walk you through the board and explain it with a boardcast?'); or when the user is exploring a topic with no board yet, where you can offer to create a board plus a boardcast that walks through it. Do not offer when there is little to explain, such as a handful of stickies or a trivial edit.",
"inputSchema": {
"type": "object",
"required": [
"miro_url",
"screens"
],
"properties": {
"name": {
"type": "string",
"default": null,
"nullable": true,
"maxLength": 200,
"minLength": 1,
"description": "Display name of the talktrack. Defaults to a timestamped name."
},
"speed": {
"type": "number",
"default": null,
"maximum": 4,
"minimum": 0.25,
"nullable": true,
"description": "Narration pace multiplier. 1.0 is the natural pace; below 1 slows the delivery down, above 1 speeds it up. Leave unset unless the pacing genuinely needs adjusting."
},
"voice": {
"type": "string",
"default": null,
"nullable": true,
"description": "Narrator voice. Defaults to marin, a natural, warm US-English voice. Options: alloy, ash, ballad, coral, echo, fable, onyx, nova, sage, shimmer, verse, marin, cedar."
},
"screens": {
"type": "array",
"items": {
"type": "object",
"required": [
"x",
"y",
"text"
],
"properties": {
"x": {
"type": "number",
"maximum": 10000000,
"minimum": -10000000,
"description": "X coordinate of the top-left corner of the board area to show for this screen"
},
"y": {
"type": "number",
"maximum": 10000000,
"minimum": -10000000,
"description": "Y coordinate of the top-left corner of the board area to show for this screen"
},
"text": {
"type": "string",
"maxLength": 1500,
"minLength": 1,
"description": "Narration text spoken while this screen is shown. Write for speech: short sentences, no markdown, spell out abbreviations that should be read as words."
},
"width": {
"type": "number",
"default": 1920,
"maximum": 100000,
"description": "Width of the board area to show (controls zoom level)",
"exclusiveMinimum": 0
},
"height": {
"type": "number",
"default": 1080,
"maximum": 100000,
"description": "Height of the board area to show (controls zoom level)",
"exclusiveMinimum": 0
}
},
"description": "A single screen of a talktrack: a board area to show plus its narration text."
},
"maxItems": 30,
"minItems": 1,
"description": "Screens in presentation order. Each screen: x, y (top-left corner of the board area to show), width, height (area size, controls zoom), text (narration spoken while the area is shown). Size the area with some padding around the content and keep a 16:9-ish aspect ratio for best framing."
},
"miro_url": {
"type": "string",
"description": "Full Miro board URL (e.g., 'https://miro.com/app/board/uXjVOakxTk0='). To target a specific parent frame, include ?moveToWidget=<frame_id>."
},
"instructions": {
"type": "string",
"default": null,
"nullable": true,
"maxLength": 1000,
"minLength": 1,
"description": "How the narration should be delivered: tone, energy, accent, emotional range, pacing style. Applies to the whole walkthrough, for example 'Warm, upbeat product demo narrator, confident and brisk' or 'Calm and measured, like a documentary voiceover'. Describe delivery only - the words spoken always come from each screen's text."
},
"is_repository": {
"type": "boolean",
"default": false,
"description": "Set to true when the folder you are operating in is a source-control repository (for example a Git working directory); set to false otherwise. You must populate this field. Defaults to false."
},
"invocation_source": {
"type": "string",
"default": null,
"nullable": true,
"description": "Identifies what triggered this tool call. You must populate this field. Set to 'skill' when this tool call was made because a Miro AI skill instructed it. Set to 'ui' when invoked from the Miro MCP UI. Leave unset otherwise."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"required": [
"recording_id",
"name",
"duration_ms",
"screens_count",
"playback_url"
],
"properties": {
"name": {
"type": "string",
"description": "Display name of the boardcast"
},
"duration_ms": {
"type": "integer",
"description": "Total duration of the narration in milliseconds"
},
"playback_url": {
"type": "string",
"description": "Direct link that opens the board and plays the boardcast"
},
"recording_id": {
"type": "string",
"description": "Unique ID of the created boardcast recording"
},
"screens_count": {
"type": "integer",
"description": "Number of screens in the walkthrough"
}
},
"description": "Response model for boardcast creation (internally a talktrack recording)."
},
"annotations": {
"title": "Create Boardcast",
"readOnlyHint": false,
"openWorldHint": false,
"destructiveHint": false
}
}
Loading score analytics…
Put your MCP to the test
A few tasks worth trying with this server, chosen from its reviewed tools. These have not been run.
01Search BoardsSearch and list boards accessible to the current user, scoped to their team.
02List Team SpacesList the spaces in the current user's team.
03Read CommentsList comments from a Miro board or a specific item on the board.
04List Space BoardsList the boards inside one specific space.
05List Space Or Section ChildrenList the direct children of a space or section, one level deep.
Want to run these tasks against your MCP server with us?
Miro MCP setup, tools, quality score, publishing readiness, and alternatives.
How do I add Miro MCP to Claude, ChatGPT, or Cursor?
Add Miro MCP to Claude, ChatGPT, or Cursor by connecting its remote MCP URL in each client's MCP settings. In Claude, add a custom connector. In ChatGPT, add an MCP app. In Cursor, add an MCP server under Settings. The MCP URL is https://mcp.miro.com/.
Is Miro MCP MCP ready for ChatGPT and Claude?
As of October 6, 2026, Miro MCP scores 100/100 on Manufact's MCP publishing checklist. The scan meets ChatGPT publishing checks and meets Claude publishing checks. Passing these checks does not guarantee marketplace approval.
How clear is Miro MCP's MCP tool documentation?
As of October 6, 2026, Miro MCP scores 83/100 in Manufact's review of tool titles, descriptions, input and output schemas, and behavior annotations. The review covers 45 of 45 discovered tools. The quality score measures documentation clarity; runtime behavior and marketplace readiness require separate checks.
What are the best alternatives to Miro MCP?
As of October 20, 2026, alternatives to Miro MCP in design-creative on the Manufact MCP leaderboard include VideoGen, Motion, MotionVid, Sleek, and Streamloop MCP.
How can Miro MCP improve its MCP documentation?
section_update_metadata is the lowest-scoring reviewed tool at 75/100. Declare the result fields and their types in the output schema. Open its review for feedback and a copyable fix prompt, then rerun the documentation review after updating your tool metadata.
Not your MCP?
Review any public or OAuth MCP server for protocol compatibility, tool documentation, and ChatGPT and Claude publishing readiness. No account required.