MCP服务器模板

一个生产就绪的MCP服务器模板,提供完整的认证基础设施,适用于多项目范围和组织白标化场景。

  • by MeasureBit
  • Python
  • 本地部署
  • 更新于
在 GitHub 查看 MeasureBit/mcp-server-template

使用说明

MCP服务器模板

从经过实战测试的生产部署中提取的具有完整身份验证基础设施的生产就绪MCP服务器模板。

特性

  • OAuth 2.0+PKCE --S256代码挑战的完整授权代码流
  • 自动授权 --已知电子邮件会自动跳过登录表单
  • 刷新令牌 --JWT轮换的7天刷新代币
  • 客户端凭据 --通过客户端_secret_post或客户端_secret-basic进行机器对机器身份验证
  • 主管API密钥验证 --具有可配置TTL的缓存密钥查找
  • 多项目范围界定 — allowed_projects 每个密钥限制跨MCP部署的访问
  • 组织白标 --从主机头解析基于CNAME的品牌(自定义名称、favicon)
  • 使用跟踪 --每个密钥请求计数和令牌使用情况持续到Supabase
  • 弹性回退 --无法访问Supabase时的可配置行为(拒绝/允许/env)
  • 开发/生产表分离 — ENV=dev 用途 api_keys_dev/usage_dev 表格
  • 静态文件服务 --从以下位置提供品牌资产(收藏夹图标、徽标) /static/
  • 健康检查 — GET /health 回报 {"status": "ok"}

快速开始

  1. 安装依赖项

    pip install -r requirements.txt
    
  2. 配置环境

    cp .env.example .env
    # Edit .env with your Supabase credentials and PROJECT_ID
    
  3. 设置数据库 --针对您的Supabase项目按顺序运行SQL迁移:

    migrations/000_base_tables.sql   # API keys + usage tables
    migrations/001_organizations.sql # Organizations (optional, for whitelabeling)
    
  4. 添加您的工具 --编辑 server.py 并替换 echo 用你自己的例子 @mcp.tool 装饰功能。

  5. 跑

    # Streamable HTTP (production)
    TRANSPORT=http python server.py
    
    # stdio (local development / Claude Desktop)
    python server.py
    

项目结构

文件 目的
server.py 入口点+您的MCP工具(编辑此内容)
auth.py Auth中间件-OAuth,JWT,API密钥,组织(不编辑)
tracking.py 通过contextvars跟踪令牌/使用情况(不要编辑)
requirements.txt Python依赖关系
Dockerfile 容器部署
.env.example 记录所有配置变量
migrations/ Supabase表的SQL迁移
static/ 品牌资产(图标、徽标)

服务器说明(LLM指南)

这 instructions 参数打开 FastMCP() 是控制LLM如何使用服务器的最重要方法。它在MCP初始化握手期间返回,并告诉LLM它需要知道的一切-不需要外部技能文件或文档。

mcp = FastMCP(
    "my_server",
    instructions="""My server does X. Use tool_a for quick checks, tool_b for deep analysis.

## Workflow
1. tool_a — start here for fast results
2. tool_b — use after tool_a when the user wants more detail

## Before calling any tool
Always ask the user for: their input data, preferred format, and any constraints.

## Presenting results
Lead with the key metric. Show supporting detail after. Never dump raw JSON.

## Important
- Never call tool_b without calling tool_a first.
- Reuse results from earlier calls — don't repeat work.
"""
)

包括哪些内容:

  • 工作流程 --按什么顺序调用哪些工具
  • 先决条件 --在调用工具之前从用户那里收集什么
  • 输出规则 --如何格式化和呈现结果
  • 约束条件 --陷阱、订购要求、要避免的事情
  • 面板/状态重用 --何时重用以前的结果与进行新的调用

不包括的内容:

  • 内部实施细节(模型名称、评分方法)
  • API密钥或凭据
  • 任何你不想展示给最终用户的东西

添加工具

添加工具 server.py 使用 @mcp.tool 装饰师:

@mcp.tool(
    name="my_tool",
    annotations={
        "title": "My Tool",
        "readOnlyHint": True,
        "destructiveHint": False,
        "idempotentHint": True,
        "openWorldHint": False,
    },
)
async def my_tool(input_text: str, option: str = "default") -> str:
    """Description of what this tool does.

    Args:
        input_text: The main input.
        option: An optional parameter.

    Returns:
        The tool's output.
    """
    # Your logic here
    return result

对于调用LLM并希望进行令牌跟踪的工具:

from tracking import track_tokens

@mcp.tool(name="my_llm_tool")
async def my_llm_tool(prompt: str) -> str:
    """A tool that calls an LLM."""
    response = await my_llm_call(prompt)
    await track_tokens(response.input_tokens, response.output_tokens)
    return response.text

身份验证流程

  1. 客户端在以下位置发现OAuth元数据 /.well-known/oauth-authorization-server
  2. 客户端重定向到 /authorize 具有PKCE参数
  3. 如果 client_id 是一封已知的电子邮件,使用身份验证码自动重定向(无表单)
  4. 否则,用户将看到登录表单(电子邮件+API密钥)
  5. 客户端在以下位置交换令牌的身份验证码 /token
  6. 访问令牌(JWT,30分钟)用作 Bearer 令牌打开 /mcp
  7. 用于获取新访问令牌的刷新令牌(JWT,7天)

组织白标

要设置白标实例,请执行以下操作:

  1. 跑 migrations/001_organizations.sql
  2. 插入组织:
    INSERT INTO organizations (slug, brand_name, favicon_url, cname_domain)
    VALUES ('acme', 'Acme Corp MCP', '/static/acme-favicon.png', 'mcp.acme.com');
    
  3. 设置CNAME记录: mcp.acme.com → 您的部署URL
  4. 地方 acme-favicon.png 在 static/
  5. 具有匹配项的API密钥 organization_id 将看到Acme品牌

配置参考

变量 必填 默认 描述
SUPABASE_URL 是 -- 请提供项目URL
SUPABASE_KEY 是 -- 请提供匿名或服务角色密钥
PROJECT_ID 是 -- 此MCP项目的唯一ID
TRANSPORT 没有 stdio http 对于可流式传输的HTTP, stdio 对于本地
PORT 没有 8000 HTTP端口(当TRANSPORT=HTTP时)
ENV 没有 prod dev 用途 _dev 表格变体
JWT_SECRET 否 自动生成 签名JWT的密码
JWT_EXPIRY 没有 1800 访问令牌过期时间(秒)
SUPABASE_FALLBACK 没有 deny deny/allow/env 当Supabase无法访问时
API_KEYS 无 -- 逗号分隔键(回退=仅限于env)
BLOCKED_KEYS 否 -- 逗号分隔的阻塞键(回退=仅限于env)

部署

码头工人

docker build -t my-mcp .
docker run -p 8000:8000 --env-file .env my-mcp

铁路

  1. 连接您的仓库
  2. 在铁路仪表板中设置环境变量
  3. 铁路自动检测Dockerfile

端点

端点 方法 身份验证 描述
/health GET 否 健康检查
/.well-known/oauth-authorization-server GET 否 OAuth元数据
/.well-known/oauth-protected-resource GET 否 受保护的资源元数据
/authorize GET/POST 否 OAuth授权(登录表单)
/token POST 否 令牌交换
/register POST 否 客户端注册(返回已禁用)
/mcp POST/DELETE 是 MCP可流式传输HTTP端点
/ POST/DELETE 是 别名 /mcp
/usage GET admin_key 使用统计
/static/* GET 否 静态资产