image-mcp
by RuntimeAll
README.md
# image-mcp
> **lk888 (gpt-image-2) 图像生成 MCP server** · 文生图 + 图生图 · 双 transport (stdio + HTTP) · MySQL 使用量统计 · OSS 持久化
> 用于 Claude Code / 任何 MCP 客户端做 UI 形态对照、参考稿、概念草图。
## 1. 它是什么
- **协议**:Model Context Protocol (MCP),工具被任何 MCP 客户端(Claude Code / Claude Desktop / Cursor 等)调用
- **能力**:一个工具 `generate_image` — 调 lk888 `/v1/media/generate` 异步任务,出图后下载 → 上传 OSS → 落 MySQL → 把图直接 base64 返给客户端
- **存储**:OSS 永久持久化(预签名 URL,1h),本地是 fallback;MySQL 一张 `mcp_usage` 表统计每次调用的 size/quality/cost/duration
- **transport**:
- `stdio` 本地直连(Claude Code 拉起本地进程)
- `http` 远程(ECS + Nginx + Bearer 鉴权,任何 MCP 客户端都能连)
## 2. 一次性准备(只跑一次)
### 2.1 RDS 建库
```bash
mysql -h rm-bp1126b6e6ibav2uxzo.mysql.rds.aliyuncs.com -P 3306 -u error_boot -p \
-e "CREATE DATABASE IF NOT EXISTS \`image2-mcp\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
```
> 库名带连字符,SQL 里必须反引号转义。表 `mcp_usage` server 启动会自动 `CREATE TABLE IF NOT EXISTS`,不需要手建。
### 2.2 白名单
把"本机公网 IP"和"ECS 公网 IP `47.98.87.96`"加进 RDS 白名单(阿里云控制台 → 数据安全性 → 白名单)。
### 2.3 凭据 — 与 errorbook 共享 `.env`,只追加独有 key
**复用思路**:`RDS_*` / `ALIYUN_AK/SK` 这些"轮换困难"的凭据已经在 errorbook 的 `.env.prod` / `.env.local` 里了,**image-mcp 不重新定义**,通过 docker compose 多 `--env-file` 叠加引用。
| 文件 | 位置 | 内容 |
|---|---|---|
| 共享基础 .env | 本地 `D:\workplace\superpower-dev\.env.local` / `.env.prod`,ECS `/opt/errorbook/.env.prod` | RDS_HOST / RDS_USERNAME / RDS_PASSWORD / ALIYUN_ACCESS_KEY_ID/SECRET 等(errorbook 已有,**不动**) |
| image-mcp 增量 | 本地 `D:\workplace\superpower-dev\image-mcp\.env.local` / `.env.prod`,ECS `/opt/image-mcp/.env.prod` | LK888_KEY / MCP_AUTH_TOKEN / RDS_DB=image2-mcp / IMAGE_MCP_ACR_IMAGE / NGINX_PORT 等(参考 `.env.example`) |
**键名对齐说明**:
- ✅ `RDS_USERNAME`(不是 `RDS_USER`)— 对齐 errorbook .env
- ✅ `RDS_DB` 独立 key,值 = `image2-mcp` — 错开 errorbook 的 `RDS_DATABASE`=`ai_errorbook_v2`
- ✅ `IMAGE_MCP_ACR_IMAGE` 独立 key — 错开 errorbook 的 `ACR_IMAGE`
- ✅ `NGINX_PORT` 默认 `8080`,避开 errorbook nginx 占的 80
## 3. 工具签名
```python
generate_image(
prompt: str, # 必填,中英文皆可
images: list[str] | None = None, # 参考图 URL(最多 10);空=文生图,非空=图生图
size: "1024x1024" | "1024x1536" | "1536x1024" |
"2048x2048" | "2048x1152" | "3840x2160" | "2160x3840" | "auto" = "1024x1536",
quality: "low" | "medium" | "high" | "auto" = "medium",
background: "opaque" | "transparent" = "opaque",
n: int = 1, # 1~4
) -> [ImageContent (base64 PNG), TextContent (元信息 + OSS URL)]
```
每次调用会落一条 `mcp_usage` 记录:`ts / task_id / mode (t2i|i2i) / size / quality / duration_s / cost_usd / status / result_url / oss_key / oss_url / local_path`。
## 4. 本地跑
### 4.1 stdio 模式(Claude Code 直连)
`claude_desktop_config.json`(Windows 在 `%APPDATA%\Claude\`):
```json
{
"mcpServers": {
"image-mcp": {
"command": "D:/workplace/superpower-dev/image-mcp/.venv/Scripts/python.exe",
"args": ["-m", "image_mcp.server"],
"env": {
"PYTHONPATH": "D:/workplace/superpower-dev/image-mcp/src",
"LK888_KEY": "sk-...",
"RDS_HOST": "rm-bp1126b6e6ibav2uxzo.mysql.rds.aliyuncs.com",
"RDS_USERNAME": "error_boot",
"RDS_PASSWORD": "...",
"RDS_DB": "image2-mcp",
"ALIYUN_ACCESS_KEY_ID": "...",
"ALIYUN_ACCESS_KEY_SECRET": "..."
}
}
}
}
```
> stdio 模式 env 直接写 `claude_desktop_config.json` 是 Claude Code 唯一的注入方式 — 这份配置在用户 AppData 下,**不入项目 git**。如果嫌重复,也可以把 env 留空,改用 dotenv 自动加载(让 server 启动时读 `D:\workplace\superpower-dev\.env.local`)。
### 4.2 HTTP 模式(本机调试)
```powershell
# PowerShell,凭据走 session env
$env:LK888_KEY = "..."; $env:RDS_HOST = "..."; ...; $env:MCP_AUTH_TOKEN = "<32+ chars>"
$env:PYTHONPATH = "src"
.venv\Scripts\python.exe -m image_mcp.server --transport http --port 8765
```
Claude Code 连远程:
```bash
claude mcp add image-mcp --transport http http://127.0.0.1:8765/mcp \
--header "Authorization: Bearer <token>"
```
## 5. 云上部署(参考 superpower/部署空间/部署运维手册.md 风格)
> 复用 errorbook 后端的 ACR + ECS 链路,新仓库 `errorboot/image-mcp`。
### 5.1 本地 build + push 镜像
```powershell
cd D:\workplace\superpower-dev\image-mcp
docker build -t crpi-4e3qyeiaxmbfzar4.cn-hangzhou.personal.cr.aliyuncs.com/errorboot/image-mcp:latest .
docker push crpi-4e3qyeiaxmbfzar4.cn-hangzhou.personal.cr.aliyuncs.com/errorboot/image-mcp:latest
```
首次 push 需要 `docker login crpi-4e3qyeiaxmbfzar4.cn-hangzhou.personal.cr.aliyuncs.com`(凭据在 ACR 控制台 "访问凭证")。
### 5.2 ECS 一次性准备
```bash
ssh root@47.98.87.96
mkdir -p /opt/image-mcp/deploy
cd /opt/image-mcp
# scp 上去:docker-compose.prod.yml + deploy/nginx.conf
# .env.prod 自己建(只放 image-mcp 独有 key,参考 .env.example;不入 git)
docker login crpi-4e3qyeiaxmbfzar4-vpc.cn-hangzhou.personal.cr.aliyuncs.com
```
### 5.3 ECS 拉镜像 + 起服务 — **共享 errorbook .env.prod**
```bash
cd /opt/image-mcp
docker compose -f docker-compose.prod.yml \
--env-file /opt/errorbook/.env.prod \ # 复用 errorbook 的 RDS_* / ALIYUN_*
--env-file ./.env.prod \ # image-mcp 独有:LK888_KEY / MCP_AUTH_TOKEN / RDS_DB / IMAGE_MCP_ACR_IMAGE
pull
docker compose -f docker-compose.prod.yml \
--env-file /opt/errorbook/.env.prod \
--env-file ./.env.prod \
up -d
docker compose -f docker-compose.prod.yml \
--env-file /opt/errorbook/.env.prod \
--env-file ./.env.prod \
ps
```
> 🔴 **铁则升级版**:这里和 errorbook 部署手册 §1 的"单 --env-file"铁则**有意分歧**:image-mcp 走**双 --env-file 叠加**(后面的覆盖前面的)。共享凭据基础 + 服务独立配置,避免凭据重复定义。
> **建议沉淀一个 alias** 在 ECS `~/.bashrc`:
> ```bash
> alias img-mcp='docker compose -f /opt/image-mcp/docker-compose.prod.yml --env-file /opt/errorbook/.env.prod --env-file /opt/image-mcp/.env.prod'
> # 之后:img-mcp pull / img-mcp up -d / img-mcp ps / img-mcp logs -f image-mcp
> ```
### 5.4 smoke 验证
```bash
# Bearer 校验 — 无 token 应 401
curl -s -o /dev/null -w "%{http_code}\n" http://localhost/mcp
# 带正确 token + MCP initialize 应 200 + SSE 流
curl -s -i -X POST http://localhost/mcp \
-H "Authorization: Bearer $TOKEN" \
-H "Accept: application/json, text/event-stream" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"smoke","version":"0"}}}' \
| head -20
```
### 5.5 改代码后重发
```powershell
docker build -t crpi-4e3qyeiaxmbfzar4.cn-hangzhou.personal.cr.aliyuncs.com/errorboot/image-mcp:latest .
docker push crpi-4e3qyeiaxmbfzar4.cn-hangzhou.personal.cr.aliyuncs.com/errorboot/image-mcp:latest
```
```bash
ssh root@47.98.87.96 'img-mcp pull && img-mcp up -d' # 用 §5.3 沉淀的 alias
```
## 6. 凭据安全
- 全部走 env(`.env.local` / `.env.prod`),源码、git 历史、Docker 镜像里都见不到凭据
- `.gitignore` 屏蔽 `.env*`
- push 前 grep:`grep -rn "lizhao@\|aliyun.*KEY\|sk-" --include="*.py" --include="*.yml" --include="*.toml" .`
- `MCP_AUTH_TOKEN` 用 32+ 位强随机串(`openssl rand -hex 32`)
- 密码在对话/截图前**永远先脱敏**
## 7. 已知坑
- 库名 `image2-mcp` 带连字符,所有 SQL 引用必须反引号 `` `image2-mcp` ``
- POST 端点是 `/mcp`(不带尾 slash);带 `/mcp/` 会 307 重定向
- `dev:h5` / playwright 等浏览器自动化**不适用**(MCP 协议层,不是 web 页面)
- OSS 是私有 bucket,返回的是预签名 URL,**1h 后失效**,需要查时重签
## 8. 待办
- ICP 备案 + 域名 + HTTPS → 解锁微信小程序审核场景调用
- 多 caller 区分(目前 `caller` 字段恒为 NULL,后期按 token / IP 落)
- 接监控告警(失败率、cost 周报)