Skip to main content
Glama
TranChiHuu

MCP SQL Server

by TranChiHuu

connect_database

Establish a connection to PostgreSQL or MySQL databases using direct parameters or environment variables for secure data access.

Instructions

Connect to a PostgreSQL or MySQL database. Parameters can be provided directly or loaded from environment variables. If no parameters are provided, will use environment variables (DB_TYPE, DB_HOST, DB_PORT, DB_DATABASE, DB_USER, DB_PASSWORD, DB_SSL). For PostgreSQL: POSTGRES_HOST, POSTGRES_PORT, etc. For MySQL: MYSQL_HOST, MYSQL_PORT, etc.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
typeNoDatabase type (optional if using env vars)
hostNoDatabase host (optional if using env vars)
portNoDatabase port (optional if using env vars)
databaseNoDatabase name (optional if using env vars)
userNoDatabase user (optional if using env vars)
passwordNoDatabase password (optional if using env vars)
sslNoUse SSL connection (optional)

Implementation Reference

  • The core handler function for the 'connect_database' tool. It merges user-provided config with environment variables, disconnects any existing connection, initializes a connection pool for PostgreSQL or MySQL, tests the connection, and returns a success message.
    async connectDatabase(config) {
      // Merge with environment variables if config is partial
      let finalConfig;
      
      if (!config.type || !config.host || !config.port || !config.database || !config.user || !config.password) {
        // Try to get missing values from env
        const envConfig = this.getConfigFromEnv();
        if (!envConfig) {
          throw new Error(
            'Incomplete database configuration. Provide all parameters or set environment variables:\n' +
            'For PostgreSQL: DB_TYPE=postgresql, DB_HOST, DB_PORT, DB_DATABASE, DB_USER, DB_PASSWORD\n' +
            'For MySQL: DB_TYPE=mysql, MYSQL_HOST, MYSQL_PORT, MYSQL_DATABASE, MYSQL_USER, MYSQL_PASSWORD'
          );
        }
        
        // Merge provided config with env config (provided values take precedence)
        finalConfig = {
          type: config.type || envConfig.type,
          host: config.host || envConfig.host,
          port: config.port || envConfig.port,
          database: config.database || envConfig.database,
          user: config.user || envConfig.user,
          password: config.password || envConfig.password,
          ssl: config.ssl !== undefined ? config.ssl : envConfig.ssl,
        };
      } else {
        finalConfig = config;
      }
    
      // Disconnect existing connections
      await this.disconnectDatabase();
    
      this.currentConfig = finalConfig;
    
      if (finalConfig.type === 'postgresql') {
        this.postgresPool = new Pool({
          host: finalConfig.host,
          port: finalConfig.port,
          database: finalConfig.database,
          user: finalConfig.user,
          password: finalConfig.password,
          ssl: finalConfig.ssl ? { rejectUnauthorized: false } : false,
          max: 10,
        });
    
        // Test connection
        const client = await this.postgresPool.connect();
        await client.query('SELECT NOW()');
        client.release();
    
        return {
          content: [
            {
              type: 'text',
              text: `Successfully connected to PostgreSQL database: ${finalConfig.database}@${finalConfig.host}:${finalConfig.port}`,
            },
          ],
        };
      } else if (finalConfig.type === 'mysql') {
        this.mysqlConnection = mysql.createPool({
          host: finalConfig.host,
          port: finalConfig.port,
          database: finalConfig.database,
          user: finalConfig.user,
          password: finalConfig.password,
          ssl: finalConfig.ssl ? {} : undefined,
          waitForConnections: true,
          connectionLimit: 10,
        });
    
        // Test connection
        await this.mysqlConnection.query('SELECT NOW()');
    
        return {
          content: [
            {
              type: 'text',
              text: `Successfully connected to MySQL database: ${finalConfig.database}@${finalConfig.host}:${finalConfig.port}`,
            },
          ],
        };
      } else {
        throw new Error(`Unsupported database type: ${finalConfig.type}`);
      }
    }
  • Input schema defining the parameters for connecting to a database: type (postgresql/mysql), host, port, database, user, password, ssl.
    inputSchema: {
      type: 'object',
      properties: {
        type: {
          type: 'string',
          enum: ['postgresql', 'mysql'],
          description: 'Database type (optional if using env vars)',
        },
        host: {
          type: 'string',
          description: 'Database host (optional if using env vars)',
        },
        port: {
          type: 'number',
          description: 'Database port (optional if using env vars)',
        },
        database: {
          type: 'string',
          description: 'Database name (optional if using env vars)',
        },
        user: {
          type: 'string',
          description: 'Database user (optional if using env vars)',
        },
        password: {
          type: 'string',
          description: 'Database password (optional if using env vars)',
        },
        ssl: {
          type: 'boolean',
          description: 'Use SSL connection (optional)',
          default: false,
        },
      },
      required: [],
    },
  • index.js:112-152 (registration)
    Tool registration in the ListToolsRequestSchema handler, including name, description, and input schema.
    {
      name: 'connect_database',
      description:
        'Connect to a PostgreSQL or MySQL database. Parameters can be provided directly or loaded from environment variables. If no parameters are provided, will use environment variables (DB_TYPE, DB_HOST, DB_PORT, DB_DATABASE, DB_USER, DB_PASSWORD, DB_SSL). For PostgreSQL: POSTGRES_HOST, POSTGRES_PORT, etc. For MySQL: MYSQL_HOST, MYSQL_PORT, etc.',
      inputSchema: {
        type: 'object',
        properties: {
          type: {
            type: 'string',
            enum: ['postgresql', 'mysql'],
            description: 'Database type (optional if using env vars)',
          },
          host: {
            type: 'string',
            description: 'Database host (optional if using env vars)',
          },
          port: {
            type: 'number',
            description: 'Database port (optional if using env vars)',
          },
          database: {
            type: 'string',
            description: 'Database name (optional if using env vars)',
          },
          user: {
            type: 'string',
            description: 'Database user (optional if using env vars)',
          },
          password: {
            type: 'string',
            description: 'Database password (optional if using env vars)',
          },
          ssl: {
            type: 'boolean',
            description: 'Use SSL connection (optional)',
            default: false,
          },
        },
        required: [],
      },
    },
  • index.js:213-214 (registration)
    Dispatch logic in the CallToolRequestSchema handler that routes 'connect_database' calls to the connectDatabase method.
    case 'connect_database':
      return await this.connectDatabase(args);
  • Supporting utility to extract and validate database configuration from various environment variable formats for both PostgreSQL and MySQL.
    getConfigFromEnv() {
      // Check for PostgreSQL env vars
      const pgHost = process.env.DB_HOST || process.env.POSTGRES_HOST;
      const pgPort = process.env.DB_PORT || process.env.POSTGRES_PORT;
      const pgDatabase = process.env.DB_DATABASE || process.env.POSTGRES_DATABASE;
      const pgUser = process.env.DB_USER || process.env.POSTGRES_USER;
      const pgPassword = process.env.DB_PASSWORD || process.env.POSTGRES_PASSWORD;
      const dbType = process.env.DB_TYPE || process.env.DATABASE_TYPE;
    
      // Check for MySQL env vars
      const mysqlHost = process.env.MYSQL_HOST;
      const mysqlPort = process.env.MYSQL_PORT;
      const mysqlDatabase = process.env.MYSQL_DATABASE;
      const mysqlUser = process.env.MYSQL_USER;
      const mysqlPassword = process.env.MYSQL_PASSWORD;
    
      // Determine database type
      let type = null;
      if (dbType) {
        type = dbType.toLowerCase() === 'mysql' ? 'mysql' : 'postgresql';
      } else if (mysqlHost || mysqlDatabase) {
        type = 'mysql';
      } else if (pgHost || pgDatabase) {
        type = 'postgresql';
      }
    
      if (!type) {
        return null;
      }
    
      if (type === 'postgresql') {
        if (!pgHost || !pgPort || !pgDatabase || !pgUser || !pgPassword) {
          return null;
        }
        return {
          type: 'postgresql',
          host: pgHost,
          port: parseInt(pgPort, 10),
          database: pgDatabase,
          user: pgUser,
          password: pgPassword,
          ssl: process.env.DB_SSL === 'true' || process.env.POSTGRES_SSL === 'true',
        };
      } else {
        if (!mysqlHost || !mysqlPort || !mysqlDatabase || !mysqlUser || !mysqlPassword) {
          return null;
        }
        return {
          type: 'mysql',
          host: mysqlHost,
          port: parseInt(mysqlPort, 10),
          database: mysqlDatabase,
          user: mysqlUser,
          password: mysqlPassword,
          ssl: process.env.DB_SSL === 'true' || process.env.MYSQL_SSL === 'true',
        };
      }
    }
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It explains the fallback to environment variables and SSL usage, which adds useful context. However, it lacks details on error handling, connection persistence, timeouts, or authentication requirements beyond basic parameters, leaving gaps in behavioral understanding.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is appropriately sized and front-loaded with the core purpose. Each sentence adds necessary information about parameter sourcing and environment variables without redundancy. It could be slightly more structured by separating concerns (e.g., parameter vs. env var details), but it remains efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity of a database connection tool with 7 parameters, no annotations, and no output schema, the description is moderately complete. It covers parameter sourcing and basic usage but lacks details on return values, error cases, or connection lifecycle, which are critical for such an operation. The absence of output schema exacerbates this gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all parameters. The description adds value by explaining the environment variable mappings (e.g., DB_TYPE, POSTGRES_HOST, MYSQL_HOST) and the optional nature of parameters, which clarifies usage beyond the schema's basic descriptions. It does not fully detail parameter interactions or validation rules.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Connect to a PostgreSQL or MySQL database') and specifies the resource (database), making the purpose explicit. It distinguishes from sibling tools like 'execute_query' or 'list_tables' by focusing on establishing a connection rather than querying or metadata operations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context on when to use this tool (to connect to a database) and how parameters can be sourced (directly or from environment variables). However, it does not explicitly state when not to use it or mention alternatives like using existing connections from other tools, which prevents a perfect score.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/TranChiHuu/postgres-mysql-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server