@bytebase/dbhub 0.2.2 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +21 -18
  2. package/dist/index.js +58 -55
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -36,14 +36,14 @@ https://demo.dbhub.ai/sse connects a [sample employee database](https://github.c
36
36
 
37
37
  ### Database Resources
38
38
 
39
- | Resource Name | URI Format | PostgreSQL | MySQL | SQL Server | SQLite |
40
- | ----------------------------- | ----------------------------------------------------------- | :--------: | :---: | :--------: | :----: |
41
- | schemas | `db://schemas` | ✅ | ✅ | ✅ | ✅ |
42
- | tables_in_schema | `db://schemas/{schemaName}/tables` | ✅ | ✅ | ✅ | ✅ |
43
- | table_structure_in_schema | `db://schemas/{schemaName}/tables/{tableName}` | ✅ | ✅ | ✅ | ✅ |
44
- | indexes_in_table | `db://schemas/{schemaName}/tables/{tableName}/indexes` | ✅ | ✅ | ✅ | ✅ |
45
- | procedures_in_schema | `db://schemas/{schemaName}/procedures` | ✅ | ✅ | ✅ | ❌ |
46
- | procedure_details_in_schema | `db://schemas/{schemaName}/procedures/{procedureName}` | ✅ | ✅ | ✅ | ❌ |
39
+ | Resource Name | URI Format | PostgreSQL | MySQL | SQL Server | SQLite |
40
+ | --------------------------- | ------------------------------------------------------ | :--------: | :---: | :--------: | :----: |
41
+ | schemas | `db://schemas` | ✅ | ✅ | ✅ | ✅ |
42
+ | tables_in_schema | `db://schemas/{schemaName}/tables` | ✅ | ✅ | ✅ | ✅ |
43
+ | table_structure_in_schema | `db://schemas/{schemaName}/tables/{tableName}` | ✅ | ✅ | ✅ | ✅ |
44
+ | indexes_in_table | `db://schemas/{schemaName}/tables/{tableName}/indexes` | ✅ | ✅ | ✅ | ✅ |
45
+ | procedures_in_schema | `db://schemas/{schemaName}/procedures` | ✅ | ✅ | ✅ | ❌ |
46
+ | procedure_details_in_schema | `db://schemas/{schemaName}/procedures/{procedureName}` | ✅ | ✅ | ✅ | ❌ |
47
47
 
48
48
  ### Database Tools
49
49
 
@@ -54,10 +54,10 @@ https://demo.dbhub.ai/sse connects a [sample employee database](https://github.c
54
54
 
55
55
  ### Prompt Capabilities
56
56
 
57
- | Prompt | Command Name | PostgreSQL | MySQL | SQL Server | SQLite |
58
- | ------------------- | --------------- | :--------: | :---: | :--------: | :----: |
59
- | Generate SQL | `generate_sql` | ✅ | ✅ | ✅ | ✅ |
60
- | Explain DB Elements | `explain_db` | ✅ | ✅ | ✅ | ✅ |
57
+ | Prompt | Command Name | PostgreSQL | MySQL | SQL Server | SQLite |
58
+ | ------------------- | -------------- | :--------: | :---: | :--------: | :----: |
59
+ | Generate SQL | `generate_sql` | ✅ | ✅ | ✅ | ✅ |
60
+ | Explain DB Elements | `explain_db` | ✅ | ✅ | ✅ | ✅ |
61
61
 
62
62
  ## Installation
63
63
 
@@ -181,14 +181,17 @@ For real databases, a Database Source Name (DSN) is required. You can provide th
181
181
  DSN=postgres://user:password@localhost:5432/dbname?sslmode=disable
182
182
  ```
183
183
 
184
+ > [!WARNING]
185
+ > When running in Docker, use `host.docker.internal` instead of `localhost` to connect to databases running on your host machine. For example: `mysql://user:password@host.docker.internal:3306/dbname`
186
+
184
187
  DBHub supports the following database connection string formats:
185
188
 
186
- | Database | DSN Format | Example |
187
- | ---------- | -------------------------------------------------------- | ----------------------------------------------------------------- |
188
- | PostgreSQL | `postgres://[user]:[password]@[host]:[port]/[database]` | `postgres://user:password@localhost:5432/dbname?sslmode=disable` |
189
- | SQLite | `sqlite:///[path/to/file]` or `sqlite::memory:` | `sqlite:///path/to/database.db` or `sqlite::memory:` |
190
- | SQL Server | `sqlserver://[user]:[password]@[host]:[port]/[database]` | `sqlserver://user:password@localhost:1433/dbname` |
191
- | MySQL | `mysql://[user]:[password]@[host]:[port]/[database]` | `mysql://user:password@localhost:3306/dbname` |
189
+ | Database | DSN Format | Example |
190
+ | ---------- | -------------------------------------------------------- | ---------------------------------------------------------------- |
191
+ | PostgreSQL | `postgres://[user]:[password]@[host]:[port]/[database]` | `postgres://user:password@localhost:5432/dbname?sslmode=disable` |
192
+ | SQLite | `sqlite:///[path/to/file]` or `sqlite::memory:` | `sqlite:///path/to/database.db` or `sqlite::memory:` |
193
+ | SQL Server | `sqlserver://[user]:[password]@[host]:[port]/[database]` | `sqlserver://user:password@localhost:1433/dbname` |
194
+ | MySQL | `mysql://[user]:[password]@[host]:[port]/[database]` | `mysql://user:password@localhost:3306/dbname` |
192
195
 
193
196
  ### Transport
194
197
 
package/dist/index.js CHANGED
@@ -974,11 +974,11 @@ var MySQLConnector = class {
974
974
  }
975
975
  try {
976
976
  const [rows] = await this.pool.query(`
977
- SELECT schema_name
978
- FROM information_schema.schemata
979
- ORDER BY schema_name
977
+ SELECT SCHEMA_NAME
978
+ FROM INFORMATION_SCHEMA.SCHEMATA
979
+ ORDER BY SCHEMA_NAME
980
980
  `);
981
- return rows.map((row) => row.schema_name);
981
+ return rows.map((row) => row.SCHEMA_NAME);
982
982
  } catch (error) {
983
983
  console.error("Error getting schemas:", error);
984
984
  throw error;
@@ -989,15 +989,15 @@ var MySQLConnector = class {
989
989
  throw new Error("Not connected to database");
990
990
  }
991
991
  try {
992
- const schemaClause = schema ? "WHERE table_schema = ?" : "WHERE table_schema = DATABASE()";
992
+ const schemaClause = schema ? "WHERE TABLE_SCHEMA = ?" : "WHERE TABLE_SCHEMA = DATABASE()";
993
993
  const queryParams = schema ? [schema] : [];
994
994
  const [rows] = await this.pool.query(`
995
- SELECT table_name
996
- FROM information_schema.tables
995
+ SELECT TABLE_NAME
996
+ FROM INFORMATION_SCHEMA.TABLES
997
997
  ${schemaClause}
998
- ORDER BY table_name
998
+ ORDER BY TABLE_NAME
999
999
  `, queryParams);
1000
- return rows.map((row) => row.table_name);
1000
+ return rows.map((row) => row.TABLE_NAME);
1001
1001
  } catch (error) {
1002
1002
  console.error("Error getting tables:", error);
1003
1003
  throw error;
@@ -1008,15 +1008,15 @@ var MySQLConnector = class {
1008
1008
  throw new Error("Not connected to database");
1009
1009
  }
1010
1010
  try {
1011
- const schemaClause = schema ? "WHERE table_schema = ?" : "WHERE table_schema = DATABASE()";
1011
+ const schemaClause = schema ? "WHERE TABLE_SCHEMA = ?" : "WHERE TABLE_SCHEMA = DATABASE()";
1012
1012
  const queryParams = schema ? [schema, tableName] : [tableName];
1013
1013
  const [rows] = await this.pool.query(`
1014
- SELECT COUNT(*) as count
1015
- FROM information_schema.tables
1014
+ SELECT COUNT(*) AS COUNT
1015
+ FROM INFORMATION_SCHEMA.TABLES
1016
1016
  ${schemaClause}
1017
- AND table_name = ?
1017
+ AND TABLE_NAME = ?
1018
1018
  `, queryParams);
1019
- return rows[0].count > 0;
1019
+ return rows[0].COUNT > 0;
1020
1020
  } catch (error) {
1021
1021
  console.error("Error checking if table exists:", error);
1022
1022
  throw error;
@@ -1036,7 +1036,7 @@ var MySQLConnector = class {
1036
1036
  NON_UNIQUE,
1037
1037
  SEQ_IN_INDEX
1038
1038
  FROM
1039
- information_schema.STATISTICS
1039
+ INFORMATION_SCHEMA.STATISTICS
1040
1040
  WHERE
1041
1041
  ${schemaClause}
1042
1042
  AND TABLE_NAME = ?
@@ -1080,18 +1080,18 @@ var MySQLConnector = class {
1080
1080
  throw new Error("Not connected to database");
1081
1081
  }
1082
1082
  try {
1083
- const schemaClause = schema ? "WHERE table_schema = ?" : "WHERE table_schema = DATABASE()";
1083
+ const schemaClause = schema ? "WHERE TABLE_SCHEMA = ?" : "WHERE TABLE_SCHEMA = DATABASE()";
1084
1084
  const queryParams = schema ? [schema, tableName] : [tableName];
1085
1085
  const [rows] = await this.pool.query(`
1086
1086
  SELECT
1087
- column_name,
1088
- data_type,
1089
- is_nullable,
1090
- column_default
1091
- FROM information_schema.columns
1087
+ COLUMN_NAME as column_name,
1088
+ DATA_TYPE as data_type,
1089
+ IS_NULLABLE as is_nullable,
1090
+ COLUMN_DEFAULT as column_default
1091
+ FROM INFORMATION_SCHEMA.COLUMNS
1092
1092
  ${schemaClause}
1093
- AND table_name = ?
1094
- ORDER BY ordinal_position
1093
+ AND TABLE_NAME = ?
1094
+ ORDER BY ORDINAL_POSITION
1095
1095
  `, queryParams);
1096
1096
  return rows;
1097
1097
  } catch (error) {
@@ -1104,15 +1104,15 @@ var MySQLConnector = class {
1104
1104
  throw new Error("Not connected to database");
1105
1105
  }
1106
1106
  try {
1107
- const schemaClause = schema ? "WHERE routine_schema = ?" : "WHERE routine_schema = DATABASE()";
1107
+ const schemaClause = schema ? "WHERE ROUTINE_SCHEMA = ?" : "WHERE ROUTINE_SCHEMA = DATABASE()";
1108
1108
  const queryParams = schema ? [schema] : [];
1109
1109
  const [rows] = await this.pool.query(`
1110
- SELECT routine_name
1111
- FROM information_schema.routines
1110
+ SELECT ROUTINE_NAME
1111
+ FROM INFORMATION_SCHEMA.ROUTINES
1112
1112
  ${schemaClause}
1113
- ORDER BY routine_name
1113
+ ORDER BY ROUTINE_NAME
1114
1114
  `, queryParams);
1115
- return rows.map((row) => row.routine_name);
1115
+ return rows.map((row) => row.ROUTINE_NAME);
1116
1116
  } catch (error) {
1117
1117
  console.error("Error getting stored procedures:", error);
1118
1118
  throw error;
@@ -1123,39 +1123,39 @@ var MySQLConnector = class {
1123
1123
  throw new Error("Not connected to database");
1124
1124
  }
1125
1125
  try {
1126
- const schemaClause = schema ? "WHERE r.routine_schema = ?" : "WHERE r.routine_schema = DATABASE()";
1126
+ const schemaClause = schema ? "WHERE r.ROUTINE_SCHEMA = ?" : "WHERE r.ROUTINE_SCHEMA = DATABASE()";
1127
1127
  const queryParams = schema ? [schema, procedureName] : [procedureName];
1128
1128
  const [rows] = await this.pool.query(`
1129
1129
  SELECT
1130
- r.routine_name AS procedure_name,
1130
+ r.ROUTINE_NAME AS procedure_name,
1131
1131
  CASE
1132
- WHEN r.routine_type = 'PROCEDURE' THEN 'procedure'
1132
+ WHEN r.ROUTINE_TYPE = 'PROCEDURE' THEN 'procedure'
1133
1133
  ELSE 'function'
1134
1134
  END AS procedure_type,
1135
- LOWER(r.routine_type) AS routine_type,
1136
- r.routine_definition,
1137
- r.dtd_identifier AS return_type,
1135
+ LOWER(r.ROUTINE_TYPE) AS routine_type,
1136
+ r.ROUTINE_DEFINITION,
1137
+ r.DTD_IDENTIFIER AS return_type,
1138
1138
  (
1139
1139
  SELECT GROUP_CONCAT(
1140
- CONCAT(p.parameter_name, ' ', p.parameter_mode, ' ', p.data_type)
1141
- ORDER BY p.ordinal_position
1140
+ CONCAT(p.PARAMETER_NAME, ' ', p.PARAMETER_MODE, ' ', p.DATA_TYPE)
1141
+ ORDER BY p.ORDINAL_POSITION
1142
1142
  SEPARATOR ', '
1143
1143
  )
1144
- FROM information_schema.parameters p
1145
- WHERE p.specific_schema = r.routine_schema
1146
- AND p.specific_name = r.routine_name
1147
- AND p.parameter_name IS NOT NULL
1144
+ FROM INFORMATION_SCHEMA.PARAMETERS p
1145
+ WHERE p.SPECIFIC_SCHEMA = r.ROUTINE_SCHEMA
1146
+ AND p.SPECIFIC_NAME = r.ROUTINE_NAME
1147
+ AND p.PARAMETER_NAME IS NOT NULL
1148
1148
  ) AS parameter_list
1149
- FROM information_schema.routines r
1149
+ FROM INFORMATION_SCHEMA.ROUTINES r
1150
1150
  ${schemaClause}
1151
- AND r.routine_name = ?
1151
+ AND r.ROUTINE_NAME = ?
1152
1152
  `, queryParams);
1153
1153
  if (rows.length === 0) {
1154
1154
  const schemaName = schema || "current schema";
1155
1155
  throw new Error(`Stored procedure '${procedureName}' not found in ${schemaName}`);
1156
1156
  }
1157
1157
  const procedure = rows[0];
1158
- let definition = procedure.routine_definition;
1158
+ let definition = procedure.ROUTINE_DEFINITION;
1159
1159
  try {
1160
1160
  const schemaValue = schema || await this.getCurrentSchema();
1161
1161
  if (procedure.procedure_type === "procedure") {
@@ -1183,15 +1183,15 @@ var MySQLConnector = class {
1183
1183
  }
1184
1184
  if (!definition) {
1185
1185
  const [bodyRows] = await this.pool.query(`
1186
- SELECT routine_definition, routine_body
1187
- FROM information_schema.routines
1188
- WHERE routine_schema = ? AND routine_name = ?
1186
+ SELECT ROUTINE_DEFINITION, ROUTINE_BODY
1187
+ FROM INFORMATION_SCHEMA.ROUTINES
1188
+ WHERE ROUTINE_SCHEMA = ? AND ROUTINE_NAME = ?
1189
1189
  `, [schemaValue, procedureName]);
1190
1190
  if (bodyRows && bodyRows.length > 0) {
1191
- if (bodyRows[0].routine_definition) {
1192
- definition = bodyRows[0].routine_definition;
1193
- } else if (bodyRows[0].routine_body) {
1194
- definition = bodyRows[0].routine_body;
1191
+ if (bodyRows[0].ROUTINE_DEFINITION) {
1192
+ definition = bodyRows[0].ROUTINE_DEFINITION;
1193
+ } else if (bodyRows[0].ROUTINE_BODY) {
1194
+ definition = bodyRows[0].ROUTINE_BODY;
1195
1195
  }
1196
1196
  }
1197
1197
  }
@@ -1214,8 +1214,8 @@ var MySQLConnector = class {
1214
1214
  }
1215
1215
  // Helper method to get current schema (database) name
1216
1216
  async getCurrentSchema() {
1217
- const [rows] = await this.pool.query("SELECT DATABASE() as db");
1218
- return rows[0].db;
1217
+ const [rows] = await this.pool.query("SELECT DATABASE() AS DB");
1218
+ return rows[0].DB;
1219
1219
  }
1220
1220
  async executeQuery(query) {
1221
1221
  if (!this.pool) {
@@ -1595,7 +1595,7 @@ async function tablesResourceHandler(uri, variables, _extra) {
1595
1595
  }
1596
1596
 
1597
1597
  // src/resources/schema.ts
1598
- async function schemaResourceHandler(uri, variables, _extra) {
1598
+ async function tableStructureResourceHandler(uri, variables, _extra) {
1599
1599
  const connector = ConnectorManager.getCurrentConnector();
1600
1600
  const tableName = Array.isArray(variables.tableName) ? variables.tableName[0] : variables.tableName;
1601
1601
  const schemaName = variables.schemaName ? Array.isArray(variables.schemaName) ? variables.schemaName[0] : variables.schemaName : void 0;
@@ -1796,7 +1796,7 @@ function registerResources(server) {
1796
1796
  server.resource(
1797
1797
  "table_structure_in_schema",
1798
1798
  new ResourceTemplate("db://schemas/{schemaName}/tables/{tableName}", { list: void 0 }),
1799
- schemaResourceHandler
1799
+ tableStructureResourceHandler
1800
1800
  );
1801
1801
  server.resource(
1802
1802
  "indexes_in_table",
@@ -1846,7 +1846,6 @@ async function runQueryToolHandler({ query }, _extra) {
1846
1846
 
1847
1847
  // src/tools/list-connectors.ts
1848
1848
  async function listConnectorsToolHandler(_args, _extra) {
1849
- const connectors = ConnectorManager.getAvailableConnectors();
1850
1849
  const samples = ConnectorRegistry.getAllSampleDSNs();
1851
1850
  let activeConnectorId = null;
1852
1851
  try {
@@ -2169,6 +2168,10 @@ ${possibleTableMatches.join("\n")}`
2169
2168
  "EXPLANATION_ERROR"
2170
2169
  );
2171
2170
  }
2171
+ return formatPromptErrorResponse(
2172
+ `Unable to process request for schema: ${schema}, table: ${table}`,
2173
+ "UNHANDLED_REQUEST"
2174
+ );
2172
2175
  }
2173
2176
  function determineTablePurpose(tableName, columns) {
2174
2177
  const lowerTableName = tableName.toLowerCase();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bytebase/dbhub",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "Universal Database MCP Server",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",