Amogh-2404/mcp-vs-rest-comparison
If you are the rightful owner of mcp-vs-rest-comparison and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.
This directory contains runnable code examples demonstrating the migration of a REST API to a Model Context Protocol (MCP) server.
REST vs MCP Implementation - Working Code
This directory contains the complete, runnable code examples from the Medium article "I Migrated My Side Project's REST API to MCP in 3 Weeks."
Directory Structure
code/
├── shared/ # Shared mock database
│ └── db.js
├── rest/ # REST implementation
│ ├── server.js # Express REST API (85 lines)
│ └── client.js # REST client (217 lines)
├── mcp/ # MCP implementation
│ ├── server.js # MCP server (120 lines)
│ ├── client.js # MCP client (23 lines)
│ └── package.json # MCP dependencies
├── benchmarks/ # Performance tests
│ └── compare.js # REST vs MCP comparison
├── package.json # Root dependencies
└── README.md # This file
Quick Start
Prerequisites
- Node.js 18+ installed
- npm or yarn
Installation
# Install root dependencies
npm install
# Install MCP dependencies
cd mcp && npm install && cd ..
Running the Examples
1. REST Implementation
Start the REST server:
npm run rest:server
# Server starts on http://localhost:3000
# Get a test token: curl http://localhost:3000/auth/token
Run the REST client (in another terminal):
npm run rest:client
# Output shows all CRUD operations with full error handling
Manual API testing:
# Get auth token
TOKEN=$(curl -s http://localhost:3000/auth/token | jq -r .token)
# List all tasks
curl -H "Authorization: Bearer $TOKEN" http://localhost:3000/tasks
# Get specific task
curl -H "Authorization: Bearer $TOKEN" http://localhost:3000/tasks/1
# Create task
curl -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"title":"New task","status":"todo"}' \
http://localhost:3000/tasks
# Update task
curl -X PUT -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"status":"done"}' \
http://localhost:3000/tasks/1
# Delete task
curl -X DELETE -H "Authorization: Bearer $TOKEN" \
http://localhost:3000/tasks/1
2. MCP Implementation
Run the MCP client (starts server automatically):
npm run mcp:client
# Output shows:
# 1. Tool discovery
# 2. All CRUD operations
# 3. Automatic tool schema
Run MCP server standalone:
npm run mcp:server
# Server runs on stdio (for MCP protocol)
3. Performance Benchmarks
Run the comparison benchmark:
npm run benchmark
# Output:
# - Single request latency (REST vs MCP)
# - Multi-step workflow comparison
# - Throughput analysis
# - Summary with recommendations
Key Differences Demonstrated
Line Count Comparison
| Component | REST | MCP | Reduction |
|---|---|---|---|
| Server | 85 lines | 120 lines | -41% |
| Client | 217 lines | 23 lines | -89% |
| Total | 302 lines | 143 lines | -53% |
What the Code Shows
REST Client (217 lines) includes:
- Manual retry logic with exponential backoff
- Rate limiting detection and handling
- Timeout management
- Error parsing and formatting
- Request/response serialization
- HTTP header management
- Query string building
MCP Client (23 lines) gets:
- All of the above handled by the protocol
- Automatic tool discovery
- Self-documenting API
- Stateful connection (faster workflows)
Performance Results
Based on the benchmarks in this code:
Single Request:
- REST: ~3.5ms
- MCP: ~5.2ms
- Winner: REST (48% faster)
5-Step Workflow:
- REST: ~18.7ms
- MCP: ~11.2ms
- Winner: MCP (40% faster)
Overhead:
- REST: 629 bytes/request
- MCP: 162 bytes/request
- Winner: MCP (74% less)
Architecture Comparison
REST Architecture
Client → HTTP Request → Express Middleware → JWT Auth → Handler → Database → Response
- Stateless (each request independent)
- HTTP-based transport
- Manual authentication per request
- Client handles retry/errors
MCP Architecture
Client → MCP Tool Call → MCP Server → Database → MCP Response
- Stateful (persistent connection)
- JSON-RPC transport
- Process-level authentication
- Protocol handles retry/errors
When to Use Each
Use REST when:
- ✅ Building public-facing APIs
- ✅ Need HTTP caching (CDN support)
- ✅ Simple, stateless requests
- ✅ Mobile apps or browsers (universal support)
- ✅ One-off API calls
Use MCP when:
- ✅ Building AI agents with tool access
- ✅ Internal integrations (multiple services)
- ✅ Long-running, conversational workflows
- ✅ Security-critical (keep credentials local)
- ✅ Want minimal client code
Code Quality Notes
REST Implementation
- ✅ Production-ready error handling
- ✅ JWT authentication
- ✅ Retry logic with exponential backoff
- ✅ Rate limiting support
- ✅ Comprehensive logging
- ⚠️ Lots of boilerplate
MCP Implementation
- ✅ Self-documenting tools
- ✅ Auto-discovery
- ✅ Clean, minimal code
- ✅ Protocol-level error handling
- ⚠️ Requires MCP-compatible clients
- ⚠️ Not suitable for public APIs
Extending the Code
Adding a New Endpoint (REST)
// In rest/server.js
app.get('/tasks/:id/comments', authenticateToken, (req, res) => {
// Your logic here
});
// In rest/client.js (add 20+ lines)
async getTaskComments(taskId) {
return this.request('GET', `/tasks/${taskId}/comments`);
}
Adding a New Tool (MCP)
// In mcp/server.js tools list
{
name: "get_task_comments",
description: "Get comments for a task",
inputSchema: { /* schema */ }
}
// In mcp/server.js tools/call handler
case "get_task_comments": {
// Your logic here
}
// Client usage (no changes needed - auto-discovery!)
await client.callTool("get_task_comments", { taskId: 1 });
Troubleshooting
REST Server Won't Start
# Check if port 3000 is in use
lsof -i :3000
# Kill existing process
kill -9 <PID>
# Or use a different port
PORT=3001 npm run rest:server
MCP Client Connection Fails
# Make sure you're in the mcp directory or use full path
cd mcp && npm run client
# Check Node version (requires 18+)
node --version
Benchmark Errors
# Ensure REST server is NOT running before benchmarks
# The benchmark starts its own server instance
Testing
The code includes working examples that demonstrate:
- ✅ All CRUD operations
- ✅ Error handling
- ✅ Authentication (REST)
- ✅ Tool discovery (MCP)
- ✅ Performance comparison
- ✅ Realistic use cases
License
MIT License - Free to use for your projects
Questions?
See the full Medium article for detailed explanation of:
- Why these architectural decisions were made
- Block's Goose case study (enterprise MCP usage)
- Security implications
- When NOT to use MCP
- Migration strategy
Article: "I Migrated My Side Project's REST API to MCP in 3 Weeks" Author: R.Amogh Code Repository: This directory contains all runnable examples from the article