Mural MCP server for AI agents

Live

OAUTH 2.0

VISUAL WHITEBOARD

Design

Mural gives your agent visual whiteboard work: create murals from templates, add sticky notes, text, shapes, tables, and comments, read the widgets on a board, organize rooms and folders, invite collaborators, and export murals.

  • Per-user credentials: each call uses the actual user's token, never a shared bot.
  • Encrypted per-tenant vault: AES-256, resolved at request time, never in LLM context.
  • Scoped before every call: pre-call scope check, 90-day SIEM-exportable audit chain.
Mural
agent · Acme Q3
Run
Summarize the sticky notes on our Q4 retro mural.
S
mural_list_widgets
122ms
Workshop agent
The retro mural has 46 sticky notes. The top themes are slow code reviews, flaky staging, and praise for the new on-call rotation.
Sources: Q4 retro mural, 46 sticky notes
mural
46 widgets
18:29
Message Claude...

Tools your workshop agent reaches for on Mural, scoped per user.

CALL ANY TOOL
61 tools for visual whiteboards in Mural: create murals from templates, add and update sticky notes, text, shapes, arrows, tables, and comments, organize rooms and folders, invite or remove people, and export murals.
mural_create_area
Create area
Create an area (container) widget on a mural. Returns a value object with the created area (id, position, size, title). Use to group widgets. Pass the area's id as parent_id when creating widgets inside it.
Parameters
Name
Type
Required
Description
mural_id
string
Required
Unique identifier of the mural, in the form <workspaceId>.<timestamp>. Get it from mural list or search tools.
background_color
string
Optional
Fill color. Hex color with alpha channel, 8 uppercase hex digits after the #.
border_color
string
Optional
Border color. Hex color with alpha channel, 8 uppercase hex digits after the #.
border_style
string
Optional
Border style: solid, dashed, dotted-spaced, or dotted. One of: `solid`, `dashed`, `dotted-spaced`, `dotted`.
border_width
number
Optional
Border width in px, from 1 to 7.
height
number
Optional
Height of the widget in px.
hidden
boolean
Optional
Set true to hide the widget from participants.
instruction
string
Optional
Facilitator instruction attached to the widget.
layout
string
Optional
How widgets inside the area are arranged: free, column, or row. One of: `free`, `column`, `row`.
parent_id
string
Optional
ID of a parent widget, such as an area, to place this widget inside.
show_title
boolean
Optional
Set true to show the area title.
title
string
Optional
Title of the area.
title_font_size
number
Optional
Font size of the area title.
width
number
Optional
Width of the widget in px.
x
number
Optional
Horizontal position in px, measured from the left of the parent widget (or the mural if there is no parent).
y
number
Optional
Vertical position in px, measured from the top of the parent widget (or the mural if there is no parent).
mural_create_comment
Create comment
mural_create_mural_from_template
Create mural from template
mural_create_room_folder
Create room folder
mural_create_sticky_note
Create sticky note
mural_create_tag
Create tag
mural_create_textbox
Create textbox
mural_delete_mural
Delete mural
mural_delete_room_folder
Delete room folder
mural_delete_template
Delete template
mural_duplicate_mural
Duplicate mural
mural_get_current_user
Get current user
mural_get_mural_chat
Get mural chat
mural_get_room
Get room
mural_get_widget
Get widget
mural_invite_mural_users
Invite mural users
mural_list_default_templates
List default templates
mural_list_open_rooms
List open rooms
mural_list_recent_templates
List recent templates
mural_list_room_murals
List room murals
mural_list_tags
List tags
mural_list_workspace_murals
List workspace murals
mural_list_workspace_templates
List workspace templates
mural_remove_mural_users
Remove mural users
mural_search_murals
Search murals
mural_update_area
Update area
mural_update_comment
Update comment
mural_update_room
Update room
mural_update_sticky_note
Update sticky note
mural_update_textbox
Update textbox

For more tools, view docs.

Build your Agent
Same auth pattern across LangChain, OpenAI, Anthropic, and Google ADK.
Python · LlamaIndex
import { ScalekitClient } from "@scalekit-sdk/node";
import { createReactAgent } from "@langchain/langgraph/prebuilt";

