使用说明
TypeSpec MCP 示例:购物车服务
这个项目展示了建筑(的过程/方法/成果等,具体根据上下文确定) 两者都 一个模型上下文协议(MCP)服务器 并且 一个来自单一TypeSpec定义的REST API。它提供了一个统一的购物车服务,具备用户和订单管理功能。
✨ 主要特点:双输出
使用TypeSpec与HTTP装饰器,此项目生成:
- 🤖 机器人 MCP 服务器 - 用于AI代理工具调用
- 🌐 表示“互联网”或“世界万维网”。 OpenAPI 3.0 规范 - 用于REST API文档和客户端生成
一个定义 → 两个输出! 见 `DUAL_OUTPUT_GUIDE.md` 翻译为中文是:“双输出指南.md” 详情见下。
📦 要求
- Node.js 版本 >= 20
- npm 版本 >= 9
- TypeScript
🏗️ 安装
mkdir api-dual-demo
cd api-dual-demo
git clone https://github.com/anfibiacreativa/typespec-mcp-openapi-dual-output-demo
安装所有依赖项:
npm install --legacy-peer-deps
⚠️ 安装问题注意事项:
- 使用
--legacy-peer-deps以避免严格的npm 7+版本中的同级依赖冲突 - 在Apple Silicon上,一些较旧的包(@alloy-js/core)可能需要
--legacy-peer-deps
建筑
APISummit/
├─ main.tsp # Unified TypeSpec definitions (with HTTP decorators)
├─ tspconfig.yml # TypeSpec configuration (dual emitters)
├─ src/
│ ├─ http-server.ts # Express HTTP bridge
│ └─ mcp-server.ts # MCP server implementation
└─ tsp-output/
├─ typespec-mcp-server-js/ # Generated MCP TypeScript server
│ ├─ index.ts # MCP server
│ ├─ tools.ts # Tool interfaces
│ └─ schemas/ # Zod and JSON schemas
└─ openapi/ # Generated OpenAPI spec
└─ openapi.yaml # OpenAPI 3.0 specification
🔨 构建
构建过程会编译TypeSpec和TypeScript:
npm run build
这运行的是:
npm run build:tsp- 将TypeSpec编译以生成:- MCP服务器代码在
tsp-output/typespec-mcp-server-js/ - OpenAPI规范在
tsp-output/openapi/openapi.yaml
- MCP服务器代码在
npm run build:ts- 将TypeScript编译为JavaScript
生成的输出:
- ✅ MCP 服务器(TypeScript)
- ✅ OpenAPI 3.0 规范(YAML 格式)
- ✅ 类型定义和验证模式
🚀 运行HTTP桥接器
这个(或:该) http-server.ts 设置 Express 以将 MCP 操作作为 HTTP 端点公开。
npm start
服务器监听于 http://localhost:3000 翻译为中文是:“本地主机的3000端口”。不过,通常我们不会直接翻译网址,而是会说“访问本地主机的3000端口”或者“打开http://localhost:3000”。这里的“localhost”指的是本地计算机,“3000”是端口号
可用路线:
GET /users/:id -> userOperations.getUser
POST /users -> userOperations.createUser
GET /orders/:id -> orderOperations.getOrder
POST /orders -> orderOperations.createOrder
⚡ 测试API
用户运营
创建用户:
curl -X POST http://localhost:3000/users \
-H "Content-Type: application/json" \
-d '{"id":"u-1001","name":"Ada Lovelace","email":"ada@example.com"}'
获取一个用户:
curl http://localhost:3000/users/u-1001
预期响应:
{
"id": "u-1001",
"name": "Alice Example",
"email": "alice@example.com"
}
订单操作
创建一个订单:
curl -X POST http://localhost:3000/orders \
-H "Content-Type: application/json" \
-d '{"id":"o-5001","userId":"u-1001","total":149.99}'
接到一个订单:
curl http://localhost:3000/orders/o-5001
预期响应:
{
"id": "o-5001",
"userId": "u-1001",
"total": 42.99
}
📋 MCP 工具
TypeSpec 定义生成以下 MCP 工具:
user_operations_get_user- 通过ID检索用户user_operations_create_user- 创建一个新用户order_operations_get_order- 通过ID检索订单order_operations_create_order- 创建一个新订单
开放API规范
该项目还生成了一份完整的OpenAPI 3.0规范 tsp-output/openapi/openapi.yaml。
你可以用它来做什么:
-
查看文档
# Serve with Swagger UI (install globally if needed) npx swagger-ui-express tsp-output/openapi/openapi.yaml -
生成客户端SDK(软件开发工具包)
# TypeScript client npx @openapitools/openapi-generator-cli generate \ -i tsp-output/openapi/openapi.yaml \ -g typescript-fetch \ -o ./generated-client # Python client npx @openapitools/openapi-generator-cli generate \ -i tsp-output/openapi/openapi.yaml \ -g python \ -o ./generated-client-python -
导入到API工具
- Postman: 文件 → 导入 →
tsp-output/openapi/openapi.yaml - 失眠(此处可能指软件或功能名,直译为“失眠”可能不贴切,但按原文结构翻译): 创建 → 导入 → 选择文件
- 布鲁诺:导入集合 → OpenAPI
- Postman: 文件 → 导入 →
-
模拟API
# Use Prism to create a mock server npx @stoplight/prism-cli mock tsp-output/openapi/openapi.yaml
见 `DUAL_OUTPUT_GUIDE.md` 翻译为中文是:“双输出指南.md” 如需更多关于使用OpenAPI规范的详细信息,请参阅。
🎯 预期行为
- MCP服务器返回用户和订单的JSON对象
- HTTP桥为MCP操作提供了一个REST API封装
- 所有操作都通过TypeSpec生成的MCP层进行
- 输入和输出验证是通过Zod模式来处理的
- OpenAPI规范提供了完整的REST API文档
📝 数据模型
用户
{
id: string; // Unique user identifier
name: string; // User's full name
email: string; // User's email address
}
订单
{
id: string; // Unique order identifier
userId: string; // Reference to user ID
total: number; // Order total amount (float32)
}
🛠 故障排除
构建失败,存在类型错误:
- 构建脚本会自动添加
@ts-nocheck生成的文件 - 如果问题仍然存在,请尝试:
npm run build:tsp && npm run build:ts
端口3000已被占用:
- 改变
PORT(在……中)恒定的src/http-server.ts - 或者使用端口3000终止进程:
lsof -ti:3000 | xargs kill
在Apple Silicon上的安装问题:
- 使用
npm install --legacy-peer-deps - 确保你使用的是 Node.js 20 或更高版本