MCP服务器发现服务

Athena MCP Registry是一个基于域名的MCP服务器智能发现与配置服务,帮助用户根据上下文自动匹配相关MCP服务器。

  • by lespaceman
  • TypeScript
  • 本地部署
  • 3 星标
  • 更新于
在 GitHub 查看 lespaceman/athena-mcp-registry

使用说明

Athena MCP注册表

一个干净、类型安全的MCP(模型上下文协议)注册表,可帮助根据域上下文发现和配置MCP服务器。使用Fastify、TypeScript和SQLite构建。

什么是MCP查找?

这 MCP查找API 支持基于域上下文的MCP服务器的智能发现。当用户访问网站或使用特定服务时,查找端点会自动建议相关的MCP服务器,以增强他们的体验。

示例用例:

  • 浏览github → 建议GitHub MCP Server提供管理仓库、问题和PR的工具
  • 在你的公司atlasian.net工作 → 建议使用Jira MCP服务器和项目管理工具
  • 阅读API文档 → 建议API的相关MCP服务器

API消费者快速入门

基础URL

http://localhost:3000  # Local development
https://your-domain.com  # Production

基本查找请求

# Find MCP servers for a domain
curl "http://localhost:3000/api/v1/lookup?domain=github.com"

示例响应

{
  "domain": "github.com",
  "match_metadata": {
    "match_count": 1,
    "search_time_ms": 12,
    "cache_hit": false
  },
  "matches": [
    {
      "server_id": "abc-123",
      "name": "GitHub MCP Server",
      "description": "Access GitHub repositories, issues, pull requests, and more through MCP.",
      "version": "1.0.0",
      "deployment_type": "local",
      "match_type": "exact",
      "match_confidence": 100,
      "installation_complexity": "simple",
      "estimated_setup_minutes": 5,
      "requires_restart": false,
      "auth_required": true,
      "auth_type": "api_key",
      "oauth_ready": false,
      "auth_methods": ["api_key"],
      "configurations": [
        {
          "config_id": "cfg-123",
          "runtime": "nodejs",
          "transport": "stdio",
          "quick_install": true
        }
      ],
      "tools_count": 5,
      "top_tools": [
        "Create or Update File",
        "Push Files",
        "Create Issue",
        "Create Pull Request",
        "Search Repositories"
      ],
      "resources_available": false,
      "trust_level": "verified",
      "popularity_score": 95,
      "install_count": 15000,
      "last_updated": "2025-01-10T12:00:00Z"
    }
  ]
}

API 参考

MCP查找端点

GET /api/v1/lookup

通过智能匹配和过滤查找给定域的MCP服务器。

查询参数

参数 类型 默认值 说明
domain 字符串 必需的 要查找的域(例如“github.com”、“api.example.com”)
trust_levels 字符串 "verified,community" 逗号分隔的信任级别: verified, community, unverified
deployment_types 字符串 "local,remote,hybrid" 逗号分隔的部署类型
max_results 整数 10 最大结果数(1-50)
include_categories 布尔值 false 包括基于类别的匹配

请求示例

# Basic lookup
curl "http://localhost:3000/api/v1/lookup?domain=github.com"

# Only verified servers
curl "http://localhost:3000/api/v1/lookup?domain=github.com&trust_levels=verified"

# Only local deployments
curl "http://localhost:3000/api/v1/lookup?domain=slack.com&deployment_types=local"

# Limit results
curl "http://localhost:3000/api/v1/lookup?domain=example.com&max_results=5"

# Multiple filters
curl "http://localhost:3000/api/v1/lookup?domain=github.com&trust_levels=verified,community&deployment_types=local&max_results=3"

响应结构

成功响应(200 OK)

