@automattic/mcp-wordpress-remote 0.2.16 → 0.2.18
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 +49 -0
- package/dist/lib.d.ts +19 -2
- package/dist/lib.js +28809 -2102
- package/dist/proxy.js +290 -53
- package/package.json +1 -1
package/dist/proxy.js
CHANGED
|
@@ -36036,7 +36036,7 @@ async function selectCallbackPort(serverUrl, specifiedPort, _unused) {
|
|
|
36036
36036
|
}
|
|
36037
36037
|
|
|
36038
36038
|
// src/lib/config.ts
|
|
36039
|
-
var MCP_WORDPRESS_REMOTE_VERSION = "0.2.
|
|
36039
|
+
var MCP_WORDPRESS_REMOTE_VERSION = "0.2.18";
|
|
36040
36040
|
var CONFIG = {
|
|
36041
36041
|
// API Configuration
|
|
36042
36042
|
WP_API_URL: process.env.WP_API_URL || "https://example.com",
|
|
@@ -36082,6 +36082,9 @@ var CONFIG = {
|
|
|
36082
36082
|
JWT_TOKEN: process.env.JWT_TOKEN,
|
|
36083
36083
|
WOO_CUSTOMER_KEY: process.env.WOO_CUSTOMER_KEY,
|
|
36084
36084
|
WOO_CUSTOMER_SECRET: process.env.WOO_CUSTOMER_SECRET,
|
|
36085
|
+
// Custom Headers Configuration
|
|
36086
|
+
CUSTOM_HEADERS: process.env.CUSTOM_HEADERS || "",
|
|
36087
|
+
// JSON string or comma-separated header:value pairs
|
|
36085
36088
|
// Environment
|
|
36086
36089
|
NODE_ENV: process.env.NODE_ENV || "development"
|
|
36087
36090
|
};
|
|
@@ -36095,17 +36098,54 @@ function getDefaultOAuthScopes() {
|
|
|
36095
36098
|
const defaultScopes = ["read", "write"];
|
|
36096
36099
|
return parseOAuthScopes(CONFIG.OAUTH_SCOPES, defaultScopes);
|
|
36097
36100
|
}
|
|
36101
|
+
function parseCustomHeaders(customHeadersString) {
|
|
36102
|
+
if (!customHeadersString || customHeadersString.trim() === "") {
|
|
36103
|
+
return {};
|
|
36104
|
+
}
|
|
36105
|
+
try {
|
|
36106
|
+
if (customHeadersString.trim().startsWith("{")) {
|
|
36107
|
+
return JSON.parse(customHeadersString);
|
|
36108
|
+
}
|
|
36109
|
+
const headers = {};
|
|
36110
|
+
const pairs = customHeadersString.split(",");
|
|
36111
|
+
for (const pair of pairs) {
|
|
36112
|
+
const colonIndex = pair.indexOf(":");
|
|
36113
|
+
if (colonIndex > 0) {
|
|
36114
|
+
const key = pair.substring(0, colonIndex).trim();
|
|
36115
|
+
const value = pair.substring(colonIndex + 1).trim();
|
|
36116
|
+
if (key && value) {
|
|
36117
|
+
headers[key] = value;
|
|
36118
|
+
}
|
|
36119
|
+
}
|
|
36120
|
+
}
|
|
36121
|
+
return headers;
|
|
36122
|
+
} catch (error) {
|
|
36123
|
+
logger.error("Error parsing custom headers", "CONFIG", error);
|
|
36124
|
+
return {};
|
|
36125
|
+
}
|
|
36126
|
+
}
|
|
36127
|
+
function getCustomHeaders() {
|
|
36128
|
+
const customHeadersEnv = process.env.CUSTOM_HEADERS || "";
|
|
36129
|
+
return parseCustomHeaders(customHeadersEnv);
|
|
36130
|
+
}
|
|
36098
36131
|
function validateConfig() {
|
|
36099
36132
|
const errors = [];
|
|
36100
|
-
const
|
|
36101
|
-
const
|
|
36102
|
-
const
|
|
36103
|
-
|
|
36133
|
+
const currentApiUrl = process.env.WP_API_URL || CONFIG.WP_API_URL;
|
|
36134
|
+
const currentCustomHeaders = process.env.CUSTOM_HEADERS || CONFIG.CUSTOM_HEADERS;
|
|
36135
|
+
const currentJwtToken = process.env.JWT_TOKEN || CONFIG.JWT_TOKEN;
|
|
36136
|
+
const currentUsername = process.env.WP_API_USERNAME || CONFIG.WP_API_USERNAME;
|
|
36137
|
+
const currentPassword = process.env.WP_API_PASSWORD || CONFIG.WP_API_PASSWORD;
|
|
36138
|
+
const currentOAuthEnabled = process.env.OAUTH_ENABLED === "true" || CONFIG.OAUTH_ENABLED;
|
|
36139
|
+
const hasJWT = !!currentJwtToken;
|
|
36140
|
+
const hasBasicAuth = !!(currentUsername && currentPassword);
|
|
36141
|
+
const hasOAuth = currentOAuthEnabled;
|
|
36142
|
+
const hasCustomHeaders = !!currentCustomHeaders && currentCustomHeaders.trim() !== "";
|
|
36143
|
+
if (!hasJWT && !hasBasicAuth && !hasOAuth && !hasCustomHeaders) {
|
|
36104
36144
|
errors.push(
|
|
36105
|
-
"No authentication method configured. Please set one of: JWT_TOKEN, WP_API_USERNAME+WP_API_PASSWORD, or
|
|
36145
|
+
"No authentication method configured. Please set one of: JWT_TOKEN, WP_API_USERNAME+WP_API_PASSWORD, enable OAuth, or set CUSTOM_HEADERS"
|
|
36106
36146
|
);
|
|
36107
36147
|
}
|
|
36108
|
-
if (!
|
|
36148
|
+
if (!currentApiUrl || currentApiUrl === "https://example.com") {
|
|
36109
36149
|
errors.push("WP_API_URL must be set to your WordPress site URL");
|
|
36110
36150
|
}
|
|
36111
36151
|
if (CONFIG.OAUTH_ENABLED) {
|
|
@@ -36139,7 +36179,8 @@ function formatConfigError(error) {
|
|
|
36139
36179
|
return `${error}. Configure one of these options:
|
|
36140
36180
|
\u2022 JWT_TOKEN=your_jwt_token (preferred for APIs)
|
|
36141
36181
|
\u2022 WP_API_USERNAME=username and WP_API_PASSWORD=app_password (for application passwords)
|
|
36142
|
-
\u2022 Set OAUTH_ENABLED=true and WP_OAUTH_CLIENT_ID=your_client_id (for OAuth 2.1)
|
|
36182
|
+
\u2022 Set OAUTH_ENABLED=true and WP_OAUTH_CLIENT_ID=your_client_id (for OAuth 2.1)
|
|
36183
|
+
\u2022 CUSTOM_HEADERS='{"X-API-Key": "your_api_key"}' (for custom header authentication)`;
|
|
36143
36184
|
}
|
|
36144
36185
|
if (error.includes("OAUTH_CALLBACK_PORT")) {
|
|
36145
36186
|
return `${error}. The port must be available for the OAuth callback server. Try a different port like 7777, 7890, or other ports in the safe 7000-7999 range.`;
|
|
@@ -36177,7 +36218,9 @@ function log(message, level = 2 /* INFO */, category = "GENERAL", ...args) {
|
|
|
36177
36218
|
const formattedArgs = args.length > 0 ? args.map((arg) => typeof arg === "object" ? JSON.stringify(arg, null, 2) : arg).join(" ") : "";
|
|
36178
36219
|
const logMessage = `${timestamp} [${levelName}] [${category}] ${message}${formattedArgs ? "\n" + formattedArgs : ""}
|
|
36179
36220
|
`;
|
|
36180
|
-
process.
|
|
36221
|
+
if (process.env.LOG_TO_STDERR === "true") {
|
|
36222
|
+
process.stderr.write(logMessage);
|
|
36223
|
+
}
|
|
36181
36224
|
if (process.env.LOG_FILE) {
|
|
36182
36225
|
fs2.appendFileSync(process.env.LOG_FILE, logMessage);
|
|
36183
36226
|
}
|
|
@@ -36739,7 +36782,13 @@ async function discoverAuthorizationServerMetadata(authorizationServerUrl) {
|
|
|
36739
36782
|
try {
|
|
36740
36783
|
const metadataUrl = new URL("/.well-known/oauth-authorization-server", authorizationServerUrl);
|
|
36741
36784
|
logger.oauth(`Discovering authorization server metadata: ${metadataUrl}`);
|
|
36742
|
-
const
|
|
36785
|
+
const customHeaders = getCustomHeaders();
|
|
36786
|
+
const response = await fetch(metadataUrl.toString(), {
|
|
36787
|
+
headers: {
|
|
36788
|
+
"Accept": "application/json",
|
|
36789
|
+
...customHeaders
|
|
36790
|
+
}
|
|
36791
|
+
});
|
|
36743
36792
|
if (!response.ok) {
|
|
36744
36793
|
throw new OAuthError(
|
|
36745
36794
|
`Failed to fetch authorization server metadata: ${response.status}`,
|
|
@@ -36770,7 +36819,13 @@ async function discoverProtectedResourceMetadata(resourceUrl) {
|
|
|
36770
36819
|
const url = new URL(resourceUrl);
|
|
36771
36820
|
const metadataUrl = new URL("/.well-known/oauth-protected-resource", url.origin);
|
|
36772
36821
|
logger.oauth(`Discovering protected resource metadata: ${metadataUrl}`);
|
|
36773
|
-
const
|
|
36822
|
+
const customHeaders = getCustomHeaders();
|
|
36823
|
+
const response = await fetch(metadataUrl.toString(), {
|
|
36824
|
+
headers: {
|
|
36825
|
+
"Accept": "application/json",
|
|
36826
|
+
...customHeaders
|
|
36827
|
+
}
|
|
36828
|
+
});
|
|
36774
36829
|
if (!response.ok) {
|
|
36775
36830
|
throw new OAuthError(
|
|
36776
36831
|
`Failed to fetch protected resource metadata: ${response.status}`,
|
|
@@ -36830,10 +36885,12 @@ function parseWWWAuthenticateHeader(headerValue) {
|
|
|
36830
36885
|
async function registerDynamicClient(registrationEndpoint, registrationRequest) {
|
|
36831
36886
|
try {
|
|
36832
36887
|
logger.oauth(`Attempting dynamic client registration: ${registrationEndpoint}`);
|
|
36888
|
+
const customHeaders = getCustomHeaders();
|
|
36833
36889
|
const response = await fetch(registrationEndpoint, {
|
|
36834
36890
|
method: "POST",
|
|
36835
36891
|
headers: {
|
|
36836
|
-
"Content-Type": "application/json"
|
|
36892
|
+
"Content-Type": "application/json",
|
|
36893
|
+
...customHeaders
|
|
36837
36894
|
},
|
|
36838
36895
|
body: JSON.stringify(registrationRequest)
|
|
36839
36896
|
});
|
|
@@ -36880,10 +36937,12 @@ async function exchangeAuthorizationCode(tokenEndpoint, code, redirectUri, clien
|
|
|
36880
36937
|
if (resource) {
|
|
36881
36938
|
params.set("resource", resource);
|
|
36882
36939
|
}
|
|
36940
|
+
const customHeaders = getCustomHeaders();
|
|
36883
36941
|
const response = await fetch(tokenEndpoint, {
|
|
36884
36942
|
method: "POST",
|
|
36885
36943
|
headers: {
|
|
36886
|
-
"Content-Type": "application/x-www-form-urlencoded"
|
|
36944
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
36945
|
+
...customHeaders
|
|
36887
36946
|
},
|
|
36888
36947
|
body: params.toString()
|
|
36889
36948
|
});
|
|
@@ -37346,9 +37405,11 @@ var MCPOAuthProvider = class {
|
|
|
37346
37405
|
async discoverVia401Response() {
|
|
37347
37406
|
try {
|
|
37348
37407
|
logger.oauth("Attempting discovery via 401 response method");
|
|
37408
|
+
const customHeaders = getCustomHeaders();
|
|
37349
37409
|
const response = await fetch(this.config.serverUrl, {
|
|
37350
37410
|
headers: {
|
|
37351
|
-
Accept: "application/json"
|
|
37411
|
+
Accept: "application/json",
|
|
37412
|
+
...customHeaders
|
|
37352
37413
|
}
|
|
37353
37414
|
});
|
|
37354
37415
|
if (response.status === 401) {
|
|
@@ -37357,7 +37418,12 @@ var MCPOAuthProvider = class {
|
|
|
37357
37418
|
const authInfo = parseWWWAuthenticateHeader(wwwAuthHeader);
|
|
37358
37419
|
logger.oauth("WWW-Authenticate header parsed successfully");
|
|
37359
37420
|
if (authInfo.resource_metadata_url) {
|
|
37360
|
-
const metadataResponse = await fetch(authInfo.resource_metadata_url
|
|
37421
|
+
const metadataResponse = await fetch(authInfo.resource_metadata_url, {
|
|
37422
|
+
headers: {
|
|
37423
|
+
"Accept": "application/json",
|
|
37424
|
+
...customHeaders
|
|
37425
|
+
}
|
|
37426
|
+
});
|
|
37361
37427
|
if (metadataResponse.ok) {
|
|
37362
37428
|
this.resourceMetadata = await metadataResponse.json();
|
|
37363
37429
|
logger.oauth("Protected resource metadata obtained via 401 response");
|
|
@@ -38381,25 +38447,43 @@ async function wpRequest(requestData, useJsonRpc = true) {
|
|
|
38381
38447
|
authHeader = `Basic ${auth2}`;
|
|
38382
38448
|
logger.debug(`Auth header length: ${auth2.length}`, "AUTH");
|
|
38383
38449
|
}
|
|
38384
|
-
|
|
38450
|
+
const customHeaders = getCustomHeaders();
|
|
38451
|
+
const hasCustomHeaders = Object.keys(customHeaders).length > 0;
|
|
38452
|
+
if (!authHeader && !hasCustomHeaders) {
|
|
38385
38453
|
throw new AuthError(
|
|
38386
|
-
"No authentication method available. Please configure JWT_TOKEN, OAuth,
|
|
38454
|
+
"No authentication method available. Please configure JWT_TOKEN, OAuth, Basic Auth (WP_API_USERNAME+WP_API_PASSWORD), or CUSTOM_HEADERS.",
|
|
38387
38455
|
"NO_AUTH_METHOD"
|
|
38388
38456
|
);
|
|
38389
38457
|
}
|
|
38458
|
+
const currentApiUrl = process.env.WP_API_URL || CONFIG.WP_API_URL;
|
|
38390
38459
|
logger.debug(`Environment: ${CONFIG.NODE_ENV}`, "API");
|
|
38391
|
-
logger.debug(`Base API URL: ${
|
|
38392
|
-
const url = constructApiUrl(
|
|
38460
|
+
logger.debug(`Base API URL: ${currentApiUrl}`, "API");
|
|
38461
|
+
const url = constructApiUrl(currentApiUrl, endpoint);
|
|
38393
38462
|
logger.debug(`Final requesting URL: ${url}`, "API");
|
|
38394
38463
|
const headers = {
|
|
38395
|
-
Authorization: authHeader,
|
|
38396
38464
|
"Content-Type": "application/json",
|
|
38397
|
-
"MCP-Protocol-Version": "2025-06-18"
|
|
38465
|
+
"MCP-Protocol-Version": "2025-06-18",
|
|
38398
38466
|
// MCP protocol version
|
|
38467
|
+
...customHeaders
|
|
38468
|
+
// Merge custom headers
|
|
38399
38469
|
};
|
|
38470
|
+
if (authHeader) {
|
|
38471
|
+
headers.Authorization = authHeader;
|
|
38472
|
+
}
|
|
38400
38473
|
if (globalSessionId) {
|
|
38401
38474
|
headers["Mcp-Session-Id"] = globalSessionId;
|
|
38402
38475
|
}
|
|
38476
|
+
if (authHeader) {
|
|
38477
|
+
logger.debug("Using Authorization header for authentication", "API");
|
|
38478
|
+
} else if (hasCustomHeaders) {
|
|
38479
|
+
logger.auth("Using custom headers for authentication (no Authorization header)");
|
|
38480
|
+
}
|
|
38481
|
+
if (hasCustomHeaders) {
|
|
38482
|
+
logger.debug(`Custom headers added: ${Object.keys(customHeaders).join(", ")}`, "API");
|
|
38483
|
+
for (const [key, value] of Object.entries(customHeaders)) {
|
|
38484
|
+
logger.debug(`Header ${key}: ${value.length} characters`, "API");
|
|
38485
|
+
}
|
|
38486
|
+
}
|
|
38403
38487
|
const fetchOptions = {
|
|
38404
38488
|
method,
|
|
38405
38489
|
headers,
|
|
@@ -38496,28 +38580,83 @@ function createSessionContext() {
|
|
|
38496
38580
|
}
|
|
38497
38581
|
|
|
38498
38582
|
// src/lib/transport-detection.ts
|
|
38499
|
-
async function detectTransportType(context) {
|
|
38500
|
-
logger.info("
|
|
38583
|
+
async function detectTransportType(context, initParams) {
|
|
38584
|
+
logger.info("\u{1F50D} Starting transport detection and WordPress API initialization...", "TRANSPORT_DETECT");
|
|
38501
38585
|
let init;
|
|
38502
38586
|
let transportType = null;
|
|
38587
|
+
const enhancedParams = initParams ? { ...initParams } : {};
|
|
38588
|
+
if (enhancedParams.clientInfo) {
|
|
38589
|
+
if (typeof enhancedParams.clientInfo === "object" && enhancedParams.clientInfo !== null && !Array.isArray(enhancedParams.clientInfo)) {
|
|
38590
|
+
const originalClient = enhancedParams.clientInfo?.name || "unknown";
|
|
38591
|
+
const newClientInfo = { ...enhancedParams.clientInfo };
|
|
38592
|
+
if (newClientInfo.proxied && typeof newClientInfo.proxied === "object") {
|
|
38593
|
+
newClientInfo.proxied = {
|
|
38594
|
+
...newClientInfo.proxied,
|
|
38595
|
+
name: "@automattic/mcp-wordpress-remote",
|
|
38596
|
+
version: MCP_WORDPRESS_REMOTE_VERSION
|
|
38597
|
+
};
|
|
38598
|
+
} else {
|
|
38599
|
+
newClientInfo.proxied = {
|
|
38600
|
+
name: "@automattic/mcp-wordpress-remote",
|
|
38601
|
+
version: MCP_WORDPRESS_REMOTE_VERSION
|
|
38602
|
+
};
|
|
38603
|
+
}
|
|
38604
|
+
enhancedParams.clientInfo = newClientInfo;
|
|
38605
|
+
logger.info("\u{1F4CB} Added proxy information to clientInfo", "TRANSPORT_DETECT", {
|
|
38606
|
+
originalClient,
|
|
38607
|
+
proxyName: "@automattic/mcp-wordpress-remote",
|
|
38608
|
+
proxyVersion: MCP_WORDPRESS_REMOTE_VERSION
|
|
38609
|
+
});
|
|
38610
|
+
} else {
|
|
38611
|
+
logger.warn("clientInfo is present but not a valid object, skipping enhancement", "TRANSPORT_DETECT", {
|
|
38612
|
+
clientInfoType: typeof enhancedParams.clientInfo,
|
|
38613
|
+
isArray: Array.isArray(enhancedParams.clientInfo),
|
|
38614
|
+
isNull: enhancedParams.clientInfo === null
|
|
38615
|
+
});
|
|
38616
|
+
}
|
|
38617
|
+
} else {
|
|
38618
|
+
logger.debug("No clientInfo provided in initialize parameters", "TRANSPORT_DETECT");
|
|
38619
|
+
}
|
|
38503
38620
|
try {
|
|
38504
|
-
logger.info("Attempting JSON-RPC transport...", "
|
|
38505
|
-
const
|
|
38621
|
+
logger.info("\u{1F4E1} Attempting JSON-RPC transport...", "TRANSPORT_DETECT");
|
|
38622
|
+
const wpRequestParams = {
|
|
38623
|
+
method: "initialize",
|
|
38624
|
+
...enhancedParams
|
|
38625
|
+
};
|
|
38626
|
+
const initMessage = addSessionInfo(wpRequestParams, {}, context);
|
|
38627
|
+
logger.info("Sending initialization message via JSON-RPC:", "TRANSPORT_DETECT", {
|
|
38628
|
+
method: initMessage.method,
|
|
38629
|
+
id: initMessage.id,
|
|
38630
|
+
jsonrpc: initMessage.jsonrpc,
|
|
38631
|
+
hasParams: !!initMessage.params && Object.keys(initMessage.params).length > 1
|
|
38632
|
+
// More than just _proxy_request_id
|
|
38633
|
+
});
|
|
38634
|
+
logger.debug("Complete JSON-RPC init message:", "TRANSPORT_DETECT", initMessage);
|
|
38506
38635
|
const initResponse = await wpRequest(initMessage, true);
|
|
38507
38636
|
init = initResponse;
|
|
38508
38637
|
transportType = "jsonrpc";
|
|
38509
|
-
logger.info("\u2705 JSON-RPC transport detected and working", "
|
|
38638
|
+
logger.info("\u2705 JSON-RPC transport detected and working", "TRANSPORT_DETECT");
|
|
38639
|
+
logger.debug("JSON-RPC initialization response:", "TRANSPORT_DETECT", init);
|
|
38510
38640
|
} catch (error) {
|
|
38511
|
-
logger.warn("JSON-RPC transport failed, trying simple transport...", "
|
|
38512
|
-
logger.debug("JSON-RPC error:", "
|
|
38641
|
+
logger.warn("\u26A0\uFE0F JSON-RPC transport failed, trying simple transport...", "TRANSPORT_DETECT");
|
|
38642
|
+
logger.debug("JSON-RPC error details:", "TRANSPORT_DETECT", error);
|
|
38513
38643
|
try {
|
|
38514
|
-
const
|
|
38515
|
-
|
|
38644
|
+
const simpleRequestParams = {
|
|
38645
|
+
method: "initialize",
|
|
38646
|
+
...enhancedParams
|
|
38647
|
+
};
|
|
38648
|
+
logger.info("Sending initialization message via Simple transport:", "TRANSPORT_DETECT", {
|
|
38649
|
+
method: simpleRequestParams.method,
|
|
38650
|
+
hasParams: Object.keys(simpleRequestParams).length > 1
|
|
38651
|
+
});
|
|
38652
|
+
logger.debug("Complete Simple init message:", "TRANSPORT_DETECT", simpleRequestParams);
|
|
38653
|
+
const initResponse = await wpRequest(simpleRequestParams, false);
|
|
38516
38654
|
init = initResponse;
|
|
38517
38655
|
transportType = "simple";
|
|
38518
|
-
logger.info("\u2705 Simple transport detected and working", "
|
|
38656
|
+
logger.info("\u2705 Simple transport detected and working", "TRANSPORT_DETECT");
|
|
38657
|
+
logger.debug("Simple initialization response:", "TRANSPORT_DETECT", init);
|
|
38519
38658
|
} catch (simpleError) {
|
|
38520
|
-
logger.error("Both JSON-RPC and simple transports failed", "
|
|
38659
|
+
logger.error("\u274C Both JSON-RPC and simple transports failed", "TRANSPORT_DETECT", simpleError);
|
|
38521
38660
|
throw new Error("Unable to establish connection with either transport type");
|
|
38522
38661
|
}
|
|
38523
38662
|
}
|
|
@@ -38539,36 +38678,54 @@ async function detectTransportType(context) {
|
|
|
38539
38678
|
|
|
38540
38679
|
// src/lib/error-utils.ts
|
|
38541
38680
|
function mapHttpStatusToMcpCode(statusCode) {
|
|
38542
|
-
const
|
|
38681
|
+
const JSONRPC_ERROR_CODES = {
|
|
38543
38682
|
PARSE_ERROR: -32700,
|
|
38544
38683
|
INVALID_REQUEST: -32600,
|
|
38545
38684
|
METHOD_NOT_FOUND: -32601,
|
|
38546
38685
|
INVALID_PARAMS: -32602,
|
|
38547
|
-
INTERNAL_ERROR: -32603
|
|
38548
|
-
|
|
38549
|
-
|
|
38686
|
+
INTERNAL_ERROR: -32603
|
|
38687
|
+
};
|
|
38688
|
+
const MCP_ERROR_CODES = {
|
|
38689
|
+
SERVER_ERROR: -32e3,
|
|
38690
|
+
// Generic server error
|
|
38691
|
+
TIMEOUT_ERROR: -32001,
|
|
38692
|
+
// Request timeout
|
|
38693
|
+
RESOURCE_NOT_FOUND: -32002,
|
|
38694
|
+
// Resource not found
|
|
38695
|
+
TOOL_NOT_FOUND: -32003,
|
|
38696
|
+
// Tool not found
|
|
38697
|
+
PROMPT_NOT_FOUND: -32004,
|
|
38698
|
+
// Prompt not found
|
|
38699
|
+
PERMISSION_DENIED: -32008,
|
|
38700
|
+
// Access denied/forbidden
|
|
38701
|
+
UNAUTHORIZED: -32010
|
|
38702
|
+
// Authentication required
|
|
38550
38703
|
};
|
|
38551
38704
|
switch (statusCode) {
|
|
38552
38705
|
case 400:
|
|
38553
|
-
return
|
|
38706
|
+
return JSONRPC_ERROR_CODES.INVALID_REQUEST;
|
|
38554
38707
|
case 401:
|
|
38555
38708
|
return MCP_ERROR_CODES.UNAUTHORIZED;
|
|
38556
38709
|
case 403:
|
|
38557
38710
|
return MCP_ERROR_CODES.PERMISSION_DENIED;
|
|
38558
38711
|
case 404:
|
|
38559
|
-
return
|
|
38712
|
+
return JSONRPC_ERROR_CODES.METHOD_NOT_FOUND;
|
|
38713
|
+
case 408:
|
|
38714
|
+
return MCP_ERROR_CODES.TIMEOUT_ERROR;
|
|
38715
|
+
case 413:
|
|
38716
|
+
// Payload Too Large
|
|
38560
38717
|
case 422:
|
|
38561
|
-
return
|
|
38718
|
+
return JSONRPC_ERROR_CODES.INVALID_PARAMS;
|
|
38562
38719
|
case 500:
|
|
38563
|
-
|
|
38720
|
+
return JSONRPC_ERROR_CODES.INTERNAL_ERROR;
|
|
38564
38721
|
case 502:
|
|
38565
38722
|
// Bad Gateway
|
|
38566
38723
|
case 503:
|
|
38567
|
-
|
|
38724
|
+
return MCP_ERROR_CODES.SERVER_ERROR;
|
|
38568
38725
|
case 504:
|
|
38569
|
-
|
|
38726
|
+
return MCP_ERROR_CODES.TIMEOUT_ERROR;
|
|
38570
38727
|
default:
|
|
38571
|
-
return
|
|
38728
|
+
return JSONRPC_ERROR_CODES.INTERNAL_ERROR;
|
|
38572
38729
|
}
|
|
38573
38730
|
}
|
|
38574
38731
|
function convertAPIErrorToMcpError(error) {
|
|
@@ -38598,17 +38755,38 @@ function createRequestHandler(config, context) {
|
|
|
38598
38755
|
function createWrappedHandler(config, context) {
|
|
38599
38756
|
const handler = createRequestHandler(config, context);
|
|
38600
38757
|
return async (request) => {
|
|
38601
|
-
logger.
|
|
38758
|
+
logger.info(`\u{1F4E9} Client Message: ${config.name}`, "CLIENT");
|
|
38759
|
+
logger.info(`Request ID: ${request.id || "none"} | Method: ${config.method}`, "CLIENT");
|
|
38760
|
+
if (request.params && Object.keys(request.params).length > 0) {
|
|
38761
|
+
logger.info(`Request parameters:`, "CLIENT", {
|
|
38762
|
+
paramCount: Object.keys(request.params).length,
|
|
38763
|
+
paramKeys: Object.keys(request.params)
|
|
38764
|
+
});
|
|
38765
|
+
logger.debug(`Full request parameters:`, "CLIENT", request.params);
|
|
38766
|
+
} else {
|
|
38767
|
+
logger.info(`No request parameters`, "CLIENT");
|
|
38768
|
+
}
|
|
38602
38769
|
logger.debug(
|
|
38603
|
-
`
|
|
38604
|
-
"
|
|
38770
|
+
`Session context - ID: ${context.sessionId || "none"}, Transport: ${context.transportType || "detecting"}, Counter: ${context.requestIdCounter}`,
|
|
38771
|
+
"CLIENT"
|
|
38605
38772
|
);
|
|
38773
|
+
logger.debug(`Complete client request object:`, "CLIENT", request);
|
|
38774
|
+
const startTime = Date.now();
|
|
38606
38775
|
try {
|
|
38607
38776
|
const response = await handler(request);
|
|
38608
|
-
|
|
38777
|
+
const duration = Date.now() - startTime;
|
|
38778
|
+
logger.info(`\u2705 Client Response: ${config.name} completed in ${duration}ms`, "CLIENT");
|
|
38779
|
+
logger.debug(`Response sent to client:`, "CLIENT", {
|
|
38780
|
+
hasResponse: !!response,
|
|
38781
|
+
responseKeys: response && typeof response === "object" ? Object.keys(response) : "primitive"
|
|
38782
|
+
});
|
|
38609
38783
|
return response;
|
|
38610
38784
|
} catch (error) {
|
|
38611
|
-
|
|
38785
|
+
const duration = Date.now() - startTime;
|
|
38786
|
+
logger.error(`\u274C Client Error: ${config.name} failed after ${duration}ms`, "CLIENT", {
|
|
38787
|
+
error: error instanceof Error ? error.message : String(error),
|
|
38788
|
+
requestId: request.id
|
|
38789
|
+
});
|
|
38612
38790
|
if (isAPIError(error) && context.transportType === "simple") {
|
|
38613
38791
|
logger.debug(`Converting APIError to MCP error format for ${config.name} (simple transport)`, "MCP", {
|
|
38614
38792
|
statusCode: error.statusCode,
|
|
@@ -38733,17 +38911,57 @@ async function WordPressProxy() {
|
|
|
38733
38911
|
logger.warn("Error cleaning up expired tokens", "PROXY", error);
|
|
38734
38912
|
}
|
|
38735
38913
|
const sessionContext = createSessionContext();
|
|
38736
|
-
const { initResult } = await detectTransportType(sessionContext);
|
|
38737
38914
|
const server = new Server(
|
|
38738
38915
|
{
|
|
38739
|
-
name:
|
|
38740
|
-
version:
|
|
38916
|
+
name: "WordPress MCP Remote Proxy",
|
|
38917
|
+
version: "0.2.17"
|
|
38741
38918
|
},
|
|
38742
38919
|
{
|
|
38743
|
-
capabilities:
|
|
38744
|
-
|
|
38920
|
+
capabilities: {
|
|
38921
|
+
tools: {},
|
|
38922
|
+
resources: {},
|
|
38923
|
+
prompts: {},
|
|
38924
|
+
logging: {},
|
|
38925
|
+
completions: {}
|
|
38926
|
+
}
|
|
38745
38927
|
}
|
|
38746
38928
|
);
|
|
38929
|
+
server.setRequestHandler(InitializeRequestSchema, async (request) => {
|
|
38930
|
+
logger.info("\u{1F4E9} Client Initialize Request received", "INIT");
|
|
38931
|
+
logger.debug("Initialize request details:", "INIT", request);
|
|
38932
|
+
try {
|
|
38933
|
+
logger.info("\u{1F504} Initializing WordPress connection with client parameters", "INIT");
|
|
38934
|
+
const { initResult } = await detectTransportType(sessionContext, request.params);
|
|
38935
|
+
const wordpressInitResponse = {
|
|
38936
|
+
protocolVersion: initResult.protocolVersion || "2025-06-18",
|
|
38937
|
+
serverInfo: initResult.serverInfo,
|
|
38938
|
+
capabilities: initResult.capabilities,
|
|
38939
|
+
instructions: initResult.instructions || "MCP WordPress Remote Proxy Server"
|
|
38940
|
+
};
|
|
38941
|
+
logger.info("\u2705 Returning WordPress server initialize response", "INIT");
|
|
38942
|
+
logger.debug("Initialize response:", "INIT", wordpressInitResponse);
|
|
38943
|
+
return wordpressInitResponse;
|
|
38944
|
+
} catch (error) {
|
|
38945
|
+
logger.error("\u274C Failed to initialize WordPress connection with client parameters", "INIT", error);
|
|
38946
|
+
const fallbackResponse = {
|
|
38947
|
+
protocolVersion: "2025-06-18",
|
|
38948
|
+
serverInfo: {
|
|
38949
|
+
name: "WordPress MCP Remote Proxy",
|
|
38950
|
+
version: "0.2.17"
|
|
38951
|
+
},
|
|
38952
|
+
capabilities: {
|
|
38953
|
+
tools: {},
|
|
38954
|
+
resources: {},
|
|
38955
|
+
prompts: {},
|
|
38956
|
+
logging: {},
|
|
38957
|
+
completions: {}
|
|
38958
|
+
},
|
|
38959
|
+
instructions: "MCP WordPress Remote Proxy Server (Connection Failed)"
|
|
38960
|
+
};
|
|
38961
|
+
logger.warn("\u26A0\uFE0F Using fallback initialize response", "INIT");
|
|
38962
|
+
return fallbackResponse;
|
|
38963
|
+
}
|
|
38964
|
+
});
|
|
38747
38965
|
server.setRequestHandler(ListToolsRequestSchema, createWrappedHandler(HANDLER_CONFIGS.listTools, sessionContext));
|
|
38748
38966
|
server.setRequestHandler(CallToolRequestSchema, createWrappedHandler(HANDLER_CONFIGS.callTool, sessionContext));
|
|
38749
38967
|
server.setRequestHandler(ListResourcesRequestSchema, createWrappedHandler(HANDLER_CONFIGS.listResources, sessionContext));
|
|
@@ -38757,6 +38975,25 @@ async function WordPressProxy() {
|
|
|
38757
38975
|
server.setRequestHandler(CompleteRequestSchema, createWrappedHandler(HANDLER_CONFIGS.complete, sessionContext));
|
|
38758
38976
|
server.setRequestHandler(ListRootsRequestSchema, createWrappedHandler(HANDLER_CONFIGS.listRoots, sessionContext));
|
|
38759
38977
|
const transport = new StdioServerTransport();
|
|
38978
|
+
transport.onmessage = (message) => {
|
|
38979
|
+
const msg = message;
|
|
38980
|
+
const method = typeof msg?.method === "string" ? msg.method : "unknown";
|
|
38981
|
+
const id = msg?.id ?? "none";
|
|
38982
|
+
const hasParams = Boolean(msg?.params && typeof msg.params === "object" && Object.keys(msg.params).length);
|
|
38983
|
+
logger.info("\u{1F4E5} Raw client message received", "TRANSPORT", {
|
|
38984
|
+
method,
|
|
38985
|
+
id,
|
|
38986
|
+
hasParams,
|
|
38987
|
+
messageType: method === "unknown" ? "response/notification" : "request"
|
|
38988
|
+
});
|
|
38989
|
+
logger.debug("Complete raw message:", "TRANSPORT", message);
|
|
38990
|
+
};
|
|
38991
|
+
transport.onerror = (error) => {
|
|
38992
|
+
logger.error("\u274C Transport error:", "TRANSPORT", error);
|
|
38993
|
+
};
|
|
38994
|
+
transport.onclose = () => {
|
|
38995
|
+
logger.info("\u{1F50C} Transport connection closed", "TRANSPORT");
|
|
38996
|
+
};
|
|
38760
38997
|
server.connect(transport).then(() => {
|
|
38761
38998
|
logger.info("MCP server connected to transport successfully", "PROXY");
|
|
38762
38999
|
}).catch((error) => {
|