MCP服务器模板

一个生产就绪的Model Context Protocol (MCP)服务器模板,可在5分钟内部署到Vercel,支持Bun运行时、JWT认证和服务注入。

  • by linyiru
  • TypeScript
  • 本地部署
  • 更新于
在 GitHub 查看 linyiru/mcp-server-vercel-template

使用说明

MCP服务器Vercel模板

生产准备就绪 模型上下文协议(MCP) 服务器模板,可部署到 维塞尔 随着 包子 运行时间不到5分钟。

特性

  • 荣誉 具有CORS、中间件和类型化上下文的web框架
  • Bun本地bundler → 单 index.js 通过生成输出API v3
  • JWT身份验证 通过JWKS(jose)提供可选的不透明令牌支持
  • 服务注入 通过代理模式(在您自己的数据库/API层中交换)
  • MCP传输:流式HTTP(POST/)和SSE(/sse + /message)
  • OAuth元数据:RFC 9728 /.well-known/oauth-protected-resource
  • 3个示例工具:Notes CRUD,Weather API,文档阅读器

快速开始

1.从模板创建

点击 “使用此模板” 在GitHub上,或:

git clone https://github.com/user/mcp-server-vercel-template.git my-mcp-server
cd my-mcp-server

2.安装依赖项

bun install

3.配置

复制 .env.example 到 .env 并设置 AUTH_SKIP=true 地方发展:

cp .env.example .env
echo 'AUTH_SKIP=true' >> .env

4.构建和验证

bun scripts/build.ts

5.部署到Vercel

vercel deploy

项目结构

src/
├── index.ts                  # Entry point (re-exports app)
├── app.ts                    # Hono app: CORS, routes, MCP handler, OAuth metadata
├── config.ts                 # Centralized configuration from env vars
├── env.ts                    # Hono context type definitions
├── context.ts                # Service Proxy (lazy initialization)
├── server.ts                 # Tool/prompt registration
├── middleware/
│   └── mcp-auth.ts           # JWT (jose) + opaque token verification
├── services/
│   ├── types.ts              # Service interface definitions
│   └── in-memory.ts          # Example: in-memory implementation
├── tools/
│   ├── index.ts              # Barrel export
│   ├── errors.ts             # Standardized error responses
│   ├── notes.ts              # Example: CRUD tools (services proxy)
│   └── weather.ts            # Example: external API tool (Open-Meteo)
├── prompts/
│   └── index.ts              # Example MCP prompts
└── resources/
    ├── index.ts              # Lazy fs.readFileSync loader
    └── getting-started.md    # Example documentation
scripts/
└── build.ts                  # Bun bundler → Build Output API v3

建筑

服务代理模式

使此模板工作的核心模式是 服务注入代理 在 context.ts:

// context.ts — tools import this proxy
import type { Services } from './services/types.js'

let _services: Services
export function initServices(impl: Services) { _services = impl }
export const services: Services = new Proxy({} as Services, {
  get(_, prop, receiver) { return Reflect.get(_services, prop, receiver) }
})
// tools/notes.ts — uses the proxy, no concrete dependency
import { services } from '../context.js'
const notes = await services.notes.list()
// app.ts middleware — injects the concrete implementation once
initServices(new InMemoryServices())

为什么? 当10+个工具文件都导入同一个重模块(如数据库客户端)时,Bun的ESM链接器可能会失败,并显示“请求的模块尚未实例化”。代理将大量进口商品隔离在 app.ts.

认证

JWT验证通过 何塞 使用JWKS端点:

  • JWT代币:已在本地验证 jwtVerify() + createRemoteJWKSet()
  • 不透明令牌:可选回拨方式 setOpaqueTokenVerifier()
  • 发展:设置 AUTH_SKIP=true 绕过所有身份验证

构建系统

Bun的本地bundler制作了一首单曲 index.js 文件,然后构建脚本生成Vercel的build Output API v3结构:

.vercel/output/
├── config.json              # Route config
└── functions/
    └── index.func/
        ├── index.js         # Bundled application
        ├── .vc-config.json  # Bun runtime config
        └── src/resources/   # Copied .md files

MCP运输

路线 方法 描述
/ GET 服务器发现(未经身份验证)
/ POST 可流式HTTP传输
/ DELETE 会话清理
/sse GET SSE运输
/message POST HTTP消息传输
/.well-known/oauth-protected-resource GET OAuth元数据(RFC 9728)

定制指南

更换服务层

  1. 在中定义您的接口 src/services/types.ts
  2. 创建一个实现(例如。, src/services/database.ts)
  3. 在 src/app.ts,替换 new InMemoryServices() 随着您的实施

添加新工具

  1. 创建 src/tools/my-tool.ts:
    import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
    import { z } from 'zod'
    import { services } from '../context.js'
    
    export function registerMyTools(server: McpServer) {
      server.tool('my_tool', 'Description', { param: z.string() }, async ({ param }) => {
        // Your logic here
        return { content: [{ type: 'text', text: JSON.stringify({ success: true }) }] }
      })
    }
    
  2. 出口自 src/tools/index.ts
  3. 呼叫 registerMyTools(server) 在 src/server.ts

添加文档资源

  1. 添加 .md 文件到 src/resources/
  2. 将它们注册到 src/resources/index.ts (标题+文件地图)
  3. 将文件名添加到 scripts/build.ts 复制列表

配置身份验证

设置这些环境变量(或在Vercel仪表板中):

变量 描述 示例
AUTH_ISSUER JWT发行人URL https://auth.example.com
AUTH_JWKS_URL JWKS端点 https://auth.example.com/.well-known/jwks.json
AUTH_AUDIENCES 接受的受众(逗号分隔) https://mcp.example.com
AUTH_SKIP 跳过身份验证(仅限开发人员) true

启用Redis会话

集 REDIS_URL 在无服务器调用之间持久化MCP会话:

REDIS_URL="redis://your-redis-host:6379"

依赖项

包装 用途
hono Web框架
mcp-handler MCP协议+会话管理
@modelcontextprotocol/sdk MCP类型定义
jose JWT/JWKS验证
zod 参数验证

许可证

麻省理工学院