ai-diagrams-mcp 1.0.2 → 1.1.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 +40 -1
- package/dist/sharing/index.d.ts +16 -0
- package/dist/sharing/index.d.ts.map +1 -0
- package/dist/sharing/index.js +28 -0
- package/dist/sharing/index.js.map +1 -0
- package/dist/tools/render-diagram.d.ts +7 -0
- package/dist/tools/render-diagram.d.ts.map +1 -1
- package/dist/tools/render-diagram.js +40 -5
- package/dist/tools/render-diagram.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,6 +8,7 @@ An MCP (Model Context Protocol) server that renders Mermaid diagrams to an inter
|
|
|
8
8
|
- **Multiple Diagrams** - Render multiple diagrams in a single view
|
|
9
9
|
- **Mermaid Themes** - Support for default, dark, forest, and neutral themes
|
|
10
10
|
- **Light/Dark Mode** - Automatic system preference detection with manual toggle
|
|
11
|
+
- **Shareable Links** - Upload diagrams and get public HTTPS links (no account required)
|
|
11
12
|
- **Cross-Platform** - Works on macOS, Linux, and Windows
|
|
12
13
|
|
|
13
14
|
## Quick Start
|
|
@@ -257,11 +258,13 @@ The `render_diagram` tool accepts:
|
|
|
257
258
|
|
|
258
259
|
- **diagrams** - Array of `{ title?: string, code: string }` objects
|
|
259
260
|
- **theme** - Optional: `'default'` | `'dark'` | `'forest'` | `'neutral'`
|
|
261
|
+
- **share** - Optional: `true` to upload and get a public shareable link
|
|
262
|
+
- **shareExpiry** - Optional: `'1h'` | `'12h'` | `'24h'` | `'72h'` (default: `'1h'`)
|
|
260
263
|
|
|
261
264
|
## Example
|
|
262
265
|
|
|
263
266
|
```javascript
|
|
264
|
-
// Tool call
|
|
267
|
+
// Tool call - local only
|
|
265
268
|
{
|
|
266
269
|
"diagrams": [
|
|
267
270
|
{
|
|
@@ -271,6 +274,17 @@ The `render_diagram` tool accepts:
|
|
|
271
274
|
],
|
|
272
275
|
"theme": "dark"
|
|
273
276
|
}
|
|
277
|
+
|
|
278
|
+
// Tool call - with shareable link
|
|
279
|
+
{
|
|
280
|
+
"diagrams": [
|
|
281
|
+
{
|
|
282
|
+
"title": "Authentication Flow",
|
|
283
|
+
"code": "graph TD\n A[User] -->|Login| B[Auth Server]\n B -->|Token| A"
|
|
284
|
+
}
|
|
285
|
+
],
|
|
286
|
+
"share": true
|
|
287
|
+
}
|
|
274
288
|
```
|
|
275
289
|
|
|
276
290
|
## Supported Diagram Types
|
|
@@ -298,6 +312,31 @@ See [Mermaid documentation](https://mermaid.js.org/intro/) for full syntax refer
|
|
|
298
312
|
- **Reset** - Return to original view
|
|
299
313
|
- **Theme Toggle** - Switch between light, dark, and system modes
|
|
300
314
|
|
|
315
|
+
## Sharing
|
|
316
|
+
|
|
317
|
+
Generate temporary public links to share diagrams with colleagues:
|
|
318
|
+
|
|
319
|
+
```javascript
|
|
320
|
+
{
|
|
321
|
+
"diagrams": [...],
|
|
322
|
+
"share": true,
|
|
323
|
+
"shareExpiry": "24h" // Options: 1h, 12h, 24h, 72h
|
|
324
|
+
}
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
- No account required
|
|
328
|
+
- Full interactive viewer with zoom/pan
|
|
329
|
+
- Links expire automatically (default: 1h)
|
|
330
|
+
|
|
331
|
+
## Output Files
|
|
332
|
+
|
|
333
|
+
Each render creates two files in the temp directory:
|
|
334
|
+
|
|
335
|
+
- `mermaid-viewer-{uuid}.html` - Interactive viewer (opened in browser)
|
|
336
|
+
- `mermaid-source-{uuid}.json` - Diagram source for reference/iteration
|
|
337
|
+
|
|
338
|
+
The source file makes it easy to adjust and re-render diagrams.
|
|
339
|
+
|
|
301
340
|
## Development
|
|
302
341
|
|
|
303
342
|
```bash
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface ShareResult {
|
|
2
|
+
url: string;
|
|
3
|
+
expiresIn: string;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Format expiry for display
|
|
7
|
+
*/
|
|
8
|
+
export declare function formatExpiry(expiresIn: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Upload HTML to litterbox.catbox.moe (anonymous, temporary file hosting)
|
|
11
|
+
* No restrictive CSP - JavaScript execution works fully
|
|
12
|
+
*
|
|
13
|
+
* Retention options: 1h, 12h, 24h, 72h
|
|
14
|
+
*/
|
|
15
|
+
export declare function uploadToLitterbox(html: string, filename: string, time?: '1h' | '12h' | '24h' | '72h'): Promise<ShareResult>;
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sharing/index.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE,IAAI,GAAG,KAAK,GAAG,KAAK,GAAG,KAAa,GACzC,OAAO,CAAC,WAAW,CAAC,CAkBtB"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Format expiry for display
|
|
3
|
+
*/
|
|
4
|
+
export function formatExpiry(expiresIn) {
|
|
5
|
+
return `in ${expiresIn}`;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Upload HTML to litterbox.catbox.moe (anonymous, temporary file hosting)
|
|
9
|
+
* No restrictive CSP - JavaScript execution works fully
|
|
10
|
+
*
|
|
11
|
+
* Retention options: 1h, 12h, 24h, 72h
|
|
12
|
+
*/
|
|
13
|
+
export async function uploadToLitterbox(html, filename, time = '72h') {
|
|
14
|
+
const formData = new FormData();
|
|
15
|
+
formData.append('reqtype', 'fileupload');
|
|
16
|
+
formData.append('time', time);
|
|
17
|
+
formData.append('fileToUpload', new Blob([html], { type: 'text/html' }), filename);
|
|
18
|
+
const response = await fetch('https://litterbox.catbox.moe/resources/internals/api.php', {
|
|
19
|
+
method: 'POST',
|
|
20
|
+
body: formData,
|
|
21
|
+
});
|
|
22
|
+
if (!response.ok) {
|
|
23
|
+
throw new Error(`Upload failed: ${response.status} ${response.statusText}`);
|
|
24
|
+
}
|
|
25
|
+
const url = await response.text();
|
|
26
|
+
return { url: url.trim(), expiresIn: time };
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sharing/index.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,SAAiB;IAC5C,OAAO,MAAM,SAAS,EAAE,CAAC;AAC3B,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,IAAY,EACZ,QAAgB,EAChB,OAAqC,KAAK;IAE1C,MAAM,QAAQ,GAAG,IAAI,QAAQ,EAAE,CAAC;IAChC,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IACzC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,cAAc,EAAE,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;IAEnF,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,0DAA0D,EAAE;QACvF,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,QAAQ;KACf,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,kBAAkB,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;IAC9E,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IAElC,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;AAC9C,CAAC"}
|
|
@@ -10,6 +10,13 @@ export declare const renderDiagramSchema: z.ZodObject<{
|
|
|
10
10
|
forest: "forest";
|
|
11
11
|
neutral: "neutral";
|
|
12
12
|
}>>>;
|
|
13
|
+
share: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
14
|
+
shareExpiry: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
|
|
15
|
+
"1h": "1h";
|
|
16
|
+
"12h": "12h";
|
|
17
|
+
"24h": "24h";
|
|
18
|
+
"72h": "72h";
|
|
19
|
+
}>>>;
|
|
13
20
|
}, z.core.$strip>;
|
|
14
21
|
export type RenderDiagramInput = z.infer<typeof renderDiagramSchema>;
|
|
15
22
|
export declare function renderDiagram(input: RenderDiagramInput): Promise<string>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render-diagram.d.ts","sourceRoot":"","sources":["../../src/tools/render-diagram.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"render-diagram.d.ts","sourceRoot":"","sources":["../../src/tools/render-diagram.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;iBAyB9B,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAErE,wBAAsB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAmD9E"}
|
|
@@ -4,6 +4,7 @@ import { tmpdir } from 'node:os';
|
|
|
4
4
|
import { join } from 'node:path';
|
|
5
5
|
import open from 'open';
|
|
6
6
|
import { z } from 'zod';
|
|
7
|
+
import { uploadToLitterbox, formatExpiry } from '../sharing/index.js';
|
|
7
8
|
import { generateViewerHTML } from '../templates/viewer-bundle.js';
|
|
8
9
|
export const renderDiagramSchema = z.object({
|
|
9
10
|
diagrams: z
|
|
@@ -18,6 +19,16 @@ export const renderDiagramSchema = z.object({
|
|
|
18
19
|
.optional()
|
|
19
20
|
.default('default')
|
|
20
21
|
.describe('Mermaid theme to use'),
|
|
22
|
+
share: z
|
|
23
|
+
.boolean()
|
|
24
|
+
.optional()
|
|
25
|
+
.default(false)
|
|
26
|
+
.describe('Upload and return a public shareable link'),
|
|
27
|
+
shareExpiry: z
|
|
28
|
+
.enum(['1h', '12h', '24h', '72h'])
|
|
29
|
+
.optional()
|
|
30
|
+
.default('1h')
|
|
31
|
+
.describe('How long the shareable link should last (default: 1h)'),
|
|
21
32
|
});
|
|
22
33
|
export async function renderDiagram(input) {
|
|
23
34
|
// Validate input
|
|
@@ -28,15 +39,39 @@ export async function renderDiagram(input) {
|
|
|
28
39
|
theme: validated.theme,
|
|
29
40
|
});
|
|
30
41
|
// Create unique filename in temp directory
|
|
31
|
-
const
|
|
42
|
+
const uuid = randomUUID();
|
|
43
|
+
const filename = `mermaid-viewer-${uuid}.html`;
|
|
32
44
|
const filepath = join(tmpdir(), filename);
|
|
33
|
-
//
|
|
34
|
-
|
|
45
|
+
// Also save diagram source for easy reference/iteration
|
|
46
|
+
const sourceFilename = `mermaid-source-${uuid}.json`;
|
|
47
|
+
const sourceFilepath = join(tmpdir(), sourceFilename);
|
|
48
|
+
const sourceData = {
|
|
49
|
+
diagrams: validated.diagrams,
|
|
50
|
+
theme: validated.theme,
|
|
51
|
+
generatedAt: new Date().toISOString(),
|
|
52
|
+
};
|
|
53
|
+
// Write HTML file and source file
|
|
54
|
+
await Promise.all([
|
|
55
|
+
writeFile(filepath, html, 'utf-8'),
|
|
56
|
+
writeFile(sourceFilepath, JSON.stringify(sourceData, null, 2), 'utf-8'),
|
|
57
|
+
]);
|
|
35
58
|
// Open in default browser
|
|
36
59
|
await open(filepath);
|
|
37
|
-
//
|
|
60
|
+
// Build result message
|
|
38
61
|
const diagramCount = validated.diagrams.length;
|
|
39
62
|
const diagramWord = diagramCount === 1 ? 'diagram' : 'diagrams';
|
|
40
|
-
|
|
63
|
+
let result = `Successfully rendered ${diagramCount} ${diagramWord} and opened in browser.\nFile saved to: ${filepath}\nSource saved to: ${sourceFilepath}`;
|
|
64
|
+
// Upload to litterbox if sharing is enabled
|
|
65
|
+
if (validated.share) {
|
|
66
|
+
try {
|
|
67
|
+
const shareResult = await uploadToLitterbox(html, filename, validated.shareExpiry);
|
|
68
|
+
result += `\n\nShareable link: ${shareResult.url}\nExpires: ${formatExpiry(shareResult.expiresIn)}`;
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
72
|
+
result += `\n\nFailed to create shareable link: ${message}`;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return result;
|
|
41
76
|
}
|
|
42
77
|
//# sourceMappingURL=render-diagram.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render-diagram.js","sourceRoot":"","sources":["../../src/tools/render-diagram.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,kBAAkB,EAAqB,MAAM,+BAA+B,CAAC;AAEtF,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,QAAQ,EAAE,CAAC;SACR,KAAK,CACJ,CAAC,CAAC,MAAM,CAAC;QACP,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC;QACvE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;KAClD,CAAC,CACH;SACA,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CAAC,6BAA6B,CAAC;IAC1C,KAAK,EAAE,CAAC;SACL,IAAI,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;SAC9C,QAAQ,EAAE;SACV,OAAO,CAAC,SAAS,CAAC;SAClB,QAAQ,CAAC,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"render-diagram.js","sourceRoot":"","sources":["../../src/tools/render-diagram.ts"],"names":[],"mappings":"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"}
|