Skip to main content
Glama

面向生产的远程 MCP 服务,用于 xAI 图像生成、图像编辑、视频生成和文本转语音。它通过 MCP TypeScript SDK 的 Streamable HTTP 处理器,在 api/mcp.ts 暴露一个 Vercel Function。

每个计费结果都会从 xAI 复制到一个不可变的 Vercel Blob 对象中。客户端收到的是持久化的公共 Blob URL,而不是临时的 xAI URL。测试仅使用模拟的 HTTP 和内存存储;它们不会发起任何外部或计费调用。

该服务被设计为 overnight 团队的渲染边界。只有该团队的 Render bot 应接收此 MCP 连接。

工具

Tool

Input

Structured output

generate_image

{prompt, model?, n?} (n: 1–10)

{urls,cost_usd,model,ms}

edit_image

{prompt,image_url}

{url,cost_usd,ms}

generate_video

{prompt,image_url?,duration_sec,model?} (duration_sec: 1–15)

{url,cost_usd,duration_sec,ms}

speak

{text,voice_id?,language?} (15,000 Unicode code points max)

{url,cost_usd,chars,ms}

图像模型:grok-imagine-image-2.0、grok-imagine-image 和 grok-imagine-image-quality。视频模型:grok-imagine-video-1.5 和 grok-imagine-video。

默认值分别是图像模型 grok-imagine-image-2.0、视频模型 grok-imagine-video-1.5、音色 eve 和语言 auto。工具 schema 仅允许上面契约中列出的文档化模型 ID,因此新引入的更高价格模型无法绕过预留表。当存在 API 上报的用量时,将替换估算值。

Related MCP server: MiniMax MCP JS

架构

flowchart LR
    B["Grok Bot<br/>Render only"] -->|x-mcp-secret| M["MCP endpoint<br/>auth + spend reserve"]
    M --> X["xAI API<br/>image / video / TTS"]
    X --> P[("Public Blob store<br/>persistent media")]
    X --> L[("Private Blob store<br/>append-only ledger")]
    P --> B
  • api/mcp.ts — Vercel fetch 入口点。

  • src/server.ts — 身份验证、Origin 策略、MCP 注册、运行时装配。

  • src/xai.ts — xAI REST 客户端、响应校验、视频轮询和有界重试。

  • src/tools/ — 每个 MCP 工具一个模块。

  • src/media.ts — 有界媒体下载和不可变持久化。

  • src/store.ts — Vercel Blob 和内存适配器;生产环境接入一个公共媒体存储和一个私有账本存储。

  • src/ledger.ts — 只追加的每日预留/对账事件。

  • src/pricing.ts — 已发布的回退费率和用量计次换算。

  • src/config.ts — 默认拒绝(fail-closed)的环境校验。

该 MCP 处理器支持当前按请求的 MCP 流量,以及 SDK 的无状态旧版 Streamable HTTP 回退。函数实例中不存储任何会话状态。

环境

将 .env.example 复制到你的密钥管理器或 Vercel 项目设置中。不要提交 .env。

必需项:

  • MCP_SHARED_SECRET:32–4096 个字符。每个真实的 MCP GET、POST 和 DELETE 请求都必须将其作为 x-mcp-secret 发送。

  • XAI_API_KEY:服务端 xAI 密钥。

  • DAILY_SPEND_LIMIT_USD:正的按 UTC 日计算的 xAI 生成费用上限。

  • 一个用于返回媒体的公共 Vercel Blob 存储:

    • MEDIA_BLOB_READ_WRITE_TOKEN,或

    • MEDIA_BLOB_STORE_ID 配合 VERCEL_OIDC_TOKEN。

  • 一个用于支出账本事件的独立私有 Vercel Blob 存储:

    • LEDGER_BLOB_READ_WRITE_TOKEN,或

    • LEDGER_BLOB_STORE_ID 配合 VERCEL_OIDC_TOKEN。

Vercel 在创建存储时即固定其公共/私有模式,因此一个存储不能同时承担两种角色。复用同一个已知令牌或存储 ID 会导致配置校验失败。已弃用的 BLOB_TOKEN 和无前缀的 BLOB_READ_WRITE_TOKEN 变量不会被使用。

可选:

  • MCP_ALLOWED_ORIGINS:逗号分隔的精确 HTTP(S) 浏览器 Origin。

  • MAX_IMAGE_BYTES、MAX_VIDEO_BYTES、MAX_AUDIO_BYTES:正的字节数限制。默认值分别为 25 MiB、128 MiB 和 50 MiB。

在不打印值且不发起网络请求的情况下校验配置:

npm run doctor

安装与验证

Node.js 20 或更高版本:

./init.sh
./test.sh

等效的 npm 命令:

npm ci
npm run typecheck
npm test
npm run build

stop.sh 被故意设为空操作,因为此仓库不会启动后台守护进程。生产函数生命周期由 Vercel 负责。

