@iflow-mcp/xexr_mcp-libsql 1.1.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.
- package/LICENSE +21 -0
- package/README.md +509 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +327 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/base-tool.d.ts +29 -0
- package/dist/lib/base-tool.d.ts.map +1 -0
- package/dist/lib/base-tool.js +175 -0
- package/dist/lib/base-tool.js.map +1 -0
- package/dist/lib/constants.d.ts +26 -0
- package/dist/lib/constants.d.ts.map +1 -0
- package/dist/lib/constants.js +47 -0
- package/dist/lib/constants.js.map +1 -0
- package/dist/lib/database.d.ts +39 -0
- package/dist/lib/database.d.ts.map +1 -0
- package/dist/lib/database.js +284 -0
- package/dist/lib/database.js.map +1 -0
- package/dist/lib/logger.d.ts +23 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +124 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/server-manager.d.ts +31 -0
- package/dist/lib/server-manager.d.ts.map +1 -0
- package/dist/lib/server-manager.js +283 -0
- package/dist/lib/server-manager.js.map +1 -0
- package/dist/schemas/alter-table.d.ts +23 -0
- package/dist/schemas/alter-table.d.ts.map +1 -0
- package/dist/schemas/alter-table.js +85 -0
- package/dist/schemas/alter-table.js.map +1 -0
- package/dist/schemas/create-table.d.ts +23 -0
- package/dist/schemas/create-table.d.ts.map +1 -0
- package/dist/schemas/create-table.js +81 -0
- package/dist/schemas/create-table.js.map +1 -0
- package/dist/schemas/describe-table.d.ts +26 -0
- package/dist/schemas/describe-table.d.ts.map +1 -0
- package/dist/schemas/describe-table.js +47 -0
- package/dist/schemas/describe-table.js.map +1 -0
- package/dist/schemas/list-tables.d.ts +29 -0
- package/dist/schemas/list-tables.d.ts.map +1 -0
- package/dist/schemas/list-tables.js +37 -0
- package/dist/schemas/list-tables.js.map +1 -0
- package/dist/schemas/read-query.d.ts +17 -0
- package/dist/schemas/read-query.d.ts.map +1 -0
- package/dist/schemas/read-query.js +66 -0
- package/dist/schemas/read-query.js.map +1 -0
- package/dist/schemas/write-query.d.ts +20 -0
- package/dist/schemas/write-query.d.ts.map +1 -0
- package/dist/schemas/write-query.js +58 -0
- package/dist/schemas/write-query.js.map +1 -0
- package/dist/tools/alter-table.d.ts +31 -0
- package/dist/tools/alter-table.d.ts.map +1 -0
- package/dist/tools/alter-table.js +139 -0
- package/dist/tools/alter-table.js.map +1 -0
- package/dist/tools/create-table.d.ts +31 -0
- package/dist/tools/create-table.d.ts.map +1 -0
- package/dist/tools/create-table.js +121 -0
- package/dist/tools/create-table.js.map +1 -0
- package/dist/tools/describe-table.d.ts +30 -0
- package/dist/tools/describe-table.d.ts.map +1 -0
- package/dist/tools/describe-table.js +165 -0
- package/dist/tools/describe-table.js.map +1 -0
- package/dist/tools/list-tables.d.ts +32 -0
- package/dist/tools/list-tables.d.ts.map +1 -0
- package/dist/tools/list-tables.js +210 -0
- package/dist/tools/list-tables.js.map +1 -0
- package/dist/tools/read-query.d.ts +17 -0
- package/dist/tools/read-query.d.ts.map +1 -0
- package/dist/tools/read-query.js +112 -0
- package/dist/tools/read-query.js.map +1 -0
- package/dist/tools/write-query.d.ts +20 -0
- package/dist/tools/write-query.d.ts.map +1 -0
- package/dist/tools/write-query.js +63 -0
- package/dist/tools/write-query.js.map +1 -0
- package/dist/types/index.d.ts +50 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/error-handler.d.ts +22 -0
- package/dist/utils/error-handler.d.ts.map +1 -0
- package/dist/utils/error-handler.js +85 -0
- package/dist/utils/error-handler.js.map +1 -0
- package/dist/utils/performance.d.ts +16 -0
- package/dist/utils/performance.d.ts.map +1 -0
- package/dist/utils/performance.js +40 -0
- package/dist/utils/performance.js.map +1 -0
- package/package.json +1 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { BaseTool } from '../lib/base-tool.js';
|
|
2
|
+
import { formatPerformanceMetrics } from '../utils/performance.js';
|
|
3
|
+
import { WriteQueryInputSchema } from '../schemas/write-query.js';
|
|
4
|
+
export class WriteQueryTool extends BaseTool {
|
|
5
|
+
name = 'write-query';
|
|
6
|
+
description = 'Execute INSERT, UPDATE, DELETE queries on the libSQL database. Returns affected row count and performance metrics. Supports parameterized queries for security.';
|
|
7
|
+
inputSchema = WriteQueryInputSchema;
|
|
8
|
+
async executeImpl(context) {
|
|
9
|
+
const { query, parameters, useTransaction } = context.arguments;
|
|
10
|
+
try {
|
|
11
|
+
const startTime = Date.now();
|
|
12
|
+
let result;
|
|
13
|
+
if (useTransaction) {
|
|
14
|
+
// Use transaction for automatic rollback on errors
|
|
15
|
+
result = await context.connection.transaction(async (tx) => {
|
|
16
|
+
return parameters && parameters.length > 0
|
|
17
|
+
? await tx.execute({ sql: query, args: parameters })
|
|
18
|
+
: await tx.execute(query);
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
// Execute directly without transaction
|
|
23
|
+
result =
|
|
24
|
+
parameters && parameters.length > 0
|
|
25
|
+
? await context.connection.execute(query, parameters)
|
|
26
|
+
: await context.connection.execute(query);
|
|
27
|
+
}
|
|
28
|
+
const executionTime = Date.now() - startTime;
|
|
29
|
+
const metrics = formatPerformanceMetrics({
|
|
30
|
+
executionTime,
|
|
31
|
+
rowsAffected: result.rowsAffected
|
|
32
|
+
});
|
|
33
|
+
let output = `Query executed successfully${useTransaction ? ' (with transaction)' : ''}\n\n`;
|
|
34
|
+
output += `Rows affected: ${result.rowsAffected}\n`;
|
|
35
|
+
if (result.lastInsertRowid !== undefined && result.lastInsertRowid !== null) {
|
|
36
|
+
output += `Last insert row ID: ${result.lastInsertRowid}\n`;
|
|
37
|
+
}
|
|
38
|
+
output += `\n${metrics}`;
|
|
39
|
+
return {
|
|
40
|
+
content: [
|
|
41
|
+
{
|
|
42
|
+
type: 'text',
|
|
43
|
+
text: output
|
|
44
|
+
}
|
|
45
|
+
]
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
50
|
+
const rollbackMessage = useTransaction ? ' (transaction rolled back)' : '';
|
|
51
|
+
return {
|
|
52
|
+
content: [
|
|
53
|
+
{
|
|
54
|
+
type: 'text',
|
|
55
|
+
text: `Error executing query: ${errorMessage}${rollbackMessage}`
|
|
56
|
+
}
|
|
57
|
+
],
|
|
58
|
+
isError: true
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=write-query.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write-query.js","sourceRoot":"","sources":["../../src/tools/write-query.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAuD,MAAM,qBAAqB,CAAC;AACpG,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,qBAAqB,EAAwB,MAAM,2BAA2B,CAAC;AAExF,MAAM,OAAO,cAAe,SAAQ,QAAQ;IACjC,IAAI,GAAG,aAAa,CAAC;IACrB,WAAW,GAClB,iKAAiK,CAAC;IAC3J,WAAW,GAAG,qBAAqB,CAAC;IAEnC,KAAK,CAAC,WAAW,CAAC,OAA6B;QACvD,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,SAA4B,CAAC;QAEnF,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAE7B,IAAI,MAAM,CAAC;YAEX,IAAI,cAAc,EAAE,CAAC;gBACnB,mDAAmD;gBACnD,MAAM,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,KAAK,EAAC,EAAE,EAAC,EAAE;oBACvD,OAAO,UAAU,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC;wBACxC,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;wBACpD,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;gBAC9B,CAAC,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,uCAAuC;gBACvC,MAAM;oBACJ,UAAU,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC;wBACjC,CAAC,CAAC,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,UAAU,CAAC;wBACrD,CAAC,CAAC,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAChD,CAAC;YAED,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;YAE7C,MAAM,OAAO,GAAG,wBAAwB,CAAC;gBACvC,aAAa;gBACb,YAAY,EAAE,MAAM,CAAC,YAAY;aAClC,CAAC,CAAC;YAEH,IAAI,MAAM,GAAG,8BAA8B,cAAc,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC;YAC7F,MAAM,IAAI,kBAAkB,MAAM,CAAC,YAAY,IAAI,CAAC;YAEpD,IAAI,MAAM,CAAC,eAAe,KAAK,SAAS,IAAI,MAAM,CAAC,eAAe,KAAK,IAAI,EAAE,CAAC;gBAC5E,MAAM,IAAI,uBAAuB,MAAM,CAAC,eAAe,IAAI,CAAC;YAC9D,CAAC;YAED,MAAM,IAAI,KAAK,OAAO,EAAE,CAAC;YAEzB,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,MAAM;qBACb;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC5E,MAAM,eAAe,GAAG,cAAc,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3E,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,0BAA0B,YAAY,GAAG,eAAe,EAAE;qBACjE;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export interface DatabaseConfig {
|
|
2
|
+
url: string;
|
|
3
|
+
authToken?: string;
|
|
4
|
+
minConnections?: number;
|
|
5
|
+
maxConnections?: number;
|
|
6
|
+
connectionTimeout?: number;
|
|
7
|
+
retryInterval?: number;
|
|
8
|
+
queryTimeout?: number;
|
|
9
|
+
maxResultSize?: number;
|
|
10
|
+
}
|
|
11
|
+
export interface QueryMetrics {
|
|
12
|
+
executionTime: number;
|
|
13
|
+
rowsAffected?: number;
|
|
14
|
+
rowsReturned?: number;
|
|
15
|
+
queryPlan?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface QueryResult<T = Record<string, unknown>> {
|
|
18
|
+
data: T[];
|
|
19
|
+
metrics: QueryMetrics;
|
|
20
|
+
}
|
|
21
|
+
export interface WriteResult {
|
|
22
|
+
affectedRows: number;
|
|
23
|
+
metrics: QueryMetrics;
|
|
24
|
+
}
|
|
25
|
+
export interface DatabaseConnection {
|
|
26
|
+
execute: (query: string, params?: any) => Promise<any>;
|
|
27
|
+
transaction: <T>(fn: (tx: any) => Promise<T>) => Promise<T>;
|
|
28
|
+
close: () => Promise<void>;
|
|
29
|
+
isHealthy: () => Promise<boolean>;
|
|
30
|
+
}
|
|
31
|
+
export interface ConnectionPool {
|
|
32
|
+
getConnection: () => Promise<DatabaseConnection>;
|
|
33
|
+
releaseConnection: (connection: DatabaseConnection) => void;
|
|
34
|
+
close: () => Promise<void>;
|
|
35
|
+
healthCheck: () => Promise<boolean>;
|
|
36
|
+
}
|
|
37
|
+
export interface LogLevel {
|
|
38
|
+
ERROR: 'error';
|
|
39
|
+
WARN: 'warn';
|
|
40
|
+
INFO: 'info';
|
|
41
|
+
DEBUG: 'debug';
|
|
42
|
+
}
|
|
43
|
+
export interface LogEntry {
|
|
44
|
+
timestamp: string;
|
|
45
|
+
level: keyof LogLevel;
|
|
46
|
+
message: string;
|
|
47
|
+
context?: Record<string, unknown>;
|
|
48
|
+
error?: Error;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACtD,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,OAAO,EAAE,YAAY,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,YAAY,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IAEjC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IAEvD,WAAW,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,GAAG,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IAC5D,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,SAAS,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,MAAM,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACjD,iBAAiB,EAAE,CAAC,UAAU,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAC5D,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,WAAW,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,QAAQ,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,KAAK,CAAC,EAAE,KAAK,CAAC;CACf"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { McpError } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
+
export declare class DatabaseError extends Error {
|
|
3
|
+
readonly originalError?: Error | undefined;
|
|
4
|
+
readonly query?: string | undefined;
|
|
5
|
+
readonly params?: any[] | undefined;
|
|
6
|
+
constructor(message: string, originalError?: Error | undefined, query?: string | undefined, params?: any[] | undefined);
|
|
7
|
+
}
|
|
8
|
+
export declare class ConnectionError extends DatabaseError {
|
|
9
|
+
constructor(message: string, originalError?: Error);
|
|
10
|
+
}
|
|
11
|
+
export declare class QueryValidationError extends DatabaseError {
|
|
12
|
+
constructor(message: string, query?: string);
|
|
13
|
+
}
|
|
14
|
+
export declare class QueryTimeoutError extends DatabaseError {
|
|
15
|
+
constructor(timeout: number, query?: string);
|
|
16
|
+
}
|
|
17
|
+
export declare class ResultSizeError extends DatabaseError {
|
|
18
|
+
constructor(resultSize: number, maxSize: number);
|
|
19
|
+
}
|
|
20
|
+
export declare function handleDatabaseError(error: Error, context?: Record<string, unknown>): McpError;
|
|
21
|
+
export declare function withTimeout<T>(promise: Promise<T>, timeoutMs: number, timeoutError?: Error): Promise<T>;
|
|
22
|
+
//# sourceMappingURL=error-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-handler.d.ts","sourceRoot":"","sources":["../../src/utils/error-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAa,MAAM,oCAAoC,CAAC;AAGzE,qBAAa,aAAc,SAAQ,KAAK;aAGpB,aAAa,CAAC,EAAE,KAAK;aACrB,KAAK,CAAC,EAAE,MAAM;aAEd,MAAM,CAAC,EAAE,GAAG,EAAE;gBAJ9B,OAAO,EAAE,MAAM,EACC,aAAa,CAAC,EAAE,KAAK,YAAA,EACrB,KAAK,CAAC,EAAE,MAAM,YAAA,EAEd,MAAM,CAAC,EAAE,GAAG,EAAE,YAAA;CAKjC;AAED,qBAAa,eAAgB,SAAQ,aAAa;gBACpC,OAAO,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,KAAK;CAInD;AAED,qBAAa,oBAAqB,SAAQ,aAAa;gBACzC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM;CAI5C;AAED,qBAAa,iBAAkB,SAAQ,aAAa;gBACtC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM;CAI5C;AAED,qBAAa,eAAgB,SAAQ,aAAa;gBACpC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAIhD;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,QAAQ,CAwC7F;AAED,wBAAgB,WAAW,CAAC,CAAC,EAC3B,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EACnB,SAAS,EAAE,MAAM,EACjB,YAAY,CAAC,EAAE,KAAK,GACnB,OAAO,CAAC,CAAC,CAAC,CASZ"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
+
import { logger } from '../lib/logger.js';
|
|
3
|
+
export class DatabaseError extends Error {
|
|
4
|
+
originalError;
|
|
5
|
+
query;
|
|
6
|
+
params;
|
|
7
|
+
constructor(message, originalError, query,
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
9
|
+
params) {
|
|
10
|
+
super(message);
|
|
11
|
+
this.originalError = originalError;
|
|
12
|
+
this.query = query;
|
|
13
|
+
this.params = params;
|
|
14
|
+
this.name = 'DatabaseError';
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export class ConnectionError extends DatabaseError {
|
|
18
|
+
constructor(message, originalError) {
|
|
19
|
+
super(message, originalError);
|
|
20
|
+
this.name = 'ConnectionError';
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export class QueryValidationError extends DatabaseError {
|
|
24
|
+
constructor(message, query) {
|
|
25
|
+
super(message, undefined, query);
|
|
26
|
+
this.name = 'QueryValidationError';
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export class QueryTimeoutError extends DatabaseError {
|
|
30
|
+
constructor(timeout, query) {
|
|
31
|
+
super(`Query timed out after ${timeout}ms`, undefined, query);
|
|
32
|
+
this.name = 'QueryTimeoutError';
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export class ResultSizeError extends DatabaseError {
|
|
36
|
+
constructor(resultSize, maxSize) {
|
|
37
|
+
super(`Result set too large: ${resultSize} rows exceeds limit of ${maxSize}`);
|
|
38
|
+
this.name = 'ResultSizeError';
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
export function handleDatabaseError(error, context) {
|
|
42
|
+
logger.error('Database operation failed', context, error);
|
|
43
|
+
if (error instanceof QueryValidationError) {
|
|
44
|
+
return new McpError(ErrorCode.InvalidParams, error.message, { query: error.query });
|
|
45
|
+
}
|
|
46
|
+
if (error instanceof ConnectionError) {
|
|
47
|
+
return new McpError(ErrorCode.InternalError, 'Database connection failed', {
|
|
48
|
+
originalMessage: error.message
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
if (error instanceof QueryTimeoutError) {
|
|
52
|
+
return new McpError(ErrorCode.InternalError, 'Query execution timed out', {
|
|
53
|
+
query: error.query
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
if (error instanceof ResultSizeError) {
|
|
57
|
+
return new McpError(ErrorCode.InvalidParams, error.message);
|
|
58
|
+
}
|
|
59
|
+
if (error instanceof DatabaseError) {
|
|
60
|
+
return new McpError(ErrorCode.InternalError, error.message, {
|
|
61
|
+
query: error.query,
|
|
62
|
+
params: error.params,
|
|
63
|
+
originalMessage: error.originalError?.message
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
// Handle libSQL client errors
|
|
67
|
+
if (error.message.includes('SQLITE_')) {
|
|
68
|
+
return new McpError(ErrorCode.InvalidParams, `SQL error: ${error.message}`);
|
|
69
|
+
}
|
|
70
|
+
// Generic error fallback
|
|
71
|
+
return new McpError(ErrorCode.InternalError, 'An unexpected database error occurred', {
|
|
72
|
+
originalMessage: error.message
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
export function withTimeout(promise, timeoutMs, timeoutError) {
|
|
76
|
+
return Promise.race([
|
|
77
|
+
promise,
|
|
78
|
+
new Promise((_, reject) => {
|
|
79
|
+
setTimeout(() => {
|
|
80
|
+
reject(timeoutError || new QueryTimeoutError(timeoutMs));
|
|
81
|
+
}, timeoutMs);
|
|
82
|
+
})
|
|
83
|
+
]);
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=error-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../../src/utils/error-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { QueryMetrics } from '../types/index.js';
|
|
2
|
+
import type { ResultSet } from '@libsql/client';
|
|
3
|
+
export declare class PerformanceMonitor {
|
|
4
|
+
static createMetrics(startTime: number, endTime: number, result: ResultSet): QueryMetrics;
|
|
5
|
+
static measureQuery<T>(operation: () => Promise<T>): Promise<{
|
|
6
|
+
result: T;
|
|
7
|
+
executionTime: number;
|
|
8
|
+
}>;
|
|
9
|
+
static formatMetrics(metrics: QueryMetrics): string;
|
|
10
|
+
}
|
|
11
|
+
export declare function formatPerformanceMetrics(params: {
|
|
12
|
+
executionTime: number;
|
|
13
|
+
rowsAffected?: number;
|
|
14
|
+
rowsReturned?: number;
|
|
15
|
+
}): string;
|
|
16
|
+
//# sourceMappingURL=performance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"performance.d.ts","sourceRoot":"","sources":["../../src/utils/performance.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,qBAAa,kBAAkB;IAC7B,MAAM,CAAC,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,YAAY;WAa5E,YAAY,CAAC,CAAC,EACzB,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAC1B,OAAO,CAAC;QAAE,MAAM,EAAE,CAAC,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;IAWhD,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM;CAapD;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE;IAC/C,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,MAAM,CAQT"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export class PerformanceMonitor {
|
|
2
|
+
static createMetrics(startTime, endTime, result) {
|
|
3
|
+
const metrics = {
|
|
4
|
+
executionTime: endTime - startTime,
|
|
5
|
+
rowsAffected: result.rowsAffected,
|
|
6
|
+
rowsReturned: result.rows.length
|
|
7
|
+
};
|
|
8
|
+
// libSQL doesn't provide query plans in the same way as SQLite
|
|
9
|
+
// queryPlan is optional, so we don't include it if not available
|
|
10
|
+
return metrics;
|
|
11
|
+
}
|
|
12
|
+
static async measureQuery(operation) {
|
|
13
|
+
const startTime = Date.now();
|
|
14
|
+
const result = await operation();
|
|
15
|
+
const endTime = Date.now();
|
|
16
|
+
return {
|
|
17
|
+
result,
|
|
18
|
+
executionTime: endTime - startTime
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
static formatMetrics(metrics) {
|
|
22
|
+
const parts = [`${metrics.executionTime}ms`];
|
|
23
|
+
if (metrics.rowsAffected !== undefined && metrics.rowsAffected > 0) {
|
|
24
|
+
parts.push(`${metrics.rowsAffected} affected`);
|
|
25
|
+
}
|
|
26
|
+
if (metrics.rowsReturned !== undefined && metrics.rowsReturned > 0) {
|
|
27
|
+
parts.push(`${metrics.rowsReturned} returned`);
|
|
28
|
+
}
|
|
29
|
+
return parts.join(', ');
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export function formatPerformanceMetrics(params) {
|
|
33
|
+
const metrics = {
|
|
34
|
+
executionTime: params.executionTime,
|
|
35
|
+
...(params.rowsAffected !== undefined && { rowsAffected: params.rowsAffected }),
|
|
36
|
+
...(params.rowsReturned !== undefined && { rowsReturned: params.rowsReturned })
|
|
37
|
+
};
|
|
38
|
+
return PerformanceMonitor.formatMetrics(metrics);
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=performance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"performance.js","sourceRoot":"","sources":["../../src/utils/performance.ts"],"names":[],"mappings":"AAGA,MAAM,OAAO,kBAAkB;IAC7B,MAAM,CAAC,aAAa,CAAC,SAAiB,EAAE,OAAe,EAAE,MAAiB;QACxE,MAAM,OAAO,GAAiB;YAC5B,aAAa,EAAE,OAAO,GAAG,SAAS;YAClC,YAAY,EAAE,MAAM,CAAC,YAAY;YACjC,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM;SACjC,CAAC;QAEF,+DAA+D;QAC/D,iEAAiE;QAEjE,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,YAAY,CACvB,SAA2B;QAE3B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;QACjC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE3B,OAAO;YACL,MAAM;YACN,aAAa,EAAE,OAAO,GAAG,SAAS;SACnC,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,aAAa,CAAC,OAAqB;QACxC,MAAM,KAAK,GAAG,CAAC,GAAG,OAAO,CAAC,aAAa,IAAI,CAAC,CAAC;QAE7C,IAAI,OAAO,CAAC,YAAY,KAAK,SAAS,IAAI,OAAO,CAAC,YAAY,GAAG,CAAC,EAAE,CAAC;YACnE,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,YAAY,WAAW,CAAC,CAAC;QACjD,CAAC;QAED,IAAI,OAAO,CAAC,YAAY,KAAK,SAAS,IAAI,OAAO,CAAC,YAAY,GAAG,CAAC,EAAE,CAAC;YACnE,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,YAAY,WAAW,CAAC,CAAC;QACjD,CAAC;QAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;CACF;AAED,MAAM,UAAU,wBAAwB,CAAC,MAIxC;IACC,MAAM,OAAO,GAAiB;QAC5B,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,GAAG,CAAC,MAAM,CAAC,YAAY,KAAK,SAAS,IAAI,EAAE,YAAY,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC;QAC/E,GAAG,CAAC,MAAM,CAAC,YAAY,KAAK,SAAS,IAAI,EAAE,YAAY,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC;KAChF,CAAC;IAEF,OAAO,kBAAkB,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;AACnD,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"name": "@iflow-mcp/xexr_mcp-libsql", "version": "1.1.0", "description": "MCP server for libSQL database operations", "type": "module", "engines": {"node": ">=20.0.0"}, "main": "dist/index.js", "bin": {"iflow-mcp-xexr-mcp-libsql": "dist/index.js"}, "files": ["dist/**/*", "README.md", "LICENSE"], "scripts": {"build": "tsc && chmod 755 dist/index.js", "dev": "nodemon --exec \"tsx src/index.ts --dev\"", "start": "node dist/index.js", "test": "vitest run", "test:watch": "vitest --watch", "test:coverage": "vitest --coverage", "typecheck": "tsc --noEmit", "lint": "eslint src/**/*.ts", "lint:fix": "eslint src/**/*.ts --fix", "format": "prettier --write src/**/*.ts", "format:check": "prettier --check src/**/*.ts", "prepack": "tsc && chmod 755 dist/index.js", "prepublishOnly": "pnpm test && pnpm typecheck", "release:patch": "npm version patch && git push --follow-tags", "release:minor": "npm version minor && git push --follow-tags", "release:major": "npm version major && git push --follow-tags"}, "keywords": ["mcp", "libsql", "database", "sql", "ai", "model-context-protocol"], "author": "xexr", "license": "MIT", "repository": {"type": "git", "url": "https://github.com/Xexr/mcp-libsql.git"}, "homepage": "https://github.com/Xexr/mcp-libsql", "bugs": {"url": "https://github.com/Xexr/mcp-libsql/issues"}, "publishConfig": {"access": "public"}, "dependencies": {"@libsql/client": "^0.15.7", "@modelcontextprotocol/sdk": "^1.12.0", "zod": "^3.25.32"}, "devDependencies": {"@eslint/js": "^9.27.0", "@types/node": "^22.15.23", "@typescript-eslint/eslint-plugin": "^8.33.0", "@vitest/coverage-v8": "^3.1.4", "eslint": "^9.27.0", "nodemon": "^3.1.10", "prettier": "^3.5.3", "tsx": "^4.19.4", "typescript": "^5.8.3", "vitest": "^3.1.4"}}
|