Content
# MCP Canvas
A universal definition-based canvas engine for 2D/3D rendering with CDL (Canvas Definition Language) support. Any type of diagram, drawing, or visualization can be rendered on this engine — node-edge graphs, circuit diagrams, PCB layouts, 3D models, block layouts, page documents, relationship diagrams, tree structures — all on the same engine.
## Features
- **Definition-Based Rendering** - No images stored; definitions are stored and rendered per view
- **CDL (Canvas Definition Language)** - DSL for describing visual definitions; LLM-generated, reproducible
- **Universal Canvas** - Not bound to any specific use case; renders anything based on registered types
- **Extensible Type System** - Unknown types can be rendered with registered definitions and renderers
- **Performance Guaranteed** - Real-time interaction maintained with tens of thousands of elements
- **9 Built-in Layout Algorithms**:
- manual, auto-grid, auto-flow (Sugiyama), force-directed (Barnes-Hut)
- constraint, circular, compact, stack, free-form
- **Core Primitives**: 13 shape types (rect, circle, ellipse, line, polyline, polygon, arc, path, text, richText, image, group, foreignContent)
- **3D Support**: Box, sphere, cylinder, cone, torus, extrude, revolve, mesh geometries with PBR materials
- **Cross-platform support**: Android, iOS, web, Linux, Windows, macOS
## Quick Start
```dart
import 'package:mcp_canvas/mcp_canvas.dart';
void main() {
// Create a canvas
final canvas = Canvas();
// Register a custom node type
canvas.registry.registerNodeType(NodeTypeDefinition(
type: 'resistor',
displayName: 'Resistor',
defaultDefinition: VisualDefinition(
id: 'resistor-def',
type: 'resistor',
),
));
// Create nodes
final node1 = canvas.createNode(
'resistor',
const Position(100, 100),
properties: {'resistance': '10k'},
);
final node2 = canvas.createNode(
'resistor',
const Position(300, 100),
properties: {'resistance': '22k'},
);
// Create an edge between nodes
final edge = canvas.createEdge(
EdgeEndpoint(nodeId: node1.id, portId: 'out'),
EdgeEndpoint(nodeId: node2.id, portId: 'in'),
);
// Serialize to JSON
final json = canvas.toJson();
// Search for elements
final results = canvas.search('10k');
}
```
## Core Concepts
### Visual Definition
Every visual element exists as a **definition** — a complete description of what primitives it consists of, how it looks under different conditions, and how it responds to state changes.
```dart
final definition = VisualDefinition(
id: 'my-type',
type: 'my-type',
shape2d: Shape2D(
primitives: [
RectPrimitive(
CommonAttributes(id: 'body', fill: SolidFill(CanvasColor(200, 200, 255))),
width: 120, height: 60, cornerRadius: 8,
),
TextPrimitive(
CommonAttributes(id: 'label'),
x: 60, y: 30, content: r'${name}',
),
],
),
);
```
### Type Registry
The type registry provides 9 extension points for host applications:
| Extension Point | Description |
|----------------|-------------|
| NodeTypeDefinition | Custom node types with default visuals, ports, properties |
| EdgeTypeDefinition | Custom edge types with routing, style, connection rules |
| PortTypeDefinition | Custom port types with compatibility rules |
| CanvasLayoutStrategy | Custom layout algorithms |
| CanvasInteractionMode | Custom interaction modes |
| CanvasRenderer | Custom renderer backends |
| CustomRenderer | Foreign content area rendering |
| ConnectionValidator | Custom port connection logic |
| ExportFormat | Custom export formats |
### Layout Engine
9 built-in layout algorithms with constraint support:
```dart
final engine = LayoutEngine();
// Auto-flow layout (Sugiyama layered graph)
final result = engine.layout('auto-flow', canvas.nodes, canvas.edges);
// Force-directed layout
final result = engine.layout('force-directed', canvas.nodes, canvas.edges);
// Apply constraints
engine.layout('constraint', canvas.nodes, canvas.edges,
constraints: [
Constraint(type: ConstraintType.align, targets: ['n1', 'n2'],
params: {'axis': 'horizontal'}),
],
);
```
### CDL (Canvas Definition Language)
LLM-efficient DSL for visual definitions with round-trip guarantee:
```dart
// Parse CDL
final parser = CdlParser();
final ast = parser.parse('''
type resistor {
shape2d {
rect body { width: 120; height: 60; cornerRadius: 8; }
text label { x: 60; y: 30; content: "\${resistance}"; }
}
ports {
in: left, direction: input;
out: right, direction: output;
}
}
canvas {
node r1: resistor { x: 100; y: 100; resistance: "10k"; }
node r2: resistor { x: 300; y: 100; resistance: "22k"; }
edge r1.out -> r2.in
}
''');
// Serialize to CDL
final serializer = CdlSerializer();
final cdlText = serializer.serialize(canvas.nodes, canvas.edges, canvas.groups);
```
### Event System
Full event bus with wildcard matching and undo/redo:
```dart
// Listen for all node events
canvas.on('node.*', (event) {
// Handles node.create, node.delete, node.move, etc.
});
// Undo/redo support
canvas.undo();
canvas.redo();
```
### Collaboration Display
Remote collaboration visuals (sync logic is host app responsibility):
```dart
// Show remote cursor
canvas.setCursor('user-1', Position(200, 300), name: 'Alice');
// Show remote selection
canvas.setPresence('user-1', ['node-1', 'node-2']);
// Lock element for editing
canvas.collaboration.setEditLock('node-1', userId: 'user-1');
```
### Large-Scale Support
Automatic performance optimization based on element count:
```dart
// Spatial indexing for fast queries
final index = RTreeIndex();
index.insert('node-1', Rect(100, 100, 120, 60));
final nearbyElements = index.query(Rect(0, 0, 500, 500));
// Virtualization for 10,000+ elements
final virtualization = Virtualization(bufferRatio: 1.5);
final result = virtualization.compute(viewport, allNodes, index);
// result.fullElements — render in detail
// result.metadataOnly — render simplified
// Automatic strategy selection
final selector = PerformanceStrategySelector();
final strategy = selector.select(elementCount);
// < 100: immediate, 100-1000: culling+LOD, 1000-10000: cache, 10000+: virtualization
```
## Architecture
```
lib/
├── src/
│ ├── core/ # Foundation types
│ │ ├── common/ # Position, Size, Rect, Color, Transform, Matrix3, Vector3
│ │ ├── graph_model/ # CanvasNode, CanvasPort, CanvasEdge, CanvasGroup
│ │ ├── visual_definition/ # VisualDefinition, Primitives, Styles, Filters
│ │ ├── type_registry/ # TypeRegistry, Schema, Type definitions
│ │ └── surface/ # CanvasSurface, Grid, Snap, Rulers, Pages
│ ├── feature/ # Feature modules
│ │ ├── layout/ # LayoutEngine + 9 algorithms + edge routing
│ │ ├── view/ # SemanticZoom, Layers, Viewports, Camera
│ │ ├── interaction/ # SelectionManager, Shortcuts, Gestures
│ │ ├── event/ # EventBus, HistoryManager, Subscriptions
│ │ ├── animation/ # AnimationSystem, Easing functions
│ │ ├── cdl/ # CDL Lexer, Parser, Serializer, AST
│ │ ├── collaboration/ # Remote cursors, presence, edit locks
│ │ ├── search/ # Full-text search with scoring
│ │ └── large_scale/ # Virtualization, SpatialIndex, Minimap
│ ├── rendering/ # Render pipeline
│ │ ├── pipeline/ # 10-stage RenderPipeline, RenderScene
│ │ ├── renderer/ # Abstract CanvasRenderer, CustomRenderer
│ │ └── cache/ # 3-layer CacheManager (layout, raster, geometry)
│ └── api/ # Public API
│ ├── canvas.dart # Canvas facade (single entry point)
│ ├── error/ # 30+ typed error classes
│ └── serialization/ # JSON, CDL, Export/Import
└── mcp_canvas.dart # Public barrel file
```
## Issues and Feedback
Please file any issues, bugs, or feature requests in our [issue tracker](https://github.com/app-appplayer/mcp_canvas/issues).
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
Connection Info
You Might Also Like
everything-claude-code
Complete Claude Code configuration collection - agents, skills, hooks,...
markitdown
MarkItDown-MCP is a lightweight server for converting URIs to Markdown.
cc-switch
All-in-One Assistant for Claude Code, Codex & Gemini CLI across platforms.
servers
Model Context Protocol Servers
servers
Model Context Protocol Servers
Time
A Model Context Protocol server for time and timezone conversions.