部署到 Vercel

  1. 从该仓库创建一个 Vercel 项目。

  2. 连接两个 Vercel Blob 存储:一个公共存储用于媒体,一个私有存储用于账本事件。为它们设置环境变量前缀 MEDIA 和 LEDGER,或配置上述显式变量。

  3. 为目标部署环境配置上述每个必需的环境变量。

  4. 将 api/mcp.ts 保留在 /api/mcp。vercel.json 请求一个 800 秒的函数,这需要 Vercel Pro 或 Enterprise。这涵盖了 xAI 视频轮询的十分钟截止时限以及响应处理。

  5. 通过你正常的审查工作流进行部署。

此仓库不运行部署命令。Vercel Hobby 目前将函数上限设为 300 秒,因此它适合图像/编辑/TTS 使用,但无法可靠地满足此同步 generate_video 契约。不要将 Hobby 部署描述为视频就绪。

Vercel Host 与 Origin 行为

该服务未硬编码 Host 白名单。Vercel 的部署、预览和自定义域主机名会独立变化,且 Vercel 在调用函数之前会验证路由和 TLS。MCP_ALLOWED_ORIGINS 控制浏览器的 Origin 请求头,而非 Vercel 目标主机名。

非浏览器 MCP 客户端通常会省略 Origin,并在通过 secret 身份验证后被接受。发送 Origin 的请求会被拒绝,除非配置了其精确来源。这使浏览器访问变成显式选择加入(opt-in)。被允许的 CORS 预检不会调用 MCP 或 xAI;随后的 MCP 请求仍然需要 x-mcp-secret。

连接与冒烟测试

设置 shell 变量,同时避免将密钥写入命令历史:

export MCP_URL='https://your-project.vercel.app/api/mcp'
read -s MCP_SHARED_SECRET
export MCP_SHARED_SECRET

Streamable HTTP 初始化冒烟请求:

curl --fail-with-body --no-buffer \
  -X POST "$MCP_URL" \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -H "x-mcp-secret: $MCP_SHARED_SECRET" \
  --data '{
    "jsonrpc":"2.0",
    "id":1,
    "method":"initialize",
    "params":{
      "protocolVersion":"2025-06-18",
      "capabilities":{},
      "clientInfo":{"name":"curl-smoke","version":"1.0.0"}
    }
  }'

未经过身份验证的检查应返回 401,且不调用任何工具:

curl -i -X POST "$MCP_URL" \
  -H 'Content-Type: application/json' \
  --data '{"jsonrpc":"2.0","id":1,"method":"ping"}'

对于 MCP Inspector:

npx @modelcontextprotocol/inspector

在 Inspector 中,选择 Streamable HTTP,输入 $MCP_URL,并添加自定义请求头 x-mcp-secret。如果 Inspector 直接从其浏览器 UI 发送请求,请将该 UI 的精确来源添加到 MCP_ALLOWED_ORIGINS;如果它使用本地代理,通常不会有浏览器 Origin 到达该服务。先列出工具,再调用工具。当使用真实的 xAI 密钥进行配置时,工具调用会产生费用。

支持远程请求头的 MCP 客户端应配置相同的 URL,以及一个来自其自身环境或密钥存储的 secret 请求头。切勿将 xAI API 密钥粘贴到 MCP 客户端中;客户端配置中只应包含共享的 MCP secret。

安全说明

  • 共享密钥比较会对两个值进行哈希,并使用 crypto.timingSafeEqual。缺失或格式错误的身份验证都会以 fail-closed 方式失败。密钥、请求头和上游请求体不会输出到应用程序日志。

  • 此服务返回的媒体有意设为公开。请勿生成敏感内容。独立私有账本存储中的预留事件会保留提交的提示词/文本,以及工具、模型、估算值和时间戳;对账事件会补充实际费用。切勿将凭证放入提示词中。

  • 调用方提供的 image_url 值会作为 JSON 传递给 xAI,此服务绝不会获取这些值。

  • 该服务只获取从成功的 xAI 响应中获得的 URL。它要求使用 HTTPS,拒绝明显的本地/私有字面主机名,禁用重定向,校验媒体 MIME 类型,并强制实施请求头和流式大小限制。xAI 返回的签名 URL 的 DNS 所有权仍属于上游信任边界的一部分。

  • DAILY_SPEND_LIMIT_USD 始终是必需的。有关预留行为和已文档化的无服务器并发上限,请参阅 COST.md。

  • Blob 存储、出口流量和 Vercel 执行费用不由 xAI 报告,也不在 xAI 生成费用上限之内。

测试策略

所有测试都注入模拟的 fetch 实现和内存对象存储。它们覆盖身份验证、定价与用量计次、图像请求结构、视频轮询/重试/超时、二进制 TTS、媒体校验、Blob 适配器选项以及费用上限行为。没有任何测试读取 XAI_API_KEY、联系 xAI、写入 Vercel Blob、部署或产生费用。

请通过 SECURITY.md 中的私有流程报告漏洞,而不要提交公开的 issue。

许可证

MIT。生成的媒体仍受提供商条款及其源材料中的任何权利约束。

Related MCP Connectors

Related MCP Servers