MCP注册管理服务

一个用于发现、分享和管理模型上下文协议(MCP)服务器及工具的生产级Web应用程序。

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

使用说明

MCP注册表

用于发现、共享和管理模型上下文协议(MCP)服务器和工具的生产质量web应用程序。

技术栈

  • 框架:Next.js 15,带应用路由器
  • 语言:TypeScript
  • 样式:顺风CSS
  • 数据库/身份验证:Supabase(Postgres+Auth)
  • 部署:Vercel
  • 程序包管理器:pnpm

先决条件

  • Node.js 18.17.0或更高版本
  • pnpm 9.x(npm install -g pnpm)
  • Docker(用于本地Supabase)
  • Supabase命令行界面(npm install -g supabase)

地方发展设置

1.克隆存储库

git clone https://github.com/your-org/mcp-registry.git
cd mcp-registry

2.安装依赖项

pnpm install

3.启动本地数据库

本地开发使用在Docker中运行的Supabase:

# Start Supabase (requires Docker)
pnpm supabase:start

# Apply migrations and seed data
pnpm supabase:db:reset

# Generate TypeScript types
pnpm supabase:types

启动后,Supabase将输出本地URL和密钥。在你的 .env.local:

NEXT_PUBLIC_SUPABASE_URL=http://127.0.0.1:54321
NEXT_PUBLIC_SUPABASE_ANON_KEY=<anon-key-from-supabase-start-output>

本地Supabase服务:

  • 工作室: http://localhost:54323(数据库管理UI)
  • API: http://localhost:54321
  • Inbucket: http://localhost:54324(电子邮件测试-在此处查看魔术链接!)
  • 每日公报postgresql://postgres:postgres@本地主机:54322/postgres

4.设置第一个管理员用户

