@pilat/mcp-datalink 1.0.1

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 (95) hide show
  1. package/README.md +442 -0
  2. package/databases.example.json +18 -0
  3. package/dist/__integration__/global-setup.d.ts +8 -0
  4. package/dist/__integration__/global-setup.d.ts.map +1 -0
  5. package/dist/__integration__/global-setup.js +34 -0
  6. package/dist/__integration__/global-setup.js.map +1 -0
  7. package/dist/__integration__/global-teardown.d.ts +8 -0
  8. package/dist/__integration__/global-teardown.d.ts.map +1 -0
  9. package/dist/__integration__/global-teardown.js +17 -0
  10. package/dist/__integration__/global-teardown.js.map +1 -0
  11. package/dist/__integration__/helpers.d.ts +58 -0
  12. package/dist/__integration__/helpers.d.ts.map +1 -0
  13. package/dist/__integration__/helpers.js +568 -0
  14. package/dist/__integration__/helpers.js.map +1 -0
  15. package/dist/__integration__/setup.d.ts +79 -0
  16. package/dist/__integration__/setup.d.ts.map +1 -0
  17. package/dist/__integration__/setup.js +230 -0
  18. package/dist/__integration__/setup.js.map +1 -0
  19. package/dist/adapters/factory.d.ts +40 -0
  20. package/dist/adapters/factory.d.ts.map +1 -0
  21. package/dist/adapters/factory.js +114 -0
  22. package/dist/adapters/factory.js.map +1 -0
  23. package/dist/adapters/index.d.ts +31 -0
  24. package/dist/adapters/index.d.ts.map +1 -0
  25. package/dist/adapters/index.js +34 -0
  26. package/dist/adapters/index.js.map +1 -0
  27. package/dist/adapters/mysql/adapter.d.ts +61 -0
  28. package/dist/adapters/mysql/adapter.d.ts.map +1 -0
  29. package/dist/adapters/mysql/adapter.js +567 -0
  30. package/dist/adapters/mysql/adapter.js.map +1 -0
  31. package/dist/adapters/postgresql/adapter.d.ts +52 -0
  32. package/dist/adapters/postgresql/adapter.d.ts.map +1 -0
  33. package/dist/adapters/postgresql/adapter.js +429 -0
  34. package/dist/adapters/postgresql/adapter.js.map +1 -0
  35. package/dist/adapters/sqlite/adapter.d.ts +56 -0
  36. package/dist/adapters/sqlite/adapter.d.ts.map +1 -0
  37. package/dist/adapters/sqlite/adapter.js +582 -0
  38. package/dist/adapters/sqlite/adapter.js.map +1 -0
  39. package/dist/adapters/types.d.ts +155 -0
  40. package/dist/adapters/types.d.ts.map +1 -0
  41. package/dist/adapters/types.js +7 -0
  42. package/dist/adapters/types.js.map +1 -0
  43. package/dist/config/loader.d.ts +11 -0
  44. package/dist/config/loader.d.ts.map +1 -0
  45. package/dist/config/loader.js +127 -0
  46. package/dist/config/loader.js.map +1 -0
  47. package/dist/index.d.ts +8 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +38 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/server.d.ts +21 -0
  52. package/dist/server.d.ts.map +1 -0
  53. package/dist/server.js +191 -0
  54. package/dist/server.js.map +1 -0
  55. package/dist/tools/describe-table.d.ts +11 -0
  56. package/dist/tools/describe-table.d.ts.map +1 -0
  57. package/dist/tools/describe-table.js +23 -0
  58. package/dist/tools/describe-table.js.map +1 -0
  59. package/dist/tools/execute.d.ts +22 -0
  60. package/dist/tools/execute.d.ts.map +1 -0
  61. package/dist/tools/execute.js +48 -0
  62. package/dist/tools/execute.js.map +1 -0
  63. package/dist/tools/explain.d.ts +25 -0
  64. package/dist/tools/explain.d.ts.map +1 -0
  65. package/dist/tools/explain.js +81 -0
  66. package/dist/tools/explain.js.map +1 -0
  67. package/dist/tools/list-databases.d.ts +18 -0
  68. package/dist/tools/list-databases.d.ts.map +1 -0
  69. package/dist/tools/list-databases.js +17 -0
  70. package/dist/tools/list-databases.js.map +1 -0
  71. package/dist/tools/list-tables.d.ts +22 -0
  72. package/dist/tools/list-tables.d.ts.map +1 -0
  73. package/dist/tools/list-tables.js +43 -0
  74. package/dist/tools/list-tables.js.map +1 -0
  75. package/dist/tools/query.d.ts +25 -0
  76. package/dist/tools/query.d.ts.map +1 -0
  77. package/dist/tools/query.js +109 -0
  78. package/dist/tools/query.js.map +1 -0
  79. package/dist/types.d.ts +93 -0
  80. package/dist/types.d.ts.map +1 -0
  81. package/dist/types.js +5 -0
  82. package/dist/types.js.map +1 -0
  83. package/dist/utils/errors.d.ts +22 -0
  84. package/dist/utils/errors.d.ts.map +1 -0
  85. package/dist/utils/errors.js +41 -0
  86. package/dist/utils/errors.js.map +1 -0
  87. package/dist/utils/formatter.d.ts +13 -0
  88. package/dist/utils/formatter.d.ts.map +1 -0
  89. package/dist/utils/formatter.js +56 -0
  90. package/dist/utils/formatter.js.map +1 -0
  91. package/dist/utils/truncate.d.ts +37 -0
  92. package/dist/utils/truncate.d.ts.map +1 -0
  93. package/dist/utils/truncate.js +91 -0
  94. package/dist/utils/truncate.js.map +1 -0
  95. package/package.json +65 -0
