Fetchmux

io.github.krutftw由 GitHub 帳號 krutftw 發布v0.1.0更新於 Oct 27, 2026

Self-hosted retrieval router for AI agents: budgets, provider routing, route receipts.

概覽

AI 產生的概覽

面向自架 FetchMux 閘道的 MCP 用戶端,讓 AI 助理在成本與延遲預算內跨多個搜尋供應商路由檢索請求,並回傳路由回執。

可以做什麼
  • 透過自架閘道執行網頁搜尋,由閘道依你的策略挑選可用供應商,回傳正規化結果與路由回執。
  • 預覽路由決策:列出候選供應商排名與原因碼,不會實際呼叫任何供應商。
  • 可為每次請求設定成本上限與截止時間,失敗時安全重試,僅在可重試錯誤時回退。
  • 對外只提供兩個唯讀工具。
適用情境
當助理需要網頁或學術檢索,而你希望由自己託管的閘道統一控管供應商選擇、花費上限與延遲上限,並保留「哪個供應商執行、花了多少錢」的追蹤紀錄時適用。適合已在本地或 Docker 執行 FetchMux 閘道的團隊。
執行需求
需要可透過 FETCHMUX_BASE_URL 存取的 FetchMux 閘道(預設本機連接埠 8787),以及 FETCHMUX_API_KEY 中的 Bearer 金鑰。MCP 伺服器本身以 npx 在本機執行。供應商金鑰如 BRAVE_API_KEY、TAVILY_API_KEY、EXA_API_KEY、FIRECRAWL_API_KEY 設定於閘道端;免金鑰的 Crossref 路由需設定 CROSSREF_ENABLED 與 CROSSREF_CONTACT_EMAIL。閘道與 npx 套件需要 Node.js。
安裝前請注意
FETCHMUX_API_KEY 用來保護搜尋路由;將 FETCHMUX_AUTH_DISABLED 設為 true 會略過驗證,僅應在可信任的本機環境使用。供應商金鑰留在閘道端,但都是實際的付費金鑰,且必須設定各供應商的單次成本變數,美元預算才會生效。README 內含供應商註冊推薦連結,專案可從中取得佣金。路由事件會以 JSON 輸出到 stdout。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 Fetchmux,將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。

其他 MCP 客戶端

參照 儲存庫 中的啟動說明。

README

FetchMux

[npm] [License] [Node] [MCP]

One search endpoint for AI agents. Put a router in front of Brave, Tavily, Exa, Firecrawl, and Crossref. Every request carries a hard cost ceiling and deadline; every response comes back with a receipt that says which provider ran, why, and what it cost.

Your agents stop hard-coding a provider into prompts and app code. They send one request shape; the gateway picks an eligible provider under a policy you control, enforces the budget and deadline before the call, retries safely on failure, and returns normalized results plus a full trace. You keep your provider keys — they never leave your gateway.

The receipt

Nothing is a black box. Every /v1/search response carries the routing decision:

jsonc
"route": {  "selectedProvider": "brave",  "attemptedProviders": ["brave"],  "reasonCodes": ["TASK_MATCH", "WITHIN_BUDGET", "RELIABILITY_WEIGHT"],  "attempts": [    { "provider": "brave", "outcome": "success", "latencyMs": 640, "estimatedCostUsd": 0.005 }  ],  "estimatedCostUsd": 0.005,  "latencyMs": 640,  "fallbackUsed": false,  "traceId": "rt_b400e7c8"}

How it routes

  agent  ──▶  { query · task · maxCostUsd · maxLatencyMs }                             │                             ▼                      ┌──────────────┐        your keys                      │   FetchMux    │ ─────▶ Brave · Tavily · Exa                      │    policy     │        Firecrawl · Crossref                      └──────────────┘ ◀─────  (bring your own)                             │                             ▼  agent  ◀──  evidence[]  +  route receipt

A provider is eligible only when its credentials, task fit, circuit state, spend, and deadline all pass. Budgets and deadlines are eligibility rules, not best-effort hints. Fallback happens only on retryable failures.

Quick start

No provider account needed — the public Crossref route runs out of the box:

bash
git clone https://github.com/krutftw/fetchmuxcd fetchmuxnpm installnpm run build
export FETCHMUX_API_KEY="a-long-random-key"export CROSSREF_ENABLED=trueexport CROSSREF_CONTACT_EMAIL="[email protected]"npm run dev:gateway

From another shell:

bash
curl http://127.0.0.1:8787/v1/search \  -H "Authorization: Bearer a-long-random-key" \  -H "Content-Type: application/json" \  -d '{ "query": "retrieval augmented generation", "task": "scholarly", "maxLatencyMs": 8000 }'

To route real web search, set a provider key and use a web task instead:

