Skip to main content
Glama
LucasSiqueiraSurreco

Database Bridge MCP Server

mysql.adapter.ts3.92 kB
import * as mysql2 from "mysql2/promise"; import { log } from "../../utils/index.js"; import type { DatabaseAdapter, DatabaseType, ConnectionConfig, DatabasePool, DatabaseConnection, NormalizedResult, } from "./types.js"; class MySQLConnection implements DatabaseConnection { constructor(private connection: mysql2.PoolConnection) {} async query<T = any>(sql: string, params?: any[]): Promise<T> { const result = await this.connection.query(sql, params); return (Array.isArray(result) ? result[0] : result) as T; } async beginTransaction(): Promise<void> { await this.connection.beginTransaction(); } async commit(): Promise<void> { await this.connection.commit(); } async rollback(): Promise<void> { await this.connection.rollback(); } release(): void { this.connection.release(); } } class MySQLPool implements DatabasePool { constructor(private pool: mysql2.Pool) {} async getConnection(): Promise<DatabaseConnection> { const connection = await this.pool.getConnection(); return new MySQLConnection(connection); } async end(): Promise<void> { await this.pool.end(); } } export class MySQLAdapter implements DatabaseAdapter { readonly type: DatabaseType = "mysql"; async createPool(config: ConnectionConfig): Promise<DatabasePool> { try { const poolConfig: mysql2.PoolOptions = { ...(config.socketPath ? { socketPath: config.socketPath } : { host: config.host ?? "127.0.0.1", port: config.port ?? 3306, }), user: config.user ?? "root", password: config.password ?? "", database: config.database, connectionLimit: config.connectionLimit ?? 10, authPlugins: { mysql_clear_password: () => () => Buffer.from(config.password ?? ""), }, ...(config.ssl ? { ssl: { rejectUnauthorized: config.ssl.rejectUnauthorized ?? true, ...(config.ssl.ca ? { ca: config.ssl.ca } : {}), ...(config.ssl.cert ? { cert: config.ssl.cert } : {}), ...(config.ssl.key ? { key: config.ssl.key } : {}), }, } : {}), }; const pool = mysql2.createPool(poolConfig); log("info", "MySQL pool created successfully"); return new MySQLPool(pool); } catch (error) { log("error", "Error creating MySQL pool:", error); throw error; } } async executeQuery<T>( pool: DatabasePool, sql: string, params?: any[], ): Promise<T> { let connection: DatabaseConnection | undefined; try { connection = await pool.getConnection(); const result = await connection.query(sql, params); return result as T; } catch (error) { log("error", "Error executing MySQL query:", error); throw error; } finally { if (connection) connection.release(); } } async setReadOnly(connection: DatabaseConnection): Promise<void> { await connection.query("SET SESSION TRANSACTION READ ONLY"); } async unsetReadOnly(connection: DatabaseConnection): Promise<void> { await connection.query("SET SESSION TRANSACTION READ WRITE"); } normalizeResult(result: any): NormalizedResult { if (!result) { return { rows: [] }; } // Se for um ResultSetHeader (INSERT, UPDATE, DELETE, DDL) if ( "affectedRows" in result || "insertId" in result || "changedRows" in result ) { return { rows: [], affectedRows: result.affectedRows ?? 0, insertId: result.insertId ?? 0, changedRows: result.changedRows ?? 0, }; } // Se for um array de rows (SELECT) if (Array.isArray(result)) { return { rows: result }; } return { rows: [] }; } supportsReadOnlyMode(): boolean { return true; } }

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/LucasSiqueiraSurreco/mcp-db-bridge'

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