@drawio/mcp 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +285 -0
- package/package.json +47 -0
- package/src/index.js +372 -0
package/README.md
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
# Draw.io MCP Server
|
|
2
|
+
|
|
3
|
+
The official [draw.io](https://www.draw.io) MCP (Model Context Protocol) server that enables LLMs to create and open diagrams in the draw.io editor.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Open XML diagrams**: Load native draw.io/mxGraph XML format
|
|
8
|
+
- **Import CSV data**: Convert tabular data to diagrams (org charts, flowcharts, etc.)
|
|
9
|
+
- **Render Mermaid.js**: Transform Mermaid syntax into editable draw.io diagrams
|
|
10
|
+
- **URL support**: Fetch content from URLs automatically
|
|
11
|
+
- **Customizable display**: Lightbox mode, dark mode, and more
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
### Using npx (recommended)
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npx @drawio/mcp
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Global installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install -g @drawio/mcp
|
|
25
|
+
drawio-mcp
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### From source
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
git clone https://github.com/jgraph/drawio-mcp.git
|
|
32
|
+
cd drawio-mcp
|
|
33
|
+
npm install
|
|
34
|
+
npm start
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Configuration
|
|
38
|
+
|
|
39
|
+
### Claude Desktop
|
|
40
|
+
|
|
41
|
+
Add to your Claude Desktop configuration file:
|
|
42
|
+
|
|
43
|
+
**macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
44
|
+
**Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
45
|
+
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"mcpServers": {
|
|
49
|
+
"drawio": {
|
|
50
|
+
"command": "npx",
|
|
51
|
+
"args": ["@drawio/mcp"]
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Other MCP Clients
|
|
58
|
+
|
|
59
|
+
Configure your MCP client to run the server via stdio:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
npx @drawio/mcp
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Tools
|
|
66
|
+
|
|
67
|
+
### `open_drawio_xml`
|
|
68
|
+
|
|
69
|
+
Opens the draw.io editor with XML content.
|
|
70
|
+
|
|
71
|
+
| Parameter | Type | Required | Description |
|
|
72
|
+
|-----------|------|----------|-------------|
|
|
73
|
+
| `content` | string | Yes | Draw.io XML or URL to XML |
|
|
74
|
+
| `lightbox` | boolean | No | Read-only view mode (default: false) |
|
|
75
|
+
| `dark` | string | No | "auto", "true", or "false" (default: "auto") |
|
|
76
|
+
|
|
77
|
+
### `open_drawio_csv`
|
|
78
|
+
|
|
79
|
+
Opens the draw.io editor with CSV data converted to a diagram.
|
|
80
|
+
|
|
81
|
+
| Parameter | Type | Required | Description |
|
|
82
|
+
|-----------|------|----------|-------------|
|
|
83
|
+
| `content` | string | Yes | CSV content or URL to CSV |
|
|
84
|
+
| `lightbox` | boolean | No | Read-only view mode (default: false) |
|
|
85
|
+
| `dark` | string | No | "auto", "true", or "false" (default: "auto") |
|
|
86
|
+
|
|
87
|
+
### `open_drawio_mermaid`
|
|
88
|
+
|
|
89
|
+
Opens the draw.io editor with a Mermaid.js diagram.
|
|
90
|
+
|
|
91
|
+
| Parameter | Type | Required | Description |
|
|
92
|
+
|-----------|------|----------|-------------|
|
|
93
|
+
| `content` | string | Yes | Mermaid syntax or URL |
|
|
94
|
+
| `lightbox` | boolean | No | Read-only view mode (default: false) |
|
|
95
|
+
| `dark` | string | No | "auto", "true", or "false" (default: "auto") |
|
|
96
|
+
|
|
97
|
+
## Example Prompts
|
|
98
|
+
|
|
99
|
+
Here are example prompts you can use with Claude to create diagrams.
|
|
100
|
+
|
|
101
|
+
**Important:** Claude Desktop may have multiple ways to create diagrams (artifacts, browser control, MCP tools). To ensure Claude uses the draw.io MCP, explicitly mention the tool name in your prompt.
|
|
102
|
+
|
|
103
|
+
You can also add a system instruction to your Claude Desktop project:
|
|
104
|
+
> "Always use the draw.io MCP tools (open_drawio_mermaid, open_drawio_csv, open_drawio_xml) to create diagrams. Do not use browser control or artifacts."
|
|
105
|
+
|
|
106
|
+
### Explicit MCP Tool Calls
|
|
107
|
+
|
|
108
|
+
These prompts explicitly request the draw.io MCP tools:
|
|
109
|
+
|
|
110
|
+
**Mermaid:**
|
|
111
|
+
- "Use `open_drawio_mermaid` to create a flowchart for a user login process"
|
|
112
|
+
- "Use the draw.io MCP tool `open_drawio_mermaid` to make a sequence diagram showing OAuth2 flow"
|
|
113
|
+
- "Create a state diagram with `open_drawio_mermaid` for an order lifecycle"
|
|
114
|
+
|
|
115
|
+
**CSV:**
|
|
116
|
+
- "Use `open_drawio_csv` to create an org chart for our team: CEO -> CTO, CFO; CTO -> 3 Engineers"
|
|
117
|
+
- "Use the draw.io MCP tool `open_drawio_csv` to generate a network topology diagram"
|
|
118
|
+
- "Create a microservices architecture with `open_drawio_csv`"
|
|
119
|
+
|
|
120
|
+
**XML:**
|
|
121
|
+
- "Use `open_drawio_xml` to create a detailed AWS architecture diagram with VPC, subnets, and security groups"
|
|
122
|
+
- "Use the draw.io MCP tool `open_drawio_xml` to create a floor plan with 3 offices and a conference room"
|
|
123
|
+
- "Create a network rack diagram with `open_drawio_xml` showing servers, switches, and cabling"
|
|
124
|
+
|
|
125
|
+
### Mermaid Diagrams
|
|
126
|
+
|
|
127
|
+
**Flowcharts:**
|
|
128
|
+
- "Create a flowchart showing a user login process with password validation and 2FA"
|
|
129
|
+
- "Make a diagram of a CI/CD pipeline with build, test, and deploy stages"
|
|
130
|
+
- "Draw a decision tree for troubleshooting network connectivity issues"
|
|
131
|
+
|
|
132
|
+
**Sequence Diagrams:**
|
|
133
|
+
- "Create a sequence diagram showing OAuth2 authentication flow"
|
|
134
|
+
- "Make a sequence diagram of a REST API request/response cycle"
|
|
135
|
+
- "Draw the interaction between a web browser, server, and database for a search query"
|
|
136
|
+
|
|
137
|
+
**Class Diagrams:**
|
|
138
|
+
- "Create a class diagram for a simple e-commerce system with Product, Order, and Customer classes"
|
|
139
|
+
- "Make a UML class diagram showing inheritance for a vehicle hierarchy"
|
|
140
|
+
|
|
141
|
+
**Other Mermaid Types:**
|
|
142
|
+
- "Create an entity relationship diagram for a blog with users, posts, and comments"
|
|
143
|
+
- "Make a state diagram for an order lifecycle (pending, confirmed, shipped, delivered)"
|
|
144
|
+
- "Draw a Gantt chart for a 3-month software development project"
|
|
145
|
+
|
|
146
|
+
### CSV Diagrams
|
|
147
|
+
|
|
148
|
+
**Org Charts (generated from description):**
|
|
149
|
+
- "Create an org chart for a tech startup with a CEO, CTO with 3 engineers, and CFO with 2 accountants"
|
|
150
|
+
- "Make an organizational diagram for a hospital with departments: Emergency, Surgery, Pediatrics, each with a head doctor and 2 staff"
|
|
151
|
+
- "Generate an org chart showing: John (CEO) manages Sarah (VP Sales) and Mike (VP Engineering). Sarah manages 2 sales reps, Mike manages 3 developers"
|
|
152
|
+
|
|
153
|
+
**Network/Architecture Diagrams (generated from description):**
|
|
154
|
+
- "Create a network diagram showing: Load Balancer connects to 3 Web Servers, each Web Server connects to a shared Database and Cache"
|
|
155
|
+
- "Make an AWS architecture diagram with: Users -> CloudFront -> ALB -> 2 EC2 instances -> RDS"
|
|
156
|
+
- "Generate a microservices diagram with API Gateway connecting to Auth, Users, Orders, and Payments services"
|
|
157
|
+
|
|
158
|
+
**Process/Workflow Diagrams (generated from description):**
|
|
159
|
+
- "Create a diagram showing our hiring process: Application -> HR Review -> Technical Interview -> Culture Fit -> Offer -> Onboarding"
|
|
160
|
+
- "Make a diagram of a pizza order flow from customer order through kitchen stations to delivery"
|
|
161
|
+
|
|
162
|
+
**From Existing Data:**
|
|
163
|
+
- "Create a diagram from this CSV data showing project dependencies"
|
|
164
|
+
- "Turn this spreadsheet of employees and managers into an org chart"
|
|
165
|
+
|
|
166
|
+
### XML Diagrams
|
|
167
|
+
|
|
168
|
+
**Complex Custom Diagrams:**
|
|
169
|
+
- "Create a detailed AWS architecture diagram with VPC, subnets, EC2, and RDS"
|
|
170
|
+
- "Make a custom floor plan layout with specific room dimensions"
|
|
171
|
+
- "Draw a circuit diagram with specific component placements"
|
|
172
|
+
|
|
173
|
+
**Importing Existing Diagrams:**
|
|
174
|
+
- "Open this draw.io XML file and let me edit it"
|
|
175
|
+
- "Load my existing diagram from this URL: https://example.com/diagram.xml"
|
|
176
|
+
|
|
177
|
+
## Format Examples
|
|
178
|
+
|
|
179
|
+
### Flowchart with Mermaid
|
|
180
|
+
|
|
181
|
+
```text
|
|
182
|
+
graph TD
|
|
183
|
+
A[Start] --> B{Decision}
|
|
184
|
+
B -->|Yes| C[Action 1]
|
|
185
|
+
B -->|No| D[Action 2]
|
|
186
|
+
C --> E[End]
|
|
187
|
+
D --> E
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Sequence Diagram with Mermaid
|
|
191
|
+
|
|
192
|
+
```text
|
|
193
|
+
sequenceDiagram
|
|
194
|
+
participant User
|
|
195
|
+
participant Server
|
|
196
|
+
participant Database
|
|
197
|
+
|
|
198
|
+
User->>Server: Login Request
|
|
199
|
+
Server->>Database: Validate Credentials
|
|
200
|
+
Database-->>Server: User Data
|
|
201
|
+
Server-->>User: JWT Token
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Org Chart with CSV
|
|
205
|
+
|
|
206
|
+
```csv
|
|
207
|
+
## Org Chart
|
|
208
|
+
# label: %name%<br><i style="color:gray;">%title%</i>
|
|
209
|
+
# style: rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;
|
|
210
|
+
# connect: {"from":"manager","to":"name","invert":true,"style":"curved=1;endArrow=blockThin;endFill=1;"}
|
|
211
|
+
# layout: auto
|
|
212
|
+
# nodespacing: 40
|
|
213
|
+
# levelspacing: 60
|
|
214
|
+
name,title,manager
|
|
215
|
+
Alice Johnson,CEO,
|
|
216
|
+
Bob Smith,CTO,Alice Johnson
|
|
217
|
+
Carol Williams,CFO,Alice Johnson
|
|
218
|
+
Dave Brown,Lead Engineer,Bob Smith
|
|
219
|
+
Eve Davis,Senior Engineer,Bob Smith
|
|
220
|
+
Frank Miller,Accountant,Carol Williams
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Entity List with CSV
|
|
224
|
+
|
|
225
|
+
```csv
|
|
226
|
+
## Entity Diagram
|
|
227
|
+
# label: %name%
|
|
228
|
+
# style: shape=rectangle;rounded=1;whiteSpace=wrap;html=1;
|
|
229
|
+
# connect: {"from":"connects_to","to":"name","style":"endArrow=classic;"}
|
|
230
|
+
# layout: horizontalflow
|
|
231
|
+
name,type,connects_to
|
|
232
|
+
API Gateway,service,Auth Service
|
|
233
|
+
Auth Service,service,User Database
|
|
234
|
+
User Database,database,
|
|
235
|
+
API Gateway,service,Product Service
|
|
236
|
+
Product Service,service,Product Database
|
|
237
|
+
Product Database,database,
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### Native XML
|
|
241
|
+
|
|
242
|
+
```xml
|
|
243
|
+
<mxGraphModel>
|
|
244
|
+
<root>
|
|
245
|
+
<mxCell id="0"/>
|
|
246
|
+
<mxCell id="1" parent="0"/>
|
|
247
|
+
<mxCell id="2" value="Hello World" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;"
|
|
248
|
+
vertex="1" parent="1">
|
|
249
|
+
<mxGeometry x="100" y="100" width="120" height="60" as="geometry"/>
|
|
250
|
+
</mxCell>
|
|
251
|
+
<mxCell id="3" value="Another Box" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;"
|
|
252
|
+
vertex="1" parent="1">
|
|
253
|
+
<mxGeometry x="280" y="100" width="120" height="60" as="geometry"/>
|
|
254
|
+
</mxCell>
|
|
255
|
+
<mxCell id="4" style="endArrow=classic;html=1;" edge="1" parent="1" source="2" target="3">
|
|
256
|
+
<mxGeometry relative="1" as="geometry"/>
|
|
257
|
+
</mxCell>
|
|
258
|
+
</root>
|
|
259
|
+
</mxGraphModel>
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
## How It Works
|
|
263
|
+
|
|
264
|
+
1. The MCP server receives diagram content (XML, CSV, or Mermaid)
|
|
265
|
+
2. Content is compressed using pako deflateRaw and encoded as base64
|
|
266
|
+
3. A draw.io URL is generated with the `#create` hash parameter
|
|
267
|
+
4. The URL is returned to the LLM, which can present it to the user
|
|
268
|
+
5. Opening the URL loads draw.io with the diagram ready to view/edit
|
|
269
|
+
|
|
270
|
+
## Development
|
|
271
|
+
|
|
272
|
+
```bash
|
|
273
|
+
# Install dependencies
|
|
274
|
+
npm install
|
|
275
|
+
|
|
276
|
+
# Run the server
|
|
277
|
+
npm start
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
## Related Resources
|
|
281
|
+
|
|
282
|
+
- [draw.io](https://www.draw.io) - Free online diagram editor
|
|
283
|
+
- [draw.io Desktop](https://github.com/jgraph/drawio-desktop) - Desktop application
|
|
284
|
+
- [Mermaid.js Documentation](https://mermaid.js.org/intro/)
|
|
285
|
+
- [MCP Specification](https://modelcontextprotocol.io/)
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@drawio/mcp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Official draw.io MCP server for LLMs - Open diagrams in draw.io editor",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "src/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"drawio-mcp": "./src/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"start": "node src/index.js"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"mcp",
|
|
15
|
+
"drawio",
|
|
16
|
+
"draw.io",
|
|
17
|
+
"diagrams",
|
|
18
|
+
"mermaid",
|
|
19
|
+
"csv",
|
|
20
|
+
"xml",
|
|
21
|
+
"llm",
|
|
22
|
+
"claude",
|
|
23
|
+
"anthropic"
|
|
24
|
+
],
|
|
25
|
+
"author": "JGraph Ltd",
|
|
26
|
+
"license": "Apache-2.0",
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "https://github.com/jgraph/drawio-mcp.git"
|
|
30
|
+
},
|
|
31
|
+
"homepage": "https://github.com/jgraph/drawio-mcp#readme",
|
|
32
|
+
"bugs": {
|
|
33
|
+
"url": "https://github.com/jgraph/drawio-mcp/issues"
|
|
34
|
+
},
|
|
35
|
+
"engines": {
|
|
36
|
+
"node": ">=18.0.0"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@modelcontextprotocol/sdk": "1.11.2",
|
|
40
|
+
"pako": "^2.1.0"
|
|
41
|
+
},
|
|
42
|
+
"files": [
|
|
43
|
+
"src",
|
|
44
|
+
"README.md",
|
|
45
|
+
"LICENSE"
|
|
46
|
+
]
|
|
47
|
+
}
|
package/src/index.js
ADDED
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
4
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
5
|
+
import { ListToolsRequestSchema, CallToolRequestSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
6
|
+
import pako from "pako";
|
|
7
|
+
import { exec } from "child_process";
|
|
8
|
+
|
|
9
|
+
const DRAWIO_BASE_URL = "https://app.diagrams.net/";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Opens a URL in the default browser (cross-platform)
|
|
13
|
+
*/
|
|
14
|
+
function openBrowser(url)
|
|
15
|
+
{
|
|
16
|
+
const platform = process.platform;
|
|
17
|
+
let command;
|
|
18
|
+
|
|
19
|
+
if (platform === "win32")
|
|
20
|
+
{
|
|
21
|
+
command = `start "" "${url}"`;
|
|
22
|
+
}
|
|
23
|
+
else if (platform === "darwin")
|
|
24
|
+
{
|
|
25
|
+
command = `open "${url}"`;
|
|
26
|
+
}
|
|
27
|
+
else
|
|
28
|
+
{
|
|
29
|
+
command = `xdg-open "${url}"`;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
exec(command, (error) =>
|
|
33
|
+
{
|
|
34
|
+
if (error)
|
|
35
|
+
{
|
|
36
|
+
console.error(`Failed to open browser: ${error.message}`);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Compresses data using pako deflateRaw and encodes as base64
|
|
43
|
+
* This matches the compression used by draw.io tools
|
|
44
|
+
*/
|
|
45
|
+
function compressData(data)
|
|
46
|
+
{
|
|
47
|
+
if (!data || data.length === 0)
|
|
48
|
+
{
|
|
49
|
+
return data;
|
|
50
|
+
}
|
|
51
|
+
const encoded = encodeURIComponent(data);
|
|
52
|
+
const compressed = pako.deflateRaw(encoded);
|
|
53
|
+
return Buffer.from(compressed).toString("base64");
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Generates a draw.io URL with the #create hash parameter
|
|
58
|
+
*/
|
|
59
|
+
function generateDrawioUrl(data, type, options = {})
|
|
60
|
+
{
|
|
61
|
+
const {
|
|
62
|
+
lightbox = false,
|
|
63
|
+
border = 10,
|
|
64
|
+
dark = false,
|
|
65
|
+
edit = "_blank",
|
|
66
|
+
} = options;
|
|
67
|
+
|
|
68
|
+
const compressedData = compressData(data);
|
|
69
|
+
|
|
70
|
+
const createObj = {
|
|
71
|
+
type: type,
|
|
72
|
+
compressed: true,
|
|
73
|
+
data: compressedData,
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const params = new URLSearchParams();
|
|
77
|
+
|
|
78
|
+
if (lightbox)
|
|
79
|
+
{
|
|
80
|
+
params.set("lightbox", "1");
|
|
81
|
+
params.set("edit", "_blank");
|
|
82
|
+
params.set("border", "10");
|
|
83
|
+
}
|
|
84
|
+
else
|
|
85
|
+
{
|
|
86
|
+
params.set("grid", "0");
|
|
87
|
+
params.set("pv", "0");
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (dark === true)
|
|
91
|
+
{
|
|
92
|
+
params.set("dark", "1");
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
params.set("border", border.toString());
|
|
96
|
+
params.set("edit", edit);
|
|
97
|
+
|
|
98
|
+
const createHash = "#create=" + encodeURIComponent(JSON.stringify(createObj));
|
|
99
|
+
|
|
100
|
+
// Workaround for unsupported xml type
|
|
101
|
+
if (createObj.type === "xml")
|
|
102
|
+
{
|
|
103
|
+
createHash = "#R" + compressedData;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const paramsStr = params.toString();
|
|
107
|
+
|
|
108
|
+
return DRAWIO_BASE_URL + (paramsStr ? "?" + paramsStr : "") + createHash;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Fetches content from a URL
|
|
113
|
+
*/
|
|
114
|
+
async function fetchContent(url)
|
|
115
|
+
{
|
|
116
|
+
const response = await fetch(url);
|
|
117
|
+
if (!response.ok)
|
|
118
|
+
{
|
|
119
|
+
throw new Error(`Failed to fetch ${url}: ${response.status} ${response.statusText}`);
|
|
120
|
+
}
|
|
121
|
+
return response.text();
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Determines if the input is a URL
|
|
126
|
+
*/
|
|
127
|
+
function isUrl(input)
|
|
128
|
+
{
|
|
129
|
+
try
|
|
130
|
+
{
|
|
131
|
+
new URL(input);
|
|
132
|
+
return true;
|
|
133
|
+
}
|
|
134
|
+
catch
|
|
135
|
+
{
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Define the tools
|
|
141
|
+
const tools =
|
|
142
|
+
[
|
|
143
|
+
{
|
|
144
|
+
name: "open_drawio_xml",
|
|
145
|
+
description:
|
|
146
|
+
"Opens the draw.io editor with a diagram from XML content or a URL to XML content. " +
|
|
147
|
+
"Use this to view, edit, or create diagrams in draw.io format. " +
|
|
148
|
+
"The XML should be valid draw.io/mxGraph XML format.",
|
|
149
|
+
inputSchema:
|
|
150
|
+
{
|
|
151
|
+
type: "object",
|
|
152
|
+
properties:
|
|
153
|
+
{
|
|
154
|
+
content:
|
|
155
|
+
{
|
|
156
|
+
type: "string",
|
|
157
|
+
description:
|
|
158
|
+
"The draw.io XML content or a URL pointing to XML content. " +
|
|
159
|
+
"If a URL is provided, the content will be fetched automatically.",
|
|
160
|
+
},
|
|
161
|
+
lightbox:
|
|
162
|
+
{
|
|
163
|
+
type: "boolean",
|
|
164
|
+
description: "Open in lightbox mode (read-only view). Default: false",
|
|
165
|
+
},
|
|
166
|
+
dark:
|
|
167
|
+
{
|
|
168
|
+
type: "string",
|
|
169
|
+
enum: ["auto", "true", "false"],
|
|
170
|
+
description: "Dark mode setting. Default: auto",
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
required: ["content"],
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
name: "open_drawio_csv",
|
|
178
|
+
description:
|
|
179
|
+
"Opens the draw.io editor with a diagram generated from CSV data or a URL to CSV data. " +
|
|
180
|
+
"The CSV format should follow draw.io's CSV import specification which allows " +
|
|
181
|
+
"creating org charts, flowcharts, and other diagrams from tabular data.",
|
|
182
|
+
inputSchema:
|
|
183
|
+
{
|
|
184
|
+
type: "object",
|
|
185
|
+
properties:
|
|
186
|
+
{
|
|
187
|
+
content:
|
|
188
|
+
{
|
|
189
|
+
type: "string",
|
|
190
|
+
description:
|
|
191
|
+
"The CSV content or a URL pointing to CSV content. " +
|
|
192
|
+
"If a URL is provided, the content will be fetched automatically. " +
|
|
193
|
+
"The CSV should follow draw.io's CSV import format.",
|
|
194
|
+
},
|
|
195
|
+
lightbox:
|
|
196
|
+
{
|
|
197
|
+
type: "boolean",
|
|
198
|
+
description: "Open in lightbox mode (read-only view). Default: false",
|
|
199
|
+
},
|
|
200
|
+
dark:
|
|
201
|
+
{
|
|
202
|
+
type: "string",
|
|
203
|
+
enum: ["auto", "true", "false"],
|
|
204
|
+
description: "Dark mode setting. Default: auto",
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
required: ["content"],
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
name: "open_drawio_mermaid",
|
|
212
|
+
description:
|
|
213
|
+
"Opens the draw.io editor with a diagram generated from Mermaid.js syntax or a URL to Mermaid content. " +
|
|
214
|
+
"Supports flowcharts, sequence diagrams, class diagrams, state diagrams, " +
|
|
215
|
+
"entity relationship diagrams, and more using Mermaid.js syntax.",
|
|
216
|
+
inputSchema:
|
|
217
|
+
{
|
|
218
|
+
type: "object",
|
|
219
|
+
properties:
|
|
220
|
+
{
|
|
221
|
+
content:
|
|
222
|
+
{
|
|
223
|
+
type: "string",
|
|
224
|
+
description:
|
|
225
|
+
"The Mermaid.js diagram definition or a URL pointing to Mermaid content. " +
|
|
226
|
+
"If a URL is provided, the content will be fetched automatically. " +
|
|
227
|
+
"Example: 'graph TD; A-->B; B-->C;'",
|
|
228
|
+
},
|
|
229
|
+
lightbox:
|
|
230
|
+
{
|
|
231
|
+
type: "boolean",
|
|
232
|
+
description: "Open in lightbox mode (read-only view). Default: false",
|
|
233
|
+
},
|
|
234
|
+
dark:
|
|
235
|
+
{
|
|
236
|
+
type: "string",
|
|
237
|
+
enum: ["auto", "true", "false"],
|
|
238
|
+
description: "Dark mode setting. Default: auto",
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
required: ["content"],
|
|
242
|
+
},
|
|
243
|
+
},
|
|
244
|
+
];
|
|
245
|
+
|
|
246
|
+
// Create the MCP server
|
|
247
|
+
const server = new Server(
|
|
248
|
+
{
|
|
249
|
+
name: "drawio-mcp",
|
|
250
|
+
version: "1.0.0",
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
capabilities:
|
|
254
|
+
{
|
|
255
|
+
tools: {},
|
|
256
|
+
},
|
|
257
|
+
}
|
|
258
|
+
);
|
|
259
|
+
|
|
260
|
+
// Handle tool listing
|
|
261
|
+
server.setRequestHandler(ListToolsRequestSchema, async () =>
|
|
262
|
+
{
|
|
263
|
+
return { tools };
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
// Handle tool execution
|
|
267
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) =>
|
|
268
|
+
{
|
|
269
|
+
const { name, arguments: args } = request.params;
|
|
270
|
+
|
|
271
|
+
try
|
|
272
|
+
{
|
|
273
|
+
let content;
|
|
274
|
+
let type;
|
|
275
|
+
const lightbox = args?.lightbox === true;
|
|
276
|
+
const darkArg = args?.dark;
|
|
277
|
+
const dark = darkArg === "true" ? true : darkArg === "false" ? false : "auto";
|
|
278
|
+
|
|
279
|
+
const inputContent = args?.content;
|
|
280
|
+
|
|
281
|
+
if (!inputContent)
|
|
282
|
+
{
|
|
283
|
+
return {
|
|
284
|
+
content:
|
|
285
|
+
[
|
|
286
|
+
{
|
|
287
|
+
type: "text",
|
|
288
|
+
text: "Error: content parameter is required",
|
|
289
|
+
},
|
|
290
|
+
],
|
|
291
|
+
isError: true,
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// Fetch content if it's a URL
|
|
296
|
+
if (isUrl(inputContent))
|
|
297
|
+
{
|
|
298
|
+
content = await fetchContent(inputContent);
|
|
299
|
+
}
|
|
300
|
+
else
|
|
301
|
+
{
|
|
302
|
+
content = inputContent;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
switch (name)
|
|
306
|
+
{
|
|
307
|
+
case "open_drawio_xml":
|
|
308
|
+
type = "xml";
|
|
309
|
+
break;
|
|
310
|
+
case "open_drawio_csv":
|
|
311
|
+
type = "csv";
|
|
312
|
+
break;
|
|
313
|
+
case "open_drawio_mermaid":
|
|
314
|
+
type = "mermaid";
|
|
315
|
+
break;
|
|
316
|
+
default:
|
|
317
|
+
return {
|
|
318
|
+
content:
|
|
319
|
+
[
|
|
320
|
+
{
|
|
321
|
+
type: "text",
|
|
322
|
+
text: `Error: Unknown tool "${name}"`,
|
|
323
|
+
},
|
|
324
|
+
],
|
|
325
|
+
isError: true,
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
const url = generateDrawioUrl(content, type, { lightbox, dark });
|
|
330
|
+
|
|
331
|
+
// Open the URL in the default browser
|
|
332
|
+
openBrowser(url);
|
|
333
|
+
|
|
334
|
+
return {
|
|
335
|
+
content:
|
|
336
|
+
[
|
|
337
|
+
{
|
|
338
|
+
type: "text",
|
|
339
|
+
text: `Draw.io Editor URL:\n${url}\n\nThe diagram has been opened in your default browser.`,
|
|
340
|
+
},
|
|
341
|
+
],
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
catch (error)
|
|
345
|
+
{
|
|
346
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
347
|
+
return {
|
|
348
|
+
content:
|
|
349
|
+
[
|
|
350
|
+
{
|
|
351
|
+
type: "text",
|
|
352
|
+
text: `Error: ${errorMessage}`,
|
|
353
|
+
},
|
|
354
|
+
],
|
|
355
|
+
isError: true,
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
// Start the server
|
|
361
|
+
async function main()
|
|
362
|
+
{
|
|
363
|
+
const transport = new StdioServerTransport();
|
|
364
|
+
await server.connect(transport);
|
|
365
|
+
console.error("Draw.io MCP server running on stdio");
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
main().catch((error) =>
|
|
369
|
+
{
|
|
370
|
+
console.error("Fatal error:", error);
|
|
371
|
+
process.exit(1);
|
|
372
|
+
});
|