bash
export FETCHMUX_API_KEY="a-long-random-key"export BRAVE_API_KEY="your-brave-key"export BRAVE_COST_PER_REQUEST_USD="0.005"   # from your provider plannpm run dev:gateway

New to Firecrawl? New accounts get 10% off the first month through this link (referral — FetchMux earns a small commission, no extra cost to you).

Use it from an agent

Point any MCP client (Claude, Cursor, and friends) at the published server:

json
{  "mcpServers": {    "fetchmux": {      "command": "npx",      "args": ["-y", "@fetchmux/mcp"],      "env": {        "FETCHMUX_BASE_URL": "http://127.0.0.1:8787/",        "FETCHMUX_API_KEY": "your-gateway-key"      }    }  }}

Two read-only tools: search_web and preview_search_route.

Or use the typed SDK, @fetchmux/sdk:

typescript
import { FetchMux } from "@fetchmux/sdk";
const client = new FetchMux({  baseUrl: "http://127.0.0.1:8787/",  apiKey: process.env.FETCHMUX_API_KEY,  fetch: globalThis.fetch.bind(globalThis),});
const res = await client.search({  query: "latest stable Node.js release",  task: "fresh_facts",  maxCostUsd: 0.02,});

Providers

Bring your own key for each. Set the matching *_API_KEY, plus an optional *_COST_PER_REQUEST_USD if you want dollar budgets enforced.

ProviderUseKey
Braveweb searchBRAVE_API_KEY
Tavilyweb search, researchTAVILY_API_KEY
Exaweb search, docsEXA_API_KEY
Firecrawlpage contentFIRECRAWL_API_KEY
Crossrefscholarly metadatanone (CROSSREF_ENABLED=true)

REST endpoints

MethodPathAuthBehavior
GET/healthpublicProcess health and version
GET/readypublicProvider readiness
GET/v1/providersbearerProvider configuration status
POST/v1/route/previewbearerRanked candidates, no provider call
POST/v1/searchbearerRouted retrieval and route receipt

Full contract: docs/openapi.yaml.

All configuration variables

The process does not auto-load .env in local Node development; set variables in the shell or a process manager. Docker Compose reads the ignored .env file.

VariableDefaultPurpose
FETCHMUX_API_KEYnoneProtected-route bearer key
FETCHMUX_API_KEYSnoneComma-separated keys for rotation
FETCHMUX_AUTH_DISABLEDfalseExact true bypasses auth (trusted local use only)
FETCHMUX_ALLOWED_ORIGINSnoneComma-separated browser origins; no CORS when empty
FETCHMUX_HOST127.0.0.1Bind address
FETCHMUX_PORT8787TCP port
BRAVE_API_KEY / TAVILY_API_KEY / EXA_API_KEY / FIRECRAWL_API_KEYnoneProvider credentials
CROSSREF_ENABLEDfalseExact true enables the credential-free scholarly route
CROSSREF_CONTACT_EMAILnoneMonitored contact for Crossref's polite pool
*_COST_PER_REQUEST_USDnonePer-provider cost estimates used by dollar budgets

See provider configuration before enabling maxCostUsd.

Run in Docker

bash
cp .env.example .env    # add your keys, never commit itdocker compose up --build -dcurl http://127.0.0.1:8787/health

Non-root Distroless image: Linux capabilities dropped, read-only root filesystem, provider credentials passed only at container start.

Benchmark

Validate every case and provider pairing with no network calls or credits:

bash
npm run benchmark -- --workload benchmarks/workloads/founding-v1.json --mode dry-run

Live mode needs provider keys and an explicit --confirm-live. Check each provider's terms before publishing results — see the benchmark methodology.

What it is (and isn't)

Open source, self-hosted, single-tenant, BYOK. Route events go to stdout as JSON and exclude your query text, keys, and result content by default. No database, no telemetry.

It is not a hosted service, a pooled-credit reseller, or a claim that these providers are interchangeable. Provider names are the adapters it ships with, not partnerships. A hosted version is on the roadmap — star the repo to follow.

Development

bash
npm test          # 232 testsnpm run typechecknpm run lintnpm run buildnpm run dev:gatewaynpm run dev:site

More docs: product design · local development · deployment · provider configuration · data handling · incident response

Security issues: [email protected].

License

Apache-2.0. Free to self-host, modify, and redistribute.

來源:README.md,提交 18f8b31

工具

0
SourceWeft 尚未在沙箱中啟動過該軟體包,因此其工具未知。

版本歷史

1
  1. v0.1.0最新Sep 16, 2026

評分

已滿足適用檢查項的 50%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通25 分

    請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。

  • 已宣告認證方式10 分

    請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。

  • 已列出工具15 分

    請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。

  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分