@pilat/mcp-datalink 1.0.3 → 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.
Files changed (82) hide show
  1. package/README.md +30 -387
  2. package/dist/adapters/factory.d.ts +0 -4
  3. package/dist/adapters/factory.d.ts.map +1 -1
  4. package/dist/adapters/factory.js +3 -8
  5. package/dist/adapters/factory.js.map +1 -1
  6. package/dist/adapters/mysql/adapter.d.ts +2 -31
  7. package/dist/adapters/mysql/adapter.d.ts.map +1 -1
  8. package/dist/adapters/mysql/adapter.js +27 -283
  9. package/dist/adapters/mysql/adapter.js.map +1 -1
  10. package/dist/adapters/postgresql/adapter.d.ts +2 -22
  11. package/dist/adapters/postgresql/adapter.d.ts.map +1 -1
  12. package/dist/adapters/postgresql/adapter.js +18 -175
  13. package/dist/adapters/postgresql/adapter.js.map +1 -1
  14. package/dist/adapters/sqlite/adapter.d.ts +3 -25
  15. package/dist/adapters/sqlite/adapter.d.ts.map +1 -1
  16. package/dist/adapters/sqlite/adapter.js +65 -364
  17. package/dist/adapters/sqlite/adapter.js.map +1 -1
  18. package/dist/adapters/sqlite/pragma-check.d.ts +19 -0
  19. package/dist/adapters/sqlite/pragma-check.d.ts.map +1 -0
  20. package/dist/adapters/sqlite/pragma-check.js +25 -0
  21. package/dist/adapters/sqlite/pragma-check.js.map +1 -0
  22. package/dist/adapters/sqlite/url-parser.d.ts +34 -0
  23. package/dist/adapters/sqlite/url-parser.d.ts.map +1 -0
  24. package/dist/adapters/sqlite/url-parser.js +73 -0
  25. package/dist/adapters/sqlite/url-parser.js.map +1 -0
  26. package/dist/adapters/types.d.ts +10 -113
  27. package/dist/adapters/types.d.ts.map +1 -1
  28. package/dist/config/loader.d.ts +10 -7
  29. package/dist/config/loader.d.ts.map +1 -1
  30. package/dist/config/loader.js +20 -97
  31. package/dist/config/loader.js.map +1 -1
  32. package/dist/index.d.ts +0 -2
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +10 -9
  35. package/dist/index.js.map +1 -1
  36. package/dist/server.d.ts.map +1 -1
  37. package/dist/server.js +113 -40
  38. package/dist/server.js.map +1 -1
  39. package/dist/tools/describe-table.d.ts +5 -6
  40. package/dist/tools/describe-table.d.ts.map +1 -1
  41. package/dist/tools/describe-table.js +65 -9
  42. package/dist/tools/describe-table.js.map +1 -1
  43. package/dist/tools/execute.d.ts +5 -6
  44. package/dist/tools/execute.d.ts.map +1 -1
  45. package/dist/tools/execute.js +13 -11
  46. package/dist/tools/execute.js.map +1 -1
  47. package/dist/tools/explain.d.ts +5 -10
  48. package/dist/tools/explain.d.ts.map +1 -1
  49. package/dist/tools/explain.js +25 -26
  50. package/dist/tools/explain.js.map +1 -1
  51. package/dist/tools/list-databases.d.ts +5 -7
  52. package/dist/tools/list-databases.d.ts.map +1 -1
  53. package/dist/tools/list-databases.js +31 -0
  54. package/dist/tools/list-databases.js.map +1 -1
  55. package/dist/tools/list-tables.d.ts +5 -10
  56. package/dist/tools/list-tables.d.ts.map +1 -1
  57. package/dist/tools/list-tables.js +27 -9
  58. package/dist/tools/list-tables.js.map +1 -1
  59. package/dist/tools/query.d.ts +1 -6
  60. package/dist/tools/query.d.ts.map +1 -1
  61. package/dist/tools/query.js +7 -27
  62. package/dist/tools/query.js.map +1 -1
  63. package/dist/types.d.ts +39 -12
  64. package/dist/types.d.ts.map +1 -1
  65. package/dist/utils/formatter.d.ts +7 -4
  66. package/dist/utils/formatter.d.ts.map +1 -1
  67. package/dist/utils/formatter.js +20 -10
  68. package/dist/utils/formatter.js.map +1 -1
  69. package/dist/utils/sql-parser.d.ts +51 -0
  70. package/dist/utils/sql-parser.d.ts.map +1 -0
  71. package/dist/utils/sql-parser.js +310 -0
  72. package/dist/utils/sql-parser.js.map +1 -0
  73. package/dist/utils/truncate.d.ts +4 -13
  74. package/dist/utils/truncate.d.ts.map +1 -1
  75. package/dist/utils/truncate.js +38 -18
  76. package/dist/utils/truncate.js.map +1 -1
  77. package/dist/utils/validation.d.ts +35 -0
  78. package/dist/utils/validation.d.ts.map +1 -0
  79. package/dist/utils/validation.js +89 -0
  80. package/dist/utils/validation.js.map +1 -0
  81. package/package.json +11 -13
  82. package/databases.example.json +0 -18
