one-design-mcp 0.2.1 → 0.2.2
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 +14 -1
- package/dist/server.js +152 -24
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -103,6 +103,17 @@ the same email (`sign_in`). The session is kept in `~/.config/one-design/mcp-acc
|
|
|
103
103
|
|
|
104
104
|
Needs Node.js 20 or newer.
|
|
105
105
|
|
|
106
|
+
**One command** (adds it to Claude Desktop, Cursor and Claude Code, wherever they're installed, and
|
|
107
|
+
keeps a `.bak` of any config it changes):
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
npx -y one-design-mcp setup
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
`--dry-run` shows what it would change, `--app desktop|cursor|code` picks one app, and `--remove`
|
|
114
|
+
takes it out again. An agent with a terminal (Claude Code, Cursor) can run it for you: ask it to
|
|
115
|
+
"set up the One Design MCP server with npx -y one-design-mcp setup".
|
|
116
|
+
|
|
106
117
|
**Claude Code**
|
|
107
118
|
|
|
108
119
|
```bash
|
|
@@ -129,6 +140,8 @@ claude mcp add one-design -- node /path/to/one-design/mcp/dist/server.js
|
|
|
129
140
|
|
|
130
141
|
The build takes the site's public Supabase address and anon key from `../.env.local` (or
|
|
131
142
|
`ONE_DESIGN_SUPABASE_URL` / `ONE_DESIGN_SUPABASE_ANON_KEY`) so sign-in and checkout work.
|
|
132
|
-
`ONE_DESIGN_PAYMENTS=off` makes a free-beta build with every tool open.
|
|
143
|
+
`ONE_DESIGN_PAYMENTS=off` makes a free-beta build with every tool open. These are build settings
|
|
144
|
+
only: at run time nothing a user sets changes the plan (no environment variables, and the plan is
|
|
145
|
+
never read back from the saved session; it's checked against the account and kept in memory). Link Lock's encryption is
|
|
133
146
|
the website's own (`src/lib/linklock.ts`), bundled at build time, so links made here open on
|
|
134
147
|
one.design. Plan rules mirror `src/lib/plans.ts` and `src/lib/plan.ts`: keep `src/plan.ts` in step.
|
package/dist/server.js
CHANGED
|
@@ -1,10 +1,122 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __esm = (fn, res, err) => function __init() {
|
|
5
|
+
if (err) throw err[0];
|
|
6
|
+
try {
|
|
7
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
8
|
+
} catch (e) {
|
|
9
|
+
throw err = [e], e;
|
|
10
|
+
}
|
|
11
|
+
};
|
|
3
12
|
var __export = (target, all) => {
|
|
4
13
|
for (var name in all)
|
|
5
14
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
6
15
|
};
|
|
7
16
|
|
|
17
|
+
// src/setup.ts
|
|
18
|
+
var setup_exports = {};
|
|
19
|
+
__export(setup_exports, {
|
|
20
|
+
setup: () => setup
|
|
21
|
+
});
|
|
22
|
+
import { promises as fs9, existsSync } from "node:fs";
|
|
23
|
+
import path9 from "node:path";
|
|
24
|
+
import os7 from "node:os";
|
|
25
|
+
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
26
|
+
function entry() {
|
|
27
|
+
return { command: npxPath(), args: ["-y", "one-design-mcp@latest"] };
|
|
28
|
+
}
|
|
29
|
+
function npxPath() {
|
|
30
|
+
try {
|
|
31
|
+
const found = execFileSync2(process.platform === "win32" ? "where" : "which", ["npx"], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).split(/\r?\n/)[0].trim();
|
|
32
|
+
if (found) return found;
|
|
33
|
+
} catch {
|
|
34
|
+
}
|
|
35
|
+
const beside = path9.join(path9.dirname(process.execPath), process.platform === "win32" ? "npx.cmd" : "npx");
|
|
36
|
+
return existsSync(beside) ? beside : "npx";
|
|
37
|
+
}
|
|
38
|
+
function desktopConfig() {
|
|
39
|
+
const home = os7.homedir();
|
|
40
|
+
if (process.platform === "darwin") return path9.join(home, "Library", "Application Support", "Claude", "claude_desktop_config.json");
|
|
41
|
+
if (process.platform === "win32") return path9.join(process.env.APPDATA ?? path9.join(home, "AppData", "Roaming"), "Claude", "claude_desktop_config.json");
|
|
42
|
+
return path9.join(process.env.XDG_CONFIG_HOME ?? path9.join(home, ".config"), "Claude", "claude_desktop_config.json");
|
|
43
|
+
}
|
|
44
|
+
async function editJson(file, remove, dry) {
|
|
45
|
+
if (!existsSync(path9.dirname(file))) return "not installed here, skipped";
|
|
46
|
+
let config = {};
|
|
47
|
+
let before = "";
|
|
48
|
+
if (existsSync(file)) {
|
|
49
|
+
before = await fs9.readFile(file, "utf8");
|
|
50
|
+
try {
|
|
51
|
+
config = before.trim() ? JSON.parse(before) : {};
|
|
52
|
+
} catch {
|
|
53
|
+
return `its config isn\u2019t valid JSON, left alone: ${file}`;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const servers = { ...config.mcpServers ?? {} };
|
|
57
|
+
const had = NAME in servers;
|
|
58
|
+
if (remove) {
|
|
59
|
+
if (!had) return "not set up there, nothing to remove";
|
|
60
|
+
delete servers[NAME];
|
|
61
|
+
} else servers[NAME] = entry();
|
|
62
|
+
const after = JSON.stringify({ ...config, mcpServers: servers }, null, 2) + "\n";
|
|
63
|
+
if (after === before) return "already set up";
|
|
64
|
+
if (dry) return remove ? "would remove One Design" : had ? "would update One Design" : "would add One Design";
|
|
65
|
+
await fs9.mkdir(path9.dirname(file), { recursive: true });
|
|
66
|
+
if (before) await fs9.writeFile(`${file}.bak`, before);
|
|
67
|
+
await fs9.writeFile(file, after);
|
|
68
|
+
return `${remove ? "removed" : had ? "updated" : "added"} (${file}${before ? ", old copy saved as .bak" : ""})`;
|
|
69
|
+
}
|
|
70
|
+
function claudeCode(remove, dry) {
|
|
71
|
+
try {
|
|
72
|
+
execFileSync2(process.platform === "win32" ? "where" : "which", ["claude"], { stdio: "ignore" });
|
|
73
|
+
} catch {
|
|
74
|
+
return "not installed here, skipped";
|
|
75
|
+
}
|
|
76
|
+
const list = (() => {
|
|
77
|
+
try {
|
|
78
|
+
return execFileSync2("claude", ["mcp", "list"], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] });
|
|
79
|
+
} catch {
|
|
80
|
+
return "";
|
|
81
|
+
}
|
|
82
|
+
})();
|
|
83
|
+
const had = new RegExp(`^${NAME}:`, "m").test(list);
|
|
84
|
+
if (remove) {
|
|
85
|
+
if (!had) return "not set up there, nothing to remove";
|
|
86
|
+
if (dry) return "would remove One Design";
|
|
87
|
+
execFileSync2("claude", ["mcp", "remove", NAME, "--scope", "user"], { stdio: "ignore" });
|
|
88
|
+
return "removed";
|
|
89
|
+
}
|
|
90
|
+
if (had) return "already set up";
|
|
91
|
+
if (dry) return "would add One Design (for every project)";
|
|
92
|
+
execFileSync2("claude", ["mcp", "add", "--scope", "user", NAME, "--", "npx", "-y", "one-design-mcp@latest"], { stdio: "ignore" });
|
|
93
|
+
return "added (for every project)";
|
|
94
|
+
}
|
|
95
|
+
async function setup(argv) {
|
|
96
|
+
const dry = argv.includes("--dry-run");
|
|
97
|
+
const remove = argv.includes("--remove");
|
|
98
|
+
const only = argv[argv.indexOf("--app") + 1];
|
|
99
|
+
const want = (app) => !argv.includes("--app") || only === app;
|
|
100
|
+
const lines = [];
|
|
101
|
+
if (want("desktop")) lines.push(`Claude Desktop: ${await editJson(desktopConfig(), remove, dry)}`);
|
|
102
|
+
if (want("cursor")) lines.push(`Cursor: ${await editJson(cursorConfig(), remove, dry)}`);
|
|
103
|
+
if (want("code")) lines.push(`Claude Code: ${claudeCode(remove, dry)}`);
|
|
104
|
+
console.log(`One Design for Claude${dry ? " (dry run, nothing changed)" : ""}
|
|
105
|
+
|
|
106
|
+
${lines.map((l) => ` ${l}`).join("\n")}
|
|
107
|
+
`);
|
|
108
|
+
if (!dry && !remove && lines.some((l) => /added|updated/.test(l)))
|
|
109
|
+
console.log("Next: quit and reopen the app (on a Mac, \u2318Q), then ask Claude \u201CWhat can One Design do?\u201D.\nOther MCP apps: add a server with the command npx and the arguments -y one-design-mcp@latest.");
|
|
110
|
+
}
|
|
111
|
+
var NAME, cursorConfig;
|
|
112
|
+
var init_setup = __esm({
|
|
113
|
+
"src/setup.ts"() {
|
|
114
|
+
"use strict";
|
|
115
|
+
NAME = "one-design";
|
|
116
|
+
cursorConfig = () => path9.join(os7.homedir(), ".cursor", "mcp.json");
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
|
|
8
120
|
// src/server.ts
|
|
9
121
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
10
122
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
@@ -223,9 +335,9 @@ import { promises as fs2 } from "node:fs";
|
|
|
223
335
|
import path2 from "node:path";
|
|
224
336
|
import os2 from "node:os";
|
|
225
337
|
import { exec } from "node:child_process";
|
|
226
|
-
var SB_URL =
|
|
227
|
-
var SB_KEY =
|
|
228
|
-
var PAYMENTS = (
|
|
338
|
+
var SB_URL = true ? "https://jaznopltkefnwooyksrk.supabase.co" : "";
|
|
339
|
+
var SB_KEY = true ? "sb_publishable_WfXjMAOVoXE9dtJMfJCshw_9rfMboU7" : "";
|
|
340
|
+
var PAYMENTS = (true ? "on" : "on").toLowerCase();
|
|
229
341
|
var SITE = "https://one.design";
|
|
230
342
|
var PRICING_URL = `${SITE}/pricing`;
|
|
231
343
|
var ACCOUNT_URL = `${SITE}/account`;
|
|
@@ -276,18 +388,19 @@ function isPaid(s) {
|
|
|
276
388
|
if (["active", "on_trial", "past_due"].includes(s.status)) return true;
|
|
277
389
|
return s.status === "cancelled" && !!s.ends_at && new Date(s.ends_at) > /* @__PURE__ */ new Date();
|
|
278
390
|
}
|
|
391
|
+
var checked = null;
|
|
279
392
|
async function currentPlan(force = false) {
|
|
280
393
|
if (freeBeta()) return { plan: "pro", label: "Free beta: every tool is open to everyone for now" };
|
|
281
394
|
if (!accountsAvailable()) return { plan: "free", label: "Free (sign-in isn\u2019t set up in this build)" };
|
|
282
395
|
const s = await freshSession();
|
|
283
396
|
if (!s) return { plan: "free", label: "Free (not signed in)" };
|
|
284
|
-
if (!force &&
|
|
397
|
+
if (!force && checked && checked.user === s.user_id && Date.now() - checked.at < 10 * 60 * 1e3) return { plan: checked.plan, email: s.email, label: checked.label };
|
|
285
398
|
const r = await sb(`/rest/v1/subscriptions?select=plan,status,ends_at&user_id=eq.${s.user_id}`, { token: s.access_token });
|
|
286
399
|
const rows = r.ok ? await r.json() : [];
|
|
287
400
|
const sub = rows[0] ?? null;
|
|
288
401
|
const paid = isPaid(sub);
|
|
289
402
|
const label = paid ? sub.plan === "lifetime" ? "Pro (Lifetime)" : "Pro" : "Free";
|
|
290
|
-
|
|
403
|
+
if (r.ok) checked = { user: s.user_id, plan: paid ? "pro" : "free", label, at: Date.now() };
|
|
291
404
|
return { plan: paid ? "pro" : "free", email: s.email, label };
|
|
292
405
|
}
|
|
293
406
|
async function sendCode(email) {
|
|
@@ -306,6 +419,7 @@ async function verifyCode(email, code) {
|
|
|
306
419
|
return currentPlan(true);
|
|
307
420
|
}
|
|
308
421
|
async function signOut() {
|
|
422
|
+
checked = null;
|
|
309
423
|
await writeSession(null);
|
|
310
424
|
}
|
|
311
425
|
async function checkoutUrl() {
|
|
@@ -324,6 +438,12 @@ async function billingPortalUrl() {
|
|
|
324
438
|
const j = await r.json().catch(() => ({}));
|
|
325
439
|
return j.url ?? ACCOUNT_URL;
|
|
326
440
|
}
|
|
441
|
+
async function librariesGrandfathered() {
|
|
442
|
+
const s = await freshSession();
|
|
443
|
+
if (!s) return false;
|
|
444
|
+
const r = await sb("/rest/v1/rpc/libraries_grandfathered", { method: "POST", body: "{}", token: s.access_token });
|
|
445
|
+
return r.ok && await r.json().catch(() => false) === true;
|
|
446
|
+
}
|
|
327
447
|
async function brandLibraries() {
|
|
328
448
|
const s = await freshSession();
|
|
329
449
|
if (!s) throw new Error("Sign in first (sign_in), with the email you use on one.design.");
|
|
@@ -601,7 +721,9 @@ function register(t2) {
|
|
|
601
721
|
});
|
|
602
722
|
t2.tool({
|
|
603
723
|
name: "brand_library",
|
|
604
|
-
|
|
724
|
+
// Not gated by the usual Pro check: accounts that had libraries before they became Pro-only keep
|
|
725
|
+
// them (checked below, and enforced by the database)
|
|
726
|
+
siteId: "",
|
|
605
727
|
title: "Your Brand Libraries",
|
|
606
728
|
description: "Reads the Brand Libraries synced to the signed-in one.design account: colours (name and HEX), fonts, logos. Use the colours in other tools (QR codes, watermarks, store shots, bento). save_logos writes the logos to a folder so other tools can use them.",
|
|
607
729
|
openWorld: true,
|
|
@@ -610,7 +732,8 @@ function register(t2) {
|
|
|
610
732
|
save_logos: z.boolean().default(false).describe("Save the logos (and fonts) as files."),
|
|
611
733
|
output_dir: z.string().optional().describe("Where to save them. Default: ~/Downloads/one-design.")
|
|
612
734
|
},
|
|
613
|
-
async run(a) {
|
|
735
|
+
async run(a, ctx) {
|
|
736
|
+
if (ctx.plan !== "pro" && !await librariesGrandfathered()) return text(proPitch("Your Brand Libraries"), true);
|
|
614
737
|
let libs = await brandLibraries();
|
|
615
738
|
if (a.library) libs = libs.filter((l) => l.name.toLowerCase() === a.library.toLowerCase());
|
|
616
739
|
if (!libs.length) throw new ToolError(a.library ? `No Brand Library called ${a.library}.` : "This account has no Brand Libraries yet. Make one at https://one.design/brand.");
|
|
@@ -5006,9 +5129,9 @@ async function postage(img, o) {
|
|
|
5006
5129
|
const inset = bordered ? margin : Math.round(hole * 2.2);
|
|
5007
5130
|
const value = o.value.trim();
|
|
5008
5131
|
if (value) {
|
|
5009
|
-
const
|
|
5010
|
-
const tw = await measure(value,
|
|
5011
|
-
const pad =
|
|
5132
|
+
const fs10 = Math.round(unit * 0.09);
|
|
5133
|
+
const tw = await measure(value, fs10, 400, "serif");
|
|
5134
|
+
const pad = fs10 * 0.35;
|
|
5012
5135
|
const bx = Math.max(0, Math.round(margin + iw - tw - pad * 2 - (bordered ? 0 : inset)));
|
|
5013
5136
|
const by = Math.max(0, Math.round(inset));
|
|
5014
5137
|
const flat = await sharp(pic).flatten({ background: o.paper }).raw().toBuffer({ resolveWithObject: true });
|
|
@@ -5017,7 +5140,7 @@ async function postage(img, o) {
|
|
|
5017
5140
|
const x0 = Math.max(0, bx - margin);
|
|
5018
5141
|
const y0 = Math.max(0, by - margin);
|
|
5019
5142
|
const x1 = Math.min(iw, bx - margin + Math.round(tw + pad * 2));
|
|
5020
|
-
const y1 = Math.min(ih, by - margin + Math.round(
|
|
5143
|
+
const y1 = Math.min(ih, by - margin + Math.round(fs10 + pad * 1.2));
|
|
5021
5144
|
for (let y = y0; y < y1; y++)
|
|
5022
5145
|
for (let x = x0; x < x1; x++) {
|
|
5023
5146
|
const i = (y * iw + x) * flat.info.channels;
|
|
@@ -5025,18 +5148,18 @@ async function postage(img, o) {
|
|
|
5025
5148
|
cnt++;
|
|
5026
5149
|
}
|
|
5027
5150
|
const under = cnt ? sum / cnt : 255;
|
|
5028
|
-
body.push(text2(margin + iw - tw - pad - (bordered ? 0 : inset), fromTop(inset + pad * 0.6,
|
|
5151
|
+
body.push(text2(margin + iw - tw - pad - (bordered ? 0 : inset), fromTop(inset + pad * 0.6, fs10), value, { size: fs10, font: "serif", fill: under < 110 ? o.paper : inkOnPaper }));
|
|
5029
5152
|
}
|
|
5030
5153
|
const caption = o.caption.trim();
|
|
5031
5154
|
if (caption) {
|
|
5032
5155
|
if (band) {
|
|
5033
|
-
const
|
|
5034
|
-
body.push(text2(W / 2, fromMiddle(margin + ih + band / 2 + margin * 0.3,
|
|
5156
|
+
const fs10 = await fitSize(caption, W - margin * 2, Math.round(band * 0.6), 400, "serif");
|
|
5157
|
+
body.push(text2(W / 2, fromMiddle(margin + ih + band / 2 + margin * 0.3, fs10), caption, { size: fs10, font: "serif", fill: inkOnPaper, anchor: "middle" }));
|
|
5035
5158
|
} else {
|
|
5036
5159
|
const max = Math.round(unit * 0.085);
|
|
5037
|
-
const
|
|
5160
|
+
const fs10 = await fitSize(caption, W - inset * 2, max, 400, "serif");
|
|
5038
5161
|
defs.push(`<filter id="capshadow" x="-20%" y="-50%" width="140%" height="200%"><feDropShadow dx="0" dy="0" stdDeviation="${n(max * 0.2)}" flood-color="#000000" flood-opacity="0.6"/></filter>`);
|
|
5039
|
-
body.push(text2(W / 2, fromMiddle(H - inset - max * 0.55,
|
|
5162
|
+
body.push(text2(W / 2, fromMiddle(H - inset - max * 0.55, fs10), caption, { size: fs10, font: "serif", fill: o.paper, anchor: "middle", extra: 'filter="url(#capshadow)"' }));
|
|
5040
5163
|
}
|
|
5041
5164
|
}
|
|
5042
5165
|
const holes = [];
|
|
@@ -5073,8 +5196,8 @@ async function rubber(img, o, seed) {
|
|
|
5073
5196
|
image(gap + line2 * 3, gap + line2 * 3, iw, ih, dataUri2(inked, "image/png"))
|
|
5074
5197
|
];
|
|
5075
5198
|
if (band) {
|
|
5076
|
-
const
|
|
5077
|
-
body.push(text2(W / 2, fromMiddle(H - line2 * 3 - band / 2 - gap * 0.3,
|
|
5199
|
+
const fs10 = await fitSize(caption, W - line2 * 10, Math.round(band * 0.5), 700);
|
|
5200
|
+
body.push(text2(W / 2, fromMiddle(H - line2 * 3 - band / 2 - gap * 0.3, fs10), caption, { size: fs10, weight: 700, fill: o.ink, anchor: "middle" }));
|
|
5078
5201
|
}
|
|
5079
5202
|
const png = await rasterise(svgDoc(W, H, body.join(""))).png().toBuffer();
|
|
5080
5203
|
return wearOut(png, distress(W, H, o.wear / 100, seed));
|
|
@@ -5095,10 +5218,10 @@ async function seal(img, o, seed) {
|
|
|
5095
5218
|
];
|
|
5096
5219
|
const ringText = o.caption.trim().toUpperCase();
|
|
5097
5220
|
const ringR = (c - line2 + inner) / 2;
|
|
5098
|
-
const
|
|
5221
|
+
const fs10 = Math.round((c - line2 - inner) * 0.52);
|
|
5099
5222
|
const chars = [...ringText];
|
|
5100
5223
|
const widths2 = [];
|
|
5101
|
-
for (const ch of chars) widths2.push(await measure(ch,
|
|
5224
|
+
for (const ch of chars) widths2.push(await measure(ch, fs10, 700));
|
|
5102
5225
|
const total = widths2.reduce((a2, b) => a2 + b, 0);
|
|
5103
5226
|
const spread = chars.length ? Math.min(Math.PI * 1.7, total * 1.18 / ringR) : 0;
|
|
5104
5227
|
let a = -Math.PI / 2 - spread / 2;
|
|
@@ -5107,13 +5230,13 @@ async function seal(img, o, seed) {
|
|
|
5107
5230
|
a += step / 2;
|
|
5108
5231
|
const x = c + Math.cos(a) * ringR;
|
|
5109
5232
|
const y = c + Math.sin(a) * ringR;
|
|
5110
|
-
body.push(`<g transform="translate(${n(x)},${n(y)}) rotate(${n((a + Math.PI / 2) * 180 / Math.PI)})">${text2(0, fromMiddle(0,
|
|
5233
|
+
body.push(`<g transform="translate(${n(x)},${n(y)}) rotate(${n((a + Math.PI / 2) * 180 / Math.PI)})">${text2(0, fromMiddle(0, fs10), ch, { size: fs10, weight: 700, fill: o.ink, anchor: "middle" })}</g>`);
|
|
5111
5234
|
a += step / 2;
|
|
5112
5235
|
});
|
|
5113
5236
|
const star = (ang) => {
|
|
5114
5237
|
const x = c + Math.cos(ang) * ringR;
|
|
5115
5238
|
const y = c + Math.sin(ang) * ringR;
|
|
5116
|
-
const R =
|
|
5239
|
+
const R = fs10 * 0.4;
|
|
5117
5240
|
const pts = Array.from({ length: 10 }, (_, i) => {
|
|
5118
5241
|
const rr2 = i % 2 ? R * 0.42 : R;
|
|
5119
5242
|
const t2 = -Math.PI / 2 + i * Math.PI / 5;
|
|
@@ -6057,7 +6180,7 @@ ${notes.join("\n")}` : ""
|
|
|
6057
6180
|
const r = { x, y, w: cols.start[tile.col + tile.colSpan - 1] + cols.size[tile.col + tile.colSpan - 1] - x, h: rows.start[tile.row + tile.rowSpan - 1] + rows.size[tile.row + tile.rowSpan - 1] - y };
|
|
6058
6181
|
if (r.w < 1 || r.h < 1) continue;
|
|
6059
6182
|
defs.push(`<clipPath id="t${i}"><path d="${rr(r.x, r.y, r.w, r.h, Math.max(0, Math.min(a.radius, r.w / 2, r.h / 2)))}"/></clipPath>`);
|
|
6060
|
-
const parts = [`<rect x="${n(r.x)}" y="${n(r.y)}" width="${n(r.w)}" height="${n(r.h)}" fill="${tile.fill}"/>`];
|
|
6183
|
+
const parts = tile.kind === "photo" && tile.file ? [] : [`<rect x="${n(r.x)}" y="${n(r.y)}" width="${n(r.w)}" height="${n(r.h)}" fill="${tile.fill}"/>`];
|
|
6061
6184
|
if (tile.kind === "photo") {
|
|
6062
6185
|
if (tile.file) {
|
|
6063
6186
|
let href;
|
|
@@ -6220,7 +6343,12 @@ ${notes.join("\n")}` : "");
|
|
|
6220
6343
|
}
|
|
6221
6344
|
|
|
6222
6345
|
// src/server.ts
|
|
6223
|
-
var VERSION = "0.2.
|
|
6346
|
+
var VERSION = "0.2.2";
|
|
6347
|
+
if (process.argv[2] === "setup") {
|
|
6348
|
+
const { setup: setup2 } = await Promise.resolve().then(() => (init_setup(), setup_exports));
|
|
6349
|
+
await setup2(process.argv.slice(3));
|
|
6350
|
+
process.exit(0);
|
|
6351
|
+
}
|
|
6224
6352
|
var server = new McpServer({ name: "one-design", title: "One Design", version: VERSION, websiteUrl: "https://one.design" }, { instructions: INSTRUCTIONS });
|
|
6225
6353
|
var t = toolkit(server);
|
|
6226
6354
|
for (const m of [basics_exports, optimise_exports, privacy_docs_exports, brand_exports, account_exports]) m.register(t);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "one-design-mcp",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "Every one.design tool for Claude and other MCP apps: compress, resize, convert, privacy, brand, store screenshots, PDFs and more, all on your own computer.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|