noddle draw
dev.noddle/draw · 12 stars · TypeScript · MIT
MCP server Read, create and edit open-source noddle draw diagram boards, browse versions and comment.
Install
The repo has no one-line install. Follow its README.
Published as
- mcpb
https://github.com/noddle-dev/noddle-draw/releases/download/mcpb-v1.0.0/noddle-draw.mcpbstdio
From the server's entry in the official MCP Registry.
Configuration
| Name | Set as | What it is |
|---|---|---|
NODDLE_BASE_URLOptional | Env var | http(s) origin of the noddle draw instance. Set it to your own origin when self-hosting. |
NODDLE_AGENT_NAMEOptional | Env var | Display name on the agent's comments and version snapshots (max 40 chars). |
NODDLE_AI_PROVIDEROptional | Env var | Optional bring-your-own-key provider for generate_diagram. |
NODDLE_AI_KEYOptional · Secret | Env var | Optional AI provider key, sent only to NODDLE_BASE_URL per call and never stored. |
NODDLE_AI_MODELOptional | Env var | Optional model override for generate_diagram. |
Files
noddle draw MCP server
Lets an AI agent (Claude Code, Claude Desktop, or any MCP client) work on a board alongside you: read, create and edit boards, browse version history, and comment like any other collaborator.
noddle draw is anonymous. There are no accounts and no tokens. A board id (12 hex
chars) or a board URL is the capability. The agent can open any board you give it, and
anyone holding the link of a board the agent creates can open it too. The agent signs its
comments and version snapshots with NODDLE_AGENT_NAME.
- Stdlib-only Python ≥ 3.9 (
urllib+json), so there is nothing to install. - stdio transport: one JSON-RPC 2.0 message per line. stdout carries only protocol messages, and logs go to stderr.
- MCP protocol, dual-era:
- 2026-07-28 (modern, stateless): every request carries
_meta["io.modelcontextprotocol/protocolVersion"]+clientCapabilities. The server implementsserver/discover, and setsresultTypeand_meta["io.modelcontextprotocol/serverInfo"]on every result, plusttlMs/cacheScopeon list/read results. An unsupported version returns-32022 UnsupportedProtocolVersion. - Legacy
initializehandshake: 2025-11-25, 2025-06-18, 2025-03-26, 2024-11-05. The server answers with the client's version when it supports it, and otherwise with 2025-11-25.pingworks in this mode. JSON-RPC batches are accepted only for 2025-03-26, the only revision that allowed them.
- 2026-07-28 (modern, stateless): every request carries
1. Register
Claude Code (from the repo root; an absolute script path is more robust):
claude mcp add noddle -- python3 mcp/noddle_mcp.py # a self-hosted instance instead of draw.noddle.dev: claude mcp add noddle --env NODDLE_BASE_URL=http://127.0.0.1:8000 -- python3 mcp/noddle_mcp.py
Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json)
or a project .mcp.json use the same shape:
{
"mcpServers": {
"noddle": {
"command": "python3",
"args": ["/absolute/path/to/noddle-draw/mcp/noddle_mcp.py"],
"env": { "NODDLE_BASE_URL": "https://draw.noddle.dev" }
}
}
}
MCP Bundle (one-click install in Claude Desktop and other MCPB clients): download
noddle-draw.mcpb from the latest mcpb-v* release
and open it. It needs only Python 3.10+ (standard library, no install step).
From a checkout (pyproject.toml here):
uvx --from ./mcp noddle-draw-mcp # or: pipx install ./mcp && noddle-draw-mcp
The server is listed in the official MCP Registry
as dev.noddle/draw (see Releasing).
| Env | Default | |
|---|---|---|
NODDLE_BASE_URL |
https://draw.noddle.dev |
http(s) origin of the noddle draw instance. A non-http(s) value exits with code 2 |
NODDLE_AGENT_NAME |
MCP agent |
display name on comments and version history (max 40 chars) |
NODDLE_TIMEOUT |
30 |
seconds per board API call |
NODDLE_AI_TIMEOUT |
180 |
seconds for generate_diagram |
NODDLE_AI_PROVIDER |
— | optional BYOK for generate_diagram: claude, openai, gemini, openrouter or custom |
NODDLE_AI_KEY |
— | your AI provider key. It is sent only to NODDLE_BASE_URL, as the same X-AI-* headers the web app uses, and never stored. Unset means the instance's shared pool is used, if it has one |
NODDLE_AI_MODEL |
— | optional model override |
NODDLE_AI_BASE |
— | OpenAI-compatible base URL (provider custom only) |
CLI: --help, --version, --list-tools (prints the tool definitions as JSON).
Exit codes: 0 when stdin closes (normal shutdown), 2 for bad configuration.
2. Tools
Every tool returns structuredContent that conforms to its outputSchema, plus the same
JSON as a text block. Board tools also return a resource_link to noddle://board/{id}
(revisions ≥ 2025-06-18). Wherever a tool takes doc_id, you can pass either the 12-hex
id or the board URL ({base}/d/{id} or /embed/{id}). A URL on a different origin than
NODDLE_BASE_URL is refused.
| Tool | readOnly | destructive | idempotent | openWorld | What it does |
|---|---|---|---|---|---|
get_board |
✓ | ✗ | Name, url, my_role (editor/viewer), updated_at, page summary and diagram JSON. Optional page_id and include_svg |
||
create_board |
✗ | ✗ | ✗ | ✗ | New board, with optional diagram JSON. Anyone with its url can edit it |
update_board |
✗ | ✓ | ✓ | ✗ | Replace the WHOLE diagram (fetch → edit → send back). A version snapshot is kept. expected_updated_at turns a concurrent edit into a conflict error instead of an overwrite |
rename_board |
✗ | ✗ | ✓ | ✗ | Rename |
list_versions |
✓ | ✗ | Version-history snapshots, newest first | ||
get_version |
✓ | ✗ | One snapshot's diagram. To restore it, pass it to update_board |
||
list_comments |
✓ | ✗ | Comment threads | ||
add_comment |
✗ | ✗ | ✗ | ✗ | Pin to ONE of node_id / edge_id / parent_id (reply) / point x,y (+ page_id). Works on view-only links too |
generate_diagram |
✓ | ✓ | Turns prose or Mermaid into diagram JSON through the instance's AI (your BYOK key or its shared pool). It saves nothing, so pass the result to create_board/update_board |
There is deliberately no list_boards and no delete: the API has neither. Link access
is not discovery, and an anonymous board has no owner who could be trusted to delete it.
Writes to a board whose link is view-only fail with a 403 tool error.
Diagram payloads are pass-through. The server checks only the envelope
({pages:[{id,nodes,edges}]} or legacy {nodes,edges}, with string ids). Node and edge
fields are forwarded untouched, so new editor fields (e.g. the freedraw kind with
points, or curved routing) work without a server update. See DiagramNode /
DiagramEdge in contracts/openapi.yaml.
Errors:
- Bad arguments, API failures (400/403/404/413/422/429/503) and conflicts come back as
isError: truetool results that the model can act on. - Protocol errors use standard JSON-RPC codes: unknown tool or invalid params
-32602, unknown method-32601, malformed JSON-32700, invalid request-32600.
3. Resources & prompts
- Resources:
resources/listlists the boards this session has created, read or edited, asnoddle://board/{id}(application/json,lastModified). It starts empty, because the API has no listing.resources/templates/listexposesnoddle://board/{doc_id}, so a client can read any board by id.resources/readreturns the same JSON asget_board. An unknown board returns-32602. - Prompts:
design_board(topic, notes?): generate → sanity-check →create_board→ reply with the url.review_board(doc_id): embeds the board as a resource and asks for a critique posted as anchored comments.
4. Example (Claude Code)
> Create a board "Payment flow" with Client → API Gateway → Payment Service → Database,
then comment on the Database node reminding the team to review indexes.
Claude: generate_diagram(text="Client -> API Gateway -> Payment Service -> Database")
→ create_board(name="Payment flow", diagram=…)
→ add_comment(doc_id, body="Please review indexes for the payments table", node_id="db")
→ returns https://draw.noddle.dev/d/{id}
Comments reach an open board in realtime. A diagram written with update_board shows up
when the board is reloaded.
5. Tests
python3 -m pytest mcp -q # or: python3 -m unittest discover mcp
test_noddle_mcp.py runs the real server over stdio against a fake in-process REST
backend. It covers version negotiation (modern and legacy), schema validity, read and
write tools, board-URL ids, view-only links, resources, prompts, BYOK header forwarding
and error paths. It also asserts that stdout carries only JSON-RPC, that no request ever
carries an Authorization header, and that a BYOK key never leaks into output or logs.
Releasing
mcp/server.json is the registry listing (dev.noddle/draw); it points at the MCP Bundle
attached to a GitHub release. The dev.noddle/* namespace is verified over HTTP: noddle.dev
serves the publisher's ed25519 public key at /.well-known/mcp-registry-auth.
- Bump the version everywhere, all equal:
__version__innoddle_mcp.py,versioninmcpb/manifest.json,versioninpyproject.toml, andversioninserver.json. Registry versions are immutable; a metadata-only fix uses a suffix such as1.0.0-1. - Build the bundle:
mcp/build_mcpb.sh→mcp/dist/noddle-draw.mcpb(prints its SHA-256). - Create the release with that exact file:
gh release create mcpb-v<version> mcp/dist/noddle-draw.mcpb --title "MCP server <version>". - In
server.json, set the packageidentifierto the release download URL andfileSha256to the printed hash, then publish with the namespace key holder'smcp-publisher login http --domain noddle.dev --private-key …andmcp-publisher publish mcp/server.json.
Notes
update_boardkeeps the stored SVG preview. The preview refreshes on the next save in the editor.- Cross-origin HTTP redirects are refused, so a BYOK key is never forwarded to another
host. A BYOK key over plain
httpto a non-loopback host logs a warning. generate_diagramsends text to an AI provider. Never pass customer PII, credentials or account numbers.
Facts
- Kind
- MCP server
- Group
- Uncategorized
- Stars
- 12
- License
- MIT
- Language
- TypeScript
- Last push
- 2026-10-03
- Forks
- 1
- MCP Registry
- dev.noddle/draw
- Homepage
- draw.noddle.dev
- Topics
- ai, collaboration, diagramming, excalidraw-alternative, mcp, whiteboard, diagram, svg
- 1REAio.github.morluto/reaReverse engineer anything from your terminal or agent with one CLI and MCP server.125.3k
- 2com.browser-use/browser-usecom.browser-use/browser-useControl a real Chrome browser to complete any task: fill forms, extract data, book flights.117.7k
- 3World Monitorapp.worldmonitor/mcpLive markets, conflicts, country risk, chokepoints, energy, and China decision signals. 93 tools.88.3k
- 4Scrapling MCP Serverd4vinci/scrapling🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl! Don't be shy, join here: https://discord.gg/EMgGbDceNQ and follow here for daily tips and tricks: https://x.com/Scraplingdev86.9k
- 5Everythingmodelcontextprotocol/serversThis MCP server attempts to exercise all the features of the MCP protocol. It is not intended to be a useful server, but rather a test server for builders of MCP clients. It implements prompts, tools, resources, sampling, and more to showcase MCP capabilities.85.8k
- 6Fetchmodelcontextprotocol/serversA Model Context Protocol server that provides web content fetching capabilities. This server enables LLMs to retrieve and process content from web pages, converting HTML to markdown for easier consumption.85.8k