@coral-viz/mcp-server 0.2.3
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/LICENSE +4 -0
- package/README.md +17 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +87 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/convert.d.ts +59 -0
- package/dist/tools/convert.d.ts.map +1 -0
- package/dist/tools/convert.js +152 -0
- package/dist/tools/convert.js.map +1 -0
- package/dist/tools/explain.d.ts +36 -0
- package/dist/tools/explain.d.ts.map +1 -0
- package/dist/tools/explain.js +393 -0
- package/dist/tools/explain.js.map +1 -0
- package/dist/tools/generate.d.ts +38 -0
- package/dist/tools/generate.d.ts.map +1 -0
- package/dist/tools/generate.js +242 -0
- package/dist/tools/generate.js.map +1 -0
- package/dist/tools/layout.d.ts +97 -0
- package/dist/tools/layout.d.ts.map +1 -0
- package/dist/tools/layout.js +142 -0
- package/dist/tools/layout.js.map +1 -0
- package/dist/tools/render.d.ts +58 -0
- package/dist/tools/render.d.ts.map +1 -0
- package/dist/tools/render.js +150 -0
- package/dist/tools/render.js.map +1 -0
- package/dist/tools/validate.d.ts +27 -0
- package/dist/tools/validate.d.ts.map +1 -0
- package/dist/tools/validate.js +55 -0
- package/dist/tools/validate.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/** Generate deterministic SVG or standalone HTML from GraphIR or Coral DSL. */
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { validateIR } from '@graph-ir/core';
|
|
4
|
+
import { renderHtml, renderSvg } from '@coral-viz/render';
|
|
5
|
+
import { computeLayout, readGraph } from './layout.js';
|
|
6
|
+
export const renderTool = {
|
|
7
|
+
name: 'coral_render',
|
|
8
|
+
description: 'Generate a deterministic SVG or standalone HTML visualization of a Coral diagram or Graph-IR.',
|
|
9
|
+
inputSchema: {
|
|
10
|
+
type: 'object',
|
|
11
|
+
properties: {
|
|
12
|
+
content: { type: 'string', description: 'Graph-IR JSON or Coral DSL to render' },
|
|
13
|
+
options: {
|
|
14
|
+
type: 'object',
|
|
15
|
+
description: 'Rendering options',
|
|
16
|
+
properties: {
|
|
17
|
+
format: {
|
|
18
|
+
type: 'string',
|
|
19
|
+
enum: ['svg', 'html'],
|
|
20
|
+
description: 'Output document format',
|
|
21
|
+
default: 'svg',
|
|
22
|
+
},
|
|
23
|
+
direction: {
|
|
24
|
+
type: 'string',
|
|
25
|
+
enum: ['RIGHT', 'DOWN', 'LEFT', 'UP'],
|
|
26
|
+
description: 'Layout direction for nodes without complete geometry',
|
|
27
|
+
default: 'RIGHT',
|
|
28
|
+
},
|
|
29
|
+
theme: {
|
|
30
|
+
type: 'string',
|
|
31
|
+
enum: ['light', 'dark'],
|
|
32
|
+
description: 'Color theme',
|
|
33
|
+
default: 'light',
|
|
34
|
+
},
|
|
35
|
+
nodeSpacing: { type: 'number', description: 'Spacing between nodes', default: 50 },
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
required: ['content'],
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
const RenderOptionsSchema = z.object({
|
|
43
|
+
format: z.enum(['svg', 'html']).default('svg'),
|
|
44
|
+
direction: z.enum(['RIGHT', 'DOWN', 'LEFT', 'UP']).default('RIGHT'),
|
|
45
|
+
theme: z.enum(['light', 'dark']).default('light'),
|
|
46
|
+
nodeSpacing: z.number().positive().default(50),
|
|
47
|
+
});
|
|
48
|
+
const RenderArgsSchema = z.object({
|
|
49
|
+
content: z.string(),
|
|
50
|
+
options: RenderOptionsSchema.optional(),
|
|
51
|
+
});
|
|
52
|
+
function flattenNodes(nodes, offsetX = 0, offsetY = 0) {
|
|
53
|
+
return nodes.flatMap((node) => {
|
|
54
|
+
const x = offsetX + (node.position?.x ?? 0);
|
|
55
|
+
const y = offsetY + (node.position?.y ?? 0);
|
|
56
|
+
const { children, ...rest } = node;
|
|
57
|
+
return [
|
|
58
|
+
{ ...rest, position: { x, y } },
|
|
59
|
+
...flattenNodes(children ?? [], x, y),
|
|
60
|
+
];
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
function everyNodeHasPosition(nodes) {
|
|
64
|
+
return nodes.every((node) => node.position !== undefined && everyNodeHasPosition(node.children ?? []));
|
|
65
|
+
}
|
|
66
|
+
function someNodeHasPosition(nodes) {
|
|
67
|
+
return nodes.some((node) => node.position !== undefined || someNodeHasPosition(node.children ?? []));
|
|
68
|
+
}
|
|
69
|
+
async function toRenderGraph(content, direction, nodeSpacing) {
|
|
70
|
+
let graph;
|
|
71
|
+
try {
|
|
72
|
+
graph = readGraph(content);
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
const validation = validateIR(graph);
|
|
78
|
+
if (!validation.valid)
|
|
79
|
+
return null;
|
|
80
|
+
if (graph.nodes.length === 0)
|
|
81
|
+
return { nodes: [], edges: graph.edges };
|
|
82
|
+
// Complete supplied geometry is authoritative, including relative child
|
|
83
|
+
// positions. Rendering must not silently replace manual layout with ELK.
|
|
84
|
+
if (everyNodeHasPosition(graph.nodes)) {
|
|
85
|
+
return { nodes: flattenNodes(graph.nodes), edges: graph.edges };
|
|
86
|
+
}
|
|
87
|
+
const layout = await computeLayout(graph, {
|
|
88
|
+
algorithm: 'layered',
|
|
89
|
+
direction,
|
|
90
|
+
nodeSpacing,
|
|
91
|
+
layerSpacing: nodeSpacing + 30,
|
|
92
|
+
});
|
|
93
|
+
const layoutNodes = new Map(layout.nodes.map((node) => [node.id, node]));
|
|
94
|
+
const materialize = (nodes, chosenParent, layoutParent) => nodes.flatMap((node) => {
|
|
95
|
+
const laid = layoutNodes.get(node.id);
|
|
96
|
+
const relativeLayout = laid && layoutParent
|
|
97
|
+
? { x: laid.x - layoutParent.x, y: laid.y - layoutParent.y }
|
|
98
|
+
: { x: laid?.x ?? 0, y: laid?.y ?? 0 };
|
|
99
|
+
const position = node.position
|
|
100
|
+
? {
|
|
101
|
+
x: (chosenParent?.x ?? 0) + node.position.x,
|
|
102
|
+
y: (chosenParent?.y ?? 0) + node.position.y,
|
|
103
|
+
}
|
|
104
|
+
: chosenParent
|
|
105
|
+
? { x: chosenParent.x + relativeLayout.x, y: chosenParent.y + relativeLayout.y }
|
|
106
|
+
: relativeLayout;
|
|
107
|
+
const { children, ...rest } = node;
|
|
108
|
+
const current = {
|
|
109
|
+
...rest,
|
|
110
|
+
position,
|
|
111
|
+
dimensions: node.dimensions ?? (laid
|
|
112
|
+
? { width: laid.width, height: laid.height }
|
|
113
|
+
: undefined),
|
|
114
|
+
};
|
|
115
|
+
return [current, ...materialize(children ?? [], position, laid)];
|
|
116
|
+
});
|
|
117
|
+
const sections = new Map(layout.edges.map((edge) => [edge.id, edge.sections[0]]));
|
|
118
|
+
const preserveManualGeometry = someNodeHasPosition(graph.nodes);
|
|
119
|
+
return {
|
|
120
|
+
nodes: materialize(graph.nodes),
|
|
121
|
+
edges: graph.edges.map((edge) => {
|
|
122
|
+
const section = sections.get(edge.id);
|
|
123
|
+
return section && edge.routingPoints === undefined && !preserveManualGeometry
|
|
124
|
+
? { ...edge, routingPoints: section.bendPoints }
|
|
125
|
+
: edge;
|
|
126
|
+
}),
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
export async function handleRender(args) {
|
|
130
|
+
const parsed = RenderArgsSchema.parse(args);
|
|
131
|
+
const options = RenderOptionsSchema.parse(parsed.options ?? {});
|
|
132
|
+
const graph = await toRenderGraph(parsed.content, options.direction, options.nodeSpacing);
|
|
133
|
+
if (!graph || graph.nodes.length === 0) {
|
|
134
|
+
return {
|
|
135
|
+
content: [{ type: 'text', text: 'Could not parse and validate any nodes from the input.' }],
|
|
136
|
+
isError: true,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
const document = options.format === 'html'
|
|
140
|
+
? renderHtml(graph, { theme: options.theme })
|
|
141
|
+
: renderSvg(graph, { theme: options.theme });
|
|
142
|
+
const label = options.format.toUpperCase();
|
|
143
|
+
return {
|
|
144
|
+
content: [{
|
|
145
|
+
type: 'text',
|
|
146
|
+
text: `Generated ${label} for ${graph.nodes.length} nodes, ${graph.edges.length} edges.\n\n${document}`,
|
|
147
|
+
}],
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/tools/render.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export declare const validateTool: {
|
|
2
|
+
name: string;
|
|
3
|
+
description: string;
|
|
4
|
+
inputSchema: {
|
|
5
|
+
type: "object";
|
|
6
|
+
properties: {
|
|
7
|
+
content: {
|
|
8
|
+
type: string;
|
|
9
|
+
description: string;
|
|
10
|
+
};
|
|
11
|
+
strict: {
|
|
12
|
+
type: string;
|
|
13
|
+
description: string;
|
|
14
|
+
default: boolean;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
required: string[];
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
export declare function handleValidate(args: unknown): Promise<{
|
|
21
|
+
isError?: boolean | undefined;
|
|
22
|
+
content: {
|
|
23
|
+
type: "text";
|
|
24
|
+
text: string;
|
|
25
|
+
}[];
|
|
26
|
+
}>;
|
|
27
|
+
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/tools/validate.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;CAWxB,CAAC;AAQF,wBAAsB,cAAc,CAAC,IAAI,EAAE,OAAO;;;;;;GA8BjD"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/** Validate Coral DSL or Graph-IR with the shared 0.2 contracts. */
|
|
2
|
+
import { validateIR } from '@graph-ir/core';
|
|
3
|
+
import { parse } from '@coral-viz/language';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
export const validateTool = {
|
|
6
|
+
name: 'coral_validate',
|
|
7
|
+
description: 'Validate Coral DSL or Graph-IR JSON for syntax, schema, and reference errors.',
|
|
8
|
+
inputSchema: {
|
|
9
|
+
type: 'object',
|
|
10
|
+
properties: {
|
|
11
|
+
content: { type: 'string', description: 'Coral DSL or Graph-IR JSON to validate' },
|
|
12
|
+
strict: { type: 'boolean', description: 'Treat warnings as errors', default: false },
|
|
13
|
+
},
|
|
14
|
+
required: ['content'],
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
const Args = z.object({ content: z.string(), strict: z.boolean().default(false) });
|
|
18
|
+
function formatIssue(issue) {
|
|
19
|
+
return `${issue.severity === 'warning' ? '⚠' : '✗'} ${issue.code}: ${issue.message}`;
|
|
20
|
+
}
|
|
21
|
+
export async function handleValidate(args) {
|
|
22
|
+
const { content, strict } = Args.parse(args);
|
|
23
|
+
const isJson = content.trimStart().startsWith('{');
|
|
24
|
+
if (isJson) {
|
|
25
|
+
let value;
|
|
26
|
+
try {
|
|
27
|
+
value = JSON.parse(content);
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
return result(false, 'graph-ir-json', 0, 0, [
|
|
31
|
+
`✗ INVALID_JSON: ${error instanceof Error ? error.message : String(error)}`,
|
|
32
|
+
]);
|
|
33
|
+
}
|
|
34
|
+
if (value && typeof value === 'object' && value.version === '1.0') {
|
|
35
|
+
value = { ...value, version: '1.0.0' };
|
|
36
|
+
}
|
|
37
|
+
const validation = validateIR(value, { strict });
|
|
38
|
+
return result(validation.valid, 'graph-ir-json', validation.stats?.nodes ?? 0, validation.stats?.edges ?? 0, [...validation.errors, ...validation.warnings].map(formatIssue));
|
|
39
|
+
}
|
|
40
|
+
const parsed = parse(content);
|
|
41
|
+
if (!parsed.success || !parsed.graph) {
|
|
42
|
+
return result(false, 'coral-dsl', 0, 0, parsed.errors.map((error) => `✗ PARSE_ERROR (line ${error.line}): ${error.message}`));
|
|
43
|
+
}
|
|
44
|
+
const validation = validateIR(parsed.graph, { strict });
|
|
45
|
+
return result(validation.valid, 'coral-dsl', validation.stats?.nodes ?? 0, validation.stats?.edges ?? 0, [...validation.errors, ...validation.warnings].map(formatIssue));
|
|
46
|
+
}
|
|
47
|
+
function result(valid, format, nodes, edges, issues) {
|
|
48
|
+
const text = [
|
|
49
|
+
`Validation: ${valid ? 'valid' : 'invalid'} ${format}`,
|
|
50
|
+
`Summary: ${nodes} nodes, ${edges} edges`,
|
|
51
|
+
...issues,
|
|
52
|
+
].join('\n');
|
|
53
|
+
return { content: [{ type: 'text', text }], ...(valid ? {} : { isError: true }) };
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/tools/validate.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@coral-viz/mcp-server",
|
|
3
|
+
"version": "0.2.3",
|
|
4
|
+
"description": "MCP server for Coral diagram parsing, conversion, and layout",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"coral-mcp": "dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "node ../../scripts/clean.mjs dist && tsc",
|
|
13
|
+
"prepack": "npm run build",
|
|
14
|
+
"dev": "tsc --watch",
|
|
15
|
+
"start": "node dist/index.js",
|
|
16
|
+
"test": "vitest",
|
|
17
|
+
"test:run": "vitest run",
|
|
18
|
+
"test:coverage": "vitest run --coverage",
|
|
19
|
+
"typecheck": "tsc --noEmit",
|
|
20
|
+
"lint": "eslint src/"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"mcp",
|
|
24
|
+
"coral",
|
|
25
|
+
"diagram",
|
|
26
|
+
"graph-ir",
|
|
27
|
+
"mermaid",
|
|
28
|
+
"graphviz",
|
|
29
|
+
"elk"
|
|
30
|
+
],
|
|
31
|
+
"author": "",
|
|
32
|
+
"license": "Apache-2.0",
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "git+https://github.com/coreyt/coral.git",
|
|
36
|
+
"directory": "packages/mcp-server"
|
|
37
|
+
},
|
|
38
|
+
"files": [
|
|
39
|
+
"dist",
|
|
40
|
+
"README.md",
|
|
41
|
+
"LICENSE"
|
|
42
|
+
],
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"@coral-viz/language": "0.2.3",
|
|
45
|
+
"@graph-ir/core": "0.2.0",
|
|
46
|
+
"@modelcontextprotocol/sdk": "1.30.0",
|
|
47
|
+
"elkjs": "0.12.0",
|
|
48
|
+
"zod": "4.5.4",
|
|
49
|
+
"@coral-viz/render": "0.2.3"
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@types/node": "24.13.3",
|
|
53
|
+
"@vitest/coverage-v8": "5.0.0",
|
|
54
|
+
"typescript": "6.0.3",
|
|
55
|
+
"vitest": "5.0.0"
|
|
56
|
+
},
|
|
57
|
+
"engines": {
|
|
58
|
+
"node": ">=24.19.0"
|
|
59
|
+
},
|
|
60
|
+
"publishConfig": {
|
|
61
|
+
"access": "public"
|
|
62
|
+
}
|
|
63
|
+
}
|