-
Notifications
You must be signed in to change notification settings - Fork 211
# Custom HTTP Routes Implementation - Closes #160 #172
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
This commit successfully implements **custom HTTP route support** for FastMCP TypeScript, achieving feature parity with the Python implementation in punkpeye#160. ## Key Features Delivered **Complete Route Support** - All HTTP methods: GET, POST, PUT, DELETE, PATCH, OPTIONS - Path parameters with pattern matching (`/users/:id`, `/users/:userId/posts/:postId`) - Wildcard routes for static files (`/static/*`) - Query string parsing with array support (`?tags=a&tags=b`) - JSON and text body parsing with 10MB size limits **Authentication Integration** - Routes inherit existing authentication system - **Public routes** option (`{ public: true }`) to bypass auth - Perfect for static assets, health checks, and webhook endpoints **Enhanced Request/Response Objects** ```typescript // Rich request object with helper methods server.addRoute('POST', '/api/users/:id', async (req, res) => { const userId = req.params.id; // Path parameters const filters = req.query.filter; // Query parameters const body = await req.json(); // JSON parsing const auth = req.auth; // Authentication context res.status(201).json({ created: body }); // Chainable response }); ``` **Real-World Use Cases Enabled** - Admin dashboards with HTML interfaces - Webhook endpoints for GitHub/Slack integrations - File upload/download endpoints - REST APIs complementing MCP functionality - Static file serving for assets and documentation ## Implementation Highlights **Zero Dependencies** - Uses only Node.js built-ins for maximum compatibility **Backward Compatible** - All existing MCP functionality unchanged, including existing OAuth discovery endpoints **Route Priority** - Custom routes processed *before* built-in endpoints (health, OAuth), allowing overrides **Comprehensive Testing** - 15 new test cases covering all scenarios: - HTTP methods, path/query parameters, authentication - Public routes, wildcards, concurrent requests, error handling - Integration with existing MCP tools and endpoints **Complete Documentation** - Updated README with examples and API reference ## Technical Implementation The implementation extends the existing `#handleUnhandledRequest` method as suggested, with: - **Route matching engine** with parameter extraction and wildcard support - **Enhanced request object** with helper methods for body parsing - **Chainable response object** with status codes and content-type handling - **Public route system** that bypasses authentication when needed - **Error boundary** for graceful handling of route handler exceptions ## Usage Example ```typescript import { FastMCP } from '@jordanburke/fastmcp'; const server = new FastMCP({ name: 'MyServer', version: '1.0.0' }); // REST API endpoint server.addRoute('GET', '/api/users/:id', async (req, res) => { res.json({ userId: req.params.id, query: req.query }); }); // Admin interface server.addRoute('GET', '/admin', async (req, res) => { res.send('<html><body><h1>Admin Panel</h1></body></html>'); }); // Public webhook (no auth required) server.addRoute('POST', '/webhook/github', async (req, res) => { const payload = await req.json(); res.json({ received: true }); }, { public: true }); ```
What's the benefit of this over just bringing fastify as a dependency? |
Great Question - the custom implementation keeps FastMCP lightweight (~200 lines vs Fastify's ~50+ dependencies), integrates seamlessly, and provides the routes without the additional bloat. I intentionally avoided pulling in a library, since it's a significant architectural decision that affects FastMCP's direction. However, I'm happy to refactor this to use Fastify (I like the lib personally) if that aligns better with the project's roadmap. The custom approach maintains the MCP ecosystem's lightweight philosophy, but I'm flexible on the implementation approach! |
@punkpeye @jordanburke I'm taking a look at #136 this week and this unmerged PR may affect implementation. Should I branch from main or here? Question: Do we feel that adding a custom router is worth the maintenance burden? I generally agree about fastify, but what if we use Hono (16.6k minified, zero deps)? |
@jacksteamdev I actually like Hono quite a bit. In fact, I have a working MCP impl on Cloudflare using Hono right now. Works great IMO. Might also be a good choice if fastmcp wants to support Cloudflare down the road - #136 |
This commit successfully implements custom HTTP route support for FastMCP TypeScript, achieving feature parity with the Python implementation in #160.
Key Features Delivered
Complete Route Support
/users/:id
,/users/:userId/posts/:postId
)/static/*
)?tags=a&tags=b
)Authentication Integration
{ public: true }
) to bypass authEnhanced Request/Response Objects
Real-World Use Cases Enabled
Implementation Highlights
Zero Dependencies - Uses only Node.js built-ins for maximum compatibility
Backward Compatible - All existing MCP functionality unchanged, including existing OAuth discovery endpoints
Route Priority - Custom routes processed before built-in endpoints (health, OAuth), allowing overrides
Comprehensive Testing - 15 new test cases covering all scenarios:
Complete Documentation - Updated README with examples and API reference
Technical Implementation
The implementation extends the existing
#handleUnhandledRequest
method as suggested, with:Usage Example