18 KiB
name, overview, todos
| name | overview | todos | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| HTTP MCP Server on Netlify | Deploy an HTTP-based Model Context Protocol (MCP) server on Netlify that's accessible 24/7 at www.markdown.fast/mcp. The server uses optional authentication (public access with rate limiting, API key for higher limits) and exposes read-only tools for accessing blog posts, pages, homepage, and search functionality. |
|
HTTP-Based MCP Server on Netlify Plan
Overview
Deploy an HTTP-based MCP server as a Netlify Edge Function that's accessible 24/7 at https://www.markdown.fast/mcp. The server uses optional authentication (public access by default with rate limiting, API key authentication for higher limits) and exposes read-only tools for AI tools like Cursor to access blog content.
Architecture
flowchart LR
subgraph client[AI Client]
Cursor[Cursor/Claude/etc]
end
subgraph netlify[Netlify Edge]
MCPFunction[MCP Server<br/>netlify/edge-functions/mcp.ts]
RateLimit[Rate Limiting]
Auth[Optional Auth]
end
subgraph convex[Convex Cloud]
ConvexDB[(Convex Database)]
Queries[Convex Queries<br/>posts.ts, pages.ts, search.ts]
end
Cursor -->|"HTTP POST<br/>/mcp"| MCPFunction
MCPFunction --> RateLimit
RateLimit --> Auth
Auth -->|"ConvexHttpClient<br/>(HTTP)"| Queries
Queries --> ConvexDB
Key Differences from Local Server
- HTTP Transport: Uses HTTP instead of stdio (accessible remotely)
- Netlify Deployment: Runs on Netlify Edge Functions (always available) https://docs.netlify.com/build/edge-functions/overview/
- Optional Authentication: Public access with rate limiting, API key for higher limits
- No Local Machine: Accessible from anywhere, no laptop needed
Implementation Steps
1. Add MCP SDK Dependency
File: package.json
- Add
@modelcontextprotocol/sdkto dependencies - Version: Use latest stable version
- No local script needed (runs on Netlify)
2. Create MCP Edge Function
New File: netlify/edge-functions/mcp.ts
Key Components:
- Import MCP SDK:
@modelcontextprotocol/sdk - Use
ConvexHttpClientpattern (similar toapi.tsedge function) - Read
VITE_CONVEX_URLfrom Netlify environment variables - Implement HTTP transport for MCP protocol
- Handle JSON-RPC requests/responses over HTTP
- Support optional authentication via
Authorizationheader
MCP Tools to Implement:
-
list_posts- Get all published posts- Calls:
api.posts.getAllPosts - Returns: Array of post metadata (no content)
- Calls:
-
get_post- Get single post by slug with full content- Args:
slug: string - Calls:
api.posts.getPostBySlug - Returns: Full post object with content
- Args:
-
list_pages- Get all published pages- Calls:
api.pages.getAllPages - Returns: Array of page metadata (no content)
- Calls:
-
get_page- Get single page by slug with full content- Args:
slug: string - Calls:
api.pages.getPageBySlug - Returns: Full page object with content
- Args:
-
get_homepage- Get homepage structure and featured content- Calls:
api.posts.getFeaturedPosts,api.pages.getFeaturedPages,api.posts.getAllPosts(limited) - Returns: Combined homepage data structure
- Calls:
-
search_content- Full text search across posts and pages- Args:
query: string - Calls:
api.search.search - Returns: Search results with snippets
- Args:
-
export_all- Batch export all posts and pages with full content- Calls: Multiple queries to get all content
- Returns: Complete content export
Rate Limiting:
- Use Netlify's built-in rate limiting (not in-memory)
- Configure in edge function
configexport usingrateLimitproperty - Public access: 50 requests/minute per IP address
- Authenticated access: 1000 requests/minute per API key
- Reference: Netlify Rate Limiting Docs
- Use
aggregateBy: ["ip", "domain"]for public rate limiting - Use separate rate limit rules for authenticated vs public access
Optional Authentication:
- Check for
Authorization: Bearer <key>header - If no header: Public access with lower rate limits
- If valid API key: Higher rate limits
- API key stored in Netlify environment variable
MCP_API_KEY - Return 401 if invalid API key provided
Error Handling:
- Validate Convex URL is set
- Handle Convex query errors gracefully
- Return proper MCP JSON-RPC error responses
- Never expose internal errors or stack traces
- Log errors to console (Netlify logs)
3. Configure Netlify
File: netlify.toml
Add edge function configuration (rate limiting configured in function code, not here):
[[edge_functions]]
path = "/mcp"
function = "mcp"
Note: Rate limiting is configured in the edge function's config export, not in netlify.toml. See Netlify Rate Limiting Docs for code-based rules.
Environment Variables (Netlify Dashboard):
VITE_CONVEX_URL- Already existsMCP_API_KEY- Optional, for authenticated access (generate secure random key)
4. Create Blog Post with Usage Instructions
New File: content/blog/how-to-use-mcp-server.md
Content Sections:
- What is MCP and why use it
- HTTP-based vs local server comparison
- Public access (no authentication needed)
- Optional API key setup (for higher limits)
- Client configuration examples (Cursor, Claude, etc.)
- Available tools reference
- Rate limiting details
- Troubleshooting common issues
- Security considerations
Frontmatter:
title: "How to Use the MCP Server"
description: "Guide to using the HTTP-based Model Context Protocol server at www.markdown.fast/mcp with Cursor and other AI tools"
date: "2025-12-28"
slug: "how-to-use-mcp-server"
published: true
tags: ["mcp", "cursor", "ai", "tutorial", "netlify"]
5. Update Documentation Files
File: content/pages/docs.md
Add new section "MCP Server" after "API Endpoints" section:
- Overview of HTTP-based MCP server
- Endpoint URL:
https://www.markdown.fast/mcp - Public access (no authentication required)
- Optional API key setup
- Rate limiting information
- Available tools list with descriptions
- Client configuration examples
- Link to detailed blog post
File: content/blog/setup-guide.md
Add subsection under "Next Steps" or create new section:
- Brief mention of HTTP MCP server capability
- Endpoint URL
- Link to detailed guide
- Note about 24/7 availability
File: src/config/siteConfig.ts
Add optional MCP configuration:
mcpServer: {
enabled: true,
endpoint: "/mcp",
publicRateLimit: 50, // requests per minute (Netlify built-in rate limiting)
authenticatedRateLimit: 1000, // requests per minute (Netlify built-in rate limiting)
requireAuth: false, // Optional: set to true to require API key
}
6. Update Reference Files
File: files.md
Add entry under "Netlify (netlify/edge-functions/)" section:
| `mcp.ts` | HTTP-based MCP server for AI tool integration. Accessible at /mcp endpoint. Exposes read-only tools for accessing blog posts, pages, and search. Uses optional authentication (public access with rate limiting, API key for higher limits). |
File: changelog.md
Add entry at top:
## [Unreleased]
### Added
- HTTP-based MCP (Model Context Protocol) server deployed on Netlify
- Accessible 24/7 at https://www.markdown.fast/mcp
- Public access with Netlify built-in rate limiting (50 req/min per IP)
- Optional API key authentication for higher limits (1000 req/min)
- Read-only access to blog posts, pages, homepage, and search
- Exposes 7 tools: list_posts, get_post, list_pages, get_page, get_homepage, search_content, export_all
- No local machine required - accessible from anywhere
- Blog post: "How to Use the MCP Server"
File: content/pages/changelog-page.md
Add same entry at top (before v1.38.0)
7. Update README.md
File: README.md
Add section "MCP Server" after "Fork Configuration":
- Brief description of HTTP-based MCP server
- Endpoint URL:
https://www.markdown.fast/mcp - Public access (no authentication required)
- Optional API key for higher limits
- Link to detailed documentation
- Note about 24/7 availability
Technical Details
HTTP Transport Implementation
MCP HTTP transport uses JSON-RPC over HTTP POST:
- Endpoint:
POST /mcp - Content-Type:
application/json - Request body: JSON-RPC 2.0 format
- Response: JSON-RPC 2.0 format
MCP SDK Compatibility with Deno/Edge Functions
Important Considerations:
-
npm Package Support: Netlify Edge Functions support npm packages in beta
- Edge Functions run on Deno runtime, not Node.js
- npm imports work but may have limitations
- Test thoroughly before deploying
-
MCP SDK Compatibility Check:
- Verify
@modelcontextprotocol/sdkworks in Deno - Check for Node.js-specific dependencies (e.g.,
fs,path,crypto) - Test imports and runtime behavior
- Verify
-
Fallback Options if SDK Doesn't Work:
Option A: Manual JSON-RPC Implementation
- MCP protocol is JSON-RPC 2.0 over HTTP
- Implement JSON-RPC request/response handling manually
- Parse request body, validate JSON-RPC format, route to tools
- Return proper JSON-RPC responses
- Reference: JSON-RPC 2.0 Specification
Option B: URL/CDN Imports
- If SDK provides ESM/CDN builds, use URL imports
- Example:
import { Server } from "https://cdn.example.com/mcp-sdk.js" - Check SDK documentation for Deno-compatible builds
Option C: Minimal MCP Implementation
- Implement only needed MCP features (tools, not resources/prompts)
- Focus on JSON-RPC message handling
- Use ConvexHttpClient directly (no MCP SDK needed for HTTP transport)
- Testing Strategy:
- Test MCP SDK import in local Edge Functions development
- Verify all tool handlers work correctly
- Test error handling and edge cases
- Have fallback implementation ready if SDK fails
Rate Limiting Strategy
Public Access (No API Key):
- 100 requests per minute per IP address
- Tracked using IP address from request
- Simple in-memory counter (Edge Functions reset on cold start)
Authenticated Access (With API Key):
- 1000 requests per minute per API key
- Tracked using API key from Authorization header
- Higher limits for trusted users
Rate Limit Headers:
X-RateLimit-Limit: Maximum requests allowedX-RateLimit-Remaining: Remaining requests in current windowX-RateLimit-Reset: Time when limit resets
Authentication Flow
- Check for
Authorizationheader - If present: Validate API key against
MCP_API_KEYenv var - If valid: Apply authenticated rate limits
- If invalid: Return 401 Unauthorized
- If absent: Apply public rate limits
Convex Connection
- Use
ConvexHttpClient(same asapi.tsedge function) - Read
VITE_CONVEX_URLfrom environment - Convert
.cloudto.sitefor HTTP endpoints - Handle errors gracefully
Error Responses
Return proper MCP JSON-RPC error format:
{
"jsonrpc": "2.0",
"id": <request-id>,
"error": {
"code": <error-code>,
"message": "<user-friendly-message>"
}
}
Security Considerations
- Read-only access: Only queries, no mutations exposed
- Public content: Uses same queries as public website
- Rate limiting: Prevents abuse using Netlify's built-in rate limiting (50 req/min public per IP, 1000 req/min authenticated per API key)
- HTTPS encryption: Automatic with Netlify
- Optional authentication: API key for higher limits (stored in Netlify env vars)
- Error handling: Never expose internal errors or stack traces
- CORS: Configure appropriate CORS headers for MCP clients
Client Configuration Examples
Cursor Configuration
{
"mcpServers": {
"markdown-fast": {
"url": "https://www.markdown.fast/mcp"
}
}
}
With API Key (Optional)
{
"mcpServers": {
"markdown-fast": {
"url": "https://www.markdown.fast/mcp",
"headers": {
"Authorization": "Bearer your-api-key-here"
}
}
}
}
Testing Checklist
- MCP server responds to HTTP POST requests
- All 7 tools respond correctly
- Convex connection works via HTTP client
- Netlify built-in rate limiting works for public access (50 req/min)
- Netlify built-in rate limiting works for authenticated access (1000 req/min)
- MCP SDK imports successfully in Edge Function (Deno runtime)
- All MCP SDK features work correctly (or fallback implementation works)
- JSON-RPC request/response handling works correctly
- Netlify rate limiting configuration is correct
- Authentication validates API keys correctly
- Error handling returns proper JSON-RPC errors
- CORS headers allow MCP clients
- Documentation is clear and complete
- Blog post provides step-by-step instructions
Files to Create
netlify/edge-functions/mcp.ts- HTTP-based MCP server implementationcontent/blog/how-to-use-mcp-server.md- Usage guide blog post
Files to Update
package.json- Add@modelcontextprotocol/sdkdependencynetlify.toml- Add edge function configuration for/mcpcontent/pages/docs.md- Add MCP Server sectioncontent/blog/setup-guide.md- Add MCP mentionsrc/config/siteConfig.ts- Add MCP server configurationfiles.md- Add edge function descriptionchangelog.md- Add feature entrycontent/pages/changelog-page.md- Add feature entryREADME.md- Add MCP Server section
Environment Variables (Netlify)
VITE_CONVEX_URL- Already exists (required)MCP_API_KEY- Optional, for authenticated access (generate secure random key)
Dependencies
@modelcontextprotocol/sdk- MCP SDK for TypeScript- Note: npm package support in Netlify Edge Functions is in beta
- Edge Functions use Deno runtime, not Node.js
- Verify compatibility: Check for Node.js-specific dependencies
- Fallback options if SDK doesn't work:
- Implement JSON-RPC manually (MCP protocol is JSON-RPC 2.0)
- Use URL imports if SDK supports ESM/CDN
- Check SDK documentation for Deno compatibility
- Existing:
convex(already in package.json) - Netlify Edge Functions runtime (Deno)
Notes
- No newsletter or email features exposed (as requested)
- Server is read-only for security
- Uses existing Convex queries (no backend changes needed)
- Follows same pattern as
api.tsedge function for Convex connection - Compatible with Cursor, Claude Desktop, and other MCP HTTP clients
- Always available (no local machine needed)
- Public access by default (no authentication required)
- Optional API key for higher rate limits
- Rate limiting: Uses Netlify's built-in rate limiting (not in-memory)
- MCP SDK compatibility: npm packages in Edge Functions are beta - verify Deno compatibility and have fallback plan
- Durable storage: If needed for rate limiting state, consider Netlify KV or external storage (not required with Netlify built-in rate limiting)