@aemeath-projects/gpt-image-mcp 0.0.0-stage → 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 +213 -2
- package/dist/chunk-C7L4O5AX.js +2 -0
- package/dist/chunk-C7L4O5AX.js.map +1 -0
- package/dist/chunk-MUVEW5A6.js +5 -0
- package/dist/chunk-MUVEW5A6.js.map +1 -0
- package/dist/chunk-UOUKCFO3.js +2 -0
- package/dist/chunk-UOUKCFO3.js.map +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +21 -0
- package/dist/cli.js.map +1 -0
- package/dist/http.d.ts +25 -0
- package/dist/http.js +2 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/node-HNQD3U4G.js +3 -0
- package/dist/node-HNQD3U4G.js.map +1 -0
- package/package.json +113 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Aemeath
|
|
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
CHANGED
|
@@ -1,3 +1,214 @@
|
|
|
1
|
-
#
|
|
1
|
+
# gpt-image-mcp
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
GPT Image 图像生成与编辑的 MCP Server,为 LLM 客户端提供标准化的工具调用能力。
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
## 特性
|
|
10
|
+
|
|
11
|
+
- **三种运行方式**:stdio、Streamable HTTP、Cloudflare Workers,共用同一套工具代码。
|
|
12
|
+
- **双输出**:每次调用同时返回 Markdown 文本与满足 `outputSchema` 的 `structuredContent`。
|
|
13
|
+
- **统一结果约定**:成功走 `content` + `structuredContent`,失败走 `isError` 通道。
|
|
14
|
+
- **可扩展骨架**:`src/gpt-image/` 预留领域目录,新增工具只需实现 `registerXxxTools`。
|
|
15
|
+
- **零配置启动**:无需 API Key,`npx` 即可运行。
|
|
16
|
+
|
|
17
|
+
## 目录
|
|
18
|
+
|
|
19
|
+
- [快速开始](#快速开始)
|
|
20
|
+
- [工具](#工具)
|
|
21
|
+
- [运行方式](#运行方式)
|
|
22
|
+
- [配置](#配置)
|
|
23
|
+
- [数据来源](#数据来源)
|
|
24
|
+
- [开发](#开发)
|
|
25
|
+
|
|
26
|
+
## 快速开始
|
|
27
|
+
|
|
28
|
+
直接运行(stdio,默认传输方式):
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npx -y -p @aemeath-projects/gpt-image-mcp gpt-image-mcp
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
在 Claude Code 中注册:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
claude mcp add gpt-image -- npx -y -p @aemeath-projects/gpt-image-mcp gpt-image-mcp
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Claude Desktop 配置示例:
|
|
41
|
+
|
|
42
|
+
```json
|
|
43
|
+
{
|
|
44
|
+
"mcpServers": {
|
|
45
|
+
"gpt-image": {
|
|
46
|
+
"command": "npx",
|
|
47
|
+
"args": ["-y", "-p", "@aemeath-projects/gpt-image-mcp", "gpt-image-mcp"]
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
> Windows 下若客户端找不到 `npx`,可将 `command` 改为 `cmd`,并在 `args` 开头加入 `/c`。
|
|
54
|
+
|
|
55
|
+
## 工具
|
|
56
|
+
|
|
57
|
+
所有工具都声明 `annotations`。成功时返回 Markdown 文本与 `structuredContent`;
|
|
58
|
+
失败时返回 `isError: true` 与单行错误信息。
|
|
59
|
+
|
|
60
|
+
| 工具 | 用途 | 关键参数 | 注解 |
|
|
61
|
+
| ------ | -------------------------------- | -------- | ------------------------------------------------------ |
|
|
62
|
+
| `echo` | 回显输入文本及其字符数,验证链路 | `text` | `readOnlyHint`、`idempotentHint`、非破坏性、非开放世界 |
|
|
63
|
+
|
|
64
|
+
当前仓库处于脚手架阶段,仅提供 `echo` 示例工具。gpt-image 领域工具将在后续版本加入。
|
|
65
|
+
|
|
66
|
+
## 运行方式
|
|
67
|
+
|
|
68
|
+
### stdio
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
npx -y -p @aemeath-projects/gpt-image-mcp gpt-image-mcp
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
从源码运行:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
pnpm build
|
|
78
|
+
pnpm start # 等价于 node dist/cli.js
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Streamable HTTP
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
pnpm start:http # 等价于 node dist/cli.js --transport http
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
默认监听 `http://127.0.0.1:3000/mcp`。健康检查固定为 `GET /health`,不受 `--path` 影响。
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
# 健康检查
|
|
91
|
+
curl -s http://127.0.0.1:3000/health
|
|
92
|
+
|
|
93
|
+
# 列出工具
|
|
94
|
+
curl -s -X POST http://127.0.0.1:3000/mcp \
|
|
95
|
+
-H 'Content-Type: application/json' \
|
|
96
|
+
-H 'Accept: application/json, text/event-stream' \
|
|
97
|
+
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
|
|
98
|
+
|
|
99
|
+
# 调用 echo
|
|
100
|
+
curl -s -X POST http://127.0.0.1:3000/mcp \
|
|
101
|
+
-H 'Content-Type: application/json' \
|
|
102
|
+
-H 'Accept: application/json, text/event-stream' \
|
|
103
|
+
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"echo","arguments":{"text":"hello"}}}'
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
响应为 SSE,`result.structuredContent` 是结构化数据,`result.content` 是对应的 Markdown:
|
|
107
|
+
|
|
108
|
+
```text
|
|
109
|
+
event: message
|
|
110
|
+
data: {"jsonrpc":"2.0","id":2,"result":{"content":[{"type":"text","text":"# 回声\n\nhello\n\n字符数:5"}],"structuredContent":{"text":"hello","length":5}}}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Node 侧默认绑定 `127.0.0.1`,并启用 localhost 级别的 Host/Origin 校验。监听 `0.0.0.0`
|
|
114
|
+
或经反向代理暴露时,必须显式配置 `MCP_ALLOWED_HOSTS` 与 `MCP_ALLOWED_ORIGINS`。
|
|
115
|
+
|
|
116
|
+
### Cloudflare Workers
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
pnpm worker:dev # http://127.0.0.1:8787/mcp
|
|
120
|
+
pnpm worker:check # 仅打包校验,不部署
|
|
121
|
+
pnpm worker:deploy # 手动部署,仅用于调试
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
日常发布使用 Cloudflare Workers Builds:在 Dashboard 连接 Git 仓库,生产分支设为
|
|
125
|
+
`master`,Root directory 为 `/`,Build command 为 `pnpm run build`,Deploy command 为
|
|
126
|
+
`npx wrangler deploy`,构建环境变量只需 `NODE_VERSION=26`。运行时变量
|
|
127
|
+
`ALLOWED_HOSTS`、`ALLOWED_ORIGINS` 在 Worker 的 Variables 中配置。Worker 端 MCP 端点
|
|
128
|
+
固定为 `/mcp`,健康检查为 `/health`。
|
|
129
|
+
|
|
130
|
+
## 配置
|
|
131
|
+
|
|
132
|
+
CLI 参数优先级高于环境变量。`MCP_ALLOWED_ORIGINS` 与 `MCP_ALLOWED_HOSTS` 未显式配置时,
|
|
133
|
+
绑定 localhost 会自动使用 SDK 的 localhost 白名单。
|
|
134
|
+
|
|
135
|
+
| CLI 参数 | 环境变量 | 默认值 | 说明 |
|
|
136
|
+
| --------------------------- | --------------------- | ----------- | ------------------------------ |
|
|
137
|
+
| `--transport <stdio\|http>` | `MCP_TRANSPORT` | `stdio` | 传输方式 |
|
|
138
|
+
| `--host <host>` | `MCP_HOST` | `127.0.0.1` | HTTP 监听地址 |
|
|
139
|
+
| `--port <port>` | `MCP_PORT` | `3000` | HTTP 监听端口 |
|
|
140
|
+
| `--path <path>` | `MCP_PATH` | `/mcp` | MCP 端点路径 |
|
|
141
|
+
| — | `MCP_ALLOWED_HOSTS` | 未设置 | 允许的 Host 主机名,逗号分隔 |
|
|
142
|
+
| — | `MCP_ALLOWED_ORIGINS` | 未设置 | 允许的 Origin 主机名,逗号分隔 |
|
|
143
|
+
| `--help` / `-h` | — | — | 显示帮助 |
|
|
144
|
+
| `--version` / `-v` | — | — | 显示版本 |
|
|
145
|
+
|
|
146
|
+
Worker 运行时使用 `ALLOWED_HOSTS`、`ALLOWED_ORIGINS`(逗号分隔),空值表示不启用对应校验。
|
|
147
|
+
|
|
148
|
+
## 数据来源
|
|
149
|
+
|
|
150
|
+
- 当前版本不访问外部数据源,`echo` 仅回显输入内容。
|
|
151
|
+
- 接入 gpt-image 接口后,将在此补充 API 地址、鉴权方式与数据处理说明。
|
|
152
|
+
|
|
153
|
+
## 开发
|
|
154
|
+
|
|
155
|
+
环境要求:Node.js `>= 24.22.1`,pnpm `12.15.0`(由 `packageManager` 固定)。
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
pnpm install
|
|
159
|
+
pnpm build
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
构建产物输出到 `dist/`:
|
|
163
|
+
|
|
164
|
+
- `dist/index.js`:公共库入口
|
|
165
|
+
- `dist/http.js`:web-standard HTTP handler
|
|
166
|
+
- `dist/cli.js`:命令行入口(含 shebang)
|
|
167
|
+
- `dist/chunk-*.js`:代码分割产生的共享 chunk
|
|
168
|
+
|
|
169
|
+
常用脚本:
|
|
170
|
+
|
|
171
|
+
| 脚本 | 说明 |
|
|
172
|
+
| ------------------- | ------------------------------ |
|
|
173
|
+
| `pnpm dev` | tsup watch 构建 |
|
|
174
|
+
| `pnpm lint` | ESLint 检查 |
|
|
175
|
+
| `pnpm lint:fix` | ESLint 自动修复 |
|
|
176
|
+
| `pnpm format` | Prettier 检查 |
|
|
177
|
+
| `pnpm format:fix` | Prettier 格式化 |
|
|
178
|
+
| `pnpm type-check` | TypeScript 类型检查 |
|
|
179
|
+
| `pnpm inspect` | MCP Inspector 调试(需先构建) |
|
|
180
|
+
| `pnpm worker:dev` | 本地 Worker 开发 |
|
|
181
|
+
| `pnpm worker:check` | Worker 打包校验 |
|
|
182
|
+
| `pnpm bump` | 版本号、CHANGELOG、tag 与提交 |
|
|
183
|
+
| `pnpm commit` | Commitizen 交互式提交 |
|
|
184
|
+
|
|
185
|
+
完整脚本(含 `bump:patch` / `bump:minor` / `bump:major`、`changelog`、`start:http` 等)
|
|
186
|
+
见 `package.json`。
|
|
187
|
+
|
|
188
|
+
目录结构:
|
|
189
|
+
|
|
190
|
+
```text
|
|
191
|
+
src/
|
|
192
|
+
├── cli.ts # bin 入口,stdio/http 分流
|
|
193
|
+
├── config.ts # CLI 与环境变量解析
|
|
194
|
+
├── env.ts # 列表环境变量解析(Worker 可用)
|
|
195
|
+
├── errors.ts # ToolError 业务错误基类
|
|
196
|
+
├── http.ts # 共享 web-standard fetch handler
|
|
197
|
+
├── index.ts # 公共库 barrel
|
|
198
|
+
├── node.ts # node:http + toNodeHandler
|
|
199
|
+
├── server.ts # McpServer 工厂与工具注册
|
|
200
|
+
├── version.ts # 服务名与版本号
|
|
201
|
+
├── worker.ts # Cloudflare Worker 入口
|
|
202
|
+
├── gpt-image/ # 领域目录(待实现)
|
|
203
|
+
│ └── client.ts # 接口错误类与后续请求封装
|
|
204
|
+
└── tools/ # 工具域
|
|
205
|
+
├── echo.ts # 示例工具
|
|
206
|
+
└── register.ts # 统一的成功/失败结果封装
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
新增工具时,按 `src/tools/echo.ts` 的模式实现 `registerXxxTools(server)`,在
|
|
210
|
+
`src/server.ts` 中注册,并在 `src/gpt-image/` 中补充数据访问代码。
|
|
211
|
+
|
|
212
|
+
`http.ts`、`server.ts`、`worker.ts`、`env.ts`、`version.ts`、`tools/**`、`gpt-image/**`
|
|
213
|
+
保持 Node-free,由 ESLint `no-restricted-imports` 约束;Node 适配器 `node.ts` 仅在 HTTP
|
|
214
|
+
模式下动态加载。
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/env.ts"],"names":["parseList","value","items","item"],"mappings":"AAMO,SAASA,CAAAA,CAAUC,CAAAA,CAAiD,CACzE,GAAIA,CAAAA,GAAU,MAAA,CACZ,OAGF,IAAMC,CAAAA,CAAQD,CAAAA,CACX,KAAA,CAAM,GAAG,EACT,GAAA,CAAKE,CAAAA,EAASA,CAAAA,CAAK,IAAA,EAAM,CAAA,CACzB,MAAA,CAAQA,CAAAA,EAASA,CAAAA,CAAK,MAAA,CAAS,CAAC,CAAA,CAEnC,OAAOD,CAAAA,CAAM,MAAA,CAAS,CAAA,CAAIA,EAAQ,MACpC","file":"chunk-C7L4O5AX.js","sourcesContent":["/**\n * 解析逗号分隔的列表配置。\n *\n * 空字符串、纯空白与空项会被忽略;没有任何有效项时返回 `undefined`,\n * 以便调用方区分“未配置”与“配置了空列表”(后者会导致校验拒绝所有请求)。\n */\nexport function parseList(value: string | undefined): string[] | undefined {\n if (value === undefined) {\n return undefined\n }\n\n const items = value\n .split(',')\n .map((item) => item.trim())\n .filter((item) => item.length > 0)\n\n return items.length > 0 ? items : undefined\n}\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import {McpServer}from'@modelcontextprotocol/server';import {z}from'zod';var i={version:"0.1.0"};var s="gpt-image-mcp",c=i.version;var r=class extends Error{constructor(e){super(e),this.name="ToolError";}};function p(t,e){return {content:[{type:"text",text:e}],structuredContent:t}}function d(t){return {isError:true,content:[{type:"text",text:`\u274C ${t instanceof Error?t.message:String(t)}`}]}}async function m(t){try{return await t()}catch(e){return e instanceof r||console.error("[gpt-image] \u5DE5\u5177\u6267\u884C\u5931\u8D25\uFF1A",e),d(e)}}var u=z.object({text:z.string().min(1).max(1e4).describe("\u8981\u56DE\u663E\u7684\u6587\u672C\uFF081-10000 \u4E2A\u5B57\u7B26\uFF09")}),h=z.object({text:z.string(),length:z.number().int().nonnegative()});function a(t){t.registerTool("echo",{title:"\u56DE\u58F0\u6D4B\u8BD5",description:"\u539F\u6837\u8FD4\u56DE\u8F93\u5165\u6587\u672C\u53CA\u5176\u5B57\u7B26\u6570\uFF0C\u7528\u4E8E\u9A8C\u8BC1 MCP \u8FDE\u63A5\u4E0E\u5DE5\u5177\u8C03\u7528\u94FE\u8DEF\u3002",inputSchema:u,outputSchema:h,annotations:{readOnlyHint:true,destructiveHint:false,idempotentHint:true,openWorldHint:false}},async e=>m(async()=>{let n=Array.from(e.text).length,l=["# \u56DE\u58F0","",e.text,"",`\u5B57\u7B26\u6570\uFF1A${String(n)}`].join(`
|
|
2
|
+
`);return p({text:e.text,length:n},l)}));}var f=`\u672C\u670D\u52A1\u5668\u63D0\u4F9B GPT Image \u76F8\u5173\u7684 MCP \u5DE5\u5177\u3002
|
|
3
|
+
- \u5F53\u524D\u7248\u672C\u4EC5\u63D0\u4F9B echo \u793A\u4F8B\u5DE5\u5177\uFF0C\u7528\u4E8E\u9A8C\u8BC1\u5BA2\u6237\u7AEF\u8FDE\u63A5\u4E0E\u5DE5\u5177\u8C03\u7528\u94FE\u8DEF\u3002
|
|
4
|
+
- \u8C03\u7528\u524D\u8BF7\u4F7F\u7528 tools/list \u67E5\u770B\u5F53\u524D\u53EF\u7528\u5DE5\u5177\uFF1Bgpt-image \u9886\u57DF\u5DE5\u5177\u5C06\u5728\u540E\u7EED\u7248\u672C\u52A0\u5165\u3002`;function P(){let t=new McpServer({name:s,version:c},{instructions:f});return a(t),t}export{s as a,c as b,P as c};//# sourceMappingURL=chunk-MUVEW5A6.js.map
|
|
5
|
+
//# sourceMappingURL=chunk-MUVEW5A6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../package.json","../src/version.ts","../src/errors.ts","../src/tools/register.ts","../src/tools/echo.ts","../src/server.ts"],"names":["package_default","SERVER_NAME","SERVER_VERSION","ToolError","message","ok","data","markdown","fail","error","run","handler","echoInputSchema","z","echoOutputSchema","registerEchoTools","server","args","length","INSTRUCTIONS","createServer","McpServer"],"mappings":"yEAAA,IAAAA,CAAAA,CAAA,CAEE,QAAW,OAmHb,ECnHO,IAAMC,CAAAA,CAAc,gBACdC,CAAAA,CAAiBF,CAAAA,CAAI,QCF3B,IAAMG,CAAAA,CAAN,cAAwB,KAAM,CACnC,WAAA,CAAYC,CAAAA,CAAiB,CAC3B,KAAA,CAAMA,CAAO,EACb,IAAA,CAAK,IAAA,CAAO,YACd,CACF,CAAA,CCOO,SAASC,CAAAA,CAAGC,CAAAA,CAA+BC,EAA8B,CAC9E,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAMA,CAAS,CAAC,CAAA,CAC1C,kBAAmBD,CACrB,CACF,CAGO,SAASE,CAAAA,CAAKC,EAA4B,CAG/C,OAAO,CACL,OAAA,CAAS,IAAA,CACT,QAAS,CAAC,CAAE,KAAM,MAAA,CAAQ,IAAA,CAAM,UAJlBA,CAAAA,YAAiB,KAAA,CAAQA,CAAAA,CAAM,OAAA,CAAU,MAAA,CAAOA,CAAK,CAIvB,CAAA,CAAG,CAAC,CAClD,CACF,CAGA,eAAsBC,CAAAA,CAAIC,CAAAA,CAAyD,CACjF,GAAI,CACF,OAAO,MAAMA,CAAAA,EACf,CAAA,MAASF,CAAAA,CAAO,CACd,OAAMA,CAAAA,YAAiBN,CAAAA,EACrB,OAAA,CAAQ,KAAA,CAAM,wDAAA,CAAuBM,CAAK,CAAA,CAErCD,CAAAA,CAAKC,CAAK,CACnB,CACF,CCnCA,IAAMG,CAAAA,CAAkBC,EAAE,MAAA,CAAO,CAC/B,KAAMA,CAAAA,CAAE,MAAA,GAAS,GAAA,CAAI,CAAC,EAAE,GAAA,CAAI,GAAM,CAAA,CAAE,QAAA,CAAS,4EAAqB,CACpE,CAAC,CAAA,CAEKC,CAAAA,CAAmBD,EAAE,MAAA,CAAO,CAChC,KAAMA,CAAAA,CAAE,MAAA,GACR,MAAA,CAAQA,CAAAA,CAAE,QAAO,CAAE,GAAA,GAAM,WAAA,EAC3B,CAAC,CAAA,CAEM,SAASE,CAAAA,CAAkBC,CAAAA,CAAyB,CACzDA,CAAAA,CAAO,aACL,MAAA,CACA,CACE,MAAO,0BAAA,CACP,WAAA,CAAa,gLACb,WAAA,CAAaJ,CAAAA,CACb,aAAcE,CAAAA,CACd,WAAA,CAAa,CACX,YAAA,CAAc,IAAA,CACd,gBAAiB,KAAA,CACjB,cAAA,CAAgB,KAChB,aAAA,CAAe,KACjB,CACF,CAAA,CACA,MAAOG,CAAAA,EACLP,EAAI,SAAY,CACd,IAAMQ,CAAAA,CAAS,KAAA,CAAM,KAAKD,CAAAA,CAAK,IAAI,CAAA,CAAE,MAAA,CAC/BV,CAAAA,CAAW,CAAC,iBAAQ,EAAA,CAAIU,CAAAA,CAAK,KAAM,EAAA,CAAI,CAAA,wBAAA,EAAO,OAAOC,CAAM,CAAC,CAAA,CAAE,CAAA,CAAE,IAAA,CAAK;AAAA,CAAI,EAE/E,OAAOb,CAAAA,CAAG,CAAE,IAAA,CAAMY,EAAK,IAAA,CAAM,MAAA,CAAAC,CAAO,CAAA,CAAGX,CAAQ,CACjD,CAAC,CACL,EACF,CChCA,IAAMY,CAAAA,CAAe,CAAA;AAAA;AAAA,gMAAA,CAAA,CAUd,SAASC,GAA0B,CACxC,IAAMJ,EAAS,IAAIK,SAAAA,CACjB,CACE,IAAA,CAAMpB,CAAAA,CACN,OAAA,CAASC,CACX,CAAA,CACA,CAAE,aAAciB,CAAa,CAC/B,EAEA,OAAAJ,CAAAA,CAAkBC,CAAM,CAAA,CAEjBA,CACT","file":"chunk-MUVEW5A6.js","sourcesContent":["{\n \"name\": \"@aemeath-projects/gpt-image-mcp\",\n \"version\": \"0.1.0\",\n \"description\": \"GPT Image 图像生成与编辑 MCP 服务器\",\n \"type\": \"module\",\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"bin\": {\n \"gpt-image-mcp\": \"./dist/cli.js\"\n },\n \"files\": [\n \"dist\"\n ],\n \"engines\": {\n \"node\": \">=24.22.1\"\n },\n \"packageManager\": \"pnpm@12.15.0\",\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"start\": \"node dist/cli.js\",\n \"start:http\": \"node dist/cli.js --transport http\",\n \"worker:dev\": \"wrangler dev\",\n \"worker:deploy\": \"wrangler deploy\",\n \"worker:check\": \"wrangler deploy --dry-run --outdir .wrangler-dry-run\",\n \"lint\": \"eslint \\\"src/**/*.ts\\\" \\\"*.ts\\\"\",\n \"lint:fix\": \"eslint \\\"src/**/*.ts\\\" \\\"*.ts\\\" --fix\",\n \"format\": \"prettier --check .\",\n \"format:fix\": \"prettier --write .\",\n \"type-check\": \"tsc --noEmit\",\n \"inspect\": \"npx @modelcontextprotocol/inspector node dist/cli.js\",\n \"bump\": \"commit-and-tag-version\",\n \"bump:patch\": \"commit-and-tag-version --release-as patch\",\n \"bump:minor\": \"commit-and-tag-version --release-as minor\",\n \"bump:major\": \"commit-and-tag-version --release-as major\",\n \"changelog\": \"commit-and-tag-version --skip.bump --skip.commit --skip.tag\",\n \"commit\": \"cz\",\n \"prepare\": \"husky\"\n },\n \"keywords\": [\n \"mcp\",\n \"model-context-protocol\",\n \"gpt-image\",\n \"image-generation\"\n ],\n \"author\": \"Aemeath Projects\",\n \"license\": \"MIT\",\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/aemeath-projects/gpt-image-mcp.git\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/aemeath-projects/gpt-image-mcp/issues\"\n },\n \"homepage\": \"https://github.com/aemeath-projects/gpt-image-mcp#readme\",\n \"config\": {\n \"commitizen\": {\n \"path\": \"cz-conventional-changelog\"\n }\n },\n \"lint-staged\": {\n \"src/**/*.ts\": [\n \"eslint --fix\",\n \"prettier --write\"\n ],\n \"*.ts\": [\n \"eslint --fix\",\n \"prettier --write\"\n ],\n \"*.{json,jsonc}\": [\n \"prettier --write\"\n ],\n \".github/**/*.yml\": [\n \"prettier --write\"\n ],\n \"*.md\": [\n \"prettier --write\"\n ]\n },\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\"\n },\n \"./http\": {\n \"types\": \"./dist/http.d.ts\",\n \"import\": \"./dist/http.js\"\n },\n \"./package.json\": \"./package.json\"\n },\n \"dependencies\": {\n \"@modelcontextprotocol/node\": \"^2.1.2\",\n \"@modelcontextprotocol/server\": \"^2.4.0\",\n \"zod\": \"^4.6.7\"\n },\n \"devDependencies\": {\n \"@commitlint/cli\": \"^21.2.4\",\n \"@commitlint/config-conventional\": \"^21.2.4\",\n \"@eslint/js\": \"^10.0.1\",\n \"@types/node\": \"^26.6.5\",\n \"commit-and-tag-version\": \"^13.3.0\",\n \"commitizen\": \"^4.3.2\",\n \"cz-conventional-changelog\": \"^3.3.0\",\n \"eslint\": \"^10.13.0\",\n \"eslint-config-prettier\": \"^10.1.8\",\n \"eslint-plugin-import-x\": \"^4.17.1\",\n \"husky\": \"^9.1.7\",\n \"lint-staged\": \"^17.6.0\",\n \"prettier\": \"^3.9.10\",\n \"tsup\": \"^9.0.0\",\n \"typescript\": \"^6.0.3\",\n \"typescript-eslint\": \"^8.72.0\",\n \"wrangler\": \"^4.152.0\"\n }\n}\n","import pkg from '../package.json' with { type: 'json' }\n\nexport const SERVER_NAME = 'gpt-image-mcp'\nexport const SERVER_VERSION = pkg.version\n","/** 可安全呈现给 MCP 客户端的业务错误;工具层不为其记录服务端日志。 */\nexport class ToolError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'ToolError'\n }\n}\n","import { ToolError } from '../errors.js'\n\ntype ToolResult =\n | {\n content: { type: 'text'; text: string }[]\n structuredContent: Record<string, unknown>\n }\n | {\n isError: true\n content: { type: 'text'; text: string }[]\n }\n\n/** 成功结果:Markdown 文本 + 满足 outputSchema 的结构化数据。 */\nexport function ok(data: Record<string, unknown>, markdown: string): ToolResult {\n return {\n content: [{ type: 'text', text: markdown }],\n structuredContent: data,\n }\n}\n\n/** 失败结果:使用 MCP 的 `isError` 通道,错误信息保持单行可读。 */\nexport function fail(error: unknown): ToolResult {\n const message = error instanceof Error ? error.message : String(error)\n\n return {\n isError: true,\n content: [{ type: 'text', text: `❌ ${message}` }],\n }\n}\n\n/** 统一捕获工具执行期的异常,避免每个工具重复 try/catch。 */\nexport async function run(handler: () => Promise<ToolResult>): Promise<ToolResult> {\n try {\n return await handler()\n } catch (error) {\n if (!(error instanceof ToolError)) {\n console.error('[gpt-image] 工具执行失败:', error)\n }\n return fail(error)\n }\n}\n","import type { McpServer } from '@modelcontextprotocol/server'\nimport { z } from 'zod'\n\nimport { ok, run } from './register.js'\n\nconst echoInputSchema = z.object({\n text: z.string().min(1).max(10_000).describe('要回显的文本(1-10000 个字符)'),\n})\n\nconst echoOutputSchema = z.object({\n text: z.string(),\n length: z.number().int().nonnegative(),\n})\n\nexport function registerEchoTools(server: McpServer): void {\n server.registerTool(\n 'echo',\n {\n title: '回声测试',\n description: '原样返回输入文本及其字符数,用于验证 MCP 连接与工具调用链路。',\n inputSchema: echoInputSchema,\n outputSchema: echoOutputSchema,\n annotations: {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n async (args) =>\n run(async () => {\n const length = Array.from(args.text).length\n const markdown = ['# 回声', '', args.text, '', `字符数:${String(length)}`].join('\\n')\n\n return ok({ text: args.text, length }, markdown)\n }),\n )\n}\n","import { McpServer } from '@modelcontextprotocol/server'\n\nimport { registerEchoTools } from './tools/echo.js'\nimport { SERVER_NAME, SERVER_VERSION } from './version.js'\n\nconst INSTRUCTIONS = `本服务器提供 GPT Image 相关的 MCP 工具。\n- 当前版本仅提供 echo 示例工具,用于验证客户端连接与工具调用链路。\n- 调用前请使用 tools/list 查看当前可用工具;gpt-image 领域工具将在后续版本加入。`\n\n/**\n * 创建一个 MCP Server 实例。\n *\n * SDK 的 `McpServerFactory` 会把 `McpRequestContext` 作为第一个参数传入,\n * 因此这里刻意保持零参数,避免上下文被误认为配置项。\n */\nexport function createServer(): McpServer {\n const server = new McpServer(\n {\n name: SERVER_NAME,\n version: SERVER_VERSION,\n },\n { instructions: INSTRUCTIONS },\n )\n\n registerEchoTools(server)\n\n return server\n}\n"]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import {c}from'./chunk-MUVEW5A6.js';import {createMcpHandler,hostHeaderValidationResponse,originValidationResponse}from'@modelcontextprotocol/server';var h="/mcp",n=createMcpHandler(c);function m(i={}){let c=i.path??h,{allowedHosts:o,allowedOrigins:r}=i;return {async fetch(e,l){let s=new URL(e.url);if(e.method==="GET"&&s.pathname==="/health")return Response.json({status:"ok"});if(s.pathname!==c)return new Response("Not Found",{status:404});if(o!==void 0&&o.length>0){let t=hostHeaderValidationResponse(e,o);if(t!==void 0)return t}if(r!==void 0&&r.length>0){let t=originValidationResponse(e,r);if(t!==void 0)return t}return n.fetch(e,l)},close:()=>n.close(),notify:n.notify,bus:n.bus}}export{m as a};//# sourceMappingURL=chunk-UOUKCFO3.js.map
|
|
2
|
+
//# sourceMappingURL=chunk-UOUKCFO3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/http.ts"],"names":["DEFAULT_PATH","mcpHandler","createMcpHandler","createServer","createFetchHandler","options","path","allowedHosts","allowedOrigins","request","requestOptions","url","rejection","hostHeaderValidationResponse","originValidationResponse"],"mappings":"sJAwBA,IAAMA,CAAAA,CAAe,MAAA,CAEfC,CAAAA,CAAaC,gBAAAA,CAAiBC,CAAY,CAAA,CAQzC,SAASC,CAAAA,CAAmBC,CAAAA,CAA+B,EAAC,CAAiB,CAClF,IAAMC,CAAAA,CAAOD,CAAAA,CAAQ,IAAA,EAAQL,CAAAA,CACvB,CAAE,YAAA,CAAAO,CAAAA,CAAc,eAAAC,CAAe,CAAA,CAAIH,CAAAA,CAEzC,OAAO,CACL,MAAM,KAAA,CAAMI,CAAAA,CAASC,CAAAA,CAAgB,CACnC,IAAMC,CAAAA,CAAM,IAAI,GAAA,CAAIF,CAAAA,CAAQ,GAAG,EAE/B,GAAIA,CAAAA,CAAQ,MAAA,GAAW,KAAA,EAASE,CAAAA,CAAI,QAAA,GAAa,SAAA,CAC/C,OAAO,QAAA,CAAS,IAAA,CAAK,CAAE,MAAA,CAAQ,IAAK,CAAC,CAAA,CAGvC,GAAIA,EAAI,QAAA,GAAaL,CAAAA,CACnB,OAAO,IAAI,QAAA,CAAS,WAAA,CAAa,CAAE,MAAA,CAAQ,GAAI,CAAC,CAAA,CAGlD,GAAIC,CAAAA,GAAiB,MAAA,EAAaA,CAAAA,CAAa,MAAA,CAAS,CAAA,CAAG,CACzD,IAAMK,CAAAA,CAAYC,4BAAAA,CAA6BJ,CAAAA,CAASF,CAAY,CAAA,CACpE,GAAIK,CAAAA,GAAc,MAAA,CAChB,OAAOA,CAEX,CAEA,GAAIJ,CAAAA,GAAmB,QAAaA,CAAAA,CAAe,MAAA,CAAS,CAAA,CAAG,CAC7D,IAAMI,CAAAA,CAAYE,wBAAAA,CAAyBL,CAAAA,CAASD,CAAc,CAAA,CAClE,GAAII,CAAAA,GAAc,MAAA,CAChB,OAAOA,CAEX,CAEA,OAAOX,CAAAA,CAAW,KAAA,CAAMQ,CAAAA,CAASC,CAAc,CACjD,CAAA,CACA,KAAA,CAAO,IAAMT,CAAAA,CAAW,KAAA,EAAM,CAC9B,MAAA,CAAQA,CAAAA,CAAW,MAAA,CACnB,GAAA,CAAKA,CAAAA,CAAW,GAClB,CACF","file":"chunk-UOUKCFO3.js","sourcesContent":["import {\n createMcpHandler,\n hostHeaderValidationResponse,\n originValidationResponse,\n type McpHttpHandler,\n} from '@modelcontextprotocol/server'\n\nimport { createServer } from './server.js'\n\nexport interface FetchHandlerOptions {\n /** MCP 端点路径,必须以 `/` 开头。 */\n path?: string\n /** 允许的 Host 主机名(不含端口);未配置时跳过校验。 */\n allowedHosts?: string[]\n /** 允许的 Origin 主机名;未配置时跳过校验。 */\n allowedOrigins?: string[]\n}\n\n/**\n * 与 SDK 的 `McpHttpHandler` 对齐,保留 `notify` / `bus`,以便后续启用\n * `subscriptions/listen` 服务端推送能力。\n */\nexport type FetchHandler = Pick<McpHttpHandler, 'fetch' | 'close' | 'notify' | 'bus'>\n\nconst DEFAULT_PATH = '/mcp'\n\nconst mcpHandler = createMcpHandler(createServer)\n\n/**\n * 创建 web-standard 的 MCP 请求处理器,可同时用于 Node 与 Cloudflare Workers。\n *\n * Host/Origin 校验在此统一完成,Node 与 Worker 两侧不重复实现;SDK 的\n * `createMcpHandler` 本身刻意不做校验,因此这里是唯一的校验层。\n */\nexport function createFetchHandler(options: FetchHandlerOptions = {}): FetchHandler {\n const path = options.path ?? DEFAULT_PATH\n const { allowedHosts, allowedOrigins } = options\n\n return {\n async fetch(request, requestOptions) {\n const url = new URL(request.url)\n\n if (request.method === 'GET' && url.pathname === '/health') {\n return Response.json({ status: 'ok' })\n }\n\n if (url.pathname !== path) {\n return new Response('Not Found', { status: 404 })\n }\n\n if (allowedHosts !== undefined && allowedHosts.length > 0) {\n const rejection = hostHeaderValidationResponse(request, allowedHosts)\n if (rejection !== undefined) {\n return rejection\n }\n }\n\n if (allowedOrigins !== undefined && allowedOrigins.length > 0) {\n const rejection = originValidationResponse(request, allowedOrigins)\n if (rejection !== undefined) {\n return rejection\n }\n }\n\n return mcpHandler.fetch(request, requestOptions)\n },\n close: () => mcpHandler.close(),\n notify: mcpHandler.notify,\n bus: mcpHandler.bus,\n }\n}\n"]}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {a as a$1}from'./chunk-C7L4O5AX.js';import {a,b,c as c$1}from'./chunk-MUVEW5A6.js';import {serveStdio}from'@modelcontextprotocol/server/stdio';import {parseArgs}from'util';var T="127.0.0.1",d=3e3,l="/mcp";function c(t,o){let{values:r}=parseArgs({args:t,options:{transport:{type:"string"},host:{type:"string"},port:{type:"string"},path:{type:"string"},help:{type:"boolean",short:"h"},version:{type:"boolean",short:"v"}},allowPositionals:false}),s=r.transport??o.MCP_TRANSPORT??"stdio";if(s!=="stdio"&&s!=="http")throw new Error(`\u65E0\u6548\u7684 transport "${s}"\uFF0C\u5E94\u4E3A "stdio" \u6216 "http"`);let n=r.path??o.MCP_PATH??l;if(!n.startsWith("/"))throw new Error(`\u65E0\u6548\u7684 path "${n}"\uFF0C\u5FC5\u987B\u4EE5 "/" \u5F00\u5934`);return {transport:s,host:r.host??o.MCP_HOST??T,port:P(r.port??o.MCP_PORT),path:n,allowedHosts:a$1(o.MCP_ALLOWED_HOSTS),allowedOrigins:a$1(o.MCP_ALLOWED_ORIGINS),help:r.help===true,version:r.version===true}}function P(t){if(t===void 0)return d;let o=Number(t);if(!Number.isInteger(o)||o<1||o>65535)throw new Error(`\u65E0\u6548\u7684 port "${t}"\uFF0C\u5E94\u4E3A 1-65535 \u4E4B\u95F4\u7684\u6574\u6570`);return o}var f=`\u7528\u6CD5\uFF1A${a} [\u9009\u9879]
|
|
3
|
+
|
|
4
|
+
\u9009\u9879\uFF1A
|
|
5
|
+
--transport <stdio|http> \u4F20\u8F93\u65B9\u5F0F\uFF08\u9ED8\u8BA4\uFF1Astdio\uFF09
|
|
6
|
+
--host <host> HTTP \u76D1\u542C\u5730\u5740\uFF08\u9ED8\u8BA4\uFF1A127.0.0.1\uFF09
|
|
7
|
+
--port <port> HTTP \u76D1\u542C\u7AEF\u53E3\uFF08\u9ED8\u8BA4\uFF1A3000\uFF09
|
|
8
|
+
--path <path> MCP \u7AEF\u70B9\u8DEF\u5F84\uFF08\u9ED8\u8BA4\uFF1A/mcp\uFF09
|
|
9
|
+
-h, --help \u663E\u793A\u5E2E\u52A9
|
|
10
|
+
-v, --version \u663E\u793A\u7248\u672C
|
|
11
|
+
|
|
12
|
+
\u73AF\u5883\u53D8\u91CF\uFF1A
|
|
13
|
+
MCP_TRANSPORT stdio | http
|
|
14
|
+
MCP_HOST HTTP \u76D1\u542C\u5730\u5740
|
|
15
|
+
MCP_PORT HTTP \u76D1\u542C\u7AEF\u53E3
|
|
16
|
+
MCP_PATH MCP \u7AEF\u70B9\u8DEF\u5F84
|
|
17
|
+
MCP_ALLOWED_HOSTS \u5141\u8BB8\u7684 Host \u4E3B\u673A\u540D\uFF0C\u9017\u53F7\u5206\u9694
|
|
18
|
+
MCP_ALLOWED_ORIGINS \u5141\u8BB8\u7684 Origin \u4E3B\u673A\u540D\uFF0C\u9017\u53F7\u5206\u9694`;async function m(){let t=c(process.argv.slice(2),process.env);if(t.help){process.stdout.write(`${f}
|
|
19
|
+
`);return}if(t.version){process.stdout.write(`${b}
|
|
20
|
+
`);return}if(t.transport==="stdio"){let r=serveStdio(c$1);console.error(`${a} ${b} \u5DF2\u542F\u52A8\uFF08stdio\uFF09`);let s=()=>{r.close();};process.once("SIGINT",s),process.once("SIGTERM",s);return}let{startHttpServer:o}=await import('./node-HNQD3U4G.js');o(t);}m().catch(t=>{console.error(t instanceof Error?t.message:String(t)),process.exitCode=1;});//# sourceMappingURL=cli.js.map
|
|
21
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/config.ts","../src/cli.ts"],"names":["DEFAULT_HOST","DEFAULT_PORT","DEFAULT_PATH","parseCliOptions","argv","env","values","parseArgs","transport","path","parsePort","parseList","value","port","HELP_TEXT","SERVER_NAME","main","options","SERVER_VERSION","handle","serveStdio","createServer","shutdown","startHttpServer","error"],"mappings":"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","file":"cli.js","sourcesContent":["import { parseArgs } from 'node:util'\n\nimport { parseList } from './env.js'\n\nexport type Transport = 'stdio' | 'http'\n\nexport interface CliOptions {\n transport: Transport\n host: string\n port: number\n path: string\n allowedHosts?: string[]\n allowedOrigins?: string[]\n help: boolean\n version: boolean\n}\n\nconst DEFAULT_HOST = '127.0.0.1'\nconst DEFAULT_PORT = 3000\nconst DEFAULT_PATH = '/mcp'\n\n/**\n * 解析 CLI 参数与环境变量。优先级:CLI > 环境变量 > 默认值。\n *\n * 未知参数会由 `parseArgs` 直接抛出异常。\n */\nexport function parseCliOptions(\n argv: string[],\n env: Record<string, string | undefined>,\n): CliOptions {\n const { values } = parseArgs({\n args: argv,\n options: {\n transport: { type: 'string' },\n host: { type: 'string' },\n port: { type: 'string' },\n path: { type: 'string' },\n help: { type: 'boolean', short: 'h' },\n version: { type: 'boolean', short: 'v' },\n },\n allowPositionals: false,\n })\n\n const transport = values.transport ?? env.MCP_TRANSPORT ?? 'stdio'\n if (transport !== 'stdio' && transport !== 'http') {\n throw new Error(`无效的 transport \"${transport}\",应为 \"stdio\" 或 \"http\"`)\n }\n\n const path = values.path ?? env.MCP_PATH ?? DEFAULT_PATH\n if (!path.startsWith('/')) {\n throw new Error(`无效的 path \"${path}\",必须以 \"/\" 开头`)\n }\n\n return {\n transport,\n host: values.host ?? env.MCP_HOST ?? DEFAULT_HOST,\n port: parsePort(values.port ?? env.MCP_PORT),\n path,\n allowedHosts: parseList(env.MCP_ALLOWED_HOSTS),\n allowedOrigins: parseList(env.MCP_ALLOWED_ORIGINS),\n help: values.help === true,\n version: values.version === true,\n }\n}\n\nfunction parsePort(value: string | undefined): number {\n if (value === undefined) {\n return DEFAULT_PORT\n }\n\n const port = Number(value)\n if (!Number.isInteger(port) || port < 1 || port > 65535) {\n throw new Error(`无效的 port \"${value}\",应为 1-65535 之间的整数`)\n }\n\n return port\n}\n","#!/usr/bin/env node\nimport { serveStdio } from '@modelcontextprotocol/server/stdio'\n\nimport { parseCliOptions } from './config.js'\nimport { createServer } from './server.js'\nimport { SERVER_NAME, SERVER_VERSION } from './version.js'\n\nconst HELP_TEXT = `用法:${SERVER_NAME} [选项]\n\n选项:\n --transport <stdio|http> 传输方式(默认:stdio)\n --host <host> HTTP 监听地址(默认:127.0.0.1)\n --port <port> HTTP 监听端口(默认:3000)\n --path <path> MCP 端点路径(默认:/mcp)\n -h, --help 显示帮助\n -v, --version 显示版本\n\n环境变量:\n MCP_TRANSPORT stdio | http\n MCP_HOST HTTP 监听地址\n MCP_PORT HTTP 监听端口\n MCP_PATH MCP 端点路径\n MCP_ALLOWED_HOSTS 允许的 Host 主机名,逗号分隔\n MCP_ALLOWED_ORIGINS 允许的 Origin 主机名,逗号分隔`\n\nasync function main(): Promise<void> {\n const options = parseCliOptions(process.argv.slice(2), process.env)\n\n if (options.help) {\n process.stdout.write(`${HELP_TEXT}\\n`)\n return\n }\n\n if (options.version) {\n process.stdout.write(`${SERVER_VERSION}\\n`)\n return\n }\n\n if (options.transport === 'stdio') {\n const handle = serveStdio(createServer)\n console.error(`${SERVER_NAME} ${SERVER_VERSION} 已启动(stdio)`)\n\n const shutdown = (): void => {\n void handle.close()\n }\n process.once('SIGINT', shutdown)\n process.once('SIGTERM', shutdown)\n return\n }\n\n const { startHttpServer } = await import('./node.js')\n startHttpServer(options)\n}\n\nvoid main().catch((error: unknown) => {\n console.error(error instanceof Error ? error.message : String(error))\n process.exitCode = 1\n})\n"]}
|
package/dist/http.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { McpHttpHandler } from '@modelcontextprotocol/server';
|
|
2
|
+
|
|
3
|
+
interface FetchHandlerOptions {
|
|
4
|
+
/** MCP 端点路径,必须以 `/` 开头。 */
|
|
5
|
+
path?: string;
|
|
6
|
+
/** 允许的 Host 主机名(不含端口);未配置时跳过校验。 */
|
|
7
|
+
allowedHosts?: string[];
|
|
8
|
+
/** 允许的 Origin 主机名;未配置时跳过校验。 */
|
|
9
|
+
allowedOrigins?: string[];
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* 与 SDK 的 `McpHttpHandler` 对齐,保留 `notify` / `bus`,以便后续启用
|
|
13
|
+
* `subscriptions/listen` 服务端推送能力。
|
|
14
|
+
*/
|
|
15
|
+
type FetchHandler = Pick<McpHttpHandler, 'fetch' | 'close' | 'notify' | 'bus'>;
|
|
16
|
+
/**
|
|
17
|
+
* 创建 web-standard 的 MCP 请求处理器,可同时用于 Node 与 Cloudflare Workers。
|
|
18
|
+
*
|
|
19
|
+
* Host/Origin 校验在此统一完成,Node 与 Worker 两侧不重复实现;SDK 的
|
|
20
|
+
* `createMcpHandler` 本身刻意不做校验,因此这里是唯一的校验层。
|
|
21
|
+
*/
|
|
22
|
+
declare function createFetchHandler(options?: FetchHandlerOptions): FetchHandler;
|
|
23
|
+
|
|
24
|
+
export { createFetchHandler };
|
|
25
|
+
export type { FetchHandler, FetchHandlerOptions };
|
package/dist/http.js
ADDED
package/dist/http.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"http.js"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export { FetchHandler, FetchHandlerOptions, createFetchHandler } from './http.js';
|
|
2
|
+
import { McpServer } from '@modelcontextprotocol/server';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 解析逗号分隔的列表配置。
|
|
6
|
+
*
|
|
7
|
+
* 空字符串、纯空白与空项会被忽略;没有任何有效项时返回 `undefined`,
|
|
8
|
+
* 以便调用方区分“未配置”与“配置了空列表”(后者会导致校验拒绝所有请求)。
|
|
9
|
+
*/
|
|
10
|
+
declare function parseList(value: string | undefined): string[] | undefined;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* 创建一个 MCP Server 实例。
|
|
14
|
+
*
|
|
15
|
+
* SDK 的 `McpServerFactory` 会把 `McpRequestContext` 作为第一个参数传入,
|
|
16
|
+
* 因此这里刻意保持零参数,避免上下文被误认为配置项。
|
|
17
|
+
*/
|
|
18
|
+
declare function createServer(): McpServer;
|
|
19
|
+
|
|
20
|
+
declare const SERVER_NAME = "gpt-image-mcp";
|
|
21
|
+
declare const SERVER_VERSION: string;
|
|
22
|
+
|
|
23
|
+
export { SERVER_NAME, SERVER_VERSION, createServer, parseList };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import {a}from'./chunk-UOUKCFO3.js';import'./chunk-MUVEW5A6.js';import {createServer}from'http';import {toNodeHandler}from'@modelcontextprotocol/node';import {localhostAllowedHostnames,localhostAllowedOrigins}from'@modelcontextprotocol/server';var f=new Set([...localhostAllowedHostnames(),"::1"]);function m(e){let t=f.has(e.host);e.allowedHosts===void 0&&!t&&console.warn(`\u672A\u914D\u7F6E MCP_ALLOWED_HOSTS\uFF0C\u4E14\u7ED1\u5B9A\u5730\u5740 ${e.host} \u4E0D\u662F localhost\uFF1BHost \u6821\u9A8C\u5DF2\u7981\u7528\uFF0C\u8BF7\u81EA\u884C\u786E\u4FDD\u53CD\u5411\u4EE3\u7406\u5B89\u5168\u3002`),e.allowedOrigins===void 0&&!t&&console.warn(`\u672A\u914D\u7F6E MCP_ALLOWED_ORIGINS\uFF0C\u4E14\u7ED1\u5B9A\u5730\u5740 ${e.host} \u4E0D\u662F localhost\uFF1BOrigin \u6821\u9A8C\u5DF2\u7981\u7528\u3002`);let s=a({path:e.path,allowedHosts:e.allowedHosts??(t?localhostAllowedHostnames():void 0),allowedOrigins:e.allowedOrigins??(t?localhostAllowedOrigins():void 0)}),a$1=toNodeHandler(s,{onerror:o=>{console.error("MCP \u8BF7\u6C42\u5904\u7406\u5931\u8D25\uFF1A",o);}}),r=createServer((o,d)=>{a$1(o,d);});r.on("error",o=>{console.error("HTTP \u670D\u52A1\u9519\u8BEF\uFF1A",o),process.exitCode=1;}),r.listen(e.port,e.host,()=>{let o=`http://${e.host}:${String(e.port)}${e.path}`;console.error(`MCP HTTP \u670D\u52A1\u5DF2\u542F\u52A8\uFF1A${o}`);});let l=()=>{console.error("\u6B63\u5728\u5173\u95ED HTTP \u670D\u52A1..."),r.close(),r.closeAllConnections(),s.close().catch(o=>{console.error("\u5173\u95ED MCP handler \u5931\u8D25\uFF1A",o);});};return process.once("SIGINT",l),process.once("SIGTERM",l),r}
|
|
2
|
+
export{m as startHttpServer};//# sourceMappingURL=node-HNQD3U4G.js.map
|
|
3
|
+
//# sourceMappingURL=node-HNQD3U4G.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/node.ts"],"names":["LOCALHOST_HOSTNAMES","localhostAllowedHostnames","startHttpServer","options","isLocalhost","handler","createFetchHandler","localhostAllowedOrigins","nodeHandler","toNodeHandler","error","server","createHttpServer","req","res","address","shutdown"],"mappings":"oPASA,IAAMA,CAAAA,CAAsB,IAAI,IAAI,CAAC,GAAGC,2BAA0B,CAAG,KAAK,CAAC,CAAA,CAWpE,SAASC,EAAgBC,CAAAA,CAA0D,CACxF,IAAMC,CAAAA,CAAcJ,CAAAA,CAAoB,IAAIG,CAAAA,CAAQ,IAAI,EAEpDA,CAAAA,CAAQ,YAAA,GAAiB,QAAa,CAACC,CAAAA,EACzC,QAAQ,IAAA,CACN,CAAA,yEAAA,EAA+BD,CAAAA,CAAQ,IAAI,CAAA,8IAAA,CAC7C,CAAA,CAGEA,EAAQ,cAAA,GAAmB,MAAA,EAAa,CAACC,CAAAA,EAC3C,OAAA,CAAQ,KACN,CAAA,2EAAA,EAAiCD,CAAAA,CAAQ,IAAI,CAAA,wEAAA,CAC/C,CAAA,CAGF,IAAME,CAAAA,CAAUC,CAAAA,CAAmB,CACjC,IAAA,CAAMH,CAAAA,CAAQ,KACd,YAAA,CAAcA,CAAAA,CAAQ,eAAiBC,CAAAA,CAAcH,yBAAAA,GAA8B,MAAA,CAAA,CACnF,cAAA,CAAgBE,EAAQ,cAAA,GAAmBC,CAAAA,CAAcG,yBAAwB,CAAI,MAAA,CACvF,CAAC,CAAA,CAEKC,GAAAA,CAAcC,cAAcJ,CAAAA,CAAS,CACzC,QAAUK,CAAAA,EAAU,CAClB,QAAQ,KAAA,CAAM,gDAAA,CAAeA,CAAK,EACpC,CACF,CAAC,EAEKC,CAAAA,CAASC,YAAAA,CAAiB,CAACC,CAAAA,CAAKC,CAAAA,GAAQ,CACvCN,GAAAA,CAAYK,CAAAA,CAAKC,CAAG,EAC3B,CAAC,EAEDH,CAAAA,CAAO,EAAA,CAAG,QAAUD,CAAAA,EAAU,CAC5B,QAAQ,KAAA,CAAM,qCAAA,CAAcA,CAAK,CAAA,CACjC,OAAA,CAAQ,SAAW,EACrB,CAAC,EAEDC,CAAAA,CAAO,MAAA,CAAOR,EAAQ,IAAA,CAAMA,CAAAA,CAAQ,KAAM,IAAM,CAC9C,IAAMY,CAAAA,CAAU,CAAA,OAAA,EAAUZ,EAAQ,IAAI,CAAA,CAAA,EAAI,OAAOA,CAAAA,CAAQ,IAAI,CAAC,CAAA,EAAGA,CAAAA,CAAQ,IAAI,GAC7E,OAAA,CAAQ,KAAA,CAAM,gDAAkBY,CAAO,CAAA,CAAE,EAC3C,CAAC,CAAA,CAED,IAAMC,CAAAA,CAAW,IAAY,CAC3B,OAAA,CAAQ,KAAA,CAAM,+CAAiB,CAAA,CAC/BL,CAAAA,CAAO,OAAM,CACbA,CAAAA,CAAO,qBAAoB,CACtBN,CAAAA,CAAQ,OAAM,CAAE,KAAA,CAAOK,GAAmB,CAC7C,OAAA,CAAQ,MAAM,6CAAA,CAAsBA,CAAK,EAC3C,CAAC,EACH,EAEA,OAAA,OAAA,CAAQ,IAAA,CAAK,SAAUM,CAAQ,CAAA,CAC/B,QAAQ,IAAA,CAAK,SAAA,CAAWA,CAAQ,CAAA,CAEzBL,CACT","file":"node-HNQD3U4G.js","sourcesContent":["import { createServer as createHttpServer } from 'node:http'\n\nimport { toNodeHandler } from '@modelcontextprotocol/node'\nimport { localhostAllowedHostnames, localhostAllowedOrigins } from '@modelcontextprotocol/server'\n\nimport type { CliOptions } from './config.js'\nimport { createFetchHandler } from './http.js'\n\n/** SDK 的 localhost 名单用于匹配 Host 头;`::1` 是 `server.listen` 的裸 IPv6 绑定形式。 */\nconst LOCALHOST_HOSTNAMES = new Set([...localhostAllowedHostnames(), '::1'])\n\n/**\n * 启动 Node HTTP 服务。\n *\n * 仅在 `--transport http` 时被 `cli.ts` 动态加载,避免 stdio 模式引入\n * Node HTTP 适配器。\n *\n * Host/Origin 校验统一由 `createFetchHandler` 完成:显式配置的 allowlist 原样生效,\n * 绑定 localhost 且未配置时降级为 SDK 的 localhost 默认 allowlist。\n */\nexport function startHttpServer(options: CliOptions): ReturnType<typeof createHttpServer> {\n const isLocalhost = LOCALHOST_HOSTNAMES.has(options.host)\n\n if (options.allowedHosts === undefined && !isLocalhost) {\n console.warn(\n `未配置 MCP_ALLOWED_HOSTS,且绑定地址 ${options.host} 不是 localhost;Host 校验已禁用,请自行确保反向代理安全。`,\n )\n }\n\n if (options.allowedOrigins === undefined && !isLocalhost) {\n console.warn(\n `未配置 MCP_ALLOWED_ORIGINS,且绑定地址 ${options.host} 不是 localhost;Origin 校验已禁用。`,\n )\n }\n\n const handler = createFetchHandler({\n path: options.path,\n allowedHosts: options.allowedHosts ?? (isLocalhost ? localhostAllowedHostnames() : undefined),\n allowedOrigins: options.allowedOrigins ?? (isLocalhost ? localhostAllowedOrigins() : undefined),\n })\n\n const nodeHandler = toNodeHandler(handler, {\n onerror: (error) => {\n console.error('MCP 请求处理失败:', error)\n },\n })\n\n const server = createHttpServer((req, res) => {\n void nodeHandler(req, res)\n })\n\n server.on('error', (error) => {\n console.error('HTTP 服务错误:', error)\n process.exitCode = 1\n })\n\n server.listen(options.port, options.host, () => {\n const address = `http://${options.host}:${String(options.port)}${options.path}`\n console.error(`MCP HTTP 服务已启动:${address}`)\n })\n\n const shutdown = (): void => {\n console.error('正在关闭 HTTP 服务...')\n server.close()\n server.closeAllConnections()\n void handler.close().catch((error: unknown) => {\n console.error('关闭 MCP handler 失败:', error)\n })\n }\n\n process.once('SIGINT', shutdown)\n process.once('SIGTERM', shutdown)\n\n return server\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,116 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aemeath-projects/gpt-image-mcp",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "GPT Image 图像生成与编辑 MCP 服务器",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"gpt-image-mcp": "./dist/cli.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist"
|
|
13
|
+
],
|
|
14
|
+
"engines": {
|
|
15
|
+
"node": ">=24.22.1"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"mcp",
|
|
19
|
+
"model-context-protocol",
|
|
20
|
+
"gpt-image",
|
|
21
|
+
"image-generation"
|
|
22
|
+
],
|
|
23
|
+
"author": "Aemeath Projects",
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public"
|
|
27
|
+
},
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "https://github.com/aemeath-projects/gpt-image-mcp.git"
|
|
31
|
+
},
|
|
32
|
+
"bugs": {
|
|
33
|
+
"url": "https://github.com/aemeath-projects/gpt-image-mcp/issues"
|
|
34
|
+
},
|
|
35
|
+
"homepage": "https://github.com/aemeath-projects/gpt-image-mcp#readme",
|
|
36
|
+
"config": {
|
|
37
|
+
"commitizen": {
|
|
38
|
+
"path": "cz-conventional-changelog"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"lint-staged": {
|
|
42
|
+
"src/**/*.ts": [
|
|
43
|
+
"eslint --fix",
|
|
44
|
+
"prettier --write"
|
|
45
|
+
],
|
|
46
|
+
"*.ts": [
|
|
47
|
+
"eslint --fix",
|
|
48
|
+
"prettier --write"
|
|
49
|
+
],
|
|
50
|
+
"*.{json,jsonc}": [
|
|
51
|
+
"prettier --write"
|
|
52
|
+
],
|
|
53
|
+
".github/**/*.yml": [
|
|
54
|
+
"prettier --write"
|
|
55
|
+
],
|
|
56
|
+
"*.md": [
|
|
57
|
+
"prettier --write"
|
|
58
|
+
]
|
|
59
|
+
},
|
|
60
|
+
"exports": {
|
|
61
|
+
".": {
|
|
62
|
+
"types": "./dist/index.d.ts",
|
|
63
|
+
"import": "./dist/index.js"
|
|
64
|
+
},
|
|
65
|
+
"./http": {
|
|
66
|
+
"types": "./dist/http.d.ts",
|
|
67
|
+
"import": "./dist/http.js"
|
|
68
|
+
},
|
|
69
|
+
"./package.json": "./package.json"
|
|
70
|
+
},
|
|
71
|
+
"dependencies": {
|
|
72
|
+
"@modelcontextprotocol/node": "^2.1.2",
|
|
73
|
+
"@modelcontextprotocol/server": "^2.4.0",
|
|
74
|
+
"zod": "^4.6.7"
|
|
75
|
+
},
|
|
76
|
+
"devDependencies": {
|
|
77
|
+
"@commitlint/cli": "^21.2.4",
|
|
78
|
+
"@commitlint/config-conventional": "^21.2.4",
|
|
79
|
+
"@eslint/js": "^10.0.1",
|
|
80
|
+
"@types/node": "^26.6.5",
|
|
81
|
+
"commit-and-tag-version": "^13.3.0",
|
|
82
|
+
"commitizen": "^4.3.2",
|
|
83
|
+
"cz-conventional-changelog": "^3.3.0",
|
|
84
|
+
"eslint": "^10.13.0",
|
|
85
|
+
"eslint-config-prettier": "^10.1.8",
|
|
86
|
+
"eslint-plugin-import-x": "^4.17.1",
|
|
87
|
+
"husky": "^9.1.7",
|
|
88
|
+
"lint-staged": "^17.6.0",
|
|
89
|
+
"prettier": "^3.9.10",
|
|
90
|
+
"tsup": "^9.0.0",
|
|
91
|
+
"typescript": "^6.0.3",
|
|
92
|
+
"typescript-eslint": "^8.72.0",
|
|
93
|
+
"wrangler": "^4.152.0"
|
|
94
|
+
},
|
|
95
|
+
"scripts": {
|
|
96
|
+
"build": "tsup",
|
|
97
|
+
"dev": "tsup --watch",
|
|
98
|
+
"start": "node dist/cli.js",
|
|
99
|
+
"start:http": "node dist/cli.js --transport http",
|
|
100
|
+
"worker:dev": "wrangler dev",
|
|
101
|
+
"worker:deploy": "wrangler deploy",
|
|
102
|
+
"worker:check": "wrangler deploy --dry-run --outdir .wrangler-dry-run",
|
|
103
|
+
"lint": "eslint \"src/**/*.ts\" \"*.ts\"",
|
|
104
|
+
"lint:fix": "eslint \"src/**/*.ts\" \"*.ts\" --fix",
|
|
105
|
+
"format": "prettier --check .",
|
|
106
|
+
"format:fix": "prettier --write .",
|
|
107
|
+
"type-check": "tsc --noEmit",
|
|
108
|
+
"inspect": "npx @modelcontextprotocol/inspector node dist/cli.js",
|
|
109
|
+
"bump": "commit-and-tag-version",
|
|
110
|
+
"bump:patch": "commit-and-tag-version --release-as patch",
|
|
111
|
+
"bump:minor": "commit-and-tag-version --release-as minor",
|
|
112
|
+
"bump:major": "commit-and-tag-version --release-as major",
|
|
113
|
+
"changelog": "commit-and-tag-version --skip.bump --skip.commit --skip.tag",
|
|
114
|
+
"commit": "cz"
|
|
115
|
+
}
|
|
6
116
|
}
|