统一声明:
1.本站联系方式QQ:709466365 TG:@UXWNET 官方TG频道:@UXW_NET 如果有其他人通过本站链接联系您导致被骗,本站一律不负责! 2.需要付费搭建请联系站长QQ:709466365 TG:@UXWNET 3.免实名域名注册购买- 游侠云域名 4.免实名国外服务器购买- 游侠网云服务Model Context Protocol (MCP) 正在改变 AI 应用连接外部工具和数据的方式。虽然许多教程停留在”连接 GitHub”或”读取文件”的层面,但 MCP 的真正力量在于解锁您的内部数据——数据库、内部 API、知识库和专有系统——以结构化、安全的方式向 AI 助手开放。
本文将带您完成构建生产级 MCP 服务器的全过程,将组织的内部数据暴露给 AI 模型,涵盖认证、多租户、流式传输和实际部署所需的模式。

什么是 MCP,为什么它对内部数据很重要?
MCP 是由 Anthropic 创建的开放协议,标准化了 AI 助手发现和调用外部工具的方式。将其想象成 AI 的 USB-C 端口——一个标准接口,让任何 AI 模型连接到任何数据源。
在 MCP 之前,将 AI 助手连接到内部数据库意味着:
- 为每个 LLM 提供商编写自定义工具定义
- 将数据访问逻辑硬编码到 AI 应用中
- 切换模型或添加新数据源时重新构建一切
MCP 将数据层与AI 层分离。您的 MCP 服务器暴露工具和资源,任何兼容 MCP 的客户端(Claude、ChatGPT、您的自定义应用)都可以使用它们而无需修改。
架构概览

