Skip to main content
Glama
Sylvan-Cheng

mcp-key-rotator

by Sylvan-Cheng

mcp-key-rotator

本机代理。官方 Tavily / Firecrawl MCP 仍由 npx 启动,密钥轮换发生在它们发出的 HTTP 请求之前。

额度按账号计算。同一账号里的多把 key 共用一个额度池,轮换没有效果。每把 key 应来自各自独立的账号。

行为

状态

含义

处理

402、432、433

额度用尽

这把 key 停用到账单重置,换下一把重试

429

频率限制

按 retry-after 冷却,最长 1 小时,然后换下一把

401

key 无效

停用,直到进程重启

400、403、404、5xx

参数、权限或上游故障

原样返回,不换 key

数组里的第一把 key 是主 key,后面的是副 key。也可以写 "role": "primary",它会被排到最前,一个池里只能有一把。主 key 可用时每次都用它。

主 key 失败后记一个恢复时间,写到 key 文件旁边的 state.json。在此之前新请求直接走副 key,并发请求只让一路去探测失败的主 key。Tavily 的额度在每个自然月 1 日(UTC)恢复,接口不返回这个日期。Firecrawl 返回 402 时再读一次 GET /v2/team/credit-usage,用 billingPeriodEnd。429 只冷却 Retry-After 那段时间,连续触发会把冷却加倍,最长 1 小时。

搜索、抓取这类被拒绝的请求会换 key 重发。已经返回 200 的请求不会重发。响应里的 id / request_id 会钉在创建它的那把 key 上,之后的轮询一直用它。Tavily research、Firecrawl crawl 都是这样。响应里指向 api.firecrawl.dev 或 api.tavily.com 的链接会改写回本机代理。

代理只监听 127.0.0.1。日志里的 key 只保留末四位。

Related MCP server: tavily-proxy-mcp

准备

cd D:\Github\mcp-key-rotator
npm install
npm test
npm run build

把 keys.example.json 复制到 %USERPROFILE%\.grok\key-rotator\keys.json:

{
  "tavily": [
    { "label": "primary", "key": "tvly-...", "role": "primary" },
    { "label": "secondary", "key": "tvly-...", "role": "secondary" }
  ],
  "firecrawl": [
    { "label": "primary", "key": "fc-...", "role": "primary" },
    { "label": "secondary", "key": "fc-...", "role": "secondary" }
  ]
}

字符串和带 label 的对象都可以。不写 role 时,数组顺序就是优先级。

环境变量:

变量

默认

作用

KEYS_FILE

当前目录的 keys.json,否则 %USERPROFILE%\.grok\key-rotator\keys.json

key 文件

ROTATOR_PORT

8788

监听端口

CREDIT_RESET_DAY

1

Firecrawl 读不到 billingPeriodEnd 时的回退日

直接跑代理:

$env:KEYS_FILE = "$env:USERPROFILE\.grok\key-rotator\keys.json"
npm start

GET http://127.0.0.1:8788/healthz 返回各池剩余可用 key 数量,不返回密钥。改完 keys.json 要重启代理。

接到 Grok

~/.grok/config.toml:

[mcp_servers.firecrawl]
command = "node"
args = ["D:\\Github\\mcp-key-rotator\\dist\\launch.js", "firecrawl"]
enabled = true
startup_timeout_sec = 90

[mcp_servers.firecrawl.env]
KEYS_FILE = "C:\\Users\\Ruixi\\.grok\\key-rotator\\keys.json"

[mcp_servers.tavily]
command = "node"
args = ["D:\\Github\\mcp-key-rotator\\dist\\launch.js", "tavily"]
enabled = true
startup_timeout_sec = 90

[mcp_servers.tavily.env]
KEYS_FILE = "C:\\Users\\Ruixi\\.grok\\key-rotator\\keys.json"

launch.js firecrawl 把官方 firecrawl-mcp 的 FIRECRAWL_API_URL 指到本机。launch.js tavily 给官方 tavily-mcp 加上 dist/redirect.js:那个包把地址写死成 https://api.tavily.com,垫片把这些请求改到本机,代理再同时替换 Authorization 和 JSON 里的 api_key。

两个进程会共用一个已经在听的代理。代理是独立进程,MCP 退出后它还在。停掉它:

Get-NetTCPConnection -LocalPort 8788 -State Listen |
  ForEach-Object { Stop-Process -Id $_.OwningProcess }

改完配置后新开一个 Grok 会话。

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    D
    maintenance
    A multi-API key load balancing MCP server for Tavily that automatically rotates between multiple API keys to provide high availability and increased request limits.
    6
    72
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    A proxy MCP server that connects to Tavily's official Streamable HTTP MCP, managing multiple API keys and automatically switching to the next one when the current key's quota is exhausted.
    5
    13 npm
    1
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Exposes pooled Tavily API keys through an MCP streamable HTTP endpoint, providing search, extract, crawl, map, research, and pool status tools with automatic key rotation and quota management.
    MIT