@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/index.js
CHANGED
|
@@ -2743,32 +2743,19 @@ function isDirectComponent(name, components) {
|
|
|
2743
2743
|
}
|
|
2744
2744
|
|
|
2745
2745
|
// src/tools/capture.ts
|
|
2746
|
-
import { writeFile as writeFile6 } from "fs/promises";
|
|
2746
|
+
import { mkdir, writeFile as writeFile6 } from "fs/promises";
|
|
2747
|
+
import { dirname as dirname6, join as join3 } from "path";
|
|
2747
2748
|
import {
|
|
2748
2749
|
createDefaultRegistry as createDefaultRegistry2
|
|
2749
2750
|
} from "@genart-dev/core";
|
|
2750
2751
|
|
|
2751
2752
|
// src/capture/headless.ts
|
|
2752
|
-
|
|
2753
|
-
async function loadPuppeteer() {
|
|
2754
|
-
if (!cachedModule) {
|
|
2755
|
-
try {
|
|
2756
|
-
const mod = await import("puppeteer");
|
|
2757
|
-
cachedModule = mod.default ?? mod;
|
|
2758
|
-
} catch {
|
|
2759
|
-
throw new Error(
|
|
2760
|
-
"Puppeteer is required for screenshot capture. Install it with: npm install puppeteer"
|
|
2761
|
-
);
|
|
2762
|
-
}
|
|
2763
|
-
}
|
|
2764
|
-
return cachedModule;
|
|
2765
|
-
}
|
|
2753
|
+
import puppeteer from "puppeteer";
|
|
2766
2754
|
var browserInstance = null;
|
|
2767
2755
|
async function getBrowser() {
|
|
2768
2756
|
if (browserInstance && browserInstance.connected) {
|
|
2769
2757
|
return browserInstance;
|
|
2770
2758
|
}
|
|
2771
|
-
const puppeteer = await loadPuppeteer();
|
|
2772
2759
|
browserInstance = await puppeteer.launch({
|
|
2773
2760
|
headless: true,
|
|
2774
2761
|
executablePath: process.env.PUPPETEER_EXECUTABLE_PATH || void 0,
|
|
@@ -2862,8 +2849,9 @@ function generateSketchHtml(sketch, opts) {
|
|
|
2862
2849
|
}
|
|
2863
2850
|
return adapter.generateStandaloneHTML(effective);
|
|
2864
2851
|
}
|
|
2865
|
-
function
|
|
2866
|
-
|
|
2852
|
+
function deriveSnapshotPath(sketchPath, sketchId, seed) {
|
|
2853
|
+
const wsDir = dirname6(sketchPath);
|
|
2854
|
+
return join3(wsDir, "snapshots", `${sketchId}-${seed}-preview.png`);
|
|
2867
2855
|
}
|
|
2868
2856
|
async function captureScreenshot(state, input) {
|
|
2869
2857
|
state.requireWorkspace();
|
|
@@ -2896,11 +2884,12 @@ async function captureScreenshot(state, input) {
|
|
|
2896
2884
|
height,
|
|
2897
2885
|
inlineSize
|
|
2898
2886
|
});
|
|
2899
|
-
const
|
|
2887
|
+
const effectiveSeed = input.seed ?? sketch.state.seed;
|
|
2888
|
+
const previewPath = deriveSnapshotPath(loaded.path, sketchId, effectiveSeed);
|
|
2900
2889
|
const metadata = await buildScreenshotMetadata(state, multi, {
|
|
2901
2890
|
target,
|
|
2902
2891
|
sketchId,
|
|
2903
|
-
seed:
|
|
2892
|
+
seed: effectiveSeed,
|
|
2904
2893
|
previewPath
|
|
2905
2894
|
});
|
|
2906
2895
|
const previewJpegBase64 = Buffer.from(multi.inlineJpeg).toString("base64");
|
|
@@ -2921,8 +2910,10 @@ async function buildScreenshotMetadata(state, multi, info) {
|
|
|
2921
2910
|
previewPath: info.previewPath
|
|
2922
2911
|
};
|
|
2923
2912
|
if (!state.remoteMode) {
|
|
2913
|
+
await mkdir(dirname6(info.previewPath), { recursive: true });
|
|
2924
2914
|
await writeFile6(info.previewPath, multi.previewPng);
|
|
2925
2915
|
metadata.savedPreviewTo = info.previewPath;
|
|
2916
|
+
metadata.previewWritten = true;
|
|
2926
2917
|
}
|
|
2927
2918
|
return metadata;
|
|
2928
2919
|
}
|
|
@@ -2951,11 +2942,12 @@ async function captureBatch(state, input) {
|
|
|
2951
2942
|
height,
|
|
2952
2943
|
inlineSize
|
|
2953
2944
|
});
|
|
2954
|
-
const
|
|
2945
|
+
const effectiveSeed = input.seed ?? sketch.state.seed;
|
|
2946
|
+
const previewPath = deriveSnapshotPath(loaded.path, id, effectiveSeed);
|
|
2955
2947
|
const itemMetadata = await buildScreenshotMetadata(state, multi, {
|
|
2956
2948
|
target: "sketch",
|
|
2957
2949
|
sketchId: id,
|
|
2958
|
-
seed:
|
|
2950
|
+
seed: effectiveSeed,
|
|
2959
2951
|
previewPath
|
|
2960
2952
|
});
|
|
2961
2953
|
items.push({
|
|
@@ -3315,7 +3307,7 @@ function gatherRelevantSkills(aspects) {
|
|
|
3315
3307
|
|
|
3316
3308
|
// src/tools/series.ts
|
|
3317
3309
|
import { writeFile as writeFile7 } from "fs/promises";
|
|
3318
|
-
import { basename as basename8, dirname as
|
|
3310
|
+
import { basename as basename8, dirname as dirname7, resolve as resolve3 } from "path";
|
|
3319
3311
|
import {
|
|
3320
3312
|
serializeGenart as serializeGenart5,
|
|
3321
3313
|
serializeWorkspace as serializeWorkspace4
|
|
@@ -3595,7 +3587,7 @@ async function promoteSketch(state, input) {
|
|
|
3595
3587
|
...input.agent ? { agent: input.agent } : {},
|
|
3596
3588
|
...input.model ? { model: input.model } : {}
|
|
3597
3589
|
};
|
|
3598
|
-
const sourceDir =
|
|
3590
|
+
const sourceDir = dirname7(source.path);
|
|
3599
3591
|
const newPath = resolve3(sourceDir, `${newId}.genart`);
|
|
3600
3592
|
const json = serializeGenart5(promotedDef);
|
|
3601
3593
|
if (!state.remoteMode) {
|
|
@@ -3665,8 +3657,8 @@ function countBy(items) {
|
|
|
3665
3657
|
}
|
|
3666
3658
|
|
|
3667
3659
|
// src/tools/reference.ts
|
|
3668
|
-
import { copyFile, mkdir, readFile as readFile5 } from "fs/promises";
|
|
3669
|
-
import { basename as basename9, dirname as
|
|
3660
|
+
import { copyFile, mkdir as mkdir2, readFile as readFile5 } from "fs/promises";
|
|
3661
|
+
import { basename as basename9, dirname as dirname8, extname, resolve as resolve4 } from "path";
|
|
3670
3662
|
import {
|
|
3671
3663
|
serializeGenart as serializeGenart6,
|
|
3672
3664
|
serializeWorkspace as serializeWorkspace5
|
|
@@ -3721,9 +3713,9 @@ async function addReference(state, input) {
|
|
|
3721
3713
|
`Invalid reference type: '${refType}'. Valid types: ${VALID_REFERENCE_TYPES.join(", ")}`
|
|
3722
3714
|
);
|
|
3723
3715
|
}
|
|
3724
|
-
const workspaceDir =
|
|
3716
|
+
const workspaceDir = dirname8(state.workspacePath);
|
|
3725
3717
|
const refsDir = resolve4(workspaceDir, "references");
|
|
3726
|
-
await
|
|
3718
|
+
await mkdir2(refsDir, { recursive: true });
|
|
3727
3719
|
const ext = extname(input.image);
|
|
3728
3720
|
const destFilename = `${id}${ext}`;
|
|
3729
3721
|
const destPath = resolve4(refsDir, destFilename);
|
|
@@ -3811,7 +3803,7 @@ async function addReference(state, input) {
|
|
|
3811
3803
|
async function analyzeReference(state, input) {
|
|
3812
3804
|
state.requireWorkspace();
|
|
3813
3805
|
const { ref, location } = findReference(state, input.referenceId, input.seriesId, input.sketchId);
|
|
3814
|
-
const workspaceDir =
|
|
3806
|
+
const workspaceDir = dirname8(state.workspacePath);
|
|
3815
3807
|
const imagePath = resolve4(workspaceDir, ref.path);
|
|
3816
3808
|
let previewJpegBase64;
|
|
3817
3809
|
try {
|
|
@@ -3971,7 +3963,7 @@ async function extractPalette(state, input) {
|
|
|
3971
3963
|
input.sketchId
|
|
3972
3964
|
);
|
|
3973
3965
|
const count = input.count ?? 6;
|
|
3974
|
-
const workspaceDir =
|
|
3966
|
+
const workspaceDir = dirname8(state.workspacePath);
|
|
3975
3967
|
const imagePath = resolve4(workspaceDir, ref.path);
|
|
3976
3968
|
let previewJpegBase64;
|
|
3977
3969
|
try {
|
|
@@ -4048,7 +4040,7 @@ function findReference(state, referenceId, seriesId, sketchId) {
|
|
|
4048
4040
|
// src/tools/export.ts
|
|
4049
4041
|
import { createWriteStream } from "fs";
|
|
4050
4042
|
import { stat as stat4, writeFile as writeFile9 } from "fs/promises";
|
|
4051
|
-
import { dirname as
|
|
4043
|
+
import { dirname as dirname9 } from "path";
|
|
4052
4044
|
import archiver from "archiver";
|
|
4053
4045
|
import {
|
|
4054
4046
|
createDefaultRegistry as createDefaultRegistry3,
|
|
@@ -4056,7 +4048,7 @@ import {
|
|
|
4056
4048
|
} from "@genart-dev/core";
|
|
4057
4049
|
var registry4 = createDefaultRegistry3();
|
|
4058
4050
|
async function validateOutputPath(outputPath) {
|
|
4059
|
-
const parentDir =
|
|
4051
|
+
const parentDir = dirname9(outputPath);
|
|
4060
4052
|
try {
|
|
4061
4053
|
const s = await stat4(parentDir);
|
|
4062
4054
|
if (!s.isDirectory()) {
|
|
@@ -5326,20 +5318,24 @@ async function initializePluginRegistry() {
|
|
|
5326
5318
|
await registry5.register(tracePlugin);
|
|
5327
5319
|
return registry5;
|
|
5328
5320
|
}
|
|
5329
|
-
function createServer(state) {
|
|
5321
|
+
function createServer(state, options) {
|
|
5322
|
+
const captureOnly = options?.captureOnly ?? false;
|
|
5330
5323
|
const server = new McpServer(
|
|
5331
5324
|
{
|
|
5332
|
-
name: "@genart/mcp-server",
|
|
5325
|
+
name: captureOnly ? "@genart/mcp-capture" : "@genart/mcp-server",
|
|
5333
5326
|
version: "0.4.0"
|
|
5334
5327
|
},
|
|
5335
5328
|
{
|
|
5336
5329
|
capabilities: {
|
|
5337
5330
|
tools: {},
|
|
5338
|
-
resources: {},
|
|
5339
|
-
prompts: {}
|
|
5331
|
+
...!captureOnly && { resources: {}, prompts: {} }
|
|
5340
5332
|
}
|
|
5341
5333
|
}
|
|
5342
5334
|
);
|
|
5335
|
+
if (captureOnly) {
|
|
5336
|
+
registerCaptureTools(server, state);
|
|
5337
|
+
return server;
|
|
5338
|
+
}
|
|
5343
5339
|
const registryReady = initializePluginRegistry().then((registry5) => {
|
|
5344
5340
|
state.pluginRegistry = registry5;
|
|
5345
5341
|
registerPluginMcpTools(server, registry5, state);
|
|
@@ -5356,7 +5352,9 @@ function createServer(state) {
|
|
|
5356
5352
|
registerSnapshotTools(server, state);
|
|
5357
5353
|
registerKnowledgeTools(server, state);
|
|
5358
5354
|
registerDesignTools(server, state);
|
|
5359
|
-
|
|
5355
|
+
if (!state.remoteMode) {
|
|
5356
|
+
registerCaptureTools(server, state);
|
|
5357
|
+
}
|
|
5360
5358
|
registerCritiqueTools(server, state);
|
|
5361
5359
|
registerSeriesTools(server, state);
|
|
5362
5360
|
registerReferenceTools(server, state);
|
|
@@ -6066,7 +6064,7 @@ function registerSnapshotTools(server, state) {
|
|
|
6066
6064
|
function registerCaptureTools(server, state) {
|
|
6067
6065
|
server.tool(
|
|
6068
6066
|
"capture_screenshot",
|
|
6069
|
-
"Capture a screenshot of a sketch. Returns metadata as text + a small inline JPEG image for visual review. In
|
|
6067
|
+
"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.",
|
|
6070
6068
|
{
|
|
6071
6069
|
target: z2.enum(["selected", "sketch"]).optional().describe("What to capture (default: selected)"),
|
|
6072
6070
|
sketchId: z2.string().optional().describe("Required when target is 'sketch'"),
|
|
@@ -6079,6 +6077,7 @@ function registerCaptureTools(server, state) {
|
|
|
6079
6077
|
async (args) => {
|
|
6080
6078
|
try {
|
|
6081
6079
|
const result = await captureScreenshot(state, args);
|
|
6080
|
+
console.error(`[capture_screenshot] jpeg base64 length: ${result.previewJpegBase64.length}, metadata: ${JSON.stringify(result.metadata)}`);
|
|
6082
6081
|
return {
|
|
6083
6082
|
content: [
|
|
6084
6083
|
{ type: "text", text: JSON.stringify(result.metadata, null, 2) },
|
|
@@ -6086,6 +6085,7 @@ function registerCaptureTools(server, state) {
|
|
|
6086
6085
|
]
|
|
6087
6086
|
};
|
|
6088
6087
|
} catch (e) {
|
|
6088
|
+
console.error(`[capture_screenshot] error: ${e instanceof Error ? e.message : String(e)}`);
|
|
6089
6089
|
return toolError(e instanceof Error ? e.message : String(e));
|
|
6090
6090
|
}
|
|
6091
6091
|
}
|
|
@@ -6726,14 +6726,17 @@ function registerKnowledgeTools(server, state) {
|
|
|
6726
6726
|
|
|
6727
6727
|
// src/index.ts
|
|
6728
6728
|
async function main() {
|
|
6729
|
-
const
|
|
6730
|
-
|
|
6729
|
+
const captureOnly = process.argv.includes("--capture-only");
|
|
6730
|
+
const sidecar = !captureOnly && isSidecarMode();
|
|
6731
|
+
if (captureOnly) {
|
|
6732
|
+
console.error("[genart-mcp] Starting in capture-only mode");
|
|
6733
|
+
} else if (sidecar) {
|
|
6731
6734
|
console.error("[genart-mcp] Starting in sidecar mode");
|
|
6732
6735
|
} else {
|
|
6733
6736
|
console.error("[genart-mcp] Starting in stdio mode");
|
|
6734
6737
|
}
|
|
6735
6738
|
const state = new EditorState();
|
|
6736
|
-
const server = createServer(state);
|
|
6739
|
+
const server = createServer(state, { captureOnly });
|
|
6737
6740
|
const transport = new StdioServerTransport();
|
|
6738
6741
|
await server.connect(transport);
|
|
6739
6742
|
console.error("[genart-mcp] Server connected and ready");
|