mysql-db-mcp 0.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 +374 -0
- package/dist/config.d.ts +26 -0
- package/dist/config.js +83 -0
- package/dist/config.js.map +1 -0
- package/dist/db/MySqlClient.d.ts +16 -0
- package/dist/db/MySqlClient.js +115 -0
- package/dist/db/MySqlClient.js.map +1 -0
- package/dist/db/MySqlPool.d.ts +3 -0
- package/dist/db/MySqlPool.js +36 -0
- package/dist/db/MySqlPool.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +60 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +6 -0
- package/dist/logger.js +53 -0
- package/dist/logger.js.map +1 -0
- package/dist/security.d.ts +17 -0
- package/dist/security.js +165 -0
- package/dist/security.js.map +1 -0
- package/dist/tools/alterTableAddColumn.d.ts +3 -0
- package/dist/tools/alterTableAddColumn.js +49 -0
- package/dist/tools/alterTableAddColumn.js.map +1 -0
- package/dist/tools/alterTableAddIndex.d.ts +3 -0
- package/dist/tools/alterTableAddIndex.js +46 -0
- package/dist/tools/alterTableAddIndex.js.map +1 -0
- package/dist/tools/alterTableDropColumn.d.ts +3 -0
- package/dist/tools/alterTableDropColumn.js +36 -0
- package/dist/tools/alterTableDropColumn.js.map +1 -0
- package/dist/tools/alterTableDropIndex.d.ts +3 -0
- package/dist/tools/alterTableDropIndex.js +33 -0
- package/dist/tools/alterTableDropIndex.js.map +1 -0
- package/dist/tools/alterTableModifyColumn.d.ts +3 -0
- package/dist/tools/alterTableModifyColumn.js +46 -0
- package/dist/tools/alterTableModifyColumn.js.map +1 -0
- package/dist/tools/alterTableRenameColumn.d.ts +3 -0
- package/dist/tools/alterTableRenameColumn.js +38 -0
- package/dist/tools/alterTableRenameColumn.js.map +1 -0
- package/dist/tools/describeTable.d.ts +3 -0
- package/dist/tools/describeTable.js +18 -0
- package/dist/tools/describeTable.js.map +1 -0
- package/dist/tools/explainSelect.d.ts +3 -0
- package/dist/tools/explainSelect.js +18 -0
- package/dist/tools/explainSelect.js.map +1 -0
- package/dist/tools/insertRow.d.ts +3 -0
- package/dist/tools/insertRow.js +30 -0
- package/dist/tools/insertRow.js.map +1 -0
- package/dist/tools/insertRows.d.ts +3 -0
- package/dist/tools/insertRows.js +40 -0
- package/dist/tools/insertRows.js.map +1 -0
- package/dist/tools/listSchemas.d.ts +3 -0
- package/dist/tools/listSchemas.js +7 -0
- package/dist/tools/listSchemas.js.map +1 -0
- package/dist/tools/listTables.d.ts +3 -0
- package/dist/tools/listTables.js +16 -0
- package/dist/tools/listTables.js.map +1 -0
- package/dist/tools/querySelect.d.ts +3 -0
- package/dist/tools/querySelect.js +20 -0
- package/dist/tools/querySelect.js.map +1 -0
- package/dist/tools/shared.d.ts +43 -0
- package/dist/tools/shared.js +113 -0
- package/dist/tools/shared.js.map +1 -0
- package/package.json +41 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { assertDDLEnabled, assertIdentifier, quoteIdentifier } from "../security.js";
|
|
3
|
+
import { assertAndQuoteDDLTarget, resolveSchema, runTool } from "./shared.js";
|
|
4
|
+
export function registerAlterTableRenameColumnTool(server, client) {
|
|
5
|
+
server.tool("alter_table_rename_column", "Rename a column using MySQL 8.0 RENAME COLUMN syntax. This high-risk DDL always requires confirm: true.", {
|
|
6
|
+
schema: z.string().optional(),
|
|
7
|
+
table: z.string(),
|
|
8
|
+
oldColumnName: z.string(),
|
|
9
|
+
newColumnName: z.string(),
|
|
10
|
+
confirm: z.boolean()
|
|
11
|
+
}, async (args) => runTool(async () => {
|
|
12
|
+
assertDDLEnabled(args.confirm, true);
|
|
13
|
+
const schemaName = resolveSchema(args.schema);
|
|
14
|
+
assertIdentifier(args.table, "table");
|
|
15
|
+
assertIdentifier(args.oldColumnName, "oldColumnName");
|
|
16
|
+
assertIdentifier(args.newColumnName, "newColumnName");
|
|
17
|
+
const tableSql = assertAndQuoteDDLTarget(schemaName, args.table);
|
|
18
|
+
if (!(await client.columnExists(schemaName, args.table, args.oldColumnName))) {
|
|
19
|
+
throw new Error(`oldColumnName '${args.oldColumnName}' does not exist.`);
|
|
20
|
+
}
|
|
21
|
+
if (await client.columnExists(schemaName, args.table, args.newColumnName)) {
|
|
22
|
+
throw new Error(`newColumnName '${args.newColumnName}' already exists.`);
|
|
23
|
+
}
|
|
24
|
+
if (await client.isPrimaryKeyColumn(schemaName, args.table, args.oldColumnName)) {
|
|
25
|
+
throw new Error("Refusing to rename primary key columns.");
|
|
26
|
+
}
|
|
27
|
+
const executedSqlTemplate = `ALTER TABLE ${tableSql} RENAME COLUMN ${quoteIdentifier(args.oldColumnName)} TO ${quoteIdentifier(args.newColumnName)}`;
|
|
28
|
+
const result = await client.execute(executedSqlTemplate);
|
|
29
|
+
return {
|
|
30
|
+
affectedRows: result.affectedRows,
|
|
31
|
+
schemaName,
|
|
32
|
+
tableName: args.table,
|
|
33
|
+
operation: "rename_column",
|
|
34
|
+
executedSqlTemplate
|
|
35
|
+
};
|
|
36
|
+
}));
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=alterTableRenameColumn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alterTableRenameColumn.js","sourceRoot":"","sources":["../../src/tools/alterTableRenameColumn.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACrF,OAAO,EAAE,uBAAuB,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE9E,MAAM,UAAU,kCAAkC,CAAC,MAAiB,EAAE,MAAmB;IACvF,MAAM,CAAC,IAAI,CACT,2BAA2B,EAC3B,yGAAyG,EACzG;QACE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC7B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;QACjB,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE;QACzB,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE;QACzB,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;KACrB,EACD,KAAK,EAAE,IAAI,EAAE,EAAE,CACb,OAAO,CAAC,KAAK,IAAI,EAAE;QACjB,gBAAgB,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACrC,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC9C,gBAAgB,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACtC,gBAAgB,CAAC,IAAI,CAAC,aAAa,EAAE,eAAe,CAAC,CAAC;QACtD,gBAAgB,CAAC,IAAI,CAAC,aAAa,EAAE,eAAe,CAAC,CAAC;QACtD,MAAM,QAAQ,GAAG,uBAAuB,CAAC,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QACjE,IAAI,CAAC,CAAC,MAAM,MAAM,CAAC,YAAY,CAAC,UAAU,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC;YAC7E,MAAM,IAAI,KAAK,CAAC,kBAAkB,IAAI,CAAC,aAAa,mBAAmB,CAAC,CAAC;QAC3E,CAAC;QACD,IAAI,MAAM,MAAM,CAAC,YAAY,CAAC,UAAU,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC;YAC1E,MAAM,IAAI,KAAK,CAAC,kBAAkB,IAAI,CAAC,aAAa,mBAAmB,CAAC,CAAC;QAC3E,CAAC;QACD,IAAI,MAAM,MAAM,CAAC,kBAAkB,CAAC,UAAU,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC;YAChF,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;QAC7D,CAAC;QAED,MAAM,mBAAmB,GAAG,eAAe,QAAQ,kBAAkB,eAAe,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,eAAe,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC;QACrJ,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;QACzD,OAAO;YACL,YAAY,EAAE,MAAM,CAAC,YAAY;YACjC,UAAU;YACV,SAAS,EAAE,IAAI,CAAC,KAAK;YACrB,SAAS,EAAE,eAAe;YAC1B,mBAAmB;SACpB,CAAC;IACJ,CAAC,CAAC,CACL,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { assertIdentifier } from "../security.js";
|
|
3
|
+
import { resolveSchema, runTool } from "./shared.js";
|
|
4
|
+
export function registerDescribeTableTool(server, client) {
|
|
5
|
+
server.tool("describe_table", "Describe columns for a table using INFORMATION_SCHEMA.COLUMNS.", {
|
|
6
|
+
schema: z.string().optional().describe("Schema name. Defaults to MYSQL_DATABASE."),
|
|
7
|
+
table: z.string().describe("Table name.")
|
|
8
|
+
}, async (args) => runTool(async () => {
|
|
9
|
+
const schemaName = resolveSchema(args.schema);
|
|
10
|
+
assertIdentifier(args.table, "table");
|
|
11
|
+
return {
|
|
12
|
+
schemaName,
|
|
13
|
+
tableName: args.table,
|
|
14
|
+
columns: await client.describeTable(schemaName, args.table)
|
|
15
|
+
};
|
|
16
|
+
}));
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=describeTable.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"describeTable.js","sourceRoot":"","sources":["../../src/tools/describeTable.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAErD,MAAM,UAAU,yBAAyB,CAAC,MAAiB,EAAE,MAAmB;IAC9E,MAAM,CAAC,IAAI,CACT,gBAAgB,EAChB,gEAAgE,EAChE;QACE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,0CAA0C,CAAC;QAClF,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC;KAC1C,EACD,KAAK,EAAE,IAAI,EAAE,EAAE,CACb,OAAO,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC9C,gBAAgB,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACtC,OAAO;YACL,UAAU;YACV,SAAS,EAAE,IAAI,CAAC,KAAK;YACrB,OAAO,EAAE,MAAM,MAAM,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC;SAC5D,CAAC;IACJ,CAAC,CAAC,CACL,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { assertSafeExplainSql, validateSqlValue } from "../security.js";
|
|
3
|
+
import { primitiveValueSchema, runTool } from "./shared.js";
|
|
4
|
+
export function registerExplainSelectTool(server, client) {
|
|
5
|
+
server.tool("explain_select", "Run EXPLAIN for a single SELECT query.", {
|
|
6
|
+
sql: z.string().describe("A single SELECT statement without semicolons."),
|
|
7
|
+
params: z.array(primitiveValueSchema).optional().describe("Parameter values for ? placeholders.")
|
|
8
|
+
}, async (args) => runTool(async () => {
|
|
9
|
+
assertSafeExplainSql(args.sql);
|
|
10
|
+
const params = (args.params ?? []).map((value, index) => validateSqlValue(value, `params[${index}]`));
|
|
11
|
+
const executedSqlTemplate = `EXPLAIN ${args.sql.trim()}`;
|
|
12
|
+
return {
|
|
13
|
+
executedSqlTemplate,
|
|
14
|
+
plan: await client.queryRows(executedSqlTemplate, params)
|
|
15
|
+
};
|
|
16
|
+
}));
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=explainSelect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"explainSelect.js","sourceRoot":"","sources":["../../src/tools/explainSelect.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACxE,OAAO,EAAE,oBAAoB,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE5D,MAAM,UAAU,yBAAyB,CAAC,MAAiB,EAAE,MAAmB;IAC9E,MAAM,CAAC,IAAI,CACT,gBAAgB,EAChB,wCAAwC,EACxC;QACE,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,+CAA+C,CAAC;QACzE,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sCAAsC,CAAC;KAClG,EACD,KAAK,EAAE,IAAI,EAAE,EAAE,CACb,OAAO,CAAC,KAAK,IAAI,EAAE;QACjB,oBAAoB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC/B,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,gBAAgB,CAAC,KAAK,EAAE,UAAU,KAAK,GAAG,CAAC,CAAiB,CAAC;QACtH,MAAM,mBAAmB,GAAG,WAAW,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;QACzD,OAAO;YACL,mBAAmB;YACnB,IAAI,EAAE,MAAM,MAAM,CAAC,SAAS,CAAC,mBAAmB,EAAE,MAAM,CAAC;SAC1D,CAAC;IACJ,CAAC,CAAC,CACL,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { assertIdentifier, assertWriteEnabled, quoteIdentifier } from "../security.js";
|
|
3
|
+
import { assertAndQuoteWriteTarget, dataRecordSchema, normalizeInsertRecord, resolveSchema, runTool } from "./shared.js";
|
|
4
|
+
export function registerInsertRowTool(server, client) {
|
|
5
|
+
server.tool("insert_row", "Insert one row using structured parameters. Disabled unless MYSQL_ENABLE_WRITE=true.", {
|
|
6
|
+
schema: z.string().optional().describe("Schema name. Defaults to MYSQL_DATABASE."),
|
|
7
|
+
table: z.string().describe("Table name."),
|
|
8
|
+
data: dataRecordSchema.describe("Column/value object for one row."),
|
|
9
|
+
confirm: z.boolean().optional().describe("Must be true when MYSQL_REQUIRE_CONFIRMATION=true.")
|
|
10
|
+
}, async (args) => runTool(async () => {
|
|
11
|
+
assertWriteEnabled(args.confirm);
|
|
12
|
+
const schemaName = resolveSchema(args.schema);
|
|
13
|
+
assertIdentifier(args.table, "table");
|
|
14
|
+
const tableSql = assertAndQuoteWriteTarget(schemaName, args.table);
|
|
15
|
+
const { columns, values } = normalizeInsertRecord(args.data);
|
|
16
|
+
const columnSql = columns.map((column) => quoteIdentifier(column)).join(", ");
|
|
17
|
+
const placeholders = columns.map(() => "?").join(", ");
|
|
18
|
+
const executedSqlTemplate = `INSERT INTO ${tableSql} (${columnSql}) VALUES (${placeholders})`;
|
|
19
|
+
const result = await client.execute(executedSqlTemplate, values);
|
|
20
|
+
return {
|
|
21
|
+
affectedRows: result.affectedRows,
|
|
22
|
+
insertId: result.insertId,
|
|
23
|
+
schemaName,
|
|
24
|
+
tableName: args.table,
|
|
25
|
+
columns,
|
|
26
|
+
executedSqlTemplate
|
|
27
|
+
};
|
|
28
|
+
}));
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=insertRow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"insertRow.js","sourceRoot":"","sources":["../../src/tools/insertRow.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACvF,OAAO,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEzH,MAAM,UAAU,qBAAqB,CAAC,MAAiB,EAAE,MAAmB;IAC1E,MAAM,CAAC,IAAI,CACT,YAAY,EACZ,sFAAsF,EACtF;QACE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,0CAA0C,CAAC;QAClF,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC;QACzC,IAAI,EAAE,gBAAgB,CAAC,QAAQ,CAAC,kCAAkC,CAAC;QACnE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oDAAoD,CAAC;KAC/F,EACD,KAAK,EAAE,IAAI,EAAE,EAAE,CACb,OAAO,CAAC,KAAK,IAAI,EAAE;QACjB,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACjC,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC9C,gBAAgB,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACtC,MAAM,QAAQ,GAAG,yBAAyB,CAAC,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QACnE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7D,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9E,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvD,MAAM,mBAAmB,GAAG,eAAe,QAAQ,KAAK,SAAS,aAAa,YAAY,GAAG,CAAC;QAC9F,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC;QACjE,OAAO;YACL,YAAY,EAAE,MAAM,CAAC,YAAY;YACjC,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,UAAU;YACV,SAAS,EAAE,IAAI,CAAC,KAAK;YACrB,OAAO;YACP,mBAAmB;SACpB,CAAC;IACJ,CAAC,CAAC,CACL,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { config } from "../config.js";
|
|
3
|
+
import { assertIdentifier, assertWriteEnabled, quoteIdentifier, validateSqlValue } from "../security.js";
|
|
4
|
+
import { assertAndQuoteWriteTarget, assertSameColumns, dataRecordSchema, resolveSchema, runTool } from "./shared.js";
|
|
5
|
+
export function registerInsertRowsTool(server, client) {
|
|
6
|
+
server.tool("insert_rows", "Insert multiple rows with one structured INSERT statement. Disabled unless MYSQL_ENABLE_WRITE=true.", {
|
|
7
|
+
schema: z.string().optional().describe("Schema name. Defaults to MYSQL_DATABASE."),
|
|
8
|
+
table: z.string().describe("Table name."),
|
|
9
|
+
rows: z.array(dataRecordSchema).describe("Array of row objects. All rows must have identical fields."),
|
|
10
|
+
confirm: z.boolean().optional().describe("Must be true when MYSQL_REQUIRE_CONFIRMATION=true.")
|
|
11
|
+
}, async (args) => runTool(async () => {
|
|
12
|
+
assertWriteEnabled(args.confirm);
|
|
13
|
+
if (args.rows.length === 0) {
|
|
14
|
+
throw new Error("rows cannot be empty.");
|
|
15
|
+
}
|
|
16
|
+
if (args.rows.length > config.security.maxInsertRows) {
|
|
17
|
+
throw new Error(`rows cannot exceed MYSQL_MAX_INSERT_ROWS (${config.security.maxInsertRows}).`);
|
|
18
|
+
}
|
|
19
|
+
const schemaName = resolveSchema(args.schema);
|
|
20
|
+
assertIdentifier(args.table, "table");
|
|
21
|
+
const tableSql = assertAndQuoteWriteTarget(schemaName, args.table);
|
|
22
|
+
const columns = assertSameColumns(args.rows);
|
|
23
|
+
const columnSql = columns.map((column) => quoteIdentifier(column)).join(", ");
|
|
24
|
+
const rowPlaceholder = `(${columns.map(() => "?").join(", ")})`;
|
|
25
|
+
const placeholders = args.rows.map(() => rowPlaceholder).join(", ");
|
|
26
|
+
const values = args.rows.flatMap((row, rowIndex) => columns.map((column) => validateSqlValue(row[column], `rows[${rowIndex}].${column}`)));
|
|
27
|
+
const executedSqlTemplate = `INSERT INTO ${tableSql} (${columnSql}) VALUES ${placeholders}`;
|
|
28
|
+
const result = await client.execute(executedSqlTemplate, values);
|
|
29
|
+
return {
|
|
30
|
+
affectedRows: result.affectedRows,
|
|
31
|
+
insertId: result.insertId,
|
|
32
|
+
schemaName,
|
|
33
|
+
tableName: args.table,
|
|
34
|
+
rowCount: args.rows.length,
|
|
35
|
+
columns,
|
|
36
|
+
executedSqlTemplate
|
|
37
|
+
};
|
|
38
|
+
}));
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=insertRows.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"insertRows.js","sourceRoot":"","sources":["../../src/tools/insertRows.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { runTool } from "./shared.js";
|
|
2
|
+
export function registerListSchemasTool(server, client) {
|
|
3
|
+
server.tool("list_schemas", "List non-system MySQL schemas.", {}, async () => runTool(async () => ({
|
|
4
|
+
schemas: await client.listSchemas()
|
|
5
|
+
})));
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=listSchemas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"listSchemas.js","sourceRoot":"","sources":["../../src/tools/listSchemas.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC,MAAM,UAAU,uBAAuB,CAAC,MAAiB,EAAE,MAAmB;IAC5E,MAAM,CAAC,IAAI,CACT,cAAc,EACd,gCAAgC,EAChC,EAAE,EACF,KAAK,IAAI,EAAE,CACT,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;QACnB,OAAO,EAAE,MAAM,MAAM,CAAC,WAAW,EAAE;KACpC,CAAC,CAAC,CACN,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { assertIdentifier } from "../security.js";
|
|
3
|
+
import { resolveSchema, runTool } from "./shared.js";
|
|
4
|
+
export function registerListTablesTool(server, client) {
|
|
5
|
+
server.tool("list_tables", "List tables in a MySQL schema using INFORMATION_SCHEMA.", {
|
|
6
|
+
schema: z.string().optional().describe("Schema name. Defaults to MYSQL_DATABASE.")
|
|
7
|
+
}, async (args) => runTool(async () => {
|
|
8
|
+
const schemaName = resolveSchema(args.schema);
|
|
9
|
+
assertIdentifier(schemaName, "schema");
|
|
10
|
+
return {
|
|
11
|
+
schemaName,
|
|
12
|
+
tables: await client.listTables(schemaName)
|
|
13
|
+
};
|
|
14
|
+
}));
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=listTables.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"listTables.js","sourceRoot":"","sources":["../../src/tools/listTables.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAErD,MAAM,UAAU,sBAAsB,CAAC,MAAiB,EAAE,MAAmB;IAC3E,MAAM,CAAC,IAAI,CACT,aAAa,EACb,yDAAyD,EACzD;QACE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,0CAA0C,CAAC;KACnF,EACD,KAAK,EAAE,IAAI,EAAE,EAAE,CACb,OAAO,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC9C,gBAAgB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QACvC,OAAO;YACL,UAAU;YACV,MAAM,EAAE,MAAM,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC;SAC5C,CAAC;IACJ,CAAC,CAAC,CACL,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { config } from "../config.js";
|
|
3
|
+
import { assertSafeSelectSql, validateSqlValue } from "../security.js";
|
|
4
|
+
import { primitiveValueSchema, runTool } from "./shared.js";
|
|
5
|
+
export function registerQuerySelectTool(server, client) {
|
|
6
|
+
server.tool("query_select", "Execute a single read-only SELECT query. Mutating statements and multi statements are blocked.", {
|
|
7
|
+
sql: z.string().describe("A single SELECT statement without semicolons."),
|
|
8
|
+
params: z.array(primitiveValueSchema).optional().describe("Parameter values for ? placeholders.")
|
|
9
|
+
}, async (args) => runTool(async () => {
|
|
10
|
+
assertSafeSelectSql(args.sql);
|
|
11
|
+
const params = (args.params ?? []).map((value, index) => validateSqlValue(value, `params[${index}]`));
|
|
12
|
+
const rows = await client.queryRows(args.sql, params);
|
|
13
|
+
return {
|
|
14
|
+
rowCount: rows.length,
|
|
15
|
+
maxRows: config.mysql.maxRows,
|
|
16
|
+
rows
|
|
17
|
+
};
|
|
18
|
+
}));
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=querySelect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"querySelect.js","sourceRoot":"","sources":["../../src/tools/querySelect.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE5D,MAAM,UAAU,uBAAuB,CAAC,MAAiB,EAAE,MAAmB;IAC5E,MAAM,CAAC,IAAI,CACT,cAAc,EACd,gGAAgG,EAChG;QACE,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,+CAA+C,CAAC;QACzE,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sCAAsC,CAAC;KAClG,EACD,KAAK,EAAE,IAAI,EAAE,EAAE,CACb,OAAO,CAAC,KAAK,IAAI,EAAE;QACjB,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9B,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,gBAAgB,CAAC,KAAK,EAAE,UAAU,KAAK,GAAG,CAAC,CAAiB,CAAC;QACtH,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACtD,OAAO;YACL,QAAQ,EAAE,IAAI,CAAC,MAAM;YACrB,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO;YAC7B,IAAI;SACL,CAAC;IACJ,CAAC,CAAC,CACL,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { type SafeSqlValue } from "../security.js";
|
|
3
|
+
export declare const primitiveValueSchema: z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>;
|
|
4
|
+
export declare const dataRecordSchema: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
5
|
+
export declare function jsonContent(value: unknown): {
|
|
6
|
+
content: {
|
|
7
|
+
type: "text";
|
|
8
|
+
text: string;
|
|
9
|
+
}[];
|
|
10
|
+
};
|
|
11
|
+
export declare function errorContent(error: unknown): {
|
|
12
|
+
isError: boolean;
|
|
13
|
+
content: {
|
|
14
|
+
type: "text";
|
|
15
|
+
text: string;
|
|
16
|
+
}[];
|
|
17
|
+
};
|
|
18
|
+
export declare function runTool(handler: () => Promise<unknown> | unknown): Promise<{
|
|
19
|
+
content: {
|
|
20
|
+
type: "text";
|
|
21
|
+
text: string;
|
|
22
|
+
}[];
|
|
23
|
+
}>;
|
|
24
|
+
export declare function resolveSchema(schema: string | undefined): string;
|
|
25
|
+
export declare function assertReadTarget(schema: string, table?: string): void;
|
|
26
|
+
export declare function assertAndQuoteWriteTarget(schema: string, table: string): string;
|
|
27
|
+
export declare function assertAndQuoteDDLTarget(schema: string, table: string): string;
|
|
28
|
+
export declare function normalizeInsertRecord(data: Record<string, unknown>): {
|
|
29
|
+
columns: string[];
|
|
30
|
+
values: SafeSqlValue[];
|
|
31
|
+
};
|
|
32
|
+
export declare function assertSameColumns(rows: readonly Record<string, unknown>[]): string[];
|
|
33
|
+
export declare function buildColumnDefinition(args: {
|
|
34
|
+
columnName: string;
|
|
35
|
+
columnType: string;
|
|
36
|
+
nullable?: boolean;
|
|
37
|
+
defaultValue?: string | number | boolean | null;
|
|
38
|
+
hasDefaultValue: boolean;
|
|
39
|
+
comment?: string;
|
|
40
|
+
}): {
|
|
41
|
+
sql: string;
|
|
42
|
+
params: SafeSqlValue[];
|
|
43
|
+
};
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { defaultSchema } from "../config.js";
|
|
3
|
+
import { assertDDLTarget, assertIdentifier, assertWriteTarget, quoteIdentifier, quoteQualifiedTable, validateComment, validateSqlValue } from "../security.js";
|
|
4
|
+
export const primitiveValueSchema = z.union([z.string(), z.number(), z.boolean(), z.null()]);
|
|
5
|
+
export const dataRecordSchema = z.record(z.unknown());
|
|
6
|
+
export function jsonContent(value) {
|
|
7
|
+
return {
|
|
8
|
+
content: [
|
|
9
|
+
{
|
|
10
|
+
type: "text",
|
|
11
|
+
text: JSON.stringify(value, null, 2)
|
|
12
|
+
}
|
|
13
|
+
]
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export function errorContent(error) {
|
|
17
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
18
|
+
return {
|
|
19
|
+
isError: true,
|
|
20
|
+
content: [
|
|
21
|
+
{
|
|
22
|
+
type: "text",
|
|
23
|
+
text: JSON.stringify({ error: message }, null, 2)
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export async function runTool(handler) {
|
|
29
|
+
try {
|
|
30
|
+
return jsonContent(await handler());
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
return errorContent(error);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export function resolveSchema(schema) {
|
|
37
|
+
const schemaName = schema ?? defaultSchema();
|
|
38
|
+
assertIdentifier(schemaName, "schema");
|
|
39
|
+
return schemaName;
|
|
40
|
+
}
|
|
41
|
+
export function assertReadTarget(schema, table) {
|
|
42
|
+
assertIdentifier(schema, "schema");
|
|
43
|
+
if (table !== undefined) {
|
|
44
|
+
assertIdentifier(table, "table");
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export function assertAndQuoteWriteTarget(schema, table) {
|
|
48
|
+
assertWriteTarget(schema, table);
|
|
49
|
+
return quoteQualifiedTable(schema, table);
|
|
50
|
+
}
|
|
51
|
+
export function assertAndQuoteDDLTarget(schema, table) {
|
|
52
|
+
assertDDLTarget(schema, table);
|
|
53
|
+
return quoteQualifiedTable(schema, table);
|
|
54
|
+
}
|
|
55
|
+
export function normalizeInsertRecord(data) {
|
|
56
|
+
const columns = Object.keys(data);
|
|
57
|
+
if (columns.length === 0) {
|
|
58
|
+
throw new Error("data cannot be empty.");
|
|
59
|
+
}
|
|
60
|
+
const values = columns.map((column) => {
|
|
61
|
+
assertIdentifier(column, "column");
|
|
62
|
+
return validateSqlValue(data[column], `data.${column}`);
|
|
63
|
+
});
|
|
64
|
+
return { columns, values };
|
|
65
|
+
}
|
|
66
|
+
export function assertSameColumns(rows) {
|
|
67
|
+
if (rows.length === 0) {
|
|
68
|
+
throw new Error("rows cannot be empty.");
|
|
69
|
+
}
|
|
70
|
+
const columns = Object.keys(rows[0] ?? {});
|
|
71
|
+
if (columns.length === 0) {
|
|
72
|
+
throw new Error("rows cannot contain empty objects.");
|
|
73
|
+
}
|
|
74
|
+
const signature = columns.join("\u0000");
|
|
75
|
+
for (const [index, row] of rows.entries()) {
|
|
76
|
+
const rowColumns = Object.keys(row);
|
|
77
|
+
if (rowColumns.length === 0) {
|
|
78
|
+
throw new Error(`rows[${index}] cannot be empty.`);
|
|
79
|
+
}
|
|
80
|
+
if (rowColumns.join("\u0000") !== signature) {
|
|
81
|
+
throw new Error("All rows must have the same field set in the same order.");
|
|
82
|
+
}
|
|
83
|
+
for (const column of rowColumns) {
|
|
84
|
+
assertIdentifier(column, "column");
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return columns;
|
|
88
|
+
}
|
|
89
|
+
export function buildColumnDefinition(args) {
|
|
90
|
+
assertIdentifier(args.columnName, "columnName");
|
|
91
|
+
const nullableSql = args.nullable === false ? "NOT NULL" : "NULL";
|
|
92
|
+
const params = [];
|
|
93
|
+
const pieces = [quoteIdentifier(args.columnName), args.columnType, nullableSql];
|
|
94
|
+
if (args.hasDefaultValue) {
|
|
95
|
+
if (args.defaultValue === null) {
|
|
96
|
+
pieces.push("DEFAULT NULL");
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
pieces.push("DEFAULT ?");
|
|
100
|
+
params.push(validateSqlValue(args.defaultValue, "defaultValue"));
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const comment = validateComment(args.comment);
|
|
104
|
+
if (comment !== undefined) {
|
|
105
|
+
pieces.push("COMMENT ?");
|
|
106
|
+
params.push(comment);
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
sql: pieces.join(" "),
|
|
110
|
+
params
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/tools/shared.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAEjB,MAAM,gBAAgB,CAAC;AAExB,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;AAC7F,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;AAEtD,MAAM,UAAU,WAAW,CAAC,KAAc;IACxC,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAe;gBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;aACrC;SACF;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,OAAO;QACL,OAAO,EAAE,IAAI;QACb,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAe;gBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;aAClD;SACF;KACF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,OAAyC;IACrE,IAAI,CAAC;QACH,OAAO,WAAW,CAAC,MAAM,OAAO,EAAE,CAAC,CAAC;IACtC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAA0B;IACtD,MAAM,UAAU,GAAG,MAAM,IAAI,aAAa,EAAE,CAAC;IAC7C,gBAAgB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IACvC,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAc,EAAE,KAAc;IAC7D,gBAAgB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACnC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,gBAAgB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACnC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,MAAc,EAAE,KAAa;IACrE,iBAAiB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACjC,OAAO,mBAAmB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,MAAc,EAAE,KAAa;IACnE,eAAe,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC/B,OAAO,mBAAmB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,IAA6B;IAIjE,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAC3C,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QACpC,gBAAgB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QACnC,OAAO,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,QAAQ,MAAM,EAAE,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAwC;IACxE,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAC3C,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IAC3C,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;IACxD,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACzC,KAAK,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;QAC1C,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,QAAQ,KAAK,oBAAoB,CAAC,CAAC;QACrD,CAAC;QAED,IAAI,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,SAAS,EAAE,CAAC;YAC5C,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;QAC9E,CAAC;QAED,KAAK,MAAM,MAAM,IAAI,UAAU,EAAE,CAAC;YAChC,gBAAgB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,IAOrC;IACC,gBAAgB,CAAC,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;IAChD,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC;IAClE,MAAM,MAAM,GAAmB,EAAE,CAAC;IAClC,MAAM,MAAM,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;IAEhF,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,YAAY,KAAK,IAAI,EAAE,CAAC;YAC/B,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC9B,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YACzB,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC,CAAC;QACnE,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9C,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACzB,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACvB,CAAC;IAED,OAAO;QACL,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;QACrB,MAAM;KACP,CAAC;AACJ,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "mysql-db-mcp",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A secure MySQL MCP server with read-only defaults, structured inserts, and guarded DDL tools.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"mysql-db-mcp": "./dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"README.md"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"dev": "tsx src/index.ts",
|
|
15
|
+
"build": "tsc",
|
|
16
|
+
"postbuild": "node -e \"require('fs').chmodSync('dist/index.js', 0o755)\"",
|
|
17
|
+
"start": "node dist/index.js",
|
|
18
|
+
"prepublishOnly": "npm run build"
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"mcp",
|
|
22
|
+
"mysql",
|
|
23
|
+
"database",
|
|
24
|
+
"model-context-protocol"
|
|
25
|
+
],
|
|
26
|
+
"author": "",
|
|
27
|
+
"license": "MIT",
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@modelcontextprotocol/sdk": "^1.13.2",
|
|
30
|
+
"mysql2": "^3.11.5",
|
|
31
|
+
"zod": "^3.25.67"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/node": "^22.10.2",
|
|
35
|
+
"tsx": "^4.19.2",
|
|
36
|
+
"typescript": "^5.7.2"
|
|
37
|
+
},
|
|
38
|
+
"engines": {
|
|
39
|
+
"node": ">=18"
|
|
40
|
+
}
|
|
41
|
+
}
|