@genart-dev/mcp-server 0.4.1 → 0.4.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/dist/index.cjs +55 -52
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +44 -41
- package/dist/index.js.map +1 -1
- package/dist/lib.cjs +56 -56
- package/dist/lib.cjs.map +1 -1
- package/dist/lib.d.cts +6 -2
- package/dist/lib.d.ts +6 -2
- package/dist/lib.js +40 -40
- package/dist/lib.js.map +1 -1
- package/package.json +2 -10
package/dist/lib.d.cts
CHANGED
|
@@ -116,7 +116,11 @@ declare class EditorState extends EventEmitter {
|
|
|
116
116
|
* Creates a McpServer instance with all tools, resources, and prompts.
|
|
117
117
|
*/
|
|
118
118
|
|
|
119
|
+
interface CreateServerOptions {
|
|
120
|
+
/** Only register capture tools (for local-only capture companion server). */
|
|
121
|
+
captureOnly?: boolean;
|
|
122
|
+
}
|
|
119
123
|
/** Create and configure the MCP server with all tools. */
|
|
120
|
-
declare function createServer(state: EditorState): McpServer;
|
|
124
|
+
declare function createServer(state: EditorState, options?: CreateServerOptions): McpServer;
|
|
121
125
|
|
|
122
|
-
export { type EditorMutationEvent, type EditorMutationType, EditorState, type EditorStateSnapshot, type LoadedSketch, createServer };
|
|
126
|
+
export { type CreateServerOptions, type EditorMutationEvent, type EditorMutationType, EditorState, type EditorStateSnapshot, type LoadedSketch, createServer };
|
package/dist/lib.d.ts
CHANGED
|
@@ -116,7 +116,11 @@ declare class EditorState extends EventEmitter {
|
|
|
116
116
|
* Creates a McpServer instance with all tools, resources, and prompts.
|
|
117
117
|
*/
|
|
118
118
|
|
|
119
|
+
interface CreateServerOptions {
|
|
120
|
+
/** Only register capture tools (for local-only capture companion server). */
|
|
121
|
+
captureOnly?: boolean;
|
|
122
|
+
}
|
|
119
123
|
/** Create and configure the MCP server with all tools. */
|
|
120
|
-
declare function createServer(state: EditorState): McpServer;
|
|
124
|
+
declare function createServer(state: EditorState, options?: CreateServerOptions): McpServer;
|
|
121
125
|
|
|
122
|
-
export { type EditorMutationEvent, type EditorMutationType, EditorState, type EditorStateSnapshot, type LoadedSketch, createServer };
|
|
126
|
+
export { type CreateServerOptions, type EditorMutationEvent, type EditorMutationType, EditorState, type EditorStateSnapshot, type LoadedSketch, createServer };
|
package/dist/lib.js
CHANGED
|
@@ -2424,32 +2424,19 @@ function isDirectComponent(name, components) {
|
|
|
2424
2424
|
}
|
|
2425
2425
|
|
|
2426
2426
|
// src/tools/capture.ts
|
|
2427
|
-
import { writeFile as writeFile5 } from "fs/promises";
|
|
2427
|
+
import { mkdir, writeFile as writeFile5 } from "fs/promises";
|
|
2428
|
+
import { dirname as dirname5, join as join3 } from "path";
|
|
2428
2429
|
import {
|
|
2429
2430
|
createDefaultRegistry as createDefaultRegistry2
|
|
2430
2431
|
} from "@genart-dev/core";
|
|
2431
2432
|
|
|
2432
2433
|
// src/capture/headless.ts
|
|
2433
|
-
|
|
2434
|
-
async function loadPuppeteer() {
|
|
2435
|
-
if (!cachedModule) {
|
|
2436
|
-
try {
|
|
2437
|
-
const mod = await import("puppeteer");
|
|
2438
|
-
cachedModule = mod.default ?? mod;
|
|
2439
|
-
} catch {
|
|
2440
|
-
throw new Error(
|
|
2441
|
-
"Puppeteer is required for screenshot capture. Install it with: npm install puppeteer"
|
|
2442
|
-
);
|
|
2443
|
-
}
|
|
2444
|
-
}
|
|
2445
|
-
return cachedModule;
|
|
2446
|
-
}
|
|
2434
|
+
import puppeteer from "puppeteer";
|
|
2447
2435
|
var browserInstance = null;
|
|
2448
2436
|
async function getBrowser() {
|
|
2449
2437
|
if (browserInstance && browserInstance.connected) {
|
|
2450
2438
|
return browserInstance;
|
|
2451
2439
|
}
|
|
2452
|
-
const puppeteer = await loadPuppeteer();
|
|
2453
2440
|
browserInstance = await puppeteer.launch({
|
|
2454
2441
|
headless: true,
|
|
2455
2442
|
executablePath: process.env.PUPPETEER_EXECUTABLE_PATH || void 0,
|
|
@@ -2543,8 +2530,9 @@ function generateSketchHtml(sketch, opts) {
|
|
|
2543
2530
|
}
|
|
2544
2531
|
return adapter.generateStandaloneHTML(effective);
|
|
2545
2532
|
}
|
|
2546
|
-
function
|
|
2547
|
-
|
|
2533
|
+
function deriveSnapshotPath(sketchPath, sketchId, seed) {
|
|
2534
|
+
const wsDir = dirname5(sketchPath);
|
|
2535
|
+
return join3(wsDir, "snapshots", `${sketchId}-${seed}-preview.png`);
|
|
2548
2536
|
}
|
|
2549
2537
|
async function captureScreenshot(state, input) {
|
|
2550
2538
|
state.requireWorkspace();
|
|
@@ -2577,11 +2565,12 @@ async function captureScreenshot(state, input) {
|
|
|
2577
2565
|
height,
|
|
2578
2566
|
inlineSize
|
|
2579
2567
|
});
|
|
2580
|
-
const
|
|
2568
|
+
const effectiveSeed = input.seed ?? sketch.state.seed;
|
|
2569
|
+
const previewPath = deriveSnapshotPath(loaded.path, sketchId, effectiveSeed);
|
|
2581
2570
|
const metadata = await buildScreenshotMetadata(state, multi, {
|
|
2582
2571
|
target,
|
|
2583
2572
|
sketchId,
|
|
2584
|
-
seed:
|
|
2573
|
+
seed: effectiveSeed,
|
|
2585
2574
|
previewPath
|
|
2586
2575
|
});
|
|
2587
2576
|
const previewJpegBase64 = Buffer.from(multi.inlineJpeg).toString("base64");
|
|
@@ -2602,8 +2591,10 @@ async function buildScreenshotMetadata(state, multi, info) {
|
|
|
2602
2591
|
previewPath: info.previewPath
|
|
2603
2592
|
};
|
|
2604
2593
|
if (!state.remoteMode) {
|
|
2594
|
+
await mkdir(dirname5(info.previewPath), { recursive: true });
|
|
2605
2595
|
await writeFile5(info.previewPath, multi.previewPng);
|
|
2606
2596
|
metadata.savedPreviewTo = info.previewPath;
|
|
2597
|
+
metadata.previewWritten = true;
|
|
2607
2598
|
}
|
|
2608
2599
|
return metadata;
|
|
2609
2600
|
}
|
|
@@ -2632,11 +2623,12 @@ async function captureBatch(state, input) {
|
|
|
2632
2623
|
height,
|
|
2633
2624
|
inlineSize
|
|
2634
2625
|
});
|
|
2635
|
-
const
|
|
2626
|
+
const effectiveSeed = input.seed ?? sketch.state.seed;
|
|
2627
|
+
const previewPath = deriveSnapshotPath(loaded.path, id, effectiveSeed);
|
|
2636
2628
|
const itemMetadata = await buildScreenshotMetadata(state, multi, {
|
|
2637
2629
|
target: "sketch",
|
|
2638
2630
|
sketchId: id,
|
|
2639
|
-
seed:
|
|
2631
|
+
seed: effectiveSeed,
|
|
2640
2632
|
previewPath
|
|
2641
2633
|
});
|
|
2642
2634
|
items.push({
|
|
@@ -2996,7 +2988,7 @@ function gatherRelevantSkills(aspects) {
|
|
|
2996
2988
|
|
|
2997
2989
|
// src/tools/series.ts
|
|
2998
2990
|
import { writeFile as writeFile6 } from "fs/promises";
|
|
2999
|
-
import { basename as basename8, dirname as
|
|
2991
|
+
import { basename as basename8, dirname as dirname6, resolve as resolve2 } from "path";
|
|
3000
2992
|
import {
|
|
3001
2993
|
serializeGenart as serializeGenart4,
|
|
3002
2994
|
serializeWorkspace as serializeWorkspace3
|
|
@@ -3276,7 +3268,7 @@ async function promoteSketch(state, input) {
|
|
|
3276
3268
|
...input.agent ? { agent: input.agent } : {},
|
|
3277
3269
|
...input.model ? { model: input.model } : {}
|
|
3278
3270
|
};
|
|
3279
|
-
const sourceDir =
|
|
3271
|
+
const sourceDir = dirname6(source.path);
|
|
3280
3272
|
const newPath = resolve2(sourceDir, `${newId}.genart`);
|
|
3281
3273
|
const json = serializeGenart4(promotedDef);
|
|
3282
3274
|
if (!state.remoteMode) {
|
|
@@ -3346,8 +3338,8 @@ function countBy(items) {
|
|
|
3346
3338
|
}
|
|
3347
3339
|
|
|
3348
3340
|
// src/tools/reference.ts
|
|
3349
|
-
import { copyFile, mkdir, readFile as readFile4 } from "fs/promises";
|
|
3350
|
-
import { basename as basename9, dirname as
|
|
3341
|
+
import { copyFile, mkdir as mkdir2, readFile as readFile4 } from "fs/promises";
|
|
3342
|
+
import { basename as basename9, dirname as dirname7, extname, resolve as resolve3 } from "path";
|
|
3351
3343
|
import {
|
|
3352
3344
|
serializeGenart as serializeGenart5,
|
|
3353
3345
|
serializeWorkspace as serializeWorkspace4
|
|
@@ -3402,9 +3394,9 @@ async function addReference(state, input) {
|
|
|
3402
3394
|
`Invalid reference type: '${refType}'. Valid types: ${VALID_REFERENCE_TYPES.join(", ")}`
|
|
3403
3395
|
);
|
|
3404
3396
|
}
|
|
3405
|
-
const workspaceDir =
|
|
3397
|
+
const workspaceDir = dirname7(state.workspacePath);
|
|
3406
3398
|
const refsDir = resolve3(workspaceDir, "references");
|
|
3407
|
-
await
|
|
3399
|
+
await mkdir2(refsDir, { recursive: true });
|
|
3408
3400
|
const ext = extname(input.image);
|
|
3409
3401
|
const destFilename = `${id}${ext}`;
|
|
3410
3402
|
const destPath = resolve3(refsDir, destFilename);
|
|
@@ -3492,7 +3484,7 @@ async function addReference(state, input) {
|
|
|
3492
3484
|
async function analyzeReference(state, input) {
|
|
3493
3485
|
state.requireWorkspace();
|
|
3494
3486
|
const { ref, location } = findReference(state, input.referenceId, input.seriesId, input.sketchId);
|
|
3495
|
-
const workspaceDir =
|
|
3487
|
+
const workspaceDir = dirname7(state.workspacePath);
|
|
3496
3488
|
const imagePath = resolve3(workspaceDir, ref.path);
|
|
3497
3489
|
let previewJpegBase64;
|
|
3498
3490
|
try {
|
|
@@ -3652,7 +3644,7 @@ async function extractPalette(state, input) {
|
|
|
3652
3644
|
input.sketchId
|
|
3653
3645
|
);
|
|
3654
3646
|
const count = input.count ?? 6;
|
|
3655
|
-
const workspaceDir =
|
|
3647
|
+
const workspaceDir = dirname7(state.workspacePath);
|
|
3656
3648
|
const imagePath = resolve3(workspaceDir, ref.path);
|
|
3657
3649
|
let previewJpegBase64;
|
|
3658
3650
|
try {
|
|
@@ -3729,7 +3721,7 @@ function findReference(state, referenceId, seriesId, sketchId) {
|
|
|
3729
3721
|
// src/tools/export.ts
|
|
3730
3722
|
import { createWriteStream } from "fs";
|
|
3731
3723
|
import { stat as stat4, writeFile as writeFile8 } from "fs/promises";
|
|
3732
|
-
import { dirname as
|
|
3724
|
+
import { dirname as dirname8 } from "path";
|
|
3733
3725
|
import archiver from "archiver";
|
|
3734
3726
|
import {
|
|
3735
3727
|
createDefaultRegistry as createDefaultRegistry3,
|
|
@@ -3737,7 +3729,7 @@ import {
|
|
|
3737
3729
|
} from "@genart-dev/core";
|
|
3738
3730
|
var registry4 = createDefaultRegistry3();
|
|
3739
3731
|
async function validateOutputPath(outputPath) {
|
|
3740
|
-
const parentDir =
|
|
3732
|
+
const parentDir = dirname8(outputPath);
|
|
3741
3733
|
try {
|
|
3742
3734
|
const s = await stat4(parentDir);
|
|
3743
3735
|
if (!s.isDirectory()) {
|
|
@@ -5007,20 +4999,24 @@ async function initializePluginRegistry() {
|
|
|
5007
4999
|
await registry5.register(tracePlugin);
|
|
5008
5000
|
return registry5;
|
|
5009
5001
|
}
|
|
5010
|
-
function createServer(state) {
|
|
5002
|
+
function createServer(state, options) {
|
|
5003
|
+
const captureOnly = options?.captureOnly ?? false;
|
|
5011
5004
|
const server = new McpServer(
|
|
5012
5005
|
{
|
|
5013
|
-
name: "@genart/mcp-server",
|
|
5006
|
+
name: captureOnly ? "@genart/mcp-capture" : "@genart/mcp-server",
|
|
5014
5007
|
version: "0.4.0"
|
|
5015
5008
|
},
|
|
5016
5009
|
{
|
|
5017
5010
|
capabilities: {
|
|
5018
5011
|
tools: {},
|
|
5019
|
-
resources: {},
|
|
5020
|
-
prompts: {}
|
|
5012
|
+
...!captureOnly && { resources: {}, prompts: {} }
|
|
5021
5013
|
}
|
|
5022
5014
|
}
|
|
5023
5015
|
);
|
|
5016
|
+
if (captureOnly) {
|
|
5017
|
+
registerCaptureTools(server, state);
|
|
5018
|
+
return server;
|
|
5019
|
+
}
|
|
5024
5020
|
const registryReady = initializePluginRegistry().then((registry5) => {
|
|
5025
5021
|
state.pluginRegistry = registry5;
|
|
5026
5022
|
registerPluginMcpTools(server, registry5, state);
|
|
@@ -5037,7 +5033,9 @@ function createServer(state) {
|
|
|
5037
5033
|
registerSnapshotTools(server, state);
|
|
5038
5034
|
registerKnowledgeTools(server, state);
|
|
5039
5035
|
registerDesignTools(server, state);
|
|
5040
|
-
|
|
5036
|
+
if (!state.remoteMode) {
|
|
5037
|
+
registerCaptureTools(server, state);
|
|
5038
|
+
}
|
|
5041
5039
|
registerCritiqueTools(server, state);
|
|
5042
5040
|
registerSeriesTools(server, state);
|
|
5043
5041
|
registerReferenceTools(server, state);
|
|
@@ -5747,7 +5745,7 @@ function registerSnapshotTools(server, state) {
|
|
|
5747
5745
|
function registerCaptureTools(server, state) {
|
|
5748
5746
|
server.tool(
|
|
5749
5747
|
"capture_screenshot",
|
|
5750
|
-
"Capture a screenshot of a sketch. Returns metadata as text + a small inline JPEG image for visual review. In
|
|
5748
|
+
"Capture a screenshot of a sketch. Returns metadata as text + a small inline JPEG image for visual review. In local mode, writes a full-res PNG to snapshots/<sketchId>-<seed>-preview.png next to the workspace. The savedPreviewTo path in metadata points to the file on disk.",
|
|
5751
5749
|
{
|
|
5752
5750
|
target: z2.enum(["selected", "sketch"]).optional().describe("What to capture (default: selected)"),
|
|
5753
5751
|
sketchId: z2.string().optional().describe("Required when target is 'sketch'"),
|
|
@@ -5760,6 +5758,7 @@ function registerCaptureTools(server, state) {
|
|
|
5760
5758
|
async (args) => {
|
|
5761
5759
|
try {
|
|
5762
5760
|
const result = await captureScreenshot(state, args);
|
|
5761
|
+
console.error(`[capture_screenshot] jpeg base64 length: ${result.previewJpegBase64.length}, metadata: ${JSON.stringify(result.metadata)}`);
|
|
5763
5762
|
return {
|
|
5764
5763
|
content: [
|
|
5765
5764
|
{ type: "text", text: JSON.stringify(result.metadata, null, 2) },
|
|
@@ -5767,6 +5766,7 @@ function registerCaptureTools(server, state) {
|
|
|
5767
5766
|
]
|
|
5768
5767
|
};
|
|
5769
5768
|
} catch (e) {
|
|
5769
|
+
console.error(`[capture_screenshot] error: ${e instanceof Error ? e.message : String(e)}`);
|
|
5770
5770
|
return toolError(e instanceof Error ? e.message : String(e));
|
|
5771
5771
|
}
|
|
5772
5772
|
}
|
|
@@ -6408,7 +6408,7 @@ function registerKnowledgeTools(server, state) {
|
|
|
6408
6408
|
// src/state.ts
|
|
6409
6409
|
import { EventEmitter } from "events";
|
|
6410
6410
|
import { readFile as readFile5 } from "fs/promises";
|
|
6411
|
-
import { dirname as
|
|
6411
|
+
import { dirname as dirname9, isAbsolute, resolve as resolve4 } from "path";
|
|
6412
6412
|
|
|
6413
6413
|
// src/sidecar.ts
|
|
6414
6414
|
function isSidecarMode() {
|
|
@@ -6502,7 +6502,7 @@ var EditorState = class extends EventEmitter {
|
|
|
6502
6502
|
}
|
|
6503
6503
|
throw new Error("No workspace is currently open");
|
|
6504
6504
|
}
|
|
6505
|
-
const resolved = resolve4(
|
|
6505
|
+
const resolved = resolve4(dirname9(this.workspacePath), file);
|
|
6506
6506
|
if (this.basePath && !resolved.startsWith(this.basePath)) {
|
|
6507
6507
|
throw new Error(`Path escapes sandbox: ${resolved}`);
|
|
6508
6508
|
}
|