@@ -0,0 +1,34 @@
1
+ /**
2
+ * SQLite URL and Path Parsing Utilities
3
+ *
4
+ * Handles parsing of SQLite connection URLs and path validation/resolution.
5
+ */
6
+ /**
7
+ * Parse SQLite URL to extract file path
8
+ *
9
+ * Supported formats:
10
+ * - sqlite:///absolute/path.db
11
+ * - sqlite://./relative/path.db
12
+ * - sqlite://:memory:
13
+ * - /absolute/path.db (plain file path)
14
+ * - ./relative/path.db (plain file path)
15
+ *
16
+ * @param url - SQLite connection URL or file path
17
+ * @returns Resolved absolute file path or :memory:
18
+ */
19
+ export declare function parseSqliteUrl(url: string): string;
20
+ /**
21
+ * Validate and resolve SQLite database path
22
+ *
23
+ * SECURITY: Prevents path traversal attacks by:
24
+ * 1. Resolving to absolute path
25
+ * 2. Ensuring path doesn't contain suspicious patterns
26
+ * 3. Checking file exists (unless :memory:)
27
+ *
28
+ * @param rawPath - Raw path from config
29
+ * @param basePath - Base directory for relative paths (process.cwd())
30
+ * @returns Validated absolute path
31
+ * @throws DbMcpError if path is invalid or file not found
32
+ */
33
+ export declare function validateAndResolvePath(rawPath: string, basePath: string): string;
34
+ //# sourceMappingURL=url-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"url-parser.d.ts","sourceRoot":"","sources":["../../../src/adapters/sqlite/url-parser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAelD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAqChF"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * SQLite URL and Path Parsing Utilities
3
+ *
4
+ * Handles parsing of SQLite connection URLs and path validation/resolution.
5
+ */
6
+ import * as path from 'path';
7
+ import * as fs from 'fs';
8
+ import { DbMcpError, ErrorCode } from '../../utils/errors.js';
9
+ /**
10
+ * Parse SQLite URL to extract file path
11
+ *
12
+ * Supported formats:
13
+ * - sqlite:///absolute/path.db
14
+ * - sqlite://./relative/path.db
15
+ * - sqlite://:memory:
16
+ * - /absolute/path.db (plain file path)
17
+ * - ./relative/path.db (plain file path)
18
+ *
19
+ * @param url - SQLite connection URL or file path
20
+ * @returns Resolved absolute file path or :memory:
21
+ */
22
+ export function parseSqliteUrl(url) {
23
+ if (url.startsWith('sqlite://')) {
24
+ const pathPart = url.slice('sqlite://'.length);
25
+ // Special case: :memory:
26
+ if (pathPart === ':memory:') {
27
+ return ':memory:';
28
+ }
29
+ // Handle both absolute (/path) and relative (./path) paths
30
+ return pathPart;
31
+ }
32
+ // Plain file path (no sqlite:// prefix)
33
+ return url;
34
+ }
35
+ /**
36
+ * Validate and resolve SQLite database path
37
+ *
38
+ * SECURITY: Prevents path traversal attacks by:
39
+ * 1. Resolving to absolute path
40
+ * 2. Ensuring path doesn't contain suspicious patterns
41
+ * 3. Checking file exists (unless :memory:)
42
+ *
43
+ * @param rawPath - Raw path from config
44
+ * @param basePath - Base directory for relative paths (process.cwd())
45
+ * @returns Validated absolute path
46
+ * @throws DbMcpError if path is invalid or file not found
47
+ */
48
+ export function validateAndResolvePath(rawPath, basePath) {
49
+ // :memory: is always valid
50
+ if (rawPath === ':memory:') {
51
+ return ':memory:';
52
+ }
53
+ // Resolve to absolute path
54
+ const absolutePath = path.isAbsolute(rawPath) ? rawPath : path.resolve(basePath, rawPath);
55
+ // Normalize to remove any .. or . components
56
+ const normalizedPath = path.normalize(absolutePath);
57
+ // SECURITY: Check for path traversal attempts
58
+ // After normalization, path should not go above the base directory for relative paths
59
+ if (!path.isAbsolute(rawPath)) {
60
+ // For relative paths, ensure the resolved path is still within reasonable bounds
61
+ // This prevents sqlite://../../etc/passwd type attacks
62
+ const relativeToCwd = path.relative(basePath, normalizedPath);
63
+ if (relativeToCwd.startsWith('..')) {
64
+ throw new DbMcpError(ErrorCode.CONFIG_INVALID, 'Path traversal detected. SQLite path must not escape the working directory.', { path: rawPath, resolved: normalizedPath });
65
+ }
66
+ }
67
+ // Check file exists
68
+ if (!fs.existsSync(normalizedPath)) {
69
+ throw new DbMcpError(ErrorCode.CONNECTION_FAILED, `SQLite database file not found: ${normalizedPath}`, { path: rawPath, resolved: normalizedPath });
70
+ }
71
+ return normalizedPath;
72
+ }
73
+ //# sourceMappingURL=url-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"url-parser.js","sourceRoot":"","sources":["../../../src/adapters/sqlite/url-parser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAE9D;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,IAAI,GAAG,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAChC,MAAM,QAAQ,GAAG,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAE/C,yBAAyB;QACzB,IAAI,QAAQ,KAAK,UAAU,EAAE,CAAC;YAC5B,OAAO,UAAU,CAAC;QACpB,CAAC;QAED,2DAA2D;QAC3D,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,wCAAwC;IACxC,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,sBAAsB,CAAC,OAAe,EAAE,QAAgB;IACtE,2BAA2B;IAC3B,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;QAC3B,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,2BAA2B;IAC3B,MAAM,YAAY,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAE1F,6CAA6C;IAC7C,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IAEpD,8CAA8C;IAC9C,sFAAsF;IACtF,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9B,iFAAiF;QACjF,uDAAuD;QACvD,MAAM,aAAa,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;QAC9D,IAAI,aAAa,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACnC,MAAM,IAAI,UAAU,CAClB,SAAS,CAAC,cAAc,EACxB,6EAA6E,EAC7E,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,CAC5C,CAAC;QACJ,CAAC;IACH,CAAC;IAED,oBAAoB;IACpB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,UAAU,CAClB,SAAS,CAAC,iBAAiB,EAC3B,mCAAmC,cAAc,EAAE,EACnD,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,CAC5C,CAAC;IACJ,CAAC;IAED,OAAO,cAAc,CAAC;AACxB,CAAC"}
@@ -4,152 +4,49 @@
4
4
  * Core abstractions for multi-database support.
