Skip to main content
Glama

MCPDemo - Visual SQL Chat Platform

by Ayi456
mysql.ts4.24 kB
import mysql from 'mysql2/promise'; import { Connection, ExecutionResult, Schema, Column } from '../../types/sql.types.js'; import { Connector } from './index.js'; export const createMySQLConnector = (connection: Connection): Connector => { let pool: mysql.Pool | null = null; const getPool = () => { if (!pool) { const poolConfig: any = { host: connection.host, port: connection.port, user: connection.username, password: connection.password, waitForConnections: true, connectionLimit: 10, queueLimit: 0, enableKeepAlive: true, keepAliveInitialDelay: 0, ssl: connection.ssl === true ? { rejectUnauthorized: false } : connection.ssl || undefined }; // MySQL 支持不指定数据库,连接后可动态切换 if (connection.database) { poolConfig.database = connection.database; } pool = mysql.createPool(poolConfig); } return pool; }; const testConnection = async (): Promise<boolean> => { try { const conn = await getPool().getConnection(); await conn.ping(); conn.release(); return true; } catch (error) { console.error('MySQL connection test failed:', error); return false; } }; const execute = async (databaseName: string, statement: string): Promise<ExecutionResult> => { const conn = await getPool().getConnection(); try { if (databaseName) { await conn.query(`USE \`${databaseName}\``); } const [result, fields] = await conn.execute(statement); // 处理查询结果 if (Array.isArray(result)) { return { rows: result, fields: fields }; } // 处理更新/插入/删除结果 const resultHeader = result as mysql.ResultSetHeader; return { affectedRows: resultHeader.affectedRows, changedRows: resultHeader.changedRows, insertId: resultHeader.insertId, message: `Query OK, ${resultHeader.affectedRows} row(s) affected` }; } catch (error: any) { throw new Error(error.message || 'Failed to execute query'); } finally { conn.release(); } }; const getDatabases = async (): Promise<string[]> => { const result = await execute('', 'SHOW DATABASES'); if (result.rows) { return result.rows.map((row: any) => Object.values(row)[0] as string); } return []; }; const getTableSchema = async (databaseName: string): Promise<Schema[]> => { const schemas: Schema[] = []; // 获取所有表 const tablesResult = await execute(databaseName, 'SHOW TABLES'); if (!tablesResult.rows) return schemas; const tableNames = tablesResult.rows.map((row: any) => Object.values(row)[0] as string); // 获取每个表的详细信息 for (const tableName of tableNames) { const columnsResult = await execute( databaseName, `SHOW COLUMNS FROM \`${tableName}\`` ); const columns: Column[] = []; if (columnsResult.rows) { for (const row of columnsResult.rows as any[]) { columns.push({ name: row.Field, type: row.Type, nullable: row.Null === 'YES', default: row.Default, isPrimaryKey: row.Key === 'PRI', isAutoIncrement: row.Extra?.includes('auto_increment'), comment: row.Comment }); } } schemas.push({ name: tableName, type: 'table', columns }); } // 获取所有视图 try { const viewsResult = await execute( databaseName, `SELECT TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_SCHEMA = '${databaseName}'` ); if (viewsResult.rows) { for (const row of viewsResult.rows as any[]) { schemas.push({ name: row.TABLE_NAME, type: 'view' }); } } } catch (error) { // 忽略视图查询错误 console.error('Failed to get views:', error); } return schemas; }; return { testConnection, execute, getDatabases, getTableSchema }; };

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/Ayi456/visual-mcp'

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