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
103 changes: 101 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ These are the most relevant NPM scripts from package.json:

## Usage

The MCP server communicates over stdio and provides access to PatternFly documentation through the following tools. Both tools accept an argument named `urlList` which must be an array of strings. Each string is either:
The MCP server can communicate over **stdio** (default) or **HTTP** transport. It provides access to PatternFly documentation through the following tools. Both tools accept an argument named `urlList` which must be an array of strings. Each string is either:
- An external URL (e.g., a raw GitHub URL to a .md file), or
- A local file path (e.g., documentation/.../README.md). When running with the --docs-host flag, these paths are resolved under the llms-files directory instead.

Expand Down Expand Up @@ -143,6 +143,68 @@ npx @patternfly/patternfly-mcp --docs-host

Then, passing a local path such as react-core/6.0.0/llms.txt in urlList will load from llms-files/react-core/6.0.0/llms.txt.

## HTTP transport mode

By default, the server communicates over stdio. To run the server over HTTP instead, use the `--http` flag. This enables the server to accept HTTP requests on a specified port and host.

### Basic HTTP usage

```bash
npx @patternfly/patternfly-mcp --http
```

This starts the server on `http://127.0.0.1:8080` (default port and host).

### HTTP options

- `--http`: Enable HTTP transport mode (default: stdio)
- `--port <number>`: Port number to listen on (default: 8080)
- `--host <string>`: Host address to bind to (default: 127.0.0.1)
- `--allowed-origins <origins>`: Comma-separated list of allowed CORS origins
- `--allowed-hosts <hosts>`: Comma-separated list of allowed host headers

#### Security note: DNS rebinding protection (default)

This server enables DNS rebinding protection by default when running in HTTP mode. If you're behind a proxy or load balancer, ensure the client sends a correct `Host` header and configure `--allowed-hosts` accordingly. Otherwise, requests may be rejected by design. For example:

```bash
npx @patternfly/patternfly-mcp --http \
--host 0.0.0.0 --port 8080 \
--allowed-hosts "localhost,127.0.0.1,example.com"
```

If your client runs on a different origin, also set `--allowed-origins` to allow CORS. Example:

```bash
npx @patternfly/patternfly-mcp --http \
--allowed-origins "http://localhost:5173,https://app.example.com"
```

### Examples

Start on a custom port:
```bash
npx @patternfly/patternfly-mcp --http --port 8080
```

Start on a specific host:
```bash
npx @patternfly/patternfly-mcp --http --host 0.0.0.0 --port 8080
```

Start with CORS allowed origins:
```bash
npx @patternfly/patternfly-mcp --http --allowed-origins "http://localhost:3001,https://example.com"
```

### Port conflict handling

If the specified port is already in use, the server will:
- Display a helpful error message with the process ID (if available)
- Suggest using a different port with `--port` or stopping the process using the port

**Note**: The server uses memoization to prevent duplicate server instances within the same process. If you need to restart the server, simply stop the existing instance and start a new one.

## MCP client configuration examples

Most MCP clients use a JSON configuration to specify how to start this server. The server itself only reads CLI flags and environment variables, not the JSON configuration. Below are examples you can adapt to your MCP client.
Expand Down Expand Up @@ -190,6 +252,41 @@ Most MCP clients use a JSON configuration to specify how to start this server. T
}
```

### HTTP transport mode

```json
{
"mcpServers": {
"patternfly-docs": {
"command": "npx",
"args": ["-y", "@patternfly/patternfly-mcp@latest", "--http", "--port", "8080"],
"description": "PatternFly docs (HTTP transport)"
}
}
}
```

### HTTP transport with custom options

```json
{
"mcpServers": {
"patternfly-docs": {
"command": "npx",
"args": [
"-y",
"@patternfly/patternfly-mcp@latest",
"--http",
"--port", "8080",
"--host", "0.0.0.0",
"--allowed-origins", "http://localhost:3001,https://example.com"
],
"description": "PatternFly docs (HTTP transport, custom port/host/CORS)"
}
}
}
```

## Inspector-CLI examples (tools/call)

Note: The parameter name is urlList and it must be a JSON array of strings.
Expand Down Expand Up @@ -254,7 +351,9 @@ const serverWithOptions = await start({ docsHost: true });
// Multiple options can be overridden
const customServer = await start({
docsHost: true,
// Future CLI options can be added here
http: true,
port: 8080,
host: '0.0.0.0'
});

// TypeScript users can use the CliOptions type for type safety
Expand Down
17 changes: 17 additions & 0 deletions jest.setupTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,23 @@
*/
process.env.NODE_ENV = 'local';

/**
* Note: Mock child_process to avoid issues with execSync in tests
*/
jest.mock('child_process', () => ({
...jest.requireActual('child_process'),
execSync: (...args: any) => `<execSync>${JSON.stringify(args)}</execSync>`

Check warning on line 13 in jest.setupTests.ts

View workflow job for this annotation

GitHub Actions / Integration-checks (22.x)

Unexpected any. Specify a different type

Check warning on line 13 in jest.setupTests.ts

View workflow job for this annotation

GitHub Actions / Integration-checks (20.x)

Unexpected any. Specify a different type

Check warning on line 13 in jest.setupTests.ts

View workflow job for this annotation

GitHub Actions / Integration-checks (24.x)

Unexpected any. Specify a different type
}));

/**
* Note: Mock pid-port to avoid ES module import issues in Jest
* - Returns undefined to simulate port is free (no process found)
*/
jest.mock('pid-port', () => ({
__esModule: true,
portToPid: jest.fn().mockResolvedValue(undefined)
}));

/**
* Note: Mock @patternfly/patternfly-component-schemas/json to avoid top-level await issues in Jest
* - Individual tests can override mock
Expand Down
Loading
Loading