- Brand
- Mural
- Category
- Productivity
- Primary Subcategory
- Whiteboards & Visual Collaboration Canvases
Integration details
Description
Connect ChatGPT to Mural to transform information from across your organization into clear, collaborative visual work. Create, read, and edit Mural boards for meeting facilitation, research synthesis, strategic planning, and communicating complex ideas.
- Integration type
- Plugin
- Verification status
- Not applicable
- Platform
- ChatGPT
- Primary Subcategory
- Whiteboards & Visual Collaboration Canvases
- Secondary Subcategories
- None listed
- Brand
- Mural
- Access
- Account required
- First tracked
- 2026-10-06
- Tool count
- 48
- Geography
- US
The Primary Subcategory used for this profile’s headline score.
Other Subcategories where the Integration is listed.
ChatGPT Plugin discovery is coming soon
ChatGPT can surface a Plugin when it matches a user's request.Your Plugin Discovery Score measures how often yours appears.
No spam. Unsubscribe any time.
What discovery looks like

Get alerts for Mural
Get updates when Mural’s Discoverability Score or category rank changes.
Competing in ChatGPT Whiteboards & Visual Collaboration Canvases
View Category48 tools agents can invoke
Attach a tag, also called a label, to one or more widgets. This is how a widget is labeled or classified without changing its text. If tag_id is provided, attaches that existing tag to the widgets. If tag_id is omitted, creates a new tag (text is required); the optional color_name selects a curated palette entry, and the optional icon_id gives the new tag an icon (get the id from `search_icons`). Use update_tags to rename, recolor, or change the icon of an existing tag, and delete_tags to remove a tag definition from the mural entirely. Requires a live browser tab connected to the bridge.
add_tag
Add a Mural template onto the canvas. The Mural app inserts the widgets itself, so the full layout (text, shapes, clusters, tables, photos, connectors) lands with full fidelity in one undoable action, alongside existing content — nothing is replaced. By default the template lands to the right of existing content (canvas origin when empty); pass both `x` and `y` to place its top-left corner explicitly. Returns the created `widget_ids`; fill the template in with the normal read and edit tools. Only templates from Mural's built-in library (including partner methods such as LUMA) can be added; workspace or custom template ids fail with an error. Requires a live browser tab connected to the bridge.
add_template_to_canvas
Add existing canvas widgets to the mural's presentation outline, at the end of it, in the order given. Use it whenever a request says which widgets should be the slides of a presentation, and in what order — the given order is the order they are added in. This is the one and only tool for putting something in the outline — use it whether you add one widget or many; they are all added in a single call. Outline items are ordinary widgets rather than separate objects, so this tool takes the ids of widgets that already exist on the canvas; it creates nothing. Areas are the usual choice (an area in the outline is what a presentation steps through as a slide), but stickies, shapes, titles, text, images and files can all be outline items. Groups, comments, connectors, tables and table cells cannot, matching in-app behavior; nor can a widget that is already in the outline, which is reported as a per-widget failure rather than moved. Adding to the outline requires the current participant to be a facilitator. The tool resolves their role itself and rejects the whole batch when they are not one. The response is a uniform envelope: `status: "ok"` (all added — `success: true`, with an `added` count), `status: "partial"` (some added, the rest in `failed` — `success: false`), or `status: "error"` (nothing added — `success: false` with an `error_code`). Retry only the `failed` entries. Requires a live browser tab connected to the bridge.
add_to_outline
Create area (frame) widgets on the canvas. Areas act as containers, but a widget only becomes a child that moves with the area when you set its `parent_id` to the area — pass `parent_id` when creating that widget (e.g. via `create_shapes`/`create_stickies`) or call `move_widgets_to_area` afterwards; placing a widget inside the bounds alone does not parent it. Size each area generously so its planned contents fit, and keep the top edge clear so the area's name stays legible. Pass `areas` as a list — always a list, even for one area. Each item is an object with numeric `x`, `y`, `width`, `height`, and an optional `title`. The response reports each area's id, position, and size, plus a `status` of ok/partial/error, `success`, and any failures in `failed` (each with the reason it failed). Requires a live browser tab connected to the bridge.
create_areas
Draw connectors (arrows) on the canvas. This is the one and only connector-creation tool — use it whether you need one connector or many (e.g. wiring up a whole flowchart); they are all created in a single call. Pass `connectors` as a list — always a list, even for a single connector (then it is a one-element list). Each item connects a source widget to one target and is one of two shapes: widget → widget {"start_widget_id": string, "end_widget_id": string} — the arrow is anchored to both widgets and stays attached when either moves. widget → point {"start_widget_id": string, "end_x": float, "end_y": float} — the tail is anchored to the source widget; the arrowhead floats freely at the given canvas coordinate (use this for an open-ended flow, a pending connection, or to point at empty space). Give exactly one target per connector (either end_widget_id or both end_x and end_y, not both). Each item may also set an optional `arrow_type`: 'straight' (direct line, default), 'orthogonal' (right-angle elbow), 'curve' (smooth curve), or 'bezier' (cubic bezier). Each item may also set an optional `text`: plain text shown on the connector, auto-centered (not Markdown). On a Mural build without connector label support the connector is created without it; the response does not confirm the label, so read it back (list_widgets) if it matters. The response is a uniform envelope: `status: "ok"` (all created — `success: true`, each connector's id in `connectors`), `status: "partial"` (some created, the rest in `failed` — `success: false`), or `status: "error"` (none created — `success: false` with an `error_code`). Each `failed` entry carries the reason it failed. Requires a live browser tab connected to the bridge.
create_connectors
Place Noun Project icons (MURAL `sticker` widgets) on the canvas. Use the `id` from a `search_icons` result as each item's `noun_project_id`, and pass that result's `tags` so the icon stays identifiable in later canvas reads. Pass `icons` as a list — always a list, even for one icon. Each item is an object with a `noun_project_id`, numeric `x`, `y`, and optional `width` (default 100), `height` (default 100), `color` (hex tint), `tags` (list of strings), and `parent_id` (an area to nest the icon in). The response reports each icon's id, position, size, and its `noun_project_id`/`tags`, plus a `status` of ok/partial/error, `success`, and any failures in `failed` (each with the reason it failed). Requires a live browser tab connected to the bridge.
create_icons
Create a new blank mural (whiteboard) inside a specific room. Prefer passing room_id when you have it (it is in the room URL and identifies the room unambiguously, since room names are not unique). Otherwise pass workspace_name and room_name as human-readable names, not IDs; when the exact names are unknown, list_workspaces resolves the workspace name and list_rooms resolves the room name. A workspace_id from either of those tools can stand in for workspace_name. On success, returns mural_id, and member_url when the mural's URL can be resolved — the link to open it in a browser. The other canvas tools (get_mural_info, list_widgets, create_stickies, etc.) operate on a mural only once it is open in a browser tab.
create_mural
Batch-create shape widgets; pass `shapes` as a list (one or many, in a single call). Each item has numeric `x`, `y` (top-left), `width`, `height`, and a `shape_type` from one of two libraries: Smart (snake_case, preferred — refined rendering): arrow_down, arrow_left, arrow_left_right, arrow_right, arrow_top, badge, brace_left, brace_right, chonk_unicorn, cloud, connector, cross, data, database, decision, delay, direct_data, display, document, ellipse, end, hexagon_smart, internal_storage, manual_input, manual_loop, merge, multiple_documents, note_left, note_right, octagon, off_page_connector, or, papertape, pentagon_smart, porongo, predefined_process, preparation, process, rectangle, rhombus_smart, ribbon, right_triangle, rounded_square, simple_ribbon, speech_bubble_center, speech_bubble_left, speech_bubble_right, star, start, step, stored_data, summing_junction, teardrop_bubble, terminator, thinking_bubble_left, thinking_bubble_right, trapezoid, triangle_smart. Legacy (PascalCase, classic): Circle, Data, Database, Decision, Delay, Diamond, Display, DocumentShape, EventShape, Hexagon, LoopLimit, ManualInput, ManualLoop, Merge, OffPageConnector, OffPageReference, OffPageReferenceIncoming, Pentagon, Preparation, Square, Terminator, Triangle. Common picks: `rectangle`, `ellipse`, `rounded_square`, `star`, `cloud`, `speech_bubble_center`; `process`, `decision`, `start`, `end`, `data`, `document` for flowcharts. A few names exist in both libraries (e.g. `Triangle` vs `triangle_smart`) — pick the namespace matching the look you want. Concepts with no name of their own: a flowchart cylinder is `database`, a rounded rectangle is `rounded_square`, an oval is `ellipse`, and a true circle is legacy `Circle`. Optional per item (omit for SDK defaults): `background_color`, `stroke_color` (hex), `stroke_size` (px), `stroke_style` ('', '.', '-', '. ', 'solid', 'dotted'; 'dashed'/'dotted-spaced' also accepted); `rotation` (deg), `stacking_order`; `text` (Markdown) with `text_color`, `font_size`, `font_family`, `text_align` ('left'|'center'|'right'), `vertical_align` ('top'|'middle'|'bottom'); `locked`, `hidden`, `title`, `instruction`, `parent_id` (containing area). Supported Markdown in `text`: **bold**, *italic*, bulleted/numbered lists, and links; headings render as bold text. Code blocks, blockquotes, and `---` rules are not rendered. No opacity prop — use the hex alpha channel. Shapes are visual backdrops, not containers. A legacy name may be written with a lowercase first letter (`circle` for `Circle`); every other `shape_type` has to match a name above exactly. One that matches none is rejected up front: MURAL cannot resolve a name it does not know, so the shape would not render and would not survive a reload. Such a call creates nothing, and the error names the unrecognized values (a sample when there are many) along with the valid ones. The response reports each shape's id, position, and size, plus a `status` of ok/partial/error, `success`, and any failures in `failed` (each with the reason it failed). Requires a live browser tab connected to the bridge.
create_shapes
Create sticky notes on the canvas. This is the one and only sticky-creation tool — use it whether you need one sticky or hundreds (e.g. turning a list of items, tickets, or ideas into stickies); they are all created in a single call. Pass `stickies` as a list — always a list, even for a single sticky (then it is a one-element list). Each item is an object {"x": float, "y": float, "text"?: string (Markdown — plain text is valid Markdown), "background_color"?: hex like '#fcf281'}. Whole-widget restyle (bold/color/…) is applied after creation via update_widgets. Supported Markdown in `text`: **bold**, *italic*, bulleted/numbered lists, and links; headings render as bold text. Code blocks, blockquotes, and `---` rules are not rendered. Give each sticky the position you want — any sticky that would collide with existing content or another sticky in this batch is nudged to the nearest free spot, so a rough grid is fine. Areas and shapes never block: stickies aimed inside them stay put. Pass `parent_id` to place every sticky inside an area (they become its children and move with it); x/y are given as absolute canvas coordinates at creation, but once parented they are stored and read back area-relative. The response reports each sticky's final position, size, and id (a nudged sticky also carries its original coordinates as `requested_x`/`requested_y`), plus a `status` of ok/partial/error, `success`, and any failures in `failed`. A failure carrying the widget's `id` means that sticky was created but its text did not land: fix it with `update_widgets` rather than retrying, which would leave the blank one behind. A failure without one was never created, so retry it. Requires a live browser tab connected to the bridge.
create_stickies
Create a table widget on the canvas and, optionally, populate its cells in one call. Specify `rows` and `columns` (each >= 1) and pass `cell_content` as a row-major 2D array to fill cells, with the header row first. Cell content is Markdown; supported: **bold**, *italic*, bulleted/numbered lists, and links; Code blocks, blockquotes, and `---` rules are not rendered. Rows auto-size to fit their text so content never overflows; `column_widths`, `row_heights`, and `cell_font_size` override the sizing. Pass `parent_id` to nest the table inside an area so it moves with the area. Requires a live browser tab connected to the bridge.
create_table
Create textbox (a.k.a. paragraph) widgets on the canvas. In MURAL's UI this widget is labelled 'Paragraph'. It handles requests to add paragraphs, blocks of body text, or fixed-width text widgets that aren't headings/titles or stickies. For auto-resizing headings use `create_titles`; for sticky notes use `create_stickies`. Pass `textboxes` as a list — always a list, even for one textbox. Each item is an object with numeric `x`, `y` plus optional `text`, `width`, `height`, `font_size`, `font_color` (hex), and `parent_id` (an area to nest it in). `width` is honored, but `height` auto-fits to the text (the read-back height reflects the content, not the value you passed). `text` is Markdown (plain text is valid Markdown). Supported Markdown: **bold**, *italic*, bulleted/numbered lists, and links; headings render as bold text. Code blocks, blockquotes, and `---` rules are not rendered. Use inline Markdown only to emphasize part of the text. To emphasize the whole textbox, set the restyle flags `bold`, `italic`, `strike`, `underline` to true and leave `text` plain — do not wrap the entire string in Markdown. Textboxes are created exactly at the requested position. The response reports each textbox's id, position, and size, plus a `status` of ok/partial/error, `success`, and any failures in `failed` (each with the reason it failed). Requires a live browser tab connected to the bridge.
create_textboxes
Create title widgets on the canvas. Titles are MURAL's section-headline widget — visually similar to a textbox but with an auto-resizing width by default and decoration props (corner radius, custom border, shadow) that textboxes don't have. Use titles for slide headings, section banners, and other prominent labels. Pass `titles` as a list — always a list, even for one title. Each item is an object with numeric `x`, `y` plus optional styling/state fields; omit them for SDK defaults (large font, no border, no shadow). Text: `text` (Markdown — plain text is valid Markdown), `font_size`, `font_family`, `font_color` (hex), `text_align` ('left'|'center'|'right'). Supported Markdown in `text`: **bold**, *italic*, bulleted/numbered lists, and links; headings render as bold text. Code blocks, blockquotes, and `---` rules are not rendered. Use inline Markdown only to emphasize part of the text. To emphasize the whole title, set the restyle flags `bold`, `italic`, `underline`, `strike` to true and leave `text` plain — do not wrap the entire string in Markdown. Box/decoration: `width`, `height`, `fixed_width` (pin to `width`; ignored without a `width`), `background_color`, `border`, `border_color`, `border_thickness`, `corner_radius`, `shadow`. Transform/layering: `rotation`, `stacking_order`. State/metadata: `locked`, `hidden`, `title`, `instruction`, `parent_id`. Titles are created exactly at the requested position. The response reports each title's id, position, and size, plus a `status` of ok/partial/error, `success`, and any failures in `failed` (each with the reason it failed). Requires a live browser tab connected to the bridge.
create_titles
Delete tag definitions from the mural by id, also detaching them from any widgets. This is the one and only tag-deletion tool — use it whether you delete one tag or many; they are all removed in a single call. Use remove_tag to detach a tag from specific widgets while keeping the definition. Pass `tag_ids` as a list — always a list, even for a single tag (then it is a one-element list). Deleting a tag id that does not exist (or was already deleted) is treated as a successful no-op. The response is a uniform envelope: `status: "ok"` (all deleted — `success: true`, with a `deleted` count), `status: "partial"` (some deleted, the rest in `failed` — `success: false`), or `status: "error"` (nothing deleted — `success: false` with an `error_code`). Retry only the `failed` entries. Requires a live browser tab connected to the bridge.
delete_tags
Delete widgets from the canvas by id. This is the one and only widget deletion tool — use it whether you need to delete one widget or many; they are all removed in a single call. Works for any widget type (sticky, area, text, shape, etc.). Pass `widget_ids` as a list — always a list, even for a single widget (then it is a one-element list). The ids come from list_widgets. Deleting an area removes the widgets inside it too by default; pass delete_contents=false to delete only the areas and keep their widgets (the flag applies to every area in the batch). This action cannot be undone through the MCP server. The response is a uniform envelope: `status: "ok"` (all deleted — `success: true`, with a `deleted` count), or `status: "error"` (nothing deleted — `success: false` with an `error_code`; when the delete call itself fails, every id is also listed in `failed`). The `deleted` count reflects the ids submitted, not a check that each existed — an unknown or already-deleted id is counted and not reported as a failure; list_widgets shows which ids currently exist. Requires a live browser tab connected to the bridge.
delete_widgets
Get a compact, token-bounded overview of a canvas: total widget count, counts by type, overall bounding box, top-level widget count, and a list of areas with their titles. Answers structural questions about a canvas ("what types of widgets exist?", "how big is it?", "what areas exist?") — it returns counts and metadata, not widget content, and costs a fraction of `list_widgets` or `get_document_tree`. Requires a live browser tab connected to the bridge.
get_canvas_overview
Capture the entire Mural canvas as a single image. Returns an MCP image content block containing the full-canvas PNG. Use only when you need a full-canvas view — overall board layout, holistic visual overview, or content spanning the entire canvas. Prefer list_widgets for structured data or get_viewport_screenshot for targeted visual detail, as those are faster and cheaper. The image is rendered by the export service from persisted widget data rather than by the browser, so it can lag a just-created, moved, or deleted widget until that write is persisted; a structured read (list_widgets) reflects such edits immediately. Unlike get_widgets_screenshot and get_viewport_screenshot it does render the text of a widget someone is typing in, up to their last persisted keystroke. Requires a live browser tab connected to the bridge.
get_canvas_screenshot
Get a hierarchical document tree of canvas widgets. Areas contain their child widgets in a 'children' array. Top-level widgets (not inside any area) appear at the root. Each node carries the same per-widget fields as list_widgets (controlled by `view`) plus parent_id and children. For high-level structure questions ("what areas exist?", "what types of widgets are in this mural?"), `get_canvas_overview` returns counts and metadata without fetching the tree. This tool provides the full board tree or a subtree you need to traverse — e.g. 'show me everything nested under the "Planning" area'. For one widget's direct relations (children, arrows, comments), `get_widget_relations` is faster and scoped to a single widget. When using `root_id`, resolve names to ids via `get_canvas_overview`. Prefer `view="compact"` for structure or content queries — it's ~half the payload of `full`. Use `view="full"` (the default) when you need geometry, color, or lock state. Requires a live browser tab connected to the bridge.
get_document_tree
Get the current sharing permissions for the Mural — the access level granted to visitors and to workspace members. Returns {visitors, workspace_members} where each value is one of 'none', 'read', or 'write'.
get_mural_access_info
Get metadata for the current Mural (board), such as identifiers and title. Use when the agent needs mural context (which board is open). Response uses snake_case fields.
get_mural_info
Read the full text of a skill guide by its skill_id. Valid skill_ids are those returned by `list_skills`.
get_skill
Capture a raster image of an explicit Mural canvas region. When the headless Canvas Host is enabled, `region` is required and the image comes from the backend export worker without reading a human camera. In browser-bridge mode the tool captures the user's current viewport and an explicit `region` is not supported (it returns an error). For structured content, prefer `list_widgets` with `aabb` or `list_widgets_near`; they are faster and need no vision. Set max_output_dimension to the longest image side (in pixels) the caller's vision model can tokenize. Override output_width/output_height only when you need a specific output box; both values must be <= max_output_dimension. The headless worker preserves the region aspect ratio within that box. Returns an MCP image content block followed by a JSON text block with fidelity metadata - exported region and effective_pixels_per_unit. In browser-bridge mode the image reflects the tab's current render and can briefly lag a just-created, moved, or deleted widget; a structured read (list_widgets_in_viewport) reflects such edits immediately. That render also omits the text of a widget someone is currently typing in, so a blank card is not evidence of a failed write: list_widgets and get_widget_by_id are authoritative for text, and list_selected_widgets flags such a widget with `editing: true`.
get_viewport_screenshot
Get the widgets related to a single widget, as structured data. Given a `widget_id`, this returns five relation sets scoped to that widget: connected_arrows — arrows attached to the widget children — widgets directly nested in it (area/table members) descendants — all widgets nested beneath it, transitively related_comments — comments anchored to it parts_of — containers this widget is a member of Answers relationship questions ('what's connected to this shape?', 'what's inside this area?', 'what comments are on this sticky?') when you have the widget id, more directly than `get_document_tree` or `list_widgets`. Each set is `[]` when the widget has no relations of that kind. An unknown `widget_id` returns an error (not empty sets). Requires a live browser tab connected to the bridge.
get_widget_relations
Get one widget's full state by id, in the SDK's raw camelCase shape (`backgroundColor`, `parentId`, `x`/`y`) — this differs from the snake_case that list_widgets and get_document_tree return, so prefer those when you want the normalized shape. For connectors, `startRefId` is the source widget and `endRefId` is the destination (the widget the arrowhead points at), consistent with `create_connectors` and `update_widgets`. Returns `{widget: null}` for an unknown id. Requires a live browser tab connected to the bridge.
get_widget_by_id
Capture a raster screenshot of specific widgets by id so you can see them — photos, images, drawings, icons, diagrams, handwriting, or any widget whose *visual* appearance or spatial layout matters. For text, ids, types, or positions alone, list_widgets is faster and needs no vision. Set max_output_dimension to the longest image side (px) your vision model can tokenize; override output_width/output_height only for a specific output box, both <= max_output_dimension (the headless worker preserves the selection aspect ratio within that box). Returns an image block plus metadata (region, effective_pixels_per_unit); a low effective_pixels_per_unit means text may be illegible, so screenshot fewer or closer-together widgets. When none of the ids are found the call errors, and ids that aren't found are silently omitted from the image — get_canvas_screenshot covers the whole board. A container id — an area or a table — also draws everything nested inside it, and metadata.container_expansion reports how many widgets that added. In browser-bridge mode, widgets outside the user's loaded viewport (including just-created ones) may not be captured though they exist, and a widget someone is currently typing in renders without its text: a blank card is not evidence of a failed write. list_widgets and get_widget_by_id are authoritative for text, and list_selected_widgets flags such a widget with `editing: true`. With the headless Canvas Host, the backend export worker resolves each widget's absolute bounds and renders the explicit selection without a browser or human viewport.
get_widgets_screenshot
Invite people to collaborate on a mural by email. Each invitee is granted either 'view' (read-only) or 'edit' access. Requires a mural you have permission to manage. Per-invitee problems (invalid email, already a member, blocked by company policy) come back in the 'rejected' list rather than failing the whole call. Optionally include a personal 'message' and control whether an invitation email is sent with 'send_email'.
invite_users_to_mural
List the mural's presentation outline — the ordered items shown in the outline panel and stepped through in presentation mode. Returns one entry per item with `position`, `widget_id`, `widget_type`, `title`, and `is_hidden`, in outline order. Outline items are ordinary canvas widgets (most often areas, but stickies, shapes, images and files can all be in the outline), so each `widget_id` also works with the other canvas tools. `position` is a 0-based ordinal over the items returned here, not a stored property of the widget: it is contiguous even though the underlying order values are not. An empty `title` means the item is unnamed — the outline panel displays such an item as "Unnamed <type>", for example "Unnamed area". Returns an empty list when the mural has no outline. Requires a live browser tab connected to the bridge.
list_outline
List the rooms inside a MURAL workspace, excluding the ones the user is not a member of. Returns each room's exact name and id, which create_mural uses to resolve a room by name, plus is_member, can_create_murals, and type. create_mural needs a room with can_create_murals true; is_member is not enough — a member with access to only some of a room's murals, or without create permission, is still rejected. A workspace also contains rooms the user can see but is not a member of; create_mural rejects those, so they are left out unless include_all_rooms is set and hidden_non_member_rooms reports how many were withheld. Only a room reported as not a member is withheld: is_member null means the workspace did not report it readably, and those rooms are listed rather than hidden.
list_rooms
List the currently selected widgets on the canvas. Returns per-widget fields controlled by `view` (see `view` parameter); `parent_id` / `children` are not included — selection is flat. Use when the user refers to 'selected' items or the agent needs what is highlighted. A headless context has no human selection, so it returns an explicit empty selection with an explanatory message. Browser-bridge mode reads the live human selection. A widget the user is currently typing in carries `editing: true` on top of the `view` fields, in either view; its text is missing from a get_widgets_screenshot or get_viewport_screenshot image, so `get_widget_by_id` is the reliable read for it; get_canvas_screenshot renders it.
list_selected_widgets
List the skill guides available on this MCP server. Returns one [skill_id, description] pair per skill. Pass a skill_id to `get_skill` to read that guide's full text.
list_skills
List the tags defined on the mural, with the widget ids each tag is attached to. Returns name, color, optional icon, and widget_ids per tag. Surfaces existing tags (reusable with add_tag) and the widgets carrying a specific tag. Requires a live browser tab connected to the bridge.
list_tags
List widgets on the canvas (stickies, shapes, text, etc.) as a semantic snapshot. This is the broad, whole-board fallback — before reaching for it, check whether a narrower, cheaper tool answers the actual question (this tool's cost grows with the widget count; the others below do not): • counts, types, size, or the list of areas → `get_canvas_overview` (cheapest; no widget content) • one widget's arrows, children, or containing area/table → `get_widget_relations` • the nesting hierarchy (what is inside what) → `get_document_tree` • widgets around a given widget → `list_widgets_near` • what is on the user's screen right now → `list_widgets_in_viewport` • the widgets the user has selected → `list_selected_widgets` • one widget you already have the id for → `get_widget_by_id` Use `list_widgets` when you genuinely need every widget (or every widget in a region): omit `aabb` to list the whole board, or pass an `aabb` region to list only the widgets in that rectangle. Prefer `view="compact"` (widget_id, widget_type, text) for content queries like 'find the sticky about X' — it's ~half the payload of `full`. Use `view="full"` (the default) when you need geometry, color, or lock state. Pass `widget_types` to return only certain kinds of widget (e.g. just areas or connectors). Requires a live browser tab connected to the bridge.
list_widgets
List the widgets near an anchor widget, as structured data. Given an anchor `widget_id` and a `radius` in canvas pixels, this reads the anchor's bounding box, expands that box by `radius` px on each side (a box, not a circle), and returns all widgets that overlap the expanded region — including partial overlaps — with the anchor itself excluded. Use this to answer proximity questions ('what's next to this sticky?', 'what surrounds this shape?') without reading the whole board; for the entire canvas use `list_widgets`. Returns `{"widgets": []}` when nothing else is in range. An unknown `widget_id` returns an error (not an empty list).Requires a live browser tab connected to the bridge.
list_widgets_near
List the widgets currently visible in the user's browser viewport, as structured data (not an image). Best when the answer is about content: what's on screen, summarizing the current view, or the text, types, ids, or positions of visible widgets; it is faster and needs no vision. `get_viewport_screenshot` fits instead when visual appearance or spatial layout matters and structured data cannot convey it. Returns only the widgets in the visible region, not a full-board listing — for the whole board use `list_widgets`. May return nothing if the viewport is blank or zoomed onto empty canvas, which does NOT mean the board is empty. Per-widget fields are controlled by `view` (default `"full"`; use `"compact"` — widget_id, widget_type, text — for lighter content queries). This tool is deliberately unavailable with the headless Canvas Host because there is no human camera. Use `list_widgets` with an explicit `aabb`, or `list_widgets_near` with an anchor and radius.
list_widgets_in_viewport
List all MURAL workspaces the current user has access to. Returns each workspace's exact name and id. When creating a mural by name, create_mural locates the workspace from either the workspace_name or the id returned here, passed as workspace_id.
list_workspaces
Lock widgets on the canvas by id. This is the one and only locking tool — use it whether you lock one widget or many; they are all locked in a single call. Pass `widget_ids` as a list — always a list, even for a single widget (then it is a one-element list). `lock_type` applies to the whole batch; there are two kinds of lock: standard — any member can unlock it later. facilitator — only facilitators can unlock it later. The lock kind depends on the user's role: facilitators can apply either a standard or a facilitator lock, while non-facilitators can apply only a standard lock. The tool resolves the current participant's role itself and rejects a facilitator lock when they are not a facilitator. Locking a group also locks its children, matching in-app behavior. Locking an area locks only the area itself, not its children. Locking a table locks the table and its table cells. The response is a uniform envelope: `status: "ok"` (all locked — `success: true`, with a `locked` count), `status: "partial"` (some locked, the rest in `failed` — `success: false`), or `status: "error"` (nothing locked — `success: false` with an `error_code`). Retry only the `failed` entries. Requires a live browser tab connected to the bridge.
lock_widgets
Move widgets into areas, making each a child of its target area so it moves with the area when the area is repositioned. This is the one and only move-to-area tool — use it whether you move one widget or many. Pass `moves` as a list; each item is {"widget_id": string, "area_id": string}. A single move is a one-element list ([{"widget_id": ..., "area_id": ...}]). To move many widgets into one area, repeat that area_id across the items. Widgets are placed at the area's center, spiralling outward to avoid stacking on existing children or on each other. Widget ids come from list_widgets or get_document_tree; area ids also appear in get_canvas_overview. Unknown widget/area ids, or a target that is not an area, are rejected per item and reported in the response's `failed` array; the rest of the batch still applies. The response is a uniform envelope: `status: "ok"` (all moved — `success: true`), `status: "partial"` (some moved, the rest in `failed` — `success: false`), or `status: "error"` (none moved — `success: false` with an `error_code`). Retry only the `failed` entries. Requires a live browser tab connected to the bridge.
move_widgets_to_area
Detach a tag from one or more widgets. The tag definition itself stays; use delete_tags to remove a tag from the mural entirely. Requires a live browser tab connected to the bridge.
remove_tag
Remove items from the mural's presentation outline. This is the one and only tool for taking something out of the outline — use it whether you remove one item or many; they are all removed in a single call. Removing every item is how an outline is cleared. Outline items are ordinary widgets, so this only takes them out of the outline: the widget stays on the canvas untouched. A widget that is not currently in the outline is reported as a per-widget failure rather than silently ignored. Removing an item also un-hides it. An outline item can be hidden from the canvas while it is in the outline; taking it out of the outline makes it visible again, because a hidden widget outside the outline would be unreachable. Removing from the outline requires the current participant to be a facilitator. The tool resolves their role itself and rejects the whole batch when they are not one. The response is a uniform envelope: `status: "ok"` (all removed — `success: true`, with a `removed` count), `status: "partial"` (some removed, the rest in `failed` — `success: false`), or `status: "error"` (nothing removed — `success: false` with an `error_code`). Retry only the `failed` entries. Requires a live browser tab connected to the bridge.
remove_from_outline
Rename items in the mural's presentation outline — the label the outline panel shows for an item, which is the widget's title. This is the one and only tool for renaming outline items — use it whether you rename one item or many; they are all renamed in a single call. Pass `renames` as a list; each item is {"widget_id": string, "title": string}. A single rename is a one-element list. Widget ids come from `list_outline`. This tool only renames widgets that are currently in the outline; a widget outside it is reported as a per-widget failure. Renaming a widget that is not an outline item is what `update_widgets` does, and the two are not interchangeable. Renaming an outline item requires the current participant to be a facilitator. The tool resolves their role itself and rejects the whole batch when they are not one. An empty `title` clears the item's name rather than being rejected. The outline panel then displays the item as "Unnamed <type>", for example "Unnamed area", while the stored title is empty — which is what `list_outline` reports. The response is a uniform envelope: `status: "ok"` (all renamed — `success: true`, with a `renamed` count), `status: "partial"` (some renamed, the rest in `failed` — `success: false`), or `status: "error"` (nothing renamed — `success: false` with an `error_code`). Retry only the `failed` entries. Requires a live browser tab connected to the bridge.
rename_outline_item
Search the Noun Project icon library. Returns matching icons, each with ``id`` (pass to ``create_icons`` as an item's ``noun_project_id``), ``tags`` (descriptive keywords for the icon; the first is the most representative), and ``preview_data_url`` (base64 PNG — inspect to pick the best match; if ``preview_failed`` is true, rely on tags instead).
search_icons
Search Mural's built-in template library (including partner methods such as LUMA). Keyword search over title and description via `query`; omit `query` to browse. Returns matches with `template_id` and `public_hash` — pass both to `add_template_to_canvas` to insert one. Page with `offset` when `next_offset` is present. Keyword search inspects at most 100 matches; `truncated: true` on the last page means results were cut off at that cap — refine `query` to see the rest.
search_templates
Discover or set the active mural for this MCP session. Call with no arguments to list candidates; call with ``mural_id`` to make a specific mural the active selection. Not needed when the request already names a mural id: every canvas tool accepts ``mural_id`` directly, so pass it to the tool that does the work.
select_mural
Reorder the items already in the mural's presentation outline. This tool only reorders what is already there: it cannot put a widget into the outline. When the widgets are not in the outline yet — including a request that says which widgets should be the slides of a presentation, in what order — use add_to_outline instead, which appends them in the order given. This is the one and only tool for changing outline order — the whole outline is reordered in a single call, whether one item moved or all of them. `widget_ids` is the complete outline in its new order: every item currently in the outline, exactly once. The ids and their present order come from list_outline; the way to move an item is to echo that list back with the item in its new place. This tool only reorders. It cannot put a widget into the outline (add_to_outline) or take one out (remove_from_outline), so the set of items is the same before and after. Reordering the outline requires the current participant to be a facilitator. The tool resolves their role itself and rejects the request when they are not one. The response is a uniform envelope: `status: "ok"` (reordered — `success: true`, with a `reordered` count) or `status: "error"` (nothing reordered — `success: false` with an `error_code`; when the reorder call itself fails, every id is also listed in `failed`). Reordering is all-or-nothing: there is no partial result. Requires a live browser tab connected to the bridge.
set_outline_order
Returns step-by-step recovery guidance for failed Mural canvas tool calls, covering the common failure modes: unknown/stale tool names, connectivity/bridge errors, auth and access failures, view-only and archived refusals, no-mural-selected, concurrency limits, and screenshot and per-tool failures. Also covers a call that succeeds but reads as a failure: a widget that comes back blank in a screenshot, or an area that comes back empty. Errors surface as a raised tool error, as a `success: false` result dict with an `error_code`, or as an "Unknown tool" error this server raises while resolving the name. Convenience wrapper for `get_skill("troubleshooting")`.
troubleshoot
Unlock widgets on the canvas by id. This is the one and only unlocking tool — use it whether you unlock one widget or many; they are all unlocked in a single call. Works for both standard-locked and facilitator-locked widgets. Pass `widget_ids` as a list — always a list, even for a single widget (then it is a one-element list). A facilitator-locked widget can only be unlocked by a facilitator; the tool verifies this and rejects those widgets per item, while the rest of the batch still unlocks. Unlocking a group also unlocks its children, matching in-app behavior. Unlocking an area unlocks only the area itself, not its children. Unlocking a table unlocks the table and its table cells. The response is a uniform envelope: `status: "ok"` (all unlocked — `success: true`, with an `unlocked` count), `status: "partial"` (some unlocked, the rest in `failed` — `success: false`), or `status: "error"` (nothing unlocked — `success: false` with an `error_code`). Retry only the `failed` entries. Requires a live browser tab connected to the bridge.
unlock_widgets
Update settings for the current mural: Title, background color, canvas size, timer sound, and visitor avatar theme. Only provided parameters are changed. Changes persist through the Mural public API and stay synchronized with the active canvas context. Only facilitators may change settings; the tool verifies this and rejects the call if the current participant is not a facilitator.
update_mural_settings
Update tag definitions' text, color, or icon. This is the one and only tag-update tool — use it whether you update one tag or many; they are all updated in a single call. Only the fields you pass on an item are changed; the rest of that tag's definition is preserved. Pass `updates` as a list — always a list, even for a single tag (then it is a one-element list). Each item is an object with a required `tag_id` plus at least one of: text — new label text. color_name — a curated MURAL tag color; one of: watermelon, peach, banana, mint, lime, blueberry, raspberry, grape, snowberry. icon_id — an icon id (from `search_icons`) to add or replace the tag's icon. remove_icon — pass true to clear the tag's icon (cannot be combined with icon_id). The response is a uniform envelope: `status: "ok"` (all updated — `success: true`, with an `updated` count and the per-tag results in `tags`), `status: "partial"` (some updated, the rest in `failed` — `success: false`), or `status: "error"` (nothing updated — `success: false` with an `error_code`). Retry only the `failed` entries. Requires a live browser tab connected to the bridge.
update_tags
Update fields on existing widgets in place (area, arrow, shape, sticky note, textbox, title). Pass `updates` as a list of {"widget_id": string, "values": object}; `values` is a flat patch — only the fields you include change. Field names are camelCase, but snake_case keys are auto-converted, so `backgroundColor` and `background_color` both work. The real trap is positional: the read-back names `position_x`/`position_y` are NOT valid fields — write `x`/`y` (and `width`/`height`) instead. For a widget with a `parentId`, `x`/`y` are relative to that parent (matching read-back), not absolute canvas coordinates — absolute coordinates apply only to unparented widgets, and a position outside the parent's bounds can silently detach the widget (`parentId` becomes null). Unknown fields or an unknown widget_id are rejected per item into the `failed` array (response `status: "partial"`, `success: false`); the rest still apply. Retry only `failed` — its per-item error lists the allowed fields. A connector whose `points` the canvas re-derived is named in an `adjusted` array, present only when it happened. That item still updated — every other field in its patch applied — so it is not a failure and must not be retried as one; only its path differs from what you sent. Check `adjusted` after any patch carrying `points`. Set `text` (Markdown) to replace a widget's content. Supported Markdown: **bold**, *italic*, bulleted/numbered lists, and links; headings render as bold text. Code blocks, blockquotes, and `---` rules are not rendered. On a connector, `text` is the connector label as a plain string (not Markdown); null clears it. The whole-widget restyle flags `bold`, `italic`, `underline`, `strike`, `color` (hex) reformat existing content on the text widgets (sticky, shape, title, textbox) and are update-only. `backgroundColor` is top-level (never nested under "style"). Sizing interacts with `text`. On a sticky, setting `text` re-fits the font to the new content, so a `fontSize` in the same patch is overwritten — send `fontSize` in a second, text-free call to make it stick. On a textbox or title, `fontSize` applies and `height` is always recomputed from the text; `width` is honored when the widget is fixed-width (textboxes are by default, titles only with `fixedWidth: true`) and recomputed from the text otherwise. Tags (i.e. labels): managed by the dedicated tag tools (add_tag, remove_tag), not this tool. Links: to make text clickable, write a Markdown inline link in `text` (a widget-level `link` field is rejected). Fields by type (each also takes the common set): common: x, y, width, height, rotation, hidden, locked, parentId (null detaches), title, instruction sticky: backgroundColor, text, border, round, minLines, fontFamily, fontSize, textAlign, verticalAlign shape: shapeType — smart (snake_case): arrow_down, arrow_left, arrow_left_right, arrow_right, arrow_top, badge, brace_left, brace_right, chonk_unicorn, cloud, connector, cross, data, database, decision, delay, direct_data, display, document, ellipse, end, hexagon_smart, internal_storage, manual_input, manual_loop, merge, multiple_documents, note_left, note_right, octagon, off_page_connector, or, papertape, pentagon_smart, porongo, predefined_process, preparation, process, rectangle, rhombus_smart, ribbon, right_triangle, rounded_square, simple_ribbon, speech_bubble_center, speech_bubble_left, speech_bubble_right, star, start, step, stored_data, summing_junction, teardrop_bubble, terminator, thinking_bubble_left, thinking_bubble_right, trapezoid, triangle_smart; legacy (PascalCase, also accepted with a lowercase first letter): Circle, Data, Database, Decision, Delay, Diamond, Display, DocumentShape, EventShape, Hexagon, LoopLimit, ManualInput, ManualLoop, Merge, OffPageConnector, OffPageReference, OffPageReferenceIncoming, Pentagon, Preparation, Square, Terminator, Triangle. A name outside both fails that widget only, leaving the rest of the batch to apply. Also: background, color, text, strokeColor, strokeSize, strokeStyle, fontFamily, fontSize, textAlign, verticalAlign area: background, group, layout, showTitle, strokeColor, strokeStyle, strokeWidth, shadowEnabled, titleFontSize arrow: arrowType ('straight', 'orthogonal', 'curve', or 'bezier'; the int form returned by get_widget_by_id is also accepted; changing it is checked against the path the connector already has, so switching a 2-point connector to 'curve' is rejected unless the same patch sends a 3-point `points` list), text (the connector label as a plain string, matching what list_widgets reads back; null clears; position and style are automatic), points [{x,y}] (how much of the path you get depends on arrowType: a straight connector keeps only your two endpoints and drops every bend between them; a curve keeps three points and drops the rest; a bezier keeps the two endpoints and rebuilds its interior control points itself; an orthogonal connector is re-routed from its endpoints and your path is dropped unless it has 4+ points, which this tool then pins via the strategy field automatically — a pinned connector still follows the widgets it joins when they move, it just keeps your bends instead of recomputing the route from scratch. The pin holds only while the path's segments are axis-aligned; a diagonal bend sends it back to the canvas's own route. A points list too short for the arrowType is rejected, in either direction, and one under 2 points is rejected for any type), strokeColor, strokeStyle, strokeWidth, stackable, strategy (pass {'type': 'orthogonal', 'fixed': false} to keep a connector auto-routing, or provide your own value to override the above; a connector already carrying a mindmap or line strategy is never pinned, since pinning replaces the strategy rather than adding to it), startTipType/endTipType ('none', 'arrow-empty', 'arrow-solid', 'arrow-rounded', 'arrow-long', 'arrow-line', 'diamond-solid', 'diamond-empty', 'circle-solid', 'circle-empty', 'one', 'many', 'one-or-many', 'one-only', 'zero-or-many', 'zero-or-one'), startRefId (source), endRefId (destination, the arrowhead end) — changing either re-anchors the connector and recomputes its geometry (points, position, size). Avoid also setting points/x/y/width/height in the same patch because they may be overwritten by the move. Pass null to detach an end, which leaves it where it is title/textbox: backgroundColor, text, borderColor, borderThickness, cornerRadius, fontFamily, fontSize, textAlign, fixedWidth, shadow, padding (int px) Requires a live browser tab connected to the bridge.
update_widgets
Mural ChatGPT Plugin FAQ
How the directory, categories and Discoverability Score work.
Read the methodologyHow do I improve Mural's ChatGPT Plugin discoverability?
The levers are the listing surface agents actually read: names, descriptions, keywords, tool metadata, and registry health. Which lever matters depends on where discovery breaks, which is what continuous measurement shows.
What are Mural alternatives on ChatGPT?
As of 2026-10-06, Mural competes with Miro, Whimsical, B&A: Draw Sketches, B&A: Sketch, Canvs.io whiteboard, Klaxoon, Padlet, tldraw and 1 more in ChatGPT Whiteboards & Visual Collaboration Canvases, ranked by public Discoverability Score.
Where is this profile measured?
This profile uses the geography attached to the latest public registry snapshot: US. Locale tags are intentionally omitted.