Skip to content
Back to skills

Database Connect

ASecurity

Database MCP server integration for PostgreSQL, MySQL, MongoDB

  • 666 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added February 8, 2026
databasestypescriptpythongoshellbashsqlnodedjangodatabasesecurity

Works with

  • cli
  • mcp

Security analysis

A100/100

Scanned February 12, 2026

npx -y skills add majiayu000/claude-skill-registry --skill database-connect --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Database Connect?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Database Connect
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/majiayu000-database-connect/badge)](https://www.skillsdirectory.com/skills/majiayu000-database-connect)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: database-connect
description: Database MCP server integration for PostgreSQL, MySQL, MongoDB
disable-model-invocation: true
---

# Database Connection & Management

I'll help you connect to and manage databases through MCP servers for data exploration, schema inspection, and queries.

Arguments: `$ARGUMENTS` - database type (postgres, mysql, mongodb), connection details, or query

## Database Capabilities

**Supported Databases:**
- PostgreSQL (via MCP or native psql)
- MySQL/MariaDB (via MCP or native mysql)
- MongoDB (via MCP or native mongo)
- SQLite (local database files)

**Operations:**
- Schema inspection and exploration
- Safe query execution
- Data exploration and analysis
- Migration support

## Token Optimization

This skill uses database-specific patterns to minimize token usage:

### 1. Database Configuration Caching (700 token savings)
**Pattern:** Cache database connection details and configuration
- Store config in `.database-connection-cache` (1 hour TTL)
- Cache: DB type, connection string pattern, ORM tool, schema location
- Read cached config on subsequent runs (50 tokens vs 750 tokens fresh)
- Invalidate on config file changes (.env, schema.prisma, etc.)
- **Savings:** 93% on repeat connections

### 2. MCP Integration for Database Operations (1,500 token savings)
**Pattern:** Use MCP server for database interactions
- Connect via MCP database server (200 tokens)
- Execute queries through MCP (300 tokens)
- No Task agents for database operations
- Direct tool-to-database communication
- **Savings:** 83% vs LLM-mediated database operations

### 3. Bash-Based Schema Inspection (1,000 token savings)
**Pattern:** Use database CLI tools for schema inspection
- PostgreSQL: `psql -c "\\dt"` (200 tokens)
- MySQL: `mysql -e "SHOW TABLES"` (200 tokens)
- Prisma: `prisma db pull` (200 tokens)
- Parse output with grep/awk
- **Savings:** 80% vs Task-based schema analysis

### 4. Cached Schema Structure (85% savings)
**Pattern:** Store recent schema inspection results
- Cache schema in `.claude/database/schema-cache.json` (15 min TTL)
- Include table list, column info, relationships
- Return cached schema for repeated inspections (200 tokens)
- **Distribution:** ~60% of runs are schema checks
- **Savings:** 200 vs 2,000 tokens for schema re-inspection

### 5. Sample-Based Table Analysis (800 token savings)
**Pattern:** Inspect first 20 tables in detail
- Full column info for first 20 tables (600 tokens)
- Table count only for remaining tables
- Full analysis via `--full` flag
- **Savings:** 70% vs exhaustive table analysis

### 6. Template-Based Query Generation (500 token savings)
**Pattern:** Use SQL templates for common operations
- Standard patterns: SELECT *, COUNT(*), DESCRIBE TABLE
- Common query templates
- No creative SQL generation
- **Savings:** 75% vs LLM-generated queries

### 7. Connection Pooling via MCP (400 token savings)
**Pattern:** Reuse MCP server connections
- Single MCP server connection for session
- Multiple queries through same connection
- No reconnection overhead
- **Savings:** 80% on connection establishment

### 8. Early Exit for MCP Server Check (90% savings)
**Pattern:** Detect if MCP database server already configured
- Check MCP configuration file (50 tokens)
- If configured: return connection instructions (100 tokens)
- **Distribution:** ~40% of runs check existing setup
- **Savings:** 100 vs 2,000 tokens for setup checks

### Real-World Token Usage Distribution

**Typical operation patterns:**
- **Check MCP setup** (already configured): 100 tokens
- **Connect via MCP** (first time): 2,000 tokens
- **Schema inspection** (cached): 200 tokens
- **Execute query** (via MCP): 500 tokens
- **Full schema analysis**: 2,500 tokens
- **Most common:** Schema checks with cached results

**Expected per-operation:** 1,500-2,500 tokens (60% reduction from 3,500-5,500 baseline)
**Real-world average:** 700 tokens (due to MCP integration, cached schema, early exit)

## Phase 1: Database Detection

```bash
#!/bin/bash
# Detect database configuration in project

detect_databases() {
    echo "=== Database Detection ==="
    echo ""

    # Check for environment variables
    if [ -f ".env" ]; then
        echo "✓ .env file found"

        if grep -q "DATABASE_URL\|POSTGRES\|MYSQL" .env; then
            echo "  Contains database configuration"
        fi
    fi

    # Check for database config files
    if [ -f "knexfile.js" ] || [ -f "knexfile.ts" ]; then
        echo "✓ Knex configuration detected"
        DB_TOOL="knex"
    fi

    if [ -f "prisma/schema.prisma" ]; then
        echo "✓ Prisma schema detected"
        DB_TOOL="prisma"
        DB_TYPE=$(grep "provider" prisma/schema.prisma | head -1 | awk '{print $3}' | tr -d '"')
        echo "  Provider: $DB_TYPE"
    fi

    if [ -f "ormconfig.json" ] || [ -f "ormconfig.js" ]; then
        echo "✓ TypeORM configuration detected"
        DB_TOOL="typeorm"
    fi

    if [ -f "sequelize.config.js" ]; then
        echo "✓ Sequelize configuration detected"
        DB_TOOL="sequelize"
    fi

    # Check for MongoDB
    if [ -f "package.json" ]; then
        if grep -q "mongoose\|mongodb" package.json; then
            echo "✓ MongoDB client detected"
            DB_TYPE="mongodb"
        fi
    fi

    # Check for Python Django/SQLAlchemy
    if [ -f "manage.py" ]; then
        echo "✓ Django project detected"
        DB_TOOL="django"
    fi

    if [ -f "alembic.ini" ]; then
        echo "✓ Alembic migrations detected"
        DB_TOOL="alembic"
    fi

    echo ""
}

detect_databases
```

## Phase 2: MCP Server Setup

```bash
#!/bin/bash
# Check for MCP database server configuration

check_mcp_setup() {
    echo "=== MCP Database Server Check ==="
    echo ""

    if [ ! -f "$HOME/.claude/config.json" ]; then
        echo "⚠️  No MCP configuration found"
        echo "Run: /mcp-setup postgres|mysql|mongodb"
        return 1
    fi

    # Check for database MCP servers
    if grep -q "postgres" "$HOME/.claude/config.json"; then
        echo "✓ PostgreSQL MCP server configured"
        POSTGRES_MCP=true
    fi

    if grep -q "mysql" "$HOME/.claude/config.json"; then
        echo "✓ MySQL MCP server configured"
        MYSQL_MCP=true
    fi

    if grep -q "mongodb" "$HOME/.claude/config.json"; then
        echo "✓ MongoDB MCP server configured"
        MONGODB_MCP=true
    fi

    if [ -z "$POSTGRES_MCP" ] && [ -z "$MYSQL_MCP" ] && [ -z "$MONGODB_MCP" ]; then
        echo "⚠️  No database MCP servers configured"
        echo ""
        echo "Setup with: /mcp-setup"
        return 1
    fi

    echo ""
}

check_mcp_setup
```

## Phase 3: PostgreSQL Operations

### Connection and Schema Inspection

```bash
#!/bin/bash
# PostgreSQL connection and inspection

connect_postgres() {
    local db_url="$1"

    echo "=== PostgreSQL Connection ==="
    echo ""

    # Test connection
    if psql "$db_url" -c "SELECT version();" &> /dev/null; then
        echo "✓ Connection successful"
    else
        echo "❌ Connection failed"
        echo "Check your connection string and credentials"
        exit 1
    fi

    echo ""
}

inspect_postgres_schema() {
    local db_url="$1"

    echo "=== PostgreSQL Schema Inspection ==="
    echo ""

    # List all tables
    echo "Tables:"
    psql "$db_url" -c "SELECT schemaname, tablename FROM pg_tables WHERE schemaname NOT IN ('pg_catalog', 'information_schema') ORDER BY tablename;"

    echo ""
    echo "Views:"
    psql "$db_url" -c "SELECT schemaname, viewname FROM pg_views WHERE schemaname NOT IN ('pg_catalog', 'information_schema') ORDER BY viewname;"

    echo ""
}

describe_postgres_table() {
    local db_url="$1"
    local table="$2"

    echo "=== Table: $table ==="
    echo ""

    # Table structure
    echo "Columns:"
    psql "$db_url" -c "SELECT column_name, data_type, character_maximum_length, is_nullable, column_default FROM information_schema.columns WHERE table_name = '$table' ORDER BY ordinal_position;"

    echo ""
    echo "Indexes:"
    psql "$db_url" -c "SELECT indexname, indexdef FROM pg_indexes WHERE tablename = '$table';"

    echo ""
    echo "Foreign Keys:"
    psql "$db_url" -c "SELECT
        tc.constraint_name,
        tc.table_name,
        kcu.column_name,
        ccu.table_name AS foreign_table_name,
        ccu.column_name AS foreign_column_name
    FROM information_schema.table_constraints AS tc
    JOIN information_schema.key_column_usage AS kcu
        ON tc.constraint_name = kcu.constraint_name
    JOIN information_schema.constraint_column_usage AS ccu
        ON ccu.constraint_name = tc.constraint_name
    WHERE tc.constraint_type = 'FOREIGN KEY' AND tc.table_name='$table';"

    echo ""
    echo "Row count:"
    psql "$db_url" -c "SELECT COUNT(*) FROM $table;"

    echo ""
}

# Execute
case "$1" in
    connect)
        connect_postgres "$2"
        ;;
    schema)
        inspect_postgres_schema "$2"
        ;;
    describe)
        describe_postgres_table "$2" "$3"
        ;;
    *)
        echo "Usage: $0 {connect|schema|describe} <db-url> [table]"
        ;;
esac
```

### Safe Query Execution

```typescript
// scripts/db-query-postgres.ts
import { Client } from 'pg';

interface QueryConfig {
  connectionString: string;
  query: string;
  params?: any[];
  timeout?: number;
  readOnly?: boolean;
}

async function executeQuery(config: QueryConfig) {
  const client = new Client({
    connectionString: config.connectionString,
    statement_timeout: config.timeout || 30000, // 30s default
  });

  try {
    await client.connect();
    console.log('✓ Connected to PostgreSQL');

    // Enable read-only mode if requested
    if (config.readOnly) {
      await client.query('SET default_transaction_read_only = on;');
      console.log('✓ Read-only mode enabled');
    }

    console.log('');
    console.log('Executing query...');
    console.log('');

    const startTime = Date.now();
    const result = await client.query(config.query, config.params);
    const duration = Date.now() - startTime;

    console.log(`✓ Query completed in ${duration}ms`);
    console.log(`  Rows: ${result.rowCount}`);
    console.log('');

    // Display results
    if (result.rows.length > 0) {
      console.table(result.rows.slice(0, 100)); // Limit display to 100 rows

      if (result.rows.length > 100) {
        console.log(`... and ${result.rows.length - 100} more rows`);
      }
    }

    return result.rows;

  } catch (error: any) {
    console.error('❌ Query failed:', error.message);

    if (error.code) {
      console.error('  Error code:', error.code);
    }

    throw error;

  } finally {
    await client.end();
  }
}

// CLI execution
const query = process.argv[2];
const connectionString = process.env.DATABASE_URL || process.argv[3];

if (!query || !connectionString) {
  console.log('Usage: ts-node db-query-postgres.ts <query> [connection-string]');
  console.log('Or set DATABASE_URL environment variable');
  process.exit(1);
}

// Safety check - prevent destructive operations without explicit flag
const dangerousKeywords = ['DROP', 'DELETE', 'TRUNCATE', 'UPDATE'];
const isDangerous = dangerousKeywords.some(keyword =>
  query.toUpperCase().includes(keyword)
);

if (isDangerous && !process.argv.includes('--allow-destructive')) {
  console.error('❌ Destructive query detected!');
  console.error('Use --allow-destructive flag to allow this operation');
  process.exit(1);
}

executeQuery({
  connectionString,
  query,
  readOnly: !process.argv.includes('--allow-destructive'),
}).catch(() => process.exit(1));
```

## Phase 4: MySQL Operations

```bash
#!/bin/bash
# MySQL connection and operations

connect_mysql() {
    local host="${1:-localhost}"
    local user="${2:-root}"
    local database="${3}"

    echo "=== MySQL Connection ==="
    echo ""

    # Test connection
    if mysql -h "$host" -u "$user" -p -e "SHOW DATABASES;" &> /dev/null; then
        echo "✓ Connection successful"
    else
        echo "❌ Connection failed"
        exit 1
    fi

    if [ -n "$database" ]; then
        echo "Database: $database"
    fi

    echo ""
}

inspect_mysql_schema() {
    local host="$1"
    local user="$2"
    local database="$3"

    echo "=== MySQL Schema Inspection ==="
    echo ""

    # List tables
    echo "Tables:"
    mysql -h "$host" -u "$user" -p "$database" -e "SHOW TABLES;"

    echo ""
    echo "Table sizes:"
    mysql -h "$host" -u "$user" -p "$database" -e "
        SELECT
            table_name AS 'Table',
            ROUND(((data_length + index_length) / 1024 / 1024), 2) AS 'Size (MB)'
        FROM information_schema.TABLES
        WHERE table_schema = '$database'
        ORDER BY (data_length + index_length) DESC;
    "

    echo ""
}

describe_mysql_table() {
    local host="$1"
    local user="$2"
    local database="$3"
    local table="$4"

    echo "=== Table: $table ==="
    echo ""

    # Table structure
    echo "Structure:"
    mysql -h "$host" -u "$user" -p "$database" -e "DESCRIBE $table;"

    echo ""
    echo "Indexes:"
    mysql -h "$host" -u "$user" -p "$database" -e "SHOW INDEX FROM $table;"

    echo ""
    echo "Create statement:"
    mysql -h "$host" -u "$user" -p "$database" -e "SHOW CREATE TABLE $table\G"

    echo ""
}

# Execute
case "$1" in
    connect)
        connect_mysql "$2" "$3" "$4"
        ;;
    schema)
        inspect_mysql_schema "$2" "$3" "$4"
        ;;
    describe)
        describe_mysql_table "$2" "$3" "$4" "$5"
        ;;
    *)
        echo "Usage: $0 {connect|schema|describe} <host> <user> <database> [table]"
        ;;
esac
```

## Phase 5: MongoDB Operations

```typescript
// scripts/db-query-mongodb.ts
import { MongoClient } from 'mongodb';

interface MongoConfig {
  uri: string;
  database: string;
  collection?: string;
  operation: 'find' | 'aggregate' | 'count' | 'distinct';
  query?: any;
  projection?: any;
  sort?: any;
  limit?: number;
}

async function executeMongoOperation(config: MongoConfig) {
  const client = new MongoClient(config.uri);

  try {
    await client.connect();
    console.log('✓ Connected to MongoDB');

    const db = client.db(config.database);
    console.log(`✓ Using database: ${config.database}`);

    if (config.collection) {
      const collection = db.collection(config.collection);
      console.log(`✓ Using collection: ${config.collection}`);
      console.log('');

      switch (config.operation) {
        case 'find':
          const docs = await collection
            .find(config.query || {})
            .project(config.projection || {})
            .sort(config.sort || {})
            .limit(config.limit || 100)
            .toArray();

          console.log(`✓ Found ${docs.length} documents`);
          console.log('');
          console.log(JSON.stringify(docs, null, 2));
          break;

        case 'count':
          const count = await collection.countDocuments(config.query || {});
          console.log(`✓ Count: ${count}`);
          break;

        case 'distinct':
          const field = Object.keys(config.query || {})[0];
          const values = await collection.distinct(field);
          console.log(`✓ Distinct values for ${field}:`);
          console.log(values);
          break;

        case 'aggregate':
          const pipeline = config.query as any[];
          const results = await collection.aggregate(pipeline).toArray();
          console.log(`✓ Aggregation results: ${results.length} documents`);
          console.log('');
          console.log(JSON.stringify(results, null, 2));
          break;
      }
    } else {
      // List collections
      const collections = await db.listCollections().toArray();
      console.log('Collections:');
      collections.forEach(col => {
        console.log(`  - ${col.name}`);
      });
    }

  } catch (error: any) {
    console.error('❌ Operation failed:', error.message);
    throw error;

  } finally {
    await client.close();
  }
}

// CLI execution
const uri = process.env.MONGODB_URI || process.argv[2];
const database = process.argv[3];
const collection = process.argv[4];

if (!uri || !database) {
  console.log('Usage: ts-node db-query-mongodb.ts <uri> <database> [collection]');
  console.log('Or set MONGODB_URI environment variable');
  process.exit(1);
}

executeMongoOperation({
  uri,
  database,
  collection,
  operation: 'find',
  limit: 10,
}).catch(() => process.exit(1));
```

```bash
#!/bin/bash
# MongoDB shell wrapper

inspect_mongodb() {
    local uri="$1"
    local database="$2"

    echo "=== MongoDB Inspection ==="
    echo ""

    # List databases
    echo "Databases:"
    mongosh "$uri" --quiet --eval "db.adminCommand('listDatabases').databases.forEach(d => print(d.name))"

    if [ -n "$database" ]; then
        echo ""
        echo "Collections in $database:"
        mongosh "$uri/$database" --quiet --eval "db.getCollectionNames().forEach(c => print(c))"

        echo ""
        echo "Database stats:"
        mongosh "$uri/$database" --quiet --eval "printjson(db.stats())"
    fi

    echo ""
}

inspect_mongodb "$1" "$2"
```

## Phase 6: Query Builder Interface

```typescript
// scripts/db-query-builder.ts
interface QueryBuilder {
  select(columns: string[]): this;
  from(table: string): this;
  where(condition: string, params?: any[]): this;
  orderBy(column: string, direction: 'ASC' | 'DESC'): this;
  limit(count: number): this;
  toSQL(): { query: string; params: any[] };
}

class PostgreSQLQueryBuilder implements QueryBuilder {
  private columns: string[] = ['*'];
  private table: string = '';
  private conditions: string[] = [];
  private params: any[] = [];
  private orderColumn?: string;
  private orderDirection: 'ASC' | 'DESC' = 'ASC';
  private limitCount?: number;

  select(columns: string[]): this {
    this.columns = columns;
    return this;
  }

  from(table: string): this {
    this.table = table;
    return this;
  }

  where(condition: string, params?: any[]): this {
    this.conditions.push(condition);
    if (params) {
      this.params.push(...params);
    }
    return this;
  }

  orderBy(column: string, direction: 'ASC' | 'DESC' = 'ASC'): this {
    this.orderColumn = column;
    this.orderDirection = direction;
    return this;
  }

  limit(count: number): this {
    this.limitCount = count;
    return this;
  }

  toSQL(): { query: string; params: any[] } {
    let query = `SELECT ${this.columns.join(', ')} FROM ${this.table}`;

    if (this.conditions.length > 0) {
      query += ` WHERE ${this.conditions.join(' AND ')}`;
    }

    if (this.orderColumn) {
      query += ` ORDER BY ${this.orderColumn} ${this.orderDirection}`;
    }

    if (this.limitCount) {
      query += ` LIMIT ${this.limitCount}`;
    }

    return { query, params: this.params };
  }
}

// Example usage
const builder = new PostgreSQLQueryBuilder();
const { query, params } = builder
  .select(['id', 'name', 'email'])
  .from('users')
  .where('active = $1', [true])
  .where('created_at > $2', [new Date('2024-01-01')])
  .orderBy('created_at', 'DESC')
  .limit(10)
  .toSQL();

console.log('Query:', query);
console.log('Params:', params);
```

## Phase 7: Database Migration Support

```bash
#!/bin/bash
# Database migration helpers

run_migration() {
    local db_tool="$1"
    local direction="${2:-up}"

    echo "=== Running Database Migration ==="
    echo "Tool: $db_tool"
    echo "Direction: $direction"
    echo ""

    case "$db_tool" in
        prisma)
            if [ "$direction" = "up" ]; then
                npx prisma migrate deploy
            else
                echo "Prisma doesn't support down migrations"
                echo "Use 'prisma migrate diff' to create a new migration"
            fi
            ;;
        knex)
            npx knex migrate:$direction
            ;;
        typeorm)
            npx typeorm migration:run
            ;;
        alembic)
            if [ "$direction" = "up" ]; then
                alembic upgrade head
            else
                alembic downgrade -1
            fi
            ;;
        django)
            python manage.py migrate
            ;;
        *)
            echo "Unsupported migration tool: $db_tool"
            exit 1
            ;;
    esac

    if [ $? -eq 0 ]; then
        echo ""
        echo "✓ Migration completed successfully"
    else
        echo ""
        echo "❌ Migration failed"
        exit 1
    fi
}

run_migration "$1" "$2"
```

## Practical Examples

**PostgreSQL:**
```bash
/database-connect postgres --schema
/database-connect postgres --table users
/database-connect postgres --query "SELECT * FROM users LIMIT 10"
```

**MySQL:**
```bash
/database-connect mysql --schema mydb
/database-connect mysql --describe products
```

**MongoDB:**
```bash
/database-connect mongodb --list-collections
/database-connect mongodb --query users '{"active": true}'
```

## Safety Features

**Query Safety:**
- ✅ Read-only mode by default
- ✅ Query timeout enforcement
- ✅ Destructive operation warnings
- ✅ Parameter sanitization
- ✅ Connection pooling

**Best Practices:**
- ✅ Use parameterized queries
- ✅ Limit result sets
- ✅ Index usage analysis
- ✅ Connection cleanup
- ✅ Error handling

## Integration Points

- `/schema-validate` - Validate database schema against ORM
- `/query-optimize` - Analyze and optimize queries
- `/migration-generate` - Generate database migrations
- `/mcp-setup` - Configure database MCP servers

## What I'll Actually Do

1. **Detect database** - Identify database type and ORM
2. **Verify connection** - Test database accessibility
3. **Inspect safely** - Explore schema in read-only mode
4. **Execute queries** - Run with safety checks
5. **Document results** - Clear output and insights

**Important:** I will NEVER:
- Execute destructive queries without confirmation
- Expose database credentials
- Skip connection security
- Add AI attribution

All database operations will be safe, validated, and well-documented.

**Credits:** Based on MCP database server integrations and standard database CLI tools.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.