API Proxy SaaS for MCP (Model Context Protocol) Servers - Node.js/Express backend
MCP Proxy SaaS Backend
A Node.js/Express backend that serves as an API proxy for MCP (Model Context Protocol) servers. Built for deployment on Railway.
🚀 Features
- API Key Authentication - Secure Bearer token validation
- Request Caching - Node-cache for performance optimization
- Security Validation - Tool whitelist and content blacklist checking
- Audit Logging - Comprehensive request tracking
- CORS Support - Configurable cross-origin resource sharing
- Error Handling - Robust error management and logging
🏗️ Architecture
Database Schema
-- MCP Servers configuration
CREATE TABLE mcp_servers (
id SERIAL PRIMARY KEY,
project_id UUID REFERENCES projects(id),
name VARCHAR(255) NOT NULL,
base_url TEXT NOT NULL,
auth_token TEXT,
active BOOLEAN DEFAULT true,
created_at TIMESTAMP DEFAULT NOW()
);
-- API Keys management
CREATE TABLE api_keys (
id SERIAL PRIMARY KEY,
project_id UUID REFERENCES projects(id),
key_string TEXT UNIQUE NOT NULL,
allowed_tools JSONB DEFAULT '[]',
blacklist_words JSONB DEFAULT '[]',
created_at TIMESTAMP DEFAULT NOW()
);
-- Audit logging
CREATE TABLE audit_logs (
id SERIAL PRIMARY KEY,
project_id UUID REFERENCES projects(id),
api_key_id INTEGER REFERENCES api_keys(id),
tool_name VARCHAR(255) NOT NULL,
status VARCHAR(50) NOT NULL,
duration_ms INTEGER NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
);
📁 Project Structure
├── src/
│ ├── config/
│ │ └── supabase.js # Supabase client configuration
│ ├── middleware/
│ │ └── auth.js # Authentication middleware
│ └── routes/
│ └── proxy.js # Proxy route handler
├── server.js # Main server file
├── package.json
├── .env.example
└── README.md
🔧 Setup & Installation
Local Development
-
Clone and Install
git clone <repository-url> cd mcp-proxy-saas npm install -
Environment Setup
cp .env.example .env # Edit .env with your Supabase credentials -
Start Development Server
npm run dev
Railway Deployment
-
Create Railway Project
npm install -g @railway/cli railway login railway init -
Set Environment Variables
railway variables set SUPABASE_URL=your-supabase-url railway variables set SUPABASE_SERVICE_ROLE_KEY=your-service-role-key railway variables set NODE_ENV=production -
Deploy
railway up
🔐 API Usage
Authentication
Include your API key in the Authorization header:
Authorization: Bearer sk_live_your_api_key_here
Proxy Request Format
{
"server_name": "github", // Optional: specific MCP server
"method": "tools/list", // Required: MCP method
"params": {}, // Optional: method parameters
"id": "request-123" // Optional: request identifier
}
Example Requests
Simple Request (uses default server)
curl -X POST https://your-app.railway.app/v1/mcp \\
-H "Authorization: Bearer sk_live_..." \\
-H "Content-Type: application/json" \\
-d '{
"method": "tools/list",
"params": {}
}'
Targeted Request (specific server)
curl -X POST https://your-app.railway.app/v1/mcp \\
-H "Authorization: Bearer sk_live_..." \\
-H "Content-Type: application/json" \\
-d '{
"server_name": "github",
"method": "repositories/list",
"params": {"visibility": "all"}
}'
🛡️ Security Features
- API Key Validation - Database-backed authentication with caching
- Tool Whitelisting - Restrict allowed MCP methods per API key
- Content Blacklisting - Block requests containing forbidden terms
- Rate Limiting Ready - Structure prepared for rate limiting
- Input Validation - Comprehensive request validation
📊 Monitoring
- Health Check:
GET /health - API Documentation:
GET / - Audit Logs: Stored in
audit_logstable - Request Logging: Console logging for debugging
🔧 Configuration
Environment Variables
| Variable | Description | Required |
|----------|-------------|----------|
| SUPABASE_URL | Supabase project URL | Yes |
| SUPABASE_SERVICE_ROLE_KEY | Supabase service role key | Yes |
| NODE_ENV | Environment (development/production) | No |
| PORT | Server port | No (defaults to 3000) |
| ALLOWED_ORIGINS | CORS allowed origins | No |
🚨 Error Handling
The API returns structured error responses:
{
"error": "Error description",
"code": "ERROR_CODE",
"details": {} // Additional error details (optional)
}
Common Error Codes
MISSING_AUTH_HEADER- No Authorization header providedINVALID_API_KEY- API key not found or invalidSERVER_NOT_FOUND- MCP server not found or inactiveMETHOD_NOT_ALLOWED- MCP method not in whitelistFORBIDDEN_CONTENT- Request contains blacklisted contentREQUEST_TIMEOUT- MCP server request timed out
📈 Performance
- Caching: API key validation cached for 60 seconds
- Connection Pooling: Supabase connection management
- Async Logging: Fire-and-forget audit logging
- Timeout Handling: 30-second timeout for MCP requests
🤝 Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
📄 License
MIT License - see LICENSE file for details.
🆘 Support
For issues and questions:
- Check the API documentation at
GET / - Review audit logs in your Supabase dashboard
- Check Railway logs for deployment issues