@pilat/mcp-datalink 1.0.2 → 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/README.md +21 -300
- package/dist/config/loader.d.ts +10 -7
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +20 -97
- package/dist/config/loader.js.map +1 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -9
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +82 -20
- package/dist/server.js.map +1 -1
- package/dist/types.d.ts +0 -7
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -3
- package/databases.example.json +0 -18
package/README.md
CHANGED
|
@@ -13,12 +13,10 @@
|
|
|
13
13
|
</p>
|
|
14
14
|
|
|
15
15
|
<p align="center">
|
|
16
|
-
<a href="#
|
|
16
|
+
<a href="#installation">Installation</a> |
|
|
17
17
|
<a href="#supported-databases">Databases</a> |
|
|
18
|
-
<a href="#mcp-client-configuration">Clients</a> |
|
|
19
18
|
<a href="#available-tools">Tools</a> |
|
|
20
|
-
<a href="#security">Security</a>
|
|
21
|
-
<a href="#configuration">Configuration</a>
|
|
19
|
+
<a href="#security">Security</a>
|
|
22
20
|
</p>
|
|
23
21
|
|
|
24
22
|
---
|
|
@@ -46,156 +44,38 @@ AI Assistant <--> MCP Datalink <--> Your Databases
|
|
|
46
44
|
| <img src="https://img.shields.io/badge/MySQL-4479A1?style=flat-square&logo=mysql&logoColor=white" alt="MySQL" /> | Stable | mysql2 |
|
|
47
45
|
| <img src="https://img.shields.io/badge/SQLite-003B57?style=flat-square&logo=sqlite&logoColor=white" alt="SQLite" /> | Stable | better-sqlite3 |
|
|
48
46
|
|
|
49
|
-
##
|
|
47
|
+
## Installation
|
|
50
48
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
Create `databases.json` in your project directory:
|
|
54
|
-
|
|
55
|
-
```json
|
|
56
|
-
{
|
|
57
|
-
"databases": {
|
|
58
|
-
"mydb": {
|
|
59
|
-
"url": "postgresql://user:password@localhost:5432/myapp"
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
### 2. Add to your MCP client
|
|
66
|
-
|
|
67
|
-
Add to your client's MCP configuration (see [client-specific examples](#mcp-client-configuration) below):
|
|
68
|
-
|
|
69
|
-
```json
|
|
70
|
-
{
|
|
71
|
-
"mcpServers": {
|
|
72
|
-
"datalink": {
|
|
73
|
-
"command": "npx",
|
|
74
|
-
"args": ["-y", "@pilat/mcp-datalink", "--config", "./databases.json"]
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
### 3. Start using it!
|
|
81
|
-
|
|
82
|
-
Your AI assistant now has access to 6 powerful database tools:
|
|
83
|
-
|
|
84
|
-
- `list_databases` - View all configured connections
|
|
85
|
-
- `list_tables` - Browse tables with row estimates
|
|
86
|
-
- `describe_table` - Inspect schemas, indexes, and foreign keys
|
|
87
|
-
- `query` - Execute SELECT queries safely
|
|
88
|
-
- `execute` - Run INSERT/UPDATE/DELETE with write protection
|
|
89
|
-
- `explain` - Analyze query execution plans
|
|
90
|
-
|
|
91
|
-
## MCP Client Configuration
|
|
92
|
-
|
|
93
|
-
MCP Datalink works with any MCP-compatible client. Here are setup instructions for popular tools:
|
|
94
|
-
|
|
95
|
-
<details>
|
|
96
|
-
<summary><strong>Claude Desktop</strong></summary>
|
|
97
|
-
|
|
98
|
-
Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):
|
|
49
|
+
Add to your MCP client config:
|
|
99
50
|
|
|
100
51
|
```json
|
|
101
52
|
{
|
|
102
53
|
"mcpServers": {
|
|
103
54
|
"datalink": {
|
|
104
55
|
"command": "npx",
|
|
105
|
-
"args": ["-y", "@pilat/mcp-datalink",
|
|
56
|
+
"args": ["-y", "@pilat/mcp-datalink"],
|
|
57
|
+
"env": {
|
|
58
|
+
"DATALINK_MYDB_URL": "postgresql://user:password@localhost:5432/myapp"
|
|
59
|
+
}
|
|
106
60
|
}
|
|
107
61
|
}
|
|
108
62
|
}
|
|
109
63
|
```
|
|
110
64
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
Add to `~/.claude/settings.json`:
|
|
117
|
-
|
|
118
|
-
```json
|
|
119
|
-
{
|
|
120
|
-
"mcpServers": {
|
|
121
|
-
"datalink": {
|
|
122
|
-
"command": "npx",
|
|
123
|
-
"args": ["-y", "@pilat/mcp-datalink", "--config", "./databases.json"]
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
Or use the CLI command:
|
|
130
|
-
|
|
131
|
-
```bash
|
|
132
|
-
claude mcp add datalink -- npx -y @pilat/mcp-datalink --config ./databases.json
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
</details>
|
|
136
|
-
|
|
137
|
-
<details>
|
|
138
|
-
<summary><strong>Cursor</strong></summary>
|
|
139
|
-
|
|
140
|
-
Add to your Cursor MCP settings (Settings > MCP):
|
|
141
|
-
|
|
142
|
-
```json
|
|
143
|
-
{
|
|
144
|
-
"mcpServers": {
|
|
145
|
-
"datalink": {
|
|
146
|
-
"command": "npx",
|
|
147
|
-
"args": ["-y", "@pilat/mcp-datalink", "--config", "./databases.json"]
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
</details>
|
|
154
|
-
|
|
155
|
-
<details>
|
|
156
|
-
<summary><strong>Cline (VS Code Extension)</strong></summary>
|
|
157
|
-
|
|
158
|
-
Add to your Cline MCP configuration in VS Code settings:
|
|
159
|
-
|
|
160
|
-
```json
|
|
161
|
-
{
|
|
162
|
-
"cline.mcpServers": {
|
|
163
|
-
"datalink": {
|
|
164
|
-
"command": "npx",
|
|
165
|
-
"args": ["-y", "@pilat/mcp-datalink", "--config", "./databases.json"]
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
</details>
|
|
172
|
-
|
|
173
|
-
<details>
|
|
174
|
-
<summary><strong>Custom MCP Clients</strong></summary>
|
|
175
|
-
|
|
176
|
-
For any MCP-compatible client, use the standard server configuration:
|
|
177
|
-
|
|
178
|
-
```json
|
|
179
|
-
{
|
|
180
|
-
"command": "npx",
|
|
181
|
-
"args": ["-y", "@pilat/mcp-datalink", "--config", "/absolute/path/to/databases.json"]
|
|
182
|
-
}
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
Or with global installation:
|
|
65
|
+
| Variable | Description |
|
|
66
|
+
|----------|-------------|
|
|
67
|
+
| `DATALINK_{NAME}_URL` | Connection URL (creates database named `{name}`) |
|
|
68
|
+
| `DATALINK_{NAME}_READONLY` | Set to `true` to block writes |
|
|
186
69
|
|
|
187
|
-
|
|
188
|
-
npm install -g @pilat/mcp-datalink
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
```json
|
|
192
|
-
{
|
|
193
|
-
"command": "mcp-datalink",
|
|
194
|
-
"args": ["--config", "/absolute/path/to/databases.json"]
|
|
195
|
-
}
|
|
196
|
-
```
|
|
70
|
+
**Config file locations:**
|
|
197
71
|
|
|
198
|
-
|
|
72
|
+
| Client | Path |
|
|
73
|
+
|--------|------|
|
|
74
|
+
| Claude Desktop (macOS) | `~/Library/Application Support/Claude/claude_desktop_config.json` |
|
|
75
|
+
| Claude Desktop (Windows) | `%APPDATA%\Claude\claude_desktop_config.json` |
|
|
76
|
+
| Claude Code | `~/.claude/settings.json` |
|
|
77
|
+
| Cursor | Settings > MCP |
|
|
78
|
+
| Cline | VS Code settings (`cline.mcpServers`) |
|
|
199
79
|
|
|
200
80
|
## Available Tools
|
|
201
81
|
|
|
@@ -223,80 +103,6 @@ AI: Let me check...
|
|
|
223
103
|
- order_items (142,891 rows)
|
|
224
104
|
```
|
|
225
105
|
|
|
226
|
-
## Configuration
|
|
227
|
-
|
|
228
|
-
### Configuration File
|
|
229
|
-
|
|
230
|
-
Create a `databases.json` file with your database connections:
|
|
231
|
-
|
|
232
|
-
```json
|
|
233
|
-
{
|
|
234
|
-
"databases": {
|
|
235
|
-
"production": {
|
|
236
|
-
"url": "postgresql://user:pass@prod.example.com:5432/app",
|
|
237
|
-
"readonly": true
|
|
238
|
-
},
|
|
239
|
-
"development": {
|
|
240
|
-
"url": "postgresql://dev:dev@localhost:5432/app_dev",
|
|
241
|
-
"readonly": false
|
|
242
|
-
},
|
|
243
|
-
"analytics": {
|
|
244
|
-
"url": "mysql://analyst:pass@analytics.example.com:3306/warehouse",
|
|
245
|
-
"readonly": true
|
|
246
|
-
},
|
|
247
|
-
"local": {
|
|
248
|
-
"url": "sqlite:///path/to/database.db"
|
|
249
|
-
}
|
|
250
|
-
},
|
|
251
|
-
"defaults": {
|
|
252
|
-
"timeout": 30000,
|
|
253
|
-
"maxRows": 100,
|
|
254
|
-
"maxCellLength": 500,
|
|
255
|
-
"maxTotalSize": 65536
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
### Connection Options
|
|
261
|
-
|
|
262
|
-
| Option | Type | Default | Description |
|
|
263
|
-
|--------|------|---------|-------------|
|
|
264
|
-
| `url` | string | required | Database connection string |
|
|
265
|
-
| `readonly` | boolean | `false` | Block INSERT/UPDATE/DELETE operations |
|
|
266
|
-
| `maxRows` | number | `100` | Maximum rows returned per query |
|
|
267
|
-
|
|
268
|
-
### URL Formats
|
|
269
|
-
|
|
270
|
-
```bash
|
|
271
|
-
# PostgreSQL
|
|
272
|
-
postgresql://user:password@host:5432/database
|
|
273
|
-
|
|
274
|
-
# MySQL
|
|
275
|
-
mysql://user:password@host:3306/database
|
|
276
|
-
|
|
277
|
-
# SQLite
|
|
278
|
-
sqlite:///absolute/path/to/database.db
|
|
279
|
-
sqlite://./relative/path/to/database.db
|
|
280
|
-
```
|
|
281
|
-
|
|
282
|
-
### Environment Variables
|
|
283
|
-
|
|
284
|
-
Alternative to config file - set connections via environment variables:
|
|
285
|
-
|
|
286
|
-
```bash
|
|
287
|
-
DB_MCP_PRODUCTION_URL=postgresql://user:pass@prod.example.com:5432/app
|
|
288
|
-
DB_MCP_DEVELOPMENT_URL=postgresql://dev:dev@localhost:5432/app_dev
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
Pattern: `DB_MCP_{NAME}_URL` creates a connection named `{name}` (lowercase).
|
|
292
|
-
|
|
293
|
-
### Config Resolution Order
|
|
294
|
-
|
|
295
|
-
1. CLI argument: `--config ./path/to/config.json`
|
|
296
|
-
2. Environment variable: `DB_MCP_CONFIG=/path/to/config.json`
|
|
297
|
-
3. Current directory: `./databases.json`
|
|
298
|
-
4. Home directory: `~/.config/db-mcp/databases.json`
|
|
299
|
-
|
|
300
106
|
## Security
|
|
301
107
|
|
|
302
108
|
MCP Datalink is designed with security as a core principle:
|
|
@@ -324,91 +130,6 @@ To prevent overwhelming AI context windows, all outputs are automatically limite
|
|
|
324
130
|
|
|
325
131
|
When limits are exceeded, responses include `truncated: true` with pagination hints.
|
|
326
132
|
|
|
327
|
-
## Installation Options
|
|
328
|
-
|
|
329
|
-
### Zero-Install (Recommended)
|
|
330
|
-
|
|
331
|
-
Run directly with `npx` - the package is downloaded automatically:
|
|
332
|
-
|
|
333
|
-
```bash
|
|
334
|
-
npx @pilat/mcp-datalink --config ./databases.json
|
|
335
|
-
```
|
|
336
|
-
|
|
337
|
-
### Global Installation
|
|
338
|
-
|
|
339
|
-
```bash
|
|
340
|
-
npm install -g @pilat/mcp-datalink
|
|
341
|
-
mcp-datalink --config ./databases.json
|
|
342
|
-
```
|
|
343
|
-
|
|
344
|
-
### Local Installation
|
|
345
|
-
|
|
346
|
-
```bash
|
|
347
|
-
npm install @pilat/mcp-datalink
|
|
348
|
-
npx mcp-datalink --config ./databases.json
|
|
349
|
-
```
|
|
350
|
-
|
|
351
|
-
## Development
|
|
352
|
-
|
|
353
|
-
```bash
|
|
354
|
-
# Clone the repository
|
|
355
|
-
git clone https://github.com/pilat/mcp-datalink.git
|
|
356
|
-
cd mcp-datalink
|
|
357
|
-
|
|
358
|
-
# Install dependencies
|
|
359
|
-
npm install
|
|
360
|
-
|
|
361
|
-
# Build
|
|
362
|
-
npm run build
|
|
363
|
-
|
|
364
|
-
# Run tests
|
|
365
|
-
npm run test:unit # Unit tests (fast, no external deps)
|
|
366
|
-
npm run test:integration # Integration tests (uses testcontainers)
|
|
367
|
-
npm test # All tests
|
|
368
|
-
|
|
369
|
-
# Development mode
|
|
370
|
-
npm run dev # Watch mode with auto-rebuild
|
|
371
|
-
```
|
|
372
|
-
|
|
373
|
-
### Testing with MCP Inspector
|
|
374
|
-
|
|
375
|
-
```bash
|
|
376
|
-
npx @modelcontextprotocol/inspector node dist/index.js -- --config ./databases.json
|
|
377
|
-
```
|
|
378
|
-
|
|
379
|
-
## Contributing
|
|
380
|
-
|
|
381
|
-
Contributions are welcome! Please read our contributing guidelines:
|
|
382
|
-
|
|
383
|
-
1. Fork the repository
|
|
384
|
-
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
|
385
|
-
3. Commit your changes (`git commit -m 'feat: add amazing feature'`)
|
|
386
|
-
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
387
|
-
5. Open a Pull Request
|
|
388
|
-
|
|
389
|
-
### Commit Convention
|
|
390
|
-
|
|
391
|
-
We use [Conventional Commits](https://www.conventionalcommits.org/):
|
|
392
|
-
|
|
393
|
-
```
|
|
394
|
-
feat(tools): add new database tool
|
|
395
|
-
fix(security): enforce query validation
|
|
396
|
-
docs: update README
|
|
397
|
-
```
|
|
398
|
-
|
|
399
|
-
## Links
|
|
400
|
-
|
|
401
|
-
- [GitHub Repository](https://github.com/pilat/mcp-datalink)
|
|
402
|
-
- [npm Package](https://www.npmjs.com/package/@pilat/mcp-datalink)
|
|
403
|
-
- [Issue Tracker](https://github.com/pilat/mcp-datalink/issues)
|
|
404
|
-
- [MCP Documentation](https://modelcontextprotocol.io)
|
|
405
|
-
|
|
406
133
|
## License
|
|
407
134
|
|
|
408
|
-
MIT
|
|
409
|
-
|
|
410
|
-
---
|
|
411
|
-
|
|
412
|
-
<p align="center">
|
|
413
|
-
<sub>Built with care by <a href="https://github.com/pilat">@pilat</a></sub>
|
|
414
|
-
</p>
|
|
135
|
+
MIT
|
package/dist/config/loader.d.ts
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import type { Config } from '../types.js';
|
|
2
2
|
/**
|
|
3
|
-
* Load configuration
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
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(
|
|
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":"
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAkC,MAAM,aAAa,CAAC;AAsC1E;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAWnC"}
|
package/dist/config/loader.js
CHANGED
|
@@ -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
|
-
*
|
|
16
|
-
*
|
|
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
|
|
17
|
+
const urlPattern = /^DATALINK_([A-Z0-9_]+)_URL$/;
|
|
48
18
|
for (const [key, value] of Object.entries(process.env)) {
|
|
49
|
-
const match = key.match(
|
|
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:
|
|
26
|
+
readonly: readonlyValue === 'true' || readonlyValue === '1',
|
|
55
27
|
};
|
|
56
28
|
}
|
|
57
29
|
}
|
|
58
30
|
return databases;
|
|
59
31
|
}
|
|
60
32
|
/**
|
|
61
|
-
* Load configuration
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
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
|
|
69
|
-
|
|
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.
|
|
46
|
+
throw new DbMcpError(ErrorCode.CONFIG_NOT_FOUND, 'No databases configured. Set DATALINK_{NAME}_URL environment variables.');
|
|
119
47
|
}
|
|
120
|
-
|
|
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":"
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AACA,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
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA
|
|
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
|
|
18
|
+
Usage: mcp-datalink
|
|
22
19
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
|
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"}
|
package/dist/server.d.ts.map
CHANGED
|
@@ -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;
|
|
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;AAwBzC;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CA+OnD;AAED;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI7D"}
|
package/dist/server.js
CHANGED
|
@@ -13,6 +13,20 @@ import { query, formatQueryResultAsMarkdown } from './tools/query.js';
|
|
|
13
13
|
import { execute } from './tools/execute.js';
|
|
14
14
|
import { explain } from './tools/explain.js';
|
|
15
15
|
import { DbMcpError } from './utils/errors.js';
|
|
16
|
+
/**
|
|
17
|
+
* Server instructions for LLM agents.
|
|
18
|
+
* Provides workflow guidance for proper tool usage sequence.
|
|
19
|
+
*/
|
|
20
|
+
const SERVER_INSTRUCTIONS = `Database Query Workflow:
|
|
21
|
+
1. Discovery: Use list_databases to find available database connections.
|
|
22
|
+
2. Exploration: Use list_tables to discover tables in a database schema.
|
|
23
|
+
3. Schema Validation: Always call describe_table before writing queries to verify exact column names, types, and constraints. Never assume or guess column names.
|
|
24
|
+
4. Query Execution: Use query for SELECT statements, execute for INSERT/UPDATE/DELETE.
|
|
25
|
+
5. Security: All queries must use parameterized placeholders ($1, $2, ...). Never interpolate values directly into SQL strings.
|
|
26
|
+
6. Performance: Use explain to analyze query execution plans for optimization.
|
|
27
|
+
|
|
28
|
+
The recommended sequence is: list_databases → list_tables → describe_table → query/execute.
|
|
29
|
+
Skipping describe_table often leads to errors due to incorrect column names or types.`;
|
|
16
30
|
/**
|
|
17
31
|
* Creates an MCP server configured with all db-mcp tools.
|
|
18
32
|
*
|
|
@@ -27,13 +41,14 @@ export function createServer(config) {
|
|
|
27
41
|
capabilities: {
|
|
28
42
|
tools: {},
|
|
29
43
|
},
|
|
44
|
+
instructions: SERVER_INSTRUCTIONS,
|
|
30
45
|
});
|
|
31
46
|
// Register list tools handler
|
|
32
47
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
33
48
|
tools: [
|
|
34
49
|
{
|
|
35
50
|
name: 'list_databases',
|
|
36
|
-
description: 'List all configured database connections',
|
|
51
|
+
description: 'List all configured database connections available in this server.',
|
|
37
52
|
inputSchema: {
|
|
38
53
|
type: 'object',
|
|
39
54
|
properties: {},
|
|
@@ -42,64 +57,111 @@ export function createServer(config) {
|
|
|
42
57
|
},
|
|
43
58
|
{
|
|
44
59
|
name: 'list_tables',
|
|
45
|
-
description: 'List tables in a database schema',
|
|
60
|
+
description: 'List all tables and views in a database schema with row counts and metadata.',
|
|
46
61
|
inputSchema: {
|
|
47
62
|
type: 'object',
|
|
48
63
|
properties: {
|
|
49
|
-
database: {
|
|
50
|
-
|
|
64
|
+
database: {
|
|
65
|
+
type: 'string',
|
|
66
|
+
description: 'Database connection name as returned by list_databases',
|
|
67
|
+
},
|
|
68
|
+
schema: {
|
|
69
|
+
type: 'string',
|
|
70
|
+
description: 'Schema name to list tables from (default: public for PostgreSQL, none for SQLite)',
|
|
71
|
+
},
|
|
51
72
|
},
|
|
52
73
|
required: ['database'],
|
|
53
74
|
},
|
|
54
75
|
},
|
|
55
76
|
{
|
|
56
77
|
name: 'describe_table',
|
|
57
|
-
description: '
|
|
78
|
+
description: 'Retrieve detailed table structure: column names, data types, nullability, defaults, indexes, and foreign key relationships.',
|
|
58
79
|
inputSchema: {
|
|
59
80
|
type: 'object',
|
|
60
81
|
properties: {
|
|
61
|
-
database: {
|
|
62
|
-
|
|
63
|
-
|
|
82
|
+
database: {
|
|
83
|
+
type: 'string',
|
|
84
|
+
description: 'Database connection name as returned by list_databases',
|
|
85
|
+
},
|
|
86
|
+
table: {
|
|
87
|
+
type: 'string',
|
|
88
|
+
description: 'Table name as returned by list_tables',
|
|
89
|
+
},
|
|
90
|
+
schema: {
|
|
91
|
+
type: 'string',
|
|
92
|
+
description: 'Schema name (default: public for PostgreSQL)',
|
|
93
|
+
},
|
|
64
94
|
},
|
|
65
95
|
required: ['database', 'table'],
|
|
66
96
|
},
|
|
67
97
|
},
|
|
68
98
|
{
|
|
69
99
|
name: 'query',
|
|
70
|
-
description: 'Execute a read-only SELECT query
|
|
100
|
+
description: 'Execute a read-only SELECT query and return results as structured data.',
|
|
71
101
|
inputSchema: {
|
|
72
102
|
type: 'object',
|
|
73
103
|
properties: {
|
|
74
|
-
database: {
|
|
75
|
-
|
|
76
|
-
|
|
104
|
+
database: {
|
|
105
|
+
type: 'string',
|
|
106
|
+
description: 'Database connection name as returned by list_databases',
|
|
107
|
+
},
|
|
108
|
+
sql: {
|
|
109
|
+
type: 'string',
|
|
110
|
+
description: 'SELECT query using parameterized placeholders ($1, $2, ...) for values. ' +
|
|
111
|
+
'Example: SELECT * FROM users WHERE status = $1 AND created_at > $2',
|
|
112
|
+
},
|
|
113
|
+
params: {
|
|
114
|
+
type: 'array',
|
|
115
|
+
description: 'Parameter values corresponding to placeholders in order. ' +
|
|
116
|
+
'Example: ["active", "2024-01-01"] for $1 and $2',
|
|
117
|
+
},
|
|
77
118
|
},
|
|
78
119
|
required: ['database', 'sql'],
|
|
79
120
|
},
|
|
80
121
|
},
|
|
81
122
|
{
|
|
82
123
|
name: 'execute',
|
|
83
|
-
description: 'Execute INSERT
|
|
124
|
+
description: 'Execute INSERT, UPDATE, or DELETE query and return affected row count.',
|
|
84
125
|
inputSchema: {
|
|
85
126
|
type: 'object',
|
|
86
127
|
properties: {
|
|
87
|
-
database: {
|
|
88
|
-
|
|
89
|
-
|
|
128
|
+
database: {
|
|
129
|
+
type: 'string',
|
|
130
|
+
description: 'Database connection name as returned by list_databases',
|
|
131
|
+
},
|
|
132
|
+
sql: {
|
|
133
|
+
type: 'string',
|
|
134
|
+
description: 'INSERT/UPDATE/DELETE query using parameterized placeholders ($1, $2, ...). ' +
|
|
135
|
+
'Example: UPDATE users SET status = $1 WHERE id = $2',
|
|
136
|
+
},
|
|
137
|
+
params: {
|
|
138
|
+
type: 'array',
|
|
139
|
+
description: 'Parameter values corresponding to placeholders in order. ' +
|
|
140
|
+
'Example: ["inactive", 123] for $1 and $2',
|
|
141
|
+
},
|
|
90
142
|
},
|
|
91
143
|
required: ['database', 'sql'],
|
|
92
144
|
},
|
|
93
145
|
},
|
|
94
146
|
{
|
|
95
147
|
name: 'explain',
|
|
96
|
-
description: '
|
|
148
|
+
description: 'Analyze query execution plan to understand performance characteristics and identify optimization opportunities.',
|
|
97
149
|
inputSchema: {
|
|
98
150
|
type: 'object',
|
|
99
151
|
properties: {
|
|
100
|
-
database: {
|
|
101
|
-
|
|
102
|
-
|
|
152
|
+
database: {
|
|
153
|
+
type: 'string',
|
|
154
|
+
description: 'Database connection name as returned by list_databases',
|
|
155
|
+
},
|
|
156
|
+
sql: {
|
|
157
|
+
type: 'string',
|
|
158
|
+
description: 'SQL query to analyze (typically a SELECT statement)',
|
|
159
|
+
},
|
|
160
|
+
analyze: {
|
|
161
|
+
type: 'boolean',
|
|
162
|
+
description: 'If true, actually execute the query to get real timing statistics (EXPLAIN ANALYZE). ' +
|
|
163
|
+
'If false, show estimated plan only. Default: false',
|
|
164
|
+
},
|
|
103
165
|
},
|
|
104
166
|
required: ['database', 'sql'],
|
|
105
167
|
},
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAyB,MAAM,wBAAwB,CAAC;AAC3E,OAAO,EAAE,aAAa,EAA4B,MAAM,2BAA2B,CAAC;AACpF,OAAO,EAAE,KAAK,EAAoB,2BAA2B,EAAE,MAAM,kBAAkB,CAAC;AACxF,OAAO,EAAE,OAAO,EAAsB,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,OAAO,EAAsB,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,MAAc;IACzC,MAAM,MAAM,GAAG,IAAI,MAAM,CACvB;QACE,IAAI,EAAE,cAAc;QACpB,OAAO,EAAE,OAAO;KACjB,EACD;QACE,YAAY,EAAE;YACZ,KAAK,EAAE,EAAE;SACV;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -32,13 +32,6 @@ export interface Config {
|
|
|
32
32
|
databases: Record<string, DatabaseConfig>;
|
|
33
33
|
defaults: DefaultsConfig;
|
|
34
34
|
}
|
|
35
|
-
/** Raw config shape before defaults are applied */
|
|
36
|
-
export interface RawConfig {
|
|
37
|
-
databases?: Record<string, Partial<DatabaseConfig> & {
|
|
38
|
-
url: string;
|
|
39
|
-
}>;
|
|
40
|
-
defaults?: Partial<DefaultsConfig>;
|
|
41
|
-
}
|
|
42
35
|
export interface QueryResult {
|
|
43
36
|
columns: string[];
|
|
44
37
|
rows: unknown[][];
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE5E,MAAM,WAAW,WAAW;IAC1B,4BAA4B;IAC5B,IAAI,EAAE,SAAS,CAAC;IAChB,gEAAgE;IAChE,QAAQ,EAAE,OAAO,CAAC;IAClB,mEAAmE;IACnE,WAAW,EAAE,OAAO,CAAC;IACrB,+CAA+C;IAC/C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,8BAA8B;IAC9B,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,MAAM;IACrB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC1C,QAAQ,EAAE,cAAc,CAAC;CAC1B;AAED,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE5E,MAAM,WAAW,WAAW;IAC1B,4BAA4B;IAC5B,IAAI,EAAE,SAAS,CAAC;IAChB,gEAAgE;IAChE,QAAQ,EAAE,OAAO,CAAC;IAClB,mEAAmE;IACnE,WAAW,EAAE,OAAO,CAAC;IACrB,+CAA+C;IAC/C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,8BAA8B;IAC9B,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,MAAM;IACrB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC1C,QAAQ,EAAE,cAAc,CAAC;CAC1B;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE;QACV,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,WAAW,EAAE,cAAc,EAAE,CAAC;IAC9B,SAAS,EAAE,OAAO,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pilat/mcp-datalink",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "MCP server for secure database access (PostgreSQL, MySQL, SQLite)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -36,8 +36,7 @@
|
|
|
36
36
|
},
|
|
37
37
|
"license": "MIT",
|
|
38
38
|
"files": [
|
|
39
|
-
"dist"
|
|
40
|
-
"databases.example.json"
|
|
39
|
+
"dist"
|
|
41
40
|
],
|
|
42
41
|
"publishConfig": {
|
|
43
42
|
"access": "public"
|
package/databases.example.json
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"databases": {
|
|
3
|
-
"main": {
|
|
4
|
-
"url": "postgresql://user:password@localhost:5432/myapp",
|
|
5
|
-
"readonly": false
|
|
6
|
-
},
|
|
7
|
-
"analytics": {
|
|
8
|
-
"url": "postgresql://readonly:password@analytics.example.com:5432/warehouse",
|
|
9
|
-
"readonly": true
|
|
10
|
-
}
|
|
11
|
-
},
|
|
12
|
-
"defaults": {
|
|
13
|
-
"timeout": 30000,
|
|
14
|
-
"maxRows": 100,
|
|
15
|
-
"maxCellLength": 500,
|
|
16
|
-
"maxTotalSize": 65536
|
|
17
|
-
}
|
|
18
|
-
}
|