@tejasanik/postgres-mcp-server 2.0.0 → 2.1.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.
- package/README.md +335 -2
- package/dist/__tests__/server-tools.test.js +24 -0
- package/dist/__tests__/server-tools.test.js.map +1 -1
- package/dist/__tests__/sql-tools.test.js +713 -0
- package/dist/__tests__/sql-tools.test.js.map +1 -1
- package/dist/db-manager.d.ts.map +1 -1
- package/dist/db-manager.js +1 -0
- package/dist/db-manager.js.map +1 -1
- package/dist/index.js +89 -2
- package/dist/index.js.map +1 -1
- package/dist/tools/server-tools.d.ts +1 -0
- package/dist/tools/server-tools.d.ts.map +1 -1
- package/dist/tools/server-tools.js +5 -4
- package/dist/tools/server-tools.js.map +1 -1
- package/dist/tools/sql-tools.d.ts +82 -1
- package/dist/tools/sql-tools.d.ts.map +1 -1
- package/dist/tools/sql-tools.js +741 -7
- package/dist/tools/sql-tools.js.map +1 -1
- package/dist/types.d.ts +158 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/utils/masking.d.ts +0 -18
- package/dist/utils/masking.d.ts.map +0 -1
- package/dist/utils/masking.js +0 -68
- package/dist/utils/masking.js.map +0 -1
package/README.md
CHANGED
|
@@ -2,6 +2,103 @@
|
|
|
2
2
|
|
|
3
3
|
A Model Context Protocol (MCP) server for PostgreSQL database management and analysis. This server provides comprehensive tools for exploring database schemas, executing queries, analyzing performance, and monitoring database health.
|
|
4
4
|
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🤖 Agent Experience (AX) - Claude Code Review
|
|
8
|
+
|
|
9
|
+
**Tested by:** Claude Code (Sonnet 4.5)
|
|
10
|
+
**Use Case:** Database deployment, schema exploration, and SQL migration
|
|
11
|
+
**Rating:** ⭐⭐⭐⭐⭐ (9.5/10)
|
|
12
|
+
|
|
13
|
+
### What I Loved
|
|
14
|
+
|
|
15
|
+
**1. Clear, Structured Responses**
|
|
16
|
+
Every response includes connection context (`server`, `database`, `schema`), making it crystal clear which environment I'm working in. This is essential when managing multiple databases - I never have to guess where a query ran.
|
|
17
|
+
|
|
18
|
+
**2. Excellent Error Handling**
|
|
19
|
+
When I encountered a syntax error with Liquibase's `/` delimiter, the error message showed:
|
|
20
|
+
|
|
21
|
+
- Exact line number (151)
|
|
22
|
+
- The failing statement
|
|
23
|
+
- Transaction rollback confirmation
|
|
24
|
+
|
|
25
|
+
This made troubleshooting instant. No digging through logs or guessing what failed.
|
|
26
|
+
|
|
27
|
+
**3. Server Management is Intuitive**
|
|
28
|
+
|
|
29
|
+
- `list_servers` → Shows all available servers with connection status
|
|
30
|
+
- `list_databases` → Filters databases by server name
|
|
31
|
+
- `switch_server_db` → Seamless switching with immediate confirmation
|
|
32
|
+
|
|
33
|
+
The flow is natural: discover → select → connect → execute.
|
|
34
|
+
|
|
35
|
+
**4. SQL File Deployment Made Easy**
|
|
36
|
+
The `stripPatterns` feature solved my exact problem:
|
|
37
|
+
|
|
38
|
+
```javascript
|
|
39
|
+
execute_sql_file({
|
|
40
|
+
filePath: "/path/to/liquibase.sql",
|
|
41
|
+
stripPatterns: ["/"], // Removes Liquibase delimiters
|
|
42
|
+
});
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Before this feature, I had to manually remove delimiters or use raw `execute_sql`. Now it's one clean call.
|
|
46
|
+
|
|
47
|
+
**5. Dry-Run Capabilities are Outstanding**
|
|
48
|
+
`dry_run_sql_file` is a game-changer:
|
|
49
|
+
|
|
50
|
+
- Executes ALL statements in a transaction
|
|
51
|
+
- Shows REAL errors with PostgreSQL error codes and constraint names
|
|
52
|
+
- Automatically skips non-rollbackable operations (VACUUM, NEXTVAL)
|
|
53
|
+
- Provides EXPLAIN plans for skipped statements
|
|
54
|
+
- Then rolls back everything
|
|
55
|
+
|
|
56
|
+
This is _way_ better than just parsing - I can catch constraint violations, trigger issues, and get exact row counts before deployment.
|
|
57
|
+
|
|
58
|
+
**6. Security by Default**
|
|
59
|
+
|
|
60
|
+
- Credentials never appear in responses
|
|
61
|
+
- Host/port intentionally hidden (only server names visible)
|
|
62
|
+
- Readonly mode available for production safety
|
|
63
|
+
- Connection context always visible
|
|
64
|
+
|
|
65
|
+
### Improvements Based on My Feedback
|
|
66
|
+
|
|
67
|
+
The developer implemented several features after I tested the MCP:
|
|
68
|
+
|
|
69
|
+
✅ **SQL File Delimiter Support** - Added `stripPatterns` for Liquibase `/`, SQL Server `GO`, etc.
|
|
70
|
+
✅ **Validate-Only Mode** - `execute_sql_file({ validateOnly: true })` previews without execution
|
|
71
|
+
✅ **Enhanced Connection Info** - `get_current_connection` now returns `user` and AI `context`
|
|
72
|
+
✅ **Comprehensive Dry-Run** - `dry_run_sql_file` provides real execution + rollback
|
|
73
|
+
✅ **Better Error Details** - PostgreSQL error codes, constraint names, hints included
|
|
74
|
+
|
|
75
|
+
### Real-World Experience
|
|
76
|
+
|
|
77
|
+
**Task:** Deploy a PostgreSQL function to two databases (dev + GraphQL-Intro-DB)
|
|
78
|
+
|
|
79
|
+
1. **Discovery**: `list_servers` showed all configured servers
|
|
80
|
+
2. **Preview**: Used `preview_sql_file` to check the file structure
|
|
81
|
+
3. **Issue**: Got syntax error from Liquibase's `/` delimiter
|
|
82
|
+
4. **Solution**: Switched to direct `execute_sql` to bypass the delimiter
|
|
83
|
+
5. **Deployment**: Successfully deployed to both databases
|
|
84
|
+
6. **Verification**: Used `get_current_connection` to confirm each deployment
|
|
85
|
+
|
|
86
|
+
Total time: ~3 minutes. The structured responses and clear errors made it feel effortless.
|
|
87
|
+
|
|
88
|
+
### Minor Suggestions for Future
|
|
89
|
+
|
|
90
|
+
1. **Batch Cross Servers Deployment** - Deploy same script to multiple servers at once
|
|
91
|
+
2. **Recent Connections** - Quick-switch to recently used databases
|
|
92
|
+
3. **Statement Progress** - Show progress for large SQL files (e.g., "Executing statement 15/100...")
|
|
93
|
+
|
|
94
|
+
### Bottom Line
|
|
95
|
+
|
|
96
|
+
This MCP is production-ready and developer-friendly. The combination of clear responses, robust error handling, and powerful features like dry-run make it an essential tool for database work. The developer clearly understands the needs of both AI agents and human operators.
|
|
97
|
+
|
|
98
|
+
**Recommended for:** Database migrations, schema exploration, multi-environment management, and production deployments.
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
5
102
|
## Installation
|
|
6
103
|
|
|
7
104
|
```bash
|
|
@@ -264,9 +361,18 @@ Switch to a different PostgreSQL server and optionally a specific database and s
|
|
|
264
361
|
- `database` (optional): Name of the database to connect to (uses server's defaultDatabase or "postgres")
|
|
265
362
|
- `schema` (optional): Default schema to use (uses server's defaultSchema or "public")
|
|
266
363
|
|
|
364
|
+
**Returns:**
|
|
365
|
+
|
|
366
|
+
- `success`: Whether the switch was successful
|
|
367
|
+
- `message`: Success message
|
|
368
|
+
- `currentServer`: Name of the connected server
|
|
369
|
+
- `currentDatabase`: Name of the connected database
|
|
370
|
+
- `currentSchema`: Name of the current schema
|
|
371
|
+
- `context`: (If configured) AI context/guidance for the connected server
|
|
372
|
+
|
|
267
373
|
#### `get_current_connection`
|
|
268
374
|
|
|
269
|
-
Returns details about the current database connection including server, database, schema, and
|
|
375
|
+
Returns details about the current database connection including server, database, schema, access mode, user, and AI context.
|
|
270
376
|
|
|
271
377
|
**Parameters:** None
|
|
272
378
|
|
|
@@ -277,6 +383,8 @@ Returns details about the current database connection including server, database
|
|
|
277
383
|
- `database`: Current database name
|
|
278
384
|
- `schema`: Current schema name
|
|
279
385
|
- `accessMode`: "readonly" or "full"
|
|
386
|
+
- `user`: Database username for the current connection
|
|
387
|
+
- `context`: (If configured) AI context/guidance for the current server
|
|
280
388
|
|
|
281
389
|
### Schema & Object Exploration
|
|
282
390
|
|
|
@@ -341,13 +449,16 @@ Executes SQL statements on the database. Supports pagination and parameterized q
|
|
|
341
449
|
|
|
342
450
|
#### `execute_sql_file`
|
|
343
451
|
|
|
344
|
-
Executes a `.sql` file from the filesystem. Useful for running migration scripts, schema changes, or data imports.
|
|
452
|
+
Executes a `.sql` file from the filesystem. Useful for running migration scripts, schema changes, or data imports. Supports SQL files from various tools like Liquibase, Flyway, and SQL Server migrations.
|
|
345
453
|
|
|
346
454
|
**Parameters:**
|
|
347
455
|
|
|
348
456
|
- `filePath` (required): Absolute or relative path to the `.sql` file to execute
|
|
349
457
|
- `useTransaction` (optional): Wrap execution in a transaction (default: true). If any statement fails, all changes are rolled back.
|
|
350
458
|
- `stopOnError` (optional): Stop execution on first error (default: true). If false, continues with remaining statements and collects all errors.
|
|
459
|
+
- `stripPatterns` (optional): Array of patterns to remove from SQL before execution. Useful for stripping tool-specific delimiters (e.g., Liquibase's `/`, SQL Server's `GO`).
|
|
460
|
+
- `stripAsRegex` (optional): If true, treat `stripPatterns` as regular expressions; if false, as literal strings (default: false).
|
|
461
|
+
- `validateOnly` (optional): If true, parse and validate the file without executing (default: false). Returns a preview of all statements.
|
|
351
462
|
|
|
352
463
|
**Returns:**
|
|
353
464
|
|
|
@@ -364,9 +475,84 @@ Executes a `.sql` file from the filesystem. Useful for running migration scripts
|
|
|
364
475
|
- `sql`: The failing SQL (truncated to 200 chars)
|
|
365
476
|
- `error`: Error message
|
|
366
477
|
- `rollback`: Whether a rollback was performed
|
|
478
|
+
- `validateOnly`: (When validateOnly=true) Set to true
|
|
479
|
+
- `preview`: (When validateOnly=true) Array of statement previews:
|
|
480
|
+
- `index`: Statement index (1-based)
|
|
481
|
+
- `lineNumber`: Line number in the file
|
|
482
|
+
- `sql`: The SQL statement (truncated to 200 chars)
|
|
483
|
+
- `type`: Detected statement type (SELECT, INSERT, UPDATE, DELETE, CREATE, etc.)
|
|
367
484
|
|
|
368
485
|
**Limits:** Max file size: 50MB. Supports PostgreSQL-specific syntax including dollar-quoted strings and block comments.
|
|
369
486
|
|
|
487
|
+
**Examples:**
|
|
488
|
+
|
|
489
|
+
```
|
|
490
|
+
# Preview a file without executing
|
|
491
|
+
execute_sql_file({ filePath: "/path/to/migration.sql", validateOnly: true })
|
|
492
|
+
|
|
493
|
+
# Strip Liquibase delimiters (literal "/" on its own line)
|
|
494
|
+
execute_sql_file({ filePath: "/path/to/liquibase.sql", stripPatterns: ["/"] })
|
|
495
|
+
|
|
496
|
+
# Strip SQL Server GO statements (regex pattern)
|
|
497
|
+
execute_sql_file({
|
|
498
|
+
filePath: "/path/to/sqlserver.sql",
|
|
499
|
+
stripPatterns: ["^\\s*GO\\s*$"],
|
|
500
|
+
stripAsRegex: true
|
|
501
|
+
})
|
|
502
|
+
|
|
503
|
+
# Strip multiple patterns
|
|
504
|
+
execute_sql_file({
|
|
505
|
+
filePath: "/path/to/migration.sql",
|
|
506
|
+
stripPatterns: ["/", "GO", "\\"]
|
|
507
|
+
})
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
#### `preview_sql_file`
|
|
511
|
+
|
|
512
|
+
Preview a SQL file without executing it. Similar to `mutation_preview` but for SQL files. Shows statement counts by type and warnings for potentially dangerous operations. Use this before `execute_sql_file` to understand what a migration will do.
|
|
513
|
+
|
|
514
|
+
**Parameters:**
|
|
515
|
+
|
|
516
|
+
- `filePath` (required): Absolute or relative path to the `.sql` file to preview
|
|
517
|
+
- `stripPatterns` (optional): Patterns to strip from SQL before parsing (same as execute_sql_file)
|
|
518
|
+
- `stripAsRegex` (optional): If true, treat patterns as regex (default: false)
|
|
519
|
+
- `maxStatements` (optional): Maximum statements to show in preview (default: 20, max: 100)
|
|
520
|
+
|
|
521
|
+
**Returns:**
|
|
522
|
+
|
|
523
|
+
- `filePath`: Resolved file path
|
|
524
|
+
- `fileSize`: File size in bytes
|
|
525
|
+
- `fileSizeFormatted`: Human-readable file size (e.g., "15.2 KB")
|
|
526
|
+
- `totalStatements`: Total executable statements in the file
|
|
527
|
+
- `statementsByType`: Breakdown by statement type (e.g., `{ "CREATE": 5, "INSERT": 10, "ALTER": 2 }`)
|
|
528
|
+
- `statements`: Array of statement previews (up to maxStatements):
|
|
529
|
+
- `index`: Statement number (1-based)
|
|
530
|
+
- `lineNumber`: Line number in file
|
|
531
|
+
- `sql`: Statement SQL (truncated to 300 chars)
|
|
532
|
+
- `type`: Statement type (SELECT, INSERT, CREATE, etc.)
|
|
533
|
+
- `warnings`: Array of warnings for dangerous operations:
|
|
534
|
+
- DROP statements
|
|
535
|
+
- TRUNCATE statements
|
|
536
|
+
- DELETE/UPDATE without WHERE clause
|
|
537
|
+
- `summary`: Human-readable summary (e.g., "File contains 17 statements: 10 INSERT, 5 CREATE, 2 ALTER")
|
|
538
|
+
|
|
539
|
+
**Example:**
|
|
540
|
+
|
|
541
|
+
```
|
|
542
|
+
preview_sql_file({ filePath: "/path/to/migration.sql" })
|
|
543
|
+
// Returns:
|
|
544
|
+
// {
|
|
545
|
+
// "filePath": "/path/to/migration.sql",
|
|
546
|
+
// "fileSize": 15234,
|
|
547
|
+
// "fileSizeFormatted": "14.9 KB",
|
|
548
|
+
// "totalStatements": 17,
|
|
549
|
+
// "statementsByType": { "CREATE": 5, "INSERT": 10, "ALTER": 2 },
|
|
550
|
+
// "statements": [...],
|
|
551
|
+
// "warnings": ["Statement 15 (line 142): DROP statement detected - will permanently remove database object"],
|
|
552
|
+
// "summary": "File contains 17 statements: 10 INSERT, 5 CREATE, 2 ALTER"
|
|
553
|
+
// }
|
|
554
|
+
```
|
|
555
|
+
|
|
370
556
|
#### `mutation_preview`
|
|
371
557
|
|
|
372
558
|
Preview the effect of INSERT, UPDATE, or DELETE statements without executing them. Shows estimated rows affected and a sample of rows that would be modified. Essential for verifying destructive queries before running them.
|
|
@@ -392,6 +578,152 @@ mutation_preview({ sql: "DELETE FROM orders WHERE status = 'cancelled'" })
|
|
|
392
578
|
// Returns: { mutationType: "DELETE", estimatedRowsAffected: 150, sampleAffectedRows: [...5 rows...] }
|
|
393
579
|
```
|
|
394
580
|
|
|
581
|
+
#### `mutation_dry_run`
|
|
582
|
+
|
|
583
|
+
**Transaction-based dry-run for mutations.** Actually executes the INSERT/UPDATE/DELETE within a transaction, captures **REAL** results, then ROLLBACK so nothing persists. More accurate than `mutation_preview` because it catches actual constraint violations, trigger effects, and exact row counts.
|
|
584
|
+
|
|
585
|
+
**Non-Rollbackable Operations:** Statements containing explicit `NEXTVAL()` or `SETVAL()` are **skipped** to prevent sequence values from being permanently consumed. For skipped statements, an `EXPLAIN` query plan is provided instead.
|
|
586
|
+
|
|
587
|
+
**Parameters:**
|
|
588
|
+
|
|
589
|
+
- `sql` (required): The INSERT, UPDATE, or DELETE statement to dry-run
|
|
590
|
+
- `sampleSize` (optional): Number of sample rows to return (default: 10, max: 20)
|
|
591
|
+
|
|
592
|
+
**Returns:**
|
|
593
|
+
|
|
594
|
+
- `mutationType`: Type of mutation (INSERT, UPDATE, DELETE)
|
|
595
|
+
- `success`: Whether the dry-run executed successfully
|
|
596
|
+
- `skipped`: If `true`, statement was skipped (contains non-rollbackable operation)
|
|
597
|
+
- `skipReason`: Why the statement was skipped
|
|
598
|
+
- `rowsAffected`: **Actual** number of rows that would be affected
|
|
599
|
+
- `beforeRows`: Sample of rows before the change (for UPDATE/DELETE)
|
|
600
|
+
- `affectedRows`: Sample of rows after the change (for INSERT/UPDATE) or deleted rows
|
|
601
|
+
- `targetTable`: The table being modified
|
|
602
|
+
- `whereClause`: The WHERE clause (if present)
|
|
603
|
+
- `executionTimeMs`: Execution time in milliseconds
|
|
604
|
+
- `error`: Detailed PostgreSQL error information if failed:
|
|
605
|
+
- `message`: Error message
|
|
606
|
+
- `code`: PostgreSQL error code (e.g., '23505' for unique violation)
|
|
607
|
+
- `detail`: Detailed error description
|
|
608
|
+
- `hint`: Hint for fixing the error
|
|
609
|
+
- `constraint`: Constraint name that caused the error
|
|
610
|
+
- `table`, `column`, `schema`: Related database objects
|
|
611
|
+
- `nonRollbackableWarnings`: Warnings about side effects:
|
|
612
|
+
- `operation`: Type of operation (SEQUENCE, VACUUM, etc.)
|
|
613
|
+
- `message`: Warning message
|
|
614
|
+
- `mustSkip`: If `true`, operation was skipped; if `false`, just a warning
|
|
615
|
+
- `warnings`: General warnings (e.g., no WHERE clause)
|
|
616
|
+
- `explainPlan`: Query plan from EXPLAIN (for skipped DML statements with NEXTVAL/SETVAL)
|
|
617
|
+
|
|
618
|
+
**Example:**
|
|
619
|
+
|
|
620
|
+
```
|
|
621
|
+
mutation_dry_run({ sql: "INSERT INTO users (email) VALUES ('test@test.com')" })
|
|
622
|
+
// On success: { success: true, mutationType: "INSERT", rowsAffected: 1, affectedRows: [{id: 5, email: "test@test.com"}] }
|
|
623
|
+
// On failure: { success: false, error: { code: "23505", constraint: "users_email_key", detail: "Key already exists" } }
|
|
624
|
+
|
|
625
|
+
// With explicit NEXTVAL (skipped):
|
|
626
|
+
mutation_dry_run({ sql: "INSERT INTO users (id) VALUES (nextval('users_id_seq'))" })
|
|
627
|
+
// Returns: { success: true, skipped: true, skipReason: "NEXTVAL increments sequence...", explainPlan: [...] }
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
#### `dry_run_sql_file`
|
|
631
|
+
|
|
632
|
+
**Transaction-based dry-run for SQL files.** Actually executes ALL statements within a transaction, captures **REAL** results for each statement (row counts, errors with line numbers, constraint violations), then ROLLBACK so nothing persists. Perfect for testing migrations before deploying.
|
|
633
|
+
|
|
634
|
+
**Non-Rollbackable Operations:** The following operations are automatically **skipped** (not executed):
|
|
635
|
+
|
|
636
|
+
- **VACUUM, CLUSTER, REINDEX CONCURRENTLY**: Cannot run inside a transaction
|
|
637
|
+
- **CREATE INDEX CONCURRENTLY**: Cannot run inside a transaction
|
|
638
|
+
- **CREATE/DROP DATABASE**: Cannot run inside a transaction
|
|
639
|
+
- **NEXTVAL(), SETVAL()**: Would permanently consume sequence values
|
|
640
|
+
|
|
641
|
+
For skipped DML statements (INSERT/UPDATE/DELETE/SELECT with NEXTVAL/SETVAL), an `EXPLAIN` query plan is provided so you can still see what the query would do.
|
|
642
|
+
|
|
643
|
+
**Parameters:**
|
|
644
|
+
|
|
645
|
+
- `filePath` (required): Absolute or relative path to the `.sql` file
|
|
646
|
+
- `stripPatterns` (optional): Patterns to strip from SQL before execution (e.g., `["/"]` for Liquibase)
|
|
647
|
+
- `stripAsRegex` (optional): If true, treat patterns as regex (default: false)
|
|
648
|
+
- `maxStatements` (optional): Maximum statements to include in results (default: 50, max: 200)
|
|
649
|
+
- `stopOnError` (optional): Stop on first error (default: false - continues to show ALL errors)
|
|
650
|
+
|
|
651
|
+
**Returns:**
|
|
652
|
+
|
|
653
|
+
- `success`: Whether all statements executed successfully (skipped statements don't count as failures)
|
|
654
|
+
- `filePath`: Resolved file path
|
|
655
|
+
- `fileSize`: File size in bytes
|
|
656
|
+
- `fileSizeFormatted`: Human-readable file size
|
|
657
|
+
- `totalStatements`: Total statements in file
|
|
658
|
+
- `successCount`: Number of successful statements
|
|
659
|
+
- `failureCount`: Number of failed statements
|
|
660
|
+
- `skippedCount`: Number of skipped statements (non-rollbackable operations)
|
|
661
|
+
- `totalRowsAffected`: Total rows affected across all statements
|
|
662
|
+
- `statementsByType`: Breakdown by statement type (e.g., `{"CREATE": 5, "INSERT": 10}`)
|
|
663
|
+
- `executionTimeMs`: Total execution time
|
|
664
|
+
- `statementResults`: Array of results for each statement:
|
|
665
|
+
- `index`: Statement number (1-based)
|
|
666
|
+
- `lineNumber`: Line number in file
|
|
667
|
+
- `sql`: The SQL statement (truncated)
|
|
668
|
+
- `type`: Statement type (SELECT, INSERT, CREATE, etc.)
|
|
669
|
+
- `success`: Whether statement succeeded
|
|
670
|
+
- `skipped`: If `true`, statement was skipped (non-rollbackable operation)
|
|
671
|
+
- `skipReason`: Why the statement was skipped
|
|
672
|
+
- `rowCount`: Rows affected/returned
|
|
673
|
+
- `rows`: Sample rows (for SELECT or RETURNING)
|
|
674
|
+
- `executionTimeMs`: Statement execution time
|
|
675
|
+
- `error`: Detailed PostgreSQL error if failed (same fields as `mutation_dry_run`)
|
|
676
|
+
- `warnings`: Warnings for this statement
|
|
677
|
+
- `explainPlan`: Query plan from EXPLAIN (for skipped DML statements)
|
|
678
|
+
- `nonRollbackableWarnings`: Warnings about operations that can't be fully rolled back:
|
|
679
|
+
- `operation`: Type (SEQUENCE, VACUUM, CLUSTER, etc.)
|
|
680
|
+
- `message`: Warning message
|
|
681
|
+
- `mustSkip`: If `true`, operation was skipped; if `false`, just a warning
|
|
682
|
+
- `statementIndex`, `lineNumber`: Location in file
|
|
683
|
+
- `summary`: Human-readable summary
|
|
684
|
+
- `rolledBack`: Always `true` - confirms changes were rolled back
|
|
685
|
+
|
|
686
|
+
**Example:**
|
|
687
|
+
|
|
688
|
+
```
|
|
689
|
+
dry_run_sql_file({ filePath: "/path/to/migration.sql", stripPatterns: ["/"] })
|
|
690
|
+
// Returns:
|
|
691
|
+
// {
|
|
692
|
+
// "success": false,
|
|
693
|
+
// "totalStatements": 15,
|
|
694
|
+
// "successCount": 12,
|
|
695
|
+
// "failureCount": 2,
|
|
696
|
+
// "skippedCount": 1,
|
|
697
|
+
// "statementResults": [
|
|
698
|
+
// { "index": 1, "lineNumber": 1, "type": "CREATE", "success": true },
|
|
699
|
+
// { "index": 5, "lineNumber": 23, "type": "INSERT", "success": false,
|
|
700
|
+
// "error": { "code": "23505", "constraint": "users_pkey", "detail": "Key already exists" } },
|
|
701
|
+
// { "index": 8, "lineNumber": 45, "type": "SELECT", "success": true, "skipped": true,
|
|
702
|
+
// "skipReason": "NEXTVAL increments sequence...", "explainPlan": [...] },
|
|
703
|
+
// ...
|
|
704
|
+
// ],
|
|
705
|
+
// "nonRollbackableWarnings": [
|
|
706
|
+
// { "operation": "SEQUENCE", "message": "INSERT may consume sequence values...", "mustSkip": false },
|
|
707
|
+
// { "operation": "SEQUENCE", "message": "NEXTVAL increments sequence...", "mustSkip": true }
|
|
708
|
+
// ],
|
|
709
|
+
// "summary": "Dry-run of 15 statements: 12 succeeded, 2 failed, 1 skipped (non-rollbackable). All changes rolled back.",
|
|
710
|
+
// "rolledBack": true
|
|
711
|
+
// }
|
|
712
|
+
```
|
|
713
|
+
|
|
714
|
+
**When to use `dry_run_sql_file` vs `preview_sql_file`:**
|
|
715
|
+
|
|
716
|
+
| Feature | `preview_sql_file` | `dry_run_sql_file` |
|
|
717
|
+
| -------------------------------- | ------------------- | -------------------------------- |
|
|
718
|
+
| Speed | Fast (just parsing) | Slower (actual execution) |
|
|
719
|
+
| Detects syntax errors | Basic | **Actual PostgreSQL errors** |
|
|
720
|
+
| Detects constraint violations | No | **Yes** |
|
|
721
|
+
| Detects trigger effects | No | **Yes** |
|
|
722
|
+
| Accurate row counts | No (estimates) | **Yes (actual)** |
|
|
723
|
+
| Shows error details | No | **Yes (code, constraint, hint)** |
|
|
724
|
+
| Consumes sequences | No | **No (NEXTVAL/SETVAL skipped)** |
|
|
725
|
+
| Shows query plan for skipped ops | N/A | **Yes (EXPLAIN)** |
|
|
726
|
+
|
|
395
727
|
#### `batch_execute`
|
|
396
728
|
|
|
397
729
|
Execute multiple SQL queries in parallel. Returns all results keyed by query name. Efficient for fetching multiple independent pieces of data in a single call.
|
|
@@ -581,6 +913,7 @@ The server automatically handles stale database connections. When a connection e
|
|
|
581
913
|
4. Retry the operation once
|
|
582
914
|
|
|
583
915
|
This is particularly useful for:
|
|
916
|
+
|
|
584
917
|
- Staging/development servers that go idle
|
|
585
918
|
- Cloud databases with connection timeouts
|
|
586
919
|
- Network interruptions
|
|
@@ -48,6 +48,30 @@ describe('Server Tools', () => {
|
|
|
48
48
|
const result = await listServers({});
|
|
49
49
|
expect(result.servers[0].isConnected).toBe(false);
|
|
50
50
|
});
|
|
51
|
+
it('should return context for servers with AI context configured', async () => {
|
|
52
|
+
process.env.POSTGRES_SERVERS = JSON.stringify({
|
|
53
|
+
dev: {
|
|
54
|
+
host: 'localhost',
|
|
55
|
+
port: '5432',
|
|
56
|
+
username: 'user',
|
|
57
|
+
password: 'pass',
|
|
58
|
+
context: 'Development server - safe for any queries'
|
|
59
|
+
},
|
|
60
|
+
prod: {
|
|
61
|
+
host: 'prod.example.com',
|
|
62
|
+
port: '5432',
|
|
63
|
+
username: 'user',
|
|
64
|
+
password: 'pass',
|
|
65
|
+
context: 'PRODUCTION - Read-only queries only. Always use LIMIT.'
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
const result = await listServers({});
|
|
69
|
+
expect(result.servers).toHaveLength(2);
|
|
70
|
+
const devServer = result.servers.find((s) => s.name === 'dev');
|
|
71
|
+
const prodServer = result.servers.find((s) => s.name === 'prod');
|
|
72
|
+
expect(devServer?.context).toBe('Development server - safe for any queries');
|
|
73
|
+
expect(prodServer?.context).toBe('PRODUCTION - Read-only queries only. Always use LIMIT.');
|
|
74
|
+
});
|
|
51
75
|
it('should not expose host or port in response', async () => {
|
|
52
76
|
process.env.POSTGRES_SERVERS = JSON.stringify({
|
|
53
77
|
dev: { host: 'secret.example.com', port: '5432', username: 'user', password: 'pass' }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-tools.test.js","sourceRoot":"","sources":["../../src/__tests__/server-tools.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AACtF,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"server-tools.test.js","sourceRoot":"","sources":["../../src/__tests__/server-tools.test.ts"],"names":[],"mappings":"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"}
|