mcp-migration-advisor 0.2.12 → 0.2.14
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.
|
@@ -28,11 +28,12 @@ export function analyzeDataLoss(migration) {
|
|
|
28
28
|
}
|
|
29
29
|
case "DROP_TABLE": {
|
|
30
30
|
const cascade = upper.includes("CASCADE");
|
|
31
|
+
const dropTableName = stmt.tableName ?? "unknown";
|
|
31
32
|
issues.push({
|
|
32
33
|
risk: "CERTAIN",
|
|
33
34
|
statement: truncate(stmt.raw),
|
|
34
35
|
tableName: stmt.tableName,
|
|
35
|
-
description: `Dropping table '${
|
|
36
|
+
description: `Dropping table '${dropTableName}' permanently deletes all data.${cascade ? " CASCADE will also drop dependent objects." : ""}`,
|
|
36
37
|
mitigation: "Ensure a backup exists. Consider renaming the table first and dropping in a later migration.",
|
|
37
38
|
});
|
|
38
39
|
break;
|
|
@@ -79,8 +80,9 @@ export function analyzeDataLoss(migration) {
|
|
|
79
80
|
// Skip data manipulation checks for CREATE statements to avoid false positives.
|
|
80
81
|
if (/^CREATE\b/i.test(stmt.raw.trim()))
|
|
81
82
|
break;
|
|
82
|
-
// Detect TRUNCATE
|
|
83
|
-
|
|
83
|
+
// Detect TRUNCATE — use word-boundary match to avoid false positives
|
|
84
|
+
// on table/column names containing "truncate" (e.g. truncate_log).
|
|
85
|
+
if (/\bTRUNCATE\b/i.test(stmt.raw)) {
|
|
84
86
|
const tableMatch = stmt.raw.match(/TRUNCATE\s+(?:TABLE\s+)?(?:`|"|)?(?:\w+\.)?(\w+)/i);
|
|
85
87
|
issues.push({
|
|
86
88
|
risk: "CERTAIN",
|
|
@@ -85,11 +85,12 @@ function analyzeStatement(stmt) {
|
|
|
85
85
|
break;
|
|
86
86
|
}
|
|
87
87
|
case "DROP_TABLE": {
|
|
88
|
+
const dropTableName = stmt.tableName ?? "unknown";
|
|
88
89
|
risks.push({
|
|
89
90
|
severity: "HIGH",
|
|
90
91
|
statement: truncate(stmt.raw),
|
|
91
92
|
tableName: stmt.tableName,
|
|
92
|
-
risk: `DROP TABLE '${
|
|
93
|
+
risk: `DROP TABLE '${dropTableName}' is irreversible and acquires ACCESS EXCLUSIVE lock.`,
|
|
93
94
|
recommendation: "Ensure no foreign keys reference this table. Consider renaming first (expand-contract) to allow rollback.",
|
|
94
95
|
});
|
|
95
96
|
if (stmt.details.cascade === "true") {
|
package/build/index.js
CHANGED
|
@@ -6,9 +6,12 @@
|
|
|
6
6
|
* analyze_migration — Parse and analyze a SQL migration for risks
|
|
7
7
|
* score_risk — Calculate risk score for a migration
|
|
8
8
|
*/
|
|
9
|
+
import { createRequire } from "module";
|
|
9
10
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
10
11
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
11
12
|
import { z } from "zod";
|
|
13
|
+
const require = createRequire(import.meta.url);
|
|
14
|
+
const { version: packageVersion } = require("../package.json");
|
|
12
15
|
import { parseMigration } from "./parsers/flyway-sql.js";
|
|
13
16
|
import { parseLiquibaseXml } from "./parsers/liquibase-xml.js";
|
|
14
17
|
import { parseLiquibaseYaml } from "./parsers/liquibase-yaml.js";
|
|
@@ -33,7 +36,7 @@ function formatParserWarnings(migration) {
|
|
|
33
36
|
}
|
|
34
37
|
// Handle --help
|
|
35
38
|
if (process.argv.includes("--help") || process.argv.includes("-h")) {
|
|
36
|
-
console.log(`mcp-migration-advisor
|
|
39
|
+
console.log(`mcp-migration-advisor v${packageVersion} — MCP server for database migration risk analysis
|
|
37
40
|
|
|
38
41
|
Usage:
|
|
39
42
|
mcp-migration-advisor [options]
|
|
@@ -52,10 +55,10 @@ Tools provided:
|
|
|
52
55
|
}
|
|
53
56
|
const server = new McpServer({
|
|
54
57
|
name: "mcp-migration-advisor",
|
|
55
|
-
version:
|
|
58
|
+
version: packageVersion,
|
|
56
59
|
});
|
|
57
60
|
// Tool 1: analyze_migration
|
|
58
|
-
server.tool("analyze_migration", "Analyze a SQL migration file for lock risks, data loss potential, and unsafe patterns. Supports Flyway (V__*.sql) and plain SQL.", {
|
|
61
|
+
server.tool("analyze_migration", "Analyze a SQL migration file for lock risks, data loss potential, and unsafe patterns. Detects: ACCESS EXCLUSIVE locks (DROP TABLE, ADD COLUMN NOT NULL, type changes, CREATE INDEX without CONCURRENTLY), data loss operations (TRUNCATE, DELETE without WHERE, UPDATE without WHERE, DROP COLUMN), and cascade risks. Supports Flyway versioned (V__*.sql) and repeatable (R__*.sql) migrations, as well as plain SQL files.", {
|
|
59
62
|
filename: z.string().describe("Migration filename (e.g., V2__add_user_email.sql)"),
|
|
60
63
|
sql: z.string().describe("The SQL content of the migration file"),
|
|
61
64
|
}, async ({ filename, sql }) => {
|
|
@@ -126,7 +129,7 @@ server.tool("analyze_migration", "Analyze a SQL migration file for lock risks, d
|
|
|
126
129
|
}
|
|
127
130
|
});
|
|
128
131
|
// Tool 2: analyze_liquibase
|
|
129
|
-
server.tool("analyze_liquibase", "Analyze a Liquibase XML changelog for lock risks, data loss potential, and unsafe patterns. Supports createTable, dropTable, addColumn, dropColumn, modifyDataType, createIndex, addForeignKeyConstraint, renameTable, renameColumn, and
|
|
132
|
+
server.tool("analyze_liquibase", "Analyze a Liquibase XML changelog for lock risks, data loss potential, and unsafe patterns. Supports all major change types: createTable, dropTable, addColumn, dropColumn, modifyDataType, addNotNullConstraint, createIndex, dropIndex, addForeignKeyConstraint, dropForeignKeyConstraint, renameTable, renameColumn. Inline <sql> changeSets are also analyzed for TRUNCATE, DELETE without WHERE, and UPDATE without WHERE. Returns lock risk severity (ACCESS EXCLUSIVE, SHARE locks) and data loss risk per operation.", {
|
|
130
133
|
xml: z.string().describe("The Liquibase XML changelog content"),
|
|
131
134
|
}, async ({ xml }) => {
|
|
132
135
|
try {
|
|
@@ -183,7 +186,7 @@ server.tool("analyze_liquibase", "Analyze a Liquibase XML changelog for lock ris
|
|
|
183
186
|
}
|
|
184
187
|
});
|
|
185
188
|
// Tool 3: analyze_liquibase_yaml
|
|
186
|
-
server.tool("analyze_liquibase_yaml", "Analyze a Liquibase YAML changelog for lock risks, data loss potential, and unsafe patterns. Supports createTable, dropTable, addColumn, dropColumn, modifyDataType, createIndex, addForeignKeyConstraint, renameTable, renameColumn, and
|
|
189
|
+
server.tool("analyze_liquibase_yaml", "Analyze a Liquibase YAML changelog for lock risks, data loss potential, and unsafe patterns. Supports all major change types: createTable, dropTable, addColumn, dropColumn, modifyDataType, addNotNullConstraint, createIndex, dropIndex, addForeignKeyConstraint, dropForeignKeyConstraint, renameTable, renameColumn. Inline sql changeSets are also analyzed for TRUNCATE, DELETE without WHERE, and UPDATE without WHERE. Returns lock risk severity (ACCESS EXCLUSIVE, SHARE locks) and data loss risk per operation.", {
|
|
187
190
|
yaml: z.string().describe("The Liquibase YAML changelog content"),
|
|
188
191
|
}, async ({ yaml }) => {
|
|
189
192
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-migration-advisor",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.14",
|
|
4
4
|
"description": "MCP server for database migration risk analysis — Flyway and Liquibase XML/YAML/SQL support with lock detection and conflict analysis",
|
|
5
5
|
"mcpName": "io.github.dmitriusan/mcp-migration-advisor",
|
|
6
6
|
"main": "build/index.js",
|