xampp-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.
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,52 @@
1
+ import { executeMysqlSql } from "../runtime/mysqlClient.js";
2
+ import { toToolTextResult } from "../runtime/errors.js";
3
+ import { getBoolean, getOptionalString, getString } from "../runtime/validators.js";
4
+ import { assertHost, assertUsername, escapeSqlLiteral, requireConfirmation, } from "../security/policy.js";
5
+ import { mysqlConnectionFromArgs } from "./shared.js";
6
+ export function createUserCreateTool(environment) {
7
+ return {
8
+ name: "user_create",
9
+ description: "Creates a MySQL user",
10
+ inputSchema: {
11
+ type: "object",
12
+ properties: {
13
+ username: { type: "string" },
14
+ hostScope: { type: "string", description: "Host scope for the user. Example: localhost or %" },
15
+ userPassword: { type: "string", description: "Password for the user being created" },
16
+ ifNotExists: { type: "boolean" },
17
+ confirmed: { type: "boolean" },
18
+ host: { type: "string" },
19
+ port: { type: "number" },
20
+ user: { type: "string" },
21
+ password: { type: "string", description: "Admin password used to run CREATE USER" },
22
+ },
23
+ required: ["username", "userPassword", "confirmed"],
24
+ additionalProperties: false,
25
+ },
26
+ annotations: {
27
+ title: "Create User",
28
+ destructiveHint: true,
29
+ openWorldHint: false,
30
+ },
31
+ handler: async (args) => {
32
+ const username = getString(args.username, "username");
33
+ const userPassword = getString(args.userPassword, "userPassword");
34
+ const hostScope = getOptionalString(args.hostScope, "hostScope") ?? "%";
35
+ const ifNotExists = getBoolean(args.ifNotExists, "ifNotExists", true);
36
+ const confirmed = getBoolean(args.confirmed, "confirmed");
37
+ requireConfirmation(confirmed, "user_create");
38
+ assertUsername(username);
39
+ assertHost(hostScope);
40
+ const sql = `CREATE USER ${ifNotExists ? "IF NOT EXISTS " : ""}${escapeSqlLiteral(username)}@${escapeSqlLiteral(hostScope)} IDENTIFIED BY ${escapeSqlLiteral(userPassword)}`;
41
+ await executeMysqlSql(environment, {
42
+ ...mysqlConnectionFromArgs(args),
43
+ sql,
44
+ });
45
+ return toToolTextResult(`User ${username}@${hostScope} created`, {
46
+ username,
47
+ hostScope,
48
+ ifNotExists,
49
+ });
50
+ },
51
+ };
52
+ }
package/docs/tools.md ADDED
@@ -0,0 +1,221 @@
1
+ # Tools disponibles
2
+
3
+ ## preflight_check
4
+ Valida rutas críticas de XAMPP y estado de puertos.
5
+
6
+ Input:
7
+ - `apachePort?: number` (default `80`)
8
+ - `mysqlPort?: number` (default `3306`)
9
+
10
+ ## stack_status
11
+ Muestra estado de procesos (`httpd.exe`, `mysqld.exe`) y servicios Windows.
12
+
13
+ Si detecta módulos apagados, devuelve recomendaciones para que el usuario los active manualmente en XAMPP Control Panel y confirme cuando estén listos.
14
+ No debe iniciar módulos automáticamente por terminal.
15
+
16
+ Input: ninguno.
17
+
18
+ ## Política cuando MySQL está apagado
19
+
20
+ Las tools de base de datos (`db_create`, `query_execute`, `db_import`, `db_export`, etc.) devuelven un error guiado cuando MySQL no es alcanzable.
21
+
22
+ Flujo esperado:
23
+ - Pedir al usuario que abra XAMPP Control Panel.
24
+ - Pedir que inicie MySQL manualmente.
25
+ - Esperar confirmación del usuario.
26
+ - Reintentar la operación.
27
+
28
+ No ejecutar `mysql_start.bat` automáticamente.
29
+
30
+ ## Reglas de validación (nombres)
31
+
32
+ Política aplicada: usar `snake_case` (letras, números y `_`) y **no usar `-`**.
33
+
34
+ Hay dos validadores de identificadores (misma regla práctica):
35
+
36
+ - **Base de datos**
37
+ - Debe empezar por letra o `_`
38
+ - Permite letras, números y `_`
39
+ - **Tabla**
40
+ - Debe empezar por letra o `_`
41
+ - Permite letras, números y `_`
42
+
43
+ Campos de **base de datos** (no aceptan `-`):
44
+ - `db_create.database`
45
+ - `db_inspect.database`
46
+ - `db_export.database`
47
+ - `db_import.database`
48
+ - `grant_manage.database`
49
+ - `table_create.database`
50
+
51
+ Campos de **tabla** (no aceptan `-`):
52
+ - `table_create.table`
53
+
54
+ ### Ejemplo válido para `db_create`
55
+
56
+ ```json
57
+ {
58
+ "database": "mcp_test_2026",
59
+ "ifNotExists": true,
60
+ "confirmed": true
61
+ }
62
+ ```
63
+
64
+ ### Ejemplo que falla en `db_create.database`
65
+
66
+ ```json
67
+ {
68
+ "database": "database-example-2026",
69
+ "ifNotExists": true,
70
+ "confirmed": true
71
+ }
72
+ ```
73
+
74
+ Sugerencia esperada: `database_example_2026`.
75
+
76
+ ## Política de codificación de texto (UTF-8)
77
+
78
+ - El MCP usa UTF-8 (`utf8mb4`) para conexión SQL y export/import.
79
+ - Antes de ejecutar SQL, el MCP fuerza `SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci` en la sesión.
80
+ - `db_create` crea la base con `CHARACTER SET utf8mb4` y `COLLATE utf8mb4_unicode_ci`.
81
+ - No se debe "detectar idioma" para cambiar encoding: español e inglés usan la misma política UTF-8.
82
+ - Si el contenido lleva tildes (`á`, `é`, `ñ`), se debe guardar tal cual; no remover ni normalizar caracteres.
83
+
84
+ Ejemplo recomendado de texto:
85
+ - Español: `José Núñez - información pública`
86
+ - Inglés: `John Smith - public information`
87
+
88
+ ### Ejemplo que falla en `table_create.table`
89
+
90
+ ```json
91
+ {
92
+ "database": "mcp_test_2026",
93
+ "table": "items-test",
94
+ "createStatement": "CREATE TABLE `items-test` (id INT)",
95
+ "confirmed": true
96
+ }
97
+ ```
98
+
99
+ ## query_readonly
100
+ Ejecuta solo consultas `SELECT`, `SHOW`, `DESCRIBE`, `EXPLAIN`.
101
+
102
+ Input:
103
+ - `sql: string`
104
+ - `database?: string`
105
+ - `host?: string`
106
+ - `port?: number`
107
+ - `user?: string`
108
+ - `password?: string`
109
+
110
+ ## query_execute
111
+ Ejecuta SQL general con capacidad de escritura (`INSERT`, `UPDATE`, `DELETE`, DDL).
112
+
113
+ Input:
114
+ - `sql: string`
115
+ - `confirmed: boolean`
116
+ - `database?: string`
117
+ - `host?: string`
118
+ - `port?: number`
119
+ - `user?: string`
120
+ - `password?: string`
121
+
122
+ ## db_inspect
123
+ Muestra estado de una base de datos con resumen y detalle de tablas.
124
+
125
+ Input:
126
+ - `database: string`
127
+ - `host?: string`
128
+ - `port?: number`
129
+ - `user?: string`
130
+ - `password?: string`
131
+
132
+ ## db_create
133
+ Crea una base de datos.
134
+
135
+ Input:
136
+ - `database: string`
137
+ - `ifNotExists?: boolean` (default `true`)
138
+ - `confirmed: boolean`
139
+ - `host?: string`
140
+ - `port?: number`
141
+ - `user?: string`
142
+ - `password?: string`
143
+
144
+ ## table_create
145
+ Crea una tabla con sentencia `CREATE TABLE`.
146
+
147
+ Validaciones adicionales:
148
+ - `createStatement` debe empezar con `CREATE TABLE`.
149
+ - `createStatement` debe apuntar a la misma tabla indicada en `table`.
150
+
151
+ Input:
152
+ - `database: string`
153
+ - `table: string`
154
+ - `createStatement: string`
155
+ - `confirmed: boolean`
156
+ - `host?: string`
157
+ - `port?: number`
158
+ - `user?: string`
159
+ - `password?: string`
160
+
161
+ ## user_create
162
+ Crea usuario MySQL.
163
+
164
+ Input:
165
+ - `username: string`
166
+ - `userPassword: string`
167
+ - `hostScope?: string` (default `%`)
168
+ - `ifNotExists?: boolean` (default `true`)
169
+ - `confirmed: boolean`
170
+ - `host?: string`
171
+ - `port?: number`
172
+ - `user?: string`
173
+ - `password?: string` (contraseña admin para ejecutar la sentencia)
174
+
175
+ ## grant_manage
176
+ Otorga privilegios a un usuario sobre una base.
177
+
178
+ Input:
179
+ - `database: string`
180
+ - `username: string`
181
+ - `hostScope?: string` (default `%`)
182
+ - `privileges: string` (lista separada por coma o `*`)
183
+ - `withGrantOption?: boolean`
184
+ - `confirmed: boolean`
185
+ - `host?: string`
186
+ - `port?: number`
187
+ - `user?: string`
188
+ - `password?: string`
189
+
190
+ ## db_export
191
+ Exporta una base a archivo SQL.
192
+
193
+ Input:
194
+ - `database: string`
195
+ - `outputPath?: string`
196
+ - `includeCreateDatabase?: boolean` (default `true`)
197
+ - `addDropTable?: boolean` (default `true`)
198
+ - `confirmed: boolean`
199
+ - `host?: string`
200
+ - `port?: number`
201
+ - `user?: string`
202
+ - `password?: string`
203
+
204
+ ## db_import
205
+ Importa SQL a una base.
206
+
207
+ Input:
208
+ - `database: string`
209
+ - `inputPath: string`
210
+ - `confirmed: boolean`
211
+ - `host?: string`
212
+ - `port?: number`
213
+ - `user?: string`
214
+ - `password?: string`
215
+
216
+ ## php_cli_run
217
+ Ejecuta script PHP con `php.exe` de XAMPP.
218
+
219
+ Input:
220
+ - `scriptPath: string`
221
+ - `args?: string`
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "xampp-mcp",
3
+ "version": "0.1.0",
4
+ "description": "MCP server for XAMPP and MySQL administration on Windows",
5
+ "type": "module",
6
+ "main": "dist/server.js",
7
+ "bin": {
8
+ "xampp-mcp": "dist/server.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "README.md",
13
+ "docs",
14
+ "package.json"
15
+ ],
16
+ "engines": {
17
+ "node": ">=20"
18
+ },
19
+ "scripts": {
20
+ "build": "tsc -p tsconfig.json",
21
+ "clean": "rimraf dist",
22
+ "dev": "tsx src/server.ts",
23
+ "start": "node dist/server.js",
24
+ "lint": "tsc -p tsconfig.json --noEmit",
25
+ "prepack": "npm run build",
26
+ "prepublishOnly": "npm run lint && npm run build"
27
+ },
28
+ "keywords": [
29
+ "mcp",
30
+ "xampp",
31
+ "mysql",
32
+ "vscode"
33
+ ],
34
+ "license": "UNLICENSED",
35
+ "dependencies": {
36
+ "@modelcontextprotocol/sdk": "^1.22.0"
37
+ },
38
+ "devDependencies": {
39
+ "@types/node": "^22.14.0",
40
+ "rimraf": "^6.0.1",
41
+ "tsx": "^4.20.5",
42
+ "typescript": "^5.8.3"
43
+ }
44
+ }