@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/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.16";
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 hasJWT = !!CONFIG.JWT_TOKEN;
36101
- const hasBasicAuth = !!(CONFIG.WP_API_USERNAME && CONFIG.WP_API_PASSWORD);
36102
- const hasOAuth = CONFIG.OAUTH_ENABLED;
36103
- if (!hasJWT && !hasBasicAuth && !hasOAuth) {
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 enable OAuth"
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 (!CONFIG.WP_API_URL || CONFIG.WP_API_URL === "https://example.com") {
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.stderr.write(logMessage);
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 response = await fetch(metadataUrl.toString());
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 response = await fetch(metadataUrl.toString());
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
- if (!authHeader) {
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, or Basic Auth (WP_API_USERNAME+WP_API_PASSWORD).",
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: ${CONFIG.WP_API_URL}`, "API");
38392
- const url = constructApiUrl(CONFIG.WP_API_URL, endpoint);
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("Initializing connection to WordPress API with transport detection...", "PROXY");
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...", "PROXY");
38505
- const initMessage = addSessionInfo({ method: "initialize" }, {}, context);
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", "PROXY");
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...", "PROXY");
38512
- logger.debug("JSON-RPC error:", "PROXY", 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 simpleInitRequest = { method: "initialize" };
38515
- const initResponse = await wpRequest(simpleInitRequest, false);
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", "PROXY");
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", "PROXY", simpleError);
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 MCP_ERROR_CODES = {
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
- UNAUTHORIZED: -32010,
38549
- PERMISSION_DENIED: -32008
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 MCP_ERROR_CODES.INVALID_REQUEST;
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 MCP_ERROR_CODES.METHOD_NOT_FOUND;
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 MCP_ERROR_CODES.INVALID_PARAMS;
38718
+ return JSONRPC_ERROR_CODES.INVALID_PARAMS;
38562
38719
  case 500:
38563
- // Internal Server Error
38720
+ return JSONRPC_ERROR_CODES.INTERNAL_ERROR;
38564
38721
  case 502:
38565
38722
  // Bad Gateway
38566
38723
  case 503:
38567
- // Service Unavailable
38724
+ return MCP_ERROR_CODES.SERVER_ERROR;
38568
38725
  case 504:
38569
- // Gateway Timeout
38726
+ return MCP_ERROR_CODES.TIMEOUT_ERROR;
38570
38727
  default:
38571
- return MCP_ERROR_CODES.INTERNAL_ERROR;
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.debug(`Received ${config.name} request`, "MCP", request);
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
- `Adding session info - Session ID: ${context.sessionId}, MCP Request ID: ${request.id}`,
38604
- "SESSION"
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
- logger.debug(`${config.name} response sent`, "MCP");
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
- logger.error(`Error handling ${config.name} request`, "MCP", error);
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: initResult.serverInfo.name,
38740
- version: initResult.serverInfo.version
38916
+ name: "WordPress MCP Remote Proxy",
38917
+ version: "0.2.17"
38741
38918
  },
38742
38919
  {
38743
- capabilities: initResult.capabilities
38744
- // Type assertion to fix linter error
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) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automattic/mcp-wordpress-remote",
3
- "version": "0.2.16",
3
+ "version": "0.2.18",
4
4
  "description": "MCP WordPress Remote proxy server",
5
5
  "engines": {
6
6
  "node": ">=18.0.0"