{
  "domain": "string",
  "match_metadata": {
    "match_count": 0,
    "search_time_ms": 0,
    "cache_hit": false
  },
  "matches": [
    {
      "server_id": "string",
      "name": "string",
      "description": "string",
      "version": "string",
      "deployment_type": "local|remote|hybrid",
      "match_type": "exact|wildcard|category",
      "match_confidence": 0,
      "priority": 0,
      "auto_suggest": false,
      "installation_complexity": "simple|moderate|complex",
      "estimated_setup_minutes": 0,
      "requires_restart": false,
      "prerequisites_summary": "string (optional)",
      "auth_required": false,
      "auth_type": "string (optional)",
      "oauth_ready": false,
      "auth_methods": ["string"],
      "configurations": [
        {
          "config_id": "string",
          "runtime": "string (optional)",
          "transport": "string",
          "quick_install": false
        }
      ],
      "tools_count": 0,
      "top_tools": ["string"],
      "resources_available": false,
      "trust_level": "verified|community|unverified",
      "popularity_score": 0,
      "install_count": 0,
      "last_updated": "string (optional)"
    }
  ]
}

未找到匹配项(404未找到)

{
  "error": "no_matches",
  "message": "No MCP servers found for this domain",
  "domain": "example.com",
  "suggestions": {
    "similar_domains": [],
    "category_matches": []
  }
}

验证错误(400错误请求)

{
  "error": "invalid_request",
  "message": "Invalid domain format",
  "details": {
    "param": "domain",
    "code": "invalid_string"
  }
}

匹配类型

  • 精确:域与模式完全匹配(例如。, github.com)
  • 通配符:域匹配通配符模式(例如。, *.atlassian.net 火柴 yourcompany.atlassian.net)
  • 类别:根据域类别匹配服务器(当 include_categories=true)

信任级别

  • 已验证:官方或经过彻底审查的服务器
  • 社区:社区维护的服务器声誉良好
  • 未验证的:新的或未经审核的服务器

部署类型

  • 本地:在用户的计算机上运行(通常是Node.js/Python进程)
  • 远程:通过HTTP/SSE访问托管服务
  • 混合:可以以任何方式部署

缓存

  • 响应已缓存 15分钟
  • 缓存键包括所有查询参数
  • match_metadata.cache_hit 指示是否缓存了响应

健康检查

GET /_api/health

检查服务器运行状况和数据库连接。

curl http://localhost:3000/_api/health

答复:

{
  "status": "ok",
  "uptime": 123.456,
  "db": "ok"
}

指标

GET /_api/metrics

Prometheus兼容度量端点(当前版本中的占位符)。

集成示例

JavaScript/TypeScript

interface LookupResponse {
  domain: string;
  match_metadata: {
    match_count: number;
    search_time_ms: number;
    cache_hit: boolean;
  };
  matches: Array<{
    server_id: string;
    name: string;
    description: string;
    version: string;
    deployment_type: 'local' | 'remote' | 'hybrid';
    match_type: 'exact' | 'wildcard' | 'category';
    match_confidence: number;
    tools_count: number;
    top_tools: string[];
    auth_required: boolean;
    trust_level: 'verified' | 'community' | 'unverified';
    // ... other fields
  }>;
}

async function lookupMCPServers(domain: string): Promise<LookupResponse> {
  const params = new URLSearchParams({
    domain,
    trust_levels: 'verified,community',
    max_results: '10'
  });

  const response = await fetch(
    `http://localhost:3000/api/v1/lookup?${params}`
  );

  if (!response.ok) {
    if (response.status === 404) {
      return { domain, match_metadata: { match_count: 0, search_time_ms: 0, cache_hit: false }, matches: [] };
    }
    throw new Error(`Lookup failed: ${response.statusText}`);
  }

  return response.json();
}

// Usage
const results = await lookupMCPServers('github.com');
console.log(`Found ${results.match_metadata.match_count} servers`);
results.matches.forEach(server => {
  console.log(`- ${server.name}: ${server.description}`);
  console.log(`  Tools: ${server.top_tools.join(', ')}`);
});

python

import requests
from typing import Optional, List, Dict, Any

def lookup_mcp_servers(
    domain: str,
    trust_levels: str = "verified,community",
    max_results: int = 10
) -> Optional[Dict[str, Any]]:
    """Look up MCP servers for a given domain."""
    params = {
        "domain": domain,
        "trust_levels": trust_levels,
        "max_results": str(max_results)
    }

    response = requests.get(
        "http://localhost:3000/api/v1/lookup",
        params=params
    )

    if response.status_code == 404:
        return None

    response.raise_for_status()
    return response.json()