5
5
  */
6
6
  import type { ParsedQuery, TableInfo, TableDescription, DefaultsConfig, DatabaseConfig } from '../types.js';
7
- /**
8
- * Result from a raw query execution
9
- * Normalized format across all database drivers
10
- */
7
+ /** Normalized result format across all database drivers */
11
8
  export interface RawQueryResult {
12
- /** Column metadata */
13
9
  fields: Array<{
14
10
  name: string;
15
11
  }>;
16
- /** Row data as arrays (positional, not named) */
17
12
  rows: unknown[][];
18
- /** Number of rows returned or affected */
19
13
  rowCount: number;
20
14
  }
21
- /**
22
- * Database adapter interface - implemented by each database driver
23
- *
24
- * Combines connection management with SQL dialect operations.
25
- */
15
+ /** Implemented by each database driver */
26
16
  export interface DatabaseAdapter {
27
- /** Unique identifier for this adapter type */
28
17
  readonly type: 'postgresql' | 'mysql' | 'sqlite';
29
- /**
30
- * Execute a function with a managed connection.
31
- * Connection is created at start and destroyed at end.
32
- */
33
18
  withConnection<T>(fn: (conn: AdapterConnection) => Promise<T>): Promise<T>;
34
- /**
35
- * Get the default schema name for this database type
36
- *
37
- * PostgreSQL: "public"
38
- * MySQL: database name from connection URL
39
- * SQLite: "main"
40
- */
19
+ /** PostgreSQL: "public", MySQL: db name from URL, SQLite: "main" */
41
20
  getDefaultSchema(): string;
42
- /**
43
- * Clean up any resources (called on server shutdown)
44
- */
45
21
  dispose(): Promise<void>;
46
- /**
47
- * Parse a SQL statement and validate it
48
- *
49
- * SECURITY: This validates:
50
- * - Single statement only (no multi-statement attacks)
51
- * - No dangerous operations (DROP, TRUNCATE, etc.)
52
- *
53
- * @param sql - Raw SQL to parse
54
- * @throws DbMcpError if SQL is invalid or multi-statement
55
- */
22
+ /** Parse and validate SQL (rejects multi-statement, dangerous ops) */
56
23
  parseQuery(sql: string): ParsedQuery;
57
- /**
58
- * Inject LIMIT clause if query doesn't have one
59
- *
60
- * Used to enforce maxRows limit on SELECT queries.
61
- *
62
- * @param sql - Original SQL
63
- * @param limit - Limit value to inject
64
- * @returns Modified SQL with LIMIT, or original if already has LIMIT
65
- */
24
+ /** Add LIMIT if missing */
66
25
  injectLimit(sql: string, limit: number): string;
67
- /**
68
- * Validate that a SQL query is appropriate for a specific tool
69
- *
70
- * @param sql - The SQL query string
71
- * @param tool - Either 'query' (SELECT only) or 'execute' (INSERT/UPDATE/DELETE)
72
- * @throws DbMcpError with QUERY_BLOCKED if query type is not allowed
73
- */
26
+ /** Validate query is appropriate for tool (query=SELECT, execute=INSERT/UPDATE/DELETE) */
74
27
  validateQueryForTool(sql: string, tool: 'query' | 'execute'): void;
75
- /**
76
- * Get the EXPLAIN prefix for this dialect
77
- *
78
- * @param analyze - Whether to include ANALYZE
79
- * @returns Prefix to prepend to SQL for EXPLAIN
80
- *
81
- * PostgreSQL: "EXPLAIN " or "EXPLAIN ANALYZE "
82
- * MySQL: "EXPLAIN " or "EXPLAIN ANALYZE "
83
- * SQLite: "EXPLAIN QUERY PLAN "
84
- */
85
28
  getExplainPrefix(analyze: boolean): string;
86
- /**
87
- * Convert parameter placeholders to dialect-specific format
88
- *
89
- * PostgreSQL uses $1, $2, $3 (no conversion needed)
90
- * MySQL/SQLite use ? placeholders (convert $1 -> ?)
91
- *
92
- * @param sql - SQL with placeholders
93
- * @returns SQL with converted placeholders
94
- */
29
+ /** PostgreSQL: no-op, MySQL/SQLite: $1 -> ? */
95
30
  convertPlaceholders(sql: string): string;
96
31
  }
