新闻详情

新闻详情

首页 / 资讯中心 / 详情

从0写一个 MCP 服务器:用 Node/TS 把 SQL Server 里的 ERP 数据变成 AI 助手能查的工具(TaoToken 统一 Key 接入版)

发布时间:2026/9/29 6:00:11来源:尧图网络
从0写一个 MCP 服务器:用 Node/TS 把 SQL Server 里的 ERP 数据变成 AI 助手能查的工具(TaoToken 统一 Key 接入版)
1. 为什么要把 ERP 数据接给 AI 助手很多做电商或制造业的朋友都遇到过这个场景ERP 系统里躺着商品、订单、成本、库存这些核心数据但 AI 助手完全碰不到。你问它上个月利润最高的 10 个 SKU 是哪些它只能干瞪眼因为它既不会连 SQL Server你也不该直接把数据库账号密码丢给它。MCPModel Context Protocol模型上下文协议就是解决这个断层的东西。它让你把查数据库这件事封装成一个受控的工具ToolAI 助手负责决定什么时候调用、传什么参数你的服务端负责真正执行 SQL 并返回结果。边界清晰权限可控。这篇我会用一个电商 ERP 场景从零用 Node/TS 写一个 MCP 服务器把 SQL Server 里的商品表、订单表、成本利润表暴露成 AI 能调用的工具再通过 TaoToken 统一 Key 接入模型通道。全程可复制跟着敲就能跑起来。适合谁看有 Node/TS 基础、手上有 SQL Server 数据、想让 Claude 或 Codex 直接查业务库的后端同学。不需要你懂 MCP 协议细节我会把关键机制讲清楚。2. TaoToken 前置准备统一 Key 与接入通道在写服务端之前先把模型通道准备好。MCP 服务器本身只负责提供工具真正调用工具的是 AI 客户端Claude Desktop、Codex CLI 等。这些客户端要连大模型就需要一个稳定的 API 通道。TaoToken 在这里的角色是统一 Key 和 API 通道你注册后拿到一个 Key就能在多个模型客户端里复用不用每个客户端单独配一套。官网入口在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 地址是 https://taotoken.net/api 。具体操作分三步第一步登录控制台创建 API Key。地址是 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 在 API Keys 页面点新建复制生成的 Key形如 sk-xxxx这个 Key 只显示一次存好。第二步如果你要长期跑编码或 Agent 任务建议看下 Coding Plan地址 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 它针对高频调用做了额度优化比按次计费划算。第三步验证模型通道是否通。可以直接在模型对话页测试地址 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 选一个模型发一句话能正常回复说明 Key 和通道都没问题。注意MCP 服务器和模型通道是两件事。MCP 服务器跑在你本地或内网负责连 SQL Server模型通道负责 AI 的推理。两者通过 AI 客户端串起来别搞混。3. 从零搭 MCP 服务器环境、依赖与 SQL Server 连接3.1 环境准备你需要 Node.js 18 以上建议 22一台能连通的 SQL Server示例用your-server-ip,1433库名demo_db以及一个支持 MCP 的客户端。下面所有库名、表名、IP 都是示意替换成你自己的。3.2 项目初始化mkdir erp-mcp cd erp-mcp npm init -y npm install modelcontextprotocol/sdk mssql zod npm install -D tsx typescript types/node types/mssqltsx让我们直接跑 TypeScript省掉编译步骤调试期很省事。3.3 连接 SQL Server用mssql底层是 tedious 驱动封装一个带连接池的配置。新建src/db.tsimport sql from mssql; export const sqlConfig: sql.config { user: process.env.ERP_SA || sa, password: process.env.ERP_PWD || your_strong_password, server: your-server-ip, port: 1433, database: demo_db, options: { encrypt: false, trustServerCertificate: true, }, pool: { max: 10, min: 0, idleTimeoutMillis: 30000, }, }; export async function getPool() { return sql.connect(sqlConfig); }密码走环境变量ERP_PWD别硬编码进仓库。生产环境务必给 MCP 单独建一个只读账号只授予SELECT权限。3.4 定义三个业务工具新建src/index.ts注册三个工具查商品、查订单、按 SKU 汇总成本利润。import { McpServer } from modelcontextprotocol/sdk/server/mcp.js; import { StdioServerTransport } from modelcontextprotocol/sdk/server/stdio.js; import { z } from zod; import { getPool } from ./db.js; import sql from mssql; const server new McpServer({ name: erp-mcp, version: 1.0.0 }); // 工具1按关键词/分类查商品 server.tool( query_products, 按关键词或分类查询 ERP 商品表(tb_products), { keyword: z.string().optional().describe(商品名模糊匹配), category: z.string().optional().describe(商品分类), }, async ({ keyword, category }) { const pool await getPool(); const req pool.request(); let sqlText SELECT TOP 50 ProductId, ProductName, Sku, Price, Category FROM tb_products WHERE 11; if (keyword) { req.input(kw, sql.NVarChar, %${keyword}%); sqlText AND ProductName LIKE kw; } if (category) { req.input(cat, sql.NVarChar, category); sqlText AND Category cat; } const r await req.query(sqlText); return { content: [{ type: text, text: JSON.stringify(r.recordset, null, 2) }], }; } ); // 工具2查指定日期范围的订单 server.tool( query_orders, 查询指定日期范围内的订单(tb_orders), { start: z.string().describe(起始日期 YYYY-MM-DD), end: z.string().describe(结束日期 YYYY-MM-DD), }, async ({ start, end }) { const pool await getPool(); const req pool.request(); req.input(s, sql.Date, start); req.input(e, sql.Date, end); const r await req.query( SELECT OrderId, ProductId, Qty, Amount, Status FROM tb_orders WHERE CreateAt BETWEEN s AND e ); return { content: [{ type: text, text: JSON.stringify(r.recordset, null, 2) }], }; } ); // 工具3按 SKU 汇总某月成本与利润 server.tool( profit_summary, 按 SKU 汇总某月成本与利润, { month: z.string().describe(月份 YYYY-MM), }, async ({ month }) { const pool await getPool(); const req pool.request(); req.input(m, sql.NVarChar, ${month}%); const r await req.query( SELECT ProductId, SUM(Amount) AS Revenue, SUM(Cost) AS Cost, SUM(Amount - Cost) AS Profit FROM tb_orders WHERE CreateAt LIKE m GROUP BY ProductId ORDER BY Profit DESC ); return { content: [{ type: text, text: JSON.stringify(r.recordset, null, 2) }], }; } ); const transport new StdioServerTransport(); await server.connect(transport); console.error(ERP MCP server running on stdio);三个工具都用req.input()参数化这是防注入的关键后面排障会细说。3.5 启动与注册到客户端本地跑起来export ERP_PWD你的密码 npx tsx src/index.ts看到ERP MCP server running on stdio就说明服务端起来了。接着注册到 Claude Desktop 的claude_desktop_config.json{ mcpServers: { erp: { command: npx, args: [tsx, /path/to/erp-mcp/src/index.ts], env: { ERP_PWD: 你的密码 } } } }重启客户端后AI 就能看到这三个工具了。4. 验证请求让 AI 真正查一次 ERP 数据配置完成后直接在对话框里问帮我查利润最高的 5 个 SKU2026-06。AI 会自动调用profit_summary工具传入month: 2026-06服务端执行 SQL 返回 JSONAI 再把结果整理成人话给你。你也可以手动验证工具是否注册成功。在支持 MCP 的客户端里通常有工具列表能看到query_products、query_orders、profit_summary三个条目。如果客户端支持直接调用传一组参数试试{ keyword: 手机, category: 数码 }返回的recordset就是tb_products里匹配的商品。这一步通了说明从 SQL Server 到 AI 助手的链路完整了。如果你用的是 Codex CLI 或 Cursor注册方式类似都是把 MCP 服务器命令和参数写进各自的配置文件。模型通道那边把 TaoToken 的 API Key 填进客户端的模型配置即可接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 有详细说明。5. 本篇常见错排查5.1 SQL 注入千万别拼字符串我试过图省事写WHERE ProductName LIKE %${keyword}%一旦有人让 AI 传入 OR 11全表就裸了。正确做法是req.input()参数化让 mssql 走预编译参数。上面三个工具全部用了参数化这是底线。5.2 连接池与超时配置pool上限避免高并发把 SQL Server 连接打满。工具里用await getPool()复用连接别每次sql.connect新建。客户端超时会掐进程长查询加SET LOCK_TIMEOUT或限制TOP N。5.3 工具描述写清楚AI 靠工具描述决定调不调、怎么调。query_orders的描述里写明日期格式 YYYY-MM-DDAI 就不会传错格式。描述含糊AI 就容易瞎调。5.4 权限最小化生产环境给 MCP 单独建只读账号只授SELECT。别用 sa 账号跑一旦工具被滥用损失可控。5.5 客户端连不上服务端先确认npx tsx src/index.ts能独立跑起来再看客户端配置里的路径是不是绝对路径。相对路径在客户端启动时容易找不到文件。6. 下一步把更多数据源接进来MCP 把数据库能力变成 AI 可调用、你可控边界的工具是今年很值得上手的技术。这篇用 ERP SQL Server 走完了全流程建服务端、连库、定义工具、防注入、注册客户端。下一步你可以加 Resources把表结构暴露给 AI 做 schema 理解或者加 Prompts固化月度利润复盘这类话术。想验证模型通道是否稳定可以去模型对话页多试几个模型长期跑 Agent 任务的话Coding Plan 的额度更合适。接入过程中遇到工具注册或 Key 配置的问题优先查接入文档大部分坑那里都有答案。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

