This project demonstrates how to create a Model Context Protocol (MCP) server deployed on Vercel using TypeScript and modern web technologies.
The MCP server provides image generation capabilities using Google's Gemini AI model and stores the generated images in Supabase storage. It's built as a serverless function that can be deployed on Vercel and used by MCP-compatible clients.
├── api/
│ ├── server.ts # Main MCP server handler
│ ├── services/
│ │ ├── gemini.ts # Gemini AI integration
│ │ └── supabase.ts # Supabase storage integration
│ └── package.json # API dependencies
├── components/ # Frontend components
├── package.json # Frontend dependencies
├── vercel.json # Vercel configuration
└── README.md
The MCP server uses the following key packages (see api/package.json
):
{
"dependencies": {
"mcp-handler": "^1.0.1", // Core MCP protocol handler
"zod": "^3.24.2", // Schema validation
"@supabase/supabase-js": "^2.39.0", // Supabase client
"@ai-sdk/google": "^2.0.0", // Google AI SDK
"ai": "^5.0.0", // Vercel AI SDK
"pngjs": "^7.0.0" // PNG image processing
}
}
The main server file (api/server.ts
) follows this pattern:
import { createMcpHandler } from 'mcp-handler';
import { z } from 'zod';
const handler = createMcpHandler((server) => {
server.tool(
'tool_name',
'Tool description',
{
// Zod schema for parameters
param1: z.string(),
param2: z.string(),
},
async ({ param1, param2 }) => {
// Tool implementation
return {
content: [
{
type: 'text',
text: 'Response text',
},
],
};
}
);
});
export { handler as GET, handler as POST, handler as DELETE };
The server implements a generate_images
tool that:
- Accepts parameters:
prompt
(string) andfilename
(string) - Generates images: Uses Google Gemini 2.5 Flash with image preview capabilities
- Stores images: Uploads generated images to Supabase storage in the
/mcp/
folder - Returns URLs: Provides public URLs for accessing the generated images
import { createMcpHandler } from 'mcp-handler';
const handler = createMcpHandler((server) => {
// Define tools here
});
{
prompt: z.string(),
filename: z.string(),
}
import { generateText } from 'ai';
const result = await generateText({
model: 'google/gemini-2.5-flash-image-preview',
prompt: prompt,
providerOptions: {
google: {
responseModalities: ['TEXT', 'IMAGE'],
},
},
});
const { data, error } = await supabase.storage
.from('app')
.upload(filePath, buffer, {
contentType: 'image/png',
cacheControl: '3600',
upsert: true,
});
To connect to this MCP server from Claude Code:
-
Open Claude Code
-
Use the following command to add the MCP server:
claude add mcp <name> -t http <your-published-url>/api/server
Replace:
<name>
with a memorable name for your connection<your-published-url>
with your actual Vercel deployment URL
-
Example:
claude add mcp my-mcp-server -t http https://my-mcp-server.vercel.app/api/server
-
Once connected, you can use the image generation capabilities:
claude mcp my-mcp-server "Generate an image of a futuristic city"
Required environment variables:
SUPABASE_URL=your_supabase_project_url
SUPABASE_SERVICE_ROLE_KEY=your_service_role_key
GOOGLE_GENERATIVE_AI_API_KEY=your_gemini_api_key
The vercel.json
file configures the serverless function:
{
"rewrites": [{ "source": "/(.+)", "destination": "/api/server" }],
"functions": {
"api/server.ts": {
"maxDuration": 60
}
}
}
npm init -y
mkdir api
cd api
npm init -y
# API dependencies
cd api
npm install mcp-handler@^1.0.1 zod@^3.24.2 @supabase/supabase-js@^2.39.0 @ai-sdk/google@^2.0.0 ai@^5.0.0 pngjs@^7.0.0
npm install -D @types/node@^22.13.10
Create api/server.ts
with the MCP handler pattern shown above.
- Gemini Service: Handle AI image generation
- Supabase Service: Manage file uploads and storage
Create vercel.json
to route requests and set function timeout.
Configure your environment variables in Vercel dashboard or .env.local
for local development.
Once deployed, the MCP server can be used by MCP-compatible clients to:
- Generate images from text prompts
- Store images in organized folders
- Retrieve public URLs for generated content
This project uses pnpm@9.4.0
as specified in the package.json:
"packageManager": "pnpm@9.4.0"
The project also includes a React frontend built with:
- React: ^19.1.1
- TypeScript: ^4.9.3
- Vite: ^7.1.6
- Tailwind CSS: Via CDN
- React Router DOM: ^7.9.1
The frontend serves as a simple landing page but can be extended to provide a web interface for the MCP server.
Deploy to Vercel with:
vercel --prod
The MCP server will be available at your Vercel domain's /api/server
endpoint.
This implementation demonstrates a production-ready MCP server that can be easily extended with additional tools and capabilities.