97
- /**
98
- * Active connection handle - passed to tool implementations
99
- *
100
- * Provides database operations during a single request lifecycle.
101
- * Connection is automatically recycled after the request completes.
102
- */
32
+ /** Active connection handle for a single request */
103
33
  export interface AdapterConnection {
104
- /**
105
- * Execute a parameterized query
106
- *
107
- * SECURITY: All user SQL MUST go through this method with parameters
108
- *
109
- * @param sql - SQL with placeholders ($1, $2 for PG; ? for MySQL/SQLite)
110
- * @param params - Parameter values (type-safe, prevents injection)
111
- */
112
34
  query(sql: string, params?: unknown[]): Promise<RawQueryResult>;
113
- /**
114
- * Execute a raw SQL statement (for SET, BEGIN, etc.)
115
- *
116
- * Only use for validated internal commands.
117
- * Never pass user-provided values through this method.
118
- */
35
+ /** For internal commands only (SET, BEGIN, COMMIT) - never user input */
119
36
  execute(sql: string): Promise<void>;
120
- /**
121
- * List tables in a schema (adapter-specific implementation)
122
- *
123
- * @param schema - Schema name (ignored for SQLite)
124
- * @param maxTables - Maximum number of tables to return
125
- */
126
37
  listTables(schema: string, maxTables: number): Promise<ListTablesInternalResult>;
127
- /**
128
- * Describe a table structure (adapter-specific implementation)
129
- *
130
- * @param table - Table name
131
- * @param schema - Schema name (ignored for SQLite)
132
- * @param limits - Limits for columns and indexes
133
- */
134
38
  describeTable(table: string, schema: string, limits: {
135
39
  maxColumns: number;
136
40
  maxIndexes: number;
137
41
  }): Promise<TableDescription>;
138
42
  }
