MCP WebSearch
MCP WebSearch
基于 Model Context Protocol (MCP) 的 Web 搜索服务,使用最新的 MCP Streamable HTTP 协议。
功能特性
✅ MCP Streamable HTTP 协议: 符合最新 MCP 规范
✅ 单一端点设计:
/mcp支持 POST/GET/DELETE✅ Session 管理: 使用
Mcp-Session-Idheader✅ 实时消息推送: 支持 streaming 响应
✅ DuckDuckGo 搜索: 集成 DuckDuckGo 搜索引擎
✅ 身份验证: 基于 API Token 的身份验证
✅ 速率限制: 防止 API 滥用
✅ 可扩展架构: 预留其他搜索引擎集成接口
✅ TypeScript: 完整的类型安全
✅ Fastify: 高性能 Web 框架
✅ Biome: 现代化的代码格式化和 Lint 工具
技术栈
Web 框架: Fastify 5.x
MCP SDK: @modelcontextprotocol/sdk 1.21.0
MCP 协议: Streamable HTTP (2025-03-26 规范)
搜索引擎: DuckDuckGo (HTML API)
开发工具: TypeScript, Biome, tsx
认证: API Token (Bearer / X-API-Key)
速率限制: @fastify/rate-limit
MCP Streamable HTTP 协议说明
本服务实现了最新的 MCP Streamable HTTP transport 规范 (2025-03-26),取代了旧的 HTTP with separate endpoints transport。
关键特性
单一端点:
/mcp(POST/GET/DELETE)Session 管理: 使用
Mcp-Session-Idheader初始化: POST 请求自动创建 session
Streaming 连接: GET 请求建立 streaming 连接接收服务器推送
Session 终止: DELETE 请求关闭 session
端点说明
方法 | 端点 | 用途 | 需要认证 | 需要 Session ID |
GET |
| 健康检查 | ❌ | ❌ |
POST |
| 发送 JSON-RPC 消息 | ✅ | 首次请求不需要 |
GET |
| 建立 streaming 连接 | ✅ | ✅ |
DELETE |
| 终止 session | ✅ | ✅ |
快速开始
1. 安装依赖
npm install2. 配置环境变量
复制 .env.example 到 .env:
cp .env.example .env编辑 .env 文件,设置你的 API Token:
PORT=3000
NODE_ENV=production
# 设置一个或多个 API Token(逗号分隔)
API_TOKENS=your-secret-token-1,your-secret-token-2
# 速率限制配置
RATE_LIMIT_WINDOW_MS=900000 # 15分钟
RATE_LIMIT_MAX_REQUESTS=100 # 每15分钟最多100个请求
# 搜索配置
SEARCH_TIMEOUT_MS=10000 # 搜索超时时间(毫秒)
MAX_SEARCH_RESULTS=10 # 默认最大搜索结果数3. 启动服务
开发模式 (支持热重载):
npm run dev生产模式:
npm run build
npm start服务将在 http://localhost:3000 启动。
API 使用
健康检查
curl http://localhost:3000/health响应:
{
"status": "ok",
"timestamp": "2025-01-07T10:00:00.000Z",
"service": "mcp-websearch"
}MCP HTTP Streamable 协议
本服务完整实现 MCP Streamable HTTP 协议:
工作流程:
初始化 (POST /mcp)
curl -X POST http://localhost:3000/mcp \ -H "Authorization: Bearer your-token" \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {...} }'响应会包含
Mcp-Session-Idheader建立 Streaming 连接 (GET /mcp)
curl -N -H "Authorization: Bearer your-token" \ -H "Mcp-Session-Id: <session-id>" \ http://localhost:3000/mcp发送后续请求 (POST /mcp)
curl -X POST http://localhost:3000/mcp \ -H "Authorization: Bearer your-token" \ -H "Mcp-Session-Id: <session-id>" \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": {...} }'终止 Session (DELETE /mcp)
curl -X DELETE http://localhost:3000/mcp \ -H "Authorization: Bearer your-token" \ -H "Mcp-Session-Id: <session-id>"
使用示例
建立 Streaming 连接:
curl -N -H "Authorization: Bearer your-secret-token-1" \
-H "Mcp-Session-Id: your-session-id" \
http://localhost:3000/mcp或使用 X-API-Key header:
curl -N -H "X-API-Key: your-secret-token-1" \
-H "Mcp-Session-Id: your-session-id" \
http://localhost:3000/mcpWeb 搜索工具
MCP 工具名称: web_search
参数:
query(必需): 搜索查询字符串max_results(可选): 返回的最大结果数,默认 10
响应格式:
{
"query": "search term",
"results": [
{
"title": "Result Title",
"url": "https://example.com",
"snippet": "Result description...",
"source": "duckduckgo"
}
],
"totalResults": 10,
"engine": "duckduckgo",
"timestamp": "2025-01-07T10:00:00.000Z"
}在 Claude Desktop 中使用
在 Claude Desktop 的 MCP 配置中添加:
{
"mcpServers": {
"websearch": {
"url": "http://your-server:3000/mcp",
"headers": {
"Authorization": "Bearer your-secret-token-1"
}
}
}
}或使用 X-API-Key:
{
"mcpServers": {
"websearch": {
"url": "http://your-server:3000/mcp",
"headers": {
"X-API-Key": "your-secret-token-1"
}
}
}
}注意: 使用的是单一的 /mcp 端点,支持 POST/GET/DELETE 方法。
开发
开发服务器
npm run dev代码格式化和 Lint
# 格式化代码
npm run format
# 检查代码质量
npm run lint
# 自动修复问题
npm run lint:fix构建
npm run buildNginx 反向代理配置
创建 Nginx 配置文件:
server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
# Streamable HTTP 支持
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 86400s;
}
}使用 Docker 部署
构建和运行:
docker build -t mcp-websearch .
docker run -d \
-p 3000:3000 \
-e API_TOKENS=your-token \
--name mcp-websearch \
mcp-websearch或使用 docker-compose.yml:
version: '3.8'
services:
websearch:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- API_TOKENS=${API_TOKENS}
- PORT=3000
restart: unless-stopped启动:
docker-compose up -d扩展其他搜索引擎
项目架构已预留扩展接口,添加新搜索引擎步骤:
在
src/search/providers/创建新的提供商文件继承
SearchProvider基类实现
search()方法在 MCP 服务器中注册新工具
示例:
// src/search/providers/bing.ts
import { SearchProvider } from './base';
import type { SearchResult, SearchOptions } from '../types';
export class BingProvider extends SearchProvider {
readonly name = 'bing';
async search(query: string, options?: SearchOptions): Promise<SearchResult[]> {
// 实现 Bing 搜索逻辑
// ...
}
}项目结构
websearch/
├── src/
│ ├── server.ts # Fastify 服务器入口
│ ├── config/
│ │ └── index.ts # 配置管理
│ ├── mcp/
│ │ └── server.ts # MCP 服务器实现
│ ├── search/
│ │ ├── types.ts # 类型定义
│ │ └── providers/
│ │ ├── base.ts # 搜索引擎基类
│ │ └── duckduckgo.ts # DuckDuckGo 实现
│ ├── auth/
│ │ ├── middleware.ts # Fastify 认证钩子
│ │ └── rateLimiter.ts # 速率限制配置
│ └── utils/
│ ├── logger.ts # 日志工具
│ └── errors.ts # 错误处理
├── dist/ # 编译输出
├── biome.json # Biome 配置
├── .env # 环境变量(不提交)
├── .env.example # 环境变量模板
├── package.json
├── tsconfig.json
└── README.md故障排查
问题: 搜索结果为空
检查网络连接
检查 DuckDuckGo 是否可访问
增加
SEARCH_TIMEOUT_MS值
问题: 认证失败
确认
.env文件中API_TOKENS配置正确确认请求 header 格式正确
检查 token 中是否有多余的空格
问题: 速率限制触发
调整
RATE_LIMIT_MAX_REQUESTS和RATE_LIMIT_WINDOW_MS检查是否有异常请求
MCP 协议说明
本服务实现了 MCP Streamable HTTP transport 规范 (2025-03-26):
初始化连接: 客户端向
POST /mcp发送 initialize 请求Session 创建: 服务器返回
Mcp-Session-Idheader建立 Streaming: 客户端用 session ID 向
GET /mcp建立 streaming 连接消息交换: 客户端用 session ID 向
POST /mcp发送请求,通过 streaming 连接接收响应连接保持: Streaming 连接保持打开状态,支持双向通信
Session 终止: 客户端向
DELETE /mcp发送请求关闭 session
端点说明
GET /health- 健康检查(无需认证)POST /mcp- 发送 MCP 请求(首次不需要 session ID)GET /mcp- 建立 streaming 连接(需要 session ID)DELETE /mcp- 终止 session(需要 session ID)
Session 管理
Stateful 模式: 服务器自动生成并管理 session ID
Session Header: 使用
Mcp-Session-IdheaderSession 验证: 非初始化请求必须提供有效的 session ID
Session 清理: DELETE 请求或连接关闭时自动清理
License
MIT
贡献
欢迎提交 Issue 和 Pull Request!
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Eivs/mcp-websearch'
If you have feedback or need assistance with the MCP directory API, please join our Discord server