localwp-mcp 0.1.7 → 0.1.9

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,350 @@
1
+ import os from "os";
2
+ import path from "path";
3
+ import { mkdtemp, realpath, stat, writeFile } from "fs/promises";
4
+ import { isReadablePath } from "./process-utils.js";
5
+ export async function prepareWpPhpSource(options) {
6
+ const hasPhpCode = Boolean(options.phpCode?.trim());
7
+ const hasFilePath = Boolean(options.filePath?.trim());
8
+ if (hasPhpCode === hasFilePath) {
9
+ throw new Error("Pass exactly one of 'phpCode' or 'filePath' to execute_wp_php.");
10
+ }
11
+ if (hasFilePath) {
12
+ const absolutePath = await resolveTrustedWpPhpFilePath(options.siteRoot, options.filePath, {
13
+ cwd: options.cwd,
14
+ });
15
+ return {
16
+ mode: "file",
17
+ absolutePath,
18
+ sourcePath: absolutePath,
19
+ cleanupPath: null,
20
+ };
21
+ }
22
+ const tempDirectory = await mkdtemp(path.join(os.tmpdir(), "localwp-mcp-wp-php-"));
23
+ const absolutePath = path.join(tempDirectory, "runtime-inspect.php");
24
+ await writeFile(absolutePath, normalizeInlinePhpCode(options.phpCode), "utf8");
25
+ return {
26
+ mode: "inline",
27
+ absolutePath,
28
+ sourcePath: null,
29
+ cleanupPath: tempDirectory,
30
+ };
31
+ }
32
+ export function normalizeInlinePhpCode(phpCode) {
33
+ const trimmed = phpCode.trim();
34
+ if (!trimmed) {
35
+ throw new Error("The inline PHP snippet cannot be empty.");
36
+ }
37
+ if (trimmed.startsWith("<?php") ||
38
+ trimmed.startsWith("<?=") ||
39
+ trimmed.startsWith("<?")) {
40
+ return phpCode.endsWith("\n") ? phpCode : `${phpCode}\n`;
41
+ }
42
+ return `<?php\n${phpCode}${phpCode.endsWith("\n") ? "" : "\n"}`;
43
+ }
44
+ export function parseWpRuntimeArgsJson(argsJson) {
45
+ if (!argsJson?.trim()) {
46
+ return [];
47
+ }
48
+ let parsed;
49
+ try {
50
+ parsed = JSON.parse(argsJson);
51
+ }
52
+ catch (error) {
53
+ const message = error instanceof Error ? error.message : String(error);
54
+ throw new Error(`The 'argsJson' value must be valid JSON: ${message}`);
55
+ }
56
+ if (!Array.isArray(parsed)) {
57
+ throw new Error("The 'argsJson' value must decode to a JSON array.");
58
+ }
59
+ return parsed;
60
+ }
61
+ export function assertPhpFunctionIdentifier(functionName) {
62
+ if (!/^[A-Za-z_][A-Za-z0-9_\\]*$/.test(functionName)) {
63
+ throw new Error("Function names may only contain letters, numbers, underscores, and namespace separators.");
64
+ }
65
+ }
66
+ export function assertPhpMethodIdentifier(methodName) {
67
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(methodName)) {
68
+ throw new Error("Method names may only contain letters, numbers, and underscores.");
69
+ }
70
+ }
71
+ export function assertPhpClassIdentifier(className) {
72
+ if (!/^[A-Za-z_][A-Za-z0-9_\\]*$/.test(className)) {
73
+ throw new Error("Class names may only contain letters, numbers, underscores, and namespace separators.");
74
+ }
75
+ }
76
+ export async function prepareWpRuntimeCallFiles(options) {
77
+ const tempDirectory = await mkdtemp(path.join(os.tmpdir(), "localwp-mcp-wp-call-"));
78
+ const guardPath = path.join(tempDirectory, "read-only-guard.php");
79
+ const scriptPath = path.join(tempDirectory, "call.php");
80
+ await writeFile(guardPath, buildReadOnlyGuardPhp(), "utf8");
81
+ await writeFile(scriptPath, buildWpRuntimeCallPhp({
82
+ callType: options.callType,
83
+ functionName: options.functionName,
84
+ className: options.className,
85
+ methodName: options.methodName,
86
+ args: options.args,
87
+ }), "utf8");
88
+ return {
89
+ cleanupPath: tempDirectory,
90
+ guardPath,
91
+ scriptPath,
92
+ };
93
+ }
94
+ export function extractWpRuntimeCallPayload(stdout) {
95
+ const startMarker = "LOCALWP_MCP_JSON_START";
96
+ const endMarker = "LOCALWP_MCP_JSON_END";
97
+ const startIndex = stdout.indexOf(startMarker);
98
+ const endIndex = stdout.indexOf(endMarker);
99
+ if (startIndex === -1 || endIndex === -1 || endIndex < startIndex) {
100
+ throw new Error("The runtime call did not return a structured payload. Check stdout/stderr for PHP notices or fatal errors.");
101
+ }
102
+ const jsonText = stdout
103
+ .slice(startIndex + startMarker.length, endIndex)
104
+ .trim();
105
+ const leadingStdout = stdout.slice(0, startIndex).trim();
106
+ const trailingStdout = stdout.slice(endIndex + endMarker.length).trim();
107
+ const remainingStdout = [leadingStdout, trailingStdout]
108
+ .filter(Boolean)
109
+ .join("\n");
110
+ try {
111
+ return {
112
+ payload: JSON.parse(jsonText),
113
+ remainingStdout,
114
+ };
115
+ }
116
+ catch (error) {
117
+ const message = error instanceof Error ? error.message : String(error);
118
+ throw new Error(`The runtime call returned an unreadable JSON payload: ${message}`);
119
+ }
120
+ }
121
+ export async function resolveTrustedWpPhpFilePath(siteRoot, requestedPath, options = {}) {
122
+ const trimmedPath = requestedPath.trim();
123
+ if (!trimmedPath) {
124
+ throw new Error("The 'filePath' value cannot be empty.");
125
+ }
126
+ const baseCwd = options.cwd || process.cwd();
127
+ const absolutePath = path.isAbsolute(trimmedPath)
128
+ ? path.resolve(trimmedPath)
129
+ : path.resolve(baseCwd, trimmedPath);
130
+ if (path.extname(absolutePath).toLowerCase() !== ".php") {
131
+ throw new Error("execute_wp_php only allows readable '.php' files.");
132
+ }
133
+ if (!(await isReadablePath(absolutePath))) {
134
+ throw new Error(`The PHP file '${requestedPath}' is not readable.`);
135
+ }
136
+ const fileStats = await stat(absolutePath);
137
+ if (!fileStats.isFile()) {
138
+ throw new Error(`The path '${requestedPath}' is not a regular PHP file.`);
139
+ }
140
+ const targetRealPath = await realpath(absolutePath);
141
+ const allowedBases = await collectAllowedScriptBases(siteRoot, baseCwd);
142
+ if (!allowedBases.some((basePath) => isPathWithinBase(basePath, targetRealPath))) {
143
+ throw new Error("The PHP file must live inside the selected Local site or the MCP working directory.");
144
+ }
145
+ return absolutePath;
146
+ }
147
+ async function collectAllowedScriptBases(siteRoot, cwd) {
148
+ const basePaths = [await realpath(siteRoot)];
149
+ if (!(await isReadablePath(cwd)) || isFilesystemRoot(cwd)) {
150
+ return basePaths;
151
+ }
152
+ const cwdRealPath = await realpath(cwd);
153
+ if (!basePaths.includes(cwdRealPath)) {
154
+ basePaths.push(cwdRealPath);
155
+ }
156
+ return basePaths;
157
+ }
158
+ function isFilesystemRoot(candidatePath) {
159
+ const resolvedPath = path.resolve(candidatePath);
160
+ return resolvedPath === path.parse(resolvedPath).root;
161
+ }
162
+ function isPathWithinBase(basePath, candidatePath) {
163
+ const relativePath = path.relative(basePath, candidatePath);
164
+ return (relativePath === "" ||
165
+ relativePath === "." ||
166
+ (!relativePath.startsWith("..") && !path.isAbsolute(relativePath)));
167
+ }
168
+ function buildReadOnlyGuardPhp() {
169
+ return `<?php
170
+ if (!defined('DISALLOW_FILE_MODS')) {
171
+ define('DISALLOW_FILE_MODS', true);
172
+ }
173
+ if (!defined('AUTOMATIC_UPDATER_DISABLED')) {
174
+ define('AUTOMATIC_UPDATER_DISABLED', true);
175
+ }
176
+
177
+ if (class_exists('WP_CLI')) {
178
+ WP_CLI::add_hook('after_wp_load', function () {
179
+ if (function_exists('add_filter')) {
180
+ add_filter('pre_http_request', function ($pre, $parsed_args, $url) {
181
+ return new WP_Error(
182
+ 'localwp_mcp_read_only_http_blocked',
183
+ 'HTTP requests are blocked during read-only runtime inspection.'
184
+ );
185
+ }, 10, 3);
186
+
187
+ add_filter('pre_wp_mail', function ($return, $atts) {
188
+ return new WP_Error(
189
+ 'localwp_mcp_read_only_mail_blocked',
190
+ 'Emails are blocked during read-only runtime inspection.'
191
+ );
192
+ }, 10, 2);
193
+
194
+ add_filter('query', function ($query) {
195
+ $normalized_query = preg_replace('/^\\s*(?:\\/\\*.*?\\*\\/\\s*)*/s', '', (string) $query);
196
+ $verb = strtoupper((string) strtok($normalized_query, " \\t\\n\\r"));
197
+ $allowed_verbs = ['SELECT', 'SHOW', 'DESCRIBE', 'DESC', 'EXPLAIN', 'SET', 'START', 'ROLLBACK', 'COMMIT'];
198
+
199
+ if ($verb !== '' && !in_array($verb, $allowed_verbs, true)) {
200
+ throw new RuntimeException(
201
+ sprintf(
202
+ 'Blocked SQL verb %s during read-only runtime inspection.',
203
+ $verb
204
+ )
205
+ );
206
+ }
207
+
208
+ return $query;
209
+ });
210
+ }
211
+
212
+ global $wpdb;
213
+
214
+ if (isset($wpdb) && $wpdb instanceof wpdb) {
215
+ $wpdb->query('SET SESSION TRANSACTION READ ONLY');
216
+ $wpdb->query('START TRANSACTION READ ONLY');
217
+
218
+ register_shutdown_function(function () use ($wpdb) {
219
+ $wpdb->query('ROLLBACK');
220
+ });
221
+ }
222
+ });
223
+ }
224
+ `;
225
+ }
226
+ function buildWpRuntimeCallPhp(options) {
227
+ const argsLiteral = toPhpSingleQuotedString(JSON.stringify(options.args));
228
+ const callableDescription = options.callType === "function"
229
+ ? options.functionName || ""
230
+ : `${options.className || ""}::${options.methodName || ""}`;
231
+ const callableLiteral = toPhpSingleQuotedString(callableDescription);
232
+ if (options.callType === "function") {
233
+ assertPhpFunctionIdentifier(options.functionName || "");
234
+ }
235
+ else {
236
+ assertPhpClassIdentifier(options.className || "");
237
+ assertPhpMethodIdentifier(options.methodName || "");
238
+ }
239
+ const invocationPhp = options.callType === "function"
240
+ ? `$callable_name = ${toPhpSingleQuotedString(options.functionName || "")};
241
+ if (!function_exists($callable_name)) {
242
+ throw new RuntimeException(sprintf('Function %s does not exist in the loaded WordPress runtime.', $callable_name));
243
+ }
244
+
245
+ $result = call_user_func_array($callable_name, $args);`
246
+ : `$class_name = ${toPhpSingleQuotedString(options.className || "")};
247
+ $method_name = ${toPhpSingleQuotedString(options.methodName || "")};
248
+ $callable = [$class_name, $method_name];
249
+
250
+ if (!is_callable($callable)) {
251
+ throw new RuntimeException(
252
+ sprintf(
253
+ 'Static method %s::%s is not callable in the loaded WordPress runtime.',
254
+ $class_name,
255
+ $method_name
256
+ )
257
+ );
258
+ }
259
+
260
+ $result = call_user_func_array($callable, $args);`;
261
+ return `<?php
262
+ function localwp_mcp_normalize_value($value, $depth = 0) {
263
+ if ($depth >= 6) {
264
+ return ['__type' => 'truncated', 'message' => 'Maximum normalization depth reached.'];
265
+ }
266
+
267
+ if (is_null($value) || is_bool($value) || is_int($value) || is_float($value) || is_string($value)) {
268
+ return $value;
269
+ }
270
+
271
+ if ($value instanceof WP_Error) {
272
+ return [
273
+ '__type' => 'WP_Error',
274
+ 'codes' => $value->get_error_codes(),
275
+ 'messages' => $value->get_error_messages(),
276
+ ];
277
+ }
278
+
279
+ if ($value instanceof JsonSerializable) {
280
+ return localwp_mcp_normalize_value($value->jsonSerialize(), $depth + 1);
281
+ }
282
+
283
+ if ($value instanceof Traversable) {
284
+ return localwp_mcp_normalize_value(iterator_to_array($value), $depth + 1);
285
+ }
286
+
287
+ if (is_array($value)) {
288
+ $normalized = [];
289
+
290
+ foreach ($value as $key => $item) {
291
+ $normalized[$key] = localwp_mcp_normalize_value($item, $depth + 1);
292
+ }
293
+
294
+ return $normalized;
295
+ }
296
+
297
+ if (is_object($value)) {
298
+ $normalized = [
299
+ '__type' => 'object',
300
+ 'class' => get_class($value),
301
+ 'properties' => [],
302
+ ];
303
+
304
+ foreach (get_object_vars($value) as $key => $item) {
305
+ $normalized['properties'][$key] = localwp_mcp_normalize_value($item, $depth + 1);
306
+ }
307
+
308
+ if (method_exists($value, '__toString')) {
309
+ try {
310
+ $normalized['stringValue'] = (string) $value;
311
+ } catch (Throwable $exception) {
312
+ $normalized['stringValueError'] = $exception->getMessage();
313
+ }
314
+ }
315
+
316
+ return $normalized;
317
+ }
318
+
319
+ return [
320
+ '__type' => 'unknown',
321
+ 'description' => get_debug_type($value),
322
+ ];
323
+ }
324
+
325
+ try {
326
+ $args = json_decode(${argsLiteral}, true, 512, JSON_THROW_ON_ERROR);
327
+ ${invocationPhp}
328
+
329
+ $payload = [
330
+ 'ok' => true,
331
+ 'callType' => ${toPhpSingleQuotedString(options.callType)},
332
+ 'callable' => ${callableLiteral},
333
+ 'args' => localwp_mcp_normalize_value($args),
334
+ 'resultType' => get_debug_type($result),
335
+ 'result' => localwp_mcp_normalize_value($result),
336
+ ];
337
+
338
+ echo "\\nLOCALWP_MCP_JSON_START\\n";
339
+ echo wp_json_encode($payload, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
340
+ echo "\\nLOCALWP_MCP_JSON_END\\n";
341
+ } catch (Throwable $exception) {
342
+ fwrite(STDERR, $exception->getMessage() . PHP_EOL);
343
+ exit(1);
344
+ }
345
+ `;
346
+ }
347
+ function toPhpSingleQuotedString(value) {
348
+ return `'${value.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
349
+ }
350
+ //# sourceMappingURL=wp-runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wp-runtime.js","sourceRoot":"","sources":["../src/wp-runtime.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "localwp-mcp",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "description": "A LocalWP-aware MCP server for WordPress developers with simple safe and full-access profiles, logs, doctor diagnostics, SQL access, backups, restore flows, MCP resources/prompts, and site-aware WP-CLI.",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@10.32.1",