139
- /**
140
- * Internal result from listTables before tool formatting
141
- */
142
43
  export interface ListTablesInternalResult {
143
44
  tables: TableInfo[];
45
+ truncated?: boolean;
144
46
  totalAvailable: number;
145
47
  }
146
- /**
147
- * Configuration passed to adapter constructors
148
- */
149
48
  export interface AdapterConfig {
150
- /** Database configuration (url, readonly, etc.) */
151
49
  database: DatabaseConfig;
152
- /** Default settings (timeout, limits) */
153
50
  defaults: DefaultsConfig;
154
51
  }
155
52
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/adapters/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,SAAS,EACT,gBAAgB,EAChB,cAAc,EACd,cAAc,EACf,MAAM,aAAa,CAAC;AAErB;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,sBAAsB;IACtB,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChC,iDAAiD;IACjD,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC;IAClB,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,8CAA8C;IAC9C,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,GAAG,QAAQ,CAAC;IAEjD;;;OAGG;IACH,cAAc,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAE3E;;;;;;OAMG;IACH,gBAAgB,IAAI,MAAM,CAAC;IAE3B;;OAEG;IACH,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAMzB;;;;;;;;;OASG;IACH,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAAC;IAErC;;;;;;;;OAQG;IACH,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IAEhD;;;;;;OAMG;IACH,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,SAAS,GAAG,IAAI,CAAC;IAEnE;;;;;;;;;OASG;IACH,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC;IAE3C;;;;;;;;OAQG;IACH,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CAC1C;AAED;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;;;;;OAOG;IACH,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAEhE;;;;;OAKG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEpC;;;;;OAKG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAAC;IAEjF;;;;;;OAMG;IACH,aAAa,CACX,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,MAAM,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GACjD,OAAO,CAAC,gBAAgB,CAAC,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,mDAAmD;IACnD,QAAQ,EAAE,cAAc,CAAC;IACzB,yCAAyC;IACzC,QAAQ,EAAE,cAAc,CAAC;CAC1B"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/adapters/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,SAAS,EACT,gBAAgB,EAChB,cAAc,EACd,cAAc,EACf,MAAM,aAAa,CAAC;AAErB,2DAA2D;AAC3D,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChC,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,0CAA0C;AAC1C,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,GAAG,QAAQ,CAAC;IAEjD,cAAc,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAE3E,oEAAoE;IACpE,gBAAgB,IAAI,MAAM,CAAC;IAE3B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAMzB,sEAAsE;IACtE,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAAC;IAErC,2BAA2B;IAC3B,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IAEhD,0FAA0F;IAC1F,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,SAAS,GAAG,IAAI,CAAC;IAEnE,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC;IAE3C,+CAA+C;IAC/C,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CAC1C;AAED,oDAAoD;AACpD,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAEhE,yEAAyE;IACzE,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEpC,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAAC;IAEjF,aAAa,CACX,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,MAAM,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GACjD,OAAO,CAAC,gBAAgB,CAAC,CAAC;CAC9B;AAED,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,cAAc,CAAC;IACzB,QAAQ,EAAE,cAAc,CAAC;CAC1B"}
@@ -1,11 +1,14 @@
1
1
  import type { Config } from '../types.js';
