Superset MCP Server

/** * Superset API 使用示例 */ import { SupersetApiService } from '../services/superset-api.js'; // 创建环境变量配置 const SUPERSET_URL = process.env.SUPERSET_URL || ''; const SUPERSET_USERNAME = process.env.SUPERSET_USERNAME || ''; const SUPERSET_PASSWORD = process.env.SUPERSET_PASSWORD || ''; async function main() { try { console.log('初始化Superset API服务...'); // 创建Superset API服务实例 const supersetApi = new SupersetApiService({ baseUrl: SUPERSET_URL, username: SUPERSET_USERNAME, password: SUPERSET_PASSWORD, withCredentials: true, // 启用cookie认证支持 }); // 获取客户端实例 const client = supersetApi.getClient(); // 检查认证状态 console.log(`认证状态: ${client.isAuthenticated() ? '已认证' : '未认证'}`); console.log(`访问令牌: ${client.token ? client.token.substring(0, 10) + '...' : '无'}`); console.log(`刷新令牌: ${client.refresh ? client.refresh.substring(0, 10) + '...' : '无'}`); console.log(`CSRF令牌: ${client.csrf ? client.csrf.substring(0, 10) + '...' : '无'}`); // 1. 获取所有数据库 console.log('\n获取数据库列表...'); const databases = await supersetApi.getDatabases(); console.log(`找到 ${databases.length} 个数据库:`); databases.forEach((db, index) => { console.log(`[${index}] ${db.database_name} (ID: ${db.id})`); }); // 如果有数据库,获取第一个数据库的schemas if (databases.length > 0) { // 选择第一个数据库 const selectedDb = databases[0]; console.log(`\n选择数据库: "${selectedDb.database_name}" (ID: ${selectedDb.id})`); // 2. 获取所选数据库的所有schemas console.log(`获取数据库 "${selectedDb.database_name}" 的schemas...`); const schemas = await supersetApi.getSchemas(selectedDb.id); console.log(`找到 ${schemas.length} 个schemas:`); schemas.forEach((schema, index) => { console.log(`[${index}] ${schema || '(默认schema)'}`); }); // 如果有schemas,获取第一个schema的表 if (schemas.length > 0) { // 选择第一个schema const selectedSchema = schemas[0]; console.log(`\n选择schema: "${selectedSchema || '(默认schema)'}"`) // 3. 获取所选schema的所有表 console.log(`获取schema "${selectedSchema || '(默认schema)'}" 的表...`); const tables = await supersetApi.getTables(selectedDb.id, selectedSchema); console.log(`找到 ${tables.length} 个表:`); // 如果有表,获取第一个表的元数据 if (tables.length > 0) { // 选择第一个表 const selectedTable = tables[0]; console.log(`\n选择表: "${selectedTable.schema}.${selectedTable.name}"`); // 4. 获取所选表的元数据 console.log(`获取表 "${selectedTable.schema}.${selectedTable.name}" 的元数据...`); try { const tableMetadata = await supersetApi.getTableMetadata(selectedDb.id, selectedTable.schema, selectedTable.name); console.log(`表名: ${tableMetadata.name}`); console.log(`表描述: ${tableMetadata.comment || '无'}`); if (tableMetadata.columns && tableMetadata.columns.length > 0) { console.log(`找到 ${tableMetadata.columns.length} 个字段:`); tableMetadata.columns.forEach((field, index) => { console.log(`[${index}] ${field.name} (${field.type}${field.nullable ? ', nullable' : ''})`); }); // 显示主键信息 if (tableMetadata.primaryKey && tableMetadata.primaryKey.constrained_columns) { console.log(`主键: ${tableMetadata.primaryKey.name || '无名称'}, 列: ${tableMetadata.primaryKey.constrained_columns.join(', ') || '无'}`); } // 显示索引信息 if (tableMetadata.indexes && tableMetadata.indexes.length > 0) { console.log(`索引数量: ${tableMetadata.indexes.length}`); tableMetadata.indexes.forEach((index, i) => { console.log(` 索引[${i}]: ${index.name}, 列: ${index.column_names.join(', ')}, 类型: ${index.type}, 唯一: ${index.unique}`); }); } } else { console.log('未找到任何字段信息'); } // 5. 执行简单的查询 if (tableMetadata.columns && tableMetadata.columns.length > 0) { console.log(`\n在表 "${selectedTable.schema}.${selectedTable.name}" 上执行查询...`); const queryRequest = { database_id: selectedDb.id, sql: tableMetadata.selectStar ? `${tableMetadata.selectStar} LIMIT 5` : `SELECT * FROM "${selectedTable.schema}"."${selectedTable.name}" LIMIT 5`, schema: selectedTable.schema, row_limit: 5, client_id: `example_client_${Date.now()}`, sql_editor_id: `example_editor_${Date.now()}` }; console.log('执行查询:', queryRequest.sql); const queryResult = await supersetApi.executeQuery(queryRequest); console.log('查询结果:'); console.log('状态:', queryResult.status); console.log('查询ID:', queryResult.query_id); // 如果查询是异步的,可能需要轮询结果 if (queryResult.status === 'running' && queryResult.query_id) { console.log('查询正在运行,获取结果...'); const results = await supersetApi.getQueryResults(queryResult.query_id); console.log('列:', results.columns); console.log('数据:'); results.data.forEach((row, rowIndex) => { console.log(`行 ${rowIndex + 1}:`, row); }); } else { // 直接显示结果 console.log('列:', queryResult.columns); console.log('数据:'); queryResult.data.forEach((row, rowIndex) => { console.log(`行 ${rowIndex + 1}:`, row); }); } // 测试取消查询功能 if (queryResult.query_id) { console.log(`\n尝试取消查询 (ID: ${queryResult.query_id})...`); const cancelResult = await supersetApi.cancelQuery(queryResult.query_id); console.log(`取消查询结果: ${cancelResult ? '成功' : '失败'}`); } } else { console.log('没有找到任何字段,无法执行查询'); } } catch (metadataError) { console.error('获取表元数据失败:', metadataError); console.log('尝试直接执行查询...'); // 即使获取元数据失败,仍然尝试执行简单查询 const queryRequest = { database_id: selectedDb.id, sql: `SELECT * FROM "${selectedTable.schema}"."${selectedTable.name}" LIMIT 5`, schema: selectedTable.schema, row_limit: 5, client_id: `example_client_${Date.now()}`, sql_editor_id: `example_editor_${Date.now()}` }; try { console.log('执行查询:', queryRequest.sql); const queryResult = await supersetApi.executeQuery(queryRequest); console.log('查询结果:'); console.log('状态:', queryResult.status); console.log('列:', queryResult.columns); console.log('数据:'); queryResult.data.forEach((row, rowIndex) => { console.log(`行 ${rowIndex + 1}:`, row); }); } catch (queryError) { console.error('执行查询失败:', queryError); } } } else { console.log('没有找到任何表,无法获取字段和执行查询'); } } else { console.log('没有找到任何schema,无法获取表'); } } else { console.log('没有找到任何数据库,无法继续'); } console.log('\n示例完成!'); } catch (error) { console.error('示例执行过程中发生错误:', error); } } // 运行示例 main();