Redshift Mcp Server — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Redshift Mcp Server (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
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.
# 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/# 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| 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 |
redshift://username:password@hostname:port/database?ssl=true&timeout=600Example:
DATABASE_URL="redshift://admin:[email protected]:5439/analytics?ssl=true".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"Choose the right transport mode for your use case:
Best for: IDEs, CLI tools, local development
# Default mode - no configuration needed
export DATABASE_URL="redshift://..."
npm startClients:
How it works: Communicates via standard input/output streams
Best for: Web apps, Dust.tt, Kubernetes, remote integrations
# Enable HTTP transport
export DATABASE_URL="redshift://..."
export TRANSPORT_MODE="http"
npm startEndpoints:
POST/GET/DELETE /mcp - MCP protocol endpointPOST/GET/DELETE / - Root path (alias for /mcp)GET /health - Health check with metricsGET /ready - Readiness probeStateful 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
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 startHow it works:
Authorization: Bearer <token> headerAPI_TOKEN401 UnauthorizedSecurity features:
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 capabilitiesBest practices:
openssl rand -hex 32Add to your MCP config file:
.cursor/mcp.jsonmcp_config.jsonclaude_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:
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 start2. Open MCP Inspector and connect:
http://localhost:3000/mcp or http://localhost:3000/AuthorizationBearer test-token-1233. Test tools:
query toolDust.tt supports remote MCP servers. Here's how to connect:
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.ioOption B: Kubernetes (Production)
See Kubernetes Deployment section below.
https://your-ngrok-url.ngrok.io/mcp or https://your-domain.com/mcpyour-secret-token (same as API_TOKEN)✅ Success! Dust.tt agents can now query your Redshift data.
Troubleshooting:
/mcp suffix or root / pathAPI_TOKEN exactlyAsk your Dust.tt agent:
Learn more: Dust.tt MCP Guide
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: 80Key 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 |
The MCP server exposes these tools to AI assistants:
query - Execute SQLExecute 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:
BEGIN TRANSACTION READ ONLYExample prompts:
describe_table - Table SchemaGet 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:
Example prompts:
find_column - Search ColumnsFind 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:
Example prompts:
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).
#### ❌ Connection Fails
Symptoms: ENOTFOUND, ECONNREFUSED, or timeout errors
Solutions:
redshift://username:[email protected]:5439/database?ssl=truepsql "$DATABASE_URL"#### ❌ Authentication 401 Unauthorized
Solutions:
API_TOKEN="abc123" → Authorization: Bearer abc123#### ❌ MCP Inspector Won't Connect
Solutions:
STATELESS_MODE="true"http://localhost:3000/mcp or http://localhost:3000/Authorization: Bearer your-token#### ❌ Dust.tt 404 Not Found
Solutions:
https://your-ngrok-url.ngrok.io/mcp#### ❌ IDE Tools Not Showing
Solutions:
npm run build && ls -la dist/index.js# 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;"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 pointKey principles:
See [ARCHITECTURE.md](./ARCHITECTURE.md) for details.
Built-in protections:
BEGIN TRANSACTION READ ONLYBest practices:
ENABLE_AUTH=trueopenssl rand -hex 32Based on: paschmaria/redshift-mcp-server
Enhancements:
/) + OAuth discoveryHTTP 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!
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.