MCP 工具链统一配置
AI 编程工具只能读写代码文件和执行终端命令——它无法直接查询数据库、浏览网页、读取 Figma 设计稿、操作 GitHub Issue。MCP(Model Context Protocol)打破了这个限制。它是 Anthropic 提出的开放协议,让 AI 工具通过标准接口连接任意外部系统。一个 MCP Server 就像一个"AI 插件",把数据库查询、浏览器操作、设计稿读取变成 AI 可以调用的工具。本章从协议原理出发,配置一套覆盖开发全流程的 MCP 工具链。
1. MCP 协议原理
1.1 为什么需要 MCP
在 MCP 出现之前,AI 工具连接外部系统的方式是碎片化的:
Cursor:需要安装特定插件 → 每个服务一个插件
Claude Code:需要写自定义脚本 → 每个项目重复造轮子
Copilot:通过 GitHub Actions → 只能异步,不能实时
MCP 统一了这一切——一次实现,所有支持 MCP 的 AI 工具都能使用:
┌─────────────────────────────────────────┐
│ AI 工具(MCP Client) │
│ Cursor / Claude Code / Windsurf / ... │
├─────────────────────────────────────────┤
│ MCP Protocol(JSON-RPC over stdio/SSE) │
├──────┬──────┬──────┬──────┬────────────┤
│ DB │ Git │ Figma│Browser│ Custom │
│Server│Server│Server│Server │ Server │
└──────┴──────┴──────┴──────┴────────────┘
1.2 MCP 的核心概念
MCP 定义了三种能力:
| 概念 | 说明 | 示例 |
|---|---|---|
| Tools | AI 可调用的函数 | query_database(sql), create_issue(title, body) |
| Resources | AI 可读取的数据 | 数据库 schema、设计稿内容、文件列表 |
| Prompts | 预定义的提示词模板 | "分析这个表的数据分布" |
Tools 是最常用的——AI 通过 Tool Calling 机制调用 MCP Server 暴露的函数,获取结果后继续推理。
1.3 MCP 通信方式
MCP 支持两种传输协议:
stdio(本地进程)
AI 工具 ←→ stdin/stdout ←→ MCP Server 进程
AI 工具启动 MCP Server 作为子进程,通过标准输入输出通信。适合本地开发工具。
SSE(远程服务)
AI 工具 ←→ HTTP SSE ←→ MCP Server(远程)
通过 HTTP Server-Sent Events 通信。适合团队共享的服务(如共用的数据库查询服务)。
1.4 配置方式
不同 AI 工具的 MCP 配置文件:
Claude Code:~/.claude/claude_desktop_config.json 或项目级 .mcp.json
{
"mcpServers": {
"postgres": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres"],
"env": {
"DATABASE_URL": "postgresql://user:pass@localhost:5432/mydb"
}
}
}
}Cursor:Settings → MCP Servers
{
"mcpServers": {
"postgres": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres"],
"env": {
"DATABASE_URL": "postgresql://user:pass@localhost:5432/mydb"
}
}
}
}Windsurf:.windsurf/mcp.json
配置格式基本一致——这就是 MCP 标准化的价值。
2. 数据库 MCP
2.1 PostgreSQL MCP Server
数据库 MCP 是最高频的使用场景——让 AI 直接查询数据库,理解真实数据结构:
{
"mcpServers": {
"postgres": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres"],
"env": {
"DATABASE_URL": "postgresql://dev:dev@localhost:5432/nextsaas"
}
}
}
}配置后 AI 可以:
用户: "users 表有哪些字段?"
AI: [调用 MCP: list_tables → describe_table('users')]
"users 表包含以下字段:
- id: uuid (PK)
- email: text (unique, not null)
- name: text
- avatar_url: text
..."
用户: "查一下最近 7 天注册的用户数量"
AI: [调用 MCP: query("SELECT COUNT(*) FROM users WHERE created_at > NOW() - INTERVAL '7 days'")]
"最近 7 天有 42 位新注册用户。"
2.2 安全配置
永远不要把生产数据库连接给 MCP。推荐做法:
开发环境:直连本地数据库(localhost)
→ 无风险,随意查询
Staging 环境:只读用户 + 连接池限制
→ CREATE USER mcp_readonly WITH PASSWORD 'xxx';
→ GRANT SELECT ON ALL TABLES IN SCHEMA public TO mcp_readonly;
生产环境:❌ 禁止
→ 通过 Admin Dashboard 查询
2.3 Drizzle Studio 替代方案
如果不想暴露数据库连接,可以用 Drizzle Studio 的 MCP Server(社区方案):
{
"mcpServers": {
"drizzle": {
"command": "npx",
"args": ["drizzle-mcp-server"],
"env": {
"DRIZZLE_CONFIG": "./drizzle.config.ts"
}
}
}
}这种方式 AI 通过 Drizzle 的类型安全 API 查询,而不是直接写 SQL,更安全。
3. 浏览器 MCP
3.1 Playwright MCP Server
让 AI 能操控浏览器——打开页面、截图、填写表单、点击按钮:
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": ["@playwright/mcp@latest"]
}
}
}配置后 AI 可以:
用户: "打开 localhost:3000/dashboard,截图看看效果"
AI: [调用 MCP: navigate("http://localhost:3000/dashboard")]
[调用 MCP: screenshot()]
"Dashboard 页面截图如下:[图片]
我注意到侧边栏的 logo 没有正确显示。"
用户: "帮我测试登录流程"
AI: [调用 MCP: navigate("/login")]
[调用 MCP: fill("#email", "[email protected]")]
[调用 MCP: fill("#password", "password123")]
[调用 MCP: click("button[type=submit]")]
[调用 MCP: screenshot()]
"登录成功,已跳转到 Dashboard。"
3.2 浏览器 MCP 的实际用途
| 场景 | 操作 | 价值 |
|---|---|---|
| UI 验证 | 截图并分析 | 不用切到浏览器就能看效果 |
| E2E 测试 | 自动化操作 | AI 写测试的同时跑测试 |
| Bug 复现 | 按步骤操作截图 | 给 Bug 报告附证据 |
| 响应式检查 | 不同窗口大小截图 | 一次检查多种设备 |
| 表单测试 | 填写各种边界值 | 自动化边界测试 |
3.3 Browserbase MCP
如果需要更强大的浏览器能力(如绕过 CAPTCHA、处理复杂 JS),可以用云端浏览器服务:
{
"mcpServers": {
"browserbase": {
"command": "npx",
"args": ["@browserbasehq/mcp-server"],
"env": {
"BROWSERBASE_API_KEY": "your-api-key"
}
}
}
}4. Figma MCP
4.1 设计稿转代码
Figma MCP 让 AI 能读取 Figma 设计稿的结构、样式和内容:
{
"mcpServers": {
"figma": {
"command": "npx",
"args": ["figma-mcp-server"],
"env": {
"FIGMA_ACCESS_TOKEN": "your-figma-token"
}
}
}
}典型工作流:
用户: "把这个 Figma 页面转成 React 组件
https://www.figma.com/file/xxx?node-id=123"
AI: [调用 MCP: get_figma_node(fileId, nodeId)]
[获取节点的布局、颜色、字体、间距]
"根据设计稿,我创建了以下组件:
- 使用 flex 布局,间距 24px
- 标题: text-2xl font-bold text-gray-900
- 卡片: rounded-xl border shadow-sm p-6
..."
4.2 设计走查
用户: "对比 Figma 设计稿和实际页面,找出差异"
AI: [调用 Figma MCP: 获取设计稿]
[调用 Playwright MCP: 截取实际页面]
[对比分析]
"发现以下差异:
1. 标题字号:设计稿 24px,实际 20px
2. 卡片圆角:设计稿 16px,实际 12px
3. 按钮颜色:设计稿 #2563EB,实际 #3B82F6"
5. GitHub MCP
5.1 配置
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["@modelcontextprotocol/server-github"],
"env": {
"GITHUB_TOKEN": "ghp_your_token"
}
}
}
}5.2 常见用法
// 创建 Issue
用户: "给这个 Bug 创建一个 GitHub Issue,标签为 bug 和 priority-high"
AI: [调用 MCP: create_issue(title, body, labels)]
// PR 管理
用户: "列出所有待审查的 PR"
AI: [调用 MCP: list_pull_requests(state: 'open', review: 'required')]
// Issue 驱动开发
用户: "读取 Issue #42 的描述,实现其中的需求"
AI: [调用 MCP: get_issue(42)]
[理解需求]
[开始编码]
// 自动关联
用户: "提交代码并创建 PR,关联 Issue #42"
AI: [执行 git add, commit]
[调用 MCP: create_pull_request(title, body: "Closes #42")]
6. 文件系统与搜索 MCP
6.1 文件系统 MCP
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem"],
"env": {
"ALLOWED_PATHS": "/Users/me/projects/nextsaas"
}
}
}
}6.2 搜索 MCP
让 AI 能搜索互联网,获取最新文档和资讯:
{
"mcpServers": {
"tavily": {
"command": "npx",
"args": ["tavily-mcp-server"],
"env": {
"TAVILY_API_KEY": "your-api-key"
}
}
}
}7. 自定义 MCP Server
7.1 何时需要自定义
官方和社区 MCP Server 覆盖了常见场景,但业务特定的需求需要自定义:
- 查询内部 API(公司内部服务)
- 操作特定的 SaaS 工具(Jira、Notion、Slack)
- 封装复杂的数据库查询(业务报表)
- 集成 CI/CD 系统
7.2 用 TypeScript 编写 MCP Server
// mcp-servers/internal-api/index.ts
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
import { z } from 'zod'
const server = new McpServer({
name: 'internal-api',
version: '1.0.0',
})
// 注册工具:查询内部用户数据
server.tool(
'get_user_stats',
'Get user statistics for the current month',
{
tenantId: z.string().uuid().describe('The tenant ID to query'),
},
async ({ tenantId }) => {
const res = await fetch(`${process.env.INTERNAL_API_URL}/stats/users`, {
headers: { 'X-Tenant-Id': tenantId, 'Authorization': `Bearer ${process.env.INTERNAL_API_KEY}` },
})
const data = await res.json()
return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] }
}
)
// 注册工具:查询部署状态
server.tool(
'get_deployment_status',
'Get the current deployment status from Vercel',
{},
async () => {
const res = await fetch('https://api.vercel.com/v6/deployments?limit=5', {
headers: { Authorization: `Bearer ${process.env.VERCEL_TOKEN}` },
})
const { deployments } = await res.json()
const summary = deployments.map((d: any) => ({
url: d.url,
state: d.state,
createdAt: d.createdAt,
source: d.meta?.githubCommitMessage || 'N/A',
}))
return { content: [{ type: 'text', text: JSON.stringify(summary, null, 2) }] }
}
)
// 注册资源:提供数据库 Schema
server.resource(
'database-schema',
'schema://database',
async (uri) => {
// 从 drizzle schema 文件读取
const schema = await fs.readFile('./lib/db/schema.ts', 'utf-8')
return { contents: [{ uri: uri.href, mimeType: 'text/typescript', text: schema }] }
}
)
// 启动服务
const transport = new StdioServerTransport()
await server.connect(transport)配置使用:
{
"mcpServers": {
"internal": {
"command": "npx",
"args": ["tsx", "./mcp-servers/internal-api/index.ts"],
"env": {
"INTERNAL_API_URL": "https://api.internal.company.com",
"INTERNAL_API_KEY": "xxx",
"VERCEL_TOKEN": "xxx"
}
}
}
}8. MCP 工具链配置方案
8.1 推荐配置
{
"mcpServers": {
"postgres": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres"],
"env": { "DATABASE_URL": "postgresql://dev:dev@localhost:5432/nextsaas" }
},
"playwright": {
"command": "npx",
"args": ["@playwright/mcp@latest"]
},
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": { "GITHUB_TOKEN": "ghp_xxx" }
},
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem"],
"env": { "ALLOWED_PATHS": "/Users/me/projects" }
}
}
}8.2 各场景对应的 MCP
| 开发场景 | MCP Server | 用途 |
|---|---|---|
| 数据库调试 | postgres | 查询数据、检查 schema |
| UI 开发 | playwright | 截图验证、交互测试 |
| 设计还原 | figma | 读取设计稿、对比差异 |
| Issue 管理 | github | 创建/读取 Issue、管理 PR |
| 信息检索 | tavily | 搜索文档、查找解决方案 |
| 部署管理 | 自定义 | 查看部署状态、回滚 |
| 内部 API | 自定义 | 查询业务数据、触发任务 |
本章小结
- MCP 统一了 AI 工具的外部集成:一次实现,Cursor / Claude Code / Windsurf 都能用
- 三种能力:Tools(可调用函数)、Resources(可读取数据)、Prompts(提示词模板)
- 数据库 MCP:让 AI 直接查询 schema 和数据,但永远不要连生产数据库
- 浏览器 MCP:Playwright 实现截图验证、交互测试、Bug 复现
- Figma MCP:设计稿转代码、设计走查
- GitHub MCP:Issue 驱动开发、PR 管理、自动关联
- 自定义 MCP:TypeScript SDK 快速封装内部 API 和业务逻辑
- 安全第一:MCP 涉及外部系统访问,严格控制权限和数据范围