mcp-migration-advisor 0.2.0 → 0.2.2
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/build/index.js
CHANGED
|
@@ -19,6 +19,21 @@ import { detectConflicts, formatConflictReport } from "./analyzers/conflicts.js"
|
|
|
19
19
|
import { validateLicense, formatUpgradePrompt } from "./license.js";
|
|
20
20
|
// License check (reads MCP_LICENSE_KEY env var once at startup)
|
|
21
21
|
const license = validateLicense(process.env.MCP_LICENSE_KEY, "migration-advisor");
|
|
22
|
+
/**
|
|
23
|
+
* Format parser warnings into a markdown section.
|
|
24
|
+
* Returns empty string if there are no warnings.
|
|
25
|
+
*/
|
|
26
|
+
function formatParserWarnings(migration) {
|
|
27
|
+
if (migration.warnings.length === 0)
|
|
28
|
+
return "";
|
|
29
|
+
let output = "### Parser Warnings\n\n";
|
|
30
|
+
output += `> ${migration.warnings.length} DDL statement(s) could not be fully parsed and were classified as OTHER\n\n`;
|
|
31
|
+
for (const w of migration.warnings) {
|
|
32
|
+
output += `- \`${w.snippet}\`\n`;
|
|
33
|
+
}
|
|
34
|
+
output += "\n";
|
|
35
|
+
return output;
|
|
36
|
+
}
|
|
22
37
|
// Handle --help
|
|
23
38
|
if (process.argv.includes("--help") || process.argv.includes("-h")) {
|
|
24
39
|
console.log(`mcp-migration-advisor v0.1.0 — MCP server for database migration risk analysis
|
|
@@ -94,6 +109,7 @@ server.tool("analyze_migration", "Analyze a SQL migration file for lock risks, d
|
|
|
94
109
|
else {
|
|
95
110
|
output += "### Data Loss Analysis\n\nNo data loss risks detected.\n\n";
|
|
96
111
|
}
|
|
112
|
+
output += formatParserWarnings(migration);
|
|
97
113
|
return {
|
|
98
114
|
content: [{ type: "text", text: output }],
|
|
99
115
|
};
|
|
@@ -134,6 +150,7 @@ server.tool("analyze_liquibase", "Analyze a Liquibase XML changelog for lock ris
|
|
|
134
150
|
if (lockRisks.length === 0 && dataLossIssues.length === 0) {
|
|
135
151
|
output += "### No risks detected.\n";
|
|
136
152
|
}
|
|
153
|
+
output += formatParserWarnings(migration);
|
|
137
154
|
return { content: [{ type: "text", text: output }] };
|
|
138
155
|
});
|
|
139
156
|
// Tool 3: analyze_liquibase_yaml
|
|
@@ -172,6 +189,7 @@ server.tool("analyze_liquibase_yaml", "Analyze a Liquibase YAML changelog for lo
|
|
|
172
189
|
if (lockRisks.length === 0 && dataLossIssues.length === 0) {
|
|
173
190
|
output += "### No risks detected.\n";
|
|
174
191
|
}
|
|
192
|
+
output += formatParserWarnings(migration);
|
|
175
193
|
return { content: [{ type: "text", text: output }] };
|
|
176
194
|
});
|
|
177
195
|
// Tool 4: score_risk
|
|
@@ -171,6 +171,30 @@ function classifyStatement(raw) {
|
|
|
171
171
|
}
|
|
172
172
|
return { type: "OTHER", raw, tableName: null, columnName: null, details };
|
|
173
173
|
}
|
|
174
|
+
/**
|
|
175
|
+
* Build a snippet of up to ~80 characters from a raw statement for debugging.
|
|
176
|
+
*/
|
|
177
|
+
export function truncateSnippet(raw, maxLen = 80) {
|
|
178
|
+
const oneLine = raw.replace(/\s+/g, " ").trim();
|
|
179
|
+
if (oneLine.length <= maxLen)
|
|
180
|
+
return oneLine;
|
|
181
|
+
return oneLine.substring(0, maxLen) + "...";
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Collect warnings for statements classified as OTHER.
|
|
185
|
+
*/
|
|
186
|
+
export function collectParserWarnings(statements) {
|
|
187
|
+
const warnings = [];
|
|
188
|
+
for (const stmt of statements) {
|
|
189
|
+
if (stmt.type === "OTHER") {
|
|
190
|
+
warnings.push({
|
|
191
|
+
message: "Unrecognized DDL statement classified as OTHER",
|
|
192
|
+
snippet: truncateSnippet(stmt.raw),
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return warnings;
|
|
197
|
+
}
|
|
174
198
|
/**
|
|
175
199
|
* Parse a complete Flyway migration file.
|
|
176
200
|
*/
|
|
@@ -178,12 +202,14 @@ export function parseMigration(filename, sql) {
|
|
|
178
202
|
const { version, description, isRepeatable } = parseFlywayFilename(filename);
|
|
179
203
|
const rawStatements = splitStatements(sql);
|
|
180
204
|
const statements = rawStatements.map(classifyStatement);
|
|
205
|
+
const warnings = collectParserWarnings(statements);
|
|
181
206
|
return {
|
|
182
207
|
version,
|
|
183
208
|
description,
|
|
184
209
|
filename,
|
|
185
210
|
isRepeatable,
|
|
186
211
|
statements,
|
|
212
|
+
warnings,
|
|
187
213
|
};
|
|
188
214
|
}
|
|
189
215
|
//# sourceMappingURL=flyway-sql.js.map
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Parses Liquibase XML changelogs and extracts DDL operations
|
|
5
5
|
* compatible with the same DDLStatement interface used by Flyway.
|
|
6
6
|
*/
|
|
7
|
+
import { collectParserWarnings } from "./flyway-sql.js";
|
|
7
8
|
/**
|
|
8
9
|
* Parse a Liquibase XML changelog and extract DDL statements.
|
|
9
10
|
*
|
|
@@ -23,6 +24,7 @@ export function parseLiquibaseXml(xml) {
|
|
|
23
24
|
filename: "changelog.xml",
|
|
24
25
|
isRepeatable: false,
|
|
25
26
|
statements: allStatements,
|
|
27
|
+
warnings: collectParserWarnings(allStatements),
|
|
26
28
|
};
|
|
27
29
|
}
|
|
28
30
|
function extractChangeSets(xml) {
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Parses Liquibase YAML changelogs and extracts DDL operations
|
|
5
5
|
* compatible with the same DDLStatement interface used by Flyway and XML.
|
|
6
6
|
*/
|
|
7
|
+
import { collectParserWarnings } from "./flyway-sql.js";
|
|
7
8
|
/**
|
|
8
9
|
* Parse a Liquibase YAML changelog and extract DDL statements.
|
|
9
10
|
*
|
|
@@ -23,6 +24,7 @@ export function parseLiquibaseYaml(yaml) {
|
|
|
23
24
|
filename: "changelog.yaml",
|
|
24
25
|
isRepeatable: false,
|
|
25
26
|
statements: allStatements,
|
|
27
|
+
warnings: collectParserWarnings(allStatements),
|
|
26
28
|
};
|
|
27
29
|
}
|
|
28
30
|
function extractChangeSets(yaml) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-migration-advisor",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
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
|
"main": "build/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -20,17 +20,21 @@
|
|
|
20
20
|
],
|
|
21
21
|
"keywords": [
|
|
22
22
|
"mcp",
|
|
23
|
+
"mcp-server",
|
|
23
24
|
"model-context-protocol",
|
|
24
|
-
"
|
|
25
|
+
"ai",
|
|
26
|
+
"claude",
|
|
27
|
+
"anthropic",
|
|
25
28
|
"migration",
|
|
29
|
+
"database-migration",
|
|
30
|
+
"schema-migration",
|
|
31
|
+
"database",
|
|
26
32
|
"flyway",
|
|
27
33
|
"liquibase",
|
|
28
34
|
"schema",
|
|
29
35
|
"risk-analysis",
|
|
30
36
|
"postgresql",
|
|
31
|
-
"mysql"
|
|
32
|
-
"ai",
|
|
33
|
-
"claude"
|
|
37
|
+
"mysql"
|
|
34
38
|
],
|
|
35
39
|
"author": "Dmytro Lisnichenko",
|
|
36
40
|
"license": "MIT",
|