update READMEME

This commit is contained in:
Yrobot
2026-03-13 22:32:43 +08:00
parent 5a19ea13b4
commit df308e3ae6
4 changed files with 740 additions and 284 deletions

511
README.md
View File

@@ -1,220 +1,268 @@
# Cloudflare Search # Cloudflare Search
> 基于 Cloudflare Workers 的聚合搜索 API 服务 English | [中文](./README.zh.md)
> 支持 **MCP (Model Context Protocol)**,让 AI 助手拥有实时联网搜索能力 > An aggregated search API service based on Cloudflare Workers
> Supports **MCP (Model Context Protocol)**, giving AI assistants (OpenClaw, Claude Code, Codex, OpenCode) real-time web search capabilities
[![Deploy to Cloudflare Workers](https://deploy.workers.cloudflare.com/button)](https://sink.proddig.com/cloudflare-search-github) [![Deploy to Cloudflare Workers](https://deploy.workers.cloudflare.com/button)](https://sink.proddig.com/cloudflare-search-github)
## 特性 ## Features
- 🔍 **多引擎聚合** - 同时使用多个搜索引擎(GoogleBraveDuckDuckGoBing - 🔍 **Multi-engine Aggregation** - Use multiple search engines at the same time (Google, Brave, DuckDuckGo, Bing)
- 🤖 **AI 增强 (MCP)** - 原生支持 Model Context Protocol,一键为 Claude Code/Desktop 添加搜索工具 - 🤖 **AI Enhanced (MCP)** - Native support for Model Context Protocol, one-click search tool integration for **OpenClaw** / **Claude Code** / **Codex**
-**并行搜索** - 所有搜索引擎同时请求,快速返回结果 -**Parallel Search** - All search engines are requested concurrently for faster results
- 🛡️ **容错机制** - 单个引擎失败不影响其他引擎,自动标记无响应引擎 - 🛡️ **Fault Tolerance** - Failure of a single engine does not affect others; unresponsive engines are automatically marked
- ⏱️ **超时控制** - 可配置请求超时时间,避免长时间等待 - ⏱️ **Timeout Control** - Configurable request timeout to avoid long waits
- 🔒 **Token 鉴权** - 支持 Token 认证,保护服务不被滥用 - 🔒 **Token Authentication** - Supports token auth to protect the service from abuse
- 🌍 **CORS 支持** - 完整的跨域资源共享支持 - 🌍 **CORS Support** - Full cross-origin resource sharing support
- 🎨 **Web 界面** - 提供简洁的搜索界面,方便测试 - 🎨 **Web Interface** - Provides a clean search UI for easy testing
-**零成本运行** - Cloudflare Workers 免费版每天 10 万次请求 -**Zero-cost Operation** - Cloudflare Workers free tier supports 100,000 requests per day
## 页面展示 ## Page Preview
![screenshot](./screenshot.png) ![screenshot](./screenshot.png)
## 安装方式 ## MCP Integration: Use in OpenClaw / Claude Code / AI Agents
### 方式一:一键部署(推荐) With MCP (Model Context Protocol), AI assistants can directly call your search service and get real-time search results.
点击上方 "Deploy to Cloudflare Workers" 按钮,按照提示完成部署。 ### Installation and Configuration
### 方式二:使用 Wrangler CLI #### 1. Deploy the Service
First, follow the guide to [Deploy Cloudflare Search](#installation-methods)
#### 2. Add MCP Server Configuration
Edit your config file ([configuration guide](https://modelcontextprotocol.io/quickstart/user)):
- **OpenClaw**: `~/.openclaw/openclaw.json`
- **Claude Code**: `~/.claude/config.json` / `~/.claude.json`
- **Claude Desktop macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Claude Desktop Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
```json
{
"mcpServers": {
"cloudflare-search": {
"command": "npx",
"args": ["-y", "@yrobot/cf-search-mcp"],
"env": {
"CF_SEARCH_URL": "https://your-worker.workers.dev",
"CF_SEARCH_TOKEN": "your-token-here"
}
}
}
}
```
**Environment Variables**:
- `CF_SEARCH_URL`: Worker deployment URL (required)
- `CF_SEARCH_TOKEN`: Auth token (required if your Worker has `TOKEN` configured)
#### 3. Verify Installation
- **OpenClaw**: Run `openclaw gateway restart` + `openclaw mcp list` and check that `cloudflare-search` appears
- **Claude Code**:
- Run `/mcp` in Claude Code, and you should see the `cloudflare-search` tool.
- Or run `claude mcp list`; seeing `cloudflare-search: npx -y @yrobot/cf-search-mcp@latest - ✓ Connected` means setup is successful
## Installation Methods
### Method 1: One-click Deployment (Recommended)
Click the "Deploy to Cloudflare Workers" button above and follow the prompts.
### Method 2: Use Wrangler CLI
```bash ```bash
# 1. 安装 Wrangler # 1. Install Wrangler
npm install -g wrangler npm install -g wrangler
# 2. 登录 Cloudflare # 2. Login to Cloudflare
wrangler login wrangler login
# 3. 克隆仓库 # 3. Clone the repository
git clone https://github.com/Yrobot/cloudflare-search.git git clone https://github.com/Yrobot/cloudflare-search.git
cd cloudflare-search cd cloudflare-search
# 4. 部署 # 4. Deploy
wrangler deploy wrangler deploy
``` ```
### 方式三:使用 Cloudflare Dashboard ### Method 3: Use Cloudflare Dashboard
1. 登录 [Cloudflare Dashboard](https://dash.cloudflare.com/) 1. Sign in to [Cloudflare Dashboard](https://dash.cloudflare.com/)
2. 进入 **Workers & Pages** 2. Go to **Workers & Pages**
3. 点击 **Create Application** > **Create Worker** 3. Click **Create Application** > **Create Worker**
4. 点击 **Upload** 上传本地代码文件夹 4. Click **Upload** to upload your local code folder
- 选择克隆的 `cloudflare-search` 文件夹 - Select the cloned `cloudflare-search` folder
- 或者手动复制 `worker.js``envs.js``utils/` 等文件 - Or manually copy `worker.js`, `envs.js`, `utils/`, and other files
5. 点击 **Save and Deploy** 5. Click **Save and Deploy**
### 获取访问地址 ### Get Access URL
部署成功后,你会获得一个 Worker URL After deployment, you will get a Worker URL:
``` ```
https://your-worker-name.your-subdomain.workers.dev https://your-worker-name.your-subdomain.workers.dev
``` ```
**注意**:这个自带的域名在某些区域可能无法直接访问,建议绑定自己的域名使用。 **Note**: The default domain may not be directly accessible in some regions. It is recommended to bind your own custom domain.
## 使用方式 ## Usage
### 方式 1: Web 界面 ### Method 1: Web Interface
直接访问你的 Worker URL,在网页界面输入搜索关键词: Open your Worker URL directly and enter search keywords in the web UI:
``` ```
https://$YOUR-DOMAIN/ https://$YOUR-DOMAIN/
``` ```
### 方式 2: API 请求(GET ### Method 2: API Request (GET)
使用查询参数进行搜索: Search using query parameters:
```bash ```bash
# 基本搜索 # Basic search
curl "https://$YOUR-DOMAIN/search?q=cloudflare" curl "https://$YOUR-DOMAIN/search?q=cloudflare"
# 指定搜索引擎 # Specify search engines
curl "https://$YOUR-DOMAIN/search?q=cloudflare&engines=google,brave" curl "https://$YOUR-DOMAIN/search?q=cloudflare&engines=google,brave"
# 使用 token 鉴权(如果配置了 TOKEN 环境变量) # Use token authentication (if TOKEN env var is configured)
curl "https://$YOUR-DOMAIN/search?q=cloudflare&token=$YOUR-TOKEN" curl "https://$YOUR-DOMAIN/search?q=cloudflare&token=$YOUR-TOKEN"
``` ```
### 方式 3: API 请求(POST ### Method 3: API Request (POST)
通过 POST 表单提交搜索: Submit search by POST form:
```bash ```bash
curl -X POST "https://$YOUR-DOMAIN/search" \ curl -X POST "https://$YOUR-DOMAIN/search" \
-d "q=cloudflare" \ -d "q=cloudflare" \
-d "engines=google,brave" -d "engines=google,brave"
-d "token=$YOUR-TOKEN" # 如果配置了 TOKEN 环境变量 -d "token=$YOUR-TOKEN" # if TOKEN env var is configured
``` ```
## API 接口说明 ## API Reference
### `/search` 接口 ### `/search` Endpoint
用于执行搜索查询并返回聚合结果。 Used to execute search queries and return aggregated results.
#### 请求参数 #### Request Parameters
| 参数 | 类型 | 必填 | 说明 | 示例 | | Parameter | Type | Required | Description | Example |
| ------------- | -------- | ------ | ----------------------------------------- | -------------- | | ------------- | -------- | -------- | ---------------------------------------------------------- | ---------------- |
| `q` / `query` | `string` | yes | 搜索关键词 | `cloudflare` | | `q` / `query` | `string` | yes | Search keyword | `cloudflare` |
| `engines` | `string` | no | 指定搜索引擎,多个用逗号分隔 | `google,brave` | | `engines` | `string` | no | Specify search engines, separated by commas | `google,brave` |
| `token` | `string` | no/yse | 访问令牌(当配置了 TOKEN 环境变量时必填) | `$YOUR-TOKEN` | | `token` | `string` | no/yes | Access token (required when `TOKEN` env var is configured) | `$YOUR-TOKEN` |
**支持的搜索引擎** **Supported Search Engines**:
- `google` - Google 搜索(需要配置 API Key - `google` - Google Search (requires API Key configuration)
- `brave` - Brave 搜索 - `brave` - Brave Search
- `duckduckgo` - DuckDuckGo 搜索 - `duckduckgo` - DuckDuckGo Search
- `bing` - Bing 搜索 - `bing` - Bing Search
#### 返回值 #### Response Value
```typescript ```typescript
{ {
query: string; // 搜索关键词 query: string; // Search keyword
number_of_results: number; // 结果总数 number_of_results: number; // Total number of results
enabled_engines: string[]; // 启用的搜索引擎列表 enabled_engines: string[]; // Enabled search engine list
unresponsive_engines: string[]; // 无响应的搜索引擎列表 unresponsive_engines: string[]; // Unresponsive search engine list
results: Array<{ results: Array<{
title: string; // 结果标题 title: string; // Result title
description: string; // 结果描述 description: string; // Result description
url: string; // 结果链接 url: string; // Result link
engine: string; // 来源引擎 engine: string; // Source engine
}>; }>;
} }
``` ```
#### 请求示例 #### Request Examples
```bash ```bash
# GET 请求 # GET request
curl "https://$YOUR-DOMAIN/search?q=cloudflare&engines=google,brave" curl "https://$YOUR-DOMAIN/search?q=cloudflare&engines=google,brave"
# POST 请求 # POST request
curl -X POST "https://$YOUR-DOMAIN/search" \ curl -X POST "https://$YOUR-DOMAIN/search" \
-H "Content-Type: application/x-www-form-urlencoded" \ -H "Content-Type: application/x-www-form-urlencoded" \
-d "q=cloudflare&engines=google,brave" -d "q=cloudflare&engines=google,brave"
``` ```
#### 响应示例 #### Response Example
```json ```json
{ {
"query": "cloudflare", "query": "cloudflare",
"number_of_results": 15, "number_of_results": 15,
"enabled_engines": ["google", "brave", "duckduckgo"], "enabled_engines": ["google", "brave", "duckduckgo"],
"unresponsive_engines": [], "unresponsive_engines": [],
"results": [ "results": [
{ {
"title": "Cloudflare - The Web Performance & Security Company", "title": "Cloudflare - The Web Performance & Security Company",
"description": "Cloudflare is on a mission to help build a better Internet...", "description": "Cloudflare is on a mission to help build a better Internet...",
"url": "https://www.cloudflare.com/", "url": "https://www.cloudflare.com/",
"engine": "google" "engine": "google"
}, },
{ {
"title": "Cloudflare Workers", "title": "Cloudflare Workers",
"description": "Deploy serverless code instantly across the globe...", "description": "Deploy serverless code instantly across the globe...",
"url": "https://workers.cloudflare.com/", "url": "https://workers.cloudflare.com/",
"engine": "brave" "engine": "brave"
} }
] ]
} }
``` ```
## 搜索引擎说明 ## Search Engine Notes
### 支持的搜索引擎 ### Supported Search Engines
| 引擎 | 说明 | 是否需要配置 | 默认启用 | | Engine | Description | Configuration Required | Enabled by Default |
| -------------- | ------------------------ | ----------------------------- | --------------- | | -------------- | ---------------------------- | ------------------------------- | ------------------ |
| **Google** | Google Custom Search API | 需要 GOOGLE_API_KEY GOOGLE_CX | yes | | **Google** | Google Custom Search API | Requires `GOOGLE_API_KEY` and `GOOGLE_CX` | yes |
| **Brave** | Brave Search API | - | yes | | **Brave** | Brave Search API | - | yes |
| **DuckDuckGo** | DuckDuckGo 即时答案 API | - | yes | | **DuckDuckGo** | DuckDuckGo Instant Answer API | - | yes |
| **Bing** | Bing 搜索 | - | no (结果不稳定) | | **Bing** | Bing Search | - | no (unstable results) |
### 基本工作方案 ### Basic Working Approach
1. **并行请求**:所有启用的搜索引擎同时发起请求,提高响应速度 1. **Parallel Requests**: All enabled search engines are requested concurrently to improve response speed
2. **超时控制**:单个引擎超时不影响其他引擎,默认 3 秒超时 2. **Timeout Control**: Timeout of a single engine does not affect others; default timeout is 3 seconds
3. **结果聚合**:将所有成功返回的结果合并,标记来源引擎 3. **Result Aggregation**: Merge all successfully returned results and mark their source engine
4. **容错处理**:记录无响应的引擎,返回部分结果而不是完全失败 4. **Fault Tolerance**: Record unresponsive engines and return partial results instead of failing completely
## 环境变量配置 ## Environment Variable Configuration
### 环境变量说明 ### Environment Variables
| 变量名 | 类型 | 默认值 | 说明 | | Variable Name | Type | Default | Description |
| ----------------- | -------- | -------- | ------------------------------------------------- | | ------------------ | -------- | -------- | --------------------------------------------------- |
| `DEFAULT_TIMEOUT` | `string` | `"3000"` | 单个搜索引擎的超时时间(毫秒) | | `DEFAULT_TIMEOUT` | `string` | `"3000"` | Timeout per search engine request (milliseconds) |
| `GOOGLE_API_KEY` | `string` | `null` | https://console.cloud.google.com/apis/credentials | | `GOOGLE_API_KEY` | `string` | `null` | https://console.cloud.google.com/apis/credentials |
| `GOOGLE_CX` | `string` | `null` | https://programmablesearchengine.google.com/ | | `GOOGLE_CX` | `string` | `null` | https://programmablesearchengine.google.com/ |
| `TOKEN` | `string` | `null` | 访问令牌,配置后启用鉴权,保护服务不被滥用 | | `TOKEN` | `string` | `null` | Access token. Enables auth when configured to prevent abuse |
**注意** **Notes**:
- Google Custom Search API 免费版每天限制 100 次请求 - Google Custom Search API free tier is limited to 100 requests per day
- `TOKEN` 配置后,所有请求都需要提供有效的 token - After `TOKEN` is configured, all requests must provide a valid token
### 配置方式 ### Configuration Methods
#### 方式 1: wrangler.toml 文件 #### Method 1: `wrangler.toml` File
编辑 `wrangler.toml` 文件中的 `[vars]` 部分: Edit the `[vars]` section in `wrangler.toml`:
```toml ```toml
[vars] [vars]
@@ -224,218 +272,165 @@ DEFAULT_TIMEOUT = "3000"
TOKEN = "your-secret-token-here" TOKEN = "your-secret-token-here"
``` ```
#### 方式 2: Cloudflare Dashboard #### Method 2: Cloudflare Dashboard
1. 进入 Worker 设置页面 1. Go to the Worker settings page
2. 找到 **Environment Variables** 部分 2. Find the **Environment Variables** section
3. 添加变量并保存 3. Add variables and save
## 使用场景 ## Use Cases
### 1. 聚合搜索服务 ### 1. Aggregated Search Service
构建自己的搜索聚合 API整合多个搜索引擎结果 Build your own aggregated search API and combine results from multiple search engines:
```javascript ```javascript
const response = await fetch( const response = await fetch(
"https://$YOUR-DOMAIN/search?q=javascript&engines=google,brave" "https://$YOUR-DOMAIN/search?q=javascript&engines=google,brave",
); );
const data = await response.json(); const data = await response.json();
console.log(`找到 ${data.number_of_results} 个结果`); console.log(`Found ${data.number_of_results} results`);
``` ```
### 2. 前端搜索功能 ### 2. Frontend Search Feature
为网站或应用添加搜索功能: Add search functionality to your website or app:
```javascript ```javascript
async function search(query) { async function search(query) {
const response = await fetch( const response = await fetch(
`https://$YOUR-DOMAIN/search?q=${encodeURIComponent(query)}` `https://$YOUR-DOMAIN/search?q=${encodeURIComponent(query)}`,
); );
const data = await response.json(); const data = await response.json();
return data.results; return data.results;
} }
``` ```
### 3. 数据采集与分析 ### 3. Data Collection and Analysis
收集多个搜索引擎的结果进行对比分析: Collect results from multiple search engines for comparative analysis:
```javascript ```javascript
const engines = ["google", "brave", "duckduckgo"]; const engines = ["google", "brave", "duckduckgo"];
const results = await fetch( const results = await fetch(
`https://$YOUR-DOMAIN/search?q=AI&engines=${engines.join(",")}` `https://$YOUR-DOMAIN/search?q=AI&engines=${engines.join(",")}`,
); );
const data = await results.json(); const data = await results.json();
// 按引擎分组 // Group by engine
const byEngine = data.results.reduce((acc, result) => { const byEngine = data.results.reduce((acc, result) => {
acc[result.engine] = acc[result.engine] || []; acc[result.engine] = acc[result.engine] || [];
acc[result.engine].push(result); acc[result.engine].push(result);
return acc; return acc;
}, {}); }, {});
``` ```
## MCP 集成 ## MCP Integration
通过 MCP (Model Context Protocol) AI 助手直接调用你的搜索服务,获取实时搜索结果。 With MCP (Model Context Protocol), AI assistants can directly call your search service and get real-time search results.
### 安装配置 ## Notes and Reminders
#### 1. 添加 MCP 服务器配置 ### 🚨 Important Notes
编辑配置文件([配置指南](https://modelcontextprotocol.io/quickstart/user) 1. **Use a Custom Domain**
- The default Cloudflare `*.workers.dev` domain may be inaccessible in some regions
- It is **strongly recommended** to bind your own domain for a better access experience
- In Worker settings, click **Triggers** > **Add Custom Domain** to add a custom domain
- **Claude Code**: `~/.claude/config.json` / `~/.claude.json` 2. **Search Engine Limits**
- **Claude Desktop macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json` - Google API free tier is limited to 100 requests per day
- **Claude Desktop Windows**: `%APPDATA%\Claude\claude_desktop_config.json` - Other search engines generally do not have strict limits, but please use responsibly
- Frequent requests may cause temporary rate limiting
```json 3. **Timeout Settings**
{ - Default timeout per engine is 3 seconds
"mcpServers": { - Can be adjusted with `DEFAULT_TIMEOUT`
"cloudflare-search": { - Do not set it too high to avoid long overall response times
"command": "npx",
"args": ["-y", "@yrobot/cf-search-mcp"],
"env": {
"CF_SEARCH_URL": "https://your-worker.workers.dev",
"CF_SEARCH_TOKEN": "your-token-here"
}
}
}
}
```
**环境变量说明** ### 🔒 Security Configuration
- `CF_SEARCH_URL`: Worker 部署地址(必填) #### Enable Authentication
- `CF_SEARCH_TOKEN`: 鉴权 Token如果 Worker 配置了 TOKEN 则必填)
#### 2. 重启应用 1. Configure the `TOKEN` environment variable to protect your service from abuse:
保存配置后重启 Claude Code 或 Claude Desktop。 - Configure `TOKEN` in `wrangler.toml`
- Configure `TOKEN` in Cloudflare Worker Dashboard
#### 3. 验证安装 2. Pass token in requests:
- 在 Claude Code 中运行 `/mcp` 命令,应该能看到 `cloudflare-search` 工具。
- 或 使用 `claude mcp list`, 看到 `cloudflare-search: npx -y @yrobot/cf-search-mcp@latest - ✓ Connected` 说明配置成功
### 使用示例
```
用 cloudflare-search 搜索 "Cloudflare Workers 最佳实践"
```
```
用 cloudflare-search 搜索 "Next.js 14 新特性"
```
AI 会返回来自多个搜索引擎的聚合结果,包括标题、描述和链接。
## 注意与提醒
### 🚨 重要提示
1. **使用自定义域名**
- Cloudflare 默认的 `*.workers.dev` 域名在某些地区可能无法访问
- **强烈建议**绑定自己的域名以获得更好的访问体验
- 在 Worker 设置中点击 **Triggers** > **Add Custom Domain** 添加自定义域名
2. **搜索引擎限制**
- Google API 免费版每天限制 100 次请求
- 其他搜索引擎一般没有严格限制,但请合理使用
- 频繁请求可能导致被临时限制访问
3. **超时设置**
- 默认单个引擎超时 3 秒
- 可通过环境变量 `DEFAULT_TIMEOUT` 调整
- 建议不要设置过长,避免整体响应时间过长
### 🔒 安全配置
#### 启用鉴权
1. 配置 `TOKEN` 环境变量 来保护你的服务不被滥用:
- 利用 wrangler.toml 配置 TOKEN 环境变量
- 通过 Cloudflare Worker Dashboard 配置 TOKEN 环境变量
2. 在请求时传入 token
```bash ```bash
# 访问首页 # Access homepage
https://$YOUR-DOMAIN?token=$YOUR-TOKEN https://$YOUR-DOMAIN?token=$YOUR-TOKEN
# 使用 query/body 的 token 参数 请求 API # Request API with token parameter in query/body
curl "https://$YOUR-DOMAIN/search?q=cloudflare&token=$YOUR-TOKEN" curl "https://$YOUR-DOMAIN/search?q=cloudflare&token=$YOUR-TOKEN"
curl -X POST "https://$YOUR-DOMAIN/search" \ curl -X POST "https://$YOUR-DOMAIN/search" \
-d "q=cloudflare" \ -d "q=cloudflare" \
-d "token=$YOUR-TOKEN" -d "token=$YOUR-TOKEN"
``` ```
## 常见问题 ## FAQ
### Q: 为什么有些搜索引擎返回结果为空? ### Q: Why do some search engines return empty results?
A: 可能原因: A: Possible reasons:
- 搜索引擎 API 临时不可用或响应超时 - Search engine API is temporarily unavailable or timed out
- 搜索关键词没有相关结果 - No relevant results for the search keyword
- 搜索引擎限制了访问频率 - Search engine has rate-limited access
- Google 需要配置 API Key 才能使用 - Google requires API Key configuration before use
可以查看返回的 `unresponsive_engines` 字段了解哪些引擎没有响应。 You can check the `unresponsive_engines` field in the response to see which engines did not respond.
### Q: 如何提高搜索速度? ### Q: How can I improve search speed?
A: 建议: A: Recommendations:
- 减少启用的搜索引擎数量,只使用需要的引擎 - Reduce the number of enabled search engines and only use the engines you need
- 适当调整超时时间(`DEFAULT_TIMEOUT` - Adjust timeout (`DEFAULT_TIMEOUT`) appropriately
### Q: Bing 搜索为什么默认禁用? ### Q: Why is Bing search disabled by default?
A: Bing 搜索结果目前不够稳定,出现内容与搜索关联度低的情况。如需使用,可以在请求时手动指定:`engines=bing` 或修改 `envs.js` 中的 `DEFAULT_ENGINES` A: Bing search results are currently not stable enough, and may return content with low relevance to the query. If needed, you can manually specify `engines=bing` in requests or modify `DEFAULT_ENGINES` in `envs.js`.
### Q: 如何保护服务不被滥用? ### Q: How can I protect the service from abuse?
A: 建议配置 `TOKEN` 环境变量启用鉴权: A: It is recommended to configure the `TOKEN` environment variable to enable authentication:
1. `wrangler.toml` 中设置 `TOKEN = "your-random-token"` 1. Set `TOKEN = "your-random-token"` in `wrangler.toml`
2. 或在 Cloudflare Dashboard 的 Environment Variables 中添加 2. Or add it in Environment Variables in Cloudflare Dashboard
3. 配置后所有请求都需要提供有效的 token 3. After configuration, all requests must provide a valid token
鉴权失败会返回 401 错误 Authentication failure returns a 401 error.
## 免责声明 ## Disclaimer
本项目仅供学习和研究使用,使用者需遵守以下规定: This project is for learning and research purposes only. Users must comply with the following:
1. **合法使用** - 仅用于合法搜索需求,不得用于违法或侵权用途 1. **Lawful Use** - Only use for legal search purposes. Do not use for illegal or infringing activities
2. **服务条款** - 使用时需遵守 Cloudflare Workers 和各搜索引擎的服务条款 2. **Terms of Service** - Comply with the terms of Cloudflare Workers and each search engine
3. **API 限制** - 遵守各搜索引擎 API 的使用限制和配额 3. **API Limits** - Follow usage limits and quotas of each search engine API
4. **责任自负** - 使用本服务产生的任何后果由使用者自行承担 4. **Use at Your Own Risk** - Any consequences from using this service are the user's responsibility
5. **商业用途** - 如需商业使用,请确保符合相关法律法规和服务条款 5. **Commercial Use** - For commercial use, ensure compliance with relevant laws, regulations, and service terms
## 贡献 ## Contributing
欢迎提交 Issue 和 Pull Request Issues and Pull Requests are welcome!
## 许可证 ## License
[GPL-3 License](LICENSE) [GPL-3 License](LICENSE)
## 相关链接 ## Related Links
- [项目 GitHub](https://github.com/Yrobot/cloudflare-search) - [Project GitHub](https://github.com/Yrobot/cloudflare-search)
- [Cloudflare Workers 文档](https://developers.cloudflare.com/workers/) - [Cloudflare Workers Docs](https://developers.cloudflare.com/workers/)
- [Google Custom Search API](https://developers.google.com/custom-search/v1/overview) - [Google Custom Search API](https://developers.google.com/custom-search/v1/overview)
## 支持一下 ## Support the Project
如果这个项目对你有帮助,可以请作者喝杯咖啡 If this project helps you, you can buy the author a coffee
<image src="https://yrobot.top/donate_wx.jpeg" width="300"/> <image src="https://yrobot.top/donate_wx.jpeg" width="300"/>

438
README.zh.md Normal file
View File

@@ -0,0 +1,438 @@
# Cloudflare Search
[English](./README.md) | 中文
> 基于 Cloudflare Workers 的聚合搜索 API 服务
> 支持 **MCP (Model Context Protocol)**,让 AI 助手OpenClaw、Claude Code、Codex、OpenCode拥有实时联网搜索能力
[![Deploy to Cloudflare Workers](https://deploy.workers.cloudflare.com/button)](https://sink.proddig.com/cloudflare-search-github)
## 特性
- 🔍 **多引擎聚合** - 同时使用多个搜索引擎Google、Brave、DuckDuckGo、Bing
- 🤖 **AI 增强 (MCP)** - 原生支持 Model Context Protocol一键为 **OpenClaw** / **Claude Code** / **Codex** 添加搜索工具
-**并行搜索** - 所有搜索引擎同时请求,快速返回结果
- 🛡️ **容错机制** - 单个引擎失败不影响其他引擎,自动标记无响应引擎
- ⏱️ **超时控制** - 可配置请求超时时间,避免长时间等待
- 🔒 **Token 鉴权** - 支持 Token 认证,保护服务不被滥用
- 🌍 **CORS 支持** - 完整的跨域资源共享支持
- 🎨 **Web 界面** - 提供简洁的搜索界面,方便测试
-**零成本运行** - Cloudflare Workers 免费版每天 10 万次请求
## 页面展示
![screenshot](./screenshot.png)
## MCP 集成, 在 OpenClaw / Claude Code / AI Agent 中使用
通过 MCP (Model Context Protocol) 让 AI 助手直接调用你的搜索服务,获取实时搜索结果。
### 安装配置
#### 1. 部署服务
先按照文档 [部署 Cloudflare Search](#安装方式)
#### 2. 添加 MCP 服务器配置
编辑配置文件([配置指南](https://modelcontextprotocol.io/quickstart/user)
- **OpenClaw**: `~/.openclaw/openclaw.json`
- **Claude Code**: `~/.claude/config.json` / `~/.claude.json`
- **Claude Desktop macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Claude Desktop Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
```json
{
"mcpServers": {
"cloudflare-search": {
"command": "npx",
"args": ["-y", "@yrobot/cf-search-mcp"],
"env": {
"CF_SEARCH_URL": "https://your-worker.workers.dev",
"CF_SEARCH_TOKEN": "your-token-here"
}
}
}
}
```
**环境变量说明**
- `CF_SEARCH_URL`: Worker 部署地址(必填)
- `CF_SEARCH_TOKEN`: 鉴权 Token如果 Worker 配置了 TOKEN 则必填)
#### 3. 验证安装
- **OpenClaw**: `openclaw gateway restart` + `openclaw mcp list` 能看到 `cloudflare-search`
- **Claude Code**:
- 在 Claude Code 中运行 `/mcp` 命令,应该能看到 `cloudflare-search` 工具。
- 或 使用 `claude mcp list`, 看到 `cloudflare-search: npx -y @yrobot/cf-search-mcp@latest - ✓ Connected` 说明配置成功
## 安装方式
### 方式一:一键部署(推荐)
点击上方 "Deploy to Cloudflare Workers" 按钮,按照提示完成部署。
### 方式二:使用 Wrangler CLI
```bash
# 1. 安装 Wrangler
npm install -g wrangler
# 2. 登录 Cloudflare
wrangler login
# 3. 克隆仓库
git clone https://github.com/Yrobot/cloudflare-search.git
cd cloudflare-search
# 4. 部署
wrangler deploy
```
### 方式三:使用 Cloudflare Dashboard
1. 登录 [Cloudflare Dashboard](https://dash.cloudflare.com/)
2. 进入 **Workers & Pages**
3. 点击 **Create Application** > **Create Worker**
4. 点击 **Upload** 上传本地代码文件夹
- 选择克隆的 `cloudflare-search` 文件夹
- 或者手动复制 `worker.js``envs.js``utils/` 等文件
5. 点击 **Save and Deploy**
### 获取访问地址
部署成功后,你会获得一个 Worker URL
```
https://your-worker-name.your-subdomain.workers.dev
```
**注意**:这个自带的域名在某些区域可能无法直接访问,建议绑定自己的域名使用。
## 使用方式
### 方式 1: Web 界面
直接访问你的 Worker URL在网页界面输入搜索关键词
```
https://$YOUR-DOMAIN/
```
### 方式 2: API 请求GET
使用查询参数进行搜索:
```bash
# 基本搜索
curl "https://$YOUR-DOMAIN/search?q=cloudflare"
# 指定搜索引擎
curl "https://$YOUR-DOMAIN/search?q=cloudflare&engines=google,brave"
# 使用 token 鉴权(如果配置了 TOKEN 环境变量)
curl "https://$YOUR-DOMAIN/search?q=cloudflare&token=$YOUR-TOKEN"
```
### 方式 3: API 请求POST
通过 POST 表单提交搜索:
```bash
curl -X POST "https://$YOUR-DOMAIN/search" \
-d "q=cloudflare" \
-d "engines=google,brave"
-d "token=$YOUR-TOKEN" # 如果配置了 TOKEN 环境变量
```
## API 接口说明
### `/search` 接口
用于执行搜索查询并返回聚合结果。
#### 请求参数
| 参数 | 类型 | 必填 | 说明 | 示例 |
| ------------- | -------- | ------ | ----------------------------------------- | -------------- |
| `q` / `query` | `string` | yes | 搜索关键词 | `cloudflare` |
| `engines` | `string` | no | 指定搜索引擎,多个用逗号分隔 | `google,brave` |
| `token` | `string` | no/yse | 访问令牌(当配置了 TOKEN 环境变量时必填) | `$YOUR-TOKEN` |
**支持的搜索引擎**
- `google` - Google 搜索(需要配置 API Key
- `brave` - Brave 搜索
- `duckduckgo` - DuckDuckGo 搜索
- `bing` - Bing 搜索
#### 返回值
```typescript
{
query: string; // 搜索关键词
number_of_results: number; // 结果总数
enabled_engines: string[]; // 启用的搜索引擎列表
unresponsive_engines: string[]; // 无响应的搜索引擎列表
results: Array<{
title: string; // 结果标题
description: string; // 结果描述
url: string; // 结果链接
engine: string; // 来源引擎
}>;
}
```
#### 请求示例
```bash
# GET 请求
curl "https://$YOUR-DOMAIN/search?q=cloudflare&engines=google,brave"
# POST 请求
curl -X POST "https://$YOUR-DOMAIN/search" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "q=cloudflare&engines=google,brave"
```
#### 响应示例
```json
{
"query": "cloudflare",
"number_of_results": 15,
"enabled_engines": ["google", "brave", "duckduckgo"],
"unresponsive_engines": [],
"results": [
{
"title": "Cloudflare - The Web Performance & Security Company",
"description": "Cloudflare is on a mission to help build a better Internet...",
"url": "https://www.cloudflare.com/",
"engine": "google"
},
{
"title": "Cloudflare Workers",
"description": "Deploy serverless code instantly across the globe...",
"url": "https://workers.cloudflare.com/",
"engine": "brave"
}
]
}
```
## 搜索引擎说明
### 支持的搜索引擎
| 引擎 | 说明 | 是否需要配置 | 默认启用 |
| -------------- | ------------------------ | ----------------------------- | --------------- |
| **Google** | Google Custom Search API | 需要 GOOGLE_API_KEY GOOGLE_CX | yes |
| **Brave** | Brave Search API | - | yes |
| **DuckDuckGo** | DuckDuckGo 即时答案 API | - | yes |
| **Bing** | Bing 搜索 | - | no (结果不稳定) |
### 基本工作方案
1. **并行请求**:所有启用的搜索引擎同时发起请求,提高响应速度
2. **超时控制**:单个引擎超时不影响其他引擎,默认 3 秒超时
3. **结果聚合**:将所有成功返回的结果合并,标记来源引擎
4. **容错处理**:记录无响应的引擎,返回部分结果而不是完全失败
## 环境变量配置
### 环境变量说明
| 变量名 | 类型 | 默认值 | 说明 |
| ----------------- | -------- | -------- | ------------------------------------------------- |
| `DEFAULT_TIMEOUT` | `string` | `"3000"` | 单个搜索引擎的超时时间(毫秒) |
| `GOOGLE_API_KEY` | `string` | `null` | https://console.cloud.google.com/apis/credentials |
| `GOOGLE_CX` | `string` | `null` | https://programmablesearchengine.google.com/ |
| `TOKEN` | `string` | `null` | 访问令牌,配置后启用鉴权,保护服务不被滥用 |
**注意**
- Google Custom Search API 免费版每天限制 100 次请求
- `TOKEN` 配置后,所有请求都需要提供有效的 token
### 配置方式
#### 方式 1: wrangler.toml 文件
编辑 `wrangler.toml` 文件中的 `[vars]` 部分:
```toml
[vars]
GOOGLE_API_KEY = "your-google-api-key"
GOOGLE_CX = "your-google-custom-search-cx"
DEFAULT_TIMEOUT = "3000"
TOKEN = "your-secret-token-here"
```
#### 方式 2: Cloudflare Dashboard
1. 进入 Worker 设置页面
2. 找到 **Environment Variables** 部分
3. 添加变量并保存
## 使用场景
### 1. 聚合搜索服务
构建自己的搜索聚合 API整合多个搜索引擎结果
```javascript
const response = await fetch(
"https://$YOUR-DOMAIN/search?q=javascript&engines=google,brave",
);
const data = await response.json();
console.log(`找到 ${data.number_of_results} 个结果`);
```
### 2. 前端搜索功能
为网站或应用添加搜索功能:
```javascript
async function search(query) {
const response = await fetch(
`https://$YOUR-DOMAIN/search?q=${encodeURIComponent(query)}`,
);
const data = await response.json();
return data.results;
}
```
### 3. 数据采集与分析
收集多个搜索引擎的结果进行对比分析:
```javascript
const engines = ["google", "brave", "duckduckgo"];
const results = await fetch(
`https://$YOUR-DOMAIN/search?q=AI&engines=${engines.join(",")}`,
);
const data = await results.json();
// 按引擎分组
const byEngine = data.results.reduce((acc, result) => {
acc[result.engine] = acc[result.engine] || [];
acc[result.engine].push(result);
return acc;
}, {});
```
## MCP 集成
通过 MCP (Model Context Protocol) 让 AI 助手直接调用你的搜索服务,获取实时搜索结果。
## 注意与提醒
### 🚨 重要提示
1. **使用自定义域名**
- Cloudflare 默认的 `*.workers.dev` 域名在某些地区可能无法访问
- **强烈建议**绑定自己的域名以获得更好的访问体验
- 在 Worker 设置中点击 **Triggers** > **Add Custom Domain** 添加自定义域名
2. **搜索引擎限制**
- Google API 免费版每天限制 100 次请求
- 其他搜索引擎一般没有严格限制,但请合理使用
- 频繁请求可能导致被临时限制访问
3. **超时设置**
- 默认单个引擎超时 3 秒
- 可通过环境变量 `DEFAULT_TIMEOUT` 调整
- 建议不要设置过长,避免整体响应时间过长
### 🔒 安全配置
#### 启用鉴权
1. 配置 `TOKEN` 环境变量 来保护你的服务不被滥用:
- 利用 wrangler.toml 配置 TOKEN 环境变量
- 通过 Cloudflare Worker Dashboard 配置 TOKEN 环境变量
2. 在请求时传入 token
```bash
# 访问首页
https://$YOUR-DOMAIN?token=$YOUR-TOKEN
# 使用 query/body 的 token 参数 请求 API
curl "https://$YOUR-DOMAIN/search?q=cloudflare&token=$YOUR-TOKEN"
curl -X POST "https://$YOUR-DOMAIN/search" \
-d "q=cloudflare" \
-d "token=$YOUR-TOKEN"
```
## 常见问题
### Q: 为什么有些搜索引擎返回结果为空?
A: 可能原因:
- 搜索引擎 API 临时不可用或响应超时
- 搜索关键词没有相关结果
- 搜索引擎限制了访问频率
- Google 需要配置 API Key 才能使用
可以查看返回的 `unresponsive_engines` 字段了解哪些引擎没有响应。
### Q: 如何提高搜索速度?
A: 建议:
- 减少启用的搜索引擎数量,只使用需要的引擎
- 适当调整超时时间(`DEFAULT_TIMEOUT`
### Q: Bing 搜索为什么默认禁用?
A: Bing 搜索结果目前不够稳定,出现内容与搜索关联度低的情况。如需使用,可以在请求时手动指定:`engines=bing` 或修改 `envs.js` 中的 `DEFAULT_ENGINES`
### Q: 如何保护服务不被滥用?
A: 建议配置 `TOKEN` 环境变量启用鉴权:
1.`wrangler.toml` 中设置 `TOKEN = "your-random-token"`
2. 或在 Cloudflare Dashboard 的 Environment Variables 中添加
3. 配置后所有请求都需要提供有效的 token
鉴权失败会返回 401 错误
## 免责声明
本项目仅供学习和研究使用,使用者需遵守以下规定:
1. **合法使用** - 仅用于合法搜索需求,不得用于违法或侵权用途
2. **服务条款** - 使用时需遵守 Cloudflare Workers 和各搜索引擎的服务条款
3. **API 限制** - 遵守各搜索引擎 API 的使用限制和配额
4. **责任自负** - 使用本服务产生的任何后果由使用者自行承担
5. **商业用途** - 如需商业使用,请确保符合相关法律法规和服务条款
## 贡献
欢迎提交 Issue 和 Pull Request
## 许可证
[GPL-3 License](LICENSE)
## 相关链接
- [项目 GitHub](https://github.com/Yrobot/cloudflare-search)
- [Cloudflare Workers 文档](https://developers.cloudflare.com/workers/)
- [Google Custom Search API](https://developers.google.com/custom-search/v1/overview)
## 支持一下
如果这个项目对你有帮助,可以请作者喝杯咖啡 ☕
<image src="https://yrobot.top/donate_wx.jpeg" width="300"/>

View File

@@ -24,7 +24,9 @@ const CF_SEARCH_TOKEN = process.env.CF_SEARCH_TOKEN;
if (!CF_SEARCH_URL) { if (!CF_SEARCH_URL) {
console.error("Error: CF_SEARCH_URL environment variable is required"); console.error("Error: CF_SEARCH_URL environment variable is required");
console.error("Example: export CF_SEARCH_URL=https://your-worker.workers.dev"); console.error(
"Example: export CF_SEARCH_URL=https://your-worker.workers.dev",
);
process.exit(1); process.exit(1);
} }
@@ -64,46 +66,57 @@ async function searchAPI(query, engines = null) {
const server = new Server( const server = new Server(
{ {
name: "cloudflare-search", name: "cloudflare-search",
version: "1.0.0", version: "1.1.0",
}, },
{ {
capabilities: { capabilities: {
tools: {}, tools: {},
}, },
} },
); );
const SEARCH_INPUT_SCHEMA = {
type: "object",
properties: {
query: {
type: "string",
description: "The search query string",
},
engines: {
type: "array",
items: {
type: "string",
enum: ["google", "brave", "duckduckgo", "bing"],
},
description:
"Optional: Array of search engines to use. If not specified, uses default engines. " +
"Available engines: google, brave, duckduckgo, bing",
},
},
required: ["query"],
};
/** /**
* Handler for listing available tools * Handler for listing available tools
*/ */
server.setRequestHandler(ListToolsRequestSchema, async () => { server.setRequestHandler(ListToolsRequestSchema, async () => {
return { return {
tools: [ tools: [
{
name: "web_search",
description:
"Search the web for current information, news, or any topic. " +
"Uses multiple engines (Brave, DuckDuckGo, Google, Bing) simultaneously " +
"and returns aggregated results with source URLs. " +
"Use this when you need real-time information not in your training data. ",
inputSchema: SEARCH_INPUT_SCHEMA,
},
{ {
name: "search", name: "search",
description: description:
"Search across multiple search engines (Google, Brave, DuckDuckGo, Bing) and return aggregated results. " + "Search across multiple search engines (Google, Brave, DuckDuckGo, Bing) and return aggregated results. " +
"This tool provides comprehensive search results from multiple sources, with source attribution for each result.", "This tool provides comprehensive search results from multiple sources, with source attribution for each result.",
inputSchema: { inputSchema: SEARCH_INPUT_SCHEMA,
type: "object",
properties: {
query: {
type: "string",
description: "The search query string",
},
engines: {
type: "array",
items: {
type: "string",
enum: ["google", "brave", "duckduckgo", "bing"],
},
description:
"Optional: Array of search engines to use. If not specified, uses default engines. " +
"Available engines: google, brave, duckduckgo, bing",
},
},
required: ["query"],
},
}, },
], ],
}; };
@@ -113,7 +126,10 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
* Handler for tool execution * Handler for tool execution
*/ */
server.setRequestHandler(CallToolRequestSchema, async (request) => { server.setRequestHandler(CallToolRequestSchema, async (request) => {
if (request.params.name !== "search") { if (
request.params.name !== "search" &&
request.params.name !== "web_search"
) {
throw new Error(`Unknown tool: ${request.params.name}`); throw new Error(`Unknown tool: ${request.params.name}`);
} }

View File

@@ -1,6 +1,6 @@
{ {
"name": "@yrobot/cf-search-mcp", "name": "@yrobot/cf-search-mcp",
"version": "1.0.0", "version": "1.1.0",
"description": "MCP server for Cloudflare Search API - Aggregated search across multiple engines", "description": "MCP server for Cloudflare Search API - Aggregated search across multiple engines",
"type": "module", "type": "module",
"publishConfig": { "publishConfig": {
@@ -16,8 +16,15 @@
"keywords": [ "keywords": [
"mcp", "mcp",
"search", "search",
"web-search",
"cloudflare", "cloudflare",
"api", "cloudflare-workers",
"self-hosted",
"ai-agent",
"openclaw",
"free-search",
"privacy",
"aggregated-search",
"google", "google",
"brave", "brave",
"duckduckgo", "duckduckgo",