CodeBuddy 学习(7):MCP 集成与工具开发
CodeBuddy 学习(7):MCP 集成与工具开发
一、概述:AI 的边界与 MCP 的使命
1.1 AI 的天然局限
| AI 能做到的 | AI 做不到的 |
|---|---|
| 读写项目文件 | 查询数据库看真实表结构 |
| 修改代码 | 调用 GitHub API 看 Issue 内容 |
| 执行终端命令 | 搜索互联网获取最新资料 |
| 分析上下文 | 感知外部系统的状态变化 |
1.2 MCP 是什么
MCP(Model Context Protocol)= AI 的感官延伸。
它是 Anthropic 推出的开放标准协议,让 AI 能够访问外部数据和工具——就像给 AI 装上了"眼睛"(看数据库)、“手”(操作第三方服务)和"搜索"(查互联网)。
工作原理:
- 你在 CodeBuddy 中配置 MCP Server(如 SQLite Server、GitHub Server)。
- 当你提出需求时,AI 判断是否需要调用 MCP 工具。
- AI 通过 Client ↔ Server 通信获取真实数据。
- AI 基于真实数据生成代码——而不是"猜测"你的数据库结构。
核心价值:AI 不再猜你的表结构——它直接看到了。
二、六个核心概念
| 概念 | 角色 | 一句话描述 |
|---|---|---|
| MCP Host | 发起方 | CodeBuddy 本身 |
| MCP Client | 通信组件 | 负责与 Server 建立连接并传输数据 |
| MCP Server | 能力提供方 | 数据库、GitHub、搜索引擎的代理服务 |
| Tools | 可执行动作 | Server 提供的具体功能(如执行 SQL 查询) |
| Resources | 可读取数据 | Server 提供的数据源(如表结构信息) |
| Prompts | 可复用模板 | Server 预定义的提示词模板 |
2.2 六步工作流
| 步骤 | 做什么 | 示例 |
|---|---|---|
| 1. 请求 | 你说"生成用户 CRUD" | AI 判断需要查数据库 |
| 2. 匹配 | AI 从已注册的 Server 中匹配 | “这个任务需要 SQLite MCP” |
| 3. 连接 | Client 连接 SQLite Server | stdin/stdout 通信 |
| 4. 查询 | Server 执行 SQL 获取表结构 | SELECT * FROM sqlite_master |
| 5. 返回 | Server 返回真实表结构 | users(id, name, email, created_at) |
| 6. 生成 | AI 基于真实结构生成代码 | 完整的 CRUD 接口 |
三、实战主线:SQLite MCP 从零到全栈
3.1 原理讲解
SQLite MCP Server 是一个标准的 MCP 服务实现,它接受 SQL 查询并返回结果。CodeBuddy 通过它获得实时读取数据库的能力,这意味着:
- AI 看到的表结构永远是最新的(你加了字段,AI 自动感知)。
- 不需要手动告诉 AI “users 表有 name 字段”——它会自己查。
- 生成的 SQL 查询和 ORM Schema 会精确匹配当前数据库结构。
3.2 步骤一:准备数据库
创建测试数据库文件 data/app.db,包含以下三张表:
-- 用户表
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE NOT NULL,
role TEXT DEFAULT 'user',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- 订单表
CREATE TABLE orders (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL REFERENCES users(id),
amount DECIMAL(10,2) NOT NULL,
status TEXT DEFAULT 'pending',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- 商品表
CREATE TABLE products (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
price DECIMAL(10,2) NOT NULL,
category TEXT,
stock INTEGER DEFAULT 0
);
-- 插入测试数据
INSERT INTO users (name, email, role) VALUES
('张三', 'zhangsan@example.com', 'admin'),
('李四', 'lisi@example.com', 'user'),
('王五', 'wangwu@example.com', 'user');
INSERT INTO orders (user_id, amount, status) VALUES
(1, 299.00, 'paid'),
(2, 159.50, 'pending'),
(1, 89.00, 'shipped');
INSERT INTO products (name, price, category, stock) VALUES
('机械键盘', 399.00, '电子产品', 50),
('Python 编程书', 79.00, '图书', 200),
('蓝牙耳机', 259.00, '电子产品', 30);
创建数据库(在终端执行):
mkdir -p data
sqlite3 data/app.db < init.sql
# 或手动逐条执行上述 SQL
3.3 步骤二:配置 MCP
编辑 ~/.codebuddy/mcp.json(或项目根目录的 .codebuddy/mcp.json):
{
"mcpServers": {
"sqlite": {
"command": "npx",
"args": ["-y", "mcp-server-sqlite", "data/app.db"]
}
}
}
配置说明:
sqlite:MCP Server 的名称(可以自定义)。command: "npx":通过 npx 运行(自动下载并使用最新版)。args: ["-y", "mcp-server-sqlite", "data/app.db"]:-y跳过确认,data/app.db是数据库文件路径(相对于项目根目录)。
3.4 步骤三:验证配置
在 CodeBuddy 对话框中输入:
请列出当前数据库中所有表及其字段结构。
预期输出:
数据库包含以下三张表:
users 表:
- id (INTEGER, PRIMARY KEY)
- name (TEXT, NOT NULL)
- email (TEXT, UNIQUE, NOT NULL)
- role (TEXT, DEFAULT 'user')
- created_at (DATETIME, DEFAULT CURRENT_TIMESTAMP)
orders 表:
- id (INTEGER, PRIMARY KEY)
- user_id (INTEGER, REFERENCES users(id))
- amount (DECIMAL(10,2), NOT NULL)
- status (TEXT, DEFAULT 'pending')
- created_at (DATETIME, DEFAULT CURRENT_TIMESTAMP)
products 表:
- id (INTEGER, PRIMARY KEY)
- name (TEXT, NOT NULL)
- price (DECIMAL(10,2), NOT NULL)
- category (TEXT)
- stock (INTEGER, DEFAULT 0)
如果返回了真实的表结构 → 配置成功 ✅。
四、场景一:生成 Prisma Schema
4.1 操作
在对话中输入:
读取所有表结构,生成完整的 Prisma Schema。要求:
- 外键使用 @relation 声明
- 所有注释使用中文
- @@index 覆盖常用查询列
- @@map 映射原表名
4.2 预期输出
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "sqlite"
url = "file:./data/app.db"
}
/// 用户表
model User {
id Int @id @default(autoincrement()) @map("id")
name String @map("name")
email String @unique @map("email")
role String @default("user") @map("role")
createdAt DateTime @default(now()) @map("created_at")
orders Order[]
@@index([email])
@@index([role])
@@map("users")
}
/// 订单表
model Order {
id Int @id @default(autoincrement()) @map("id")
userId Int @map("user_id")
amount Decimal @map("amount")
status String @default("pending") @map("status")
createdAt DateTime @default(now()) @map("created_at")
user User @relation(fields: [userId], references: [id])
@@index([userId])
@@index([status])
@@map("orders")
}
/// 商品表
model Product {
id Int @id @default(autoincrement()) @map("id")
name String @map("name")
price Decimal @map("price")
category String? @map("category")
stock Int @default(0) @map("stock")
@@index([category])
@@map("products")
}
4.3 验证
检查生成的 Schema 是否精确匹配数据库的实际结构:
users字段名与表中name/email/role/created_at一一对应。orders.user_id→userId的驼峰转换正确。@relation的外键引用正确指向User.id。
五、场景二:自动生成完整 CRUD
5.1 操作
基于 users 表生成完整的 CRUD 接口。要求:
- GET 列表:支持分页(page/pageSize)、role 筛选、name 模糊搜索
- GET 详情:根据 id 获取单个用户
- POST 创建:Zod 校验 name/email 格式
- PUT 更新:部分字段更新
- DELETE 删除:软删除(设置 deleted_at)
- 使用 Prisma ORM,TypeScript 类型安全
- Next.js App Router 的 Route Handler 格式
5.2 预期输出(核心代码)
// src/app/api/users/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { prisma } from '@/lib/prisma';
import { z } from 'zod';
// 查询参数校验
const querySchema = z.object({
page: z.coerce.number().int().min(1).default(1),
pageSize: z.coerce.number().int().min(1).max(100).default(10),
role: z.enum(['admin', 'user']).optional(),
search: z.string().optional(),
});
// 创建用户校验
const createSchema = z.object({
name: z.string().min(1, '姓名不能为空').max(50),
email: z.string().email('邮箱格式不正确'),
role: z.enum(['admin', 'user']).default('user'),
});
export async function GET(request: NextRequest) {
try {
const { searchParams } = new URL(request.url);
const { page, pageSize, role, search } = querySchema.parse(
Object.fromEntries(searchParams)
);
// 构建查询条件
const where: any = { deletedAt: null };
if (role) where.role = role;
if (search) {
where.OR = [
{ name: { contains: search } },
{ email: { contains: search } },
];
}
// 并行查询数据和总数
const [users, total] = await Promise.all([
prisma.user.findMany({
where,
skip: (page - 1) * pageSize,
take: pageSize,
orderBy: { createdAt: 'desc' },
}),
prisma.user.count({ where }),
]);
return NextResponse.json({
code: 200,
data: { list: users, total, page, pageSize },
message: 'success',
});
} catch (error) {
if (error instanceof z.ZodError) {
return NextResponse.json(
{ code: 400, data: null, message: error.errors[0].message },
{ status: 400 }
);
}
return NextResponse.json(
{ code: 500, data: null, message: '服务器内部错误' },
{ status: 500 }
);
}
}
export async function POST(request: NextRequest) {
try {
const body = await request.json();
const data = createSchema.parse(body);
// 检查邮箱唯一性
const existing = await prisma.user.findUnique({
where: { email: data.email },
});
if (existing) {
return NextResponse.json(
{ code: 400, data: null, message: '该邮箱已被注册' },
{ status: 400 }
);
}
const user = await prisma.user.create({ data });
return NextResponse.json(
{ code: 200, data: user, message: '创建成功' },
{ status: 201 }
);
} catch (error) {
if (error instanceof z.ZodError) {
return NextResponse.json(
{ code: 400, data: null, message: error.errors[0].message },
{ status: 400 }
);
}
return NextResponse.json(
{ code: 500, data: null, message: '服务器内部错误' },
{ status: 500 }
);
}
}
5.3 验证
用 curl 或 Postman 测试:
# 列表查询
curl "http://localhost:3000/api/users?page=1&pageSize=10&search=张"
# 创建用户
curl -X POST http://localhost:3000/api/users \
-H "Content-Type: application/json" \
-d '{"name":"赵六","email":"zhaoliu@example.com"}'
六、场景三:数据库变更同步
这是 MCP 最有价值的场景——让 AI 自动感知数据库变化并同步所有依赖。
场景:你在 users 表中新增了 phone 字段。
-- 在数据库中执行
ALTER TABLE users ADD COLUMN phone TEXT;
然后在对话中输入:
users 表刚刚加了 phone 字段,帮我:
1. 更新 Prisma Schema
2. 更新 TypeScript 类型定义
3. 更新 API 接口中的校验和返回值
4. 更新前端表单
5. 生成变更清单
AI 会通过 MCP 读取最新表结构,感知到 phone 字段的存在,然后自动更新所有相关代码。
最佳实践:始终让 AI 通过 MCP 自己查表结构,不要凭记忆告诉它"users 表有这些字段……"。你在记忆里告诉 AI 的内容可能已经过时了,而 MCP 读取的是实时数据。
七、更多 MCP Server 示例
| Server | 配置方式 | 用处 |
|---|---|---|
| GitHub | npx -y @teolin/mcp-github + Token |
查 Issue / PR / 代码 |
| DuckDuckGo | npx -y @anthropic/mcp-server-duckduckgo-search |
免 Key 互联网搜索 |
| PostgreSQL | npx -y @modelcontextprotocol/server-postgres |
查 PostgreSQL 数据库 |
| 文件系统 | 内置支持 | 读写本地文件 |
GitHub MCP 配置示例(mcp.json):
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@teolin/mcp-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_xxxxxxxxxxxx"
}
}
}
}
八、调试过程
8.1 MCP 不生效 / 未检测到工具
现象:输入"查数据库表结构",AI 返回"我无法访问数据库"。
原因排查:
1. mcp.json 格式错误(JSON 语法错误,如多余的逗号)。
2. 路径问题:data/app.db 相对于项目根目录的路径不正确。
3. 未重启 CodeBuddy:修改 mcp.json 后需要重启。
排查步骤:
1. 用 JSON 验证工具检查 mcp.json 格式是否正确。
2. 在终端中手动验证 Server 能否启动:
npx -y mcp-server-sqlite data/app.db
如果有报错,根据报错信息修复。
3. 重启 CodeBuddy(关闭并重新打开)。
修复:修正 JSON 格式 → 修正路径 → 重启。
8.2 连接失败
现象:MCP Server 配置了但连接失败,AI 请求超时。
原因排查:
1. 网络问题:npx 首次运行需要下载包,可能超时。
2. npm 镜像问题:国内网络可能无法直接访问 npm registry。
排查步骤:
1. 在终端手动执行安装:
npm install -g mcp-server-sqlite
然后修改 mcp.json,将 "command": "npx" 改为 "command": "mcp-server-sqlite"。
2. 如果下载慢,先设置国内镜像:
npm config set registry https://registry.npmmirror.com/
修复:全局安装 → 改用本地命令 → 或配置代理/VPN。
8.3 Token 无效(GitHub MCP)
现象:GitHub MCP 报 "401 Unauthorized"。
原因排查:
1. Token 过期或被撤销。
2. Token 权限不足(没有读取 Issue/PR 的权限)。
排查步骤:
1. 登录 GitHub → Settings → Developer settings → Personal access tokens。
2. 检查 Token 状态和权限范围。
3. 如果过期,重新生成并更新 mcp.json 中的环境变量。
修复:重新生成 Token → 确保勾选 repo 和 read:org 权限 → 更新配置 → 重启。
九、小结
MCP = AI 的感官延伸:看到数据库、触摸 GitHub、搜索互联网
核心价值:AI 不再猜你的表结构——它直接看到了
实战主线:SQLite → 查表 → Schema → CRUD → 智能查询 → 变更同步
一个原则:始终让 AI 通过 MCP 自己查,不要凭记忆告诉它
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)