2
2
  /**
3
- * Load configuration with resolution priority:
4
- * 1. CLI argument: --config ./path/to/config.json
5
- * 2. Environment variable: DB_MCP_CONFIG
6
- * 3. Current directory: ./databases.json
7
- * 4. Home directory: ~/.config/db-mcp/databases.json
8
- * 5. ENV-only mode: DB_MCP_{NAME}_URL variables
3
+ * Load configuration from environment variables.
4
+ *
5
+ * Environment variables:
6
+ * DATALINK_{NAME}_URL - Database connection URL (required)
7
+ * DATALINK_{NAME}_READONLY - Set to "true" for read-only mode (optional)
8
+ *
9
+ * Example:
10
+ * DATALINK_PROD_URL=postgresql://user:pass@host:5432/db
11
+ * DATALINK_PROD_READONLY=true
9
12
  */
10
- export declare function loadConfig(cliConfigPath?: string): Promise<Config>;
13
+ export declare function loadConfig(): Config;
11
14
  //# sourceMappingURL=loader.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAA6C,MAAM,aAAa,CAAC;AAqErF;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA8ExE"}
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAkC,MAAM,aAAa,CAAC;AAuC1E;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAWnC"}
@@ -1,6 +1,3 @@
1
- import { readFile } from 'fs/promises';
2
- import { homedir } from 'os';
3
- import { resolve, join } from 'path';
4
1
  import { DbMcpError, ErrorCode } from '../utils/errors.js';
5
2
  const DEFAULT_CONFIG = {
6
3
  maxRows: 100,
@@ -12,116 +9,42 @@ const DEFAULT_CONFIG = {
12
9
  timeout: 30000,
13
10
  };
14
11
  /**
15
- * Try to read and parse a JSON config file.
16
- * Returns null if file doesn't exist.
17
- */
18
- async function tryReadConfigFile(path) {
19
- try {
20
- const content = await readFile(path, 'utf-8');
21
- return JSON.parse(content);
22
- }
23
- catch (err) {
24
- if (err.code === 'ENOENT') {
25
- return null;
26
- }
27
- throw new DbMcpError(ErrorCode.CONFIG_INVALID, `Failed to parse config file ${path}: ${err.message}`);
28
- }
29
- }
30
- /**
31
- * Resolve ${ENV_VAR} placeholders in a string.
32
- */
33
- function resolveEnvPlaceholders(value) {
34
- return value.replace(/\$\{([^}]+)\}/g, (_, envVar) => {
35
- const envValue = process.env[envVar];
36
- if (envValue === undefined) {
37
- throw new DbMcpError(ErrorCode.CONFIG_INVALID, `Environment variable ${envVar} is not defined`);
38
- }
39
- return envValue;
40
- });
41
- }
42
- /**
43
- * Extract databases from DB_MCP_{NAME}_URL environment variables.
12
+ * Extract databases from DATALINK_{NAME}_URL environment variables.
13
+ * Also supports DATALINK_{NAME}_READONLY=true for read-only mode.
44
14
  */
45
15
  function getDatabasesFromEnv() {
46
16
  const databases = {};
47
- const pattern = /^DB_MCP_([A-Z0-9_]+)_URL$/;
17
+ const urlPattern = /^DATALINK_([A-Z0-9_]+)_URL$/;
48
18
  for (const [key, value] of Object.entries(process.env)) {
49
- const match = key.match(pattern);
19
+ const match = key.match(urlPattern);
50
20
  if (match && value) {
51
21
  const name = match[1].toLowerCase();
22
+ const readonlyKey = `DATALINK_${match[1]}_READONLY`;
23
+ const readonlyValue = process.env[readonlyKey];
52
24
  databases[name] = {
53
25
  url: value,
54
- readonly: false,
26
+ readonly: readonlyValue === 'true' || readonlyValue === '1',
55
27
  };
56
28
  }
57
29
  }
58
30
  return databases;
59
31
  }
