@visual-layer/mcp-server 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/dist/bin.d.ts +3 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +17 -0
- package/dist/bin.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +14 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +201 -0
- package/dist/server.js.map +1 -0
- package/dist/state.d.ts +38 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +65 -0
- package/dist/state.js.map +1 -0
- package/package.json +40 -0
package/dist/bin.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":""}
|
package/dist/bin.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* MCP stdio entrypoint. Launched by Claude Code / Codex as a subprocess.
|
|
4
|
+
* All logs go to stderr; stdout is the JSON-RPC transport.
|
|
5
|
+
*/
|
|
6
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
7
|
+
import { createServer } from './server.js';
|
|
8
|
+
async function main() {
|
|
9
|
+
const { server } = createServer();
|
|
10
|
+
const transport = new StdioServerTransport();
|
|
11
|
+
await server.connect(transport);
|
|
12
|
+
}
|
|
13
|
+
main().catch((err) => {
|
|
14
|
+
process.stderr.write(`visual-layer-mcp fatal: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
15
|
+
process.exit(1);
|
|
16
|
+
});
|
|
17
|
+
//# sourceMappingURL=bin.js.map
|
package/dist/bin.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA;;;GAGG;AACH,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,KAAK,UAAU,IAAI;IACjB,MAAM,EAAE,MAAM,EAAE,GAAG,YAAY,EAAE,CAAC;IAClC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,2BAA2B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACtG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAgE,MAAM,YAAY,CAAC"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { ServerState } from './state.js';
|
|
3
|
+
export declare const MCP_SERVER_VERSION = "0.1.0";
|
|
4
|
+
export interface CreateServerOptions {
|
|
5
|
+
state?: ServerState;
|
|
6
|
+
/** Path to a mock Figma file; when set, capture_figma uses MockFigmaClient (no network). */
|
|
7
|
+
figmaMockPath?: string;
|
|
8
|
+
figmaFileKey?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function createServer(opts?: CreateServerOptions): {
|
|
11
|
+
server: McpServer;
|
|
12
|
+
state: ServerState;
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AASpE,OAAO,EAAE,WAAW,EAAqB,MAAM,YAAY,CAAC;AAE5D,eAAO,MAAM,kBAAkB,UAAU,CAAC;AAE1C,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,4FAA4F;IAC5F,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,YAAY,CAAC,IAAI,GAAE,mBAAwB,GAAG;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,WAAW,CAAA;CAAE,CAsMtG"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP stdio server. Exposes 7 VisualLayer tools usable from Claude Code and Codex.
|
|
3
|
+
* Wraps core/figma-rest/grounding; contains no business logic of its own.
|
|
4
|
+
*
|
|
5
|
+
* Logs MUST go to stderr (§18.3) — stdout is the JSON-RPC transport.
|
|
6
|
+
*/
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
9
|
+
import { snapshotToScreenGraph, structuredError, ErrorCodes, } from '@visual-layer/core';
|
|
10
|
+
import { groundInstruction, compareGraphs, evalGrounding } from '@visual-layer/grounding';
|
|
11
|
+
import { HttpFigmaClient, MockFigmaClient, captureFigma } from '@visual-layer/figma-rest';
|
|
12
|
+
import { ServerState } from './state.js';
|
|
13
|
+
export const MCP_SERVER_VERSION = '0.1.0';
|
|
14
|
+
export function createServer(opts = {}) {
|
|
15
|
+
const state = opts.state ?? new ServerState();
|
|
16
|
+
const server = new McpServer({ name: 'visual-layer', version: MCP_SERVER_VERSION });
|
|
17
|
+
const err = (code, message, runId) => state.respond({
|
|
18
|
+
error: structuredError(code, message, { tracePath: runId ? `.visual-layer/artifacts/${runId}/trace.json` : undefined }),
|
|
19
|
+
});
|
|
20
|
+
/* 1. capture_browser */
|
|
21
|
+
server.tool('capture_browser', 'Normalize a chrome-devtools-mcp take_snapshot payload into a persisted ScreenGraph.', {
|
|
22
|
+
snapshot: z.record(z.string(), z.unknown()),
|
|
23
|
+
screenshotArtifact: z
|
|
24
|
+
.object({
|
|
25
|
+
artifactId: z.string(),
|
|
26
|
+
sha256: z.string().length(64),
|
|
27
|
+
width: z.number().int().positive(),
|
|
28
|
+
height: z.number().int().positive(),
|
|
29
|
+
mimeType: z.enum(['image/png', 'image/jpeg']),
|
|
30
|
+
})
|
|
31
|
+
.optional(),
|
|
32
|
+
viewport: z.object({ width: z.number(), height: z.number(), dpr: z.number().optional(), url: z.string().optional() }).optional(),
|
|
33
|
+
}, async (args) => {
|
|
34
|
+
try {
|
|
35
|
+
const { graph } = snapshotToScreenGraph(args.snapshot, {
|
|
36
|
+
viewport: args.viewport,
|
|
37
|
+
screenshot: args.screenshotArtifact,
|
|
38
|
+
});
|
|
39
|
+
const stored = await state.capture(graph);
|
|
40
|
+
stored.trace.info('capture_browser', { interactables: graph.interactables.length });
|
|
41
|
+
await stored.trace.flush(state.store);
|
|
42
|
+
return state.respond({
|
|
43
|
+
screenGraphId: graph.id,
|
|
44
|
+
screenGraphPath: `.visual-layer/artifacts/${stored.runId}/${graph.id}/graph.json`,
|
|
45
|
+
summary: { source: graph.source, interactables: graph.interactables.length, warnings: graph.warnings.length },
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
catch (e) {
|
|
49
|
+
return err(toCode(e), msg(e));
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
/* 2. capture_figma */
|
|
53
|
+
server.tool('capture_figma', 'Capture a Figma node into a persisted ScreenGraph (uses FIGMA_TOKEN env).', {
|
|
54
|
+
fileKey: z.string().min(1),
|
|
55
|
+
nodeId: z.string().min(1),
|
|
56
|
+
includeImage: z.boolean().optional(),
|
|
57
|
+
}, async (args) => {
|
|
58
|
+
try {
|
|
59
|
+
const client = opts.figmaMockPath
|
|
60
|
+
? new MockFigmaClient({ [args.fileKey]: JSON.parse(await readFile(opts.figmaMockPath)) })
|
|
61
|
+
: new HttpFigmaClient();
|
|
62
|
+
const { graph } = await captureFigma(client, {
|
|
63
|
+
fileKey: args.fileKey,
|
|
64
|
+
nodeId: args.nodeId,
|
|
65
|
+
includeImage: args.includeImage === true,
|
|
66
|
+
});
|
|
67
|
+
const stored = await state.capture(graph);
|
|
68
|
+
return state.respond({
|
|
69
|
+
screenGraphId: graph.id,
|
|
70
|
+
screenGraphPath: `.visual-layer/artifacts/${stored.runId}/${graph.id}/graph.json`,
|
|
71
|
+
summary: { source: graph.source, figmaNodes: (graph.figmaNodes ?? []).length, interactables: graph.interactables.length, warnings: graph.warnings.length },
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
catch (e) {
|
|
75
|
+
return err(toCode(e), msg(e));
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
/* 3. ground_instruction */
|
|
79
|
+
server.tool('ground_instruction', 'Rank interactables in a ScreenGraph against a natural-language instruction. Returns top-K candidates with score breakdown.', {
|
|
80
|
+
screenGraphId: z.string().min(1),
|
|
81
|
+
instruction: z.string().min(1),
|
|
82
|
+
topK: z.number().int().positive().max(50).optional(),
|
|
83
|
+
}, async (args) => {
|
|
84
|
+
try {
|
|
85
|
+
const { graph, runId } = state.get(args.screenGraphId);
|
|
86
|
+
const result = groundInstruction(graph, args.instruction, { topK: args.topK ?? 5 });
|
|
87
|
+
return state.respond(result, []);
|
|
88
|
+
}
|
|
89
|
+
catch (e) {
|
|
90
|
+
return err(toCode(e), msg(e));
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
/* 4. get_artifact */
|
|
94
|
+
server.tool('get_artifact', 'Lookup artifact metadata by screenGraphId + artifactId. Returns path + metadata only, never raw bytes.', {
|
|
95
|
+
screenGraphId: z.string().min(1),
|
|
96
|
+
artifactId: z.string().min(1),
|
|
97
|
+
}, async (args) => {
|
|
98
|
+
try {
|
|
99
|
+
const { runId } = state.get(args.screenGraphId);
|
|
100
|
+
const meta = await state.store.lookup(runId, args.artifactId);
|
|
101
|
+
if (!meta)
|
|
102
|
+
return err('artifact_not_found', `artifact ${args.artifactId} not in run ${runId}`, runId);
|
|
103
|
+
return state.respond({
|
|
104
|
+
path: `.visual-layer/artifacts/${runId}/${meta.artifactId}/${meta.filename}`,
|
|
105
|
+
mimeType: meta.mimeType,
|
|
106
|
+
sha256: meta.sha256,
|
|
107
|
+
byteSize: meta.byteSize,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
catch (e) {
|
|
111
|
+
return err(toCode(e), msg(e));
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
/* 5. explain_element */
|
|
115
|
+
server.tool('explain_element', 'Explain why an interactable was extracted: role, name, bbox, sources, confidence, reasoning signals.', {
|
|
116
|
+
screenGraphId: z.string().min(1),
|
|
117
|
+
interactableId: z.string().min(1),
|
|
118
|
+
}, async (args) => {
|
|
119
|
+
try {
|
|
120
|
+
const { graph } = state.get(args.screenGraphId);
|
|
121
|
+
const inter = graph.interactables.find((i) => i.id === args.interactableId);
|
|
122
|
+
if (!inter)
|
|
123
|
+
return err('element_not_found', `interactable ${args.interactableId} not in graph`);
|
|
124
|
+
const signals = [];
|
|
125
|
+
if (inter.role)
|
|
126
|
+
signals.push(`AX/DOM role is ${inter.role}`);
|
|
127
|
+
if (inter.text ?? inter.name)
|
|
128
|
+
signals.push(`Label: ${inter.text ?? inter.name}`);
|
|
129
|
+
signals.push(`bbox ${JSON.stringify(inter.bbox)} in ${inter.coordinateSpace} space`);
|
|
130
|
+
signals.push(`sources: ${inter.source.join(', ')}`);
|
|
131
|
+
if (inter.source.includes('dom') && inter.source.includes('ax'))
|
|
132
|
+
signals.push('Corroborated by both DOM and AX');
|
|
133
|
+
return state.respond({
|
|
134
|
+
element: {
|
|
135
|
+
role: inter.role,
|
|
136
|
+
name: inter.name,
|
|
137
|
+
bbox: inter.bbox,
|
|
138
|
+
sources: inter.source,
|
|
139
|
+
confidence: inter.confidence,
|
|
140
|
+
},
|
|
141
|
+
reasoningSignals: signals,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
catch (e) {
|
|
145
|
+
return err(toCode(e), msg(e));
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
/* 6. compare_graphs */
|
|
149
|
+
server.tool('compare_graphs', 'Compare two ScreenGraphs (fixture-v0): missingFromActual / extraInActual / bboxDeltas.', {
|
|
150
|
+
expectedScreenGraphId: z.string().min(1),
|
|
151
|
+
actualScreenGraphId: z.string().min(1),
|
|
152
|
+
mode: z.literal('fixture-v0').optional(),
|
|
153
|
+
}, async (args) => {
|
|
154
|
+
try {
|
|
155
|
+
const expected = state.get(args.expectedScreenGraphId).graph;
|
|
156
|
+
const actual = state.get(args.actualScreenGraphId).graph;
|
|
157
|
+
const result = compareGraphs(expected, actual, { mode: args.mode ?? 'fixture-v0' });
|
|
158
|
+
return state.respond(result);
|
|
159
|
+
}
|
|
160
|
+
catch (e) {
|
|
161
|
+
return err(toCode(e), msg(e));
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
/* 7. eval_grounding */
|
|
165
|
+
server.tool('eval_grounding', 'Fixture-only grounding eval harness. Reports top-K accuracy over a fixtures dir.', {
|
|
166
|
+
fixtureDir: z.string().min(1),
|
|
167
|
+
topK: z.number().int().positive().max(50).optional(),
|
|
168
|
+
}, async (args) => {
|
|
169
|
+
try {
|
|
170
|
+
const fixtures = await loadFixtures(args.fixtureDir);
|
|
171
|
+
const result = evalGrounding(fixtures, { topK: args.topK ?? 1 });
|
|
172
|
+
return state.respond(result);
|
|
173
|
+
}
|
|
174
|
+
catch (e) {
|
|
175
|
+
return err(toCode(e), msg(e));
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
return { server, state };
|
|
179
|
+
}
|
|
180
|
+
function toCode(e) {
|
|
181
|
+
return e.code ?? ErrorCodes.internal_error;
|
|
182
|
+
}
|
|
183
|
+
function msg(e) {
|
|
184
|
+
return e instanceof Error ? e.message : String(e);
|
|
185
|
+
}
|
|
186
|
+
async function readFile(p) {
|
|
187
|
+
const { readFile: rf } = await import('node:fs/promises');
|
|
188
|
+
return rf(p, 'utf8');
|
|
189
|
+
}
|
|
190
|
+
async function loadFixtures(dir) {
|
|
191
|
+
const { readdir, readFile: rf } = await import('node:fs/promises');
|
|
192
|
+
const { join } = await import('node:path');
|
|
193
|
+
const files = (await readdir(dir)).filter((f) => f.endsWith('.json')).sort();
|
|
194
|
+
const out = [];
|
|
195
|
+
for (const f of files) {
|
|
196
|
+
const raw = await rf(join(dir, f), 'utf8');
|
|
197
|
+
out.push(JSON.parse(raw));
|
|
198
|
+
}
|
|
199
|
+
return out;
|
|
200
|
+
}
|
|
201
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/dist/state.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-process server state. Holds an artifact store and an in-memory index of
|
|
3
|
+
* captured ScreenGraphs keyed by id. The MCP stdio server is short-lived (one
|
|
4
|
+
* process per agent session), so in-memory state is fine for MVP.
|
|
5
|
+
*/
|
|
6
|
+
import { ArtifactStore, Trace, type ScreenGraph, type Warning, structuredError } from '@visual-layer/core';
|
|
7
|
+
export interface StoredGraph {
|
|
8
|
+
graph: ScreenGraph;
|
|
9
|
+
runId: string;
|
|
10
|
+
trace: Trace;
|
|
11
|
+
}
|
|
12
|
+
export interface ServerStateOptions {
|
|
13
|
+
artifactRoot?: string;
|
|
14
|
+
responseWarnBytes?: number;
|
|
15
|
+
responseMaxBytes?: number;
|
|
16
|
+
}
|
|
17
|
+
export declare class ServerState {
|
|
18
|
+
readonly store: ArtifactStore;
|
|
19
|
+
readonly graphs: Map<string, StoredGraph>;
|
|
20
|
+
readonly responseWarnBytes: number;
|
|
21
|
+
readonly responseMaxBytes: number;
|
|
22
|
+
constructor(opts?: ServerStateOptions);
|
|
23
|
+
capture(graph: ScreenGraph): Promise<StoredGraph>;
|
|
24
|
+
get(screenGraphId: string): StoredGraph;
|
|
25
|
+
/** Build a size-guarded MCP tool response. Warns over warnBytes, truncates large arrays over maxBytes. */
|
|
26
|
+
respond(payload: unknown, extraWarnings?: Warning[]): ToolResponse;
|
|
27
|
+
}
|
|
28
|
+
export interface ToolResponse {
|
|
29
|
+
content: Array<{
|
|
30
|
+
type: 'text';
|
|
31
|
+
text: string;
|
|
32
|
+
}>;
|
|
33
|
+
isError?: boolean;
|
|
34
|
+
[key: string]: unknown;
|
|
35
|
+
}
|
|
36
|
+
export declare function notFound(screenGraphId: string): Error;
|
|
37
|
+
export { structuredError };
|
|
38
|
+
//# sourceMappingURL=state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EACL,aAAa,EACb,KAAK,EAEL,KAAK,WAAW,EAChB,KAAK,OAAO,EAEZ,eAAe,EAEhB,MAAM,oBAAoB,CAAC;AAE5B,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,WAAW,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,KAAK,CAAC;CACd;AAED,MAAM,WAAW,kBAAkB;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,qBAAa,WAAW;IACtB,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,MAAM,2BAAkC;IACjD,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;gBAEtB,IAAI,GAAE,kBAAuB;IAMnC,OAAO,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAWvD,GAAG,CAAC,aAAa,EAAE,MAAM,GAAG,WAAW;IAMvC,0GAA0G;IAC1G,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,aAAa,GAAE,OAAO,EAAO,GAAG,YAAY;CAyBvE;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,wBAAgB,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,KAAK,CAMrD;AAED,OAAO,EAAE,eAAe,EAAE,CAAC"}
|
package/dist/state.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-process server state. Holds an artifact store and an in-memory index of
|
|
3
|
+
* captured ScreenGraphs keyed by id. The MCP stdio server is short-lived (one
|
|
4
|
+
* process per agent session), so in-memory state is fine for MVP.
|
|
5
|
+
*/
|
|
6
|
+
import { ArtifactStore, Trace, ErrorCodes, warn, structuredError, } from '@visual-layer/core';
|
|
7
|
+
export class ServerState {
|
|
8
|
+
store;
|
|
9
|
+
graphs = new Map();
|
|
10
|
+
responseWarnBytes;
|
|
11
|
+
responseMaxBytes;
|
|
12
|
+
constructor(opts = {}) {
|
|
13
|
+
this.store = new ArtifactStore({ root: opts.artifactRoot });
|
|
14
|
+
this.responseWarnBytes = opts.responseWarnBytes ?? 32 * 1024;
|
|
15
|
+
this.responseMaxBytes = opts.responseMaxBytes ?? 64 * 1024;
|
|
16
|
+
}
|
|
17
|
+
async capture(graph) {
|
|
18
|
+
const runId = await this.store.ensureRun();
|
|
19
|
+
const trace = new Trace(runId);
|
|
20
|
+
await this.store.write(runId, graph.id, 'graph', JSON.stringify(graph), {
|
|
21
|
+
mimeType: 'application/json',
|
|
22
|
+
});
|
|
23
|
+
const entry = { graph, runId, trace };
|
|
24
|
+
this.graphs.set(graph.id, entry);
|
|
25
|
+
return entry;
|
|
26
|
+
}
|
|
27
|
+
get(screenGraphId) {
|
|
28
|
+
const e = this.graphs.get(screenGraphId);
|
|
29
|
+
if (!e)
|
|
30
|
+
throw notFound(screenGraphId);
|
|
31
|
+
return e;
|
|
32
|
+
}
|
|
33
|
+
/** Build a size-guarded MCP tool response. Warns over warnBytes, truncates large arrays over maxBytes. */
|
|
34
|
+
respond(payload, extraWarnings = []) {
|
|
35
|
+
let body = payload;
|
|
36
|
+
const allWarnings = [...extraWarnings, ...(body.warnings ?? [])];
|
|
37
|
+
let json = JSON.stringify({ ...body, warnings: allWarnings });
|
|
38
|
+
const bytes = Buffer.byteLength(json, 'utf8');
|
|
39
|
+
let warnings = allWarnings;
|
|
40
|
+
if (bytes > this.responseMaxBytes) {
|
|
41
|
+
// drop heavy optional fields and re-serialize
|
|
42
|
+
const slim = { ...body };
|
|
43
|
+
delete slim['candidates'];
|
|
44
|
+
delete slim['bboxDeltas'];
|
|
45
|
+
json = JSON.stringify({ ...slim, warnings, truncated: true, originalBytes: bytes });
|
|
46
|
+
warnings = [...warnings, warn('response_truncated', `response ${bytes}B > ${this.responseMaxBytes}B cap; dropped candidates/bboxDeltas`, undefined)];
|
|
47
|
+
}
|
|
48
|
+
else if (bytes > this.responseWarnBytes) {
|
|
49
|
+
warnings = [...warnings, warn('response_oversize', `response ${bytes}B > ${this.responseWarnBytes}B warn threshold`, undefined)];
|
|
50
|
+
json = JSON.stringify({ ...body, warnings });
|
|
51
|
+
}
|
|
52
|
+
const isError = body.error !== undefined;
|
|
53
|
+
return {
|
|
54
|
+
content: [{ type: 'text', text: json }],
|
|
55
|
+
...(isError ? { isError: true } : {}),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
export function notFound(screenGraphId) {
|
|
60
|
+
const e = new Error(`${ErrorCodes.graph_not_found}: screenGraphId ${screenGraphId} not in this server session; call capture_browser/capture_figma first`);
|
|
61
|
+
e.code = ErrorCodes.graph_not_found;
|
|
62
|
+
return e;
|
|
63
|
+
}
|
|
64
|
+
export { structuredError };
|
|
65
|
+
//# sourceMappingURL=state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@visual-layer/mcp-server",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MCP stdio server exposing VisualLayer tools (Claude Code + Codex)",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://gitlab.com/locotine/vision-layer.git",
|
|
10
|
+
"directory": "packages/mcp-server"
|
|
11
|
+
},
|
|
12
|
+
"publishConfig": {
|
|
13
|
+
"access": "public"
|
|
14
|
+
},
|
|
15
|
+
"main": "./dist/index.js",
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"bin": {
|
|
18
|
+
"visual-layer-mcp": "./dist/bin.js"
|
|
19
|
+
},
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"types": "./dist/index.d.ts",
|
|
23
|
+
"import": "./dist/index.js"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist"
|
|
28
|
+
],
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@modelcontextprotocol/sdk": "^1.0.4",
|
|
31
|
+
"zod": "^3.23.8",
|
|
32
|
+
"@visual-layer/core": "1.0.0",
|
|
33
|
+
"@visual-layer/grounding": "1.0.0",
|
|
34
|
+
"@visual-layer/figma-rest": "1.0.0"
|
|
35
|
+
},
|
|
36
|
+
"scripts": {
|
|
37
|
+
"build": "tsc -b",
|
|
38
|
+
"typecheck": "tsc -b"
|
|
39
|
+
}
|
|
40
|
+
}
|