const sk = new ScalekitClient(env.SCALEKIT_ENV_URL, env.SCALEKIT_CLIENT_ID, env.SCALEKIT_CLIENT_SECRET);

// Mural tools scoped to this user
const { tools } = await sk.tools.listScopedTools("user_123", {
  filter: { connectionNames: ["mural"], toolNames: [
    "mural_search_murals",
    "mural_list_widgets",
    "mural_create_sticky_note"] },
  pageSize: 100,
});

const agent = createReactAgent({ llm, tools });
await agent.invoke({ messages: [{ role: "user", content: "Summarize the Q4 retro mural and add a sticky note with the top 3 actions" }] });
import OpenAI from "openai";
import { ScalekitClient } from "@scalekit-sdk/node";

const sk = new ScalekitClient(env.SCALEKIT_ENV_URL, env.SCALEKIT_CLIENT_ID, env.SCALEKIT_CLIENT_SECRET);
const openai = new OpenAI();

const { tools } = await sk.tools.listScopedTools("user_123", {
  filter: { connectionNames: ["mural"] }, pageSize: 100,
});

const res = await openai.chat.completions.create({
  model: "gpt-5",
  messages: [{ role: "user", content: "Summarize the Q4 retro mural and add a sticky note with the top 3 actions" }],
  tools,
});

// Execute the tool call with the user's vaulted Mural OAuth token
await sk.tools.executeTool(res.choices[0].message.tool_calls[0], "user_123");
import Anthropic from "@anthropic-ai/sdk";
import { ScalekitClient } from "@scalekit-sdk/node";

const sk = new ScalekitClient(env.SCALEKIT_ENV_URL, env.SCALEKIT_CLIENT_ID, env.SCALEKIT_CLIENT_SECRET);
const anthropic = new Anthropic();

const { tools } = await sk.tools.listScopedTools("user_123", {
  filter: { connectionNames: ["mural"] }, pageSize: 100,
});

const msg = await anthropic.messages.create({
  model: "claude-sonnet-5",
  max_tokens: 1024,
  messages: [{ role: "user", content: "Summarize the Q4 retro mural and add a sticky note with the top 3 actions" }],
  tools,
});

// Tool call runs with the user's vaulted Mural OAuth token
await sk.tools.executeTool(msg.content, "user_123");
import { Agent } from "@google/adk/agents";
import { ScalekitClient } from "@scalekit-sdk/node";

const sk = new ScalekitClient(env.SCALEKIT_ENV_URL, env.SCALEKIT_CLIENT_ID, env.SCALEKIT_CLIENT_SECRET);

const { tools } = await sk.tools.listScopedTools("user_123", {
  filter: { connectionNames: ["mural"] }, pageSize: 100,
});

const agent = new Agent({
  name: "workshop_agent",
  model: "gemini-2.5-pro",
  instruction: "Mural tools scoped to this user",
  tools,
});