从零到上线的AI工程完整链路:工程视角学模型训练与部署 2026/9/29 6:56:19

从零到上线的AI工程完整链路:工程视角学模型训练与部署

直接从一个场景说起。我见过很多人学AI,第一步是去啃经典论文,第二步是拿MNIST跑了个手写数字识别,第三步就卡住了——模型是跑通了,但换个数据集就不知道怎么处理,代码丢给同事跑不出来,训练完的模型也不知…

阅读更多 →
大麦 Python 自动抢票脚本完整上手:3 步跑通,失败查这里 2026/9/29 6:56:18

大麦 Python 自动抢票脚本完整上手:3 步跑通,失败查这里

大麦 Python 自动抢票脚本完整上手:3 步跑通,失败查这里 【免费下载链接】Automatic_ticket_purchase 大麦网抢票脚本 项目地址: https://gitcode.com/GitHub_Trending/au/Automatic_ticket_purchase 这篇文章带你跑通开源的自动抢票脚本 Automat…

阅读更多 →
Mobile MCP不是SDK:揭秘移动端控制协议的本质与调试实践 2026/9/29 6:56:17

Mobile MCP不是SDK:揭秘移动端控制协议的本质与调试实践

1. “mobile-mcp”不是App名,也不是SDK包名——它是一条被误读的技术暗线最近在多个开发群、技术论坛和CI/CD流水线排查现场,频繁看到“mobile-mcp”这个组合词:有人在GitHub issue里贴出Error: failed to resolve mobile-mcp,有人…

阅读更多 →
串口到网络通讯转换:TCP/IP网关、透明传输与现场排错 2026/9/29 6:56:11

串口到网络通讯转换:TCP/IP网关、透明传输与现场排错

手头攒着一台跑了十来年的老设备,面板上只有一路DB9串口,协议手册还是影印版;另一头是后台服务器,天天催着要实时数据。这种局面下,基于TCP/IP实现串口到网络的通讯转换,基本是绕不过去的一道工序。所谓串口…

阅读更多 →
【AI面试临阵磨枪-20】OpenClaw 配 TaoToken:Harness 思想下的沙箱、Guardrails、验证与回滚怎么落地? 2026/9/29 6:56:11

【AI面试临阵磨枪-20】OpenClaw 配 TaoToken:Harness 思想下的沙箱、Guardrails、验证与回滚怎么落地?

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
Windows 平台 Hermes 完整部署教程:TaoToken 统一 Key 配置与验证 2026/9/29 6:56:10

Windows 平台 Hermes 完整部署教程:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