使用说明
MCP研究服务器
基于FastMCP的研究服务器,支持MCP(模型上下文协议),用于统一搜索、抓取和清理LLM就绪输出。可通过自动HTTPS的Tailscale VPN远程访问。
特性
- FastMCP服务器:用于Claude Desktop、Claude Code和其他MCP客户端的SSE传输
- Tailscale集成:通过MagicDNS自动HTTPS(例如。,
https://mcp-server.tailb1e597.ts.net) - 多页搜索:SearXNG(Brave、Bing、DuckDuckGo、Ask),10页分页
- 智能刮擦:Crawl4AI(快速)→ 硒基地(隐形后备)→ 黑名单
- PDF支持:使用PyMuPDF从PDF文件下载和提取文本
- 域速率限制:Redis支持并发请求限制
- 清洁输出:ContentCleaner,具有LLM就绪标记的优先级提取功能
- 领域学习:PostgreSQL跟踪每个域的工作方法
- 文档工具:本地FastMCP工具,用于将任何URL作为干净的Markdown获取
- Redis缓存:用于搜索、抓取和文档的响应处理中间件
- 错误处理:输入验证、ToolError异常、隐藏的内部错误
- VPN/代理网关:Gluetun容器路由全部通过WireGuard VPN隧道
- 代理管理:用于代理状态、测试和轮换的运行时工具
- Caddy反向代理:具有自动TLS的专业部署
建筑
┌─────────────────────────────────────────┐
│ Caddy (ports 80/443) │
│ Tailscale TLS via shared socket │
└──────────────┬──────────────────────────┘
│ Docker DNS (mcp_net)
┌──────────────▼──────────────────────────┐
│ mcp-server (SSE on :8000) │
│ ┌────────────────────────────────┐ │
│ │ Web Tools: │ │
│ │ • search_web │ │
│ │ • scrape_url │ │
│ │ • get_domains │ │
│ │ • clean_database │ │
│ └────────────────────────────────┘ │
│ ┌────────────────────────────────┐ │
│ │ Docs (native, namespace: docs_) │ │
│ │ • docs_list_sources │ │
│ │ • docs_fetch_docs │ │
│ └────────────────────────────────┘ │
└──────────────┬──────────────────────────┘
│
┌─────────────────────┼─────────────────────┐
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ PostgreSQL │ │ Redis │ │ SearXNG │
│ (domains) │ │ (cache) │ │ (search) │
└──────────────┘ └──────────────┘ └──────────────┘
│
┌───────────────┼──────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Worker │ │ Beat │ │ Flower │
│(Celery) │ │(schedule)│ │(monitor) │
└──────────┘ └──────────┘ └──────────┘
External Traffic (scrape/search):
┌──────────┐ HTTP ┌──────────┐ WireGuard ┌───────────┐
│ MCP / │ ────────► │ Gluetun │ ──────────► │ Internet │
│ Celery │ :8888 │ (VPN) │ │ │
└──────────┘ └──────────┘ └───────────┘
Internal Traffic (postgres, redis, searxng):
┌──────────┐ direct ┌──────────────┐
│ MCP / │ ────────► │ Internal │
│ Celery │ │ services │
└──────────┘ └──────────────┘
快速开始
1.先决条件
- Docker和Docker Compose
- Tailscale帐户(用于远程访问)
2.配置环境
# Copy example env file
cp .env.example .env
# Edit .env with your values:
# - TS_AUTHKEY: Get from https://login.tailscale.com/admin/settings/keys
# - TAILNET_DOMAIN: Your tailnet domain (e.g., tailb1e597.ts.net)
# - TAILNET_MACHINE_NAME: Your Tailscale machine name (e.g., mcp-server)
3.启动服务
docker compose up -d
4.通过Tailscale连接
Tailscale运行后,您的MCP服务器可以在以下位置访问:
https://<TAILNET_MACHINE_NAME>.<TAILNET_DOMAIN>/sse
例子: https://gtek.tailb1e597.ts.net/sse
连接客户
克劳德代码(CLI)
claude mcp add --transport http research https://gtek.tailb1e597.ts.net/sse
用您实际的Tailscale MagicDNS URL替换该URL。
克劳德桌面版
添加到您的Claude Desktop配置中:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
窗户: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"research": {
"transport": "sse",
"url": "https://gtek.tailb1e597.ts.net/sse",
"timeout": 120000
}
}
}
其他MCP客户端
任何兼容MCP的客户端都可以通过SSE传输连接到您的Tailscale HTTPS URL。
本地访问 (仅限同一台机器):
- MCP服务器:
http://localhost:8327/sse - 花卉仪表板:
http://localhost:5921 - VPN代理:
http://localhost:8328
可用工具
网络研究(无前缀)
| 工具 | 说明 |
|---|---|
search_web |
使用多个搜索引擎搜索网络 |
scrape_url |
删除URL并提取干净的标记 |
map_domain |
从站点地图中发现URL/通用爬网(URL发现) |
crawl_site |
使用BFS策略进行深度爬行(以下链接) |
scrape_structured |
使用预构建的模式提取结构化JSON数据 |
list_schemas |
列出可用的提取模式 |
get_domains |
使用首选方法列出跟踪的域 |
clean_database |
清除所有域跟踪数据 |
文档(前缀: docs_)
| 工具 | 说明 |
|---|---|
docs_list_sources |
列出可用的文档库 |
docs_fetch_docs |
从任何URL获取文档(缓存,清理为Markdown) |
代理管理
| 工具 | 说明 |
|---|---|
proxy_status |
显示当前代理配置和轮换统计信息 |
proxy_test |
测试代理连接并报告出口IP与真实IP |
proxy_rotate |
手动旋转到旋转列表中的下一个代理 |
结构化数据抽取
这 scrape_structured 该工具使用预构建的CSS模式从网页中提取结构化JSON——不需要LLM,更快、更便宜。
架构类型
| 架构 | 提取 |
|---|---|
ecommerce |
产品(名称、价格、评级、可用性、图片、网址、sku) |
news |
文章(标题、作者、日期、内容、类别、摘要) |
jobs |
列表(职位、公司、地点、工资、描述、类型) |
blog |
帖子(标题、作者、日期、内容、标签、摘录) |
social |
社交帖子(用户名、内容、时间戳、点赞、分享) |
products |
产品目录多项目提取 |
使用示例
# Extract products from an e-commerce page
scrape_structured(
url="https://shop.example.com/products",
schema_type="ecommerce"
)
# Returns: {"items": [{"title": "...", "price": "$99", "rating": "4.5", ...}]}
# Extract job listings
scrape_structured(
url="https://jobs.example.com",
schema_type="jobs"
)
# Returns: {"items": [{"title": "Engineer", "company": "...", "salary": "...", ...}]}
# Extract with custom selector
scrape_structured(
url="https://news.example.com",
schema_type="news",
custom_selector=".article-list article" # Override base selector
)
何时使用scrape_structured与scrape_url
| 在以下情况下使用scrap_structured。.. | 在以下情况下使用scrap_url。.. |
|---|---|
| 您需要结构化的JSON数据 | 您需要完整的页面内容 |
| 提取特定字段(产品、作业) | 阅读文章、文档 |
| 构建数据集/分析 | 通用抓取 |
| 页面结构一致 | 页面结构未知 |
映射和爬网工作流
新的 map_domain 和 crawl_site 工具支持智能网站探索:
1.映射域(URL发现)
# Discover all blog posts from a site
map_domain(
domain="blog.example.com",
source="sitemap", # or "cc" for Common Crawl, "sitemap+cc" for both
pattern="*/posts/*", # Filter by URL pattern
max_urls=1000, # Maximum URLs to return
extract_head=True # Extract metadata (slower but richer)
)
# Relevance-based discovery
map_domain(
domain="docs.example.com",
source="sitemap",
query="API reference endpoints",
score_threshold=0.5, # Minimum BM25 relevance score
scoring_method="bm25"
)
来源:
sitemap:快速XML站点地图解析(每秒100-1000个URLs)cc:通用爬网数据集(历史索引)sitemap+cc:两个来源均可实现最大覆盖
2.爬行站点(深度爬行)
# Crawl documentation with depth limit
crawl_site(
url="https://docs.example.com",
max_depth=2, # Follow links 2 levels deep
max_pages=50, # Maximum pages to crawl
pattern="*/api/*", # Filter by URL pattern
word_count_threshold=100 # Skip short pages
)
战略:
- BFS(广度优先搜索)用于系统探索
- 尊重
max_depth(链接级别)和max_pages(总页数) - 可以按URL模式和字数进行过滤
- 返回每个已爬网页面的完整内容
典型工作流程
# Step 1: Discover URLs
result = map_domain(domain="python.langchain.com", pattern="*/docs/*")
# Step 2: Review discovered URLs
for url_info in result["urls"]:
print(url_info["url"], url_info.get("title", ""))
# Step 3: Deep crawl for full content
crawl_result = crawl_site(
url="https://python.langchain.com/docs/",
max_depth=2,
max_pages=20
)
# Step 4: Process crawled pages
for page in crawl_result["pages"]:
print(page["title"], len(page.get("content", "")))
Docker服务
| 容器 | 用途 | 资源 |
|---|---|---|
| mcp-caddy | 带自动TLS的反向代理 | - |
| mcp服务器 | 带SSE传输的FastMCP服务器 | 512MB限制 |
| mcp-celery worker | Scrapeng worker(10个并行浏览器) | 3GB限制,2个CPU |
| mcp芹菜节拍 | 定期任务调度程序 | 256MB限制 |
| mcp-flower | 芹菜监控(本地主机:5555) | 256MB限制 |
| mcp-postgres | 域跟踪数据库 | 512MB限制 |
| mcp-redis | 缓存+速率限制 | 256MB限制 |
| mcp searxng | 多引擎搜索 | 512MB限制 |
| mcp vpn | Gluetun vpn网关(HTTP代理) | 256MB限制 |
| mcp-ts | 尾车(主机网络) | - |
VPN/代理设置
通过WireGuard VPN隧道通过 胶屯 集装箱。你的真实IP永远不会暴露在被抓取的网站上。
它是如何工作的:
- Gluetun通过WireGuard连接到VPN服务器
- 它在以下位置公开了一个HTTP代理
gluetun:8888在Docker网络上 - MCP服务器和Celery worker通过此代理路由所有外部HTTP流量
- 内部服务(Postgres、Redis、SearXNG)直接连接——它们被排除在代理之外
如果VPN隧道中断,Gluetun的防火墙会阻止所有出站流量。您的真实IP没有退路。
设置
1.从您的VPN提供商处获取WireGuard凭据
大多数提供商(Proton VPN、Mullvad、Surfshark、NordVPN等)都允许您下载WireGuard .conf 文件。它看起来像:
[Interface]
PrivateKey = ABC123abc...
Address = 10.2.0.2/32
DNS = 10.2.0.1
[Peer]
PublicKey = XYZ789xyz...
Endpoint = 1.2.3.4:51820
AllowedIPs = 0.0.0.0/0
2.将值添加到您的 .env
WIREGUARD_PRIVATE_KEY=ABC123abc... # from [Interface] PrivateKey
WIREGUARD_ADDRESS=10.2.0.2/32 # from [Interface] Address
WIREGUARD_PUBLIC_KEY=XYZ789xyz... # from [Peer] PublicKey
WIREGUARD_ENDPOINT_IP=1.2.3.4 # from [Peer] Endpoint IP
WIREGUARD_ENDPOINT_PORT=51820 # from [Peer] Endpoint port
3.启动堆栈
docker compose up -d
4.验证它是否正常工作
使用 proxy_test MCP工具——它报告您的代理退出IP和您的真实IP。如果 ip_different: true,您的流量正在通过VPN。
代理旋转
要在多个代理(例如,不同的VPN服务器或代理池)之间轮换,请设置 MCP_PROXY_URLS 相反:
# Comma-separated list — rotates round-robin by default
MCP_PROXY_URLS=http://gluetun:8888,http://proxy2:8080,socks5://proxy3:1080
使用 proxy_rotate 手动前进到下一个代理,或 proxy_status 查看当前旋转状态。
高级配置
| 变量 | 默认值 | 描述 |
|---|---|---|
MCP_PROXY_URL |
http://gluetun:8888 |
单代理URL(HTTP或SOCKS5) |
MCP_PROXY_URLS |
(空) | 逗号分隔的列表用于轮换(覆盖 MCP_PROXY_URL) |
MCP_PROXY_ROTATION |
round-robin |
轮换策略: round-robin 或 random |
MCP_PROXY_EXCLUDE |
searxng,postgres,redis,localhost,127.0.0.1 |
绕过代理的主机名 |
禁用VPN
要在没有代理的情况下运行,请注释掉 gluetun 服务中 docker-compose.yml 并设置 MCP_PROXY_URL= (空)在你的 .env所有交通都将直达。
环境变量
看 .env.example 对于所有可配置值:
# Tailscale
TS_AUTHKEY=tskey-auth-<your-key>
TAILNET_DOMAIN=your-tailnet.ts.net
TAILNET_MACHINE_NAME=mcp-server
# PostgreSQL
POSTGRES_HOST=postgres
POSTGRES_DB=mcp_server
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
# SearXNG
SEARXNG_SECRET=<generate with: openssl rand -hex 32>
# Celery
CELERY_BROKER_URL=redis://redis:6379/0
CELERY_RESULT_BACKEND=redis://redis:6379/0
# API
MCP_PORT=8000
ALLOWED_ORIGINS=http://localhost:8000,http://127.0.0.1:8000
# VPN (WireGuard credentials from your VPN provider)
WIREGUARD_PRIVATE_KEY=<from your WireGuard config>
WIREGUARD_ADDRESS=10.2.0.2/32
WIREGUARD_PUBLIC_KEY=<from your WireGuard config>
WIREGUARD_ENDPOINT_IP=<server_ip>
WIREGUARD_ENDPOINT_PORT=51820
# Caching (seconds)
SEARCH_CACHE_TTL=300
SCRAPE_CACHE_TTL=3600
DOCS_CACHE_TTL=3600
报废流程
1. Check Cache → Return cached if available
2. Check Rate Limit → Wait if too many concurrent to domain
3. Check Blacklist → Reject if blacklisted
4. PDF? → Extract text with PyMuPDF
5. Reddit? → Use Reddit JSON API
6. Check Database → Use learned preference
7. Try Crawl4AI (3x retry, fast, JS-enabled)
8. If failed → Try Selenium (3x retry, stealth mode)
9. If both failed → Blacklist domain
10. Clean HTML → Waterfall strategy for universal scraping
内容提取优先级(瀑布策略):
- CSS选择器(如果提供)
- 瀑布 (Selectolax攻击性修剪+语义定位)
- 适用于所有页面类型:文章、SaaS、登录页、SPA
- 积极删除垃圾标签(脚本、样式、导航、页脚、表单等)
- 语义定位(
<main>,<article>,#content) - 混乱布局的全身回退
- Trafilatura(仅用于新闻/博客的文章回退)
- BeautifulSoup(核选项)
错误处理
服务器实现了符合FastMCP的错误处理:
- 输入验证:使用所有参数
Annotated[Field]有限制条件min_length/max_length对于字符串ge/le用于数值范围Literal用于枚举选择
- 用户面临错误:
ToolError用于客户端可见消息 - 内部错误:屏蔽客户端(安全),记录服务器端
- HTTP特定消息:404、403、500个错误返回有用的上下文
缓存
Redis支持的缓存,具有可配置的TTL:
# Cache TTL (seconds)
SEARCH_CACHE_TTL=300 # 5 minutes for search results
SCRAPE_CACHE_TTL=3600 # 1 hour for scraped content
DOCS_CACHE_TTL=3600 # 1 hour for documentation
缓存的响应包括元数据(使用的方法、时间戳)和绕过昂贵的操作。
文档来源
服务器包括以下官方文档:
- LangGraph -代理框架
- LangChain -LLM框架(python.langchain.com,docs.langchain.com)
- 深度智能体 -LangChain代理模式
- 快速API -Web框架
- 派丹蒂克 -数据验证(docs.pydantic.dev,ai.pydanic.dev)
- FastMCP -MCP框架(gofastmcp.com)
- 码头工人 -集装箱平台
- Next.js -React框架
- Vercel 人工智能 -React的AI SDK(AI SDK.dev)
添加更多内容 docs_config.yaml。llms.txt文件中链接的域会被自动发现并允许。
技术栈
- FastMCP -带SSE传输的MCP服务器框架
- 卡迪 -具有自动TLS的反向代理
- PostgreSQL -领域跟踪和学习
- Celery+Redis -任务队列和速率限制
- 瑟克斯NG -多引擎搜索
- Crawl4AI -支持快速JS的抓取、URL种子和深度爬行
- 硒基 -隐形刮擦回退
- ContentCleaner -多策略HTML→Markdown转换
- 胶屯 -带WireGuard和HTTP代理的VPN网关
- 尾鳞 -VPN+DNS裁判