codex-imagegen-mcp 0.1.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/CHANGELOG.md +96 -0
- package/LICENSE +201 -0
- package/NOTICE +19 -0
- package/README.md +373 -0
- package/dist/src/auth/borrowed.js +77 -0
- package/dist/src/auth/borrowed.js.map +1 -0
- package/dist/src/auth/browser-login.js +179 -0
- package/dist/src/auth/browser-login.js.map +1 -0
- package/dist/src/auth/device-login.js +39 -0
- package/dist/src/auth/device-login.js.map +1 -0
- package/dist/src/auth/jwt.js +69 -0
- package/dist/src/auth/jwt.js.map +1 -0
- package/dist/src/auth/manager.js +289 -0
- package/dist/src/auth/manager.js.map +1 -0
- package/dist/src/auth/oauth.js +246 -0
- package/dist/src/auth/oauth.js.map +1 -0
- package/dist/src/auth/pages.js +39 -0
- package/dist/src/auth/pages.js.map +1 -0
- package/dist/src/auth/pkce.js +14 -0
- package/dist/src/auth/pkce.js.map +1 -0
- package/dist/src/auth/store.js +75 -0
- package/dist/src/auth/store.js.map +1 -0
- package/dist/src/backend/images-client.js +223 -0
- package/dist/src/backend/images-client.js.map +1 -0
- package/dist/src/backend/ratelimits.js +183 -0
- package/dist/src/backend/ratelimits.js.map +1 -0
- package/dist/src/cli.js +407 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/config.js +87 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/constants.js +52 -0
- package/dist/src/constants.js.map +1 -0
- package/dist/src/doctor.js +122 -0
- package/dist/src/doctor.js.map +1 -0
- package/dist/src/errors.js +76 -0
- package/dist/src/errors.js.map +1 -0
- package/dist/src/generation.js +183 -0
- package/dist/src/generation.js.map +1 -0
- package/dist/src/history.js +47 -0
- package/dist/src/history.js.map +1 -0
- package/dist/src/images/chroma.js +200 -0
- package/dist/src/images/chroma.js.map +1 -0
- package/dist/src/images/codec.js +159 -0
- package/dist/src/images/codec.js.map +1 -0
- package/dist/src/images/inputs.js +83 -0
- package/dist/src/images/inputs.js.map +1 -0
- package/dist/src/images/output.js +100 -0
- package/dist/src/images/output.js.map +1 -0
- package/dist/src/images/preview.js +20 -0
- package/dist/src/images/preview.js.map +1 -0
- package/dist/src/images/resize.js +135 -0
- package/dist/src/images/resize.js.map +1 -0
- package/dist/src/install/opencode.js +138 -0
- package/dist/src/install/opencode.js.map +1 -0
- package/dist/src/install/skill.js +128 -0
- package/dist/src/install/skill.js.map +1 -0
- package/dist/src/install/snippets.js +127 -0
- package/dist/src/install/snippets.js.map +1 -0
- package/dist/src/log.js +58 -0
- package/dist/src/log.js.map +1 -0
- package/dist/src/remove-background.js +101 -0
- package/dist/src/remove-background.js.map +1 -0
- package/dist/src/server/context.js +2 -0
- package/dist/src/server/context.js.map +1 -0
- package/dist/src/server/index.js +94 -0
- package/dist/src/server/index.js.map +1 -0
- package/dist/src/server/instructions.js +20 -0
- package/dist/src/server/instructions.js.map +1 -0
- package/dist/src/server/login-coordinator.js +73 -0
- package/dist/src/server/login-coordinator.js.map +1 -0
- package/dist/src/server/progress.js +33 -0
- package/dist/src/server/progress.js.map +1 -0
- package/dist/src/server/prompts.js +45 -0
- package/dist/src/server/prompts.js.map +1 -0
- package/dist/src/server/resources.js +73 -0
- package/dist/src/server/resources.js.map +1 -0
- package/dist/src/server/tools.js +338 -0
- package/dist/src/server/tools.js.map +1 -0
- package/dist/src/server/workspace.js +45 -0
- package/dist/src/server/workspace.js.map +1 -0
- package/dist/src/status.js +86 -0
- package/dist/src/status.js.map +1 -0
- package/dist/src/util/format.js +36 -0
- package/dist/src/util/format.js.map +1 -0
- package/dist/src/util/fs.js +117 -0
- package/dist/src/util/fs.js.map +1 -0
- package/dist/src/util/http.js +65 -0
- package/dist/src/util/http.js.map +1 -0
- package/dist/src/util/invocation.js +43 -0
- package/dist/src/util/invocation.js.map +1 -0
- package/dist/src/util/open.js +41 -0
- package/dist/src/util/open.js.map +1 -0
- package/docs/ARCHITECTURE.md +123 -0
- package/docs/AUTH.md +242 -0
- package/docs/BACKEND.md +169 -0
- package/docs/CLIENTS.md +154 -0
- package/docs/DEVELOPMENT.md +171 -0
- package/docs/README.md +84 -0
- package/docs/TOOLS.md +221 -0
- package/package.json +67 -0
- package/skill/imagegen/LICENSE.txt +201 -0
- package/skill/imagegen/SKILL.md +189 -0
- package/skill/imagegen/references/prompting.md +112 -0
- package/skill/imagegen/references/sample-prompts.md +418 -0
- package/skill/imagegen/references/tools.md +90 -0
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
import * as z from "zod/v4";
|
|
2
|
+
import { MAX_INPUT_IMAGES, MAX_VARIANTS } from "../constants.js";
|
|
3
|
+
import { describeError, ImagegenError, toImagegenError } from "../errors.js";
|
|
4
|
+
import { ASPECT_RATIOS, runGeneration } from "../generation.js";
|
|
5
|
+
import { runRemoveBackground } from "../remove-background.js";
|
|
6
|
+
import { collectStatus, formatStatus } from "../status.js";
|
|
7
|
+
import { formatBytes, formatSeconds, formatWhen } from "../util/format.js";
|
|
8
|
+
import { cliInvocation } from "../util/invocation.js";
|
|
9
|
+
import { startProgress } from "./progress.js";
|
|
10
|
+
// NOTE: some clients strip JSON-Schema constraints (min/max/default) before showing tools to the
|
|
11
|
+
// model (opencode does for OpenAI models), so every constraint is also stated in the description.
|
|
12
|
+
const backgroundField = z
|
|
13
|
+
.enum(["auto", "transparent", "opaque"])
|
|
14
|
+
.default("auto")
|
|
15
|
+
.describe('Background: "transparent" returns a PNG with a real alpha channel (cutouts, sprites, icons, stickers, logos); "opaque" asks for a filled background (a hint — also describe the backdrop in the prompt); "auto" (default) lets the service decide.');
|
|
16
|
+
const aspectRatioField = z
|
|
17
|
+
.enum(ASPECT_RATIOS)
|
|
18
|
+
.default("auto")
|
|
19
|
+
.describe("Canvas shape: auto (default), 1:1, 4:5, 5:4, 4:3, 3:4, 3:2, 2:3, 16:9, 9:16, 21:9 or 9:21. The service chooses the exact pixel size from the prompt; this adds an explicit aspect-ratio line to it.");
|
|
20
|
+
const nField = z
|
|
21
|
+
.number()
|
|
22
|
+
.int()
|
|
23
|
+
.min(1)
|
|
24
|
+
.max(MAX_VARIANTS)
|
|
25
|
+
.default(1)
|
|
26
|
+
.describe(`Number of variants of this same prompt, 1-${MAX_VARIANTS} (default 1). Each variant is a separate request against the user's ChatGPT image quota. For several different assets make one call per asset instead.`);
|
|
27
|
+
const outputPathField = z
|
|
28
|
+
.string()
|
|
29
|
+
.optional()
|
|
30
|
+
.describe("Where to save: a .png/.jpg/.jpeg file path or a directory, absolute or relative to the workspace root. Omit to save in the server's image library (outside the project). Existing files are never replaced unless overwrite=true (a -2, -3… sibling is used instead); with n>1 a -1, -2… suffix is added.");
|
|
31
|
+
const outputFormatField = z
|
|
32
|
+
.enum(["png", "jpeg"])
|
|
33
|
+
.optional()
|
|
34
|
+
.describe("File format: png (default) or jpeg (converted locally; cannot be transparent). Inferred from output_path's extension when given.");
|
|
35
|
+
const overwriteField = z.boolean().default(false).describe("Replace an existing file at output_path (default false).");
|
|
36
|
+
const previewField = z
|
|
37
|
+
.boolean()
|
|
38
|
+
.default(true)
|
|
39
|
+
.describe("Attach a downscaled preview so you can check the result visually (default true). Set false to save tokens.");
|
|
40
|
+
const savedImageSchema = z.object({
|
|
41
|
+
id: z.string(),
|
|
42
|
+
path: z.string(),
|
|
43
|
+
mime_type: z.string(),
|
|
44
|
+
bytes: z.number().int(),
|
|
45
|
+
width: z.number().int().optional(),
|
|
46
|
+
height: z.number().int().optional(),
|
|
47
|
+
background: z.string().optional(),
|
|
48
|
+
transparent: z.boolean().optional(),
|
|
49
|
+
});
|
|
50
|
+
const generationOutputShape = {
|
|
51
|
+
images: z.array(savedImageSchema).describe("Saved images (full resolution)."),
|
|
52
|
+
prompt: z.string().describe("The exact prompt sent to the image service."),
|
|
53
|
+
elapsed_ms: z.number(),
|
|
54
|
+
failures: z.array(z.string()).describe("Errors for variants that failed (partial success)."),
|
|
55
|
+
warnings: z.array(z.string()),
|
|
56
|
+
};
|
|
57
|
+
function errorResult(err, others = []) {
|
|
58
|
+
const extra = others.filter((o) => o.message !== err.message).map((o) => describeError(o));
|
|
59
|
+
return { isError: true, content: [{ type: "text", text: [describeError(err), ...extra].join("\n") }] };
|
|
60
|
+
}
|
|
61
|
+
function imageLine(s, index, total) {
|
|
62
|
+
const dims = s.width && s.height ? `${s.width}×${s.height}` : "unknown size";
|
|
63
|
+
const format = s.mimeType === "image/jpeg" ? "JPEG" : "PNG";
|
|
64
|
+
const bg = s.transparent === true
|
|
65
|
+
? "transparent background (alpha verified)"
|
|
66
|
+
: s.transparent === false
|
|
67
|
+
? "OPAQUE (transparency was requested)"
|
|
68
|
+
: s.background === "transparent"
|
|
69
|
+
? "transparent background"
|
|
70
|
+
: "opaque background";
|
|
71
|
+
return `${total > 1 ? `${index + 1}. ` : ""}${s.path} — ${dims} ${format}, ${formatBytes(s.bytes)}, ${bg} (id ${s.id})`;
|
|
72
|
+
}
|
|
73
|
+
function generationResultToTool(result, req) {
|
|
74
|
+
const verb = req.tool === "edit_image" ? "Edited" : "Generated";
|
|
75
|
+
const count = result.saved.length;
|
|
76
|
+
const lines = [
|
|
77
|
+
`${verb} ${count} image${count === 1 ? "" : "s"} in ${formatSeconds(result.elapsedMs)} with the ChatGPT image service (your ChatGPT plan; no API key).`,
|
|
78
|
+
...result.saved.map((s, i) => imageLine(s, i, result.saved.length)),
|
|
79
|
+
];
|
|
80
|
+
if (result.failures.length > 0) {
|
|
81
|
+
lines.push(`${result.failures.length} of ${req.n} requests failed: ${[...new Set(result.failures.map((f) => describeError(f)))].join(" | ")}`);
|
|
82
|
+
}
|
|
83
|
+
for (const w of result.warnings)
|
|
84
|
+
lines.push(`Warning: ${w}`);
|
|
85
|
+
const previews = result.saved.filter((s) => s.preview);
|
|
86
|
+
if (previews.length > 0) {
|
|
87
|
+
lines.push(`${previews.length === 1 ? "A downscaled preview is" : "Downscaled previews are"} attached${previews.some((p) => p.preview?.transparent) ? " (transparent areas shown as a checkerboard)" : ""}. Check subject, composition, text and constraints before finishing.`);
|
|
88
|
+
}
|
|
89
|
+
lines.push(req.outputPath
|
|
90
|
+
? "Tell the user where the file(s) were saved."
|
|
91
|
+
: "Saved in the image library outside the project. If this asset belongs in the project, copy it into the workspace (or call again with output_path). Tell the user where it was saved.");
|
|
92
|
+
const content = [{ type: "text", text: lines.join("\n") }];
|
|
93
|
+
for (const s of previews)
|
|
94
|
+
if (s.preview)
|
|
95
|
+
content.push({ type: "image", data: s.preview.data, mimeType: s.preview.mimeType });
|
|
96
|
+
return {
|
|
97
|
+
content,
|
|
98
|
+
structuredContent: {
|
|
99
|
+
images: result.saved.map((s) => {
|
|
100
|
+
const o = { id: s.id, path: s.path, mime_type: s.mimeType, bytes: s.bytes };
|
|
101
|
+
if (s.width !== undefined)
|
|
102
|
+
o.width = s.width;
|
|
103
|
+
if (s.height !== undefined)
|
|
104
|
+
o.height = s.height;
|
|
105
|
+
if (s.background)
|
|
106
|
+
o.background = s.background;
|
|
107
|
+
if (s.transparent !== undefined)
|
|
108
|
+
o.transparent = s.transparent;
|
|
109
|
+
return o;
|
|
110
|
+
}),
|
|
111
|
+
prompt: result.promptSent,
|
|
112
|
+
elapsed_ms: result.elapsedMs,
|
|
113
|
+
failures: result.failures.map((f) => f.message),
|
|
114
|
+
warnings: result.warnings,
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
async function runGenerationTool(ctx, req, extra) {
|
|
119
|
+
const progress = startProgress(extra, req.tool === "edit_image" ? "Editing image" : "Generating image");
|
|
120
|
+
try {
|
|
121
|
+
const baseDir = await ctx.workspace.baseDir();
|
|
122
|
+
const result = await runGeneration(ctx, req, { baseDir, signal: extra.signal, onProgress: progress.update });
|
|
123
|
+
if (result.saved.length === 0) {
|
|
124
|
+
const [first, ...rest] = result.failures;
|
|
125
|
+
return errorResult(first ?? new ImagegenError("internal", "No image was produced."), rest);
|
|
126
|
+
}
|
|
127
|
+
return generationResultToTool(result, req);
|
|
128
|
+
}
|
|
129
|
+
catch (err) {
|
|
130
|
+
return errorResult(toImagegenError(err));
|
|
131
|
+
}
|
|
132
|
+
finally {
|
|
133
|
+
progress.stop();
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
export function registerTools(server, ctx) {
|
|
137
|
+
server.registerTool("generate_image", {
|
|
138
|
+
title: "Generate image",
|
|
139
|
+
description: "Generate a new raster image (photo, illustration, texture, sprite, mockup, icon, product shot…) from a text prompt, using the user's ChatGPT plan — the same image service as OpenAI Codex's built-in image tool, no API key. Saves the full-resolution file and returns its path plus a preview. The service chooses resolution and quality; steer orientation with aspect_ratio or in the prompt. Use background=\"transparent\" for assets that need real alpha. Typically takes 15-60 s.",
|
|
140
|
+
inputSchema: {
|
|
141
|
+
prompt: z
|
|
142
|
+
.string()
|
|
143
|
+
.min(1)
|
|
144
|
+
.max(32000)
|
|
145
|
+
.describe("Full image description. Structure it: use case, subject, style/medium, composition, lighting, palette, exact text in quotes, constraints/avoid."),
|
|
146
|
+
aspect_ratio: aspectRatioField,
|
|
147
|
+
background: backgroundField,
|
|
148
|
+
n: nField,
|
|
149
|
+
output_path: outputPathField,
|
|
150
|
+
output_format: outputFormatField,
|
|
151
|
+
overwrite: overwriteField,
|
|
152
|
+
include_preview: previewField,
|
|
153
|
+
},
|
|
154
|
+
outputSchema: generationOutputShape,
|
|
155
|
+
annotations: { title: "Generate image", readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
156
|
+
}, async (args, extra) => {
|
|
157
|
+
const req = {
|
|
158
|
+
tool: "generate_image",
|
|
159
|
+
prompt: args.prompt,
|
|
160
|
+
aspectRatio: args.aspect_ratio,
|
|
161
|
+
background: args.background,
|
|
162
|
+
n: args.n,
|
|
163
|
+
overwrite: args.overwrite,
|
|
164
|
+
preview: args.include_preview,
|
|
165
|
+
};
|
|
166
|
+
if (args.output_path)
|
|
167
|
+
req.outputPath = args.output_path;
|
|
168
|
+
if (args.output_format)
|
|
169
|
+
req.outputFormat = args.output_format;
|
|
170
|
+
return runGenerationTool(ctx, req, extra);
|
|
171
|
+
});
|
|
172
|
+
server.registerTool("edit_image", {
|
|
173
|
+
title: "Edit image",
|
|
174
|
+
description: `Edit or transform existing images, or create a new image guided by reference images, using the user's ChatGPT plan (no API key). Pass 1-${MAX_INPUT_IMAGES} images; refer to them in the prompt as Image 1, Image 2… (Image 1 is the primary edit target). State exactly what must change AND what must stay unchanged. Good for background replacement or removal, object removal/insertion, restyling, relighting, text localization, compositing and sketch-to-render. The input file is never modified; the result is saved as a new file.`,
|
|
175
|
+
inputSchema: {
|
|
176
|
+
images: z
|
|
177
|
+
.array(z.string().min(1))
|
|
178
|
+
.min(1)
|
|
179
|
+
.max(MAX_INPUT_IMAGES)
|
|
180
|
+
.describe(`1-${MAX_INPUT_IMAGES} input images: local file paths (absolute, ~/…, or relative to the workspace root), http(s) URLs, or data:image/…;base64 URLs. PNG, JPEG or WebP, up to 15 MB each.`),
|
|
181
|
+
prompt: z
|
|
182
|
+
.string()
|
|
183
|
+
.min(1)
|
|
184
|
+
.max(32000)
|
|
185
|
+
.describe('Edit instructions, e.g. "Image 1: replace only the sky with a warm sunset; keep the building, people and framing unchanged."'),
|
|
186
|
+
aspect_ratio: aspectRatioField,
|
|
187
|
+
background: backgroundField,
|
|
188
|
+
n: nField,
|
|
189
|
+
output_path: outputPathField,
|
|
190
|
+
output_format: outputFormatField,
|
|
191
|
+
overwrite: overwriteField,
|
|
192
|
+
include_preview: previewField,
|
|
193
|
+
},
|
|
194
|
+
outputSchema: generationOutputShape,
|
|
195
|
+
annotations: { title: "Edit image", readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
196
|
+
}, async (args, extra) => {
|
|
197
|
+
const req = {
|
|
198
|
+
tool: "edit_image",
|
|
199
|
+
prompt: args.prompt,
|
|
200
|
+
imageRefs: args.images,
|
|
201
|
+
aspectRatio: args.aspect_ratio,
|
|
202
|
+
background: args.background,
|
|
203
|
+
n: args.n,
|
|
204
|
+
overwrite: args.overwrite,
|
|
205
|
+
preview: args.include_preview,
|
|
206
|
+
};
|
|
207
|
+
if (args.output_path)
|
|
208
|
+
req.outputPath = args.output_path;
|
|
209
|
+
if (args.output_format)
|
|
210
|
+
req.outputFormat = args.output_format;
|
|
211
|
+
return runGenerationTool(ctx, req, extra);
|
|
212
|
+
});
|
|
213
|
+
server.registerTool("remove_background", {
|
|
214
|
+
title: "Remove flat background (chroma key)",
|
|
215
|
+
description: "Locally remove a flat, solid-color background from a PNG/JPEG and save a transparent PNG — no network, no quota. Use for images with a uniform backdrop (e.g. generated \"on a flat pure #00ff00 background\"), or to clean up a cutout. The key color is sampled from the image border unless key_color is given. Prefer background=\"transparent\" on generate_image/edit_image when creating new assets.",
|
|
216
|
+
inputSchema: {
|
|
217
|
+
input_path: z.string().min(1).describe("PNG or JPEG to process (absolute or relative to the workspace root)."),
|
|
218
|
+
output_path: z.string().optional().describe("Destination .png (default: <input>-transparent.png next to the input). Never overwrites unless overwrite=true."),
|
|
219
|
+
key_color: z.string().optional().describe("Background color to remove as hex, e.g. #00ff00. Default: auto-detected from the image border."),
|
|
220
|
+
soft_matte: z.boolean().default(true).describe("Smooth alpha ramp for anti-aliased edges (default true). false = hard key using tolerance."),
|
|
221
|
+
despill: z.boolean().default(true).describe("Remove key-color fringe/spill on edge pixels (default true)."),
|
|
222
|
+
tolerance: z.number().int().min(0).max(255).optional().describe("Hard-key per-channel tolerance 0-255 (default 12; used when soft_matte=false)."),
|
|
223
|
+
transparent_threshold: z.number().min(0).max(255).optional().describe("Soft matte: color distance at or below which pixels become fully transparent (default 12)."),
|
|
224
|
+
opaque_threshold: z.number().min(0).max(255).optional().describe("Soft matte: color distance at or above which pixels stay fully opaque (default 96)."),
|
|
225
|
+
edge_contract: z.number().int().min(0).max(16).optional().describe("Shrink the matte by this many pixels before feathering, 0-16 (default 0)."),
|
|
226
|
+
edge_feather: z.number().min(0).max(64).optional().describe("Blur radius for softened alpha edges, 0-64 (default 0)."),
|
|
227
|
+
overwrite: overwriteField,
|
|
228
|
+
include_preview: previewField,
|
|
229
|
+
},
|
|
230
|
+
annotations: { title: "Remove flat background", readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
231
|
+
}, async (args) => {
|
|
232
|
+
try {
|
|
233
|
+
const baseDir = await ctx.workspace.baseDir();
|
|
234
|
+
const req = {
|
|
235
|
+
inputPath: args.input_path,
|
|
236
|
+
softMatte: args.soft_matte,
|
|
237
|
+
despill: args.despill,
|
|
238
|
+
overwrite: args.overwrite,
|
|
239
|
+
preview: args.include_preview,
|
|
240
|
+
};
|
|
241
|
+
if (args.output_path)
|
|
242
|
+
req.outputPath = args.output_path;
|
|
243
|
+
if (args.key_color)
|
|
244
|
+
req.keyColor = args.key_color;
|
|
245
|
+
if (args.tolerance !== undefined)
|
|
246
|
+
req.tolerance = args.tolerance;
|
|
247
|
+
if (args.transparent_threshold !== undefined)
|
|
248
|
+
req.transparentThreshold = args.transparent_threshold;
|
|
249
|
+
if (args.opaque_threshold !== undefined)
|
|
250
|
+
req.opaqueThreshold = args.opaque_threshold;
|
|
251
|
+
if (args.edge_contract !== undefined)
|
|
252
|
+
req.edgeContract = args.edge_contract;
|
|
253
|
+
if (args.edge_feather !== undefined)
|
|
254
|
+
req.edgeFeather = args.edge_feather;
|
|
255
|
+
const r = await runRemoveBackground(ctx, req, { baseDir });
|
|
256
|
+
const lines = [
|
|
257
|
+
`Saved transparent PNG: ${r.outputPath} — ${r.width}×${r.height}, ${formatBytes(r.bytes)} (id ${r.id}).`,
|
|
258
|
+
`Removed key color ${r.keyColor}: ${r.transparentPercent.toFixed(1)}% fully transparent, ${r.partialPercent.toFixed(1)}% soft edge pixels.`,
|
|
259
|
+
...r.warnings.map((w) => `Warning: ${w}`),
|
|
260
|
+
];
|
|
261
|
+
if (r.preview)
|
|
262
|
+
lines.push("Preview attached (transparent areas shown as a checkerboard).");
|
|
263
|
+
const content = [{ type: "text", text: lines.join("\n") }];
|
|
264
|
+
if (r.preview)
|
|
265
|
+
content.push({ type: "image", data: r.preview.data, mimeType: r.preview.mimeType });
|
|
266
|
+
return { content };
|
|
267
|
+
}
|
|
268
|
+
catch (err) {
|
|
269
|
+
return errorResult(toImagegenError(err));
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
server.registerTool("auth_status", {
|
|
273
|
+
title: "Sign-in and quota status",
|
|
274
|
+
description: "Show whether image generation is signed in, which ChatGPT account/plan and credential source is used, and the current usage-limit windows. Costs no image quota. Call this when a tool reports an auth or quota problem, or after sign_in.",
|
|
275
|
+
inputSchema: {
|
|
276
|
+
check_usage: z.boolean().default(true).describe("Also fetch current usage/quota from ChatGPT (default true)."),
|
|
277
|
+
},
|
|
278
|
+
annotations: { title: "Sign-in status", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
279
|
+
}, async (args, extra) => {
|
|
280
|
+
try {
|
|
281
|
+
const options = { checkUsage: args.check_usage, signal: extra.signal };
|
|
282
|
+
const pending = ctx.login.pendingLogin;
|
|
283
|
+
if (pending)
|
|
284
|
+
options.pendingLogin = pending;
|
|
285
|
+
const last = ctx.login.lastOutcome;
|
|
286
|
+
if (last)
|
|
287
|
+
options.lastLogin = last;
|
|
288
|
+
const report = await collectStatus(ctx, options);
|
|
289
|
+
return { content: [{ type: "text", text: formatStatus(report) }] };
|
|
290
|
+
}
|
|
291
|
+
catch (err) {
|
|
292
|
+
return errorResult(toImagegenError(err));
|
|
293
|
+
}
|
|
294
|
+
});
|
|
295
|
+
server.registerTool("sign_in", {
|
|
296
|
+
title: "Sign in with ChatGPT",
|
|
297
|
+
description: "Start signing this image server in to the user's ChatGPT account (required once before generating, unless an existing Codex/opencode ChatGPT sign-in is detected). Returns a link (browser method) or a code (device method) that the USER must open or enter — relay it verbatim. Sign-in completes in the background; afterwards call auth_status to confirm.",
|
|
298
|
+
inputSchema: {
|
|
299
|
+
method: z
|
|
300
|
+
.enum(["browser", "device"])
|
|
301
|
+
.default("browser")
|
|
302
|
+
.describe('"browser" (default): the user opens a link on THIS machine (redirects to localhost:1455). "device": the user enters a code at auth.openai.com/codex/device from any device — use for remote/headless machines.'),
|
|
303
|
+
open_browser: z.boolean().default(true).describe("Try to open the link in the local browser automatically (browser method; default true)."),
|
|
304
|
+
force: z.boolean().default(false).describe("Start a new sign-in even if already signed in (e.g. to switch accounts). Default false."),
|
|
305
|
+
},
|
|
306
|
+
annotations: { title: "Sign in", readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
307
|
+
}, async (args) => {
|
|
308
|
+
try {
|
|
309
|
+
if (!args.force) {
|
|
310
|
+
const own = (await ctx.auth.inspect()).find((s) => s.source === "own");
|
|
311
|
+
if (own && (own.state === "ready" || own.state === "refreshable")) {
|
|
312
|
+
const who = own.identity?.email ? ` as ${own.identity.email}` : "";
|
|
313
|
+
return { content: [{ type: "text", text: `Already signed in${who}. Pass force=true to sign in again (for example with a different account).` }] };
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
const { info, reused, browserOpened } = await ctx.login.start(args.method, { openBrowser: args.open_browser });
|
|
317
|
+
const expires = info.expiresAt ? ` It expires ${formatWhen(info.expiresAt)}.` : "";
|
|
318
|
+
const text = info.method === "device"
|
|
319
|
+
? [
|
|
320
|
+
`${reused ? "A device-code sign-in is already in progress." : "Device-code sign-in started."} Ask the user to open ${info.url} on any device, sign in to ChatGPT and enter this code: ${info.userCode ?? "?"}${expires}`,
|
|
321
|
+
"(If ChatGPT says device codes are disabled, enable “device code authorization for Codex” in ChatGPT → Settings → Security, or use method=\"browser\".)",
|
|
322
|
+
"When the user has approved it, call auth_status to confirm.",
|
|
323
|
+
].join("\n")
|
|
324
|
+
: [
|
|
325
|
+
`${reused ? "A browser sign-in is already in progress." : "Browser sign-in started."} Ask the user to open this link and sign in with their ChatGPT account:`,
|
|
326
|
+
info.url,
|
|
327
|
+
`${browserOpened ? "(It was also opened in the default browser on this machine.) " : ""}The browser must run on the same machine as this server, because the sign-in redirects to http://localhost:1455.${expires}`,
|
|
328
|
+
`On a remote or headless machine use method="device", or run \`${cliInvocation()} login --device\` in a terminal.`,
|
|
329
|
+
"When the user has finished, call auth_status to confirm.",
|
|
330
|
+
].join("\n");
|
|
331
|
+
return { content: [{ type: "text", text }] };
|
|
332
|
+
}
|
|
333
|
+
catch (err) {
|
|
334
|
+
return errorResult(toImagegenError(err, "login_failed"));
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
//# sourceMappingURL=tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../../src/server/tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import os from "node:os";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
/**
|
|
5
|
+
* Resolves the directory relative paths are interpreted against: the client's first `file://`
|
|
6
|
+
* root when the client supports MCP roots (opencode reports the project directory), otherwise the
|
|
7
|
+
* process working directory (MCP clients usually spawn servers in the project directory). A
|
|
8
|
+
* filesystem root (`/`, as some desktop apps use) falls back to the home directory.
|
|
9
|
+
*/
|
|
10
|
+
export class Workspace {
|
|
11
|
+
server;
|
|
12
|
+
logger;
|
|
13
|
+
cwd;
|
|
14
|
+
cached;
|
|
15
|
+
constructor(server, logger, cwd = process.cwd()) {
|
|
16
|
+
this.server = server;
|
|
17
|
+
this.logger = logger;
|
|
18
|
+
this.cwd = cwd;
|
|
19
|
+
}
|
|
20
|
+
invalidate() {
|
|
21
|
+
this.cached = undefined;
|
|
22
|
+
}
|
|
23
|
+
async baseDir() {
|
|
24
|
+
if (this.cached)
|
|
25
|
+
return this.cached;
|
|
26
|
+
let dir;
|
|
27
|
+
if (this.server.getClientCapabilities()?.roots) {
|
|
28
|
+
try {
|
|
29
|
+
const { roots } = await this.server.listRoots(undefined, { timeout: 3_000 });
|
|
30
|
+
const first = roots.find((r) => r.uri.startsWith("file://"));
|
|
31
|
+
if (first)
|
|
32
|
+
dir = fileURLToPath(first.uri);
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
this.logger.debug("roots/list failed; using cwd", { message: err instanceof Error ? err.message : String(err) });
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
dir ??= this.cwd;
|
|
39
|
+
if (path.parse(dir).root === dir)
|
|
40
|
+
dir = os.homedir();
|
|
41
|
+
this.cached = dir;
|
|
42
|
+
return dir;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=workspace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../../src/server/workspace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAIzC;;;;;GAKG;AACH,MAAM,OAAO,SAAS;IAID,MAAM;IACN,MAAM;IACN,GAAG;IALd,MAAM,CAAqB;IAEnC,YACmB,MAAc,EACd,MAAc,EACd,GAAG,GAAW,OAAO,CAAC,GAAG,EAAE;sBAF3B,MAAM;sBACN,MAAM;mBACN,GAAG;IACnB,CAAC;IAEJ,UAAU;QACR,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,OAAO;QACX,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC,MAAM,CAAC;QACpC,IAAI,GAAuB,CAAC;QAC5B,IAAI,IAAI,CAAC,MAAM,CAAC,qBAAqB,EAAE,EAAE,KAAK,EAAE,CAAC;YAC/C,IAAI,CAAC;gBACH,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;gBAC7E,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;gBAC7D,IAAI,KAAK;oBAAE,GAAG,GAAG,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC5C,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,EAAE,EAAE,OAAO,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACnH,CAAC;QACH,CAAC;QACD,GAAG,KAAK,IAAI,CAAC,GAAG,CAAC;QACjB,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,GAAG;YAAE,GAAG,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;QACrD,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC;QAClB,OAAO,GAAG,CAAC;IACb,CAAC;CACF"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { AuthManager } from "./auth/manager.js";
|
|
2
|
+
import { describeUsage } from "./backend/ratelimits.js";
|
|
3
|
+
import { toImagegenError } from "./errors.js";
|
|
4
|
+
import { formatWhen } from "./util/format.js";
|
|
5
|
+
import { cliInvocation } from "./util/invocation.js";
|
|
6
|
+
export async function collectStatus(deps, options) {
|
|
7
|
+
const sources = await deps.auth.inspect();
|
|
8
|
+
const active = AuthManager.activeSource(sources);
|
|
9
|
+
const report = { signedIn: Boolean(active), sources };
|
|
10
|
+
if (active)
|
|
11
|
+
report.active = active;
|
|
12
|
+
if (options.pendingLogin)
|
|
13
|
+
report.pendingLogin = options.pendingLogin;
|
|
14
|
+
if (options.lastLogin)
|
|
15
|
+
report.lastLogin = options.lastLogin;
|
|
16
|
+
if (active && options.checkUsage) {
|
|
17
|
+
try {
|
|
18
|
+
report.usage = await deps.images.getUsage(options.signal ? { signal: options.signal } : {});
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
report.usageError = toImagegenError(err).message;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return report;
|
|
25
|
+
}
|
|
26
|
+
const STATE_MARK = {
|
|
27
|
+
ready: "✓",
|
|
28
|
+
refreshable: "✓",
|
|
29
|
+
missing: "·",
|
|
30
|
+
expired: "✗",
|
|
31
|
+
unusable: "✗",
|
|
32
|
+
disabled: "-",
|
|
33
|
+
};
|
|
34
|
+
function identityLine(r) {
|
|
35
|
+
const parts = [];
|
|
36
|
+
if (r.identity?.email)
|
|
37
|
+
parts.push(r.identity.email);
|
|
38
|
+
if (r.identity?.planType)
|
|
39
|
+
parts.push(`ChatGPT ${r.identity.planType} plan`);
|
|
40
|
+
if (r.identity?.accountId)
|
|
41
|
+
parts.push(`account …${r.identity.accountId.slice(-6)}`);
|
|
42
|
+
return parts.join(", ");
|
|
43
|
+
}
|
|
44
|
+
export function formatStatus(report, now = Date.now()) {
|
|
45
|
+
const lines = [];
|
|
46
|
+
const invocation = cliInvocation();
|
|
47
|
+
if (report.active) {
|
|
48
|
+
const who = identityLine(report.active);
|
|
49
|
+
lines.push(`Signed in: yes — using the ${report.active.label}${who ? ` (${who})` : ""}.`);
|
|
50
|
+
if (report.active.expiresAt !== undefined) {
|
|
51
|
+
const renew = report.active.source === "own" ? "renewed automatically" : "renewed by the app that owns it";
|
|
52
|
+
lines.push(`Access token ${report.active.expiresAt > now ? "expires" : "expired"} ${formatWhen(report.active.expiresAt, now)} (${renew}).`);
|
|
53
|
+
}
|
|
54
|
+
if (report.active.identity?.planType === "free") {
|
|
55
|
+
lines.push("Note: Codex image generation is not available on the ChatGPT Free plan.");
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
lines.push("Signed in: no.");
|
|
60
|
+
lines.push(`To sign in, run \`${invocation} login\` in a terminal (add --device on a headless machine), or call the sign_in tool.`);
|
|
61
|
+
}
|
|
62
|
+
if (report.usage) {
|
|
63
|
+
const usageLines = describeUsage(report.usage, now);
|
|
64
|
+
if (usageLines.length > 0)
|
|
65
|
+
lines.push(`Usage: ${usageLines.join("; ")}.`);
|
|
66
|
+
}
|
|
67
|
+
else if (report.usageError) {
|
|
68
|
+
lines.push(`Usage: unavailable (${report.usageError}).`);
|
|
69
|
+
}
|
|
70
|
+
if (report.pendingLogin) {
|
|
71
|
+
const p = report.pendingLogin;
|
|
72
|
+
lines.push(p.method === "device"
|
|
73
|
+
? `Sign-in in progress (device code): open ${p.url} and enter ${p.userCode ?? "the code"}.`
|
|
74
|
+
: `Sign-in in progress (browser): ${p.url}`);
|
|
75
|
+
}
|
|
76
|
+
if (report.lastLogin)
|
|
77
|
+
lines.push(`Last sign-in attempt: ${report.lastLogin.ok ? "succeeded" : "failed"} — ${report.lastLogin.message}`);
|
|
78
|
+
lines.push("Credential sources (checked in this order):");
|
|
79
|
+
for (const s of report.sources) {
|
|
80
|
+
const who = identityLine(s);
|
|
81
|
+
const expiry = s.expiresAt !== undefined && (s.state === "ready" || s.state === "refreshable") ? `, token expires ${formatWhen(s.expiresAt, now)}` : "";
|
|
82
|
+
lines.push(` ${STATE_MARK[s.state]} ${s.label}: ${s.detail}${who ? ` — ${who}` : ""}${expiry} [${s.file}]`);
|
|
83
|
+
}
|
|
84
|
+
return lines.join("\n");
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/status.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export function formatDuration(ms) {
|
|
2
|
+
if (!Number.isFinite(ms))
|
|
3
|
+
return "?";
|
|
4
|
+
const totalSeconds = Math.max(0, Math.round(ms / 1000));
|
|
5
|
+
if (totalSeconds < 60)
|
|
6
|
+
return `${totalSeconds}s`;
|
|
7
|
+
const days = Math.floor(totalSeconds / 86_400);
|
|
8
|
+
const hours = Math.floor((totalSeconds % 86_400) / 3_600);
|
|
9
|
+
const minutes = Math.floor((totalSeconds % 3_600) / 60);
|
|
10
|
+
if (days > 0)
|
|
11
|
+
return hours > 0 ? `${days}d ${hours}h` : `${days}d`;
|
|
12
|
+
if (hours > 0)
|
|
13
|
+
return minutes > 0 ? `${hours}h ${minutes}m` : `${hours}h`;
|
|
14
|
+
return `${minutes}m`;
|
|
15
|
+
}
|
|
16
|
+
export function formatSeconds(ms) {
|
|
17
|
+
return `${(ms / 1000).toFixed(1)}s`;
|
|
18
|
+
}
|
|
19
|
+
export function formatBytes(bytes) {
|
|
20
|
+
if (bytes < 1024)
|
|
21
|
+
return `${bytes} B`;
|
|
22
|
+
if (bytes < 1024 * 1024)
|
|
23
|
+
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
24
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
25
|
+
}
|
|
26
|
+
/** "in 1h 29m (2026-09-23 14:03 local)" for a future epoch-ms timestamp. */
|
|
27
|
+
export function formatWhen(epochMs, now = Date.now()) {
|
|
28
|
+
const delta = epochMs - now;
|
|
29
|
+
const local = new Date(epochMs);
|
|
30
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
31
|
+
const stamp = `${local.getFullYear()}-${pad(local.getMonth() + 1)}-${pad(local.getDate())} ${pad(local.getHours())}:${pad(local.getMinutes())}`;
|
|
32
|
+
if (delta >= 0)
|
|
33
|
+
return `in ${formatDuration(delta)} (${stamp} local)`;
|
|
34
|
+
return `${formatDuration(-delta)} ago (${stamp} local)`;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../../src/util/format.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,cAAc,CAAC,EAAU;IACvC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;QAAE,OAAO,GAAG,CAAC;IACrC,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC;IACxD,IAAI,YAAY,GAAG,EAAE;QAAE,OAAO,GAAG,YAAY,GAAG,CAAC;IACjD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,MAAM,CAAC,CAAC;IAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,YAAY,GAAG,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC;IAC1D,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,YAAY,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;IACxD,IAAI,IAAI,GAAG,CAAC;QAAE,OAAO,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,KAAK,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC;IACnE,IAAI,KAAK,GAAG,CAAC;QAAE,OAAO,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,OAAO,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC;IAC1E,OAAO,GAAG,OAAO,GAAG,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,EAAU;IACtC,OAAO,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,IAAI,KAAK,GAAG,IAAI;QAAE,OAAO,GAAG,KAAK,IAAI,CAAC;IACtC,IAAI,KAAK,GAAG,IAAI,GAAG,IAAI;QAAE,OAAO,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;IAClE,OAAO,GAAG,CAAC,KAAK,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;AACpD,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,UAAU,CAAC,OAAe,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;IAC1D,MAAM,KAAK,GAAG,OAAO,GAAG,GAAG,CAAC;IAC5B,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC;IAChC,MAAM,GAAG,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACtD,MAAM,KAAK,GAAG,GAAG,KAAK,CAAC,WAAW,EAAE,IAAI,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC;IAChJ,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,MAAM,cAAc,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC;IACtE,OAAO,GAAG,cAAc,CAAC,CAAC,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC;AAC1D,CAAC"}
|