@hellocrossman/mcp-sdk 0.1.2 → 0.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 (68) hide show
  1. package/README.md +99 -28
  2. package/dist/cjs/cli.d.ts +3 -0
  3. package/dist/cjs/cli.d.ts.map +1 -0
  4. package/dist/cjs/cli.js +182 -0
  5. package/dist/cjs/cli.js.map +1 -0
  6. package/dist/cjs/db-executor.d.ts +4 -0
  7. package/dist/cjs/db-executor.d.ts.map +1 -0
  8. package/dist/cjs/db-executor.js +152 -0
  9. package/dist/cjs/db-executor.js.map +1 -0
  10. package/dist/cjs/db-introspect.d.ts +18 -0
  11. package/dist/cjs/db-introspect.d.ts.map +1 -0
  12. package/dist/cjs/db-introspect.js +145 -0
  13. package/dist/cjs/db-introspect.js.map +1 -0
  14. package/dist/cjs/db-tool-generator.d.ts +9 -0
  15. package/dist/cjs/db-tool-generator.d.ts.map +1 -0
  16. package/dist/cjs/db-tool-generator.js +167 -0
  17. package/dist/cjs/db-tool-generator.js.map +1 -0
  18. package/dist/cjs/enrichment.d.ts +13 -0
  19. package/dist/cjs/enrichment.d.ts.map +1 -0
  20. package/dist/cjs/enrichment.js +36 -0
  21. package/dist/cjs/enrichment.js.map +1 -0
  22. package/dist/cjs/index.d.ts +2 -0
  23. package/dist/cjs/index.d.ts.map +1 -1
  24. package/dist/cjs/index.js +4 -1
  25. package/dist/cjs/index.js.map +1 -1
  26. package/dist/cjs/introspect.d.ts.map +1 -1
  27. package/dist/cjs/introspect.js +10 -4
  28. package/dist/cjs/introspect.js.map +1 -1
  29. package/dist/cjs/server.d.ts +1 -0
  30. package/dist/cjs/server.d.ts.map +1 -1
  31. package/dist/cjs/server.js +113 -15
  32. package/dist/cjs/server.js.map +1 -1
  33. package/dist/cjs/types.d.ts +6 -0
  34. package/dist/cjs/types.d.ts.map +1 -1
  35. package/dist/cli.d.ts +3 -0
  36. package/dist/cli.d.ts.map +1 -0
  37. package/dist/cli.js +177 -0
  38. package/dist/cli.js.map +1 -0
  39. package/dist/db-executor.d.ts +4 -0
  40. package/dist/db-executor.d.ts.map +1 -0
  41. package/dist/db-executor.js +125 -0
  42. package/dist/db-executor.js.map +1 -0
  43. package/dist/db-introspect.d.ts +18 -0
  44. package/dist/db-introspect.d.ts.map +1 -0
  45. package/dist/db-introspect.js +118 -0
  46. package/dist/db-introspect.js.map +1 -0
  47. package/dist/db-tool-generator.d.ts +9 -0
  48. package/dist/db-tool-generator.d.ts.map +1 -0
  49. package/dist/db-tool-generator.js +163 -0
  50. package/dist/db-tool-generator.js.map +1 -0
  51. package/dist/enrichment.d.ts +13 -0
  52. package/dist/enrichment.d.ts.map +1 -0
  53. package/dist/enrichment.js +33 -0
  54. package/dist/enrichment.js.map +1 -0
  55. package/dist/index.d.ts +2 -0
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js +1 -0
  58. package/dist/index.js.map +1 -1
  59. package/dist/introspect.d.ts.map +1 -1
  60. package/dist/introspect.js +10 -4
  61. package/dist/introspect.js.map +1 -1
  62. package/dist/server.d.ts +1 -0
  63. package/dist/server.d.ts.map +1 -1
  64. package/dist/server.js +113 -15
  65. package/dist/server.js.map +1 -1
  66. package/dist/types.d.ts +6 -0
  67. package/dist/types.d.ts.map +1 -1
  68. package/package.json +13 -3
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # @hellocrossman/mcp-sdk
2
2
 
