A Model Context Protocol (MCP) server that provides comprehensive tools for interacting with Supabase databases, storage, and edge functions. This server enables seamless integration between Supabase services and MCP-compatible applications.
The Supabase MCP server acts as a bridge between MCP clients and Supabase's suite of services, providing:
- Database operations with rich querying capabilities
- Storage management for files and assets
- Edge function invocation
- Project and organization management
- User authentication and management
- Role-based access control
The server is built using TypeScript and follows a modular architecture:
supabase-server/
├── src/
│ ├── index.ts # Main server implementation
│ └── types/
│ └── supabase.d.ts # Type definitions
├── package.json
├── tsconfig.json
├── config.json.example # Example configuration file
└── .env.example # Environment variables template
- Server Class: Implements the MCP server interface and handles all client requests
- Type Definitions: Comprehensive TypeScript definitions for all operations
- Environment Configuration: Secure configuration management via environment variables
- Error Handling: Robust error handling with detailed error messages
- Node.js 16.x or higher
- A Supabase project with:
- Project URL
- Service Role Key (for admin operations)
- Access Token (for management operations)
- MCP-compatible client
To install Supabase Server for Claude Desktop automatically via Smithery:
npx -y @smithery/cli install supabase-server --client claude
- Clone the repository:
git clone https://github.com/DynamicEndpoints/supabase-mcp.git
cd supabase-mcp
- Install dependencies:
npm install
- Create environment configuration:
cp .env.example .env
- Configure environment variables:
SUPABASE_URL=your_project_url_here
SUPABASE_KEY=your_service_role_key_here
SUPABASE_ACCESS_TOKEN=your_access_token_here # Required for management operations
- Create server configuration:
cp config.json.example config.json
- Build the server:
npm run build
The server supports extensive configuration through both environment variables and a config.json file. Here's a detailed breakdown of the configuration options:
{
"server": {
"name": "supabase-server", // Server name
"version": "0.1.0", // Server version
"port": 3000, // Port number (if running standalone)
"host": "localhost" // Host address (if running standalone)
}
}
{
"supabase": {
"project": {
"url": "your_project_url",
"key": "your_service_role_key",
"accessToken": "your_access_token"
},
"storage": {
"defaultBucket": "public", // Default storage bucket
"maxFileSize": 52428800, // Max file size in bytes (50MB)
"allowedMimeTypes": [ // Allowed file types
"image/*",
"application/pdf",
"text/*"
]
},
"database": {
"maxConnections": 10, // Max DB connections
"timeout": 30000, // Query timeout in ms
"ssl": true // SSL connection
},
"auth": {
"autoConfirmUsers": false, // Auto-confirm new users
"disableSignup": false, // Disable public signups
"jwt": {
"expiresIn": "1h", // Token expiration
"algorithm": "HS256" // JWT algorithm
}
}
}
}
{
"logging": {
"level": "info", // Log level
"format": "json", // Log format
"outputs": ["console", "file"], // Output destinations
"file": {
"path": "logs/server.log", // Log file path
"maxSize": "10m", // Max file size
"maxFiles": 5 // Max number of files
}
}
}
{
"security": {
"cors": {
"enabled": true,
"origins": ["*"],
"methods": ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
"allowedHeaders": ["Content-Type", "Authorization"]
},
"rateLimit": {
"enabled": true,
"windowMs": 900000, // 15 minutes
"max": 100 // Max requests per window
}
}
}
{
"monitoring": {
"enabled": true,
"metrics": {
"collect": true,
"interval": 60000 // Collection interval in ms
},
"health": {
"enabled": true,
"path": "/health" // Health check endpoint
}
}
}
See config.json.example
for a complete example configuration file.
Add the server to your MCP settings (cline_mcp_settings.json):
{
"mcpServers": {
"supabase": {
"command": "node",
"args": ["path/to/supabase-server/build/index.js"],
"env": {
"SUPABASE_URL": "your_project_url",
"SUPABASE_KEY": "your_service_role_key",
"SUPABASE_ACCESS_TOKEN": "your_access_token"
},
"config": "path/to/config.json" // Optional: path to configuration file
}
}
}
Create a new record in a table with support for returning specific fields.
{
table: string;
data: Record<string, any>;
returning?: string[];
}
Example:
{
table: "users",
data: {
name: "John Doe",
email: "john@example.com"
},
returning: ["id", "created_at"]
}
Read records with advanced filtering, joins, and field selection.
{
table: string;
select?: string[];
filter?: Record<string, any>;
joins?: Array<{
type?: 'inner' | 'left' | 'right' | 'full';
table: string;
on: string;
}>;
}
Example:
{
table: "posts",
select: ["id", "title", "user.name"],
filter: { published: true },
joins: [{
type: "left",
table: "users",
on: "posts.user_id=users.id"
}]
}
Update records with filtering and returning capabilities.
{
table: string;
data: Record<string, any>;
filter?: Record<string, any>;
returning?: string[];
}
Example:
{
table: "users",
data: { status: "active" },
filter: { email: "john@example.com" },
returning: ["id", "status", "updated_at"]
}
Delete records with filtering and returning capabilities.
{
table: string;
filter?: Record<string, any>;
returning?: string[];
}
Example:
{
table: "posts",
filter: { status: "draft" },
returning: ["id", "title"]
}
Upload files to Supabase Storage with configurable options.
{
bucket: string;
path: string;
file: File | Blob;
options?: {
cacheControl?: string;
contentType?: string;
upsert?: boolean;
};
}
Example:
{
bucket: "avatars",
path: "users/123/profile.jpg",
file: imageBlob,
options: {
contentType: "image/jpeg",
upsert: true
}
}
Download files from Supabase Storage.
{
bucket: string;
path: string;
}
Example:
{
bucket: "documents",
path: "reports/annual-2023.pdf"
}
Invoke Supabase Edge Functions with parameters and custom options.
{
function: string;
params?: Record<string, any>;
options?: {
headers?: Record<string, string>;
responseType?: 'json' | 'text' | 'arraybuffer';
};
}
Example:
{
function: "process-image",
params: {
url: "https://example.com/image.jpg",
width: 800
},
options: {
responseType: "json"
}
}
List users with pagination support.
{
page?: number;
per_page?: number;
}
Create a new user with metadata.
{
email: string;
password: string;
data?: Record<string, any>;
}
Update user details.
{
user_id: string;
email?: string;
password?: string;
data?: Record<string, any>;
}
Delete a user.
{
user_id: string;
}
Assign a role to a user.
{
user_id: string;
role: string;
}
Remove a role from a user.
{
user_id: string;
role: string;
}
The server provides detailed error messages for common scenarios:
- Invalid parameters
- Authentication failures
- Permission issues
- Rate limiting
- Network errors
- Database constraints
Errors are returned in a standardized format:
{
code: ErrorCode;
message: string;
details?: any;
}
npm test
npm run build
npm run lint
The evals package loads an mcp client that then runs the index.ts file, so there is no need to rebuild between tests. You can load environment variables by prefixing the npx command. Full documentation can be found here.
OPENAI_API_KEY=your-key npx mcp-eval src/evals/evals.ts src/index.ts
- Fork the repository
- Create a feature branch
- Commit your changes
- Push to the branch
- Create a Pull Request
MIT License - see LICENSE for details
For support, please:
- Check the issues for existing problems/solutions
- Create a new issue with detailed reproduction steps
- Include relevant error messages and environment details