60
32
  /**
61
- * Load configuration with resolution priority:
62
- * 1. CLI argument: --config ./path/to/config.json
63
- * 2. Environment variable: DB_MCP_CONFIG
64
- * 3. Current directory: ./databases.json
65
- * 4. Home directory: ~/.config/db-mcp/databases.json
66
- * 5. ENV-only mode: DB_MCP_{NAME}_URL variables
33
+ * Load configuration from environment variables.
34
+ *
35
+ * Environment variables:
36
+ * DATALINK_{NAME}_URL - Database connection URL (required)
37
+ * DATALINK_{NAME}_READONLY - Set to "true" for read-only mode (optional)
38
+ *
39
+ * Example:
40
+ * DATALINK_PROD_URL=postgresql://user:pass@host:5432/db
41
+ * DATALINK_PROD_READONLY=true
67
42
  */
68
- export async function loadConfig(cliConfigPath) {
69
- let rawConfig = null;
70
- // 1. CLI argument
71
- if (cliConfigPath) {
72
- const resolvedPath = resolve(cliConfigPath);
73
- rawConfig = await tryReadConfigFile(resolvedPath);
74
- if (!rawConfig) {
75
- throw new DbMcpError(ErrorCode.CONFIG_NOT_FOUND, `Config file not found: ${resolvedPath}`);
76
- }
77
- }
78
- // 2. Environment variable
79
- if (!rawConfig && process.env.DB_MCP_CONFIG) {
80
- const envPath = resolve(process.env.DB_MCP_CONFIG);
81
- rawConfig = await tryReadConfigFile(envPath);
82
- if (!rawConfig) {
83
- throw new DbMcpError(ErrorCode.CONFIG_NOT_FOUND, `Config file not found: ${envPath}`);
84
- }
85
- }
86
- // 3. Current directory
87
- if (!rawConfig) {
88
- rawConfig = await tryReadConfigFile(resolve('./databases.json'));
89
- }
90
- // 4. Home directory
91
- if (!rawConfig) {
92
- const homePath = join(homedir(), '.config', 'db-mcp', 'databases.json');
93
- rawConfig = await tryReadConfigFile(homePath);
94
- }
95
- // 5. ENV-only mode
96
- const envDatabases = getDatabasesFromEnv();
97
- // Build final config
98
- const databases = {};
99
- // Add databases from config file (with env placeholder resolution)
100
- if (rawConfig?.databases) {
101
- for (const [name, dbConfig] of Object.entries(rawConfig.databases)) {
102
- databases[name] = {
103
- url: resolveEnvPlaceholders(dbConfig.url),
104
- readonly: dbConfig.readonly ?? false,
105
- maxRows: dbConfig.maxRows,
106
- };
107
- }
108
- }
109
- // Add databases from environment (ENV-only mode)
110
- // These don't override config file databases
111
- for (const [name, dbConfig] of Object.entries(envDatabases)) {
112
- if (!(name in databases)) {
113
- databases[name] = dbConfig;
114
- }
115
- }
116
- // Validate at least one database is configured
43
+ export function loadConfig() {
44
+ const databases = getDatabasesFromEnv();
117
45
  if (Object.keys(databases).length === 0) {
118
- throw new DbMcpError(ErrorCode.CONFIG_NOT_FOUND, 'No databases configured. Provide a config file or set DB_MCP_{NAME}_URL environment variables.');
46
+ throw new DbMcpError(ErrorCode.CONFIG_NOT_FOUND, 'No databases configured. Set DATALINK_{NAME}_URL environment variables.');
119
47
  }
120
- // Merge defaults
121
- const defaults = {
122
- ...DEFAULT_CONFIG,
123
- ...rawConfig?.defaults,
124
- };
125
- return { databases, defaults };
48
+ return { databases, defaults: DEFAULT_CONFIG };
126
49
  }
127
50
  //# sourceMappingURL=loader.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE3D,MAAM,cAAc,GAAmB;IACrC,OAAO,EAAE,GAAG;IACZ,aAAa,EAAE,GAAG;IAClB,YAAY,EAAE,KAAK,EAAE,OAAO;IAC5B,UAAU,EAAE,EAAE;IACd,SAAS,EAAE,GAAG;IACd,UAAU,EAAE,EAAE;IACd,OAAO,EAAE,KAAK;CACf,CAAC;AAEF;;;GAGG;AACH,SAAS,mBAAmB;IAC1B,MAAM,SAAS,GAAmC,EAAE,CAAC;IACrD,MAAM,UAAU,GAAG,6BAA6B,CAAC;IAEjD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACvD,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACpC,IAAI,KAAK,IAAI,KAAK,EAAE,CAAC;YACnB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;YACpC,MAAM,WAAW,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC;YACpD,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;YAE/C,SAAS,CAAC,IAAI,CAAC,GAAG;gBAChB,GAAG,EAAE,KAAK;gBACV,QAAQ,EAAE,aAAa,KAAK,MAAM,IAAI,aAAa,KAAK,GAAG;aAC5D,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,UAAU;IACxB,MAAM,SAAS,GAAG,mBAAmB,EAAE,CAAC;IAExC,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxC,MAAM,IAAI,UAAU,CAClB,SAAS,CAAC,gBAAgB,EAC1B,yEAAyE,CAC1E,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC;AACjD,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,8 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
3
  * Entry point for mcp-datalink server
4
- *
5
- * Parses CLI arguments and starts the MCP server.
6
4
  */
7
5
  export {};
8
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;GAIG"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;GAEG"}
package/dist/index.js CHANGED
@@ -1,8 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
3
  * Entry point for mcp-datalink server
