设计系统文档爬取服务器

一个强大的模型上下文协议(MCP)服务器,用于爬取、索引和智能查询Zeroheight设计系统文档,适用于需要程序化访问组件库和设计指南的设计系统团队。

  • by drexxdk
  • TypeScript
  • 本地部署
  • 更新于
在 GitHub 查看 drexxdk/zeroheight-mcp

使用说明

零高度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.

如何在本地启用

  1. 运行:
npm install
# (prepare runs automatically) or run explicitly:
npx husky install
  1. 进行更改并提交——预提交钩子将自动运行。

如果你更喜欢钩子,而不是只检查 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密钥

安装

  1. 克隆存储库:

    git clone https://github.com/drexxdk/zeroheight-mcp.git
    cd zeroheight-mcp
    
  2. 安装依赖项:

    npm install
    
  3. 配置环境变量:

    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.

  1. 启动开发服务器:

    npm run dev
    
  2. 测试设置:

    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 (可选):要检索的特定页面URL
  • includeImages (可选,默认值: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:页面URL
    • title:页面标题
    • content:页面内容(标记)
    • scraped_at:时间戳
  • 图像:存储图像引用

    • id:主键
    • page_id:页面的外键
    • original_url:原始图像URL
    • local_path:本地存储路径

🚀 部署

Vercel(推荐)

  1. 连接您的存储库:

    # Install Vercel CLI
    npm i -g vercel
    
    # Deploy
    vercel
    
  2. 在Vercel中设置环境变量:

    • 转到项目设置
    • 添加 ZEROHEIGHT_MCP_ACCESS_TOKEN 具有安全的随机值
    • 添加 ZEROHEIGHT_PROJECT_URL 和 ZEROHEIGHT_PROJECT_PASSWORD 如有需要
  3. 配置您的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:*

🤝 贡献

  1. 分叉存储库
  2. 创建要素分支: git checkout -b feature/your-feature
  3. 提交更改: git commit -am 'Add your feature'
  4. 推到分支: git push origin feature/your-feature
  5. 提交拉取请求

开发设置

# 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:*

🤝 贡献

  1. 分叉存储库
  2. 创建要素分支: git checkout -b feature/your-feature
  3. 提交更改: git commit -am 'Add your feature'
  4. 推到分支: git push origin feature/your-feature
  5. 提交拉取请求

开发设置

# 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和模型上下文协议