JSON Canvas MCP Server
Supports exporting canvas data to SVG format through the export_canvas tool, allowing visualization of JSON Canvas content.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@JSON Canvas MCP Server create a text node for brainstorming ideas at position 200,300"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
JSON Canvas MCP Server
A Model Context Protocol (MCP) server for working with
JSON Canvas files — the open infinite-canvas format used
by Obsidian. It lets an MCP client create, validate,
read, and list .canvas files.
Built on the official mcp Python SDK (>=1.27), which negotiates the 2025-11-25 MCP
protocol revision. Runs over stdio by default and optionally over the Streamable HTTP
transport.
Hosts that support the MCP Apps UI extension render an interactive canvas viewer inline when you read or create a canvas — a pan/zoom, Obsidian-style preview of the nodes and edges. Text-only clients are unaffected and keep receiving the canvas as text/structured output.
Components
Tools
create_canvas — Create a canvas from
nodes(and optionaledges) and write it to a date-prefixed.canvasfile underOUTPUT_PATH.Input:
nodes(array of JSON Canvas node objects),filename(string, no extension),edges(optional array of edge objects).Returns (structured):
{ path, node_count, edge_count }.
validate_canvas — Validate canvas data against the JSON Canvas 1.0 specification.
Input:
canvas(object with optionalnodesandedges).Returns (structured):
{ valid, error }.
read_canvas — Read a stored
.canvasfile and return its nodes and edges.Input:
filename(string, with or without the.canvasextension).Returns (structured):
{ nodes, edges }(also rendered by the canvas viewer; text fallback is the canvas JSON).
list_canvases — List the
.canvasfiles available inOUTPUT_PATH.Returns: array of filenames.
edit_canvas — Add, update, and/or remove nodes and edges on a stored canvas in one atomic write (a failed operation leaves the file unchanged).
Input:
filename, plus optionaladd_nodes,update_nodes(partial, must includeid),remove_node_ids(cascades connected edges),add_edges,update_edges,remove_edge_ids.Returns (structured):
{ path, node_count, edge_count, canvas }— the updated canvas, so UI-capable hosts re-render it inline.
export_canvas — Export a stored canvas to another format.
Input:
filename,format(markdown|svg).Returns (structured):
{ format, mime_type, content }. Markdown is an edge-ordered outline; SVG is a standalone vector image (node title lines only — plain SVG can't render Markdown).
search_canvases — Case-insensitive substring search across stored canvases.
Input:
query, optionalfilenameto scope to one canvas.Returns (structured):
{ matches: [{ filename, kind, id, field, snippet }] }.
create_canvas, read_canvas, and edit_canvas are linked to the canvas viewer via
_meta.ui.resourceUri, so UI-capable hosts render the result inline.
Node objects use the JSON Canvas shape: id, type (text | file | link | group),
x, y, width, height, optional color, plus type-specific fields (text, file/subpath,
url, label/background/backgroundStyle). Edge objects use id, fromNode, toNode, and
optional fromSide/toSide/fromEnd/toEnd/color/label.
Resources
canvas://schema— JSON Schema for validating canvas files.canvas://examples/basic— A simple example canvas (two text nodes joined by an edge).ui://canvas/viewer.html— The interactive canvas viewer (MCP Apps UI), served with MIME typetext/html;profile=mcp-app. Referenced bycreate_canvasandread_canvas.
Interactive canvas viewer (MCP Apps UI)
The viewer is a single self-contained HTML bundle built from the ui/ source with Vite
and the official @modelcontextprotocol/ext-apps
client. It renders nodes (with markdown, colors, and groups) and edges (sides, arrows, labels)
in a pan/zoom view, themed via the host's CSS variables.
The built bundle is committed at jsoncanvas/_ui/viewer.html and ships in the package, so
running the server needs only Python. Rebuild it after changing ui/:
make build-ui # cd ui && npm install && npm run build (requires Node.js)To preview the renderer standalone (no MCP host), run cd ui && npm run dev and open
/preview.html.
Related MCP server: MCP REST API Server
Usage with Claude Desktop
Docker (stdio)
docker build -t mcp/jsoncanvas .Add to your claude_desktop_config.json:
{
"mcpServers": {
"jsoncanvas": {
"command": "docker",
"args": ["run", "-i", "--rm", "-v", "canvas-data:/data", "mcp/jsoncanvas"],
"env": { "OUTPUT_PATH": "/data/output" }
}
}
}uv (stdio)
{
"mcpServers": {
"jsoncanvas": {
"command": "uv",
"args": ["--directory", "/path/to/jsoncanvas", "run", "mcp-server-jsoncanvas"],
"env": { "OUTPUT_PATH": "./output" }
}
}
}Streamable HTTP transport
To serve over Streamable HTTP instead of stdio:
mcp-server-jsoncanvas --transport streamable-http --host 127.0.0.1 --port 8000The MCP endpoint is then http://127.0.0.1:8000/mcp. The transport binds to localhost and, per
the 2025-11-25 spec, validates the Origin header with DNS-rebinding protection enabled
(localhost Origins only by default). To accept connections from outside the host (e.g. when
running the container with HTTP), bind --host 0.0.0.0 and configure your allowed Origins
accordingly.
Browser-based MCP hosts (the kind that render the canvas viewer) connect cross-origin and must
read the mcp-session-id response header, so the Streamable HTTP transport serves permissive
CORS headers. Restrict the allowed origins with MCP_CORS_ORIGINS (comma-separated; default
*).
Security note. The HTTP transport is unauthenticated — anyone who can reach the port can read and write
.canvasfiles underOUTPUT_PATH. The server is intended for local use; keep it bound to127.0.0.1(the default). DNS-rebinding/Originprotection is fixed to localhost Origins and Hosts at startup, so binding--host 0.0.0.0exposes the port on the network but still rejects non-localhostHost/Originheaders — to safely expose it remotely, front it with an authenticating reverse proxy rather than publishing it directly, and setMCP_CORS_ORIGINSto the specific origins you trust (never*).
Configuration
Environment variables:
OUTPUT_PATH— Directory where.canvasfiles are written/read (default./output).MCP_TRANSPORT—stdio(default) orstreamable-http.MCP_HOST/MCP_PORT— Host/port for the Streamable HTTP transport (default127.0.0.1:8000).MCP_CORS_ORIGINS— Comma-separated allowed CORS origins for the HTTP transport (default*).
Development
# Install uv: https://docs.astral.sh/uv/getting-started/installation/
make setup # uv venv && uv sync --extra dev
make build-ui # rebuild the canvas viewer bundle (requires Node.js)
make test # run the test suite
make lint # ruff check + format check
make audit # scan dependencies for known vulnerabilities (pip-audit)
make run # run the server over stdioRun the bundled library example:
make example # writes example.canvas to OUTPUT_PATH (default ./output)Library example
The jsoncanvas package can also be used directly:
from jsoncanvas import Canvas, TextNode, Edge
title = TextNode(id="title", x=100, y=100, width=400, height=100,
text="# Hello Canvas", color="#4285F4")
info = TextNode(id="info", x=600, y=100, width=300, height=100,
text="More information here", color="2") # preset color
canvas = Canvas()
canvas.add_node(title)
canvas.add_node(info)
canvas.add_edge(Edge(id="edge1", from_node="title", to_node="info",
from_side="right", to_side="left", label="Connection"))
import json
print(json.dumps(canvas.to_dict(), indent=2))License
MIT. See LICENSE.
Available Tools
7 toolscreate_canvasCreate CanvasC
Create a JSON Canvas from nodes (and optional edges) and write it as a date-prefixed .canvas file under OUTPUT_PATH.
Inputs: nodes (required), filename (required), edges. Returns: Result of writing a canvas to disk.
edit_canvasEdit CanvasA
Edit a stored .canvas file: add, update, and/or remove nodes and edges in one atomic write. Operations apply in order — add_nodes, update_nodes, add_edges, update_edges, remove_edge_ids, remove_node_ids — and removing a node also removes its connected edges. If any operation fails the file is left unchanged. Returns the updated canvas.
Inputs: filename (required), add_nodes, update_nodes, remove_node_ids, +3 more. Returns: Result of writing a canvas to disk.
export_canvasExport CanvasA
Export a stored canvas to another format: 'markdown' (an outline that follows the edges) or 'svg' (a standalone vector image). SVG renders each node's title line only.
Inputs: filename (required), format (required). Returns: Result of exporting a canvas to another format.
list_canvasesList CanvasesA
List the .canvas files available in OUTPUT_PATH.
Inputs: no named parameters. Returns: result
read_canvasRead CanvasB
Read a .canvas file from OUTPUT_PATH and return its nodes and edges.
Inputs: filename (required). Returns: A JSON Canvas document — the nodes and edges the UI viewer renders.
search_canvasesSearch CanvasesA
Case-insensitive substring search across stored canvases. Matches node text, labels, file paths, URLs, and IDs, plus edge labels. Searches every canvas in OUTPUT_PATH unless a filename is given.
Inputs: query (required), filename. Returns: Result of searching across stored canvases.
validate_canvasValidate CanvasB
Validate canvas data against the JSON Canvas 1.0 specification.
Inputs: canvas (required). Returns: Result of validating canvas data against the JSON Canvas 1.0 spec.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 7 tools
Each tool has a clearly distinct purpose: create, edit, export, list, read, search, validate. There is no overlap or ambiguity between them.
All tool names follow a consistent verb_noun pattern (e.g., create_canvas, list_canvases) using snake_case, making the set predictable and easy to navigate.
With 7 tools, the server is well-scoped for managing JSON Canvas files. Each tool earns its place, covering essential operations without excess.
The tool set covers create, read, update, list, search, export, and validate. However, a dedicated delete canvas tool is missing, which is a minor gap for full lifecycle management.
Maintenance
Related MCP Connectors
MCP Spec Compliance MCP — audits any MCP server.json against the official Model Context Protocol
Model Context Protocol server for the Apideck Unified API. Connect any MCP-compatible agent framework to 100+ accounting systems, HRIS platforms, file storage providers, and more through one integration. More information https://www.apideck.com/mcp-server
A Model Context Protocol server for Wix AI tools
Model Context Protocol server for Studex tools, notifications, and profile integrations
Related MCP Servers
- AlicenseBqualityDmaintenanceA Model Context Protocol server that enables interaction with the Canvas Learning Management System API, allowing users to manage courses, assignments, enrollments, and grades within Canvas.541,877 npm104JavaScriptMIT
- FlicenseNot gradedqualityDmaintenanceA server implementation of the Model Context Protocol (MCP) that provides REST API endpoints for managing and interacting with MCP resources.-
- FlicenseNot gradedqualityDmaintenanceA Model Context Protocol server that enables real-time communication using Server-Sent Events (SSE), providing standardized model management and resource templating capabilities.-
- AlicenseCqualityDmaintenanceA Model Context Protocol server implementation that enables real-time data communication between web pages and client applications through WebSocket connections.22,105 npmMIT