redshift-mcp-server
Enables secure, read-only access to Amazon Redshift data warehouses for AI assistants, allowing schema inspection, query execution, and data understanding.
README
Redshift MCP Server
Give AI assistants secure, read-only access to your Amazon Redshift data warehouse.
This TypeScript-based Model Context Protocol (MCP) server enables LLMs to inspect schemas, execute queries, and understand your data warehouse structure.
π Based on the original implementation by paschmaria, with production-ready enhancements.
β¨ Features
- π Read-only queries with automatic transaction safety
- ποΈ Schema introspection - tables, columns, relationships
- π Smart sampling - optional PII redaction (emails, phones)
- π Statistics - table sizes, row counts, distribution keys
- π Column search - find columns across all schemas
- π Dual modes - STDIO (IDEs) + HTTP (web/cloud)
- π Bearer auth - production-ready security
- βΈοΈ Cloud-native - stateless mode, health checks, K8s-ready
- π³ Docker - single-command deployment
π Quick Start
Local Setup (5 minutes)
# 1. Clone and install
git clone <repository-url>
cd redshift-mcp-server
npm install
# 2. Build
npm run build
# 3. Configure
export DATABASE_URL="redshift://user:pass@host:5439/db?ssl=true"
# 4. Run (STDIO mode for IDE)
npm start
# OR run HTTP mode for web/cloud
export TRANSPORT_MODE="http"
npm start
# Server: http://localhost:3000/mcp or http://localhost:3000/
Docker (1 minute)
# Build
docker build -t redshift-mcp:latest .
# Run STDIO (for IDEs)
docker run -e DATABASE_URL='redshift://...' -i --rm redshift-mcp:latest
# Run HTTP with auth (for production)
docker run \
-e DATABASE_URL='redshift://...' \
-e TRANSPORT_MODE=http \
-e STATELESS_MODE=true \
-e ENABLE_AUTH=true \
-e API_TOKEN=your-secret-token \
-e REDACT_PII=false \
-p 3000:3000 \
redshift-mcp:latest
π Table of Contents
- Configuration
- Transport Modes
- Authentication
- IDE Integration
- Dust.tt Integration
- Kubernetes Deployment
- Available Tools
- Troubleshooting
βοΈ Configuration
Environment Variables
| Variable | Required | Default | Description |
|---|---|---|---|
DATABASE_URL |
β Yes | - | Redshift connection string |
TRANSPORT_MODE |
No | stdio |
stdio for IDEs, http for web/cloud |
PORT |
No | 3000 |
HTTP server port |
STATELESS_MODE |
No | false |
true for horizontal scaling |
ENABLE_AUTH |
No | false |
Enable Bearer token authentication |
API_TOKEN |
No | - | Bearer token (required if ENABLE_AUTH=true) |
ALLOWED_ORIGINS |
No | * |
CORS allowed origins |
ENABLE_RESUMABILITY |
No | false |
Event resumability (stateful mode only) |
REDACT_PII |
No | false |
Redact email/phone in output data |
Database URL Format
redshift://username:password@hostname:port/database?ssl=true&timeout=600
Example:
DATABASE_URL="redshift://admin:MyPass123@cluster.us-east-1.redshift.amazonaws.com:5439/analytics?ssl=true"
Configuration File (.env)
# Copy example
cp .env.example .env
# Edit with your values
DATABASE_URL="redshift://..."
TRANSPORT_MODE="http"
STATELESS_MODE="true"
ENABLE_AUTH="true"
API_TOKEN="your-secret-token-here"
REDACT_PII="false"
π Transport Modes
Choose the right transport mode for your use case:
STDIO Mode (Default)
Best for: IDEs, CLI tools, local development
# Default mode - no configuration needed
export DATABASE_URL="redshift://..."
npm start
Clients:
- Cursor IDE
- Windsurf
- Claude Desktop
- Custom CLI tools
How it works: Communicates via standard input/output streams
HTTP Mode
Best for: Web apps, Dust.tt, Kubernetes, remote integrations
# Enable HTTP transport
export DATABASE_URL="redshift://..."
export TRANSPORT_MODE="http"
npm start
Endpoints:
POST/GET/DELETE /mcp- MCP protocol endpointPOST/GET/DELETE /- Root path (alias for/mcp)GET /health- Health check with metricsGET /ready- Readiness probe
Stateful vs Stateless:
| Mode | Best For | Sessions | Scaling | Set With |
|---|---|---|---|---|
| Stateful | IDE clients, MCP Inspector | β Session-based | Needs sticky sessions | STATELESS_MODE=false (default) |
| Stateless | Dust.tt, K8s, APIs | β No sessions | β Horizontal scaling | STATELESS_MODE=true |
Production recommendation: Use STATELESS_MODE=true for cloud deployments
π Authentication
Bearer Token Auth (Production)
Enable authentication for production deployments (required for Dust.tt, recommended for K8s):
export TRANSPORT_MODE="http"
export ENABLE_AUTH="true"
export API_TOKEN="your-super-secret-token-here"
npm start
How it works:
- Clients send requests with
Authorization: Bearer <token>header - Server validates token against
API_TOKEN - Invalid/missing tokens receive
401 Unauthorized
Security features:
- OPTIONS requests (CORS preflight) don't require auth
- Health/ready endpoints don't require auth
- OAuth discovery endpoints return 404 (tells clients OAuth is not available)
Testing authentication:
# Without token - should fail
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1}'
# Returns: 401 Unauthorized
# With token - should work
curl -X POST http://localhost:3000/mcp \
-H "Authorization: Bearer your-super-secret-token-here" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}},"id":1}'
# Returns: 200 OK with server capabilities
Best practices:
- Generate strong tokens:
openssl rand -hex 32 - Store tokens in secrets (K8s Secrets, env vars, vault)
- Rotate tokens regularly (every 90 days)
- Use HTTPS in production (ngrok, load balancer, ingress)
π» IDE Integration
Cursor / Windsurf / Claude Desktop
Add to your MCP config file:
- Cursor:
.cursor/mcp.json - Windsurf:
mcp_config.json - Claude Desktop:
claude_desktop_config.json
Option 1: Node.js (Recommended)
{
"mcpServers": {
"redshift": {
"command": "node",
"args": ["/absolute/path/to/redshift-mcp-server/dist/index.js"],
"env": {
"DATABASE_URL": "redshift://user:pass@host:5439/db?ssl=true",
"REDACT_PII": "false"
}
}
}
}
β οΈ Important: Use absolute paths, not relative paths!
Option 2: Docker
{
"mcpServers": {
"redshift": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "DATABASE_URL",
"-e", "REDACT_PII",
"redshift-mcp:latest"
],
"env": {
"DATABASE_URL": "redshift://user:pass@host:5439/db?ssl=true",
"REDACT_PII": "false"
}
}
}
}
After configuration:
- Restart your IDE
- Tools appear automatically in MCP settings
- Ask AI: "What tables are in my database?"
π MCP Inspector (Testing Tool)
Anthropic's MCP Inspector is a web-based tool for testing MCP servers.
Setup:
# 1. Start server with auth (optional)
export DATABASE_URL="redshift://..."
export TRANSPORT_MODE="http"
export STATELESS_MODE="true"
export ENABLE_AUTH="true"
export API_TOKEN="test-token-123"
npm start
2. Open MCP Inspector and connect:
- Transport: Streamable HTTP
- Connection: Direct
- URL:
http://localhost:3000/mcporhttp://localhost:3000/ - Authentication: Custom Header (if enabled)
- Header:
Authorization - Value:
Bearer test-token-123
- Header:
3. Test tools:
- List tools
- Execute
querytool - Check resources
βοΈ Dust.tt Integration
Dust.tt supports remote MCP servers. Here's how to connect:
Step 1: Expose Your Server
Option A: ngrok (Quick testing)
# Start server with auth
export DATABASE_URL="redshift://..."
export TRANSPORT_MODE="http"
export STATELESS_MODE="true"
export ENABLE_AUTH="true"
export API_TOKEN="your-secret-token"
npm start
# In another terminal, expose
ngrok http 3000
# You'll get: https://abc123.ngrok.io
Option B: Kubernetes (Production)
See Kubernetes Deployment section below.
Step 2: Configure in Dust.tt
- Go to Dust.tt β Connections β Add MCP Server
- Fill in:
- Server Name: Redshift Data Warehouse
- URL:
https://your-ngrok-url.ngrok.io/mcporhttps://your-domain.com/mcp - Authentication: Bearer Token
- Token:
your-secret-token(same asAPI_TOKEN)
- Click Save
β Success! Dust.tt agents can now query your Redshift data.
Troubleshooting:
- β "404 Not Found" β Use
/mcpsuffix or root/path - β "401 Unauthorized" β Check token matches
API_TOKENexactly - β "OAuth error" β Select "Bearer Token" auth (not "Automatic")
Step 3: Test in Dust.tt
Ask your Dust.tt agent:
- "What tables are in my Redshift database?"
- "Show me the schema of the users table"
- "How many rows are in the orders table?"
Learn more: Dust.tt MCP Guide
βΈοΈ Kubernetes Deployment
Production-ready K8s deployment with horizontal scaling:
Complete manifest:
apiVersion: v1
kind: Secret
metadata:
name: redshift-mcp-secrets
type: Opaque
stringData:
database-url: "redshift://user:pass@host:5439/db?ssl=true"
api-token: "your-super-secret-token"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: redshift-mcp-server
spec:
replicas: 3 # Horizontal scaling with stateless mode
selector:
matchLabels:
app: redshift-mcp-server
template:
metadata:
labels:
app: redshift-mcp-server
spec:
containers:
- name: server
image: your-registry/redshift-mcp:latest
ports:
- containerPort: 3000
env:
- name: TRANSPORT_MODE
value: "http"
- name: STATELESS_MODE
value: "true" # Enable for horizontal scaling
- name: ENABLE_AUTH
value: "true"
- name: API_TOKEN
valueFrom:
secretKeyRef:
name: redshift-mcp-secrets
key: api-token
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: redshift-mcp-secrets
key: database-url
- name: ALLOWED_ORIGINS
value: "https://dust.tt"
- name: REDACT_PII
value: "false"
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 10
periodSeconds: 30
readinessProbe:
httpGet:
path: /ready
port: 3000
initialDelaySeconds: 5
periodSeconds: 10
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
---
apiVersion: v1
kind: Service
metadata:
name: redshift-mcp-service
spec:
selector:
app: redshift-mcp-server
ports:
- protocol: TCP
port: 80
targetPort: 3000
type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: redshift-mcp-ingress
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
tls:
- hosts:
- mcp.your-company.com
secretName: mcp-tls
rules:
- host: mcp.your-company.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: redshift-mcp-service
port:
number: 80
Key configuration points:
| Feature | Configuration | Why |
|---|---|---|
| Horizontal Scaling | STATELESS_MODE=true, replicas: 3 |
No sticky sessions needed |
| Security | ENABLE_AUTH=true, token in Secret |
Protect your data |
| Health Checks | /health and /ready endpoints |
Auto-restart unhealthy pods |
| TLS | Ingress with cert-manager | HTTPS required for production |
| Resources | Adjust based on query load | Start with 256Mi RAM, 100m CPU |
π οΈ Available Tools
The MCP server exposes these tools to AI assistants:
1. query - Execute SQL
Execute read-only SQL queries with automatic transaction safety.
// Input
{
"sql": "SELECT table_name FROM information_schema.tables LIMIT 10"
}
// Output
[
{"table_name": "users"},
{"table_name": "orders"},
...
]
Features:
- Automatic
BEGIN TRANSACTION READ ONLY - Safe for production use
- Returns results as JSON array
Example prompts:
- "Show me all tables in the public schema"
- "What are the top 10 customers by revenue?"
- "Count rows in the orders table"
2. describe_table - Table Schema
Get comprehensive table information including columns, data types, and Redshift-specific attributes.
// Input
{
"schema": "public",
"table": "users"
}
// Output
{
"schema": "public",
"table": "users",
"columns": [
{
"column_name": "id",
"data_type": "integer",
"is_nullable": "NO",
"is_distkey": true,
"is_sortkey": true
},
...
]
}
Includes:
- Column names and data types
- Nullability
- Distribution keys (DISTKEY)
- Sort keys (SORTKEY)
- Defaults and constraints
Example prompts:
- "Describe the structure of the users table"
- "What columns are in the orders table?"
- "Show me the schema for public.payments"
3. find_column - Search Columns
Find tables containing columns matching a search pattern.
// Input
{
"pattern": "email"
}
// Output
[
{
"table_schema": "public",
"table_name": "users",
"column_name": "email",
"data_type": "varchar"
},
{
"table_schema": "public",
"table_name": "contacts",
"column_name": "contact_email",
"data_type": "varchar"
}
]
Use cases:
- Find all tables with customer IDs
- Locate PII fields across schemas
- Discover relationships between tables
Example prompts:
- "Find all columns containing 'customer'"
- "Which tables have an 'updated_at' column?"
- "Search for columns with 'amount' in the name"
Resources (Contextual Information)
These are auto-discovered and provided to AI assistants:
| Resource | URI Pattern | Description |
|---|---|---|
| Schema Lists | redshift://host/schema/{schema} |
All tables in a schema |
| Table Schemas | redshift://host/{schema}/{table}/schema |
Column definitions, keys |
| Sample Data | redshift://host/{schema}/{table}/sample |
5 sample rows (unredacted by default) |
| Statistics | redshift://host/{schema}/{table}/statistics |
Size, rows, distribution |
PII Redaction: Email and phone fields can be redacted in sample data by setting REDACT_PII=true (disabled by default).
π§ Troubleshooting
Common Issues
β Connection Fails
Symptoms: ENOTFOUND, ECONNREFUSED, or timeout errors
Solutions:
- Check DATABASE_URL format:
redshift://username:password@cluster.region.redshift.amazonaws.com:5439/database?ssl=true - Verify network access: Security groups, VPC settings, public access
- Test with psql:
psql "$DATABASE_URL"
β Authentication 401 Unauthorized
Solutions:
- Verify token matches:
API_TOKEN="abc123"βAuthorization: Bearer abc123 - Select "Bearer Token" in Dust.tt (not "Automatic")
- Check request headers in logs
β MCP Inspector Won't Connect
Solutions:
- Enable stateless mode:
STATELESS_MODE="true" - Use correct URL:
http://localhost:3000/mcporhttp://localhost:3000/ - Add auth header if enabled:
Authorization: Bearer your-token
β Dust.tt 404 Not Found
Solutions:
- Use full path:
https://your-ngrok-url.ngrok.io/mcp - Check ngrok logs for actual requests
- Verify auth token is correct
β IDE Tools Not Showing
Solutions:
- Use absolute paths in config
- Verify build:
npm run build && ls -la dist/index.js - Restart IDE after config changes
Debug Commands
# Health check
curl http://localhost:3000/health
# Test with auth
curl -H "Authorization: Bearer token" http://localhost:3000/mcp
# Test DB connection
psql "$DATABASE_URL" -c "SELECT 1;"
ποΈ Architecture
src/
βββ core/
β βββ redshift-tools.ts # Pure DB logic (transport-agnostic)
βββ mcp/
β βββ server.ts # MCP protocol handler
βββ transports/
β βββ stdio.ts # STDIO transport
β βββ streamable-http.ts # HTTP/SSE transport
βββ middleware/
β βββ auth.ts # Bearer token authentication
βββ index.ts # Application entry point
Key principles:
- π§© Core logic is transport-agnostic (reusable)
- π Transports are pluggable (STDIO, HTTP, WebSocket)
- π Middleware is modular (auth, CORS, logging)
- βοΈ Config is environment-driven (12-factor)
See ARCHITECTURE.md for details.
π Resources
π Security
Built-in protections:
- π Read-only transactions - All queries in
BEGIN TRANSACTION READ ONLY - π· PII redaction - Optional email/phone redaction in samples
- π Bearer auth - Token-based access control
- π SSL/TLS - Encrypted database connections
Best practices:
- Use dedicated read-only Redshift user
- Limit permissions to necessary schemas/tables
- Enable auth for production:
ENABLE_AUTH=true - Use strong tokens:
openssl rand -hex 32 - Rotate credentials every 90 days
- Deploy in private network when possible
- Monitor query logs for suspicious activity
π License & Credits
Based on: paschmaria/redshift-mcp-server
Enhancements:
- β Streamable HTTP + stateless mode
- β Bearer token authentication
- β Kubernetes-ready deployment
- β
Root path (
/) + OAuth discovery - β Clean architecture with separation of concerns
HTTP Transport Inspiration: The HTTP/SSE transport implementation took inspiration from:
Stack: TypeScript 5.3+ | Node.js 16+ | MCP SDK 1.8.0 | Express.js
π Questions? Issues? PRs welcome!
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.