4
- *
5
- * Parses CLI arguments and starts the MCP server.
6
4
  */
7
5
  import { parseArgs } from 'node:util';
8
6
  import { loadConfig } from './config/loader.js';
@@ -10,7 +8,6 @@ import { runServer } from './server.js';
10
8
  async function main() {
11
9
  const { values } = parseArgs({
12
10
  options: {
13
- config: { type: 'string', short: 'c' },
14
11
  help: { type: 'boolean', short: 'h' },
15
12
  },
16
13
  });
@@ -18,17 +15,21 @@ async function main() {
18
15
  console.log(`
19
16
  mcp-datalink - MCP server for secure database access
20
17
 
21
- Usage: mcp-datalink [options]
18
+ Usage: mcp-datalink
22
19
 
23
- Options:
24
- -c, --config <path> Path to config file (default: databases.json)
25
- -h, --help Show this help message
20
+ Configuration via environment variables:
21
+ DATALINK_{NAME}_URL Database connection URL
22
+ DATALINK_{NAME}_READONLY Set to "true" for read-only mode
26
23
 
27
- Supported databases: PostgreSQL (MySQL, SQLite coming soon)
24
+ Example:
25
+ DATALINK_PROD_URL=postgresql://user:pass@host:5432/db
26
+ DATALINK_PROD_READONLY=true
27
+
28
+ Supported databases: PostgreSQL, MySQL, SQLite
28
29
  `);
29
30
  process.exit(0);
30
31
  }
31
- const config = await loadConfig(values.config);
32
+ const config = loadConfig();
32
33
  await runServer(config);
33
34
  }
34
35
  main().catch((error) => {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,KAAK,UAAU,IAAI;IACjB,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;QAC3B,OAAO,EAAE;YACP,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE;YACtC,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE;SACtC;KACF,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;CAUf,CAAC,CAAC;QACC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC/C,MAAM,SAAS,CAAC,MAAM,CAAC,CAAC;AAC1B,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAY,EAAE,EAAE;IAC5B,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,KAAK,UAAU,IAAI;IACjB,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;QAC3B,OAAO,EAAE;YACP,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE;SACtC;KACF,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;CAcf,CAAC,CAAC;QACC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,SAAS,CAAC,MAAM,CAAC,CAAC;AAC1B,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAY,EAAE,EAAE;IAC5B,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAMnE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AASzC;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAoLnD;AAED;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI7D"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAInE,OAAO,KAAK,EACV,MAAM,EAMP,MAAM,YAAY,CAAC;AAyBpB;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CA0OnD;AAED;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI7D"}