耐火材料
一个可自托管、兼容Vercel的MCP(模型上下文协议)服务器,用于 萤火虫,采用严格的TypeScript ES2024构建, 效果TS,以及Bun运行时。
快速入门:
______________________________________________________________________
建筑
firecrawl-mcp/
├── api/ # Vercel serverless function entrypoints
│ ├── health.ts # GET /health — LB probe
│ └── mcp.ts # POST / — MCP JSON-RPC 2.0 handler
├── src/
│ ├── config/
│ │ └── app-config.ts # Effect Config — typed secret management
│ ├── errors/
│ │ └── mcp-errors.ts # Tagged domain errors (Data.TaggedError)
│ ├── services/
│ │ ├── firecrawl-client.ts # Effect Layer wrapping @mendable/firecrawl-js
│ │ └── logger.ts # Structured JSON logger service
│ ├── api/
│ │ ├── groups/
│ │ │ └── mcp-handler.ts # MCP JSON-RPC dispatch + web adapter
│ │ └── schemas/
│ │ └── firecrawl-schemas.ts # Effect Schema types for all tools
│ ├── tools/
│ │ ├── tool-definitions.ts # Static tool metadata (tools/list)
│ │ ├── tool-registry.ts # Handler map — name -> Effect handler
│ │ └── tool-schemas.ts # Schema re-exports (avoids circular imports)
│ ├── lib/
│ │ ├── app-layer.ts # Full Layer DAG composition
│ │ └── utils.ts # Pure utilities (sanitization, parsing)
│ └── server.ts # Local Bun dev server
├── .env.example
├── dprint.json
├── package.json
├── tsconfig.json
└── vercel.json实心对齐
| 原理 | 实施 |
|---|---|
| 单一责任 | 每个文件都有一个关注点:配置、错误、客户端、处理程序、模式 |
| 打开/关闭 | 通过添加新工具 TOOL_DEFINITIONS + REGISTRY 无需接触现有处理程序 |
| 利斯科夫替补 | FirecrawlClientOps 接口——云和自托管客户端可以互换 |
| 接口隔离 | FirecrawlClientOps 仅公开处理程序所需的内容,而不是完整的SDK界面 |
| 依赖倒置 | 所有服务均通过Effect解决 Layer / Context.Tag --没有直接 new 调用处理程序 |
______________________________________________________________________
需求
- 包子 >= 1.1.0
- Firecrawl API密钥 或自托管的Firecrawl实例URL
______________________________________________________________________
运行期模型
| 上下文 | 运行时 |
|---|---|
| 本地开发服务器 | Bun(本地, bun run dev) |
| 类型检查 | Bun调用 tsc (bun tsc --noEmit) |
| 格式化 | dprint(bun run fmt) |
| 邦德勒 | 邦恩(bun build --target node --format esm) |
| Vercel执行 | Node.js 22正在运行编译后的ESM输出 dist/ |
Bun是唯一的工具链——安装程序、打包器、测试运行器、开发服务器和 类型检查器主机。Vercel负责运营 _编译输出_ 在Node.js 22下。没有 运行时冲突:源代码永远不会交给Node raw。这 functions 把…的车堵住 vercel.json 故意缺席;Vercel自动检测 api/ 处理人员和 服务捆绑 dist/ 输出。
______________________________________________________________________
本地开发
# Install dependencies
bun install
# Configure environment
cp .env.example .env.local
# Edit .env.local: set FIRECRAWL_API_KEY or FIRECRAWL_API_URL
# Start dev server with hot reload
bun run dev
# Server listens on http://localhost:3000
# Type-check (bun hosts tsc — no separate tsc binary needed)
bun run typecheck
# Format all source files
bun run fmt
# Check formatting without writing (CI)
bun run fmt:check发送测试请求
# List available tools
curl -X POST http://localhost:3000 \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
# Scrape a page
curl -X POST http://localhost:3000 \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "firecrawl_scrape",
"arguments": {
"url": "https://example.com",
"formats": ["markdown"],
"onlyMainContent": true
}
}
}'
# Export Prometheus metrics
curl -X GET http://localhost:3000/metrics______________________________________________________________________
Vercel部署
# Install Vercel CLI
bun add -g vercel
# Deploy
vercel
# Set environment variables in Vercel dashboard or via CLI
vercel env add FIRECRAWL_API_KEY环境变量
| 变量 | 必填 | 描述 | |||
|---|---|---|---|---|---|
FIRECRAWL_API_KEY | 这两者之一 | Firecrawl云API密钥 | |||
FIRECRAWL_API_URL | 其中之一 | 自托管实例基URL | |||
CLOUD_SERVICE | 没有 | true 通过标头要求每个请求的API密钥 | |||
SAFE_MODE | 没有 | true 禁用浏览器执行和抓取webhooks | |||
MAX_REQUEST_BODY_BYTES | 否 | 最大请求正文大小(以字节为单位)(默认值: 1048576) | |||
REQUEST_TIMEOUT_MS | 否 | 请求超时预算(毫秒)(默认值: 25000) | |||
RATE_LIMIT_ENABLED | 否 | 启用内存中的每IP速率限制(默认值: true) | |||
RATE_LIMIT_REQUESTS | 否 | 每个窗口允许的请求(默认值: 120) | |||
RATE_LIMIT_WINDOW_MS | 否 | 速率限制窗口(毫秒)(默认值: 60000) | |||
PORT | 否 | 本地服务器端口(默认值:3000) | |||
LOG_LEVEL | 没有 | debug | info | warn | error (默认值: info) |
MCP_VERSION | 无 | MCP协议版本(默认: 2025-11-25) | |||
ALLOWED_ORIGINS | 否 | 逗号分隔的允许列表 Origin CSRF保护值。省略或设置为 * 禁用(默认值:disabled) |
______________________________________________________________________
云服务模式
当 CLOUD_SERVICE=true,API密钥是从每个传入请求中读取的,而不是 相比于环境:
POST / HTTP/1.1
x-firecrawl-api-key: fc-your-key-here
Content-Type: application/json
{"jsonrpc":"2.0","id":1,"method":"tools/list"}接受的标头(按优先级顺序):
x-firecrawl-api-keyx-api-keyAuthorization: Bearer
______________________________________________________________________
安全模式
当 SAFE_MODE=true (在以下情况下自动启用 CLOUD_SERVICE=true):
firecrawl_scrape条带actions涉及用户交互(点击、编写、执行Javascript、生成PDF)firecrawl_crawl剥去webhook选项firecrawl_browser_execute返回错误
______________________________________________________________________
可观测性
- 每个回复都包括
X-Request-Id用于端到端相关性。 - 结构化日志通过经过净化的上游诊断捕获工具故障。
GET /metrics公开Prometheus文本度量:
- mcp_requests_total - mcp_request_duration_ms_total - mcp_tool_calls_total - mcp_tool_duration_ms_total
______________________________________________________________________
CI/CD
- CI工作流程(
.github/workflows/ci.yml)在PR上运行main推送:
- 格式检查 - 类型检查 - 测试 - 烟雾检查
- 依赖关系策略工作流(
.github/workflows/dependency-policy.yml)强制执行精确的固定版本并拒绝提交bun.lock. - 安全工作流程(
.github/workflows/security.yml)跑步bun audit以及CodeQL分析。 - Dependabot配置(
.github/dependabot.yml)每周管理Bun和GitHub Actions的更新。 - CD工作流程(
.github/workflows/deploy.yml)CI成功后部署到Vercelmain.
部署所需的存储库机密:
VERCEL_TOKENVERCEL_ORG_IDVERCEL_PROJECT_ID
______________________________________________________________________
添加新工具
- 添加一个
ToolDefinition进入src/tools/tool-definitions.ts - 向添加架构
src/api/schemas/firecrawl-schemas.ts - 在中重新导出架构
src/tools/tool-schemas.ts - 添加一个处理程序函数并将其注册到
src/tools/tool-registry.ts
没有其他文件需要修改。
______________________________________________________________________
效果层DAG
AppConfigLive (Config env)
|
+-- AppLoggerLive
|
+-- FirecrawlClientLive
|
+-- AppLive (merged)
|
+-- ManagedRuntime (api/mcp.ts)