@pixeldojo/mcp 0.25.0 → 0.26.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 +2 -1
- package/dist/cli.cjs +168 -11
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +168 -11
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +168 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +168 -11
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
PixelDojo MCP server. One install for Claude Code, Cursor, OpenClaw, and any
|
|
4
4
|
other [Model Context Protocol](https://modelcontextprotocol.io) host.
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
25 named tools, 140+ models, async by default.
|
|
7
7
|
|
|
8
8
|
**Prefer zero install?** PixelDojo also runs a hosted MCP server with OAuth
|
|
9
9
|
sign-in (no API key): point any remote-capable client at
|
|
@@ -58,6 +58,7 @@ Restart your agent. You'll see 23 new tools.
|
|
|
58
58
|
| `pixeldojo_overlay` | Ad text layouts on a video: hook title, lower-third callout, review card, progress bar, countdown timer, price tag, offer badge and a branded end card with logo. Exact text, your brand color, clear of the platform UI. |
|
|
59
59
|
| `pixeldojo_caption` | Animated word-by-word captions on a video with speech, placed clear of the TikTok/Reels/Shorts buttons. Pop, Highlighter or Clean, any highlight color. |
|
|
60
60
|
| `pixeldojo_audio` | Full audio scenes: dialogue + effects + music in one clip (Seed Audio 1.0). Reference clips are hosted URLs; local audio files are not accepted. |
|
|
61
|
+
| `pixeldojo_effects` / `pixeldojo_effect` | One-click effects with the prompt built in: list them (283 video effects like AI Hug or Earth Zoom In, 30 photo effects like action figure or Ghibli style, and one-job tools like watermark or background removal), then run one by slug on your photos. |
|
|
61
62
|
| `pixeldojo_library` | Search your media library: saved Library items + recent generations. |
|
|
62
63
|
| `pixeldojo_save_workflow` / `run_workflow` / `list_workflows` | Save a multi-step chain once, run it by name from any chat. |
|
|
63
64
|
| `pixeldojo_upload` | Local file → 24h temp URL, for reference inputs. |
|
package/dist/cli.cjs
CHANGED
|
@@ -1839,14 +1839,17 @@ async function plan(input, ctx) {
|
|
|
1839
1839
|
look: input.look ?? (music ? MUSIC_VIDEO_LOOKS[0] : "live-action"),
|
|
1840
1840
|
lengthTarget: input.length,
|
|
1841
1841
|
...!music && input.pacing === "trailer" ? { pacing: "trailer" } : {},
|
|
1842
|
+
...input.quality === "final" ? { clipQuality: "final" } : {},
|
|
1842
1843
|
assetIds: [],
|
|
1843
1844
|
...music ? {
|
|
1844
1845
|
// No script step names a music video, so it would stay "Untitled film".
|
|
1845
1846
|
...input.idea?.trim() ? { title: input.idea.trim().slice(0, 80) } : {},
|
|
1846
1847
|
musicVideoMode: true,
|
|
1847
1848
|
musicUrl: input.song_url,
|
|
1848
|
-
...input.song_duration_sec ? { musicDurationSec: input.song_duration_sec } : {}
|
|
1849
|
-
|
|
1849
|
+
...input.song_duration_sec ? { musicDurationSec: input.song_duration_sec } : {}
|
|
1850
|
+
// Engine left on Auto, like the web composer's music mode, so the
|
|
1851
|
+
// planner routes a mature song to H3 and the rest to P-Video 2 Pro
|
|
1852
|
+
// Reference (tests/contracts/mcp-film-music-parity.test.ts).
|
|
1850
1853
|
} : {}
|
|
1851
1854
|
});
|
|
1852
1855
|
if (!created.data.film) return { kind: "text", text: `Could not create the film: ${created.data.error ?? created.status}` };
|
|
@@ -2248,14 +2251,13 @@ async function run10(input, ctx) {
|
|
|
2248
2251
|
if (action === "redo") return redoShots(input, ctx);
|
|
2249
2252
|
return advance(input.film_id, input.soundtrack, input.music_job_id, ctx);
|
|
2250
2253
|
}
|
|
2251
|
-
var STORY_LOOKS, MUSIC_VIDEO_LOOKS, LOOKS,
|
|
2254
|
+
var STORY_LOOKS, MUSIC_VIDEO_LOOKS, LOOKS, InputSchema10, InputJsonSchema10, shots, benignDispatchRefusal, count, frameDone, RETRY_CLEARS, REFUSED, isRefused, PLANNER_POLL_MS, PLANNER_MAX_POLLS, isMusicVideo, needsSlice, stillPlanningText, LOOK_MUSIC, ARC, filmSkill;
|
|
2252
2255
|
var init_film = __esm({
|
|
2253
2256
|
"src/skills/film.ts"() {
|
|
2254
2257
|
init_upload_helpers();
|
|
2255
2258
|
STORY_LOOKS = ["live-action", "anime", "3d-animation", "noir", "horror", "sci-fi", "documentary", "western", "romance", "romantic-comedy", "comedy"];
|
|
2256
2259
|
MUSIC_VIDEO_LOOKS = ["rap-video", "neon-club", "stage-performance", "retro-camcorder", "y2k-pop", "moody-rnb", "rock-grit", "dream-pop", "k-pop"];
|
|
2257
2260
|
LOOKS = [...STORY_LOOKS, ...MUSIC_VIDEO_LOOKS];
|
|
2258
|
-
MUSIC_CLIP_ENGINE_ID = "minimax-h3-reference";
|
|
2259
2261
|
InputSchema10 = zod.z.object({
|
|
2260
2262
|
idea: zod.z.string().max(2e3).optional().describe("One-to-three sentence film idea. The studio writes the screenplay (free). Provide idea OR script for planning."),
|
|
2261
2263
|
script: zod.z.string().max(2e4).optional().describe("A full screenplay to plan instead of an idea (sluglines, action lines, dialogue)."),
|
|
@@ -2266,6 +2268,7 @@ var init_film = __esm({
|
|
|
2266
2268
|
lyrics: zod.z.string().max(1e4).optional().describe("Music video mode: the song lyrics, so shots land on the right lines. Optional."),
|
|
2267
2269
|
aspect: zod.z.enum(["16:9", "9:16"]).default("16:9"),
|
|
2268
2270
|
pacing: zod.z.enum(["story", "trailer"]).default("story").describe("'story' (default) plays every shot's action whole. 'trailer' cuts it like a trailer or promo: most shots keep only their first 1.5-3 seconds."),
|
|
2271
|
+
quality: zod.z.enum(["standard", "final"]).default("standard").describe("'standard' (default) renders 720p clips and a 720p film. 'final' renders 1080p clips where the engine supports it and exports the film at 1080p; it costs more per second."),
|
|
2269
2272
|
length: zod.z.enum(["30s", "60s", "2-3min", "5min"]).default("60s").describe("Target length of the finished film."),
|
|
2270
2273
|
film_id: zod.z.string().max(40).optional().describe("Existing film id (from a previous call) for produce/status/cast/redo."),
|
|
2271
2274
|
action: zod.z.enum(["plan", "produce", "status", "cast", "redo"]).default("plan").describe("'plan' creates + storyboards (free). 'cast' casts, replaces or removes characters on an existing film. 'produce' starts charged generation. 'status' advances production and reports progress; poll it every ~30s until it returns the finished film. 'redo' renders a new take of the listed shots (charged), then status re-saves and re-exports."),
|
|
@@ -2305,6 +2308,11 @@ var init_film = __esm({
|
|
|
2305
2308
|
lyrics: { type: "string", description: "Plan step, music video mode (optional): the song lyrics, so shots land on the right lines." },
|
|
2306
2309
|
aspect: { type: "string", enum: ["16:9", "9:16"], description: "Plan step: frame aspect ratio. Default 16:9." },
|
|
2307
2310
|
length: { type: "string", enum: ["30s", "60s", "2-3min", "5min"], description: "Plan step: target length. Default 60s. Ignored for a music video, whose length is the song." },
|
|
2311
|
+
quality: {
|
|
2312
|
+
type: "string",
|
|
2313
|
+
enum: ["standard", "final"],
|
|
2314
|
+
description: "Plan step: 'standard' (default) is 720p. 'final' renders 1080p clips where the engine supports it and exports at 1080p, at a higher price per second."
|
|
2315
|
+
},
|
|
2308
2316
|
pacing: {
|
|
2309
2317
|
type: "string",
|
|
2310
2318
|
enum: ["story", "trailer"],
|
|
@@ -2853,7 +2861,7 @@ var init_episode = __esm({
|
|
|
2853
2861
|
"src/skills/episode.ts"() {
|
|
2854
2862
|
STYLES2 = ["editorial-motion", "paper-diorama", "hand-drawn", "storybook", "poster-vector", "soft-3d"];
|
|
2855
2863
|
CATEGORIES = ["education", "history", "kids", "storytelling", "custom"];
|
|
2856
|
-
ENGINES = ["omni-draft", "omni-final", "still-motion"];
|
|
2864
|
+
ENGINES = ["omni-draft", "omni-final", "omni-1080", "still-motion"];
|
|
2857
2865
|
MIN_SECONDS = 60;
|
|
2858
2866
|
MAX_SECONDS = 300;
|
|
2859
2867
|
MAX_IN_FLIGHT = 4;
|
|
@@ -2888,7 +2896,7 @@ var init_episode = __esm({
|
|
|
2888
2896
|
engine: {
|
|
2889
2897
|
type: "string",
|
|
2890
2898
|
enum: [...ENGINES],
|
|
2891
|
-
description: "Create step (optional): render every scene with one engine. omni-draft: fast, cheap motion preview. omni-final: full quality motion with sound. still-motion: one illustration per scene, gently panned, cheapest. Default: the style picks."
|
|
2899
|
+
description: "Create step (optional): render every scene with one engine. omni-draft: fast, cheap motion preview. omni-final: full quality motion with sound (720p). omni-1080: the same at 1080p, and the episode exports at 1080p. still-motion: one illustration per scene, gently panned, cheapest. Default: the style picks."
|
|
2892
2900
|
},
|
|
2893
2901
|
music: { type: "boolean", description: "Create step: add a music bed under the narration. Default true." },
|
|
2894
2902
|
title: { type: "string", description: "Create step (optional): episode title. Defaults to the topic." }
|
|
@@ -3581,6 +3589,148 @@ var init_save_character = __esm({
|
|
|
3581
3589
|
};
|
|
3582
3590
|
}
|
|
3583
3591
|
});
|
|
3592
|
+
function priceOf(e) {
|
|
3593
|
+
if (!e.creditsByEngine) return `${e.credits ?? "?"} credits`;
|
|
3594
|
+
return Object.entries(e.creditsByEngine).map(([engine, c]) => `${engine}${engine === e.defaultEngine ? " (default)" : ""} ${c ?? "?"} credits`).join(" / ");
|
|
3595
|
+
}
|
|
3596
|
+
async function listRun(input, ctx) {
|
|
3597
|
+
const q = new URLSearchParams();
|
|
3598
|
+
for (const [k, v] of Object.entries(input)) if (v !== void 0 && v !== "") q.set(k, String(v));
|
|
3599
|
+
if (!input.limit) q.set("limit", "20");
|
|
3600
|
+
const res = await (ctx.fetch ?? fetch)(`${ctx.baseUrl}/api/v1/effects?${q}`, { headers: headers(ctx, "pixeldojo_effects") });
|
|
3601
|
+
const data = await res.json().catch(() => ({}));
|
|
3602
|
+
if (!res.ok) return { kind: "text", text: `Could not list effects: ${data.error ?? `HTTP ${res.status}`}` };
|
|
3603
|
+
const effects = data.effects ?? [];
|
|
3604
|
+
const cats = Object.entries(data.categories ?? {}).map(([fam, list]) => `${fam}: ${list.join(", ")}`);
|
|
3605
|
+
if (!effects.length) {
|
|
3606
|
+
return { kind: "text", text: ["No effects match. Categories:", ...cats].join("\n") };
|
|
3607
|
+
}
|
|
3608
|
+
const lines = effects.map((e) => {
|
|
3609
|
+
const ins = e.inputs.map(
|
|
3610
|
+
(i) => i.kind === "image" ? `photo "${i.label}"` : `text "${i.label}"${i.options ? ` [${i.options.join(" | ")}]` : ""}${i.optional ? " (optional)" : ""}`
|
|
3611
|
+
);
|
|
3612
|
+
return `- ${e.slug} (${e.family}, ${e.output}, ${priceOf(e)}): ${e.title}. ${e.tagline} Inputs: ${ins.join(", ")}.`;
|
|
3613
|
+
});
|
|
3614
|
+
const shown = data.total && data.total > effects.length ? `, showing ${effects.length}` : "";
|
|
3615
|
+
return {
|
|
3616
|
+
kind: "text",
|
|
3617
|
+
text: [
|
|
3618
|
+
`${data.total ?? effects.length} effects${shown}. Run one with pixeldojo_effect (slug, image_urls in the order listed, texts for text inputs).`,
|
|
3619
|
+
...lines,
|
|
3620
|
+
...input.search || input.family || input.category ? [] : ["", "Categories:", ...cats]
|
|
3621
|
+
].join("\n")
|
|
3622
|
+
};
|
|
3623
|
+
}
|
|
3624
|
+
async function effectRun(input, ctx) {
|
|
3625
|
+
const images = input.image_paths?.length ? await uploadLocalFiles(input.image_paths, ctx) : input.image_urls ?? [];
|
|
3626
|
+
const res = await (ctx.fetch ?? fetch)(`${ctx.baseUrl}/api/v1/effects/${encodeURIComponent(input.slug)}/run`, {
|
|
3627
|
+
method: "POST",
|
|
3628
|
+
headers: headers(ctx, "pixeldojo_effect"),
|
|
3629
|
+
body: JSON.stringify({
|
|
3630
|
+
images,
|
|
3631
|
+
...input.texts ? { texts: input.texts } : {},
|
|
3632
|
+
...input.family ? { family: input.family } : {},
|
|
3633
|
+
...input.engine ? { engine: input.engine } : {}
|
|
3634
|
+
})
|
|
3635
|
+
});
|
|
3636
|
+
const data = await res.json().catch(() => ({}));
|
|
3637
|
+
if (!res.ok || !data.jobId) {
|
|
3638
|
+
return { kind: "text", text: `Effect not started (nothing charged): ${data.error ?? `HTTP ${res.status}`}` };
|
|
3639
|
+
}
|
|
3640
|
+
const result = await pollJobUntilDoneOrHandoff(data.jobId, (id) => ctx.client.getJob(id), ctx.buildStatusUrl, {
|
|
3641
|
+
now: ctx.pollOverrides?.now,
|
|
3642
|
+
sleep: ctx.pollOverrides?.sleep
|
|
3643
|
+
});
|
|
3644
|
+
return pollResultToSkillResult(
|
|
3645
|
+
result,
|
|
3646
|
+
(urls) => urls.length === 0 ? `Job ${data.jobId} completed but returned no assets.` : `Done (${data.creditCost ?? "?"} credits). Asset: ${urls[0]}`
|
|
3647
|
+
);
|
|
3648
|
+
}
|
|
3649
|
+
var FAMILIES, ENGINES2, headers, ListSchema, effectsListSkill, RunSchema, runProperties, effectRunSkill;
|
|
3650
|
+
var init_effects = __esm({
|
|
3651
|
+
"src/skills/effects.ts"() {
|
|
3652
|
+
init_poll();
|
|
3653
|
+
init_upload_helpers();
|
|
3654
|
+
init_types();
|
|
3655
|
+
FAMILIES = ["video-effect", "photo-effect", "tool"];
|
|
3656
|
+
ENGINES2 = ["klein", "qwen"];
|
|
3657
|
+
headers = (ctx, skill) => ({
|
|
3658
|
+
Authorization: `Bearer ${ctx.apiKey}`,
|
|
3659
|
+
"Content-Type": "application/json",
|
|
3660
|
+
"x-pixeldojo-source": `mcp/${ctx.mcpVersion}`,
|
|
3661
|
+
"x-pixeldojo-skill": skill
|
|
3662
|
+
});
|
|
3663
|
+
ListSchema = zod.z.object({
|
|
3664
|
+
search: zod.z.string().max(200).optional(),
|
|
3665
|
+
family: zod.z.enum(FAMILIES).optional(),
|
|
3666
|
+
category: zod.z.string().max(60).optional(),
|
|
3667
|
+
limit: zod.z.number().int().min(1).max(100).optional()
|
|
3668
|
+
});
|
|
3669
|
+
effectsListSkill = {
|
|
3670
|
+
name: "pixeldojo_effects",
|
|
3671
|
+
description: "List PixelDojo's one-click effects: 283 video effects (a photo or two in, a 5 s clip out: AI Hug, Earth Zoom In, AI Dance), 30 photo effects (a photo in, a styled image out: action figure, Ghibli style, sticker, aging filter) and one-job tools (remove a watermark, object or background, headshots, photo restoration, relight, logo, thumbnail and poster makers). Search by words, family or category; each result gives the slug, inputs and credit price. Free. Run one with pixeldojo_effect.",
|
|
3672
|
+
inputZod: ListSchema,
|
|
3673
|
+
inputJsonSchema: {
|
|
3674
|
+
type: "object",
|
|
3675
|
+
properties: {
|
|
3676
|
+
search: { type: "string", description: 'Words like "hug", "action figure", "ghibli", "remove background".' },
|
|
3677
|
+
family: {
|
|
3678
|
+
type: "string",
|
|
3679
|
+
enum: FAMILIES,
|
|
3680
|
+
description: "video-effect = photo to clip, photo-effect = photo to styled image, tool = one-job edit."
|
|
3681
|
+
},
|
|
3682
|
+
category: { type: "string", description: 'A category name from a previous listing, e.g. "Viral", "Toys & 3D".' },
|
|
3683
|
+
limit: { type: "integer", minimum: 1, maximum: 100, description: "Default 20." }
|
|
3684
|
+
}
|
|
3685
|
+
},
|
|
3686
|
+
allowedModels: [],
|
|
3687
|
+
defaultModel: "",
|
|
3688
|
+
run: listRun
|
|
3689
|
+
};
|
|
3690
|
+
RunSchema = zod.z.object({
|
|
3691
|
+
slug: zod.z.string().min(1).max(80),
|
|
3692
|
+
family: zod.z.enum(FAMILIES).optional(),
|
|
3693
|
+
image_urls: zod.z.array(zod.z.string().url()).max(4).optional(),
|
|
3694
|
+
image_paths: zod.z.array(zod.z.string()).max(4).optional(),
|
|
3695
|
+
texts: zod.z.array(zod.z.string().max(200)).max(4).optional(),
|
|
3696
|
+
engine: zod.z.enum(ENGINES2).optional()
|
|
3697
|
+
});
|
|
3698
|
+
runProperties = {
|
|
3699
|
+
slug: { type: "string", description: 'The effect slug from pixeldojo_effects, e.g. "ai-hug", "action-figure", "watermark-remover".' },
|
|
3700
|
+
family: {
|
|
3701
|
+
type: "string",
|
|
3702
|
+
enum: FAMILIES,
|
|
3703
|
+
description: "Needed only for action-figure, comic-book and red-carpet, which are both a video and a photo effect."
|
|
3704
|
+
},
|
|
3705
|
+
image_urls: {
|
|
3706
|
+
type: "array",
|
|
3707
|
+
items: { type: "string", format: "uri" },
|
|
3708
|
+
description: "The photos as https URLs, in the order the listing names them (most take one; duo effects take two)."
|
|
3709
|
+
},
|
|
3710
|
+
image_paths: {
|
|
3711
|
+
type: "array",
|
|
3712
|
+
items: { type: "string" },
|
|
3713
|
+
description: "Absolute local photo paths instead of image_urls; uploaded first (24h temp storage)."
|
|
3714
|
+
},
|
|
3715
|
+
texts: {
|
|
3716
|
+
type: "array",
|
|
3717
|
+
items: { type: "string" },
|
|
3718
|
+
description: "Text inputs in listing order, for entries that list them (object to remove, new background, brand name)."
|
|
3719
|
+
},
|
|
3720
|
+
engine: { type: "string", enum: ENGINES2, description: "Photo effects only: leave out for the default engine." }
|
|
3721
|
+
};
|
|
3722
|
+
effectRunSkill = {
|
|
3723
|
+
name: "pixeldojo_effect",
|
|
3724
|
+
description: "Run one of PixelDojo's one-click effects on your photos: the prompt is built in, so pass only the slug from pixeldojo_effects and the photos (image_urls, or image_paths for local files), plus texts for tools that ask for them. Video effects return a 5 s clip (usually handed off; poll with pixeldojo_status), photo effects and tools an image. Costs the credits the listing shows.",
|
|
3725
|
+
hostedDescription: "Run one of PixelDojo's one-click effects on your photos: the prompt is built in, so pass only the slug from pixeldojo_effects and the photos as https image_urls, plus texts for tools that ask for them. Video effects return a 5 s clip (usually handed off; poll with pixeldojo_status), photo effects and tools an image. Costs the credits the listing shows.",
|
|
3726
|
+
inputZod: RunSchema,
|
|
3727
|
+
inputJsonSchema: { type: "object", required: ["slug"], properties: runProperties },
|
|
3728
|
+
allowedModels: [],
|
|
3729
|
+
defaultModel: "",
|
|
3730
|
+
run: effectRun
|
|
3731
|
+
};
|
|
3732
|
+
}
|
|
3733
|
+
});
|
|
3584
3734
|
function substitutePlaceholders(args, inputs, prevUrl) {
|
|
3585
3735
|
const missing = [];
|
|
3586
3736
|
const fill = (value) => {
|
|
@@ -3829,6 +3979,8 @@ __export(skills_exports, {
|
|
|
3829
3979
|
captionSkill: () => captionSkill,
|
|
3830
3980
|
characterSkill: () => characterSkill,
|
|
3831
3981
|
editSkill: () => editSkill,
|
|
3982
|
+
effectRunSkill: () => effectRunSkill,
|
|
3983
|
+
effectsListSkill: () => effectsListSkill,
|
|
3832
3984
|
episodeSkill: () => episodeSkill,
|
|
3833
3985
|
filmSkill: () => filmSkill,
|
|
3834
3986
|
findHostedSkill: () => findHostedSkill,
|
|
@@ -3890,6 +4042,7 @@ var init_skills = __esm({
|
|
|
3890
4042
|
init_library();
|
|
3891
4043
|
init_save();
|
|
3892
4044
|
init_save_character();
|
|
4045
|
+
init_effects();
|
|
3893
4046
|
init_workflows();
|
|
3894
4047
|
ALL_SKILLS = [
|
|
3895
4048
|
generateSkill,
|
|
@@ -3900,6 +4053,8 @@ var init_skills = __esm({
|
|
|
3900
4053
|
captionSkill,
|
|
3901
4054
|
overlaySkill,
|
|
3902
4055
|
audioSkill,
|
|
4056
|
+
effectsListSkill,
|
|
4057
|
+
effectRunSkill,
|
|
3903
4058
|
librarySkill,
|
|
3904
4059
|
saveSkill,
|
|
3905
4060
|
saveCharacterSkill,
|
|
@@ -3941,6 +4096,8 @@ var init_skills = __esm({
|
|
|
3941
4096
|
pixeldojo_caption: render("Caption video"),
|
|
3942
4097
|
pixeldojo_overlay: render("Add offer or end card"),
|
|
3943
4098
|
pixeldojo_audio: render("Generate music, speech or sound"),
|
|
4099
|
+
pixeldojo_effects: read("List one-click effects"),
|
|
4100
|
+
pixeldojo_effect: render("Run one-click effect"),
|
|
3944
4101
|
pixeldojo_video: render("Change, animate or extend video"),
|
|
3945
4102
|
pixeldojo_ad: render("Make video ad"),
|
|
3946
4103
|
pixeldojo_campaign: render("Make product launch campaign"),
|
|
@@ -3963,10 +4120,10 @@ function makeAttributedClient(options) {
|
|
|
3963
4120
|
const { mcpVersion, skillName, baseFetch, ...sdkOptions } = options;
|
|
3964
4121
|
const real = baseFetch ?? globalThis.fetch.bind(globalThis);
|
|
3965
4122
|
const wrappedFetch = (input, init) => {
|
|
3966
|
-
const
|
|
3967
|
-
|
|
3968
|
-
if (skillName)
|
|
3969
|
-
return real(input, { ...init, headers });
|
|
4123
|
+
const headers2 = new Headers(init?.headers);
|
|
4124
|
+
headers2.set("x-pixeldojo-source", `mcp/${mcpVersion}`);
|
|
4125
|
+
if (skillName) headers2.set("x-pixeldojo-skill", skillName);
|
|
4126
|
+
return real(input, { ...init, headers: headers2 });
|
|
3970
4127
|
};
|
|
3971
4128
|
return new sdk.PixelDojoClient({
|
|
3972
4129
|
...sdkOptions,
|
|
@@ -4010,7 +4167,7 @@ function makeRedactedLogger(target = console) {
|
|
|
4010
4167
|
}
|
|
4011
4168
|
|
|
4012
4169
|
// src/server.ts
|
|
4013
|
-
var PACKAGE_VERSION = "0.
|
|
4170
|
+
var PACKAGE_VERSION = "0.26.0" ;
|
|
4014
4171
|
var SERVER_INSTRUCTIONS = "Pixel Dojo generates images, video, audio and short films from one catalog of AI models, billed in credits from the connected Pixel Dojo account. A job that runs past the 30-second wait returns a jobId to check later; check it rather than submitting again, since every new submission is charged. Generated asset URLs are deleted one hour after they are created: pixeldojo_save keeps one in the user's My Media permanently (after a safety check), and finished films stay in the account library. In any prompt, @Name uses a character, product, outfit, location, prop or style the user saved in Character Studio: its photos are attached automatically. pixeldojo_library source=characters lists them, and pixeldojo_save_character saves a new one from 3 to 5 photos.";
|
|
4015
4172
|
function buildServer(options) {
|
|
4016
4173
|
if (!options.apiKey) {
|