tai-mcp
Enables image generation and editing as MCP tools, abstracting tai-openapi's endpoints and returning images directly without relying on local URLs.
README
tai-mcp
tai-mcp 是一个可独立部署的 MCP 服务,把 tai-openapi 的 OpenAI 兼容图片生成和编辑接口
封装为 MCP 工具。MCP 客户端调用 generate_image 或 edit_image 后会直接收到标准 MCP
ImageContent,不依赖 tai-openapi 返回的本地图片 URL。
功能
generate_image:调用POST /v1/images/generations,返回一张可直接显示的图片及元数据。edit_image:调用POST /v1/images/edits,支持多张输入图、mask、size 和模型专属参数。get_image_model_capabilities:调用GET /v1/image-models/{model}/capabilities,查询 edit 模型实际接受的输入。list_image_models:调用GET /v1/models,查看当前上游启用的模型。- Streamable HTTP:MCP 地址为
http(s)://<host>:8001/mcp。 - 无状态 JSON 响应,适合反向代理和横向扩容。
- MCP 入口支持独立 Bearer Token;上游 API Key 不暴露给 MCP 客户端。
/healthz检查本服务,/readyz同时检查tai-openapi。
与 tai-openapi 的接口契约
本项目使用官方 OpenAI Python SDK 的
AsyncOpenAI 与上游通信。图片生成、图片编辑和模型列表分别直接使用
client.images.generate()、client.images.edit() 和 client.models.list();
get_image_model_capabilities 与 /readyz 所需的 capabilities、health 接口属于
tai-openapi 扩展,通过同一个官方客户端的底层 get() 方法访问。
seed 和 parameters 不是 OpenAI Image API 的标准字段,分别通过 SDK 的
extra_body 合并到 generation JSON 和 edits multipart 请求中。多图编辑采用官方 SDK
生成的 image[] 字段,tai-openapi 会将其规范化为内部的 image 输入。
generate_image 固定向上游发送:
{
"model": "tai-text-to-image",
"prompt": "A quiet library at night",
"size": "1024x1024",
"seed": 42,
"response_format": "b64_json"
}
size 和 seed 未传时不会出现在请求中。固定使用 b64_json 是为了让远程 MCP
客户端直接获得图片,并避免公网部署时误返回仅服务器本机可访问的图片 URL。
一次 MCP 调用只发起一次上游生图请求;超时或网络中断不会自动重试,以免重复生成。
编辑前应先调用 get_image_model_capabilities(model)。返回结果会明确说明:
input.min_images/input.max_images:images所需的图片数量。input.mask:forbidden、optional或required。input.size:是否允许传size。input.prompt_required:是否需要 prompt 字段。parameters_schema:parameters必须满足的 JSON Schema。parameters_example:该模型扩展参数的可用示例。
edit_image.images 和 mask 接受 PNG、JPEG、WebP 的纯 base64 字符串或
data:image/png;base64,... 形式的 Data URL。MCP 服务把它们解码后作为文件上传给上游;
response_format 固定为 b64_json。例如 tai-image-to-image 的典型参数为:
{
"prompt": "Make the bodywork brighter",
"images": ["data:image/png;base64,<base64-data>"],
"model": "tai-image-to-image",
"parameters": {"denoise": 0.55}
}
图片顺序会原样保留,具体每个位置代表原图还是参考图由所选模型的 capabilities 决定。
seed 等 edit 专属字段放在 parameters 中,不能作为顶层参数传入。
本地运行
要求 Python 3.12+ 和 uv。
Copy-Item .env.example .env
# 编辑 .env,至少填写 TAI_OPENAPI_API_KEY
uv sync --extra dev
uv run python -m tai_mcp
默认监听 0.0.0.0:8001:
- MCP:
http://127.0.0.1:8001/mcp - 存活检查:
http://127.0.0.1:8001/healthz - 就绪检查:
http://127.0.0.1:8001/readyz
stdio 模式
本地 Codex 可以通过 stdio 按需启动 MCP,无需监听端口:
uv run python -m tai_mcp --transport stdio
stdio 模式会继续从项目目录的 .env 读取上游地址、API Key 和默认模型;
MCP_HOST、MCP_PORT、MCP_API_KEY 和 CORS 配置在该模式下不生效。
注册到 Codex 时使用项目启动脚本。脚本会先切换到项目目录,确保 .env 能被读取:
codex mcp add tai-images -- `
powershell.exe -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass `
-File C:\Users\xiuzhenpeng\Desktop\vscode-dev\tai-mcp\run-stdio.ps1
不要在 codex mcp add --env 中直接写 API Key;该值会进入 Codex 配置。启动脚本让密钥
继续只保存在项目的 .env 中。
用 MCP Inspector 验证:
npx -y @modelcontextprotocol/inspector
在 Inspector 中把地址设为 http://127.0.0.1:8001/mcp。如果配置了
MCP_API_KEY,添加请求头:
Authorization: Bearer <MCP_API_KEY>
配置
| 环境变量 | 默认值 | 说明 |
|---|---|---|
TAI_OPENAPI_BASE_URL |
http://127.0.0.1:8000/v1 |
上游地址,必须以 /v1 结尾 |
TAI_OPENAPI_API_KEY |
无 | 上游 tai-openapi 原始 Bearer Token,必填 |
TAI_IMAGE_MODEL |
tai-text-to-image |
generate_image 的默认模型 |
TAI_IMAGE_EDIT_MODEL |
tai-image-to-image |
edit_image 的默认模型 |
MCP_API_KEY |
空 | MCP 客户端 Bearer Token;公网部署必须设置 |
MCP_HOST |
0.0.0.0 |
监听地址 |
MCP_PORT |
8001 |
监听端口 |
MCP_REQUEST_TIMEOUT_SECONDS |
330 |
包含生图时间的上游总超时 |
MCP_CONNECT_TIMEOUT_SECONDS |
10 |
上游连接超时 |
MCP_MAX_IMAGE_BYTES |
20971520 |
允许回传的最大解码图片大小 |
MCP_CORS_ORIGINS |
空 | 浏览器客户端的精确 Origin,逗号分隔 |
工具的 model 参数可以覆盖默认模型,但仍受上游 API Key 权限和模型配置约束。
生成 MCP_API_KEY
MCP_API_KEY 是客户端访问 /mcp 时使用的 Bearer Token。公网部署必须使用独立的
强随机值,不要复用 TAI_OPENAPI_API_KEY。
在项目目录中运行以下命令,生成一个基于 48 字节随机数据的 URL 安全密钥:
uv run python -c "import secrets; print(secrets.token_urlsafe(48))"
如果系统已经安装 OpenSSL,也可以生成 32 字节随机值并输出为 64 位十六进制:
openssl rand -hex 32
复制命令输出的完整一行,写入 .env:
MCP_API_KEY=这里替换为刚生成的随机密钥
不要把真实密钥写入 .env.example、提交到 Git 或粘贴到公开日志。修改密钥后需要重启
容器:
docker compose up -d --force-recreate
MCP 客户端访问 https://<你的域名>/mcp 时需要发送:
Authorization: Bearer <MCP_API_KEY>
Docker
先创建配置:
Copy-Item .env.example .env
如果 tai-openapi 跑在 Docker 宿主机的 8000 端口,把 .env 改为:
TAI_OPENAPI_BASE_URL=http://host.docker.internal:8000/v1
然后启动:
docker compose up -d --build
docker compose ps
如果两个服务位于同一个 Compose 网络,建议直接使用服务名,例如
TAI_OPENAPI_BASE_URL=http://tai-openapi:8000/v1。
公网发布检查清单
- 为
MCP_API_KEY生成至少 32 字节的随机值,不要和上游 API Key 共用。 - 只通过 HTTPS 暴露 MCP;可参考
deploy/nginx.conf.example。 - 防火墙只开放 80/443,不直接暴露 8001;上游 8000 更不应直接暴露。
- Nginx 的读写超时要大于
tai-openapi的最大生图时间。 - 将
.env保留在服务器,不提交到 Git。 - 若启用 CORS,只配置实际 MCP Web 客户端的 Origin,不要在公网使用
*。 - 发布后验证
/healthz、/readyz、工具列表以及一次真实生图。
静态 Bearer Token 适合私有客户端或能够配置自定义请求头的 MCP Host。如果需要面向 不受控第三方用户开放,应在反向代理或独立授权服务中实现 MCP OAuth 2.1,而不是共享 同一个静态 Token。
测试与质量检查
uv run --extra dev pytest
uv run --extra dev ruff check .
uv run --extra dev ruff format --check .
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。