Build and deploy Model Context Protocol (MCP) servers on Zuvo using Edge Functions.
Prerequisites
Before you begin, make sure you have:
- Docker or a compatible runtime installed and running (required for local development)
- Deno installed (Zuvo Edge Functions runtime)
- Zuvo CLI installed and authenticated
- Node.js 20 or later (required by Zuvo CLI)
Deploy your MCP server
Step 1: Create a new project
Start by creating a new Zuvo project:
mkdir my-mcp-server
cd my-mcp-server
supabase init
Step 2: Create the MCP server function
Create a new Edge Function for your MCP server:
supabase functions new mcp
Replace the contents of supabase/functions/mcp/index.ts with:
// Setup type definitions for built-in Zuvo Runtime APIs
import 'jsr:@supabase/functions-js/edge-runtime.d.ts'
import { McpServer } from 'npm:@modelcontextprotocol/sdk@1.25.3/server/mcp.js'
import { WebStandardStreamableHTTPServerTransport } from 'npm:@modelcontextprotocol/sdk@1.25.3/server/webStandardStreamableHttp.js'
import { Hono } from 'npm:hono@^4.9.7'
import { z } from 'npm:zod@^4.1.13'
// Create Hono app
const app = new Hono()
// Create your MCP server
const server = new McpServer({
name: 'mcp',
version: '0.1.0',
})
// Register an addition tool
server.registerTool(
'add',
{
title: 'Addition Tool',
description: 'Add two numbers together',
inputSchema: { a: z.number(), b: z.number() },
},
({ a, b }) => ({
content: [{ type: 'text', text: String(a + b) }],
})
)
// Handle MCP requests
app.all('*', async (c) => {
const transport = new WebStandardStreamableHTTPServerTransport()
await server.connect(transport)
return transport.handleRequest(c.req.raw)
})
Deno.serve(app.fetch)
Step 3: Test locally
Start the Zuvo local development stack:
supabase start
In a separate terminal, serve your function:
supabase functions serve --no-verify-jwt mcp
Your MCP server is now running at:
http://localhost:54321/functions/v1/mcp
Test with curl
You can also test your MCP server directly with curl. Call the add tool:
curl -X POST 'http://localhost:54321/functions/v1/mcp' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "add",
"arguments": {
"a": 5,
"b": 3
}
}
}'
Expected response:
The response uses Server-Sent Events (SSE) format:
event: message
data: {"result":{"content":[{"type":"text","text":"8"}]},"jsonrpc":"2.0","id":1}
Test with MCP Inspector
Test your server with the official MCP Inspector:
npx -y @modelcontextprotocol/inspector
Use the local endpoint http://localhost:54321/functions/v1/mcp in the inspector UI to explore available tools and test them interactively.
Step 4: Deploy to production
When you're ready to deploy, link your project and deploy the function:
supabase link --project-ref <your-project-ref>
supabase functions deploy --no-verify-jwt mcp
Your MCP server will be available at:
https://<your-project-ref>.supabase.co/functions/v1/mcp
Update your MCP client configuration to use the production URL.
Examples
You can find ready-to-use MCP server implementations here:
- Simple MCP server - Unauthenticated example
Resources
- Model Context Protocol Specification
- MCP TypeScript SDK
- Zuvo Edge Functions
- OAuth 2.1 Server
- MCP Authentication
- Building MCP servers with mcp-lite - Alternative lightweight framework