anfibiacreativa/typespec-mcp-openapi-dual-output-demo
If you are the rightful owner of typespec-mcp-openapi-dual-output-demo and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to henry@mcphub.com.
This project demonstrates building both a Model Context Protocol (MCP) server and a REST API from a single TypeSpec definition, providing a unified shopping cart service with user and order management capabilities.
This project demonstrates building both a Model Context Protocol (MCP) server and a REST API from a single TypeSpec definition. It provides a unified shopping cart service with user and order management capabilities.
✨ Key Feature: Dual Output
Using TypeSpec with HTTP decorators, this project generates:
- 🤖 MCP Server - For AI agent tool calling
- 🌐 OpenAPI 3.0 Spec - For REST API documentation and client generation
One definition → Two outputs! See for details.
📦 Requirements
- Node.js >= 20
- npm >= 9
- TypeScript
🏗️ Installation
mkdir api-dual-demo
cd api-dual-demo
git clone https://github.com/anfibiacreativa/typespec-mcp-openapi-dual-output-demo
Install all dependencies:
npm install --legacy-peer-deps
⚠️ Notes on installation issues:
- Use
--legacy-peer-deps
to avoid strict npm 7+ peer dependency conflicts - On Apple Silicon, some older packages (@alloy-js/core) may require
--legacy-peer-deps
Architecture
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
🔨 Build
The build process compiles TypeSpec and TypeScript:
npm run build
This runs:
npm run build:tsp
- Compiles TypeSpec to generate:- MCP server code in
tsp-output/typespec-mcp-server-js/
- OpenAPI spec in
tsp-output/openapi/openapi.yaml
- MCP server code in
npm run build:ts
- Compiles TypeScript to JavaScript
Generated Outputs:
- ✅ MCP Server (TypeScript)
- ✅ OpenAPI 3.0 Specification (YAML)
- ✅ Type definitions and validation schemas
🚀 Run HTTP Bridge
The http-server.ts
sets up Express to expose MCP operations as HTTP endpoints.
npm start
Server listens on http://localhost:3000
Available Routes:
GET /users/:id -> userOperations.getUser
POST /users -> userOperations.createUser
GET /orders/:id -> orderOperations.getOrder
POST /orders -> orderOperations.createOrder
⚡ Test the API
User Operations
Create a user:
curl -X POST http://localhost:3000/users \
-H "Content-Type: application/json" \
-d '{"id":"u-1001","name":"Ada Lovelace","email":"ada@example.com"}'
Get a user:
curl http://localhost:3000/users/u-1001
Expected response:
{
"id": "u-1001",
"name": "Alice Example",
"email": "alice@example.com"
}
Order Operations
Create an order:
curl -X POST http://localhost:3000/orders \
-H "Content-Type: application/json" \
-d '{"id":"o-5001","userId":"u-1001","total":149.99}'
Get an order:
curl http://localhost:3000/orders/o-5001
Expected response:
{
"id": "o-5001",
"userId": "u-1001",
"total": 42.99
}
📋 MCP Tools
The TypeSpec definitions generate the following MCP tools:
user_operations_get_user
- Retrieves a user by IDuser_operations_create_user
- Creates a new userorder_operations_get_order
- Retrieves an order by IDorder_operations_create_order
- Creates a new order
� OpenAPI Specification
The project also generates a complete OpenAPI 3.0 specification at tsp-output/openapi/openapi.yaml
.
What You Can Do With It:
-
View Documentation
# Serve with Swagger UI (install globally if needed) npx swagger-ui-express tsp-output/openapi/openapi.yaml
-
Generate Client SDKs
# 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
-
Import into API Tools
- Postman: File → Import →
tsp-output/openapi/openapi.yaml
- Insomnia: Create → Import → Select file
- Bruno: Import Collection → OpenAPI
- Postman: File → Import →
-
Mock the API
# Use Prism to create a mock server npx @stoplight/prism-cli mock tsp-output/openapi/openapi.yaml
See for more details on using the OpenAPI spec.
�🎯 Expected Behavior
- MCP server returns JSON objects for User and Order
- The HTTP bridge provides a REST API wrapper around MCP operations
- All operations go through the TypeSpec-generated MCP layer
- Input and output validation is handled via Zod schemas
- OpenAPI spec provides complete REST API documentation
📝 Data Models
User
{
id: string; // Unique user identifier
name: string; // User's full name
email: string; // User's email address
}
Order
{
id: string; // Unique order identifier
userId: string; // Reference to user ID
total: number; // Order total amount (float32)
}
🛠 Troubleshooting
Build fails with type errors:
- The build script automatically adds
@ts-nocheck
to generated files - If issues persist, try:
npm run build:tsp && npm run build:ts
Port 3000 already in use:
- Change the
PORT
constant insrc/http-server.ts
- Or kill the process using port 3000:
lsof -ti:3000 | xargs kill
Installation issues on Apple Silicon:
- Use
npm install --legacy-peer-deps
- Ensure you're using Node.js >= 20