Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 23 additions & 3 deletions .github/workflows/audit.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
name: Data Audit
name: Security & Data Audit

on:
pull_request:
paths:
- 'src/docs.json'
- 'tests/audit/**'
- 'package.json'
- 'package-lock.json'
schedule:
- cron: '0 0 * * *' # Daily at midnight
workflow_dispatch:

jobs:
audit-links:
documentation-audit:
name: Documentation Audit
runs-on: ubuntu-latest
permissions:
contents: read
Expand All @@ -19,7 +22,7 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v6.3.0
with:
node-version: 22.x
node-version: '24'
cache: npm
- name: Install dependencies
run: npm ci
Expand All @@ -30,3 +33,20 @@ jobs:
DOCS_AUDIT_MAX_TOTAL: ${{ github.event_name == 'schedule' && '0' || '50' }}
# Advisories are non-blocking for PRs
continue-on-error: ${{ github.event_name == 'pull_request' }}

dependency-audit:
name: Dependency Audit
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v6.3.0
with:
node-version: '24'
cache: npm
- name: Run npm audit
run: npm audit --omit=dev --audit-level=critical
# Advisories are non-blocking for PRs
continue-on-error: ${{ github.event_name == 'pull_request' }}
19 changes: 5 additions & 14 deletions .github/workflows/integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,30 +13,21 @@ jobs:
contents: read
strategy:
matrix:
node-version: [20.x, 22.x, 24.x]
node-version: [22.x, 24.x]
steps:
- uses: actions/checkout@v6

- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v6.3.0
with:
node-version: ${{ matrix.node-version }}
cache: npm
- name: Node.js modules cache
uses: actions/cache@v5
id: modules-cache
with:
path: ${{ github.workspace }}/node_modules
key: ${{ runner.os }}-${{ matrix.node-version }}-modules-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-${{ matrix.node-version }}-modules

- name: Install Node.js packages
if: ${{ steps.modules-cache.outputs.cache-hit != 'true' }}
run: npm ci
- name: Audit packages
run: npm audit --audit-level=high
continue-on-error: true

- name: Lint and test
run: npm run test:ci

- name: Confirm integration
if: ${{ success() }}
run: npm run test:integration
8 changes: 2 additions & 6 deletions .github/workflows/publishing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,12 @@ jobs:
permissions:
contents: read
id-token: write
strategy:
matrix:
node: [22.x]
steps:
- uses: actions/checkout@v6
- name: Setup Node.js ${{ matrix.node-version }}
- name: Setup Node.js
uses: actions/setup-node@v6.3.0
with:
node-version: ${{ matrix.node-version }}
cache: npm
node-version: '24'
registry-url: 'https://registry.npmjs.org'
- name: Install dependencies
run: npm ci
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ It is intended to be extensible to meet the needs of different teams and project
[Read more about our roadmap and how we've structured the server in our architecture docs](./docs/architecture.md).

## Requirements
- [Node.js 20+](https://nodejs.org/)
- [Node.js 22+](https://nodejs.org/)
- NPM (or equivalent package manager)

## Quick start
Expand All @@ -18,6 +18,8 @@ The PatternFly MCP Server supports multiple configurations; see the [usage docum

#### Set a basic MCP configuration

> Unable to update to the required Node.js version? [See pinned MCP configuration examples for earlier Node.js versions.](./docs/usage.md#pinned-mcp-package-version)

Minimal configuration
```json
{
Expand Down
7 changes: 3 additions & 4 deletions docs/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,7 @@ The documentation catalog `src/docs.json` pins remote resources to specific comm

#### Programmatic runtime requirements

- **Node.js 20+**: Required to run the core MCP server.
- **Node.js 22+**: Required for loading external tool plugins (`--tool`) and for developers working on advanced process isolation features.
- **Node.js 22+**: Required to run the MCP server, load external tool plugins (`--tool`), and use advanced process isolation features.

**Example: Programmatic test mode**
```typescript
Expand Down Expand Up @@ -411,7 +410,7 @@ These terms describe **how tools and their related properties are represented**

### Tool plugins

- **Plugins don't appear**: Verify the Node version (requires Node.js >= 20; >= 22 for tool plugins) and check logs (enable `--log-stderr`).
- **Plugins don't appear**: Verify the Node version (requires Node.js >= 22 for tool plugins) and check logs (enable `--log-stderr`).
- **Startup warnings/errors**: Startup `load:ack` warnings/errors from tool plugins are logged when stderr/protocol logging is enabled.
- **Schema errors**: If `tools/call` rejects with schema errors, ensure `inputSchema` is valid. See [Authoring tools](#authoring-tools) for details.
- **Network access issues**: If the tool is having network access issues, you may need to configure `--plugin-isolation none`. This is generally discouraged for security reasons but may be necessary in some cases.
Expand All @@ -424,7 +423,7 @@ These terms describe **how tools and their related properties are represented**

### General issues

- **Server won't start**: Check Node.js version (requires Node.js >= 20; >= 22 for tool plugins).
- **Server won't start**: Check Node.js version (requires Node.js >= 22 to run the server).
- **Missing tools/resources**: Verify the server started successfully and check logs with `--log-stderr`.
- **Type errors**: Ensure TypeScript types are installed: `npm install --save-dev @types/node`

Expand Down
37 changes: 33 additions & 4 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,33 @@ Access specific component documentation or technical specifications using the fo

Most MCP clients use JSON configuration to specify how the server is started. Below are examples you can adapt for your client.

### Pinned MCP package version

Depending on your environment, you may have to delay updating to the minimum Node.js version required by the server. If you are unable to upgrade your Node.js version and must remain on a previous Node.js version, you can pin your MCP configuration to the last compatible version of the server.

> **Note**: Currently, pinning to an older PatternFly MCP version means you will not receive updated documentation or new features until you "update" your pinned version. In the future, pinning a version may still make an allowance for documentation updates. [See our planned architecture.](./architecture.md#hybrid-documentation-in-progress)

#### When to choose `@latest` or a pinned version for configuration

| Node.js version | Package spec | Feature notes |
|-----------------|-------------------------------------|--------------------------------------------------------------------------------------------------------------------|
| **>=22** | `@patternfly/patternfly-mcp@latest` | Newest PatternFly features and rules. Includes **enhanced security isolation** for custom tool plugins. |
| **>=20** | `@patternfly/patternfly-mcp@1.1.0` | Standard features and rules. Lacks **custom tool plugins**; compatible with all default PatternFly configurations. |

##### Node.js 20 compatible pin

```json
{
"mcpServers": {
"patternfly-mcp": {
"command": "npx",
"args": ["-y", "@patternfly/patternfly-mcp@1.1.0"],
"description": "PatternFly rules and documentation (Node.js 20 compatible)"
}
}
}
```

### Minimal client config (stdio)

```json
Expand Down Expand Up @@ -182,14 +209,16 @@ These are **first-step checks** for common setup problems, not full diagnostics.

> **Agents**: PatternFly MCP server information is available internally through the `patternfly://context` MCP resource.

### 1. Verify Node.js Version
The PatternFly MCP server requires **Node.js 20 or higher**.
### 1. Verify Node.js version
The PatternFly MCP server requires **Node.js 22 or higher**.

- **How to check**:
- **macOS/Linux**: Open **Terminal** and type `node -v`.
- **Windows**: Open **PowerShell** or **Command Prompt** and type `node -v`.
- **Requirement**: You should see a version starting with `v20`, `v22`, or higher.
- **Solution**: If your version is lower than 20, please download and install the latest "LTS" (Long Term Support) version from [nodejs.org](https://nodejs.org/).
- **Requirement**: You should see a version starting with `v22`, or higher.
- **Solution**: If your version is lower than 22, please download and install the latest "LTS" (Long Term Support) version from [nodejs.org](https://nodejs.org/).

> **Unable to update your Node.js version?** [See pinned configuration examples for earlier Node.js versions.](#pinned-mcp-package-version)

### 2. Reset the npx Cache
If you encounter an `ERR_MODULE_NOT_FOUND` error or don't see the latest features, your system may be using a "stale" or corrupted version in its cache.
Expand Down
2 changes: 1 addition & 1 deletion guidelines/agent_behaviors.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ For a detailed overview of the system design and roadmap, see [docs/architecture
- **Validation Required**: Follow checklists; verify requirements; test thoroughly. Review [pull request warning signs](../CONTRIBUTING.md#pull-requests) to avoid common pitfalls.
- **Confirmation Required**: Confirm success; summarize changes; explain impact; verify understanding.
- **Guidance Review Scope**: Unless the user explicitly asks, do not make recommendations on improving guidance if all you're asked to do is review guidance.
- **Environment Awareness**:
- **Environment Awareness**:
- Server and plugin execution requirements are defined in `package.json`.
- Always verify environment compatibility by checking `patternfly://context` or `package.json`.
- Proactively check for environment mismatches (e.g., Node.js version) if tools fail to load.
Expand Down
6 changes: 3 additions & 3 deletions jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export default {
projects: [
{
displayName: 'unit',
roots: ['src'],
roots: ['<rootDir>/src'],
testMatch: ['<rootDir>/src/**/*.test.ts'],
setupFilesAfterEnv: ['<rootDir>/jest.setupTests.ts'],
...baseConfig,
Expand Down Expand Up @@ -64,7 +64,7 @@ export default {
},
{
displayName: 'e2e',
roots: ['tests/e2e'],
roots: ['<rootDir>/tests/e2e'],
testMatch: ['<rootDir>/tests/e2e/**/*.test.ts'],
setupFilesAfterEnv: ['<rootDir>/tests/e2e/jest.setupTests.ts'],
transformIgnorePatterns: [
Expand All @@ -74,7 +74,7 @@ export default {
},
{
displayName: 'audit',
roots: ['tests/audit'],
roots: ['<rootDir>/tests/audit'],
testMatch: ['<rootDir>/tests/audit/**/*.test.ts'],
...baseConfig
}
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@
"release": "changelog --non-cc --link-url https://github.com/patternfly/patternfly-mcp.git",
"start": "node dist/cli.js --log-stderr",
"start:dev": "tsx watch src/cli.ts --verbose --log-stderr",
"test": "npm run test:spell && npm run test:spell-docs && npm run test:lint && npm run test:types && jest --selectProjects unit --roots=src/",
"test:audit": "jest --selectProjects audit --roots=tests/audit/",
"test": "npm run test:spell && npm run test:spell-docs && npm run test:lint && npm run test:types && jest --selectProjects unit",
"test:audit": "jest --selectProjects audit",
"test:ci": "npm test -- --coverage",
"test:dev": "npm test -- --watchAll",
"test:integration": "npm run build && NODE_OPTIONS='--experimental-vm-modules' jest --selectProjects e2e --roots=tests/e2e/",
"test:integration": "npm run build && NODE_OPTIONS='--experimental-vm-modules' jest --selectProjects e2e",
"test:integration-dev": "npm run test:integration -- --watchAll",
"test:lint": "eslint .",
"test:lint-fix": "eslint . --fix",
Expand Down Expand Up @@ -84,7 +84,7 @@
"typescript-eslint": "^8.59.1"
},
"engines": {
"node": ">=20.0.0"
"node": ">=22.0.0"
},
"repository": {
"type": "git",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ exports[`options defaults should return specific properties: defaults 1`] = `
"test": {},
},
"name": "@patternfly/patternfly-mcp",
"nodeEngine": ">=20.0.0",
"nodeEngine": ">=22.0.0",
"nodeVersion": 22,
"nodeVersionPreferred": 22,
"patternflyOptions": {
Expand Down
16 changes: 8 additions & 8 deletions src/__tests__/__snapshots__/server.tools.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,14 @@ exports[`composeTools should attempt to setup creators, file package creators 1`
}
`;

exports[`composeTools should attempt to setup creators, file package creators, Node.js 20 1`] = `
exports[`composeTools should attempt to setup creators, file package creators, Node.js 22 1`] = `
{
"log": [
[
"Existing Tools Host session detected test-session-id. Shutting down the existing host before creating a new one.",
],
[
"External tool plugins require Node >= 22; skipping file-based tools.",
],
],
"toolsCount": 3,
"toolsCount": 5,
}
`;

Expand Down Expand Up @@ -112,17 +109,20 @@ exports[`composeTools should attempt to setup creators, inline and file package
}
`;

exports[`composeTools should attempt to setup creators, inline and file package creators, duplicates, Node.js 20 1`] = `
exports[`composeTools should attempt to setup creators, inline and file package creators, duplicates, Node.js 22 1`] = `
{
"log": [
[
"Existing Tools Host session detected test-session-id. Shutting down the existing host before creating a new one.",
],
[
"External tool plugins require Node >= 22; skipping file-based tools.",
"Skipping tool plugin "@patternfly/tools" – name already used by built-in/inline tool.",
],
[
"Skipping tool plugin "DOLOR " – name already used by built-in/inline tool.",
],
],
"toolsCount": 5,
"toolsCount": 6,
}
`;

Expand Down
12 changes: 6 additions & 6 deletions src/__tests__/server.tools.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -700,10 +700,10 @@ describe('composeTools', () => {
expectedModuleCount: 5
},
{
description: 'file package creators, Node.js 20',
nodeVersion: 20,
description: 'file package creators, Node.js 22',
nodeVersion: 22,
modules: ['file:///test/module.js', '@patternfly/tools'],
expectedModuleCount: 3
expectedModuleCount: 5
},
{
description: 'file package creators, Node.js 24',
Expand Down Expand Up @@ -756,16 +756,16 @@ describe('composeTools', () => {
expectedModuleCount: 6
},
{
description: 'inline and file package creators, duplicates, Node.js 20',
nodeVersion: 20,
description: 'inline and file package creators, duplicates, Node.js 22',
nodeVersion: 22,
modules: [
{ name: '@patternfly/tools', description: 'lorem ipsum', inputSchema: {}, handler: () => {} },
{ name: 'dolor', description: 'sit amet', inputSchema: z.object({}), handler: () => {} },
'file:///test/module.js',
'@patternfly/tools',
'DOLOR '
],
expectedModuleCount: 5
expectedModuleCount: 6
}
])('should attempt to setup creators, $description', async ({ modules, nodeVersion, expectedModuleCount }) => {
const mockChild = {
Expand Down
2 changes: 1 addition & 1 deletion src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ const run = async (): Promise<void> => {
} else {
// Everything else
error = new Error(
`Node.js version ${envNodeMajorVersion} found but ${appMinNodeMajorVersion} or higher is required. Update Node.js and try again.`
`Node.js version ${envNodeMajorVersion} found but ${appMinNodeMajorVersion} or higher is required. Update Node.js or pin to an earlier PatternFly MCP version for compatibility and try again.`
);
}

Expand Down
4 changes: 2 additions & 2 deletions src/options.defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -352,8 +352,8 @@ const MODE_OPTIONS: ModeOptions = {
* The application's preferred Node.js major. Typically used for
* unit testing.
*
* @note Currently hardcoded, but once Node.js 20 support is removed
* we could consider populating this from package.json engine.
* @note Currently hardcoded due to potential differences in Node.js
* versions. Review populating this from the `package.json` engine.
*/
const NODE_VERSION_PREFERRED = 22;

Expand Down
Loading
Loading