flowspec-mcp 3.0.0 → 4.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 +10 -1
- package/dist/export/jsonExporter.d.ts +7 -0
- package/dist/export/jsonExporter.js +152 -0
- package/dist/export/jsonExporter.js.map +1 -0
- package/dist/server.js +4 -2
- package/dist/server.js.map +1 -1
- package/dist/tools/getJson.d.ts +21 -0
- package/dist/tools/getJson.js +23 -0
- package/dist/tools/getJson.js.map +1 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
MCP (Model Context Protocol) server for [FlowSpec](https://flowspec.app) — exposes project specifications to Claude Code and other MCP-compatible AI tools.
|
|
4
4
|
|
|
5
|
+
## v4.0.0 - What's New
|
|
6
|
+
|
|
7
|
+
- **JSON Export** (NEW): `flowspec_get_json` tool for faster parsing (100x) and smaller files (40%)
|
|
8
|
+
- **YAML Export** (Deprecated): `flowspec_get_yaml` still available for backwards compatibility
|
|
9
|
+
- **Performance**: Aligned with FlowSpec v4 normalized schema (8000x faster updates)
|
|
10
|
+
|
|
11
|
+
**Migration**: Replace `flowspec_get_yaml` with `flowspec_get_json` in your workflows.
|
|
12
|
+
|
|
5
13
|
## Quick Start
|
|
6
14
|
|
|
7
15
|
Add to your `~/.claude.json`:
|
|
@@ -53,7 +61,8 @@ Local mode connects to the FlowSpec desktop server at `http://localhost:3456`.
|
|
|
53
61
|
|
|
54
62
|
### Read Tools
|
|
55
63
|
- **`flowspec_list_projects`** — List all projects with names and dates
|
|
56
|
-
- **`
|
|
64
|
+
- **`flowspec_get_json`** — Get full JSON spec for a project (v4.0.0+, recommended)
|
|
65
|
+
- **`flowspec_get_yaml`** — Get full YAML spec for a project (deprecated, use get_json)
|
|
57
66
|
- **`flowspec_get_project`** — Get raw canvas_state JSON
|
|
58
67
|
- **`flowspec_search_nodes`** — Search nodes by label across all projects
|
|
59
68
|
- **`flowspec_get_screen_context`** — Get screen/region/element structure
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { CanvasNode, CanvasEdge, Screen } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Exports canvas state to JSON specification optimised for Claude Code.
|
|
4
|
+
* v4.0.0+ - JSON format for faster parsing and smaller file sizes.
|
|
5
|
+
* Adapted from web app — uses plain interfaces instead of @xyflow/svelte types.
|
|
6
|
+
*/
|
|
7
|
+
export declare function exportToJson(nodes: CanvasNode[], edges: CanvasEdge[], projectName?: string, screens?: Screen[]): string;
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exports canvas state to JSON specification optimised for Claude Code.
|
|
3
|
+
* v4.0.0+ - JSON format for faster parsing and smaller file sizes.
|
|
4
|
+
* Adapted from web app — uses plain interfaces instead of @xyflow/svelte types.
|
|
5
|
+
*/
|
|
6
|
+
export function exportToJson(nodes, edges, projectName = 'Untitled Project', screens = []) {
|
|
7
|
+
const exportableNodes = nodes.filter((n) => n.type !== 'image' && n.type !== 'screen');
|
|
8
|
+
const dataPointNodes = exportableNodes.filter((n) => n.type === 'datapoint');
|
|
9
|
+
const componentNodes = exportableNodes.filter((n) => n.type === 'component');
|
|
10
|
+
const transformNodes = exportableNodes.filter((n) => n.type === 'transform');
|
|
11
|
+
const tableNodes = exportableNodes.filter((n) => n.type === 'table');
|
|
12
|
+
const locationMap = buildLocationMap(dataPointNodes, componentNodes, edges);
|
|
13
|
+
// Build node label lookup for screen region export
|
|
14
|
+
const nodeLabelMap = new Map();
|
|
15
|
+
for (const n of exportableNodes) {
|
|
16
|
+
const label = n.data.label ?? 'Untitled';
|
|
17
|
+
nodeLabelMap.set(n.id, { label, type: n.type ?? 'unknown' });
|
|
18
|
+
}
|
|
19
|
+
const spec = {
|
|
20
|
+
version: '1.2.0',
|
|
21
|
+
metadata: {
|
|
22
|
+
projectName,
|
|
23
|
+
exportedAt: new Date().toISOString(),
|
|
24
|
+
nodeCount: exportableNodes.length,
|
|
25
|
+
edgeCount: edges.length,
|
|
26
|
+
},
|
|
27
|
+
dataPoints: dataPointNodes.map((node) => {
|
|
28
|
+
const data = node.data;
|
|
29
|
+
return {
|
|
30
|
+
id: node.id,
|
|
31
|
+
label: data.label,
|
|
32
|
+
type: data.type,
|
|
33
|
+
source: data.source,
|
|
34
|
+
sourceDefinition: data.sourceDefinition,
|
|
35
|
+
constraints: data.constraints,
|
|
36
|
+
locations: locationMap.get(node.id) ?? [],
|
|
37
|
+
};
|
|
38
|
+
}),
|
|
39
|
+
components: componentNodes.map((node) => {
|
|
40
|
+
const data = node.data;
|
|
41
|
+
const result = {
|
|
42
|
+
id: node.id,
|
|
43
|
+
label: data.label,
|
|
44
|
+
displays: data.displays,
|
|
45
|
+
captures: data.captures,
|
|
46
|
+
};
|
|
47
|
+
if (data.wireframeRef) {
|
|
48
|
+
result.wireframeRef = data.wireframeRef;
|
|
49
|
+
}
|
|
50
|
+
return result;
|
|
51
|
+
}),
|
|
52
|
+
transforms: transformNodes.map((node) => {
|
|
53
|
+
const data = node.data;
|
|
54
|
+
return {
|
|
55
|
+
id: node.id,
|
|
56
|
+
type: data.type,
|
|
57
|
+
description: data.description,
|
|
58
|
+
inputs: data.inputs,
|
|
59
|
+
outputs: data.outputs,
|
|
60
|
+
logic: data.logic,
|
|
61
|
+
};
|
|
62
|
+
}),
|
|
63
|
+
dataFlow: edges.filter((e) => {
|
|
64
|
+
return e.data?.edgeType !== 'contains';
|
|
65
|
+
}).map((edge) => {
|
|
66
|
+
const result = {
|
|
67
|
+
from: edge.source,
|
|
68
|
+
to: edge.target,
|
|
69
|
+
edgeType: edge.data?.edgeType ?? 'flows-to',
|
|
70
|
+
};
|
|
71
|
+
if (edge.data?.label) {
|
|
72
|
+
result.label = edge.data.label;
|
|
73
|
+
}
|
|
74
|
+
return result;
|
|
75
|
+
}),
|
|
76
|
+
};
|
|
77
|
+
// Add tables section if table nodes exist
|
|
78
|
+
if (tableNodes.length > 0) {
|
|
79
|
+
spec.tables = tableNodes.map((node) => {
|
|
80
|
+
const data = node.data;
|
|
81
|
+
const result = {
|
|
82
|
+
id: node.id,
|
|
83
|
+
label: data.label,
|
|
84
|
+
sourceType: data.sourceType,
|
|
85
|
+
columns: (data.columns ?? []).map((c) => ({ name: c.name, type: c.type })),
|
|
86
|
+
};
|
|
87
|
+
if (data.endpoint) {
|
|
88
|
+
result.endpoint = data.endpoint;
|
|
89
|
+
}
|
|
90
|
+
return result;
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
// Add screens section if screens exist
|
|
94
|
+
if (screens.length > 0) {
|
|
95
|
+
spec.screens = screens.map((sc) => ({
|
|
96
|
+
id: sc.id,
|
|
97
|
+
name: sc.name,
|
|
98
|
+
imageFilename: sc.imageFilename,
|
|
99
|
+
regions: sc.regions.map((r) => {
|
|
100
|
+
const region = {
|
|
101
|
+
id: r.id,
|
|
102
|
+
label: r.label,
|
|
103
|
+
position: {
|
|
104
|
+
x: Math.round(r.position.x * 10) / 10,
|
|
105
|
+
y: Math.round(r.position.y * 10) / 10,
|
|
106
|
+
},
|
|
107
|
+
size: {
|
|
108
|
+
width: Math.round(r.size.width * 10) / 10,
|
|
109
|
+
height: Math.round(r.size.height * 10) / 10,
|
|
110
|
+
},
|
|
111
|
+
elements: r.elementIds.map((eid) => {
|
|
112
|
+
const info = nodeLabelMap.get(eid);
|
|
113
|
+
return {
|
|
114
|
+
nodeId: eid,
|
|
115
|
+
nodeLabel: info?.label ?? 'Missing element',
|
|
116
|
+
nodeType: info?.type ?? 'unknown',
|
|
117
|
+
};
|
|
118
|
+
}),
|
|
119
|
+
};
|
|
120
|
+
if (r.componentNodeId) {
|
|
121
|
+
region.componentNodeId = r.componentNodeId;
|
|
122
|
+
}
|
|
123
|
+
return region;
|
|
124
|
+
}),
|
|
125
|
+
}));
|
|
126
|
+
}
|
|
127
|
+
return JSON.stringify(spec, null, 2);
|
|
128
|
+
}
|
|
129
|
+
function buildLocationMap(dataPoints, components, edges) {
|
|
130
|
+
const map = new Map();
|
|
131
|
+
for (const dp of dataPoints) {
|
|
132
|
+
map.set(dp.id, []);
|
|
133
|
+
}
|
|
134
|
+
for (const edge of edges) {
|
|
135
|
+
const sourceIsDataPoint = dataPoints.some((n) => n.id === edge.source);
|
|
136
|
+
const targetIsComponent = components.some((n) => n.id === edge.target);
|
|
137
|
+
if (sourceIsDataPoint && targetIsComponent) {
|
|
138
|
+
const locations = map.get(edge.source) ?? [];
|
|
139
|
+
locations.push({ component: edge.target, role: 'output' });
|
|
140
|
+
map.set(edge.source, locations);
|
|
141
|
+
}
|
|
142
|
+
const sourceIsComponent = components.some((n) => n.id === edge.source);
|
|
143
|
+
const targetIsDataPoint = dataPoints.some((n) => n.id === edge.target);
|
|
144
|
+
if (sourceIsComponent && targetIsDataPoint) {
|
|
145
|
+
const locations = map.get(edge.target) ?? [];
|
|
146
|
+
locations.push({ component: edge.source, role: 'input' });
|
|
147
|
+
map.set(edge.target, locations);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return map;
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=jsonExporter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonExporter.js","sourceRoot":"","sources":["../../src/export/jsonExporter.ts"],"names":[],"mappings":"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"}
|
package/dist/server.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
2
|
import { listProjectsSchema, handleListProjects } from './tools/listProjects.js';
|
|
3
3
|
import { getYamlSchema, handleGetYaml } from './tools/getYaml.js';
|
|
4
|
+
import { getJsonSchema, handleGetJson } from './tools/getJson.js';
|
|
4
5
|
import { getProjectSchema, handleGetProject } from './tools/getProject.js';
|
|
5
6
|
import { searchNodesSchema, handleSearchNodes } from './tools/searchNodes.js';
|
|
6
7
|
import { getScreenContextSchema, handleGetScreenContext } from './tools/getScreenContext.js';
|
|
@@ -30,11 +31,12 @@ import { MODE } from './config.js';
|
|
|
30
31
|
export function createServer() {
|
|
31
32
|
const server = new McpServer({
|
|
32
33
|
name: 'flowspec',
|
|
33
|
-
version: '
|
|
34
|
+
version: '4.0.0',
|
|
34
35
|
});
|
|
35
36
|
// ─── Read tools ──────────────────────────────────────────────────
|
|
36
37
|
server.tool('flowspec_list_projects', 'List all FlowSpec projects with names and dates', listProjectsSchema.shape, handleListProjects);
|
|
37
|
-
server.tool('flowspec_get_yaml', 'Get the full YAML spec for a FlowSpec project (optimised for Claude Code consumption)', getYamlSchema.shape, handleGetYaml);
|
|
38
|
+
server.tool('flowspec_get_yaml', 'Get the full YAML spec for a FlowSpec project (optimised for Claude Code consumption) [DEPRECATED: use flowspec_get_json]', getYamlSchema.shape, handleGetYaml);
|
|
39
|
+
server.tool('flowspec_get_json', 'Get the full JSON spec for a FlowSpec project (v4.0.0+, faster parsing, smaller files)', getJsonSchema.shape, handleGetJson);
|
|
38
40
|
server.tool('flowspec_get_project', 'Get raw canvas_state JSON for a FlowSpec project', getProjectSchema.shape, handleGetProject);
|
|
39
41
|
server.tool('flowspec_search_nodes', 'Search for nodes by label across all projects, optionally filtered by type', searchNodesSchema.shape, handleSearchNodes);
|
|
40
42
|
server.tool('flowspec_get_screen_context', 'Get screen/region/element structure for a FlowSpec project (lightweight alternative to full YAML)', getScreenContextSchema.shape, handleGetScreenContext);
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AACjF,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC9E,OAAO,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAC7F,iBAAiB;AACjB,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACpF,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACpF,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACpF,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACvF,iBAAiB;AACjB,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC9E,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AACjF,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AACjF,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AACjF,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AACjF,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AACjF,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AACjF,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAEnC,MAAM,UAAU,YAAY;IAC1B,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IAEH,oEAAoE;IAEpE,MAAM,CAAC,IAAI,CACT,wBAAwB,EACxB,iDAAiD,EACjD,kBAAkB,CAAC,KAAK,EACxB,kBAAkB,CACnB,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,mBAAmB,EACnB,
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const getJsonSchema: z.ZodObject<{
|
|
3
|
+
projectId: z.ZodString;
|
|
4
|
+
}, "strip", z.ZodTypeAny, {
|
|
5
|
+
projectId: string;
|
|
6
|
+
}, {
|
|
7
|
+
projectId: string;
|
|
8
|
+
}>;
|
|
9
|
+
export declare function handleGetJson(args: z.infer<typeof getJsonSchema>): Promise<{
|
|
10
|
+
content: {
|
|
11
|
+
type: "text";
|
|
12
|
+
text: string;
|
|
13
|
+
}[];
|
|
14
|
+
isError: boolean;
|
|
15
|
+
} | {
|
|
16
|
+
content: {
|
|
17
|
+
type: "text";
|
|
18
|
+
text: string;
|
|
19
|
+
}[];
|
|
20
|
+
isError?: undefined;
|
|
21
|
+
}>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { getProject } from '../db.js';
|
|
3
|
+
import { exportToJson } from '../export/jsonExporter.js';
|
|
4
|
+
export const getJsonSchema = z.object({
|
|
5
|
+
projectId: z.string().describe('UUID of the FlowSpec project'),
|
|
6
|
+
});
|
|
7
|
+
export async function handleGetJson(args) {
|
|
8
|
+
const project = await getProject(args.projectId);
|
|
9
|
+
if (!project) {
|
|
10
|
+
return {
|
|
11
|
+
content: [{ type: 'text', text: `Project not found: ${args.projectId}` }],
|
|
12
|
+
isError: true,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
const nodes = project.canvas_state?.nodes ?? [];
|
|
16
|
+
const edges = project.canvas_state?.edges ?? [];
|
|
17
|
+
const screens = project.canvas_state?.screens ?? [];
|
|
18
|
+
const json = exportToJson(nodes, edges, project.name, screens);
|
|
19
|
+
return {
|
|
20
|
+
content: [{ type: 'text', text: json }],
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=getJson.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getJson.js","sourceRoot":"","sources":["../../src/tools/getJson.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEzD,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,8BAA8B,CAAC;CAC/D,CAAC,CAAC;AAEH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAmC;IACrE,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAEjD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,sBAAsB,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;YAClF,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,OAAO,CAAC,YAAY,EAAE,KAAK,IAAI,EAAE,CAAC;IAChD,MAAM,KAAK,GAAG,OAAO,CAAC,YAAY,EAAE,KAAK,IAAI,EAAE,CAAC;IAChD,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,OAAO,IAAI,EAAE,CAAC;IAEpD,MAAM,IAAI,GAAG,YAAY,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAE/D,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;KACjD,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "flowspec-mcp",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "MCP server for FlowSpec — exposes project specs to Claude Code",
|
|
5
|
+
"description": "MCP server for FlowSpec — exposes project specs to Claude Code (v4: JSON export, normalized schema)",
|
|
6
6
|
"bin": {
|
|
7
7
|
"flowspec-mcp": "dist/index.js"
|
|
8
8
|
},
|