await agent.run("Summarize the Q4 retro mural and add a sticky note with the top 3 actions");
Try these prompts
Copy any prompt into your agent. Each maps directly to a Mural tool. Click to copy, paste into your agent, done.
Murals
Copy the prompt
Copied
Create a mural from the Retrospective template in the Engineering room.
Copy the prompt
Copied
Search our workspace for murals about onboarding.
Copy the prompt
Copied
Export the Q4 roadmap mural as a PDF.
Board content
Copy the prompt
Copied
Summarize the sticky notes on the Q4 retro mural.
Copy the prompt
Copied
Add a sticky note that says Ship SSO by November to the roadmap mural.
Copy the prompt
Copied
Create a 3-column table for Now, Next, and Later on the planning mural.
Rooms and people
Copy the prompt
Copied
List the rooms in our workspace.
Copy the prompt
Copied
Create a private room called Acme Workshop.
Copy the prompt
Copied
Invite priya@acme.com to the Acme Workshop room as a guest.
SEE HOW AUTH WORKS
Each user signs in to Mural once, and Scalekit stores and refreshes their tokens. Credentials stay vaulted, every call is scope checked, and every action is logged.
1
Authorize
Your user connects
Mural
once. We tie it to their identity and the meetings they approved — no shared bot account, no org-wide access
Who:
user ‘A’
when:
Once per user
access:
Limited to user
2
Store
Their
Mural
token lives in a vault scoped to them. User A's meetings are never reachable by an agent acting for user B, even on the same connection
vault:
encrypted
scope:
per-user
tokens:
auto-refreshed
3
Resolve
When your agent calls a
Mural
tool, we fetch the right token server-side. It never touches your agent, never appears in the LLM context, never shows up in your logs
speed:
~40ms
check:
before every call
seen by:
nobody
4
Audit
Every
Mural
tool call is logged — who triggered it, which meeting was fetched, what came back. 90 days of history, tied to the user who authorized it
history:
90 days
export:
SIEM-ready
logged:
every call
Test other agents
See the same per-user auth pattern across other design and collaboration connectors.
Support and Ops Teams
Meeting prep
Pulls agenda, participant context, and open action items before every meeting.
Engineering Teams
Engineering standup agent
Pulls commits from GitHub and GitLab, tracks issue movement in Jira, and posts a per-engineer standup brief to Slack. Each engineer's activity is read on their own delegated OAuth.
Test other agents
See the same per-user auth pattern across other design and collaboration connectors.
OPS
Meeting prep agent
Assemble the agenda, HubSpot attendee history, and open action items from Gmail before every meeting on the calendar.
ENGINEERING
Engineering standup agent
Pull commits from GitHub and GitLab, track Jira issue movement, and post a per-engineer standup brief to Slack.
Why Scalekit
Secure your agent's access. Connectors ship in minutes
01.
Shared tokens break per-user analytics
A shared Mural token looks fine in a demo. In production every sticky note and invite looks like one service account, and you cannot tell which user triggered it. Scalekit resolves the credential of the actual user who triggered the agent, never a shared bot.
// shared token
audit → bot_service_account

// scalekit
audit → user_abc ✓
02.
Authentication is not authorization
03.
Multi-tenancy is architectural
04.
Mural today. Ten connectors tomorrow.
“Our agents act across Salesforce, Gong, Google Drive, and more, on behalf of every customer. Scalekit behind the scenes meant we can keep adding tools without ever rebuilding how credentials or tool calling work.”
Venu Madhav Kattagoni
Head of Engineering / Von
FAQs
Frequently Asked Questions
Does the agent access Mural as the user or through a shared token?
As the user. Each user signs in to Mural once, and Scalekit stores and refreshes their tokens. Widgets the agent adds and people it invites are attributed to that user in your audit trail, not a shared service account.
Where is the Mural OAuth token stored?
In Scalekit's managed AES-256 token vault, namespaced per tenant. Refresh is automatic. Revocation is a single dashboard action. Credentials never appear in prompts, logs, or LLM context.
Can I limit what the agent does in Mural?
Yes. Filter by tool name in listScopedTools to expose only what you want, for example the mural, widget, and search read tools without mural_delete_room_folder, which deletes a folder with its sub-folders and murals. Scalekit also enforces scope checks before every API call.
What happens when a user revokes Mural access?
The connection is invalidated on the next tool call. Subsequent requests for that user fail closed with a clear error. Other users in the tenant remain unaffected. The event is logged for audit.
Can the agent read what is already on a mural?
Yes. mural_list_widgets lists the widgets on a mural, optionally filtered by type, so an agent can read sticky notes and text boxes. Drawings are not included. mural_get_mural_chat returns the mural's chat messages.
Start in your coding agent
Up and running in one command
Install the Scalekit skill in your editor of choice. Connector, auth, tools, prompt, all wired up
Claude Code REPL
/plugin marketplace add scalekit-inc/claude-code-authstack
/plugin install agentkit@scalekit-auth-stack
Cursor Code REPL
# ~/.cursor/mcp.json
{
""mcpServers"": {
""mural"": {
""url"": ""https://mcp.scalekit.com/mural"",
""headers"": { ""Authorization"": ""Bearer $SCALEKIT_TOKEN"" }
}
}
}
Codex Code REPL
# ~/.codex/config.toml
[mcp_servers.mural]
url = ""https://mcp.scalekit.com/mural""
auth_env = ""SCALEKIT_TOKEN""
Copilot Code REPL
# .vscode/mcp.json
{
""servers"": {
""mural"": {
""url"": ""https://mcp.scalekit.com/mural"",
""type"": ""http""
}
}
}