@falldownthesystem/imagen-mcp 0.1.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/LICENSE +21 -0
- package/README.md +99 -0
- package/dist/index.js +126 -0
- package/dist/params.js +110 -0
- package/package.json +47 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 FallDownTheSystem
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# imagen-mcp
|
|
2
|
+
|
|
3
|
+
Minimal MCP server for OpenAI GPT Image 2.5. Two tools, two models.
|
|
4
|
+
|
|
5
|
+
| Alias | API model | Use |
|
|
6
|
+
|---|---|---|
|
|
7
|
+
| `flare` (default) | `gpt-image-2.5-flare` | Fast, general purpose |
|
|
8
|
+
| `sunburst` | `gpt-image-2.5-sunburst` | Slower, higher precision |
|
|
9
|
+
|
|
10
|
+
## Setup
|
|
11
|
+
|
|
12
|
+
Install from npm:
|
|
13
|
+
|
|
14
|
+
```sh
|
|
15
|
+
npm install -g @falldownthesystem/imagen-mcp
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Or build from source:
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
npm install
|
|
22
|
+
npm run build
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Set `OPENAI_API_KEY` in the environment, or put it in a `.env` file next to `package.json`.
|
|
26
|
+
|
|
27
|
+
Optional environment variables:
|
|
28
|
+
|
|
29
|
+
- `IMAGEN_OUTPUT_DIR`: default directory for saved images (default `./output`).
|
|
30
|
+
- `IMAGEN_DEFAULT_MODEL`: `flare` or `sunburst` (default `flare`).
|
|
31
|
+
|
|
32
|
+
## Client config
|
|
33
|
+
|
|
34
|
+
Claude Code (`.mcp.json`) or Claude Desktop, using the npm package:
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"mcpServers": {
|
|
39
|
+
"imagen": {
|
|
40
|
+
"command": "npx",
|
|
41
|
+
"args": ["-y", "@falldownthesystem/imagen-mcp"],
|
|
42
|
+
"env": {
|
|
43
|
+
"OPENAI_API_KEY": "sk-...",
|
|
44
|
+
"IMAGEN_OUTPUT_DIR": "C:/Users/me/Pictures/imagen"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Or with a local build, use `"command": "node"` and `"args": ["path/to/imagen-mcp/dist/index.js"]`.
|
|
52
|
+
|
|
53
|
+
Claude Code one-liner:
|
|
54
|
+
|
|
55
|
+
```sh
|
|
56
|
+
claude mcp add imagen -e OPENAI_API_KEY=sk-... -- npx -y @falldownthesystem/imagen-mcp
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Tools
|
|
60
|
+
|
|
61
|
+
### `generate_image`
|
|
62
|
+
|
|
63
|
+
Text to image. Required: `prompt`.
|
|
64
|
+
|
|
65
|
+
| Option | Values | Default | Notes |
|
|
66
|
+
|---|---|---|---|
|
|
67
|
+
| `moderation` | `auto`, `low` | `low` | OpenAI content filter strictness. `low` refuses fewer borderline prompts; OpenAI usage policies still apply. The API default is `auto`; this tool sends `low` unless set. |
|
|
68
|
+
|
|
69
|
+
### `edit_image`
|
|
70
|
+
|
|
71
|
+
Reference images to image. Required: `prompt`, `images`. The model regenerates the whole picture guided by the references and the prompt. Without a mask, the prompt alone decides what changes.
|
|
72
|
+
|
|
73
|
+
| Option | Values | Default | Notes |
|
|
74
|
+
|---|---|---|---|
|
|
75
|
+
| `images` | 1 to 16 file paths | required | `png`, `jpeg`, or `webp`. The first image is the main subject; extra images supply elements to combine, such as a logo or a style reference. Relative paths resolve against the server working directory. |
|
|
76
|
+
| `mask` | file path | none | PNG with an alpha channel, same width and height as the first image. Fully transparent pixels mark the region the model may repaint; opaque pixels mark what to keep. Use for inpainting one area or filling an extended canvas. It is guidance, not a hard pixel lock. |
|
|
77
|
+
| `input_fidelity` | `high`, `low` | `low` | How closely exact details from the references are preserved. `low` keeps content and layout, but faces, text, logos, and textures may shift. `high` keeps them faithful and steadies the area outside a mask. It costs more input tokens per reference image. Use `high` for real people, brands, product shots, or spot edits. |
|
|
78
|
+
|
|
79
|
+
### Shared options
|
|
80
|
+
|
|
81
|
+
Only the options you set are sent to the API. The default column shows what applies when an option is omitted.
|
|
82
|
+
|
|
83
|
+
| Option | Values | Default | Notes |
|
|
84
|
+
|---|---|---|---|
|
|
85
|
+
| `prompt` | text, up to 32000 chars | required | |
|
|
86
|
+
| `model` | `flare`, `sunburst` | `flare` | `flare` (`gpt-image-2.5-flare`) is fast and general purpose. `sunburst` (`gpt-image-2.5-sunburst`) is slower with higher precision. Same token price. `IMAGEN_DEFAULT_MODEL` env changes the default. |
|
|
87
|
+
| `size` | `auto`, `1024x1024`, `1536x1024`, `1024x1536`, `WIDTHxHEIGHT` | `auto` | Custom sizes: multiples of 16, ratio 1:3 to 3:1, long edge up to 3840. Overrides `aspect_ratio`. |
|
|
88
|
+
| `aspect_ratio` | `1:1`, `3:2`, `2:3`, `4:3`, `3:4`, `16:9`, `9:16`, `21:9`, `9:21` | none | Combined with `long_edge` to compute a size. |
|
|
89
|
+
| `long_edge` | 256 to 3840 | 1536 | Only used with `aspect_ratio`. |
|
|
90
|
+
| `quality` | `low`, `medium`, `high`, `xhigh`, `max`, `auto` | `auto` | Higher tiers add detail and cost more output tokens. `auto` lets the model choose and may pick an expensive tier. Set it explicitly to control cost. |
|
|
91
|
+
| `background` | `transparent`, `opaque`, `auto` | `auto` | `transparent` gives an alpha background for stickers, logos, and cut-outs. Needs `png` or `webp`. |
|
|
92
|
+
| `output_format` | `png`, `jpeg`, `webp` | `png` | Also sets the file extension. |
|
|
93
|
+
| `output_compression` | 0 to 100 | 100 | `jpeg` and `webp` only. Works like JPEG quality: lower is smaller with more artifacts. |
|
|
94
|
+
| `n` | 1 to 10 | 1 | Number of separate variations generated from the same prompt in one call. Each costs its own output tokens. |
|
|
95
|
+
| `output_dir` | directory path | `IMAGEN_OUTPUT_DIR` env, else `./output` | Relative to the server working directory. |
|
|
96
|
+
| `file_name` | base name without extension | timestamp plus a slug of the prompt | With `n` greater than 1, a `-1`, `-2` suffix is added. |
|
|
97
|
+
| `return_image` | boolean | `false` | Also return each image inline as MCP image content, so the client shows it and the model can inspect it. Adds about 1.4 MB of context per 1024x1024 png. The file is saved to disk either way. |
|
|
98
|
+
|
|
99
|
+
The result lists the saved file paths, the model, the size, and token usage.
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { McpServer } from "@modelcontextprotocol/server";
|
|
5
|
+
import { StdioServerTransport } from "@modelcontextprotocol/server/stdio";
|
|
6
|
+
import OpenAI, { toFile } from "openai";
|
|
7
|
+
import * as z from "zod/v4";
|
|
8
|
+
import { commonInput, resolveModel, resolveSize } from "./params.js";
|
|
9
|
+
// A .env next to the project is a convenience for local runs; MCP client configs normally pass env directly.
|
|
10
|
+
try {
|
|
11
|
+
process.loadEnvFile(path.join(import.meta.dirname, "..", ".env"));
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
// No .env file present; rely on the process environment.
|
|
15
|
+
}
|
|
16
|
+
const client = new OpenAI();
|
|
17
|
+
const server = new McpServer({ name: "imagen-mcp", version: "0.1.0" });
|
|
18
|
+
const MIME = { png: "image/png", jpeg: "image/jpeg", webp: "image/webp" };
|
|
19
|
+
const outputSchema = z.object({
|
|
20
|
+
files: z.array(z.string()),
|
|
21
|
+
model: z.string(),
|
|
22
|
+
size: z.string(),
|
|
23
|
+
usage: z
|
|
24
|
+
.object({
|
|
25
|
+
input_tokens: z.number(),
|
|
26
|
+
output_tokens: z.number(),
|
|
27
|
+
total_tokens: z.number(),
|
|
28
|
+
input_tokens_details: z.object({ image_tokens: z.number(), text_tokens: z.number() }).optional(),
|
|
29
|
+
output_tokens_details: z.object({ image_tokens: z.number(), text_tokens: z.number() }).optional(),
|
|
30
|
+
})
|
|
31
|
+
.optional(),
|
|
32
|
+
});
|
|
33
|
+
const annotations = { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true };
|
|
34
|
+
function slug(text) {
|
|
35
|
+
return text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 40) || "image";
|
|
36
|
+
}
|
|
37
|
+
function apiParams(input) {
|
|
38
|
+
return {
|
|
39
|
+
model: resolveModel(input.model),
|
|
40
|
+
prompt: input.prompt,
|
|
41
|
+
size: resolveSize(input),
|
|
42
|
+
quality: input.quality,
|
|
43
|
+
background: input.background,
|
|
44
|
+
output_format: input.output_format,
|
|
45
|
+
output_compression: input.output_compression,
|
|
46
|
+
n: input.n,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
async function saveImages(result, input, model, size) {
|
|
50
|
+
const images = result.data ?? [];
|
|
51
|
+
if (images.length === 0)
|
|
52
|
+
throw new Error("The API returned no images.");
|
|
53
|
+
const ext = input.output_format ?? "png";
|
|
54
|
+
const dir = path.resolve(input.output_dir ?? process.env.IMAGEN_OUTPUT_DIR ?? "output");
|
|
55
|
+
await fs.mkdir(dir, { recursive: true });
|
|
56
|
+
const base = input.file_name ?? `${new Date().toISOString().replace(/[:.]/g, "-")}-${slug(input.prompt)}`;
|
|
57
|
+
const files = [];
|
|
58
|
+
const content = [];
|
|
59
|
+
for (const [i, image] of images.entries()) {
|
|
60
|
+
if (!image.b64_json)
|
|
61
|
+
throw new Error(`Image ${i + 1} has no b64_json payload.`);
|
|
62
|
+
const file = path.join(dir, images.length > 1 ? `${base}-${i + 1}.${ext}` : `${base}.${ext}`);
|
|
63
|
+
await fs.writeFile(file, Buffer.from(image.b64_json, "base64"));
|
|
64
|
+
files.push(file);
|
|
65
|
+
if (input.return_image)
|
|
66
|
+
content.push({ type: "image", data: image.b64_json, mimeType: MIME[ext] });
|
|
67
|
+
}
|
|
68
|
+
const output = { files, model, size: size ?? "auto", usage: result.usage };
|
|
69
|
+
content.unshift({ type: "text", text: JSON.stringify(output, null, 2) });
|
|
70
|
+
return { content, structuredContent: output };
|
|
71
|
+
}
|
|
72
|
+
async function loadImage(file) {
|
|
73
|
+
const abs = path.resolve(file);
|
|
74
|
+
const ext = path.extname(abs).slice(1).toLowerCase();
|
|
75
|
+
const type = MIME[ext === "jpg" ? "jpeg" : ext] ?? "application/octet-stream";
|
|
76
|
+
return toFile(await fs.readFile(abs), path.basename(abs), { type });
|
|
77
|
+
}
|
|
78
|
+
server.registerTool("generate_image", {
|
|
79
|
+
title: "Generate image",
|
|
80
|
+
description: "Generate images from a text prompt with OpenAI GPT Image 2.5. Saves files to disk and returns paths and token usage.",
|
|
81
|
+
inputSchema: z.object({
|
|
82
|
+
...commonInput,
|
|
83
|
+
moderation: z
|
|
84
|
+
.enum(["auto", "low"])
|
|
85
|
+
.optional()
|
|
86
|
+
.describe("OpenAI content filter. low refuses fewer borderline prompts. Default low."),
|
|
87
|
+
}),
|
|
88
|
+
outputSchema,
|
|
89
|
+
annotations,
|
|
90
|
+
}, async (input) => {
|
|
91
|
+
const params = apiParams(input);
|
|
92
|
+
const result = await client.images.generate({ ...params, moderation: input.moderation ?? "low" });
|
|
93
|
+
return saveImages(result, input, params.model, params.size);
|
|
94
|
+
});
|
|
95
|
+
server.registerTool("edit_image", {
|
|
96
|
+
title: "Edit image",
|
|
97
|
+
description: "Edit, restyle, or combine 1-16 reference images with a text prompt using OpenAI GPT Image 2.5. The whole picture is regenerated; without a mask the prompt decides what changes. Saves files to disk and returns paths and token usage.",
|
|
98
|
+
inputSchema: z.object({
|
|
99
|
+
...commonInput,
|
|
100
|
+
images: z
|
|
101
|
+
.array(z.string())
|
|
102
|
+
.min(1)
|
|
103
|
+
.max(16)
|
|
104
|
+
.describe("Paths of 1-16 reference images (png/jpeg/webp). First = main subject; others = elements to combine. Relative to server cwd."),
|
|
105
|
+
mask: z
|
|
106
|
+
.string()
|
|
107
|
+
.optional()
|
|
108
|
+
.describe("Path of a PNG with alpha, same size as first image. Transparent pixels = region to repaint (guidance, not a hard lock). Default none."),
|
|
109
|
+
input_fidelity: z
|
|
110
|
+
.enum(["high", "low"])
|
|
111
|
+
.optional()
|
|
112
|
+
.describe("high keeps faces, text, logos and unmasked areas faithful; costs more input tokens. Default low."),
|
|
113
|
+
}),
|
|
114
|
+
outputSchema,
|
|
115
|
+
annotations,
|
|
116
|
+
}, async (input) => {
|
|
117
|
+
const params = apiParams(input);
|
|
118
|
+
const result = await client.images.edit({
|
|
119
|
+
...params,
|
|
120
|
+
image: await Promise.all(input.images.map(loadImage)),
|
|
121
|
+
mask: input.mask ? await loadImage(input.mask) : undefined,
|
|
122
|
+
input_fidelity: input.input_fidelity,
|
|
123
|
+
});
|
|
124
|
+
return saveImages(result, input, params.model, params.size);
|
|
125
|
+
});
|
|
126
|
+
await server.connect(new StdioServerTransport());
|
package/dist/params.js
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import * as z from "zod/v4";
|
|
2
|
+
export const MODELS = {
|
|
3
|
+
flare: "gpt-image-2.5-flare",
|
|
4
|
+
sunburst: "gpt-image-2.5-sunburst",
|
|
5
|
+
};
|
|
6
|
+
const ASPECT_RATIOS = {
|
|
7
|
+
"1:1": 1,
|
|
8
|
+
"3:2": 3 / 2,
|
|
9
|
+
"2:3": 2 / 3,
|
|
10
|
+
"4:3": 4 / 3,
|
|
11
|
+
"3:4": 3 / 4,
|
|
12
|
+
"16:9": 16 / 9,
|
|
13
|
+
"9:16": 9 / 16,
|
|
14
|
+
"21:9": 21 / 9,
|
|
15
|
+
"9:21": 9 / 21,
|
|
16
|
+
};
|
|
17
|
+
// Limits documented by OpenAI for custom WIDTHxHEIGHT sizes on GPT Image models.
|
|
18
|
+
const SIZE_STEP = 16;
|
|
19
|
+
const MAX_LONG_EDGE = 3840;
|
|
20
|
+
const MAX_RATIO = 3;
|
|
21
|
+
const DEFAULT_LONG_EDGE = 1536;
|
|
22
|
+
export const commonInput = {
|
|
23
|
+
prompt: z
|
|
24
|
+
.string()
|
|
25
|
+
.min(1)
|
|
26
|
+
.max(32000)
|
|
27
|
+
.describe("Image description, or the change to make when editing."),
|
|
28
|
+
model: z
|
|
29
|
+
.enum(["flare", "sunburst"])
|
|
30
|
+
.optional()
|
|
31
|
+
.describe("flare = fast, general purpose. sunburst = slower, higher precision. Same price. Default flare."),
|
|
32
|
+
size: z
|
|
33
|
+
.string()
|
|
34
|
+
.regex(/^(auto|\d+x\d+)$/)
|
|
35
|
+
.optional()
|
|
36
|
+
.describe("auto | 1024x1024 | 1536x1024 | 1024x1536 | WIDTHxHEIGHT (multiples of 16, ratio 1:3..3:1, max edge 3840). Overrides aspect_ratio. Default auto."),
|
|
37
|
+
aspect_ratio: z
|
|
38
|
+
.enum(Object.keys(ASPECT_RATIOS))
|
|
39
|
+
.optional()
|
|
40
|
+
.describe("Computes size together with long_edge. Default none."),
|
|
41
|
+
long_edge: z
|
|
42
|
+
.number()
|
|
43
|
+
.int()
|
|
44
|
+
.min(256)
|
|
45
|
+
.max(MAX_LONG_EDGE)
|
|
46
|
+
.optional()
|
|
47
|
+
.describe(`Longer side in px, used with aspect_ratio. Default ${DEFAULT_LONG_EDGE}.`),
|
|
48
|
+
quality: z
|
|
49
|
+
.enum(["low", "medium", "high", "xhigh", "max", "auto"])
|
|
50
|
+
.optional()
|
|
51
|
+
.describe("Higher = more detail, more output tokens. auto lets the model choose (may be costly). Default auto."),
|
|
52
|
+
background: z
|
|
53
|
+
.enum(["transparent", "opaque", "auto"])
|
|
54
|
+
.optional()
|
|
55
|
+
.describe("transparent needs png or webp. Default auto."),
|
|
56
|
+
output_format: z.enum(["png", "jpeg", "webp"]).optional().describe("Also the file extension. Default png."),
|
|
57
|
+
output_compression: z
|
|
58
|
+
.number()
|
|
59
|
+
.int()
|
|
60
|
+
.min(0)
|
|
61
|
+
.max(100)
|
|
62
|
+
.optional()
|
|
63
|
+
.describe("jpeg/webp quality like JPEG: lower = smaller file, more artifacts. Default 100."),
|
|
64
|
+
n: z
|
|
65
|
+
.number()
|
|
66
|
+
.int()
|
|
67
|
+
.min(1)
|
|
68
|
+
.max(10)
|
|
69
|
+
.optional()
|
|
70
|
+
.describe("Number of variations to generate; each costs output tokens. Files get -1, -2 suffixes. Default 1."),
|
|
71
|
+
output_dir: z.string().optional().describe("Save directory. Default IMAGEN_OUTPUT_DIR env or ./output (relative to server cwd)."),
|
|
72
|
+
file_name: z.string().optional().describe("Base name without extension. Default timestamp + prompt slug."),
|
|
73
|
+
return_image: z
|
|
74
|
+
.boolean()
|
|
75
|
+
.optional()
|
|
76
|
+
.describe("Also return the image inline (base64, ~1.4 MB per 1024x1024 png) so it can be viewed. File is saved either way. Default false."),
|
|
77
|
+
};
|
|
78
|
+
export function resolveModel(alias) {
|
|
79
|
+
const fallback = process.env.IMAGEN_DEFAULT_MODEL;
|
|
80
|
+
return MODELS[alias ?? fallback ?? "flare"] ?? MODELS.flare;
|
|
81
|
+
}
|
|
82
|
+
function roundToStep(value) {
|
|
83
|
+
return Math.max(SIZE_STEP, Math.round(value / SIZE_STEP) * SIZE_STEP);
|
|
84
|
+
}
|
|
85
|
+
function validateSize(size) {
|
|
86
|
+
if (size === "auto")
|
|
87
|
+
return size;
|
|
88
|
+
const [w, h] = size.split("x").map(Number);
|
|
89
|
+
if (w % SIZE_STEP !== 0 || h % SIZE_STEP !== 0) {
|
|
90
|
+
throw new Error(`size ${size}: width and height must be multiples of ${SIZE_STEP}.`);
|
|
91
|
+
}
|
|
92
|
+
if (Math.max(w, h) > MAX_LONG_EDGE) {
|
|
93
|
+
throw new Error(`size ${size}: long edge must be <= ${MAX_LONG_EDGE}.`);
|
|
94
|
+
}
|
|
95
|
+
const ratio = w / h;
|
|
96
|
+
if (ratio > MAX_RATIO || ratio < 1 / MAX_RATIO) {
|
|
97
|
+
throw new Error(`size ${size}: aspect ratio must be between 1:${MAX_RATIO} and ${MAX_RATIO}:1.`);
|
|
98
|
+
}
|
|
99
|
+
return size;
|
|
100
|
+
}
|
|
101
|
+
export function resolveSize(input) {
|
|
102
|
+
if (input.size)
|
|
103
|
+
return validateSize(input.size);
|
|
104
|
+
if (!input.aspect_ratio)
|
|
105
|
+
return undefined;
|
|
106
|
+
const ratio = ASPECT_RATIOS[input.aspect_ratio];
|
|
107
|
+
const long = roundToStep(input.long_edge ?? DEFAULT_LONG_EDGE);
|
|
108
|
+
const short = roundToStep(long / Math.max(ratio, 1 / ratio));
|
|
109
|
+
return ratio >= 1 ? `${long}x${short}` : `${short}x${long}`;
|
|
110
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@falldownthesystem/imagen-mcp",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Minimal MCP server for OpenAI GPT Image 2.5 (flare and sunburst): generate and edit images",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"imagen-mcp": "dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsc",
|
|
14
|
+
"start": "node dist/index.js",
|
|
15
|
+
"dev": "tsc --watch",
|
|
16
|
+
"prepublishOnly": "npm run build"
|
|
17
|
+
},
|
|
18
|
+
"engines": {
|
|
19
|
+
"node": ">=22"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"mcp",
|
|
23
|
+
"model-context-protocol",
|
|
24
|
+
"openai",
|
|
25
|
+
"gpt-image",
|
|
26
|
+
"image-generation"
|
|
27
|
+
],
|
|
28
|
+
"author": "FallDownTheSystem",
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "git+https://github.com/FallDownTheSystem/imagen-mcp.git"
|
|
33
|
+
},
|
|
34
|
+
"homepage": "https://github.com/FallDownTheSystem/imagen-mcp#readme",
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@modelcontextprotocol/server": "^2.0.0",
|
|
40
|
+
"openai": "^7.13.0",
|
|
41
|
+
"zod": "^4.5.4"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@types/node": "^26.5.0",
|
|
45
|
+
"typescript": "^7.0.2"
|
|
46
|
+
}
|
|
47
|
+
}
|