MCP 服务器位于 AI 客户端和内部系统之间,处理:
- 工具发现:告诉 AI 有哪些可用操作
- 参数验证:确保 AI 发送正确的输入
- 数据访问:查询内部系统
- 响应格式化:返回 AI 可以推理的结构化数据
- 认证:验证请求者身份
项目设置
让我们构建一个暴露内部员工目录和项目管理系统的 MCP 服务器:
mkdir internal-data-mcp && cd internal-data-mcp
npm init -y
npm install @modelcontextprotocol/sdk zod express pg
npm install -D typescript @types/node @types/express @types/pg tsx
构建 MCP 服务器
步骤 1:服务器骨架
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
const server = new McpServer(
{ name: "internal-data", version: "1.0.0" },
{ capabilities: { tools: {}, resources: {} } }
);
步骤 2:连接内部数据
创建数据访问层(以 PostgreSQL 为例):
import pg from "pg";
const pool = new pg.Pool({
connectionString: process.env.INTERNAL_DB_URL,
max: 10,
idleTimeoutMillis: 30000,
});
export async function searchEmployees(
query: string,
department?: string
): Promise<Employee[]> {
// 参数化查询防止 SQL 注入
const result = await pool.query(
`SELECT id, name, email, department, role FROM employees
WHERE name ILIKE $1 OR email ILIKE $1
ORDER BY name LIMIT 25`,
[`%${query}%`]
);
return result.rows;
}
步骤 3:定义工具
工具设计是最重要的部分。好的工具定义直接影响 AI 使用数据的效果:
server.tool(
"search_employees",
"搜索内部员工目录,按姓名、邮箱或角色查找。当用户询问人员、团队或组织结构时使用。",
{
query: z.string().describe("搜索词:员工姓名、邮箱或角色"),
department: z.string().optional().describe("按部门名称过滤"),
},
async ({ query, department }) => {
const employees = await searchEmployees(query, department);
if (employees.length === 0) {
return { content: [{ type: "text", text: `未找到匹配 "${query}" 的员工。` }] };
}
const formatted = employees.map(e =>
`- **${e.name}** (${e.email})\n 角色:${e.role} | 部门:${e.department}`
).join("\n");
return { content: [{ type: "text", text: `找到 ${employees.length} 名员工:\n\n${formatted}` }] };
}
);
工具设计原则
- 描述性的名称和描述:AI 完全根据描述决定调用哪个工具
- 带描述的类型化参数:使用 Zod 的
.describe()说明每个字段的期望 - 结构化返回值:使用 Markdown 表格或结构化列表,而非原始 JSON
添加认证
Bearer Token 认证
最简单的方法是验证每个请求的 token:
function authMiddleware(req, res, next) {
const authHeader = req.headers.authorization;
if (!authHeader?.startsWith("Bearer ")) {
return res.status(401).json({ error: "Missing authorization header" });
}
const token = authHeader.slice(7);
const claims = validateInternalToken(token);
req.userId = claims.sub;
req.orgId = claims.org;
next();
}
OAuth 2.0 for MCP
对于支持 MCP 内置 OAuth 流的客户端,可以实现完整的 OAuth 握手。MCP SDK 提供OAuthServerProvider接口,包括客户端注册、授权重定向、token 交换和验证等方法。
按用户范围限制数据访问
这是内部数据 MCP 服务器最重要的部分:AI 应该只访问请求用户有权看到的数据。
server.tool(
"search_employees",
"搜索员工目录。结果根据您的访问级别过滤。",
{ query: z.string().describe("姓名、邮箱或角色") },
async ({ query }) => {
const ctx = getUserContext();
// 执行访问边界
let departmentFilter;
if (ctx.role === "manager") {
departmentFilter = await getUserDepartment(ctx.userId);
}
const employees = await searchEmployees(query, departmentFilter);
// 根据角色隐藏敏感字段
const results = employees.map(e => ({
name: e.name,
email: e.email,
department: e.department,
role: e.role,
...(["admin", "hr"].includes(ctx.role) ?
{ start_date: e.start_date, manager_id: e.manager_id } : {}),
}));
return { content: [{ type: "text", text: formatEmployeeList(results) }] };
}
);
生产部署
Docker 化
使用两阶段构建保持镜像精简:
FROM node:22-slim AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:22-slim AS runtime
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
ENV NODE_ENV=production
EXPOSE 3100
HEALTHCHECK --interval=30s --timeout=5s CMD curl -f http://localhost:3100/health || exit 1
CMD ["node", "dist/index.js"]
健康检查和监控
app.get("/health", async (_req, res) => {
const checks = { database: false, ticketingApi: false };
try {
await pool.query("SELECT 1");
checks.database = true;
} catch {}
try {
const resp = await fetch(`${process.env.TICKETING_API_URL}/health`);
checks.ticketingApi = resp.ok;
} catch {}
const healthy = Object.values(checks).every(Boolean);
res.status(healthy ? 200 : 503).json({
status: healthy ? "healthy" : "degraded",
checks,
uptime: process.uptime(),
});
});
日志和审计
每次工具调用都应该记录:
function createAuditLogger() {
return {
logToolCall(params) {
console.log(JSON.stringify({
event: "mcp_tool_call",
timestamp: new Date().toISOString(),
...params,
}));
},
};
}
常见陷阱
- 返回太多数据:LLM 有上下文限制,分页或限制结果(25 项是合理的默认值)
- 工具描述太笼统:描述是模型阅读的内容,不要仅依赖工具名称
- 缺少错误处理:返回结构化错误消息,而非堆栈跟踪
- 没有限流:AI 工具调用可能在循环中发生,需要熔断器
- 不用实际 AI 模型测试:在单元测试中正确的工具可能让模型困惑
总结
为内部数据构建 MCP 服务器关乎三件事:
- 好的工具设计——清晰的描述、类型化参数、结构化响应
- 适当的访问控制——认证用户、范围数据访问、记录一切
- 生产就绪——健康检查、限流、错误处理、监控
协议本身很简单。困难的工作是在内部系统之上设计正确的抽象,使 AI 能够有效使用它们,同时不泄露数据或压垮上下文窗口。
从一个或两个高价值工具(员工查找、文档搜索)开始,用真实用户测试,然后逐步扩展。最好的内部 MCP 服务器根据人们实际询问 AI 的内容有机增长。
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,请使用WINRAR解压,如遇到无法解压的请联系管理员!
8. 精力有限,不少源码未能详细测试(解密),不能分辨部分源码是病毒还是误报,所以没有进行任何修改,大家使用前请进行甄别!
站长QQ:709466365 站长邮箱:709466365@qq.com