# Usage
result = lookup_mcp_servers("github.com")
if result:
    print(f"Found {result['match_metadata']['match_count']} servers")
    for server in result['matches']:
        print(f"- {server['name']}: {server['description']}")
        print(f"  Tools: {', '.join(server['top_tools'])}")

浏览器扩展示例

// Automatically suggest MCP servers based on current tab URL
chrome.tabs.onUpdated.addListener(async (tabId, changeInfo, tab) => {
  if (changeInfo.status === 'complete' && tab.url) {
    const domain = new URL(tab.url).hostname;

    try {
      const response = await fetch(
        `http://localhost:3000/api/v1/lookup?domain=${domain}&trust_levels=verified`
      );

      if (response.ok) {
        const data = await response.json();

        if (data.matches.length > 0) {
          // Show notification about available MCP servers
          const topMatch = data.matches[0];
          if (topMatch.auto_suggest) {
            showNotification({
              title: `MCP Server Available: ${topMatch.name}`,
              message: topMatch.description,
              actions: ['Install', 'Learn More']
            });
          }
        }
      }
    } catch (error) {
      console.error('MCP lookup failed:', error);
    }
  }
});

了解响应字段

字段 描述 示例用例
match_confidence 0-100分表示匹配质量 筛选低置信度匹配(<50)
auto_suggest 是否主动建议此服务器 仅显示auto_suggest=true的通知
installation_complexity 简单/中等/复杂 警告用户安装复杂
estimated_setup_minutes 设置时间估计 向用户显示时间承诺
auth_required 是否需要身份验证 准备OAuth流或API密钥输入
oauth_ready OAuth可用 可用时首选OAuth而不是API密钥
quick_install 可以通过npm/pip安装 启用一键安装
trust_level 服务器验证状态 按信任级别筛选以确保安全
tools_count 可用工具数量 显示功能丰富性

费率限制和性能

缓存行为

  • 缓存持续时间:15分钟
  • 缓存键:包括所有查询参数(域、信任级别、部署类型、最大结果、包含类别)
  • 缓存指示器: match_metadata.cache_hit 现场响应
  • 缓存清理:自动清理每5分钟运行一次

例子:

# First request - cache miss
curl "http://localhost:3000/api/v1/lookup?domain=github.com"
# Response: "cache_hit": false, "search_time_ms": 45

# Second request within 15 minutes - cache hit
curl "http://localhost:3000/api/v1/lookup?domain=github.com"
# Response: "cache_hit": true, "search_time_ms": 2

性能特征

  • 平均响应时间:10-50ms(冷),1-5ms(缓存)
  • 数据库:带预处理语句的SQLite
  • 并发:通过Fastify高效处理并发请求
  • 搜索策略:
    1. 精确的域匹配(最快)
    2. 通配符模式匹配(如果需要)
    3. 基于类别的匹配(如果启用)

最佳实践

  1. 缓存友好查询:使用一致的参数顺序和值
  2. 批量查找:如果查找多个域,请使用单独的请求(并行)而不是顺序请求
  3. 早期筛选:使用 trust_levels 和 deployment_types 减小结果集大小
  4. 监视器缓存命中率:轨道 cache_hit 优化查询模式的速率
  5. 尊重缓存TTL:不要不必要地绕过缓存-15分钟是发现的最佳时间

配置

配置使用Zod进行验证,并从环境变量加载:

变量 类型 默认值 描述
PORT 编号 3000 服务器端口
NODE_ENV development production test
DATABASE_URL 字符串 ./data/dev.sqlite SQLite数据库路径
LOG_LEVEL fatal error warn
SENTRY_DSN string - 用于错误跟踪的哨兵DSN(可选)

示例 .env 文件:

PORT=3000
NODE_ENV=development
DATABASE_URL=./data/dev.sqlite
LOG_LEVEL=info
SENTRY_DSN=https://your-sentry-dsn@sentry.io/project

面向开发者

建筑

本项目遵循清洁建筑原则:

  • 路线/控制器:处理HTTP请求和响应(src/routes/)
  • 用例/服务:业务逻辑层(src/services/)
  • 适配器/基础设施:外部依赖关系-数据库等。 (src/infra/)