@@ -0,0 +1,155 @@
1
+ /**
2
+ * Database Adapter Interfaces
3
+ *
4
+ * Core abstractions for multi-database support.
5
+ */
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
+ */
11
+ export interface RawQueryResult {
12
+ /** Column metadata */
13
+ fields: Array<{
14
+ name: string;
15
+ }>;
16
+ /** Row data as arrays (positional, not named) */
17
+ rows: unknown[][];
18
+ /** Number of rows returned or affected */
19
+ rowCount: number;
20
+ }
21
+ /**
22
+ * Database adapter interface - implemented by each database driver
23
+ *
24
+ * Combines connection management with SQL dialect operations.
25
+ */
26
+ export interface DatabaseAdapter {
27
+ /** Unique identifier for this adapter type */
28
+ 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
+ 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
+ */
41
+ getDefaultSchema(): string;
42
+ /**
43
+ * Clean up any resources (called on server shutdown)
44
+ */
45
+ 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
+ */
56
+ 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
+ */
66
+ 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
+ */
74
+ 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
+ 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
+ */
95
+ convertPlaceholders(sql: string): string;
96
+ }
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
+ */
103
+ 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
+ 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
+ */
119
+ 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
+ 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
+ describeTable(table: string, schema: string, limits: {
135
+ maxColumns: number;
136
+ maxIndexes: number;
137
+ }): Promise<TableDescription>;
138
+ }
139
+ /**
140
+ * Internal result from listTables before tool formatting
141
+ */
142
+ export interface ListTablesInternalResult {
143
+ tables: TableInfo[];
144
+ totalAvailable: number;
145
+ }
146
+ /**
147
+ * Configuration passed to adapter constructors
148
+ */
149
+ export interface AdapterConfig {
150
+ /** Database configuration (url, readonly, etc.) */
151
+ database: DatabaseConfig;
152
+ /** Default settings (timeout, limits) */
153
+ defaults: DefaultsConfig;
154
+ }
155
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Database Adapter Interfaces
3
+ *
4
+ * Core abstractions for multi-database support.
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/adapters/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -0,0 +1,11 @@
1
+ import type { Config } from '../types.js';
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
9
+ */
10
+ export declare function loadConfig(cliConfigPath?: string): Promise<Config>;
11
+ //# sourceMappingURL=loader.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,127 @@
1
+ import { readFile } from 'fs/promises';
2
+ import { homedir } from 'os';
3
+ import { resolve, join } from 'path';
4
+ import { DbMcpError, ErrorCode } from '../utils/errors.js';
5
+ const DEFAULT_CONFIG = {
6
+ maxRows: 100,
7
+ maxCellLength: 500,
8
+ maxTotalSize: 65536, // 64KB
9
+ maxColumns: 50,
10
+ maxTables: 200,
11
+ maxIndexes: 20,
12
+ timeout: 30000,
13
+ };
14
+ /**
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.
44
+ */
45
+ function getDatabasesFromEnv() {
46
+ const databases = {};
47
+ const pattern = /^DB_MCP_([A-Z0-9_]+)_URL$/;
48
+ for (const [key, value] of Object.entries(process.env)) {
49
+ const match = key.match(pattern);
50
+ if (match && value) {
51
+ const name = match[1].toLowerCase();
52
+ databases[name] = {
53
+ url: value,
54
+ readonly: false,
55
+ };
56
+ }
57
+ }
58
+ return databases;
59
+ }
60
+ /**
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
67
+ */
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
117
+ 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.');
119
+ }
120
+ // Merge defaults
121
+ const defaults = {
122
+ ...DEFAULT_CONFIG,
123
+ ...rawConfig?.defaults,
124
+ };
125
+ return { databases, defaults };
126
+ }
127
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Entry point for mcp-datalink server
4
+ *
5
+ * Parses CLI arguments and starts the MCP server.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;GAIG"}
package/dist/index.js ADDED
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Entry point for mcp-datalink server
4
+ *
5
+ * Parses CLI arguments and starts the MCP server.
6
+ */
7
+ import { parseArgs } from 'node:util';
8
+ import { loadConfig } from './config/loader.js';
9
+ import { runServer } from './server.js';
10
+ async function main() {
11
+ const { values } = parseArgs({
12
+ options: {
13
+ config: { type: 'string', short: 'c' },
14
+ help: { type: 'boolean', short: 'h' },
15
+ },
16
+ });
17
+ if (values.help) {
18
+ console.log(`
19
+ mcp-datalink - MCP server for secure database access
20
+
21
+ Usage: mcp-datalink [options]
22
+
23
+ Options:
24
+ -c, --config <path> Path to config file (default: databases.json)
25
+ -h, --help Show this help message
26
+
27
+ Supported databases: PostgreSQL (MySQL, SQLite coming soon)
28
+ `);
29
+ process.exit(0);
30
+ }
31
+ const config = await loadConfig(values.config);
32
+ await runServer(config);
33
+ }
34
+ main().catch((error) => {
35
+ console.error('Fatal error:', error.message);
36
+ process.exit(1);
37
+ });
38
+ //# sourceMappingURL=index.js.map
@@ -0,0 +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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * MCP Server setup for db-mcp
3
+ *
4
+ * Creates and configures the MCP server with all database tools.
5
+ */
6
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
7
+ import type { Config } from './types.js';
8
+ /**
9
+ * Creates an MCP server configured with all db-mcp tools.
10
+ *
11
+ * @param config - Application configuration with database connections and defaults
12
+ * @returns Configured MCP Server instance
13
+ */
14
+ export declare function createServer(config: Config): Server;
15
+ /**
16
+ * Starts the MCP server with stdio transport.
17
+ *
18
+ * @param config - Application configuration
19
+ */
20
+ export declare function runServer(config: Config): Promise<void>;
21
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +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"}
package/dist/server.js ADDED
@@ -0,0 +1,191 @@
1
+ /**
2
+ * MCP Server setup for db-mcp
3
+ *
4
+ * Creates and configures the MCP server with all database tools.
5
+ */
6
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
7
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
8
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
9
+ import { listDatabases } from './tools/list-databases.js';
10
+ import { listTables } from './tools/list-tables.js';
11
+ import { describeTable } from './tools/describe-table.js';
12
+ import { query, formatQueryResultAsMarkdown } from './tools/query.js';
13
+ import { execute } from './tools/execute.js';
14
+ import { explain } from './tools/explain.js';
15
+ import { DbMcpError } from './utils/errors.js';
16
+ /**
17
+ * Creates an MCP server configured with all db-mcp tools.
18
+ *
19
+ * @param config - Application configuration with database connections and defaults
20
+ * @returns Configured MCP Server instance
21
+ */
22
+ export function createServer(config) {
23
+ const server = new Server({
24
+ name: 'mcp-datalink',
25
+ version: '1.0.0',
26
+ }, {
27
+ capabilities: {
28
+ tools: {},
29
+ },
30
+ });
31
+ // Register list tools handler
32
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
33
+ tools: [
34
+ {
35
+ name: 'list_databases',
36
+ description: 'List all configured database connections',
37
+ inputSchema: {
38
+ type: 'object',
39
+ properties: {},
40
+ required: [],
41
+ },
42
+ },
43
+ {
44
+ name: 'list_tables',
45
+ description: 'List tables in a database schema',
46
+ inputSchema: {
47
+ type: 'object',
48
+ properties: {
49
+ database: { type: 'string', description: 'Database connection name' },
50
+ schema: { type: 'string', description: 'Schema name (default: public)' },
51
+ },
52
+ required: ['database'],
53
+ },
54
+ },
55
+ {
56
+ name: 'describe_table',
57
+ description: 'Get table structure including columns, indexes, and foreign keys',
58
+ inputSchema: {
59
+ type: 'object',
60
+ properties: {
61
+ database: { type: 'string', description: 'Database connection name' },
62
+ table: { type: 'string', description: 'Table name' },
63
+ schema: { type: 'string', description: 'Schema name (default: public)' },
64
+ },
65
+ required: ['database', 'table'],
66
+ },
67
+ },
68
+ {
69
+ name: 'query',
70
+ description: 'Execute a read-only SELECT query. Use $1, $2, ... placeholders for parameters.',
71
+ inputSchema: {
72
+ type: 'object',
73
+ properties: {
74
+ database: { type: 'string', description: 'Database connection name' },
75
+ sql: { type: 'string', description: 'SQL SELECT query. Use $1, $2, ... for parameter placeholders' },
76
+ params: { type: 'array', description: 'Parameter values in order ($1, $2, ...). Always use params instead of interpolating values into SQL.' },
77
+ },
78
+ required: ['database', 'sql'],
79
+ },
80
+ },
81
+ {
82
+ name: 'execute',
83
+ description: 'Execute INSERT/UPDATE/DELETE query. Use $1, $2, ... placeholders for parameters.',
84
+ inputSchema: {
85
+ type: 'object',
86
+ properties: {
87
+ database: { type: 'string', description: 'Database connection name' },
88
+ sql: { type: 'string', description: 'SQL INSERT/UPDATE/DELETE query. Use $1, $2, ... for parameter placeholders' },
89
+ params: { type: 'array', description: 'Parameter values in order ($1, $2, ...). Always use params instead of interpolating values into SQL.' },
90
+ },
91
+ required: ['database', 'sql'],
92
+ },
93
+ },
94
+ {
95
+ name: 'explain',
96
+ description: 'Show query execution plan',
97
+ inputSchema: {
98
+ type: 'object',
99
+ properties: {
100
+ database: { type: 'string', description: 'Database connection name' },
101
+ sql: { type: 'string', description: 'SQL query to explain' },
102
+ analyze: { type: 'boolean', description: 'Run EXPLAIN ANALYZE (default: false)' },
103
+ },
104
+ required: ['database', 'sql'],
105
+ },
106
+ },
107
+ ],
108
+ }));
109
+ // Register call tool handler
110
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
111
+ const { name, arguments: args } = request.params;
112
+ try {
113
+ switch (name) {
114
+ case 'list_databases':
115
+ return {
116
+ content: [{ type: 'text', text: JSON.stringify(listDatabases(config), null, 2) }],
117
+ };
118
+ case 'list_tables':
119
+ return {
120
+ content: [
121
+ {
122
+ type: 'text',
123
+ text: JSON.stringify(await listTables(args, config), null, 2),
124
+ },
125
+ ],
126
+ };
127
+ case 'describe_table':
128
+ return {
129
+ content: [
130
+ {
131
+ type: 'text',
132
+ text: JSON.stringify(await describeTable(args, config), null, 2),
133
+ },
134
+ ],
135
+ };
136
+ case 'query': {
137
+ const result = await query(args, config);
138
+ return {
139
+ content: [
140
+ {
141
+ type: 'text',
142
+ text: formatQueryResultAsMarkdown(result),
143
+ },
144
+ ],
145
+ };
146
+ }
147
+ case 'execute':
148
+ return {
149
+ content: [
150
+ {
151
+ type: 'text',
152
+ text: JSON.stringify(await execute(args, config), null, 2),
153
+ },
154
+ ],
155
+ };
156
+ case 'explain':
157
+ return {
158
+ content: [
159
+ {
160
+ type: 'text',
161
+ text: JSON.stringify(await explain(args, config), null, 2),
162
+ },
163
+ ],
164
+ };
165
+ default:
166
+ throw new Error(`Unknown tool: ${name}`);
167
+ }
168
+ }
169
+ catch (error) {
170
+ if (error instanceof DbMcpError) {
171
+ return {
172
+ content: [{ type: 'text', text: JSON.stringify(error.toJSON(), null, 2) }],
173
+ isError: true,
174
+ };
175
+ }
176
+ throw error;
177
+ }
178
+ });
179
+ return server;
180
+ }
181
+ /**
182
+ * Starts the MCP server with stdio transport.
183
+ *
184
+ * @param config - Application configuration
185
+ */
186
+ export async function runServer(config) {
187
+ const server = createServer(config);
188
+ const transport = new StdioServerTransport();
189
+ await server.connect(transport);
190
+ }
191
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * describe_table tool - Returns table structure including columns, indexes, and foreign keys
3
+ */
4
+ import type { Config, TableDescription } from '../types.js';
5
+ export interface DescribeTableParams {
6
+ database: string;
7
+ table: string;
8
+ schema?: string;
9
+ }
10
+ export declare function describeTable(params: DescribeTableParams, config: Config): Promise<TableDescription>;
11
+ //# sourceMappingURL=describe-table.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"describe-table.d.ts","sourceRoot":"","sources":["../../src/tools/describe-table.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAI5D,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,aAAa,CACjC,MAAM,EAAE,mBAAmB,EAC3B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,gBAAgB,CAAC,CAwB3B"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * describe_table tool - Returns table structure including columns, indexes, and foreign keys
3
+ */
4
+ import { createAdapter } from '../adapters/index.js';
5
+ import { DbMcpError, ErrorCode } from '../utils/errors.js';
6
+ export async function describeTable(params, config) {
7
+ const { table, database } = params;
8
+ const { maxColumns, maxIndexes } = config.defaults;
9
+ // Get database config
10
+ const dbConfig = config.databases[database];
11
+ if (!dbConfig) {
12
+ throw new DbMcpError(ErrorCode.DATABASE_NOT_FOUND, `Database "${database}" not found in configuration`, { database, available: Object.keys(config.databases) });
13
+ }
14
+ // Create adapter for this database
15
+ const adapter = createAdapter(dbConfig, config.defaults);
16
+ // Use provided schema or adapter's default schema
17
+ // PostgreSQL: "public", MySQL: database name, SQLite: "main"
18
+ const schema = params.schema ?? adapter.getDefaultSchema();
19
+ return adapter.withConnection(async (conn) => {
20
+ return conn.describeTable(table, schema, { maxColumns, maxIndexes });
21
+ });
22
+ }
23
+ //# sourceMappingURL=describe-table.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"describe-table.js","sourceRoot":"","sources":["../../src/tools/describe-table.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAQ3D,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAA2B,EAC3B,MAAc;IAEd,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC;IACnC,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC;IAEnD,sBAAsB;IACtB,MAAM,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IAC5C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,UAAU,CAClB,SAAS,CAAC,kBAAkB,EAC5B,aAAa,QAAQ,8BAA8B,EACnD,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CACvD,CAAC;IACJ,CAAC;IAED,mCAAmC;IACnC,MAAM,OAAO,GAAG,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;IAEzD,kDAAkD;IAClD,6DAA6D;IAC7D,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAE3D,OAAO,OAAO,CAAC,cAAc,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QAC3C,OAAO,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;AACL,CAAC"}