3
- Turn your Express API into an MCP server with two lines of code.
3
+ Turn your Express API into an MCP server with zero configuration.
4
4
 
5
- Your customers can access your business data and logic through AI assistants (Claude, ChatGPT, Cursor) instead of traditional UIs.
5
+ Auto-discovers your routes, database tables, and generates AI-enhanced tools so your customers can access your business data through AI assistants (Claude, ChatGPT, Cursor).
6
6
 
7
7
  ## Install
8
8
 
@@ -10,7 +10,15 @@ Your customers can access your business data and logic through AI assistants (Cl
10
10
  npm install @hellocrossman/mcp-sdk
11
11
  ```
12
12
 
13
- ## Quick Start
13
+ ## Zero-Config Setup
14
+
15
+ ```bash
16
+ npx @hellocrossman/mcp-sdk init
17
+ ```
18
+
19
+ This automatically finds your Express app file, adds the MCP setup, and you're done. Restart your app and visit `/mcp` to see your tools.
20
+
21
+ ## Manual Setup
14
22
 
15
23
  ```typescript
16
24
  import express from 'express';
@@ -21,7 +29,6 @@ const app = express();
21
29
  // Your existing routes
22
30
  app.get('/api/customers', (req, res) => { /* ... */ });
23
31
  app.post('/api/orders', (req, res) => { /* ... */ });
24
- app.get('/api/orders/:id', (req, res) => { /* ... */ });
25
32
 
26
33
  // Add MCP in one line
27
34
  createMcpServer({ app });
@@ -29,14 +36,55 @@ createMcpServer({ app });
29
36
  app.listen(3000);
30
37
  ```
31
38
 
32
- That's it. Visit `localhost:3000/mcp` to see your auto-discovered tools.
39
+ ## What Gets Discovered
40
+
41
+ The SDK automatically finds and exposes:
42
+
43
+ ### Express Routes
44
+ Every API route becomes a callable tool:
45
+
46
+ | HTTP Method | Tool Name Example | Description |
47
+ |---|---|---|
48
+ | GET | `get_customers_by_id` | Fetches a record by ID |
49
+ | POST | `create_orders` | Creates a new record |
50
+ | PUT/PATCH | `update_orders_by_id` | Updates a record |
51
+ | DELETE | `delete_orders_by_id` | Deletes a record |
33
52
 
34
- ## How It Works
53
+ ### Database Tables
54
+ If `DATABASE_URL` is in your environment (PostgreSQL), the SDK auto-discovers every table and generates tools:
35
55
 
36
- 1. **Auto-discovers your routes** -- Reads your Express router and finds all registered API routes
37
- 2. **Generates MCP tools** -- Each route becomes a tool with a name, description, and input schema
38
- 3. **Serves the MCP protocol** -- Creates a `/mcp` endpoint that speaks Streamable HTTP transport
39
- 4. **Calls your actual routes** -- When a tool is invoked, it makes an internal HTTP request to your real endpoint, so all your auth, validation, and middleware still runs
56
+ - **`list_<table>`** -- Query all records with filtering and pagination
57
+ - **`get_<table>_by_id`** -- Fetch a single record by primary key
58
+
59
+ No extra configuration needed. The SDK detects the database connection from your environment variables automatically.
60
+
61
+ ### Smart Security
62
+ Sensitive tables are **auto-hidden** by default:
63
+ - `users`, `accounts`, `sessions`, `tokens`, `passwords`, `api_keys`, `migrations`
64
+
65
+ Sensitive columns are redacted in query results:
66
+ - `password`, `password_hash`, `secret`, `api_key`, `access_token`, `credit_card`
67
+
68
+ ### AI-Enhanced Descriptions
69
+ Tool names and descriptions are automatically enriched by AI to be clear and business-oriented. Instead of `list_scans`, you get `browse_scan_history` with a description like "Retrieve all scan records to review analysis results and status."
70
+
71
+ ## Discovery Report
72
+
73
+ On startup, you'll see a clean summary in your console:
74
+
75
+ ```
76
+ [mcp-sdk] ---- Discovery Report ----
77
+ [mcp-sdk] Express routes: 4 found, 4 tools generated
78
+ [mcp-sdk] + create_scans (POST /api/scans)
79
+ [mcp-sdk] + get_scan_details (GET /api/scans/:id)
80
+ [mcp-sdk] Database: 8 tables found, 12 tools generated
81
+ [mcp-sdk] + list_roadmap_items (DB_QUERY)
82
+ [mcp-sdk] + get_feature_details (DB_QUERY)
83
+ [mcp-sdk] Auto-hidden (sensitive): users, sessions
84
+ [mcp-sdk] AI enrichment: applied
85
+ [mcp-sdk] Total tools: 16
86
+ [mcp-sdk] ----------------------------
87
+ ```
40
88
 
41
89
  ## Options
42
90
 
@@ -44,35 +92,57 @@ That's it. Visit `localhost:3000/mcp` to see your auto-discovered tools.
44
92
  createMcpServer({
45
93
  app, // Your Express app (required)
46
94
  path: '/mcp', // MCP endpoint path (default: '/mcp')
47
- name: 'my-app', // Server name shown to AI clients (default: 'mcp-server')
48
- version: '1.0.0', // Server version (default: '1.0.0')
95
+ name: 'my-app', // Server name shown to AI clients
96
+ version: '1.0.0', // Server version
49
97
  description: 'My MCP server', // Server description
50
- routePrefix: '/api', // Only expose routes starting with this (default: '/api')
51
- excludeRoutes: ['/api/admin/*'], // Hide specific routes (supports * wildcards)
98
+ routePrefix: '/api', // Only expose routes starting with this
99
+ excludeRoutes: ['/api/admin/*'], // Hide specific routes (supports wildcards)
100
+
101
+ // Database options
102
+ database: true, // Auto-detect database (default: true)
103
+ excludeTables: ['internal_logs'], // Hide specific tables
104
+ includeTables: ['products'], // Only expose these tables (overrides exclude)
105
+ includeWrites: false, // Generate create tools for tables (default: false)
106
+
107
+ // AI enrichment
108
+ enrichment: true, // Auto-enrich tool descriptions (default: true)
52
109
  });
53
110
  ```
54
111
 
55
- ## What Gets Exposed
112
+ ## Controlling What's Exposed
113
+
114
+ **Hide specific tables:**
115
+ ```typescript
116
+ createMcpServer({ app, excludeTables: ['internal_logs', 'analytics'] });
117
+ ```
118
+
119
+ **Only expose specific tables:**
120
+ ```typescript
121
+ createMcpServer({ app, includeTables: ['products', 'orders'] });
122
+ ```
123
+
124
+ **Enable write operations:**
125
+ ```typescript
126
+ createMcpServer({ app, includeWrites: true });
127
+ ```
56
128
 
57
- | HTTP Method | Tool Prefix | Example Route | Tool Name |
58
- |---|---|---|---|
59
- | GET | `get_` | `/api/customers/:id` | `get_customers_by_id` |
60
- | POST | `create_` | `/api/orders` | `create_orders` |
61
- | PUT/PATCH | `update_` | `/api/orders/:id` | `update_orders_by_id` |
62
- | DELETE | `delete_` | `/api/orders/:id` | `delete_orders_by_id` |
129
+ **Disable database discovery:**
130
+ ```typescript
131
+ createMcpServer({ app, database: false });
132
+ ```
63
133
 
64
134
  ## Security
65
135
 
66
136
  - Only routes matching `routePrefix` are exposed (default: `/api`)
67
- - Use `excludeRoutes` to hide admin or internal endpoints
68
- - Tool execution goes through your existing Express middleware stack -- auth, rate limiting, validation all still apply
69
- - No direct database access -- the SDK only calls your routes
137
+ - Sensitive tables are auto-hidden (users, sessions, tokens, migrations, etc.)
138
+ - Sensitive columns are redacted in all query results
139
+ - Database tools are read-only by default (opt-in for writes)
140
+ - Route-based tools go through your existing Express middleware (auth, rate limiting, validation)
141
+ - Use `excludeRoutes` and `excludeTables` for additional control
70
142
 
71
143
  ## Connecting AI Clients
72
144
 
73
- Once your MCP server is running, AI assistants can connect to it:
74
-
75
- **Claude Desktop** -- Add to your MCP settings:
145
+ **Claude Desktop:**
76
146
  ```json
77
147
  {
78
148
  "mcpServers": {
@@ -83,13 +153,14 @@ Once your MCP server is running, AI assistants can connect to it:
83
153
  }
84
154
  ```
85
155
 
86
- **Cursor** -- Add the MCP server URL in Cursor settings under MCP Servers.
156
+ **Cursor:** Add the MCP server URL in Cursor settings under MCP Servers.
87
157
 
88
158
  ## Requirements
89
159
 
90
160
  - Node.js >= 18
91
161
  - Express >= 4
92
162
  - Zod >= 3
163
+ - pg >= 8 (optional, for database discovery)
93
164
 
94
165
  ## License
95
166
 
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":""}
@@ -0,0 +1,182 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const IMPORT_LINE_ESM = `import { createMcpServer } from '@hellocrossman/mcp-sdk';`;
10
+ const IMPORT_LINE_CJS = `const { createMcpServer } = require('@hellocrossman/mcp-sdk');`;
11
+ const SETUP_LINE = `createMcpServer({ app });`;
12
+ const COMMON_ENTRY_FILES = [
13
+ "server/index.ts",
14
+ "server/index.js",
15
+ "src/server.ts",
16
+ "src/server.js",
17
+ "src/index.ts",
18
+ "src/index.js",
19
+ "src/app.ts",
20
+ "src/app.js",
21
+ "server.ts",
22
+ "server.js",
23
+ "index.ts",
24
+ "index.js",
25
+ "app.ts",
26
+ "app.js",
27
+ ];
28
+ const EXPRESS_PATTERNS = [
29
+ /express\(\)/,
30
+ /require\(['"]express['"]\)/,
31
+ /from\s+['"]express['"]/,
32
+ /import\s+express/,
33
+ ];
34
+ const APP_VAR_PATTERN = /(?:const|let|var)\s+(\w+)\s*=\s*express\(\)/;
35
+ const LISTEN_PATTERN = /(?:app|server|httpServer)\s*\.listen\s*\(/;
36
+ function findProjectRoot() {
37
+ let dir = process.cwd();
38
+ while (dir !== path_1.default.dirname(dir)) {
39
+ if (fs_1.default.existsSync(path_1.default.join(dir, "package.json"))) {
40
+ return dir;
41
+ }
42
+ dir = path_1.default.dirname(dir);
43
+ }
44
+ return process.cwd();
45
+ }
46
+ function findExpressEntryFile(root) {
47
+ for (const file of COMMON_ENTRY_FILES) {
48
+ const fullPath = path_1.default.join(root, file);
49
+ if (fs_1.default.existsSync(fullPath)) {
50
+ const content = fs_1.default.readFileSync(fullPath, "utf-8");
51
+ if (EXPRESS_PATTERNS.some((p) => p.test(content))) {
52
+ return fullPath;
53
+ }
54
+ }
55
+ }
56
+ const srcDirs = ["server", "src", "."];
57
+ for (const dir of srcDirs) {
58
+ const dirPath = path_1.default.join(root, dir);
59
+ if (!fs_1.default.existsSync(dirPath) || !fs_1.default.statSync(dirPath).isDirectory())
60
+ continue;
61
+ const files = fs_1.default.readdirSync(dirPath).filter((f) => /\.(ts|js|mjs)$/.test(f));
62
+ for (const file of files) {
63
+ const fullPath = path_1.default.join(dirPath, file);
64
+ const content = fs_1.default.readFileSync(fullPath, "utf-8");
65
+ if (EXPRESS_PATTERNS.some((p) => p.test(content))) {
66
+ return fullPath;
67
+ }
68
+ }
69
+ }
70
+ return null;
71
+ }
72
+ function isESM(filePath, root) {
73
+ if (filePath.endsWith(".ts") || filePath.endsWith(".mjs"))
74
+ return true;
75
+ try {
76
+ const pkg = JSON.parse(fs_1.default.readFileSync(path_1.default.join(root, "package.json"), "utf-8"));
77
+ return pkg.type === "module";
78
+ }
79
+ catch {
80
+ return false;
81
+ }
82
+ }
83
+ function alreadySetup(content) {
84
+ return (content.includes("createMcpServer") ||
85
+ content.includes("@hellocrossman/mcp-sdk") ||
86
+ content.includes("hellocrossman/mcp-sdk"));
87
+ }
88
+ function injectMcpSetup(filePath, root) {
89
+ const content = fs_1.default.readFileSync(filePath, "utf-8");
90
+ if (alreadySetup(content)) {
91
+ return { success: true, message: "MCP SDK is already set up in this file." };
92
+ }
93
+ const esm = isESM(filePath, root);
94
+ const importLine = esm ? IMPORT_LINE_ESM : IMPORT_LINE_CJS;
95
+ const appMatch = content.match(APP_VAR_PATTERN);
96
+ const appVarName = appMatch ? appMatch[1] : "app";
97
+ const setupCode = `createMcpServer({ app: ${appVarName} });`;
98
+ const lines = content.split("\n");
99
+ let lastImportIndex = -1;
100
+ for (let i = 0; i < lines.length; i++) {
101
+ if (/^import\s/.test(lines[i]) || /^const\s.*=\s*require/.test(lines[i])) {
102
+ lastImportIndex = i;
103
+ }
104
+ }
105
+ const insertImportAt = lastImportIndex + 1;
106
+ lines.splice(insertImportAt, 0, importLine);
107
+ let listenIndex = -1;
108
+ for (let i = lines.length - 1; i >= 0; i--) {
109
+ if (LISTEN_PATTERN.test(lines[i])) {
110
+ listenIndex = i;
111
+ break;
112
+ }
113
+ }
114
+ if (listenIndex >= 0) {
115
+ lines.splice(listenIndex, 0, "", `// MCP server - auto-discovered from your Express routes and database`, setupCode);
116
+ }
117
+ else {
118
+ lines.push("");
119
+ lines.push(`// MCP server - auto-discovered from your Express routes and database`);
120
+ lines.push(setupCode);
121
+ }
122
+ fs_1.default.writeFileSync(filePath, lines.join("\n"));
123
+ return {
124
+ success: true,
125
+ message: `Added MCP setup to ${path_1.default.relative(root, filePath)}`,
126
+ };
127
+ }
128
+ function main() {
129
+ const args = process.argv.slice(2);
130
+ if (args[0] !== "init") {
131
+ console.log(`
132
+ @hellocrossman/mcp-sdk CLI
133
+
134
+ Usage:
135
+ npx @hellocrossman/mcp-sdk init Auto-detect Express app and add MCP server
136
+
137
+ Options:
138
+ --file <path> Specify the Express app file manually
139
+ `);
140
+ return;
141
+ }
142
+ console.log("\n @hellocrossman/mcp-sdk\n");
143
+ console.log(" Setting up MCP server...\n");
144
+ const root = findProjectRoot();
145
+ const fileArgIndex = args.indexOf("--file");
146
+ let entryFile = null;
147
+ if (fileArgIndex >= 0 && args[fileArgIndex + 1]) {
148
+ const specified = path_1.default.resolve(root, args[fileArgIndex + 1]);
149
+ if (fs_1.default.existsSync(specified)) {
150
+ entryFile = specified;
151
+ }
152
+ else {
153
+ console.error(` Error: File not found: ${args[fileArgIndex + 1]}`);
154
+ process.exit(1);
155
+ }
156
+ }
157
+ else {
158
+ entryFile = findExpressEntryFile(root);
159
+ }
160
+ if (!entryFile) {
161
+ console.error(" Could not find an Express app file.");
162
+ console.error(" Try: npx @hellocrossman/mcp-sdk init --file server/index.ts\n");
163
+ process.exit(1);
164
+ }
165
+ console.log(` Found Express app: ${path_1.default.relative(root, entryFile)}`);
166
+ const result = injectMcpSetup(entryFile, root);
167
+ if (result.success) {
168
+ console.log(` ${result.message}`);
169
+ console.log("");
170
+ console.log(" Your MCP server will be available at /mcp when you start your app.");
171
+ console.log(" It auto-discovers Express routes and database tables.");
172
+ console.log(" Sensitive tables (users, sessions, etc.) are hidden by default.");
173
+ console.log("");
174
+ console.log(" Restart your app to see it in action.\n");
175
+ }
176
+ else {
177
+ console.error(` Error: ${result.message}\n`);
178
+ process.exit(1);
179
+ }
180
+ }
181
+ main();
182
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { DiscoveredTool } from "./types.js";
2
+ export declare function initDbPool(connectionUrl: string): Promise<void>;
3
+ export declare function executeDbTool(tool: DiscoveredTool, args: Record<string, unknown>): Promise<string>;
4
+ //# sourceMappingURL=db-executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-executor.d.ts","sourceRoot":"","sources":["../../src/db-executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAIjD,wBAAsB,UAAU,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBrE;AAED,wBAAsB,aAAa,CACjC,IAAI,EAAE,cAAc,EACpB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC,MAAM,CAAC,CAiBjB"}
@@ -0,0 +1,152 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.initDbPool = initDbPool;
27
+ exports.executeDbTool = executeDbTool;
28
+ let poolInstance = null;
29
+ async function initDbPool(connectionUrl) {
30
+ if (poolInstance)
31
+ return;
32
+ let pg;
33
+ try {
34
+ pg = await Promise.resolve().then(() => __importStar(require("pg")));
35
+ }
36
+ catch {
37
+ throw new Error("[mcp-sdk] 'pg' package required for database tools");
38
+ }
39
+ const Pool = pg.default?.Pool || pg.Pool;
40
+ poolInstance = new Pool({
41
+ connectionString: connectionUrl,
42
+ max: 5,
43
+ connectionTimeoutMillis: 5000,
44
+ idleTimeoutMillis: 30000,
45
+ });
46
+ }
47
+ async function executeDbTool(tool, args) {
48
+ if (!poolInstance) {
49
+ throw new Error("Database pool not initialized");
50
+ }
51
+ const tableName = tool.path.replace("db://", "").split("/")[0];
52
+ const safeTable = tableName.replace(/[^a-zA-Z0-9_]/g, "");
53
+ if (tool.dbOperation === "get_by_id") {
54
+ return executeGetById(safeTable, tool, args);
55
+ }
56
+ else if (tool.dbOperation === "list" || tool.method === "DB_QUERY") {
57
+ return executeList(safeTable, tool, args);
58
+ }
59
+ else if (tool.dbOperation === "insert" || tool.method === "DB_INSERT") {
60
+ return executeInsert(safeTable, tool, args);
61
+ }
62
+ throw new Error(`Unknown DB method: ${tool.method}`);
63
+ }
64
+ async function executeGetById(table, tool, args) {
65
+ const pkName = tool.params[0];
66
+ const pkValue = args[pkName];
67
+ if (pkValue === undefined || pkValue === null) {
68
+ throw new Error(`Missing required parameter: ${pkName}`);
69
+ }
70
+ const result = await poolInstance.query(`SELECT * FROM "${table}" WHERE "${pkName}" = $1 LIMIT 1`, [pkValue]);
71
+ if (result.rows.length === 0) {
72
+ return JSON.stringify({ error: "Record not found" }, null, 2);
73
+ }
74
+ return JSON.stringify(sanitizeRow(result.rows[0]), null, 2);
75
+ }
76
+ async function executeList(table, _tool, args) {
77
+ const limit = Math.min(Number(args.limit) || 50, 200);
78
+ const offset = Number(args.offset) || 0;
79
+ const conditions = [];
80
+ const values = [];
81
+ let paramIndex = 1;
82
+ for (const [key, value] of Object.entries(args)) {
83
+ if (key.startsWith("filter_") && value !== undefined && value !== null) {
84
+ const colName = key.replace("filter_", "");
85
+ const safeCol = colName.replace(/[^a-zA-Z0-9_]/g, "");
86
+ if (typeof value === "string") {
87
+ conditions.push(`"${safeCol}" ILIKE $${paramIndex}`);
88
+ values.push(`%${value}%`);
89
+ }
90
+ else {
91
+ conditions.push(`"${safeCol}" = $${paramIndex}`);
92
+ values.push(value);
93
+ }
94
+ paramIndex++;
95
+ }
96
+ }
97
+ let query = `SELECT * FROM "${table}"`;
98
+ if (conditions.length > 0) {
99
+ query += ` WHERE ${conditions.join(" AND ")}`;
100
+ }
101
+ query += ` LIMIT $${paramIndex} OFFSET $${paramIndex + 1}`;
102
+ values.push(limit, offset);
103
+ const result = await poolInstance.query(query, values);
104
+ const countQuery = conditions.length > 0
105
+ ? `SELECT COUNT(*) as total FROM "${table}" WHERE ${conditions.join(" AND ")}`
106
+ : `SELECT COUNT(*) as total FROM "${table}"`;
107
+ const countValues = conditions.length > 0 ? values.slice(0, -2) : [];
108
+ const countResult = await poolInstance.query(countQuery, countValues);
109
+ return JSON.stringify({
110
+ data: result.rows.map(sanitizeRow),
111
+ total: parseInt(countResult.rows[0].total),
112
+ limit,
113
+ offset,
114
+ }, null, 2);
115
+ }
116
+ async function executeInsert(table, _tool, args) {
117
+ const entries = Object.entries(args).filter(([_, v]) => v !== undefined && v !== null);
118
+ if (entries.length === 0) {
119
+ throw new Error("No data provided to insert");
120
+ }
121
+ const columns = entries.map(([k]) => `"${k.replace(/[^a-zA-Z0-9_]/g, "")}"`);
122
+ const placeholders = entries.map((_, i) => `$${i + 1}`);
123
+ const values = entries.map(([_, v]) => v);
124
+ const query = `INSERT INTO "${table}" (${columns.join(", ")}) VALUES (${placeholders.join(", ")}) RETURNING *`;
125
+ const result = await poolInstance.query(query, values);
126
+ return JSON.stringify(sanitizeRow(result.rows[0]), null, 2);
127
+ }
128
+ const REDACTED_FIELDS = [
129
+ "password",
130
+ "password_hash",
131
+ "hashed_password",
132
+ "secret",
133
+ "api_key",
134
+ "api_secret",
135
+ "token",
136
+ "access_token",
137
+ "refresh_token",
138
+ "private_key",
139
+ ];
140
+ function sanitizeRow(row) {
141
+ const cleaned = {};
142
+ for (const [key, value] of Object.entries(row)) {
143
+ if (REDACTED_FIELDS.includes(key.toLowerCase())) {
144
+ cleaned[key] = "[REDACTED]";
145
+ }
146
+ else {
147
+ cleaned[key] = value;
148
+ }
149
+ }
150
+ return cleaned;
151
+ }
152
+ //# sourceMappingURL=db-executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-executor.js","sourceRoot":"","sources":["../../src/db-executor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ export interface DbColumn {
2
+ name: string;
3
+ type: string;
4
+ nullable: boolean;
5
+ isPrimary: boolean;
6
+ hasDefault: boolean;
7
+ }
8
+ export interface DbTable {
9
+ name: string;
10
+ columns: DbColumn[];
11
+ }
12
+ export interface DbIntrospectionResult {
13
+ tables: DbTable[];
14
+ connectionSource: string;
15
+ }
16
+ export declare function detectDatabaseUrl(): string | null;
17
+ export declare function introspectDatabase(connectionUrl: string): Promise<DbIntrospectionResult>;
18
+ //# sourceMappingURL=db-introspect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-introspect.d.ts","sourceRoot":"","sources":["../../src/db-introspect.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,QAAQ,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,OAAO,EAAE,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAUD,wBAAgB,iBAAiB,IAAI,MAAM,GAAG,IAAI,CAkBjD;AAmCD,wBAAsB,kBAAkB,CACtC,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,qBAAqB,CAAC,CAyEhC"}