教程以订单查询服务展示TypeScript SDK v2的分包方式,以及stdio和无状态Streamable HTTP两种接入方式。强调安装新版SDK并不会自动启用2026-07-28协议,服务入口还需接收创建McpServer的工厂函数。
搜索「MCP TypeScript」,你找到的大多还是 2025 年的代码。这些代码使用单一的 @modelcontextprotocol/sdk 包,也就是 SDK v1,其中的 server.tool()、server.resource() 和 server.prompt() 方法在 v2 中已经不存在。要新建一个支持 MCP 2026-07-28 规范的服务器,你需要使用官方 SDK v2,它已经拆分成多个独立的包。
本文节选自一篇更完整的指南。我们会搭建 nortia-pedidos,用来查询 Nortia Logística 的订单。Nortia Logística 是 DesarrolloMCP 课程中的一家虚构公司。这个服务器将通过 stdio 和无状态的 Streamable HTTP 提供服务。文中所有代码都已在 @modelcontextprotocol/server 2.3.0、zod 4.6.5 和 Node 24.12 环境中运行验证。
SDK 官方指南是这样说的:「v2 默认不会在网络上传输任何标识为 2026-07-28 的字节。」决定协议版本的是服务器提供服务时使用的入口,而不是安装的包。因此,我们要把服务器的构建过程放进一个函数里,也就是一个返回 McpServer 的工厂函数:支持 2026-07-28 的入口接收的是工厂函数,而不是实例;在 HTTP 模式下,每次请求都会执行这个工厂函数。
mkdir nortia-pedidos && cd nortia-pedidos
npm init -y && npm pkg set type=module
npm i @modelcontextprotocol/server @modelcontextprotocol/client \
@modelcontextprotocol/node @modelcontextprotocol/express express zod
npm i -D typescript tsx @types/node @types/express
工厂函数 crearServidor() 会注册一个 tool(buscar_pedido,使用 Zod 4 校验输入和输出)、一个固定 resource、另一个带模板的 resource(pedidos://pedido/{pedidoId}),以及一个 prompt。完整指南提供了全部实现,并逐一解释每个设计选择:为什么订单不存在时,应该返回带有 isError: true 的结果,而不是抛出异常;以及为什么即使声明了 outputSchema,仍然需要过滤输出字段。
import { serveStdio } from '@modelcontextprotocol/server/stdio';
import { dependencias } from './entorno.js';
import { crearServidor } from './servidor.js';
const deps = dependencias('stdio'); // falla al arrancar si la configuración es inválida
const handle = serveStdio(() => crearServidor(deps));
console.error(`nortia-pedidos (${deps.inquilino}) escuchando por stdio`);
process.on('SIGINT', () => void handle.close());
让服务器使用 2026-07-28 协议的是 serveStdio(fábrica),而且它默认也支持使用握手机制的旧版协议客户端。注意,所有日志都通过 console.error 输出:在 stdio 模式下,规范禁止向 stdout 写入有效 MCP 消息之外的任何内容。
import { createMcpExpressApp } from '@modelcontextprotocol/express';
import { toNodeHandler } from '@modelcontextprotocol/node';
import { createMcpHandler } from '@modelcontextprotocol/server';
import { dependencias } from './entorno.js';
import { crearServidor } from './servidor.js';
const deps = dependencias('http');
// La fábrica se ejecuta una vez por petición HTTP: no hay nada que recordar entre dos POST.
const handler = createMcpHandler(() => crearServidor(deps));
const app = createMcpExpressApp(); // express.json() y validación de Host y Origin
const node = toNodeHandler(handler);
app.all('/mcp', (req, res) => void node(req, res, req.body));
const PORT = Number(process.env.PORT ?? 3000);
const httpServer = app.listen(PORT, '127.0.0.1', () => {
console.error(`nortia-pedidos (${deps.inquilino}) en http://127.0.0.1:${PORT}/mcp`);
});
process.on('SIGTERM', async () => {
await handler.close();
httpServer.close();
});
createMcpHandler 返回一个标准 Web handler,toNodeHandler 则把它适配到 Express。这里没有会话,也没有 Mcp-Session-Id 请求头:每个 POST 都只依靠自身携带的信息完成处理。由于每次请求都会执行工厂函数,数据库连接池、缓存、其他 API 的客户端等开销较大的对象,必须放在工厂函数之外的模块级作用域中。
MCP Inspector 默认使用带握手机制的协议版本。如果你没有指定 --protocol-era modern,或没有在其配置文件对应的服务器条目中设置 "protocolEra": "modern",测试照样会显示绿色通过,却根本没有测试 2026-07-28。确认协商使用了当前版本的标志,是响应的 _meta 中出现 io.modelcontextprotocol/serverInfo。
完整指南《DesarrolloMCP:用 TypeScript 创建 MCP 服务器》提供了其余全部代码,包括通过接口封装的数据、tool、resources 和 prompt,还包含带有 _meta 的 curl 请求、Inspector 测试方法,以及如何让 Claude Code 在明确固定使用 SDK v2 的前提下完成构建。
如果你正在用西班牙语学习 MCP,DesarrolloMCP 课程的基础级内容可以免费学习,共 14 节课,无需提供银行卡。课程已更新到 2026-07-28 规范,所有代码都经过测试。
如果需要进一步采取行动,你可以考虑屏蔽此人,或举报其滥用行为。