@cmd233/mcp-database-server 1.1.6 → 1.2.0

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.
@@ -24,6 +24,6 @@ export function createDbAdapter(type, connectionInfo) {
24
24
  case 'mysql':
25
25
  return new MysqlAdapter(connectionInfo);
26
26
  default:
27
- throw new Error(`Unsupported database type: ${type}`);
27
+ throw new Error(`不支持的数据库类型: ${type}`);
28
28
  }
29
29
  }
@@ -18,7 +18,7 @@ export async function initDatabase(connectionInfo, dbType = 'sqlite') {
18
18
  await dbAdapter.init();
19
19
  }
20
20
  catch (error) {
21
- throw new Error(`Failed to initialize database: ${error.message}`);
21
+ throw new Error(`数据库初始化失败: ${error.message}`);
22
22
  }
23
23
  }
24
24
  /**
@@ -29,7 +29,7 @@ export async function initDatabase(connectionInfo, dbType = 'sqlite') {
29
29
  */
30
30
  export function dbAll(query, params = []) {
31
31
  if (!dbAdapter) {
32
- throw new Error("Database not initialized");
32
+ throw new Error("数据库未初始化");
33
33
  }
34
34
  return dbAdapter.all(query, params);
35
35
  }
@@ -41,7 +41,7 @@ export function dbAll(query, params = []) {
41
41
  */
42
42
  export function dbRun(query, params = []) {
43
43
  if (!dbAdapter) {
44
- throw new Error("Database not initialized");
44
+ throw new Error("数据库未初始化");
45
45
  }
46
46
  return dbAdapter.run(query, params);
47
47
  }
@@ -52,7 +52,7 @@ export function dbRun(query, params = []) {
52
52
  */
53
53
  export function dbExec(query) {
54
54
  if (!dbAdapter) {
55
- throw new Error("Database not initialized");
55
+ throw new Error("数据库未初始化");
56
56
  }
57
57
  return dbAdapter.exec(query);
58
58
  }
@@ -70,7 +70,7 @@ export function closeDatabase() {
70
70
  */
71
71
  export function getDatabaseMetadata() {
72
72
  if (!dbAdapter) {
73
- throw new Error("Database not initialized");
73
+ throw new Error("数据库未初始化");
74
74
  }
75
75
  return dbAdapter.getMetadata();
76
76
  }
@@ -79,7 +79,7 @@ export function getDatabaseMetadata() {
79
79
  */
80
80
  export function getListTablesQuery() {
81
81
  if (!dbAdapter) {
82
- throw new Error("Database not initialized");
82
+ throw new Error("数据库未初始化");
83
83
  }
84
84
  return dbAdapter.getListTablesQuery();
85
85
  }
@@ -89,7 +89,44 @@ export function getListTablesQuery() {
89
89
  */
90
90
  export function getDescribeTableQuery(tableName) {
91
91
  if (!dbAdapter) {
92
- throw new Error("Database not initialized");
92
+ throw new Error("数据库未初始化");
93
93
  }
94
94
  return dbAdapter.getDescribeTableQuery(tableName);
95
95
  }
96
+ /**
97
+ * 获取列出视图的数据库特定查询
98
+ * 仅 SQL Server 支持,其他数据库返回空结果
99
+ */
100
+ export function getListViewsQuery() {
101
+ if (!dbAdapter) {
102
+ throw new Error("数据库未初始化");
103
+ }
104
+ if (dbAdapter.getListViewsQuery) {
105
+ return dbAdapter.getListViewsQuery();
106
+ }
107
+ // 不支持视图的数据库返回空结果查询
108
+ return "SELECT 1 as name WHERE 1=0";
109
+ }
110
+ /**
111
+ * 获取视图定义的数据库特定查询
112
+ * 仅 SQL Server 支持
113
+ * @param viewName 视图名
114
+ */
115
+ export function getViewDefinitionQuery(viewName) {
116
+ if (!dbAdapter) {
117
+ throw new Error("数据库未初始化");
118
+ }
119
+ if (dbAdapter.getViewDefinitionQuery) {
120
+ return dbAdapter.getViewDefinitionQuery(viewName);
121
+ }
122
+ throw new Error("当前数据库不支持视图功能");
123
+ }
124
+ /**
125
+ * 检查数据库是否支持视图功能
126
+ */
127
+ export function supportsViews() {
128
+ if (!dbAdapter) {
129
+ return false;
130
+ }
131
+ return dbAdapter.supportsViews ? dbAdapter.supportsViews() : false;
132
+ }
@@ -37,7 +37,7 @@ export class MysqlAdapter {
37
37
  if (connectionInfo.port && typeof connectionInfo.port !== 'number') {
38
38
  const parsedPort = parseInt(connectionInfo.port, 10);
39
39
  if (isNaN(parsedPort)) {
40
- throw new Error(`Invalid port value for MySQL: ${connectionInfo.port}`);
40
+ throw new Error(`无效的 MySQL 端口号: ${connectionInfo.port}`);
41
41
  }
42
42
  this.config.port = parsedPort;
43
43
  }
@@ -49,13 +49,13 @@ export class MysqlAdapter {
49
49
  */
50
50
  async generateAwsAuthToken() {
51
51
  if (!this.awsRegion) {
52
- throw new Error("AWS region is required for IAM authentication");
52
+ throw new Error("AWS IAM 认证需要 AWS 区域参数");
53
53
  }
54
54
  if (!this.config.user) {
55
- throw new Error("AWS username is required for IAM authentication");
55
+ throw new Error("AWS IAM 认证需要 AWS 用户名参数");
56
56
  }
57
57
  try {
58
- console.info(`[INFO] Generating AWS auth token for region: ${this.awsRegion}, host: ${this.host}, user: ${this.config.user}`);
58
+ console.info(`[INFO] 正在为区域 ${this.awsRegion} 生成 AWS 认证令牌, 主机: ${this.host}, 用户: ${this.config.user}`);
59
59
  const signer = new Signer({
60
60
  region: this.awsRegion,
61
61
  hostname: this.host,
@@ -63,12 +63,12 @@ export class MysqlAdapter {
63
63
  username: this.config.user,
64
64
  });
65
65
  const token = await signer.getAuthToken();
66
- console.info(`[INFO] AWS auth token generated successfully`);
66
+ console.info(`[INFO] AWS 认证令牌生成成功`);
67
67
  return token;
68
68
  }
69
69
  catch (err) {
70
- console.error(`[ERROR] Failed to generate AWS auth token: ${err.message}`);
71
- throw new Error(`AWS IAM authentication failed: ${err.message}. Please check your AWS credentials and IAM permissions.`);
70
+ console.error(`[ERROR] 生成 AWS 认证令牌失败: ${err.message}`);
71
+ throw new Error(`AWS IAM 认证失败: ${err.message}。请检查您的 AWS 凭据和 IAM 权限。`);
72
72
  }
73
73
  }
74
74
  /**
@@ -76,10 +76,10 @@ export class MysqlAdapter {
76
76
  */
77
77
  async init() {
78
78
  try {
79
- console.info(`[INFO] Connecting to MySQL: ${this.host}, Database: ${this.database}`);
79
+ console.info(`[INFO] 正在连接 MySQL: ${this.host}, 数据库: ${this.database}`);
80
80
  // 处理 AWS IAM 认证
81
81
  if (this.awsIamAuth) {
82
- console.info(`[INFO] Using AWS IAM authentication for user: ${this.config.user}`);
82
+ console.info(`[INFO] 正在为用户 ${this.config.user} 使用 AWS IAM 认证`);
83
83
  try {
84
84
  const authToken = await this.generateAwsAuthToken();
85
85
  // 使用生成的令牌作为密码创建新配置
@@ -90,22 +90,22 @@ export class MysqlAdapter {
90
90
  this.connection = await mysql.createConnection(awsConfig);
91
91
  }
92
92
  catch (err) {
93
- console.error(`[ERROR] AWS IAM authentication failed: ${err.message}`);
94
- throw new Error(`AWS IAM authentication failed: ${err.message}`);
93
+ console.error(`[ERROR] AWS IAM 认证失败: ${err.message}`);
94
+ throw new Error(`AWS IAM 认证失败: ${err.message}`);
95
95
  }
96
96
  }
97
97
  else {
98
98
  this.connection = await mysql.createConnection(this.config);
99
99
  }
100
- console.info(`[INFO] MySQL connection established successfully`);
100
+ console.info(`[INFO] MySQL 连接成功建立`);
101
101
  }
102
102
  catch (err) {
103
- console.error(`[ERROR] MySQL connection error: ${err.message}`);
103
+ console.error(`[ERROR] MySQL 连接错误: ${err.message}`);
104
104
  if (this.awsIamAuth) {
105
- throw new Error(`Failed to connect to MySQL with AWS IAM authentication: ${err.message}. Please verify your AWS credentials, IAM permissions, and RDS configuration.`);
105
+ throw new Error(`使用 AWS IAM 认证连接 MySQL 失败: ${err.message}。请验证您的 AWS 凭据、IAM 权限和 RDS 配置。`);
106
106
  }
107
107
  else {
108
- throw new Error(`Failed to connect to MySQL: ${err.message}`);
108
+ throw new Error(`连接 MySQL 失败: ${err.message}`);
109
109
  }
110
110
  }
111
111
  }
@@ -114,14 +114,14 @@ export class MysqlAdapter {
114
114
  */
115
115
  async all(query, params = []) {
116
116
  if (!this.connection) {
117
- throw new Error("Database not initialized");
117
+ throw new Error("数据库未初始化");
118
118
  }
119
119
  try {
120
120
  const [rows] = await this.connection.execute(query, params);
121
121
  return Array.isArray(rows) ? rows : [];
122
122
  }
123
123
  catch (err) {
124
- throw new Error(`MySQL query error: ${err.message}`);
124
+ throw new Error(`MySQL 查询错误: ${err.message}`);
125
125
  }
126
126
  }
127
127
  /**
@@ -129,7 +129,7 @@ export class MysqlAdapter {
129
129
  */
130
130
  async run(query, params = []) {
131
131
  if (!this.connection) {
132
- throw new Error("Database not initialized");
132
+ throw new Error("数据库未初始化");
133
133
  }
134
134
  try {
135
135
  const [result] = await this.connection.execute(query, params);
@@ -138,7 +138,7 @@ export class MysqlAdapter {
138
138
  return { changes, lastID };
139
139
  }
140
140
  catch (err) {
141
- throw new Error(`MySQL query error: ${err.message}`);
141
+ throw new Error(`MySQL 查询错误: ${err.message}`);
142
142
  }
143
143
  }
144
144
  /**
@@ -146,13 +146,13 @@ export class MysqlAdapter {
146
146
  */
147
147
  async exec(query) {
148
148
  if (!this.connection) {
149
- throw new Error("Database not initialized");
149
+ throw new Error("数据库未初始化");
150
150
  }
151
151
  try {
152
152
  await this.connection.query(query);
153
153
  }
154
154
  catch (err) {
155
- throw new Error(`MySQL batch error: ${err.message}`);
155
+ throw new Error(`MySQL 批处理错误: ${err.message}`);
156
156
  }
157
157
  }
158
158
  /**
@@ -24,7 +24,7 @@ export class PostgresqlAdapter {
24
24
  */
25
25
  async init() {
26
26
  try {
27
- console.error(`[INFO] Connecting to PostgreSQL: ${this.host}, Database: ${this.database}`);
27
+ console.error(`[INFO] 正在连接 PostgreSQL: ${this.host}, 数据库: ${this.database}`);
28
28
  console.error(`[DEBUG] Connection details:`, {
29
29
  host: this.host,
30
30
  database: this.database,
@@ -35,11 +35,11 @@ export class PostgresqlAdapter {
35
35
  });
36
36
  this.client = new pg.Client(this.config);
37
37
  await this.client.connect();
38
- console.error(`[INFO] PostgreSQL connection established successfully`);
38
+ console.error(`[INFO] PostgreSQL 连接成功建立`);
39
39
  }
40
40
  catch (err) {
41
- console.error(`[ERROR] PostgreSQL connection error: ${err.message}`);
42
- throw new Error(`Failed to connect to PostgreSQL: ${err.message}`);
41
+ console.error(`[ERROR] PostgreSQL 连接错误: ${err.message}`);
42
+ throw new Error(`连接 PostgreSQL 失败: ${err.message}`);
43
43
  }
44
44
  }
45
45
  /**
@@ -50,16 +50,17 @@ export class PostgresqlAdapter {
50
50
  */
51
51
  async all(query, params = []) {
52
52
  if (!this.client) {
53
- throw new Error("Database not initialized");
53
+ throw new Error("数据库未初始化");
54
54
  }
55
55
  try {
56
56
  // PostgreSQL 使用 $1, $2 等作为参数化查询的占位符
57
- const preparedQuery = query.replace(/\?/g, (_, i) => `$${i + 1}`);
57
+ let paramIndex = 0;
58
+ const preparedQuery = query.replace(/\?/g, () => `$${++paramIndex}`);
58
59
  const result = await this.client.query(preparedQuery, params);
59
60
  return result.rows;
60
61
  }
61
62
  catch (err) {
62
- throw new Error(`PostgreSQL query error: ${err.message}`);
63
+ throw new Error(`PostgreSQL 查询错误: ${err.message}`);
63
64
  }
64
65
  }
65
66
  /**
@@ -70,11 +71,12 @@ export class PostgresqlAdapter {
70
71
  */
71
72
  async run(query, params = []) {
72
73
  if (!this.client) {
73
- throw new Error("Database not initialized");
74
+ throw new Error("数据库未初始化");
74
75
  }
75
76
  try {
76
77
  // 将 ? 替换为编号参数
77
- const preparedQuery = query.replace(/\?/g, (_, i) => `$${i + 1}`);
78
+ let paramIndex = 0;
79
+ const preparedQuery = query.replace(/\?/g, () => `$${++paramIndex}`);
78
80
  let lastID = 0;
79
81
  let changes = 0;
80
82
  // 对于 INSERT 查询,尝试获取插入的 ID
@@ -94,7 +96,7 @@ export class PostgresqlAdapter {
94
96
  return { changes, lastID };
95
97
  }
96
98
  catch (err) {
97
- throw new Error(`PostgreSQL query error: ${err.message}`);
99
+ throw new Error(`PostgreSQL 查询错误: ${err.message}`);
98
100
  }
99
101
  }
100
102
  /**
@@ -104,13 +106,13 @@ export class PostgresqlAdapter {
104
106
  */
105
107
  async exec(query) {
106
108
  if (!this.client) {
107
- throw new Error("Database not initialized");
109
+ throw new Error("数据库未初始化");
108
110
  }
109
111
  try {
110
112
  await this.client.query(query);
111
113
  }
112
114
  catch (err) {
113
- throw new Error(`PostgreSQL batch error: ${err.message}`);
115
+ throw new Error(`PostgreSQL 批处理错误: ${err.message}`);
114
116
  }
115
117
  }
116
118
  /**
@@ -13,14 +13,14 @@ export class SqliteAdapter {
13
13
  async init() {
14
14
  return new Promise((resolve, reject) => {
15
15
  // 确保数据库路径可访问
16
- console.error(`[INFO] Opening SQLite database at: ${this.dbPath}`);
16
+ console.error(`[INFO] 正在打开 SQLite 数据库: ${this.dbPath}`);
17
17
  this.db = new sqlite3.Database(this.dbPath, sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE, (err) => {
18
18
  if (err) {
19
- console.error(`[ERROR] SQLite connection error: ${err.message}`);
19
+ console.error(`[ERROR] SQLite 连接错误: ${err.message}`);
20
20
  reject(err);
21
21
  }
22
22
  else {
23
- console.error("[INFO] SQLite database opened successfully");
23
+ console.error("[INFO] SQLite 数据库成功打开");
24
24
  resolve();
25
25
  }
26
26
  });
@@ -34,7 +34,7 @@ export class SqliteAdapter {
34
34
  */
35
35
  async all(query, params = []) {
36
36
  if (!this.db) {
37
- throw new Error("Database not initialized");
37
+ throw new Error("数据库未初始化");
38
38
  }
39
39
  return new Promise((resolve, reject) => {
40
40
  this.db.all(query, params, (err, rows) => {
@@ -55,7 +55,7 @@ export class SqliteAdapter {
55
55
  */
56
56
  async run(query, params = []) {
57
57
  if (!this.db) {
58
- throw new Error("Database not initialized");
58
+ throw new Error("数据库未初始化");
59
59
  }
60
60
  return new Promise((resolve, reject) => {
61
61
  this.db.run(query, params, function (err) {
@@ -75,7 +75,7 @@ export class SqliteAdapter {
75
75
  */
76
76
  async exec(query) {
77
77
  if (!this.db) {
78
- throw new Error("Database not initialized");
78
+ throw new Error("数据库未初始化");
79
79
  }
80
80
  return new Promise((resolve, reject) => {
81
81
  this.db.exec(query, (err) => {
@@ -68,28 +68,28 @@ export class SqlServerAdapter {
68
68
  await this.pool.close();
69
69
  }
70
70
  catch (closeErr) {
71
- console.error(`[WARN] Error closing old connection pool: ${closeErr.message}`);
71
+ console.error(`[WARN] 关闭旧连接池时出错: ${closeErr.message}`);
72
72
  }
73
73
  this.pool = null;
74
74
  }
75
- console.error(`[INFO] Connecting to SQL Server: ${this.server}, Database: ${this.database}`);
75
+ console.error(`[INFO] 正在连接 SQL Server: ${this.server}, 数据库: ${this.database}`);
76
76
  const pool = new sql.ConnectionPool(this.config);
77
77
  // 使用单次监听器防止内存泄漏
78
78
  pool.once('error', (err) => {
79
- console.error(`[ERROR] SQL Server connection pool error: ${err.message}`);
79
+ console.error(`[ERROR] SQL Server 连接池错误: ${err.message}`);
80
80
  // 标记连接池为不可用,下次查询时会自动重连
81
81
  if (this.pool === pool) {
82
82
  this.pool = null;
83
83
  }
84
84
  });
85
85
  this.pool = await pool.connect();
86
- console.error(`[INFO] SQL Server connection established successfully`);
86
+ console.error(`[INFO] SQL Server 连接成功建立`);
87
87
  return this.pool;
88
88
  }
89
89
  catch (err) {
90
90
  this.pool = null;
91
- console.error(`[ERROR] SQL Server connection error: ${err.message}`);
92
- throw new Error(`Failed to connect to SQL Server: ${err.message}`);
91
+ console.error(`[ERROR] SQL Server 连接错误: ${err.message}`);
92
+ throw new Error(`连接 SQL Server 失败: ${err.message}`);
93
93
  }
94
94
  finally {
95
95
  this.isConnecting = false;
@@ -109,7 +109,7 @@ export class SqlServerAdapter {
109
109
  // 如果超时,重置状态并抛出错误
110
110
  if (this.isConnecting) {
111
111
  this.isConnecting = false;
112
- throw new Error('Connection timeout');
112
+ throw new Error('连接超时');
113
113
  }
114
114
  }
115
115
  /**
@@ -139,7 +139,7 @@ export class SqlServerAdapter {
139
139
  // 只有在获取连接池后(即 poolAcquired = true)发生的连接错误才重试
140
140
  // ensureConnection 本身的错误(如认证失败、连接超时)不应重试
141
141
  if (isConnectionError && poolAcquired && attempt < retries && this.pool !== null) {
142
- console.error(`[WARN] Connection error detected, attempting reconnect (attempt ${attempt + 1}/${retries}): ${lastError.message}`);
142
+ console.error(`[WARN] 检测到连接错误,正在尝试重新连接 (尝试 ${attempt + 1}/${retries}): ${lastError.message}`);
143
143
  this.pool = null;
144
144
  poolAcquired = false; // 重置标记
145
145
  await new Promise(resolve => setTimeout(resolve, 1000 * (attempt + 1)));
@@ -163,7 +163,7 @@ export class SqlServerAdapter {
163
163
  await this.pool.close();
164
164
  }
165
165
  catch (err) {
166
- console.error(`[WARN] Error closing connection pool: ${err.message}`);
166
+ console.error(`[WARN] 关闭连接池时出错: ${err.message}`);
167
167
  }
168
168
  this.pool = null;
169
169
  }
@@ -207,17 +207,22 @@ export class SqlServerAdapter {
207
207
  const preparedQuery = query.replace(/\?/g, () => `@param${paramIndex++}`);
208
208
  // 如果是 INSERT,添加标识值的输出参数
209
209
  let lastID = 0;
210
+ let changes = 0;
210
211
  if (query.trim().toUpperCase().startsWith('INSERT')) {
211
212
  request.output('insertedId', sql.Int, 0);
212
213
  const updatedQuery = `${preparedQuery}; SELECT @insertedId = SCOPE_IDENTITY();`;
213
214
  const result = await request.query(updatedQuery);
214
215
  lastID = result.output.insertedId || 0;
216
+ // 使用 rowsAffected 获取受影响行数
217
+ changes = result.rowsAffected?.[0] || (lastID > 0 ? 1 : 0);
215
218
  }
216
219
  else {
217
- await request.query(preparedQuery);
220
+ const result = await request.query(preparedQuery);
221
+ // 使用 rowsAffected 获取受影响行数
222
+ changes = result.rowsAffected?.[0] || 0;
218
223
  }
219
224
  return {
220
- changes: this.getAffectedRows(query, lastID),
225
+ changes: changes,
221
226
  lastID: lastID
222
227
  };
223
228
  });
@@ -251,8 +256,8 @@ export class SqlServerAdapter {
251
256
  return "SELECT TABLE_NAME as name FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' ORDER BY TABLE_NAME";
252
257
  }
253
258
  /**
254
- * 获取描述表的数据库特定查询
255
- * @param tableName 表名
259
+ * 获取描述表或视图的数据库特定查询
260
+ * @param tableName 表名或视图名
256
261
  */
257
262
  getDescribeTableQuery(tableName) {
258
263
  return `
@@ -272,10 +277,11 @@ export class SqlServerAdapter {
272
277
  LEFT JOIN
273
278
  sys.extended_properties ep
274
279
  ON ep.major_id = (
275
- SELECT t.object_id
276
- FROM sys.tables t
277
- INNER JOIN sys.schemas s ON t.schema_id = s.schema_id
278
- WHERE t.name = '${tableName}' AND s.name = c.TABLE_SCHEMA
280
+ SELECT o.object_id
281
+ FROM sys.objects o
282
+ INNER JOIN sys.schemas s ON o.schema_id = s.schema_id
283
+ WHERE o.name = '${tableName}' AND s.name = c.TABLE_SCHEMA
284
+ AND o.type IN ('U', 'V')
279
285
  )
280
286
  AND ep.minor_id = c.ORDINAL_POSITION
281
287
  AND ep.name = 'MS_Description'
@@ -286,13 +292,23 @@ export class SqlServerAdapter {
286
292
  `;
287
293
  }
288
294
  /**
289
- * 根据查询类型获取受影响行数的辅助方法
295
+ * 获取列出视图的数据库特定查询
290
296
  */
291
- getAffectedRows(query, lastID) {
292
- const queryType = query.trim().split(' ')[0].toUpperCase();
293
- if (queryType === 'INSERT' && lastID > 0) {
294
- return 1;
295
- }
296
- return 0; // 对于 SELECT 返回 0,对于 UPDATE/DELETE 在没有额外查询的情况下未知
297
+ getListViewsQuery() {
298
+ return "SELECT TABLE_NAME as name FROM INFORMATION_SCHEMA.VIEWS ORDER BY TABLE_NAME";
299
+ }
300
+ /**
301
+ * 获取视图定义的数据库特定查询
302
+ * @param viewName 视图名
303
+ * 注意: 使用 WITH ENCRYPTION 创建的视图无法获取定义
304
+ */
305
+ getViewDefinitionQuery(viewName) {
306
+ return `SELECT VIEW_DEFINITION as definition FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_NAME = '${viewName}'`;
307
+ }
308
+ /**
309
+ * 检查数据库是否支持视图功能
310
+ */
311
+ supportsViews() {
312
+ return true;
297
313
  }
298
314
  }
@@ -31,7 +31,7 @@ export async function handleListResources() {
31
31
  };
32
32
  }
33
33
  catch (error) {
34
- throw new Error(`Error listing resources: ${error.message}`);
34
+ throw new Error(`列出资源失败: ${error.message}`);
35
35
  }
36
36
  }
37
37
  /**
@@ -47,7 +47,7 @@ export async function handleReadResource(uri) {
47
47
  const schema = pathComponents.pop();
48
48
  const tableName = pathComponents.pop();
49
49
  if (schema !== SCHEMA_PATH) {
50
- throw new Error("Invalid resource URI");
50
+ throw new Error("无效的资源 URI");
51
51
  }
52
52
  // 使用适配器特定的查询来描述表结构
53
53
  const query = getDescribeTableQuery(tableName);
@@ -67,6 +67,6 @@ export async function handleReadResource(uri) {
67
67
  };
68
68
  }
69
69
  catch (error) {
70
- throw new Error(`Error reading resource: ${error.message}`);
70
+ throw new Error(`读取资源失败: ${error.message}`);
71
71
  }
72
72
  }