使用说明
零高度mcp开发说明
关于git钩子和 debugger 规则。
胡克和赫斯基
- 这个仓库使用Husky来管理Git钩子。赫斯基是通过以下方式安装的
prepare脚本在package.json. - 开
npm install这prepare脚本运行husky install并激活钩子。
预承诺行为
- 预提交钩子运行暂存文件
debugger检查员和npm run lint. - 检查器是用TypeScript实现的,并使用
npx tsx因此,它无需单独的构建步骤即可运行。 - ESLint已配置
@eslint-community/eslint-plugin-eslint-comments禁止禁用@typescript-eslint/no-explicit-any规则;这是在npm run lint.
如何在本地启用
- 运行:
npm install
# (prepare runs automatically) or run explicitly:
npx husky install
- 进行更改并提交——预提交钩子将自动运行。
如果你更喜欢钩子,而不是只检查 debugger (更快),您可以删除 npm run lint 从 .husky/pre-commit.
支持文件
- 钩子脚本:
.husky/pre-commit(跑步npx tsx scripts/check-no-debugger.ts然后npm run lint) - 检查器:
scripts/check-no-debugger.ts
问题或更改
- 如果您希望以不同的方式执行钩子(例如,仅CI或其他检查),请告诉我如何更新钩子。
贡献
- 提交由Husky预提交钩子验证,该钩子运行分阶段的文件检查
debugger并奔跑npm run lint. - 一定要跑
npm install因此赫斯基在本地激活(prepare脚本运行husky install).
零高度MCP服务器
一个功能强大的模型上下文协议(MCP)服务器,可以抓取、索引Zeroheight设计系统文档,并为其提供智能查询功能。专为需要程序化访问其组件库和设计指南的设计系统团队而构建。
✨ 特性
- 智能刮擦:通过图像处理和重复数据删除,自动发现并抓取Zeroheight设计系统中的所有页面、组件和文档
- 强大的搜索功能:通过灵活的查询选项和完整的Supabase图像存储URL,在标题、内容和URL之间进行全文搜索
- MCP集成:基于模型上下文协议,与人工智能助手和设计工具无缝集成
- 图像管理:使用基于MD5的重复数据消除自动下载、处理和存储设计系统映像
- 数据库工具:查询和管理缓存的Zeroheight数据(安全、非破坏性操作)。
- 安全访问:带有API密钥验证的企业级身份验证
- 高性能:针对批量数据库操作和高效缓存的速度进行了优化
�️ 图像管理
刮刀通过智能过滤和优化自动处理图像处理:
支持的图像类型
- 支持:PNG、JPG/JPEG、WebP、GIF、SVG
- 过滤掉:GIF和SVG格式被排除在处理之外,以专注于静态设计资产
上传过程
- 图像从Zeroheight下载并上传到Supabase存储桶
- 每个映像都基于MD5哈希获得一个唯一的路径,以实现高效的重复数据删除
- 查询结果包括用于直接访问的完整Supabase存储URL
防止重复
- MD5哈希确保相同的图像不会被上传两次
- 检测现有图像并重复使用,而不是重新上传
- 通过智能重复数据删除将存储成本降至最低
图像优化
- 格式转换:为了保持一致性,所有图像都转换为JPEG格式
- 质量下降:图像质量降低到80%,以平衡文件大小和视觉质量
- 分辨率限制:图像最长边的最大尺寸调整为1920px
- 宽高比保持:调整大小时保持原始纵横比
🔍 页面发现和重定向处理
scraper智能地发现和处理页面,同时防止重复内容:
页面发现
- 从配置的Zeroheight项目URL开始
- 自动查找同一域内的所有链接页面
- 发现两个直接页面链接(
/p/page-slug)和导航链接 - 在处理每个页面时继续发现新链接
重定向检测
- 导航到每个URL后,检查最终目标URL
- 检测URL何时重定向到其他页面(常见于Zeroheight)
- 使用最终URL而不是原始重定向URL进行存储
防止重复
- 维护一组已处理的URL,以避免重新处理相同的内容
- 当重定向指向已处理的页面时,将完全跳过处理
- 进度计数器仅对实际处理的唯一页面进行增量
- 数据库存储使用追加销售操作来处理任何剩余的重复项
📋 控制台输出示例
以下是运行scraper时控制台输出的示例:
[dotenv@17.2.4] injecting env (5) from .env.local
Starting Zeroheight project scrape...
Navigating to https://designsystem.lruddannelse.dk...
Password provided, checking for login form...
Found password input field, entering password...
Password entered, waiting for login to process...
Current URL after password entry: https://designsystem.lruddannelse.dk/10548dffa/p/3441e1-lindhardt-og-ringhof-uddannelse-design-system
Password input no longer visible - login appears successful
Found 23 navigation links after login attempt
Final URL after loading: https://designsystem.lruddannelse.dk/10548dffa/p/3441e1-lindhardt-og-ringhof-uddannelse-design-system
Page title: Lindhardt og Ringhof Uddannelse Design System
Content container found: true
Body text length: 51103 characters
Project URL: https://designsystem.lruddannelse.dk
Allowed hostname: designsystem.lruddannelse.dk
Found 29 total raw links on page
Sample raw links: https://designsystem.lruddannelse.dk/10548dffa/p/10548dffa, https://designsystem.lruddannelse.dk/10548dffa/n/326d4d, ...
Found 0 links on main page
Found 0 Zeroheight page links (/p/ pattern)
Sample ZH page links:
Current page URL: https://designsystem.lruddannelse.dk/10548dffa/p/3441e1-lindhardt-og-ringhof-uddannelse-design-system
Total unique links to process: 1
[████████████████████] Processing page 1/3: https://designsystem.lruddannelse.dk/10548dffa/p/3441e1-lindhardt-og-ringhof-uddannelse-design-system
Discovered new link: https://designsystem.lruddannelse.dk/10548dffa/p/10548dffa
Discovered new link: https://designsystem.lruddannelse.dk/10548dffa/n/326d4d
Discovered new link: https://designsystem.lruddannelse.dk/10548dffa/n/52db31
... (more discovered links)
Redirect detected: https://designsystem.lruddannelse.dk/10548dffa/p/10548dffa -> https://designsystem.lruddannelse.dk/10548dffa/p/3441e1-lindhardt-og-ringhof-uddannelse-design-system
Skipping https://designsystem.lruddannelse.dk/10548dffa/p/10548dffa - final URL https://designsystem.lruddannelse.dk/10548dffa/p/3441e1-lindhardt-og-ringhof-uddannelse-design-system already processed
Redirect detected: https://designsystem.lruddannelse.dk/10548dffa/n/326d4d -> https://designsystem.lruddannelse.dk/10548dffa/p/256325-introduktion-til-lindhardt-og-ringhof-uddannelse
[█████████████░░░░░░░] Processing page 2/3: https://designsystem.lruddannelse.dk/10548dffa/p/256325-introduktion-til-lindhardt-og-ringhof-uddannelse
... (more processing output)
[████████████████████] Processing page 3/3: https://designsystem.lruddannelse.dk/10548dffa/p/321296-brandfortlling
Collected 3 pages for bulk insertion
Successfully inserted 3 pages
[██░░░░░░░░░░░░░░░░░░] Processing image 1/13: ze9jax4wepR4ylr5_4944A.png
[███░░░░░░░░░░░░░░░░░] Processing image 2/13: yoh8TcjKEP4TGKC6F3A9wQ.png
... (image processing continues)
Successfully inserted 2 images
Scraping completed successfully
输出说明
- 导航和身份验证:显示登录过程和初始页面加载
- 链接发现:列出新发现的链接
- 重定向检测:标识URL重定向和跳过重复项的时间
- 进度跟踪:显示页面处理状态的视觉进度条
- 图像处理:优化和上传每个图像的个人进度
- 最终总结:报告已成功处理的总页数和图像数
�🚀 快速开始
先决条件
- Node.js 18+和npm
- Zeroheight设计系统项目URL
- 用于身份验证的API密钥
安装
-
克隆存储库:
git clone https://github.com/drexxdk/zeroheight-mcp.git cd zeroheight-mcp -
安装依赖项:
npm install -
配置环境变量:
cp .env.example .env.local编辑
.env.local与您的Zeroheight项目详细信息:ZEROHEIGHT_PROJECT_URL=https://your-project.zeroheight.com/p/project-id ZEROHEIGHT_PROJECT_PASSWORD=your-password-if-required ZEROHEIGHT_MCP_ACCESS_TOKEN=your-secure-api-key
注意:这些环境变量被加载到运行时中 config 对象在启动时可用,并可用于服务器端代码 config.env.ZEROHEIGHT_* 等效物(例如。 config.env.zeroheightMcpAccessToken).代码库中的调用站点应该更喜欢导入中心 config 并从以下位置读取值 config.env.
-
启动开发服务器:
npm run dev -
测试设置:
npm run test-api
🔧 配置
环境变量
| 变量 | 描述 | 必填 |
|---|---|---|
ZEROHEIGHT_PROJECT_URL |
要抓取的Zeroheight项目的URL | 是 |
ZEROHEIGHT_PROJECT_PASSWORD |
项目受保护时的密码 | 否 |
ZEROHEIGHT_MCP_ACCESS_TOKEN |
用于服务器身份验证的API密钥 | 是(生产版) |
MCP客户端配置
复制您首选设置的MCP配置:
地方发展:
{
"mcpServers": {
"zeroheight-scraper": {
"command": "npx",
"args": ["mcp-remote", "http://localhost:3000/api/mcp"],
"env": {
"ZEROHEIGHT_MCP_ACCESS_TOKEN": "your-api-key-here"
}
}
}
}
生产(Vercel):
{
"mcpServers": {
"zeroheight-scraper": {
"command": "npx",
Note: for PowerShell users, quoting JSON args can be tricky. Example usages:
PowerShell (prompting for key):
```powershell
$k = Read-Host -AsSecureString "Enter MCP API key" | ConvertFrom-SecureString
"args": [
$env:ZEROHEIGHT_MCP_ACCESS_TOKEN = (ConvertTo-SecureString $k -AsPlainText -Force)
npm run mcp:clear
PowerShell(内联JSON参数):
"mcp-remote",
# Use your editor's MCP integration or call the MCP API directly with appropriate headers and JSON-RPC body
# Example: POST to https://zeroheight-mcp.vercel.app/api/mcp with Authorization header and Accept: application/json, text/event-stream
"--header",
Direct calls (server-first)
You can call MCP tools directly without the wrapper. Use an Authorization header or `X-API-Key` header matching the server's `ZEROHEIGHT_MCP_ACCESS_TOKEN`.
List tools (Node):
```bash
node -e "const k=process.env.ZEROHEIGHT_MCP_ACCESS_TOKEN; (async()=>{try{const res=await fetch('http://localhost:3000/api/mcp',{method:'POST',headers:{'Content-Type':'application/json','Accept':'application/json, text/event-stream','Authorization':'Bearer '+k},body:JSON.stringify({jsonrpc:'2.0',id:1,method:'tools/list',params:{}})});console.log(await res.text());}catch(e){console.error(e);} })()"
```
Call a tool (Node) — `clear-database` example (destructive):
```bash
node -e "const k=process.env.ZEROHEIGHT_MCP_ACCESS_TOKEN; (async()=>{try{const res=await fetch('http://localhost:3000/api/mcp',{method:'POST',headers:{'Content-Type':'application/json','Accept':'application/json, text/event-stream','Authorization':'Bearer '+k},body:JSON.stringify({jsonrpc:'2.0',id:1,method:'tools/call',params:{name:'clear-database',arguments:{apiKey:k}}})});console.log(await res.text());}catch(e){console.error(e);} })()"
```
PowerShell example (prompt before destructive action):
```powershell
$k = Read-Host -AsSecureString "Enter MCP API key" | ConvertFrom-SecureString
# convert back to plain (only do this locally and carefully)
$plain = ConvertTo-SecureString $k -AsPlainText -Force
# call with header
Invoke-RestMethod -Method Post -Uri http://localhost:3000/api/mcp -Headers @{ Authorization = "Bearer $plain" } -Body (@{ jsonrpc = '2.0'; id = 1; method = 'tools/call'; params = @{ name = 'clear-database'; arguments = @{ apiKey = $plain } } } | ConvertTo-Json -Depth 10)
```
Using `mcp-remote` (if available) is also supported by many editors and tools — just configure it to call the same MCP endpoint and supply the `ZEROHEIGHT_MCP_ACCESS_TOKEN` via your environment or secure editor secrets.
Security note
- **Do not store** your `ZEROHEIGHT_MCP_ACCESS_TOKEN` in repository-tracked files such as `.vscode/mcp.json`. If the key is committed or shared, it can be used to run destructive MCP tools.
- Store the key in an environment file (e.g., `.env.local` added to `.gitignore`), your OS keychain, or the editor/CI secret store.
📚 api参考
工具
注:实现 clear-database 和 query-database MCP工具已移至 src/tools/database/clear.ts 和 src/tools/database/query.ts 以便更好地将数据库检查工具与scraper实现分开。
1.报废零高度项目
自动发现并抓取配置的Zeroheight设计系统中的所有页面,包括具有重复数据消除功能的内容和图像。
参数: 无(使用环境变量)
例子:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "scrape",
"arguments": {}
}
}
2.查询零高度数据
使用灵活的搜索选项查询缓存的Zeroheight数据。返回图像的完整Supabase存储URL。
参数:
search(可选):标题或内容的搜索词url(可选):要检索的特定页面URLincludeImages(可选,默认值:true):包含具有完整存储URL的图像数据limit(可选,默认值:10):最大结果
示例:
// Get all pages (limited to 10)
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "query-database",
"arguments": {}
}
}
// Search for pages containing "brand"
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "query-database",
"arguments": {
"search": "brand",
"includeImages": true
}
}
}
// Get specific page by URL
{
"jsonrpc": "2.0",
"id": 4,
"method": "tools/call",
"params": {
"name": "query-database",
"arguments": {
"url": "https://example.zeroheight.com/p/project/page-slug",
"includeImages": true
}
}
}
🖥️ CLI工具
该项目通过服务器API公开MCP工具;您可以使用标准HTTP请求直接调用它们(包括 Authorization: Bearer <ZEROHEIGHT_MCP_ACCESS_TOKEN> 和 Accept: application/json, text/event-stream)或者使用编辑器的MCP集成。下面的“测试”部分提供了HTTP调用的示例。
🧪 测试
HTTP API测试
废料项目:
curl -X POST http://localhost:3000/api/mcp \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"scrape","arguments":{}}}'
查询数据:
curl -X POST http://localhost:3000/api/mcp \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"query-database","arguments":{"search":"color"}}}'
PowerShell测试
# Set API key
$env:ZEROHEIGHT_MCP_ACCESS_TOKEN = "your-api-key-here"
# Scrape project
Invoke-RestMethod -Uri "http://localhost:3000/api/mcp" -Method POST `
-Headers @{"Content-Type"="application/json"; "X-API-Key"=$env:ZEROHEIGHT_MCP_ACCESS_TOKEN; "Accept"="application/json, text/event-stream"} `
-Body '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"scrape","arguments":{}}}' | Format-List
# Query data
Invoke-RestMethod -Uri "http://localhost:3000/api/mcp" -Method POST `
-Headers @{"Content-Type"="application/json"; "X-API-Key"=$env:ZEROHEIGHT_MCP_ACCESS_TOKEN; "Accept"="application/json, text/event-stream"} `
-Body '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"query-database","arguments":{"search":"color"}}}' | Format-List
<!-- Execute SQL PowerShell example removed -->
🛠️ 本地任务脚本
此存储库包括方便的脚本,这些脚本现在作为数据库支持的任务开始scraper工作(因此进度、日志和结果被持久化)。脚本调用已注册的MCP工具处理程序并返回工具响应。
- 启动一个简短的测试任务(默认5分钟):
开发者文档
有关扩展的开发人员工作流程、环境和MCP使用的详细信息,请参阅 docs/DEVELOPMENT.md.
npx tsx scripts/tasks/start-test-task.ts # default 5 minutes
npx tsx scripts/tasks/start-test-task.ts 10 # run for 10 minutes
- 将整个刮刀作为任务启动(使用
ZEROHEIGHT_PROJECT_URL):
npx tsx scripts/tasks/start-scrape-project.ts
- 启动特定页面的刮刀(通过
pageUrls任务):
npx tsx scripts/tasks/start-scrape-pages.ts
- 公用设施:
# Inspect a task (admin DB client)
npx tsx scripts/tasks/tail-job-admin.ts <taskId>
# Tail a job via public tool (non-admin) — use when available
npx tsx scripts/tasks/tail-job.ts <taskId>
笔记:
- 脚本下
scripts/现在更喜欢基于任务的助手scripts/tasks/start-task.ts因此,他们启动了一个数据库支持的任务,而不是直接调用抓取器。 - 工具响应通常包含
jobId您可以使用tail/inspect脚本来查看进度。
自动化测试
运行内置测试套件:
npm run test-api
🔒 安全
此MCP服务器使用API密钥身份验证。API密钥应为:
- 设置为
ZEROHEIGHT_MCP_ACCESS_TOKEN环境变量 - 通过以下方式传递请求:
Authorization: Bearer <your-api-key>标题(推荐)X-API-Key: <your-api-key>头球?api_key=<your-api-key>查询参数(回退)
重要提示: 切勿将API密钥提交给版本控制。对于生产部署,请设置 ZEROHEIGHT_MCP_ACCESS_TOKEN 您的托管平台(Vercel等)中的环境变量。
🗄️ 数据库模式
服务器使用Supabase和下表:
-
页面:存储页面内容
id:主键url:页面URLtitle:页面标题content:页面内容(标记)scraped_at:时间戳
-
图像:存储图像引用
id:主键page_id:页面的外键original_url:原始图像URLlocal_path:本地存储路径
🚀 部署
Vercel(推荐)
-
连接您的存储库:
# Install Vercel CLI npm i -g vercel # Deploy vercel -
在Vercel中设置环境变量:
- 转到项目设置
- 添加
ZEROHEIGHT_MCP_ACCESS_TOKEN具有安全的随机值 - 添加
ZEROHEIGHT_PROJECT_URL和ZEROHEIGHT_PROJECT_PASSWORD如有需要
-
配置您的MCP客户端 带有生产URL和API密钥。
其他平台
服务器可以部署到任何支持Node.js的平台:
npm run build
npm start
🐛 故障排除
常见问题
401未经授权
- 检查一下
ZEROHEIGHT_MCP_ACCESS_TOKEN设置正确 - 验证请求标头中是否包含API密钥
406不可接受
- 添加
Accept: application/json, text/event-stream头球
连接被拒绝
- 确保服务器正在运行(
npm run dev) - 检查正确的端口(默认值:3000)
报废失败
- 验证
ZEROHEIGHT_PROJECT_URL可访问的 - 检查
ZEROHEIGHT_PROJECT_PASSWORD如果需要 - 确保项目允许刮擦
调试模式
通过设置启用详细日志记录:
DEBUG=mcp-server:*
🤝 贡献
- 分叉存储库
- 创建要素分支:
git checkout -b feature/your-feature - 提交更改:
git commit -am 'Add your feature' - 推到分支:
git push origin feature/your-feature - 提交拉取请求
开发设置
# Install dependencies
npm install
# Start development server
npm run dev
# Run tests
npm run test-api
# Lint code
npm run lint
# Generate database types
npm run generate-database-types
📄 许可证
此项目根据MIT许可证获得许可-请参阅 许可证 文件以获取详细信息。
🙏 致谢
建于❤️ 使用Next.js、TypeScript和模型上下文协议 { “name”:“query_zeroheight_data”, “论点”:{ “搜索”:“品牌”, “includeImages”:true } }
//按URL获取特定页面 { “name”:“query_zeroheight_data”, “论点”:{ “url”:“https://example.zeroheight.com/project/p/page-slug", “includeImages”:true }
## 🐛 Troubleshooting
### Common Issues
**401 Unauthorized**
- Check that `ZEROHEIGHT_MCP_ACCESS_TOKEN` is set correctly
- Verify the API key is included in request headers
**406 Not Acceptable**
- Add `Accept: application/json, text/event-stream` header
**Connection Refused**
- Ensure the server is running (`npm run dev`)
- Check the correct port (default: 3000)
**Scraping Fails**
- Verify `ZEROHEIGHT_PROJECT_URL` is accessible
- Check `ZEROHEIGHT_PROJECT_PASSWORD` if required
- Ensure the project allows scraping
### Debug Mode
Enable verbose logging by setting:
```env
DEBUG=mcp-server:*
🤝 贡献
- 分叉存储库
- 创建要素分支:
git checkout -b feature/your-feature - 提交更改:
git commit -am 'Add your feature' - 推到分支:
git push origin feature/your-feature - 提交拉取请求
开发设置
# Install dependencies
npm install
# Start development server
npm run dev
# Run tests
npm run test-api
# Lint code
npm run lint
# Generate database types
npm run generate-database-types
📄 许可证
此项目根据MIT许可证获得许可-请参阅 许可证 文件以获取详细信息。
🙏 致谢
建于❤️ 使用Next.js、TypeScript和模型上下文协议
