画布MCP
将分层画布图呈现为PNG的MCP服务器。将您的系统定义为层次结构 网络, 工厂, 机器,以及 节点 --Canvas MCP处理布局、样式和渲染。
用Python、Pillow和 模型上下文协议.
本体论
Canvas MCP使用 四级层次本体每个图都是嵌套容器的树,从最宽的范围到原子单位:
Canvas
└── Network ← system boundary
└── Factory ← functional domain
└── Machine ← pipeline
└── Node ← atomic operation为什么是这种层次结构?
大多数绘图工具都会给你方框和箭头。Canvas MCP为您提供 语义容器 --每个层次都承载着关于 *范围* 和 *角色* 它包含的内容:
- 网络 --最宽的边界。将其视为服务、部署或整个子系统。一个复杂的架构可能有多个网络。
- 工厂 --网络中的一个功能域。“数据摄取”、“分析”、“输出生成”——一个工厂将服务于共同目的的管道分组。
- 机器 --单个管道或处理链。将数据从输入转换为输出的连接操作序列。
- 节点 --原子单位。一个操作:一个API调用,一个转换,一个决策门,一个AI推理步骤。
这不是任意嵌套——它反映了真实系统的组织方式。层次结构允许您在一个图中表示微观(单个操作)和宏观(系统架构)。
标注
本体的每一层都遵循相同的标签模式:
| 字段 | 必填 | 目的 |
|---|---|---|
id | 是 | 用于连接和查找的唯一标识符 |
label | 否 | 人类可读的显示名称 |
description | 否 | 可选的更长描述(用于文档) |
规则很简单: get_label() 返回 label 如果设置,否则回退到 id.
这使得YAML食谱保持简洁。只有当你想要一个与id不同的显示名称时,你才需要一个标签:
# No label needed — "preprocess" is clear enough
- id: preprocess
type: process
content: "Clean and normalize data"
# Label overrides the id for display
- id: llm-gpt4o-analysis
type: ai
label: "AI Analysis"
content: "Run GPT-4o on cleaned data"容器也是如此:
machines:
- id: machine-1 # Renders as "machine-1" (fine for auto-generated)
nodes: [...]
- id: src-pipeline # Renders as "Data Sources"
label: "Data Sources"
nodes: [...]节点类型
节点是本体的原子单位。每个节点都有一个 类型 它决定了它的颜色并具有语义意义:
| 类型 | 颜色 | 十六进制 | 含义 |
|---|---|---|---|
input | 蓝色 | #2196F3 | 用户提供的数据进入系统 |
output | 琥珀色 | #FFC107 | 最终结果离开系统 |
process | 青色 | #00BCD4 | 转换或计算步骤 |
decision | 红色 | #F44336 | 分支点或条件门 |
ai | 紫色 | #9C27B0 | AI/LLM处理步骤 |
source | 橙色 | #FF9800 | 外部数据源(API、数据库、文件) |
static | 绿色 | #4CAF50 | 不可变种子含量或常数 |
default | 灰色 | #999999 | 通用/未指定 |
淋巴结解剖学
渲染时,每个节点显示:
- 杆式 --顶部与字体强调色相匹配的彩色条纹
- 标签 --类型栏下方的粗体文本(来自
get_label()) - 内容 --描述节点功能的单词包装正文
- 类型徽章 --右下角显示类型名称的小标签
节点属性
- id: analyze # Required. Globally unique identifier.
type: ai # Optional. One of the 8 types above. Default: "default"
label: "AI Analysis" # Optional. Display name. Default: uses id
content: "Run inference" # Optional. Body text describing the operation
x: 800 # Optional. Horizontal position. Default: 0 (auto-layout)
y: 180 # Optional. Vertical position. Default: 0 (auto-layout)
width: 250 # Optional. Node width in pixels. Default: 250
height: 120 # Optional. Node height in pixels. Default: 120
inputs: [preprocess] # Optional. IDs of upstream nodes
outputs: [report] # Optional. IDs of downstream nodes
style: # Optional. Override default NodeStyle
border_color: "#FF00FF"
fill_color: "#1e1e2e"
text_color: "#cdd6f4"
label_color: "#FF00FF"
corner_radius: 12容器造型
机器和工厂可以用 ContainerStyle 自定义他们的视觉容器:
machines:
- id: my-pipeline
label: "Custom Pipeline"
style:
border_color: "#89b4fa" # Outline color
fill_color: "#1e1e2e" # Background fill
label_color: "#89b4fa" # Label text color
alpha: 100 # Fill opacity (0-255)
corner_radius: 12 # Border radius
border_width: 2 # Outline thickness全部 ContainerStyle 字段是可选的——未设置的字段将恢复为默认值:
| 字段 | 机器默认值 | 出厂默认值 |
|---|---|---|
border_color | #313244 | #45475a |
fill_color | #181825 | 无(透明) |
label_color | #6c7086 | #a6adc8 |
alpha | 120 | 0 |
corner_radius | 8 | 12 |
border_width | 1 | 1 |
连接
通过以下方式在节点上声明连接 inputs 和 outputs --其他节点ID列表:
- id: source
type: input
outputs: [transform] # "I feed into transform"
- id: transform
type: process
inputs: [source] # "I receive from source"
outputs: [result]连接是 双向重复数据消除 --在两端声明连接就足够了。声明两者都是无害的(而且通常更清晰)。
智能端口选择
Canvas MCP根据以下参数自动选择连接端口 空间关系 节点之间:
- 水平流动 (默认):连接从右边缘退出,从左边缘进入。这将创建从左到右的图表。
- 垂直流动 (自动):当目标节点明显低于或高于其源节点时(超过源节点高度1.5倍的“地平线”阈值),连接将切换到底部/顶部端口。这将创建垂直树结构。
切换是 从几何学中产生 --您无需对其进行配置。将节点并排放置,即可获得水平流。将它们垂直堆叠,你会得到垂直流动。将两者混合,每个连接都会独立选择正确的端口。
连接渲染
连接绘制得平滑 三次贝塞尔曲线 与:
- 定向S形弯曲控制点(水平或垂直)
- 从源节点的类型导出的颜色(变暗到70%)
- 端点处的箭头
YAML格式
Canvas MCP支持两种YAML格式。使用任何适合你需要的。
简化格式
简化格式是节点的平面列表。Canvas MCP自动将它们包装在层次结构中(一个网络>一个工厂>自动检测的机器),并处理布局:
title: My Pipeline
nodes:
- id: ingest
type: input
label: "Data Ingest"
content: "Accept incoming data"
outputs: [clean]
- id: clean
type: process
label: "Clean"
content: "Normalize and validate"
inputs: [ingest]
outputs: [analyze]
- id: analyze
type: ai
label: "AI Analysis"
content: "Run LLM inference"
inputs: [clean]
outputs: [report]
- id: report
type: output
label: "Report"
content: "Generated summary"
inputs: [analyze]自动布局:当所有节点坐标均为 (0, 0) (或省略),Canvas MCP会自动排列它们。使用 organize 智能拓扑布局的标志。
汽车机械:节点的连接组件会自动分组到机器中。
分层格式
完整格式为您提供了对整个层次结构的明确控制:
canvas:
version: "2.0"
title: AI Pipeline
networks:
- id: main-system
label: "Production System"
factories:
- id: ingestion
label: "Data Ingestion"
machines:
- id: sources
label: "Data Sources"
nodes:
- id: api-feed
type: source
x: 100
y: 100
label: "API Feed"
content: "External API data"
outputs: [preprocess]
- id: db-source
type: source
x: 100
y: 260
label: "Database"
content: "Historical records"
outputs: [preprocess]
- id: processing
label: "Processing"
nodes:
- id: preprocess
type: process
x: 450
y: 180
label: "Preprocess"
content: "Clean and normalize"
inputs: [api-feed, db-source]
outputs: [analyze]
- id: analysis
label: "Analysis"
machines:
- id: ai-stage
label: "AI Stage"
nodes:
- id: analyze
type: ai
x: 800
y: 180
label: "AI Analysis"
content: "Run LLM analysis"
inputs: [preprocess]
outputs: [output]
- id: output
type: output
x: 1150
y: 180
label: "Report"
content: "Generated report"
inputs: [analyze]布局系统
Canvas MCP包括一个内置的拓扑布局引擎。
自动布局
当所有节点的坐标位于 (0, 0),基本的自动布局会排列它们:
- 机器内从左到右(80px水平间距)
- 机器之间从上到下(垂直间距200px)
- 工厂之间的额外间隙(60px)
组织算法
启用 organize: true 对于智能分层布局:
- 拓扑排序 (Kahn算法)分配层次级别
- 父中心对齐 孩子们以父母为中心
- 防止重叠 强制最小间距
- 循环处理 在循环图中优雅地定位节点
- 电网回退 在网格中排列断开连接的组件
间距级别
控制呼吸室 spacing_level 参数:
| 水平 | 水平 | 垂直 | 最适合 |
|---|---|---|---|
node | 60px | 110px | 小而紧凑的图表 |
container | 150px | 190px | 架构图(默认) |
network | 190px | 250px | 大型系统概述 |
视觉主题
Canvas MCP使用 卡布奇诺摩卡 黑暗主题:
| 元素 | 颜色 | 十六进制 |
|---|---|---|
| 画布背景 | 深色底色 | #11111b |
| 节点填充 | 基础 | #1e1e2e |
| 节点标签文本 | 浅色文本 | #cdd6f4 |
| 节点内容文本 | 静音文本 | #a6adc8 |
| 机器容器填充 | 表面 | #181825 (半透明) |
| 机器容器边界 | 覆盖 | #313244 |
| 机器标签 | 子文本 | #6c7086 |
| 工厂集装箱边界 | Surface 2 | #45475a |
| 工厂标签 | 子文本1 | #a6adc8 |
MCP工具
Canvas MCP通过模型上下文协议公开了四个工具:
render_canvas
将YAML配方字符串渲染为PNG。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
yaml_recipe | string | 必需 | 简化或分层格式的YAML |
scale | 编号 | 2.0 | 渲染比例(2.0=清晰的视网膜输出) |
filename | string | auto UUID | 输出文件名(不带扩展名) |
organize | 布尔值 | false | 应用分层布局算法 |
spacing_level | 字符串 | "container" | 其中之一: node, container, network |
create_canvas
从结构化输入(标题+节点+可选机器)创建图表。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
title | string | 必填 | 画布标题 |
nodes | array | 必填 | 节点定义列表 |
machines | array | 可选 | 将节点分组到命名计算机中 |
scale | 编号 | 2.0 | 渲染比例 |
organize | 布尔值 | true | 应用布局算法 |
spacing_level | 字符串 | "container" | 间距预设 |
返回PNG和保存的YAML配方。
list_templates
列出可用的初学者模板。返回模板名称和文件路径。
get_template
按名称检索特定模板的YAML内容。
安装
作为MCP服务器
添加到您的MCP客户端配置中(例如。, .mcp.json):
{
"mcpServers": {
"canvas-mcp": {
"command": "uv",
"args": [
"run",
"--directory", "/path/to/Canvas-MCP",
"canvas-mcp"
]
}
}
}直接运行
uv run canvas-mcp # Starts the MCP stdio server测试
uv run python test_render.py # Renders test PNGs to output/项目结构
Canvas-MCP/
├── src/canvas_mcp/
│ ├── models.py # Ontology: Canvas > Network > Factory > Machine > Node
│ ├── parser.py # YAML parser (simplified + hierarchical formats)
│ ├── renderer.py # Pillow-based PNG renderer
│ ├── organize.py # Hierarchical layout algorithm (topological sort)
│ └── server.py # MCP server with 4 tools
├── templates/
│ ├── simple-flow.yaml # 3-node linear pipeline
│ ├── decision-tree.yaml # Branching decision flow
│ └── ai-pipeline.yaml # Full hierarchical example
├── pyproject.toml
└── test_render.py输出
PNG保存到 ~/.rhode/canvas/ 默认情况下。设置 CANVAS_OUTPUT_DIR 环境变量来改变这一点。
许可证
麻省理工学院
