You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@community.apache.org by po...@apache.org on 2026/10/20 19:03:20 UTC

(comdev) branch main updated: Support running MCP with a proxy (#55)

This is an automated email from the ASF dual-hosted git repository.

potiuk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/comdev.git


The following commit(s) were added to refs/heads/main by this push:
     new a075cf8  Support running MCP with a proxy (#55)
a075cf8 is described below

commit a075cf80de67beed107af56197fdf9a590767c51
Author: Mike Drob <md...@apache.org>
AuthorDate: Tue Oct 20 14:03:15 2026 -0500

    Support running MCP with a proxy (#55)
    
    * Support running MCP with a proxy
    
    - Bump minimum Node version to 22.21
    - Document using NODE_USE_ENV_PROXY env
    
    * missing json tag
    
    Co-authored-by: Jarek Potiuk <ja...@potiuk.com>
    
    * Update .github/workflows/mcp-tests.yml
    
    Co-authored-by: Jarek Potiuk <ja...@potiuk.com>
    
    * package-lock.json
    
    * better proxy check
    
    * Exclude Node 23 from the engines range and fix its upgrade hint
    
    Node 23 never got the env proxy support, but ">=22.21" accepted it and
    the runtime warning told 23.x users to upgrade to "22.21 or later",
    which they already were. Use "^22.21 || >=24" and say so in the
    message, READMEs and AGENTS.md. Note that the dispatcher check reads
    an undici-internal global and can give a false warning.
    
    Generated-by: Claude Opus 5
    
    ---------
    
    Co-authored-by: Jarek Potiuk <ja...@potiuk.com>
---
 .github/workflows/mcp-tests.yml           |  2 +-
 AGENTS.md                                 |  4 ++--
 mcp/apache-projects-mcp/README.md         | 19 ++++++++++++++++++-
 mcp/apache-projects-mcp/index.js          | 25 +++++++++++++++++++++++++
 mcp/apache-projects-mcp/package-lock.json |  3 +++
 mcp/apache-projects-mcp/package.json      |  3 +++
 mcp/ponymail-mcp/README.md                | 19 +++++++++++++++++++
 mcp/ponymail-mcp/index.js                 | 25 +++++++++++++++++++++++++
 mcp/ponymail-mcp/package-lock.json        |  2 +-
 mcp/ponymail-mcp/package.json             |  2 +-
 10 files changed, 98 insertions(+), 6 deletions(-)

diff --git a/.github/workflows/mcp-tests.yml b/.github/workflows/mcp-tests.yml
index f106ccc..e8c47d3 100644
--- a/.github/workflows/mcp-tests.yml
+++ b/.github/workflows/mcp-tests.yml
@@ -27,7 +27,7 @@ jobs:
       fail-fast: false
       matrix:
         project: ["ponymail-mcp", "apache-projects-mcp"]
-        node-version: ["20", "22"]
+        node-version: ["22.21", "24"]
 
     defaults:
       run:
diff --git a/AGENTS.md b/AGENTS.md
index 271854b..e00016e 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -7,8 +7,8 @@ repository. Read this before making changes.
 
 | Path | What it is | Toolchain |
 |------|------------|-----------|
-| `mcp/ponymail-mcp/` | MCP server for Apache PonyMail archives | Node.js (≥20), npm |
-| `mcp/apache-projects-mcp/` | MCP server for `projects.apache.org` data | Node.js (≥20), npm |
+| `mcp/ponymail-mcp/` | MCP server for Apache PonyMail archives | Node.js (^22.21 or ≥24), npm |
+| `mcp/apache-projects-mcp/` | MCP server for `projects.apache.org` data | Node.js (^22.21 or ≥24), npm |
 | `asf-highlights/` | ASF activity / birthday report scripts | Python via `uv` (PEP-723 inline scripts) |
 | `project-activity/` | Project activity report script | Python via `uv` (PEP-723 inline scripts) |
 | `scripts/` | Repo tooling (license allowlist check, git hooks) | Node / Bash |
diff --git a/mcp/apache-projects-mcp/README.md b/mcp/apache-projects-mcp/README.md
index feda99f..f044395 100644
--- a/mcp/apache-projects-mcp/README.md
+++ b/mcp/apache-projects-mcp/README.md
@@ -50,7 +50,7 @@ All data is fetched from `https://projects.apache.org/json/foundation/` and cach
 
 ## Requirements
 
-- Node.js 20 or later
+- Node.js 22.21+ (22.x line) or 24+ (Node 23 lacks the env proxy support)
 - An MCP-compatible client
 
 ## Installation
@@ -90,6 +90,23 @@ Example stdio configuration:
 
 Adjust the path to match your local checkout.
 
+### Behind a proxy
+
+Node's built-in `fetch` only honors `HTTPS_PROXY` / `HTTP_PROXY` / `NO_PROXY`
+when `NODE_USE_ENV_PROXY=1` is set at process startup. Set both in the
+server's `env` block:
+
+```json
+"env": {
+  "HTTPS_PROXY": "http://proxy.example.com:3128",
+  "NODE_USE_ENV_PROXY": "1"
+}
+```
+
+The server prints a warning to stderr if a proxy variable is set but Node's
+proxy support is off. Only the value `1` enables it; `--use-env-proxy` in
+`NODE_OPTIONS` works too.
+
 ## Example questions
 
 Once configured in an MCP client, you can ask things like:
diff --git a/mcp/apache-projects-mcp/index.js b/mcp/apache-projects-mcp/index.js
index 83b7cb5..5795d77 100644
--- a/mcp/apache-projects-mcp/index.js
+++ b/mcp/apache-projects-mcp/index.js
@@ -746,6 +746,31 @@ server.tool(
 // ---------------------------------------------------------------------------
 
 if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
+  // Node's built-in fetch only uses proxy variables when started with
+  // NODE_USE_ENV_PROXY=1 or --use-env-proxy (on the CLI or in NODE_OPTIONS), so a
+  // proxy variable alone would be silently ignored. Rather than re-implement
+  // Node's parsing of those, check whether it installed its proxy dispatcher.
+  // Node older than 22.21, and Node 23, have no env proxy support ("engines" is only
+  // advisory), so there the fix is upgrading, not setting the variable.
+  if (
+    ["HTTPS_PROXY", "https_proxy", "HTTP_PROXY", "http_proxy"].some((v) => process.env[v]) &&
+    globalThis[Symbol.for("undici.globalDispatcher.1")]?.constructor?.name !== "EnvHttpProxyAgent"
+  ) {
+    const [major, minor] = process.versions.node.split(".").map(Number);
+    // Added in Node 24.0 and backported to 22.21; Node 23 never got it.
+    // The dispatcher check above reads an undici-internal global, so a custom
+    // dispatcher (or a future undici change) can trigger a false warning; it
+    // only warns, never blocks.
+    const nodeHasEnvProxy = major >= 24 || (major === 22 && minor >= 21);
+    console.error(
+      "apache-projects-mcp: a proxy variable is set but Node's env proxy support is off; " +
+        "requests will NOT use the proxy. " +
+        (nodeHasEnvProxy
+          ? "Set NODE_USE_ENV_PROXY=1 in the server environment."
+          : `Node ${process.versions.node} cannot use a proxy; upgrade to Node 22.21+ (22.x line) or 24+.`)
+    );
+  }
+
   // Warm cache on startup (non-blocking — tools will fetch on demand if this is slow)
   warmCache().catch(() => {});
 
diff --git a/mcp/apache-projects-mcp/package-lock.json b/mcp/apache-projects-mcp/package-lock.json
index d52d39f..bcf9b33 100644
--- a/mcp/apache-projects-mcp/package-lock.json
+++ b/mcp/apache-projects-mcp/package-lock.json
@@ -10,6 +10,9 @@
       "dependencies": {
         "@modelcontextprotocol/sdk": "^1.31.0",
         "zod": "^4.0.0"
+      },
+      "engines": {
+        "node": "^22.21 || >=24"
       }
     },
     "node_modules/@hono/node-server": {
diff --git a/mcp/apache-projects-mcp/package.json b/mcp/apache-projects-mcp/package.json
index 9766f9d..96dddf3 100644
--- a/mcp/apache-projects-mcp/package.json
+++ b/mcp/apache-projects-mcp/package.json
@@ -9,6 +9,9 @@
     "test": "node --test",
     "licenses": "node ../../scripts/check-licenses.mjs ."
   },
+  "engines": {
+    "node": "^22.21 || >=24"
+  },
   "dependencies": {
     "@modelcontextprotocol/sdk": "^1.31.0",
     "zod": "^4.0.0"
diff --git a/mcp/ponymail-mcp/README.md b/mcp/ponymail-mcp/README.md
index 70046bd..2c8adb3 100644
--- a/mcp/ponymail-mcp/README.md
+++ b/mcp/ponymail-mcp/README.md
@@ -19,6 +19,8 @@ An MCP (Model Context Protocol) server that provides access to the [Apache PonyM
 
 ## Setup
 
+Requires Node.js 22.21+ (22.x line) or 24+; Node 23 lacks the env proxy support.
+
 ```bash
 cd ponymail-mcp
 npm install
@@ -33,6 +35,23 @@ Add a local (stdio) MCP server with:
 
 Refer to your MCP client's documentation for how to add a local stdio server.
 
+### Behind a proxy
+
+Node's built-in `fetch` only honors `HTTPS_PROXY` / `HTTP_PROXY` / `NO_PROXY`
+when `NODE_USE_ENV_PROXY=1` is set at process startup. Set both in the
+server's `env` block:
+
+```json
+"env": {
+  "HTTPS_PROXY": "http://proxy.example.com:3128",
+  "NODE_USE_ENV_PROXY": "1"
+}
+```
+
+The server prints a warning to stderr if a proxy variable is set but Node's
+proxy support is off. Only the value `1` enables it; `--use-env-proxy` in
+`NODE_OPTIONS` works too.
+
 ## Environment Variables
 
 | Variable | Default | Description |
diff --git a/mcp/ponymail-mcp/index.js b/mcp/ponymail-mcp/index.js
index 799f55b..149b3ad 100644
--- a/mcp/ponymail-mcp/index.js
+++ b/mcp/ponymail-mcp/index.js
@@ -43,6 +43,31 @@ import {
 } from "./restrictions.js";
 import { Mail, extractListDomain, countDescendants } from "./mail.js";
 
+// Node's built-in fetch only uses proxy variables when started with
+// NODE_USE_ENV_PROXY=1 or --use-env-proxy (on the CLI or in NODE_OPTIONS), so a
+// proxy variable alone would be silently ignored. Rather than re-implement
+// Node's parsing of those, check whether it installed its proxy dispatcher.
+// Node older than 22.21, and Node 23, have no env proxy support ("engines" is only
+// advisory), so there the fix is upgrading, not setting the variable.
+if (
+  ["HTTPS_PROXY", "https_proxy", "HTTP_PROXY", "http_proxy"].some((v) => process.env[v]) &&
+  globalThis[Symbol.for("undici.globalDispatcher.1")]?.constructor?.name !== "EnvHttpProxyAgent"
+) {
+  const [major, minor] = process.versions.node.split(".").map(Number);
+  // Added in Node 24.0 and backported to 22.21; Node 23 never got it.
+  // The dispatcher check above reads an undici-internal global, so a custom
+  // dispatcher (or a future undici change) can trigger a false warning; it
+  // only warns, never blocks.
+  const nodeHasEnvProxy = major >= 24 || (major === 22 && minor >= 21);
+  console.error(
+    "ponymail-mcp: a proxy variable is set but Node's env proxy support is off; " +
+      "requests will NOT use the proxy. " +
+      (nodeHasEnvProxy
+        ? "Set NODE_USE_ENV_PROXY=1 in the server environment."
+        : `Node ${process.versions.node} cannot use a proxy; upgrade to Node 22.21+ (22.x line) or 24+.`)
+  );
+}
+
 const BASE_URL = process.env.PONYMAIL_BASE_URL || "https://lists.apache.org";
 
 // API endpoint suffix and method selector. ".json" (default) uses POST with
diff --git a/mcp/ponymail-mcp/package-lock.json b/mcp/ponymail-mcp/package-lock.json
index c660354..74d3fc8 100644
--- a/mcp/ponymail-mcp/package-lock.json
+++ b/mcp/ponymail-mcp/package-lock.json
@@ -11,7 +11,7 @@
         "@modelcontextprotocol/sdk": "^1.31.0"
       },
       "engines": {
-        "node": ">=20"
+        "node": "^22.21 || >=24"
       }
     },
     "node_modules/@hono/node-server": {
diff --git a/mcp/ponymail-mcp/package.json b/mcp/ponymail-mcp/package.json
index 41a9ffe..3b95586 100644
--- a/mcp/ponymail-mcp/package.json
+++ b/mcp/ponymail-mcp/package.json
@@ -10,7 +10,7 @@
     "licenses": "node ../../scripts/check-licenses.mjs ."
   },
   "engines": {
-    "node": ">=20"
+    "node": "^22.21 || >=24"
   },
   "dependencies": {
     "@modelcontextprotocol/sdk": "^1.31.0"