Skip to content

Conversation

@elasticdotventures
Copy link

Q A
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets #6026
License MIT
Doc PR https://github.com/promptexecution/pm2-mcp

Copilot AI review requested due to automatic review settings December 3, 2025 11:39
@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
1 out of 2 committers have signed the CLA.

✅ elasticdotventures
❌ Copilot
You have signed the CLA already but the status is still pending? Let us recheck it.

@elasticdotventures elasticdotventures changed the base branch from master to development December 3, 2025 11:39
Copilot finished reviewing on behalf of elasticdotventures December 3, 2025 11:40
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adds MCP (Model Context Protocol) server functionality to PM2, enabling AI assistants to manage PM2 processes. The changes include adding a new MCP server implementation, corresponding tests, new dependencies, and updates to packaging configurations to support Node.js 22+.

Key changes:

  • New MCP server exposing PM2 operations as tools and resources
  • Addition of @modelcontextprotocol/sdk and zod dependencies
  • Node.js minimum version raised from 16.0.0 to 22.0.0
  • New pm2-mcp binary for running the MCP server
  • Comprehensive test suite for the MCP server

Reviewed changes

Copilot reviewed 9 out of 13 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
package.json Added MCP dependencies, new pm2-mcp script and binary, updated Node.js requirement to >=22.0.0
pnpm-lock.yaml New lockfile reflecting dependency additions and pnpm package manager adoption
lib/mcp/server.js Main MCP server implementation with tools for PM2 operations and resource endpoints
test/mcp/server.mocha.js Comprehensive test suite covering MCP server functionality
test/unit.sh Added new MCP test to unit test runner
bin/pm2-mcp New executable binary for the MCP server
packager/* Updated packaging files for Debian, RPM, and Alpine to require Node.js >=22
README.md Documentation for the new MCP server feature
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

"version": "6.0.14",
"engines": {
"node": ">=16.0.0"
"node": ">=22.0.0"
Copy link

Copilot AI Dec 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The minimum Node.js version requirement has been raised from >=16.0.0 to >=22.0.0. This is a significant breaking change that should be clearly documented and justified. Node.js 22 is quite recent, and this will prevent many users on LTS versions (18.x, 20.x) from using this version of PM2. Consider whether this strict requirement is necessary, especially since the MCP SDK only requires Node.js >=18.

Suggested change
"node": ">=22.0.0"
"node": ">=18.0.0"

Copilot uses AI. Check for mistakes.
PM2 now bundles an [MCP](https://modelcontextprotocol.io/specification/2025-11-25) stdio server that exposes the core process controls (list, describe, start, restart, reload, stop, delete, log flush/rotation, dump, daemon kill) plus process resources.

- Run it with `pm2-mcp` (or `npm run mcp`) and point your MCP client at that stdio command.
- Prefer the Streamable HTTP transport for long-lived usage: `pm2-mcp --transport http --port 8849 --host 0.0.0.0 --path /mcp` (env aliases: `PM2_MCP_TRANSPORT`, `PM2_MCP_PORT`, `PM2_MCP_HOST`, `PM2_MCP_PATH`).
Copy link

Copilot AI Dec 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The guidance to run the MCP server over HTTP with --host 0.0.0.0 exposes a powerful PM2 management API to the public network without authentication or TLS. An attacker on the same network (or Internet, if reachable) could remotely start/stop/delete processes, rotate logs, or kill the PM2 daemon. Use HTTPS with TLS (e.g., behind a reverse proxy), require strong authentication (API key/token or mTLS), and default-bind to 127.0.0.1; document firewalling if remote access is required.

Suggested change
- Prefer the Streamable HTTP transport for long-lived usage: `pm2-mcp --transport http --port 8849 --host 0.0.0.0 --path /mcp` (env aliases: `PM2_MCP_TRANSPORT`, `PM2_MCP_PORT`, `PM2_MCP_HOST`, `PM2_MCP_PATH`).
- Prefer the Streamable HTTP transport for long-lived usage: `pm2-mcp --transport http --port 8849 --host 127.0.0.1 --path /mcp` (env aliases: `PM2_MCP_TRANSPORT`, `PM2_MCP_PORT`, `PM2_MCP_HOST`, `PM2_MCP_PATH`).
> ⚠️ **Security Warning:**
> The MCP server exposes powerful PM2 management APIs. **Do not bind to `0.0.0.0` or expose the MCP server to public or untrusted networks without proper security controls.**
> For production or remote access, always:
> - Use HTTPS (e.g., run behind a reverse proxy with TLS termination)
> - Require strong authentication (API key/token or mutual TLS)
> - Bind to `127.0.0.1` by default and only open firewall ports if strictly necessary
> - Document and restrict access via firewall rules
> Exposing the MCP server without these controls can allow attackers to start/stop/delete processes, rotate logs, or kill the PM2 daemon.

Copilot uses AI. Check for mistakes.
PM2 now bundles an [MCP](https://modelcontextprotocol.io/specification/2025-11-25) stdio server that exposes the core process controls (list, describe, start, restart, reload, stop, delete, log flush/rotation, dump, daemon kill) plus process resources.

- Run it with `pm2-mcp` (or `npm run mcp`) and point your MCP client at that stdio command.
- Prefer the Streamable HTTP transport for long-lived usage: `pm2-mcp --transport http --port 8849 --host 0.0.0.0 --path /mcp` (env aliases: `PM2_MCP_TRANSPORT`, `PM2_MCP_PORT`, `PM2_MCP_HOST`, `PM2_MCP_PATH`).
Copy link

Copilot AI Dec 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example command pm2-mcp --transport http --port 8849 --host 0.0.0.0 --path /mcp exposes the MCP control surface over cleartext HTTP on all interfaces without any authentication. This enables remote manipulation of PM2-managed processes by anyone who can reach the port. Prefer HTTPS with TLS, restrict binding to 127.0.0.1 by default, and enforce authentication (API key/token or mTLS).

Suggested change
- Prefer the Streamable HTTP transport for long-lived usage: `pm2-mcp --transport http --port 8849 --host 0.0.0.0 --path /mcp` (env aliases: `PM2_MCP_TRANSPORT`, `PM2_MCP_PORT`, `PM2_MCP_HOST`, `PM2_MCP_PATH`).
- **Secure usage recommended:** Always bind the MCP server to `127.0.0.1` (localhost) and use HTTPS with authentication. For example:<br>
<code>pm2-mcp --transport https --port 8849 --host 127.0.0.1 --path /mcp --auth-token &lt;YOUR_TOKEN&gt; --tls-cert &lt;PATH_TO_CERT&gt; --tls-key &lt;PATH_TO_KEY&gt;</code><br>
<br>
<b>Warning:</b> <i>Do not expose the MCP server on public interfaces (e.g., <code>0.0.0.0</code>) or use cleartext HTTP without authentication. This can allow remote manipulation of PM2-managed processes by anyone who can reach the port.</i><br>
<br>
(env aliases: <code>PM2_MCP_TRANSPORT</code>, <code>PM2_MCP_PORT</code>, <code>PM2_MCP_HOST</code>, <code>PM2_MCP_PATH</code>)

Copilot uses AI. Check for mistakes.
Comment on lines +13 to +17
run-mcp-http host="127.0.0.1" port="8849" path="/mcp":
#!/usr/bin/env bash
set -euo pipefail
pm2-mcp --transport http --host {{host}} --port {{port}} --path {{path}}

Copy link

Copilot AI Dec 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The run-mcp-http recipe starts the MCP server using cleartext http and binds to a user-provided host (default 127.0.0.1) with no authentication. If the host is set to 0.0.0.0 or a public IP, this would expose PM2 controls to remote clients without encryption or auth. Enforce localhost binding by default, support HTTPS/TLS, and require an authentication mechanism (API key/token or mTLS).

Suggested change
run-mcp-http host="127.0.0.1" port="8849" path="/mcp":
#!/usr/bin/env bash
set -euo pipefail
pm2-mcp --transport http --host {{host}} --port {{port}} --path {{path}}
run-mcp-http host="127.0.0.1" port="8849" path="/mcp" tls_cert="" tls_key="" auth_token="":
#!/usr/bin/env bash
set -euo pipefail
# Enforce localhost binding unless TLS and authentication are provided
if [[ "{{host}}" != "127.0.0.1" && "{{host}}" != "localhost" ]]; then
if [[ -z "{{tls_cert}}" || -z "{{tls_key}}" || -z "{{auth_token}}" ]]; then
echo "ERROR: Refusing to start pm2-mcp on non-localhost host without TLS and authentication."
echo "Provide tls_cert, tls_key, and auth_token to enable secure remote access."
exit 1
fi
fi
# Choose transport based on TLS parameters
if [[ -n "{{tls_cert}}" && -n "{{tls_key}}" ]]; then
TRANSPORT="https"
TLS_ARGS="--tls-cert {{tls_cert}} --tls-key {{tls_key}}"
else
TRANSPORT="http"
TLS_ARGS=""
fi
# Add authentication argument if provided
if [[ -n "{{auth_token}}" ]]; then
AUTH_ARGS="--auth-token {{auth_token}}"
else
AUTH_ARGS=""
fi
pm2-mcp --transport $TRANSPORT --host {{host}} --port {{port}} --path {{path}} $TLS_ARGS $AUTH_ARGS

Copilot uses AI. Check for mistakes.
Comment on lines +19 to +23
register-codex-http name="pm2-mcp-http" host="127.0.0.1" port="8849" path="/mcp":
#!/usr/bin/env bash
set -euo pipefail
url="http://{{host}}:{{port}}{{path}}"
codex mcp add {{name}} --url "$url"
Copy link

Copilot AI Dec 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The register-codex-http recipe registers an HTTP endpoint using http://{{host}}:{{port}}{{path}} without any authentication. If the MCP server is exposed beyond localhost, this registration would point clients at an unauthenticated, cleartext control surface. Use https:// with TLS and include an auth mechanism (API key/token or mTLS), and recommend registering 127.0.0.1 only unless properly secured.

Suggested change
register-codex-http name="pm2-mcp-http" host="127.0.0.1" port="8849" path="/mcp":
#!/usr/bin/env bash
set -euo pipefail
url="http://{{host}}:{{port}}{{path}}"
codex mcp add {{name}} --url "$url"
# WARNING: Do not expose the MCP server beyond localhost without HTTPS and authentication!
# If you must expose externally, use https:// and provide an API key or mTLS.
register-codex-http name="pm2-mcp-http" host="127.0.0.1" port="8849" path="/mcp" api_key="":
#!/usr/bin/env bash
set -euo pipefail
url="https://{{host}}:{{port}}{{path}}"
if [ -n "{{api_key}}" ]; then
codex mcp add {{name}} --url "$url" --header "Authorization: Bearer {{api_key}}"
else
codex mcp add {{name}} --url "$url"
fi

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants