@cmd233/mcp-database-server 1.1.1 → 1.1.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.
@@ -1,13 +1,13 @@
1
1
  import pg from 'pg';
2
2
  /**
3
- * PostgreSQL database adapter implementation
3
+ * PostgreSQL 数据库适配器实现
4
4
  */
5
5
  export class PostgresqlAdapter {
6
6
  constructor(connectionInfo) {
7
7
  this.client = null;
8
8
  this.host = connectionInfo.host;
9
9
  this.database = connectionInfo.database;
10
- // Create PostgreSQL connection config
10
+ // 创建 PostgreSQL 连接配置
11
11
  this.config = {
12
12
  host: connectionInfo.host,
13
13
  database: connectionInfo.database,
@@ -15,12 +15,12 @@ export class PostgresqlAdapter {
15
15
  user: connectionInfo.user,
16
16
  password: connectionInfo.password,
17
17
  ssl: connectionInfo.ssl,
18
- // Add connection timeout if provided (in milliseconds)
18
+ // 如果提供了连接超时,则添加(以毫秒为单位)
19
19
  connectionTimeoutMillis: connectionInfo.connectionTimeout || 30000,
20
20
  };
21
21
  }
22
22
  /**
23
- * Initialize PostgreSQL connection
23
+ * 初始化 PostgreSQL 连接
24
24
  */
25
25
  async init() {
26
26
  try {
@@ -43,17 +43,17 @@ export class PostgresqlAdapter {
43
43
  }
44
44
  }
45
45
  /**
46
- * Execute a SQL query and get all results
47
- * @param query SQL query to execute
48
- * @param params Query parameters
49
- * @returns Promise with query results
46
+ * 执行 SQL 查询并获取所有结果
47
+ * @param query 要执行的 SQL 查询
48
+ * @param params 查询参数
49
+ * @returns 包含查询结果的 Promise
50
50
  */
51
51
  async all(query, params = []) {
52
52
  if (!this.client) {
53
53
  throw new Error("Database not initialized");
54
54
  }
55
55
  try {
56
- // PostgreSQL uses $1, $2, etc. for parameterized queries
56
+ // PostgreSQL 使用 $1, $2 等作为参数化查询的占位符
57
57
  const preparedQuery = query.replace(/\?/g, (_, i) => `$${i + 1}`);
58
58
  const result = await this.client.query(preparedQuery, params);
59
59
  return result.rows;
@@ -63,23 +63,23 @@ export class PostgresqlAdapter {
63
63
  }
64
64
  }
65
65
  /**
66
- * Execute a SQL query that modifies data
67
- * @param query SQL query to execute
68
- * @param params Query parameters
69
- * @returns Promise with result info
66
+ * 执行修改数据的 SQL 查询
67
+ * @param query 要执行的 SQL 查询
68
+ * @param params 查询参数
69
+ * @returns 包含结果信息的 Promise
70
70
  */
71
71
  async run(query, params = []) {
72
72
  if (!this.client) {
73
73
  throw new Error("Database not initialized");
74
74
  }
75
75
  try {
76
- // Replace ? with numbered parameters
76
+ // ? 替换为编号参数
77
77
  const preparedQuery = query.replace(/\?/g, (_, i) => `$${i + 1}`);
78
78
  let lastID = 0;
79
79
  let changes = 0;
80
- // For INSERT queries, try to get the inserted ID
80
+ // 对于 INSERT 查询,尝试获取插入的 ID
81
81
  if (query.trim().toUpperCase().startsWith('INSERT')) {
82
- // Add RETURNING clause to get the inserted ID if it doesn't already have one
82
+ // 如果查询中没有 RETURNING 子句,则添加以获取插入的 ID
83
83
  const returningQuery = preparedQuery.includes('RETURNING')
84
84
  ? preparedQuery
85
85
  : `${preparedQuery} RETURNING id`;
@@ -98,9 +98,9 @@ export class PostgresqlAdapter {
98
98
  }
99
99
  }
100
100
  /**
101
- * Execute multiple SQL statements
102
- * @param query SQL statements to execute
103
- * @returns Promise that resolves when execution completes
101
+ * 执行多条 SQL 语句
102
+ * @param query 要执行的 SQL 语句
103
+ * @returns 执行完成后解析的 Promise
104
104
  */
105
105
  async exec(query) {
106
106
  if (!this.client) {
@@ -114,7 +114,7 @@ export class PostgresqlAdapter {
114
114
  }
115
115
  }
116
116
  /**
117
- * Close the database connection
117
+ * 关闭数据库连接
118
118
  */
119
119
  async close() {
120
120
  if (this.client) {
@@ -123,7 +123,7 @@ export class PostgresqlAdapter {
123
123
  }
124
124
  }
125
125
  /**
126
- * Get database metadata
126
+ * 获取数据库元数据
127
127
  */
128
128
  getMetadata() {
129
129
  return {
@@ -134,14 +134,14 @@ export class PostgresqlAdapter {
134
134
  };
135
135
  }
136
136
  /**
137
- * Get database-specific query for listing tables
137
+ * 获取用于列出表的数据库特定查询
138
138
  */
139
139
  getListTablesQuery() {
140
140
  return "SELECT table_name as name FROM information_schema.tables WHERE table_schema = 'public' ORDER BY table_name";
141
141
  }
142
142
  /**
143
- * Get database-specific query for describing a table
144
- * @param tableName Table name
143
+ * 获取用于描述表结构的数据库特定查询
144
+ * @param tableName 表名
145
145
  */
146
146
  getDescribeTableQuery(tableName) {
147
147
  return `
@@ -1,6 +1,6 @@
1
1
  import sqlite3 from "sqlite3";
2
2
  /**
3
- * SQLite database adapter implementation
3
+ * SQLite 数据库适配器实现
4
4
  */
5
5
  export class SqliteAdapter {
6
6
  constructor(dbPath) {
@@ -8,11 +8,11 @@ export class SqliteAdapter {
8
8
  this.dbPath = dbPath;
9
9
  }
10
10
  /**
11
- * Initialize the SQLite database connection
11
+ * 初始化 SQLite 数据库连接
12
12
  */
13
13
  async init() {
14
14
  return new Promise((resolve, reject) => {
15
- // Ensure the dbPath is accessible
15
+ // 确保数据库路径可访问
16
16
  console.error(`[INFO] Opening SQLite database at: ${this.dbPath}`);
17
17
  this.db = new sqlite3.Database(this.dbPath, sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE, (err) => {
18
18
  if (err) {
@@ -27,10 +27,10 @@ export class SqliteAdapter {
27
27
  });
28
28
  }
29
29
  /**
30
- * Execute a SQL query and get all results
31
- * @param query SQL query to execute
32
- * @param params Query parameters
33
- * @returns Promise with query results
30
+ * 执行 SQL 查询并返回所有结果
31
+ * @param query 要执行的 SQL 查询
32
+ * @param params 查询参数
33
+ * @returns 包含查询结果的 Promise
34
34
  */
35
35
  async all(query, params = []) {
36
36
  if (!this.db) {
@@ -48,10 +48,10 @@ export class SqliteAdapter {
48
48
  });
49
49
  }
50
50
  /**
51
- * Execute a SQL query that modifies data
52
- * @param query SQL query to execute
53
- * @param params Query parameters
54
- * @returns Promise with result info
51
+ * 执行修改数据的 SQL 查询
52
+ * @param query 要执行的 SQL 查询
53
+ * @param params 查询参数
54
+ * @returns 包含结果信息的 Promise
55
55
  */
56
56
  async run(query, params = []) {
57
57
  if (!this.db) {
@@ -69,9 +69,9 @@ export class SqliteAdapter {
69
69
  });
70
70
  }
71
71
  /**
72
- * Execute multiple SQL statements
73
- * @param query SQL statements to execute
74
- * @returns Promise that resolves when execution completes
72
+ * 执行多条 SQL 语句
73
+ * @param query 要执行的 SQL 语句
74
+ * @returns 执行完成后完成的 Promise
75
75
  */
76
76
  async exec(query) {
77
77
  if (!this.db) {
@@ -89,7 +89,7 @@ export class SqliteAdapter {
89
89
  });
90
90
  }
91
91
  /**
92
- * Close the database connection
92
+ * 关闭数据库连接
93
93
  */
94
94
  async close() {
95
95
  return new Promise((resolve, reject) => {
@@ -109,7 +109,7 @@ export class SqliteAdapter {
109
109
  });
110
110
  }
111
111
  /**
112
- * Get database metadata
112
+ * 获取数据库元数据
113
113
  */
114
114
  getMetadata() {
115
115
  return {
@@ -119,14 +119,14 @@ export class SqliteAdapter {
119
119
  };
120
120
  }
121
121
  /**
122
- * Get database-specific query for listing tables
122
+ * 获取列出所有表的数据库特定查询
123
123
  */
124
124
  getListTablesQuery() {
125
125
  return "SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'";
126
126
  }
127
127
  /**
128
- * Get database-specific query for describing a table
129
- * @param tableName Table name
128
+ * 获取描述表结构的数据库特定查询
129
+ * @param tableName 表名
130
130
  */
131
131
  getDescribeTableQuery(tableName) {
132
132
  return `PRAGMA table_info(${tableName})`;
@@ -1,91 +1,211 @@
1
1
  import sql from 'mssql';
2
2
  /**
3
- * SQL Server database adapter implementation
3
+ * SQL Server 数据库适配器实现
4
4
  */
5
5
  export class SqlServerAdapter {
6
6
  constructor(connectionInfo) {
7
7
  this.pool = null;
8
+ this.isConnecting = false;
8
9
  this.server = connectionInfo.server;
9
10
  this.database = connectionInfo.database;
10
- // Create SQL Server connection config
11
+ // 创建 SQL Server 连接配置
11
12
  this.config = {
12
13
  server: connectionInfo.server,
13
14
  database: connectionInfo.database,
14
15
  port: connectionInfo.port || 1433,
16
+ // 连接池配置
17
+ pool: {
18
+ max: 10, // 最大连接数
19
+ min: 1, // 最小连接数
20
+ idleTimeoutMillis: 30000, // 空闲连接超时时间 (30秒)
21
+ },
22
+ // 连接超时和请求超时配置
23
+ connectionTimeout: 30000, // 连接超时 (30秒)
24
+ requestTimeout: 30000, // 请求超时 (30秒)
15
25
  options: {
16
26
  trustServerCertificate: connectionInfo.trustServerCertificate ?? true,
27
+ enableArithAbort: true,
17
28
  ...connectionInfo.options
18
29
  }
19
30
  };
20
- // Add authentication options
31
+ // 添加认证选项
21
32
  if (connectionInfo.user && connectionInfo.password) {
22
33
  this.config.user = connectionInfo.user;
23
34
  this.config.password = connectionInfo.password;
24
35
  }
25
36
  else {
26
- // Use Windows authentication if no username/password provided
37
+ // 如果未提供用户名/密码,则使用 Windows 身份验证
27
38
  this.config.options.trustedConnection = true;
28
- this.config.options.enableArithAbort = true;
29
39
  }
30
40
  }
31
41
  /**
32
- * Initialize SQL Server connection
42
+ * 初始化 SQL Server 连接
33
43
  */
34
44
  async init() {
45
+ await this.ensureConnection();
46
+ }
47
+ /**
48
+ * 确保连接可用,如果连接断开则自动重连
49
+ */
50
+ async ensureConnection() {
51
+ // 如果正在连接中,等待连接完成
52
+ if (this.isConnecting) {
53
+ await this.waitForConnection();
54
+ if (this.pool && this.pool.connected) {
55
+ return this.pool;
56
+ }
57
+ }
58
+ // 检查现有连接是否可用
59
+ if (this.pool && this.pool.connected) {
60
+ return this.pool;
61
+ }
62
+ // 需要建立新连接
63
+ this.isConnecting = true;
35
64
  try {
65
+ // 如果存在旧的连接池,先关闭它
66
+ if (this.pool) {
67
+ try {
68
+ await this.pool.close();
69
+ }
70
+ catch (closeErr) {
71
+ console.error(`[WARN] Error closing old connection pool: ${closeErr.message}`);
72
+ }
73
+ this.pool = null;
74
+ }
36
75
  console.error(`[INFO] Connecting to SQL Server: ${this.server}, Database: ${this.database}`);
37
- this.pool = await new sql.ConnectionPool(this.config).connect();
76
+ const pool = new sql.ConnectionPool(this.config);
77
+ // 使用单次监听器防止内存泄漏
78
+ pool.once('error', (err) => {
79
+ console.error(`[ERROR] SQL Server connection pool error: ${err.message}`);
80
+ // 标记连接池为不可用,下次查询时会自动重连
81
+ if (this.pool === pool) {
82
+ this.pool = null;
83
+ }
84
+ });
85
+ this.pool = await pool.connect();
38
86
  console.error(`[INFO] SQL Server connection established successfully`);
87
+ return this.pool;
39
88
  }
40
89
  catch (err) {
90
+ this.pool = null;
41
91
  console.error(`[ERROR] SQL Server connection error: ${err.message}`);
42
92
  throw new Error(`Failed to connect to SQL Server: ${err.message}`);
43
93
  }
94
+ finally {
95
+ this.isConnecting = false;
96
+ }
44
97
  }
45
98
  /**
46
- * Execute a SQL query and get all results
47
- * @param query SQL query to execute
48
- * @param params Query parameters
49
- * @returns Promise with query results
99
+ * 等待正在进行的连接完成
50
100
  */
51
- async all(query, params = []) {
52
- if (!this.pool) {
53
- throw new Error("Database not initialized");
101
+ async waitForConnection() {
102
+ const maxWait = 30000; // 最大等待30秒
103
+ const interval = 100; // 每100ms检查一次
104
+ let waited = 0;
105
+ while (this.isConnecting && waited < maxWait) {
106
+ await new Promise(resolve => setTimeout(resolve, interval));
107
+ waited += interval;
54
108
  }
55
- try {
56
- const request = this.pool.request();
57
- // Add parameters to the request
109
+ // 如果超时,重置状态并抛出错误
110
+ if (this.isConnecting) {
111
+ this.isConnecting = false;
112
+ throw new Error('Connection timeout');
113
+ }
114
+ }
115
+ /**
116
+ * 执行带重试的操作
117
+ */
118
+ async executeWithRetry(operation, retries = 2) {
119
+ let lastError = null;
120
+ let poolAcquired = false; // 标记是否已成功获取连接池
121
+ for (let attempt = 0; attempt <= retries; attempt++) {
122
+ try {
123
+ const pool = await this.ensureConnection();
124
+ poolAcquired = true; // 成功获取连接池
125
+ return await operation(pool);
126
+ }
127
+ catch (err) {
128
+ lastError = err;
129
+ const errorMessage = lastError.message.toLowerCase();
130
+ // 检查是否是连接相关的错误
131
+ const isConnectionError = errorMessage.includes('connection') ||
132
+ errorMessage.includes('socket') ||
133
+ errorMessage.includes('timeout') ||
134
+ errorMessage.includes('closed') ||
135
+ errorMessage.includes('econnreset') ||
136
+ errorMessage.includes('econnrefused') ||
137
+ errorMessage.includes('network') ||
138
+ errorMessage.includes('failed to connect');
139
+ // 只有在获取连接池后(即 poolAcquired = true)发生的连接错误才重试
140
+ // ensureConnection 本身的错误(如认证失败、连接超时)不应重试
141
+ if (isConnectionError && poolAcquired && attempt < retries && this.pool !== null) {
142
+ console.error(`[WARN] Connection error detected, attempting reconnect (attempt ${attempt + 1}/${retries}): ${lastError.message}`);
143
+ this.pool = null;
144
+ poolAcquired = false; // 重置标记
145
+ await new Promise(resolve => setTimeout(resolve, 1000 * (attempt + 1)));
146
+ continue;
147
+ }
148
+ throw lastError;
149
+ }
150
+ }
151
+ throw lastError;
152
+ }
153
+ /**
154
+ * 关闭数据库连接
155
+ */
156
+ async close() {
157
+ // 等待正在进行的连接完成
158
+ if (this.isConnecting) {
159
+ await this.waitForConnection();
160
+ }
161
+ if (this.pool) {
162
+ try {
163
+ await this.pool.close();
164
+ }
165
+ catch (err) {
166
+ console.error(`[WARN] Error closing connection pool: ${err.message}`);
167
+ }
168
+ this.pool = null;
169
+ }
170
+ this.isConnecting = false;
171
+ }
172
+ /**
173
+ * 执行 SQL 查询并获取所有结果
174
+ * @param query 要执行的 SQL 查询
175
+ * @param params 查询参数
176
+ * @returns 包含查询结果的 Promise
177
+ */
178
+ async all(query, params = []) {
179
+ return this.executeWithRetry(async (pool) => {
180
+ const request = pool.request();
181
+ // 向请求添加参数
58
182
  params.forEach((param, index) => {
59
183
  request.input(`param${index}`, param);
60
184
  });
61
- // Replace ? with named parameters
62
- const preparedQuery = query.replace(/\?/g, (_, i) => `@param${i}`);
185
+ // ? 替换为命名参数
186
+ let paramIndex = 0;
187
+ const preparedQuery = query.replace(/\?/g, () => `@param${paramIndex++}`);
63
188
  const result = await request.query(preparedQuery);
64
189
  return result.recordset;
65
- }
66
- catch (err) {
67
- throw new Error(`SQL Server query error: ${err.message}`);
68
- }
190
+ });
69
191
  }
70
192
  /**
71
- * Execute a SQL query that modifies data
72
- * @param query SQL query to execute
73
- * @param params Query parameters
74
- * @returns Promise with result info
193
+ * 执行修改数据的 SQL 查询
194
+ * @param query 要执行的 SQL 查询
195
+ * @param params 查询参数
196
+ * @returns 包含结果信息的 Promise
75
197
  */
76
198
  async run(query, params = []) {
77
- if (!this.pool) {
78
- throw new Error("Database not initialized");
79
- }
80
- try {
81
- const request = this.pool.request();
82
- // Add parameters to the request
199
+ return this.executeWithRetry(async (pool) => {
200
+ const request = pool.request();
201
+ // 向请求添加参数
83
202
  params.forEach((param, index) => {
84
203
  request.input(`param${index}`, param);
85
204
  });
86
- // Replace ? with named parameters
87
- const preparedQuery = query.replace(/\?/g, (_, i) => `@param${i}`);
88
- // Add output parameter for identity value if it's an INSERT
205
+ // ? 替换为命名参数
206
+ let paramIndex = 0;
207
+ const preparedQuery = query.replace(/\?/g, () => `@param${paramIndex++}`);
208
+ // 如果是 INSERT,添加标识值的输出参数
89
209
  let lastID = 0;
90
210
  if (query.trim().toUpperCase().startsWith('INSERT')) {
91
211
  request.output('insertedId', sql.Int, 0);
@@ -94,46 +214,27 @@ export class SqlServerAdapter {
94
214
  lastID = result.output.insertedId || 0;
95
215
  }
96
216
  else {
97
- const result = await request.query(preparedQuery);
98
- lastID = 0;
217
+ await request.query(preparedQuery);
99
218
  }
100
219
  return {
101
220
  changes: this.getAffectedRows(query, lastID),
102
221
  lastID: lastID
103
222
  };
104
- }
105
- catch (err) {
106
- throw new Error(`SQL Server query error: ${err.message}`);
107
- }
223
+ });
108
224
  }
109
225
  /**
110
- * Execute multiple SQL statements
111
- * @param query SQL statements to execute
112
- * @returns Promise that resolves when execution completes
226
+ * 执行多条 SQL 语句
227
+ * @param query 要执行的 SQL 语句
228
+ * @returns 执行完成后解析的 Promise
113
229
  */
114
230
  async exec(query) {
115
- if (!this.pool) {
116
- throw new Error("Database not initialized");
117
- }
118
- try {
119
- const request = this.pool.request();
231
+ return this.executeWithRetry(async (pool) => {
232
+ const request = pool.request();
120
233
  await request.batch(query);
121
- }
122
- catch (err) {
123
- throw new Error(`SQL Server batch error: ${err.message}`);
124
- }
125
- }
126
- /**
127
- * Close the database connection
128
- */
129
- async close() {
130
- if (this.pool) {
131
- await this.pool.close();
132
- this.pool = null;
133
- }
234
+ });
134
235
  }
135
236
  /**
136
- * Get database metadata
237
+ * 获取数据库元数据
137
238
  */
138
239
  getMetadata() {
139
240
  return {
@@ -144,43 +245,43 @@ export class SqlServerAdapter {
144
245
  };
145
246
  }
146
247
  /**
147
- * Get database-specific query for listing tables
248
+ * 获取列出表的数据库特定查询
148
249
  */
149
250
  getListTablesQuery() {
150
251
  return "SELECT TABLE_NAME as name FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' ORDER BY TABLE_NAME";
151
252
  }
152
253
  /**
153
- * Get database-specific query for describing a table
154
- * @param tableName Table name
254
+ * 获取描述表的数据库特定查询
255
+ * @param tableName 表名
155
256
  */
156
257
  getDescribeTableQuery(tableName) {
157
- return `
158
- SELECT
159
- c.COLUMN_NAME as name,
160
- c.DATA_TYPE as type,
161
- CASE WHEN c.IS_NULLABLE = 'NO' THEN 1 ELSE 0 END as notnull,
162
- CASE WHEN pk.CONSTRAINT_TYPE = 'PRIMARY KEY' THEN 1 ELSE 0 END as pk,
163
- c.COLUMN_DEFAULT as dflt_value
164
- FROM
165
- INFORMATION_SCHEMA.COLUMNS c
166
- LEFT JOIN
167
- INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu ON c.TABLE_NAME = kcu.TABLE_NAME AND c.COLUMN_NAME = kcu.COLUMN_NAME
168
- LEFT JOIN
169
- INFORMATION_SCHEMA.TABLE_CONSTRAINTS pk ON kcu.CONSTRAINT_NAME = pk.CONSTRAINT_NAME AND pk.CONSTRAINT_TYPE = 'PRIMARY KEY'
170
- WHERE
171
- c.TABLE_NAME = '${tableName}'
172
- ORDER BY
173
- c.ORDINAL_POSITION
258
+ return `
259
+ SELECT
260
+ c.COLUMN_NAME as name,
261
+ c.DATA_TYPE as type,
262
+ CASE WHEN c.IS_NULLABLE = 'NO' THEN 1 ELSE 0 END as notnull,
263
+ CASE WHEN pk.CONSTRAINT_TYPE = 'PRIMARY KEY' THEN 1 ELSE 0 END as pk,
264
+ c.COLUMN_DEFAULT as dflt_value
265
+ FROM
266
+ INFORMATION_SCHEMA.COLUMNS c
267
+ LEFT JOIN
268
+ INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu ON c.TABLE_NAME = kcu.TABLE_NAME AND c.COLUMN_NAME = kcu.COLUMN_NAME
269
+ LEFT JOIN
270
+ INFORMATION_SCHEMA.TABLE_CONSTRAINTS pk ON kcu.CONSTRAINT_NAME = pk.CONSTRAINT_NAME AND pk.CONSTRAINT_TYPE = 'PRIMARY KEY'
271
+ WHERE
272
+ c.TABLE_NAME = '${tableName}'
273
+ ORDER BY
274
+ c.ORDINAL_POSITION
174
275
  `;
175
276
  }
176
277
  /**
177
- * Helper to get the number of affected rows based on query type
278
+ * 根据查询类型获取受影响行数的辅助方法
178
279
  */
179
280
  getAffectedRows(query, lastID) {
180
281
  const queryType = query.trim().split(' ')[0].toUpperCase();
181
282
  if (queryType === 'INSERT' && lastID > 0) {
182
283
  return 1;
183
284
  }
184
- return 0; // For SELECT, unknown for UPDATE/DELETE without additional query
285
+ return 0; // 对于 SELECT 返回 0,对于 UPDATE/DELETE 在没有额外查询的情况下未知
185
286
  }
186
287
  }
@@ -1,14 +1,14 @@
1
1
  import { dbAll, getListTablesQuery, getDescribeTableQuery, getDatabaseMetadata } from '../db/index.js';
2
2
  /**
3
- * Handle listing resources request
4
- * @returns List of available resources
3
+ * 处理列出资源的请求
4
+ * @returns 可用资源列表
5
5
  */
6
6
  export async function handleListResources() {
7
7
  try {
8
8
  const dbInfo = getDatabaseMetadata();
9
9
  const dbType = dbInfo.type;
10
10
  let resourceBaseUrl;
11
- // Create appropriate URL based on database type
11
+ // 根据数据库类型创建适当的 URL
12
12
  if (dbType === 'sqlite' && dbInfo.path) {
13
13
  resourceBaseUrl = new URL(`sqlite:///${dbInfo.path}`);
14
14
  }
@@ -19,7 +19,7 @@ export async function handleListResources() {
19
19
  resourceBaseUrl = new URL(`db:///database`);
20
20
  }
21
21
  const SCHEMA_PATH = "schema";
22
- // Use adapter-specific query to list tables
22
+ // 使用适配器特定的查询来列出表
23
23
  const query = getListTablesQuery();
24
24
  const result = await dbAll(query);
25
25
  return {
@@ -35,9 +35,9 @@ export async function handleListResources() {
35
35
  }
36
36
  }
37
37
  /**
38
- * Handle reading a specific resource
39
- * @param uri URI of the resource to read
40
- * @returns Resource contents
38
+ * 处理读取特定资源的请求
39
+ * @param uri 要读取的资源 URI
40
+ * @returns 资源内容
41
41
  */
42
42
  export async function handleReadResource(uri) {
43
43
  try {
@@ -49,7 +49,7 @@ export async function handleReadResource(uri) {
49
49
  if (schema !== SCHEMA_PATH) {
50
50
  throw new Error("Invalid resource URI");
51
51
  }
52
- // Use adapter-specific query to describe the table
52
+ // 使用适配器特定的查询来描述表结构
53
53
  const query = getDescribeTableQuery(tableName);
54
54
  const result = await dbAll(query);
55
55
  return {
@@ -1,11 +1,11 @@
1
1
  import { formatErrorResponse } from '../utils/formatUtils.js';
2
- // Import all tool implementations
2
+ // 导入所有工具实现
3
3
  import { readQuery, writeQuery, exportQuery } from '../tools/queryTools.js';
4
4
  import { createTable, alterTable, dropTable, listTables, describeTable } from '../tools/schemaTools.js';
5
5
  import { appendInsight, listInsights } from '../tools/insightTools.js';
6
6
  /**
7
- * Handle listing available tools
8
- * @returns List of available tools
7
+ * 处理列出可用工具的请求
8
+ * @returns 可用工具列表
9
9
  */
10
10
  export function handleListTools() {
11
11
  return {
@@ -120,10 +120,10 @@ export function handleListTools() {
120
120
  };
121
121
  }
122
122
  /**
123
- * Handle tool call requests
124
- * @param name Name of the tool to call
125
- * @param args Arguments for the tool
126
- * @returns Tool execution result
123
+ * 处理工具调用请求
124
+ * @param name 要调用的工具名称
125
+ * @param args 工具参数
126
+ * @returns 工具执行结果
127
127
  */
128
128
  export async function handleToolCall(name, args) {
129
129
  try {