启动本地Supabase后:

  1. 启动开发服务器: pnpm dev
  2. 首选http://localhost:3000/signin
  3. 输入您的电子邮件并查看Inbucket(http://localhost:54324)对于魔术链接
  4. 单击魔术链接登录
  5. 开放式Supabase工作室(http://localhost:54323)
  6. 转到表编辑器→ 个人资料
  7. 查找您的用户行并更改 role 从 user 到 admin

或者,使用SQL:

-- Replace with your actual user ID from auth.users table
UPDATE public.profiles
SET role = 'admin'
WHERE id = '<your-user-id>';

5.启动开发服务器

pnpm dev

打开 http://localhost:3000 在您的浏览器中。

提交和审核工作流程

对于用户

  1. 登录 通过 /signin 使用电子邮件魔术链接
  2. 提交 新的MCP服务器 /submit
    • 填写必填字段:slug、name、description、transport、auth
    • 可选择添加URL、标签和功能
  3. 轨道 你的意见书在 /my/submissions
    • 查看状态:待定、已批准或已拒绝
    • 请参阅管理员审核说明

对于管理员

  1. 访问 /admin/submissions (需要管理员角色)
  2. 审查待提交的文件:
    • 单击展开并查看完整详细信息
    • 批准:将服务器发布到 /servers
    • 拒绝:必须提供原因(提交者可见)
  3. 显示以前审查过的提交文件以供参考

安全模型

  • RLS(行级安全):所有数据访问都在数据库级别进行控制
  • 管理员验证:除了RLS(深度防御)之外的服务器端检查
  • 浏览器中没有服务角色:所有管理员操作都使用经过身份验证的用户上下文
  • 魔术链接认证:无密码存储,电子邮件自动验证

可用脚本

命令 描述
pnpm dev 启动开发服务器
pnpm build 为生产而建
pnpm start 启动生产服务器
pnpm lint 运行ESLint
pnpm lint:fix 运行ESLint并自动修复
pnpm format 使用Prettier格式化代码
pnpm format:check 检查代码格式
pnpm typecheck 运行TypeScript类型检查
pnpm test 运行单元测试(Vitest)
pnpm test:watch 在监视模式下运行测试
pnpm test:coverage 运行覆盖率测试
pnpm test:e2e 运行E2E测试(剧作家)
pnpm test:e2e:ui 使用UI运行E2E测试
pnpm test:e2e:security 运行以安全为重点的E2E烟雾测试
pnpm test:e2e:heuristics 运行产品启发式缺口检测
pnpm perf:report 生成性能趋势+回归报告
pnpm product:backlog 根据差距报告生成降价积压
pnpm audit:sha <sha> 对提交进行隔离的完整代理B审计
pnpm security:deps 审核CVE的生产依赖关系
pnpm security:test 运行依赖性审计+安全E2E测试
pnpm supabase:start 启动本地Supabase(Docker)
pnpm supabase:stop 停止本地Supabase
pnpm supabase:status 检查本地数据库状态
pnpm supabase:db:reset 重置本地数据库(应用迁移+种子)
pnpm supabase:db:push 将迁移推送到远程
pnpm supabase:types 生成TypeScript类型

项目结构

mcp-registry/
├── app/                    # Next.js App Router pages
│   ├── api/health/        # Health check endpoint
│   ├── auth/callback/     # Magic link auth callback
│   ├── signin/            # Sign in page
│   ├── submit/            # Submit new server form
│   ├── my/submissions/    # User's submission list
│   ├── admin/submissions/ # Admin moderation page
│   ├── servers/           # Browse MCP servers
│   │   ├── page.tsx       # Server list with filters
│   │   └── [slug]/        # Server detail page
│   ├── layout.tsx         # Root layout
│   ├── page.tsx           # Homepage
│   └── globals.css        # Global styles
├── components/            # React components
│   ├── header.tsx         # Site header with auth state
│   ├── footer.tsx         # Site footer
│   └── auth-buttons.tsx   # Auth-aware navigation
├── lib/                   # Utility libraries
│   └── supabase/          # Supabase client utilities
│       ├── client.ts      # Browser client
│       ├── server.ts      # Server client
│       ├── database.types.ts  # Generated types
│       └── types.ts       # Type helpers
├── supabase/              # Supabase CLI
│   ├── config.toml        # Local config
│   ├── migrations/        # SQL migrations
│   └── seed.sql           # Dev seed data
├── __tests__/             # Unit tests (Vitest)
├── e2e/                   # E2E tests (Playwright)
├── middleware.ts          # Auth session refresh
└── .github/workflows/     # GitHub Actions CI

数据库模式

表格

mcp服务器 -已发布的MCP服务器

  • id, slug, name, description, homepage_url, repo_url, docs_url
  • tags, transport, auth, capabilities, verified
  • created_at, updated_at

个人资料 -带有角色的用户配置文件

  • id (引用auth.users)
  • role (“用户”或“管理员”)
  • created_at

mcp_server_提交 -用户提交等待审核

  • id, submitted_by, status, submitted_payload
  • review_notes, reviewed_at, reviewed_by
  • created_at

RLS政策

  • mcp服务器:公共读取,仅管理员插入
  • 个人资料:用户自行阅读/更新,管理员全部阅读
  • 提交:用户拥有CRUD,管理员读取/更新所有

环境变量

变量 必填 描述
NEXT_PUBLIC_SUPABASE_URL 是 您的Supabase项目URL
NEXT_PUBLIC_SUPABASE_ANON_KEY 是 支持匿名/公钥
SUPABASE_SERVICE_ROLE_KEY 否* 服务角色密钥(仅限服务器,用于引导)
ADMIN_BOOTSTRAP_TOKEN 否* 一次性引导身份验证令牌
ADMIN_BOOTSTRAP_EMAIL 否* 引导的第一个管理员的电子邮件

*仅在初始管理员引导时需要。可以在引导完成后删除。

重要:前缀为的变量 NEXT_PUBLIC_ 暴露在浏览器中。切勿在这些变量中隐藏秘密。

数据库和迁移

本地开发(使用Docker)

# Start local Supabase (requires Docker)
pnpm supabase:start

# Apply migrations and seed data
pnpm supabase:db:reset

# Generate TypeScript types from local schema
pnpm supabase:types

# Stop local Supabase
pnpm supabase:stop

远程开发(无Docker)

如果你没有Docker,直接连接到远程Supabase项目:

# Link to remote project (one-time setup)
supabase link --project-ref <your-project-ref>

# Push migrations to remote
pnpm supabase:db:push

# Generate types from remote
supabase gen types typescript --linked > lib/supabase/database.types.ts

创建迁移

# Create a new migration
supabase migration new <migration_name>

# Edit the migration file in supabase/migrations/

# Apply locally
pnpm supabase:db:reset

# Push to remote when ready
pnpm supabase:db:push

迁移不变性规则

重要:一旦迁移被提交到git或应用于任何环境(本地、暂存、生产),就不得对其进行修改。这对于数据库的一致性至关重要。

如果您需要更改应用程序迁移中的某些内容:

  1. 不要 编辑现有迁移文件
  2. 做 创建进行必要更改的新迁移
  3. 新的迁移应该是累加的(ALTER、CREATE或REPLACE等)

示例-修复函数:

# Wrong: Editing 20260101_create_function.sql after it was applied

# Correct: Create a new migration
supabase migration new fix_function_xyz
# Then add ALTER/CREATE OR REPLACE statements in the new file

这确保了:

  • 所有环境都可以一致地重播迁移
  • supabase db reset 从头开始工作
  • 本地、临时和生产数据库之间没有漂移

连接到生产数据库

1.创建一个Supabase项目

  1. 首选 网站 supabase.com 并创建一个新项目
  2. 等待项目配置

2.获取您的证书

  1. 首选 项目设置 → API
  2. 复制 项目Url → NEXT_PUBLIC_SUPABASE_URL
  3. 复制 匿名公众 key → NEXT_PUBLIC_SUPABASE_ANON_KEY

3.推动迁移

supabase link --project-ref <your-project-ref>
supabase db push

4.设置第一管理员(生产)

使用一次性引导端点(推荐):

# 1. Set environment variables in Vercel:
#    - SUPABASE_SERVICE_ROLE_KEY (from Supabase Dashboard → Settings → API)
#    - ADMIN_BOOTSTRAP_TOKEN (generate a random string)
#    - ADMIN_BOOTSTRAP_EMAIL (your email address)

# 2. Sign up first by visiting /signin and clicking the magic link

# 3. Call the bootstrap endpoint
curl -X POST https://your-app.vercel.app/api/admin/bootstrap \
  -H "Content-Type: application/json" \
  -H "x-bootstrap-token: YOUR_ADMIN_BOOTSTRAP_TOKEN" \
  -d '{"email": "your-email@example.com"}'

# Expected response: {"success":true,"message":"Admin bootstrap completed","userId":"..."}

引导端点为:

  • 一次性:首次成功使用后自动禁用
  • 安全:需要匹配的令牌和电子邮件
  • 频率限制:防止暴力攻击
  • 已审核:将操作记录到audit_log表中

替代方案(手动SQL):

-- In Supabase SQL Editor
-- First, find your user ID after signing in
SELECT id, email FROM auth.users;

-- Then update their profile
UPDATE public.profiles
SET role = 'admin'
WHERE id = '<your-user-id>';

在Vercel上部署

自动部署

  1. 将代码推送到GitHub
  2. 将项目导入 维塞尔
  3. 在Vercel仪表板中配置环境变量
  4. 部署!

Vercel中的环境变量

在Vercel项目设置中添加以下内容:

  • NEXT_PUBLIC_SUPABASE_URL
  • NEXT_PUBLIC_SUPABASE_ANON_KEY

测试

单元测试(Vitest)

# Run all tests
pnpm test

# Watch mode
pnpm test:watch

# With coverage
pnpm test:coverage

E2E测试(剧作家)

# Run E2E tests
pnpm test:e2e

# Interactive UI mode
pnpm test:e2e:ui

# Install browsers (first time)
pnpm exec playwright install

产品测试(测试正向开发)

该项目使用测试正向开发方法,有两种类型的产品测试:

产品规格测试(必须通过)

e2e/product-spec.spec.ts -定义产品合同。这些测试验证:

  • 页面结构:每个公共页面都有 <main> 地标只有一个 <h1> 以及跳过链接
  • 导航:标题包含浏览、文档、API、变更日志、关于链接
  • 页脚:包含关于、文档、API、验证、变更日志、贡献、隐私、条款的链接
  • Footer链接健康状况:页脚链接解析,不返回4xx/5xx
  • 元数据要素:存在页面标题和元描述
  • 控制台错误:任何页面上都没有JavaScript错误
  • 链接完整性:所有内部链接都能正确解析(上限为60个链接)
  • 关键旅程:发现流程、带建议的搜索、验证透明度
# Run product spec tests only
pnpm exec playwright test product-spec

# Run with verbose output
pnpm exec playwright test product-spec --reporter=list

产品库存(无门控)

e2e/product-inventory.spec.ts -在不阻塞CI的情况下生成产品库存+差距报告。

每个公共页面的集合:

  • URL、HTTP状态、页面标题、h1文本
  • 内部/外部链接计数
  • UI功能标志:面包屑、空状态、代码块、表、表单
  • A11y快速检查:地标、跳转链接、标题导航
  • 元数据存在检查(描述和Open Graph基础知识)
  • 链接验证+衍生产品差距总结

输出:

  • e2e/reports/product-inventory.json
  • e2e/reports/product-gaps.json
# Run inventory + gap report generation
pnpm test:e2e:inventory

# View the generated reports
cat e2e/reports/product-inventory.json | jq '.summary'
cat e2e/reports/product-gaps.json | jq '.notes'

库存报告结构:

{
  "generatedAt": "2026-02-14T...",
  "pageCount": 12,
  "totalInternalLinks": 45,
  "pages": [
    {
      "url": "/servers",
      "name": "Browse Servers",
      "status": 200,
      "h1Text": "MCP Server Registry",
      "internalLinkCount": 15,
      "hasBreadcrumbs": false,
      "hasCodeBlock": false,
      "a11y": { "hasMainLandmark": true, "hasH1": true, ... }
    }
  ],
  "summary": {
    "pagesWithErrors": 0,
    "pagesWithoutH1": 0,
    "pagesWithCodeBlocks": 3
  }
}

产品启发式(无门控)

e2e/product-heuristics.spec.ts -在所有公共路由上运行UX/内容差距检测。

每页启发式检查:

  • 结构:正好一个 <h1> 标题
  • 主要行动:清除CTA按钮或主要内容中的突出链接
  • 导航:下一步链接超出页眉/页脚(死端检测)
  • 内容有用性:代码块,docs/api/about/等所需的部分。
  • 信任可发现性:链接/验证(如适用)
  • 摩擦旗:“即将推出”块,禁用控件
  • 性能健全:DOM内容加载时间阈值
  • 转换启发式:CTA存在、CTA层次结构、社会证明、CTA附近的信任、搜索匹配突出显示和长页面上的分段CTA

输出:

  • e2e/reports/product-heuristics.json
  • e2e/screenshots/product-heuristics/<route>/<theme>/<viewport>.png (关于失败)
  • e2e/reports/product-gaps.json 包括合并 heuristicGaps.conversion[] 针对以转换为重点的问题

严重性评分标准:

  • 关键的:阻碍核心旅程或在关键页面上造成混淆
  • 高:严重损害信任/转化
  • 中等:波兰语/可用性问题
  • 低:轻微一致性
# Run heuristics + merge into gap report
pnpm test:e2e:heuristics

# View heuristics summary
cat e2e/reports/product-heuristics.json | jq '.summary'

产品待办列表生成

在运行库存和启发式测试后,生成一个有优先级的降价待办事项列表:

# Generate backlog from gap report
pnpm product:backlog

product:backlog 以本地开发依赖关系运行 tsx (没有 npx fetch),因此之后它是离线安全的 pnpm install.

这创造了 docs/product-backlog.md 与:

  • 按严重程度汇总所有差距
  • 关键问题及全部细节
  • 高/中/低优先级表
  • 工作量估算(S/M/L)
  • 建议修复
  • 证据和截图路径

规范工作流程:

# 1. Run heuristics first (source of heuristic gaps)
pnpm test:e2e:heuristics

# 2. Run inventory (derives report + preserves merged heuristicGaps)
pnpm test:e2e:inventory

# 3. Validate deterministic merged report shape
pnpm exec playwright test e2e/product-gaps.spec.ts

# 4. Generate markdown backlog from canonical report
pnpm product:backlog

# 5. Review the backlog
cat docs/product-backlog.md

性能趋势(无门控)

e2e/perf-trends.spec.ts 在关键路线上捕获轻量级性能遥测数据:

  • /, /servers, /servers/github, /docs, /api, /verification
  • 导航定时代理: ttfbMs, domContentLoadedMs, loadEventEndMs
  • 喷漆时间: fcpMs (可用时)
  • 资源配置文件:JS/CSS请求计数,总资源计数
  • 转账估算: totalTransferredBytesApprox 从响应标头

输出:

  • e2e/reports/perf-trends.json
  • e2e/reports/perf-regressions.json
  • 预算来源: docs/perf-budgets.json

回归检测规则:

  • 政策: budget_only_trends_informational (配置于 docs/perf-budgets.json)
  • 只有当当前指标超过路线/默认预算时,才会记录回归
  • 基线趋势增量(>15%)仍被计算为信息性警告
  • 默认情况下无门控(用于产品智能和冲刺计划)
# Run perf trend capture only
pnpm test:e2e:perf-trends

# Compare current trends vs last committed baseline
pnpm perf:compare

# Generate all perf outputs (smoke + trends + regressions)
pnpm perf:report

独立SHA审计

对干净提交状态运行完整的Agent B系统审核:

pnpm audit:sha <sha>

这有什么作用:

  • 在分离的HEAD模式下检查目标提交
  • 跑动 git clean -xfd 强制执行干净的工作空间
  • 安装依赖项 pnpm install --frozen-lockfile
  • 跑:
    • pnpm exec playwright test e2e/product-spec.spec.ts
    • pnpm test:e2e:heuristics
    • pnpm test:e2e:inventory
    • pnpm perf:report
    • pnpm product:backlog

该脚本在执行前需要一个干净的工作树,并在执行后恢复原始引用。

在本地验证所有内容

# Full local validation workflow
pnpm supabase:start
pnpm supabase:db:reset
pnpm supabase:types
pnpm dev &
pnpm test
pnpm test:e2e

Git挂钩

此项目使用Husky作为Git钩子:

  • 预承诺:运行lint stage(ESLint+对stage文件进行预处理)

运行时会自动安装挂钩 pnpm install.

CI/CD

GitHub Actions在每个推送和拉取请求上运行:

  1. 棉绒和类型检查:ESLint、TypeScript、Prettier
  2. 单元测试:Vitest
  3. 构建:Next.js生产构建
  4. E2E测试:剧作家

许可证

麻省理工学院