关键设计决策

  • 应用工厂模式:用途 createApp() 便于使用Fastify进行测试 inject() 方法
  • 无ORM:通过以下方式直接访问SQLite better-sqlite3 为了简单和性能
  • 严格的TypeScript:启用严格模式的全类型安全
  • Zod验证:运行时配置和请求验证
  • ESLint+Pretier:通过预提交挂钩强制执行一致的代码风格

先决条件

  • Node.js 18+(或建议20+)
  • pnpm 8+

开发设置

# Install dependencies
pnpm install

# Run migrations and start dev server
pnpm dev

# The server will start on http://localhost:3000

可用脚本

pnpm dev          # Start development server with hot reload
pnpm build        # Compile TypeScript to JavaScript
pnpm start        # Run production build
pnpm test         # Run tests with Vitest
pnpm test:ui      # Run tests with Vitest UI
pnpm typecheck    # Type check without emitting files
pnpm lint         # Lint code with ESLint
pnpm format       # Format code with Prettier
pnpm migrate:run  # Run database migrations

项目结构

athena-mcp-registry/
├── src/
│   ├── app.ts                   # App factory (createApp)
│   ├── server.ts                # Server entry point
│   ├── config/
│   │   └── index.ts             # Zod-based config validation
│   ├── infra/
│   │   ├── db.ts                # SQLite database adapter
│   │   └── migrations.ts        # Migration system
│   ├── routes/
│   │   ├── health.ts            # Health check endpoint
│   │   ├── lookup.ts            # MCP lookup endpoint ⭐
│   │   └── metrics.ts           # Metrics endpoint
│   ├── services/
│   │   └── lookup.service.ts    # Lookup business logic ⭐
│   ├── types/
│   │   ├── lookup.ts            # Lookup API types
│   │   ├── models.ts            # Database models
│   │   └── schemas.ts           # Validation schemas
│   ├── tests/
│   │   ├── health.test.ts
│   │   └── lookup.test.ts       # Lookup endpoint tests
│   └── scripts/
│       ├── migrate.ts           # Migration runner
│       └── seed-sample-data.ts  # Sample data seeder
├── migrations/
│   ├── 001_init.sql
│   ├── 002_core_entities.sql
│   ├── 003_configurations.sql
│   ├── 004_authentication.sql
│   ├── 005_domain_mappings.sql
│   ├── 006_capabilities.sql
│   ├── 007_remote_server_config.sql
│   └── 008_prerequisites.sql
├── data/                        # SQLite database (gitignored)
├── dist/                        # Compiled output (gitignored)
└── package.json

数据库

该项目使用SQLite better-sqlite3 为了简单和性能。数据库在首次运行时自动创建。

运行迁移:

# Run all pending migrations
pnpm migrate:run

# Check migration status
pnpm migrate:status

播种样本数据:

tsx src/scripts/seed-sample-data.ts

测试

测试使用Vitest和Fastify的 inject() 不启动服务器的内存测试方法:

# Run tests
pnpm test

# Run tests with UI
pnpm test:ui

# Run tests with coverage
pnpm test -- --coverage

发展

添加新路线

  1. 在中创建路线文件 src/routes/
  2. 在中注册 src/app.ts
  3. 在中添加测试 src/tests/

例子:

// src/routes/example.ts
import { FastifyPluginAsync } from 'fastify';

const plugin: FastifyPluginAsync = async (server) => {
  server.get('/example', async () => {
    return { message: 'Hello World' };
  });
};

export default plugin;
// Register in src/app.ts
import exampleRoutes from './routes/example.js';
app.register(exampleRoutes, { prefix: '/_api' });

可观测性

日志记录

应用程序使用 皮诺 对于结构化日志记录:

  • 发展:印刷精美的彩色原木
  • 生产:结构化JSON日志,便于解析和聚合

日志级别: fatal, error, warn, info, debug, trace

通过配置 LOG_LEVEL 环境变量。

错误跟踪

哨兵集成 (可选):

要启用错误跟踪,请设置 SENTRY_DSN 环境变量:

export SENTRY_DSN=https://your-key@sentry.io/your-project

哨兵将自动捕获并报告:

  • 未处理的异常
  • 应用程序错误
  • 性能指标(跟踪采样率:生产中为10%)

监控

  • 健康检查: GET /_api/health -数据库连接和正常运行时间
  • 指标: GET /_api/metrics -Prometheus指标占位符

CI/CD

持续集成

CI管道在每次推送和PR上运行:

  • 安全审计(pnpm audit)
  • Linting(eslint)
  • 类型检查(tsc)
  • 单元测试(vitest)
  • 构建验证

工作流程: .github/workflows/ci.yml

持续部署

合并到 main,CD管道:

  1. 运行完整的测试套件
  2. 构建多阶段Docker镜像
  3. 运行烟雾测试(健康+指标端点)
  4. 推送到GitHub容器注册表(GHCR)

工作流程: .github/workflows/cd.yml

图像存储库: ghcr.io/lespaceman/athena-mcp-registry

图像标记:

  • latest -最新主分支机构建设
  • <sha> -具体承诺SHA
  • <version> -语义版本(标记时)

看 发布.md 了解详细的发布和部署程序。

安全

自动化安全

  • Dependabot:自动为依赖关系更新创建PR
  • npm审计:在每个CI构建上运行
  • GitHub容器注册表:安全、私密的图像存储

安全检查列表

在部署到生产环境之前,请确保:

  • []所有依赖项都是最新的(pnpm update)
  • []无关键漏洞(pnpm audit)
  • []秘密存储在环境变量中(从不存储在代码中)
  • [ ] NODE_ENV=production 已投入生产
  • []数据库文件具有适当的权限
  • []哨兵DSN已配置为错误跟踪
  • []监控健康检查端点
  • []HTTPS已启用(通过反向代理)
  • []已配置速率限制(如果需要)
  • []所有端点都已进行输入验证
  • []SQL注入预防(参数化查询)
  • []CORS配置正确(如果向浏览器提供API)
  • []已设置安全标头(通过反向代理或Fastify插件)
  • []容器以非root用户身份运行(已在Dockerfile中配置)
  • []对敏感日志进行编辑(查看引脚配置)

报告安全问题

如果您发现安全漏洞,请发送电子邮件至[安全联系人]或在GitHub上打开私人安全咨询。

不要 公开安全漏洞问题。

码头工人

构建并运行

# Build the image
docker build -t athena-mcp-registry .

# Run in production mode
docker run -d \
  --name athena-mcp-registry \
  -p 3000:3000 \
  -v $(pwd)/data:/app/data \
  -e NODE_ENV=production \
  -e LOG_LEVEL=info \
  athena-mcp-registry

# Check logs
docker logs -f athena-mcp-registry

# Health check
curl http://localhost:3000/_api/health

Docker Compose

使用提供的 docker-compose.dev.yml 地方发展:

docker-compose -f docker-compose.dev.yml up

有关生产部署,请参阅 发布.md.

开发阶段

第一阶段:基础✅

  • ✅ 工作 createApp() + server.ts
  • ✅ 健康终点(GET /_api/health)
  • ✅ SQLite数据库设置
  • ✅ 初始迁移
  • ✅ 包脚本(开发、构建、启动、测试、lint、类型检查)
  • ✅ TypeScript配置
  • ✅ ESLint+Pretier
  • ✅ 基本健康终点测试
  • ✅ README快速入门

第二阶段:硬化✅

  • ✅ 具有上/下支持的迁移系统
  • ✅ 全面的测试覆盖率
  • ✅ 预提交挂钩(赫斯基)
  • ✅ Docker开发环境
  • ✅ CI管道(GitHub操作)

第3阶段:CI/CD和可观察性✅

  • ✅ 使用Docker构建和推送的CD管道
  • ✅ CI/CD中的烟雾测试
  • ✅ 结构化日志记录(Pino)
  • ✅ 错误跟踪设置(哨兵)
  • ✅ 健康检查和指标端点
  • ✅ Dependabot配置
  • ✅ CI中的安全审计
  • ✅ 发布文档
  • ✅ 安全检查表

许可证

国际协调委员会