Welcome to the PatternFly MCP Server codebase. This guide will help you understand what this project does, how it's organized, and how to navigate it confidently.
This is a Model Context Protocol (MCP) server that gives AI assistants (like Claude, Copilot, etc.) structured access to PatternFly design system documentation, component schemas, and guidelines. Think of it as a smart, searchable library that an LLM can query to get accurate PatternFly information while helping developers write code.
In practical terms: when a developer using an AI assistant asks "how do I use the PatternFly Button component?", this server provides the AI with the actual PatternFly docs and JSON schemas rather than relying on potentially outdated training data.
- MCP (Model Context Protocol): An open standard for connecting AI models to external data sources and tools. This server implements the MCP specification.
- Tools: Functions the AI can call (like "search docs" or "fetch docs").
- Resources: Data the AI can read via URI templates (like
patternfly://docs/Button). - Transport: How the server communicates - either STDIO (piped stdin/stdout) or HTTP.
# Install dependencies
npm install
# Build (required before running)
npm run build
# Run the server locally
npm start
# Run in development watch mode (auto-rebuilds on changes)
npm run start:dev
# Run all tests
npm test
# Run just unit tests in watch mode
npm run test:dev
# Run integration/e2e tests (requires a build first)
npm run test:integration
# Inspect the server visually via the MCP Inspector
npx -y @modelcontextprotocol/inspector node dist/cli.jspatternfly-mcp/
|-- src/ # All source code lives here
| |-- index.ts # Public API entry point (start, createMcpTool)
| |-- cli.ts # CLI entry point (node version check, calls main)
| |-- server.ts # Core server: creates McpServer, registers tools & resources
| |-- docs.json # The documentation catalog (~130 components, ~324 doc URLs)
| |-- __tests__/ # Unit tests (mirrors the src/ file structure)
| |-- tool.* # Built-in MCP tool implementations
| |-- resource.* # Built-in MCP resource implementations
| |-- server.* # Server subsystems (caching, HTTP, logging, search, etc.)
| |-- options.* # Configuration and CLI option parsing
| |-- patternFly.* # PatternFly-specific logic (search, data loading, helpers)
| |-- docs.* # Documentation data loading and indexing
| +-- logger.ts # Structured logging via Node.js diagnostics_channel
|
|-- tests/
| |-- e2e/ # End-to-end transport tests (STDIO, HTTP, CLI)
| +-- audit/ # Documentation URL validation tests
|
|-- docs/ # Project documentation
| |-- architecture.md # Design decisions and roadmap
| |-- usage.md # User-facing usage guide
| |-- development.md # CLI options and programmatic API
| +-- examples/ # Runnable example scripts
|
|-- guidelines/ # AI agent development guidelines
|-- .github/workflows/ # CI/CD (build, publish, audit)
+-- dist/ # Build output (generated, not committed)
Files use dot-notation namespacing to group related code without nested directories:
| Prefix | Purpose |
|---|---|
server.* |
Core server subsystems (caching, HTTP, logging, search, schema, stats, helpers) |
tool.* |
Built-in MCP tool implementations |
resource.* |
Built-in MCP resource implementations |
options.* |
Configuration, defaults, CLI parsing, validation |
patternFly.* |
PatternFly-specific business logic |
docs.* |
Documentation catalog loading and indexing |
For example, server.caching.ts is the caching subsystem of the server; server.http.ts handles HTTP transport. This flat structure means you can find any file with a simple search rather than navigating nested folders.
Understanding the startup flow helps you trace how everything connects:
cli.ts -- checks Node version, calls main()
|
v
index.ts :: main() -- parses CLI options, merges config
|
v
server.ts :: runServer() -- creates McpServer instance
|-- registers built-in tools (usePatternFlyDocs, searchPatternFlyDocs)
|-- registers built-in resources (6 resources + auto-generated meta resources)
|-- sets up logging and stats tracking
|-- starts transport (STDIO or HTTP)
+-- returns ServerInstance { stop, isRunning, getStats, onLog }
These are the main way AI assistants interact with PatternFly data:
1. searchPatternFlyDocs (src/tool.searchPatternFlyDocs.ts)
- The "find" tool - searches the catalog by name
- Input: a search query (e.g., "button", "chart", or
*for all) - Output: matching component names and documentation URLs
- Uses fuzzy search with Levenshtein distance for typo tolerance
2. usePatternFlyDocs (src/tool.patternFlyDocs.ts)
- The "read" tool - fetches actual documentation content
- Input: either a component
nameOR a list of documentationurlListvalues - Output: markdown documentation + JSON component schemas
- Fetches content from raw GitHub URLs at runtime
Typical AI workflow: search first to find what's available, then use the results to fetch the actual docs.
Resources provide a URI-based alternative to tools. MCP clients can browse and read them via URI templates:
| Resource | URI Pattern | What it provides |
|---|---|---|
| Docs Index | patternfly://docs/index |
List all documentation entries |
| Docs Template | patternfly://docs/{name} |
Get docs for a specific component |
| Components Index | patternfly://components/index |
List all component names |
| Schemas Index | patternfly://schemas/index |
List available JSON schemas |
| Schemas Template | patternfly://schemas/{name} |
Get a specific component schema |
| Context | patternfly://context |
Server context and capabilities |
Each resource also gets an auto-generated *-meta companion resource that documents the available query parameters (version, category, section).
This is the heart of the server's data. It's a JSON file containing ~130 PatternFly component/resource entries, each pointing to raw GitHub URLs for their documentation markdown files.
{
"version": "1",
"meta": { "totalEntries": 130, "totalDocs": 324 },
"docs": {
"Button": [
{
"displayName": "Button",
"description": "Design Guidelines for the button component",
"section": "components",
"category": "design-guidelines",
"path": "https://raw.githubusercontent.com/...",
"version": "v6"
}
]
}
}The catalog is loaded and indexed at startup by docs.embedded.ts and patternFly.getResources.ts, creating lookup maps by path, version, keyword, and URI for fast access.
Beyond the two built-in tools, the server supports external tool plugins:
server.tools.ts -- composes built-in + external tools
|
v
server.toolsUser.ts -- normalizes tool definitions (files, packages, inline objects)
|
v
server.toolsHost.ts -- spawns child process for external tools
|
v
server.toolsIpc.ts -- IPC protocol between main server and tool host
External tools run in an isolated child process. In strict isolation mode, the child process uses Node.js permission flags to restrict filesystem and network access.
The search system is layered:
server.search.ts -- generic fuzzy search engine (Levenshtein distance)
|
v
patternFly.search.ts -- PatternFly-specific search (version/category filtering)
|
v
tool.searchPatternFlyDocs.ts -- MCP tool wrapper exposing search to AI clients
Search supports exact, prefix, suffix, contains, partial, and fuzzy match types. Results are ranked by match quality.
server.caching.ts provides a memo() wrapper used extensively throughout the codebase. Memoized functions cache their results to avoid redundant computation or network requests. Key memoized operations:
- Resource data loading (single-entry cache, computed once)
- Search results (10-entry cache)
- Document fetching (avoids re-downloading the same markdown)
- Server instance itself (prevents duplicate servers on the same port)
The server uses Node.js diagnostics_channel for structured logging rather than console output (since console.log would pollute STDIO transport). The logging pipeline:
logger.ts -- core log API (log.debug, log.info, log.warn, log.error)
|
v
server.logger.ts -- subscribes to MCP server events, forwards to channel
|
v
server.stats.ts -- tracks traffic and health metrics via diagnostics channel
options.ts -- CLI argument parsing (--http, --port, --tool, etc.)
options.defaults.ts -- all default values (search limits, URLs, versions, etc.)
options.context.ts -- AsyncLocalStorage-based session context
options.assertions.ts -- validation for option values
The options system uses Node.js AsyncLocalStorage to maintain per-session configuration, which matters when the server handles multiple concurrent connections via HTTP.
| Package | Purpose |
|---|---|
@modelcontextprotocol/sdk |
The MCP protocol implementation |
@patternfly/patternfly-component-schemas |
Machine-readable JSON schemas for PatternFly components |
fastest-levenshtein |
Fuzzy string matching for search |
zod |
Schema validation (required by MCP SDK for tool input schemas) |
pid-port |
Port conflict detection for HTTP mode |
semver |
Version string parsing and comparison |
The project has three test tiers:
Run with npm test. Every source module has a corresponding test file. Tests mock external dependencies (network, filesystem, child processes) so they run fast and offline.
Coverage thresholds enforced in CI:
- Lines/Statements: 85%
- Branches/Functions: 75%
Run with npm run test:integration (requires npm run build first). These start real server instances and test actual STDIO and HTTP transport communication.
Run with npm run test:audit. These validate that the URLs in docs.json are reachable. Runs daily in CI and on docs.json changes.
Edit src/docs.json following the existing entry format. There's also a skill/guide at guidelines/skills/add-docs-links/ with detailed instructions. Run npm run test:audit to validate your URLs.
See the examples in docs/examples/ (e.g., toolPluginHelloWorld.js, toolPluginGitStatus.js). External tools are loaded via the --tool CLI flag or the toolModules programmatic option.
import { start, createMcpTool } from '@patternfly/patternfly-mcp';
const server = await start({ http: { port: 8080 } });
// server.stop(), server.isRunning(), server.getStats(), server.onLog()See docs/development.md for the full programmatic API.
Test files mirror source files: src/server.caching.ts is tested by src/__tests__/server.caching.test.ts. Check jest.setupTests.ts for global mocks that might affect behavior.
Three GitHub Actions workflows:
| Workflow | Trigger | What it does |
|---|---|---|
integration.yml |
Push/PR | Lint, test, build across Node 20/22/24 |
audit.yml |
Daily + docs.json changes | Validate documentation URLs |
publishing.yml |
GitHub release | Build and publish to npm |
When you're navigating this codebase, think of it in three layers:
- Data layer:
docs.json+docs.embedded.ts+patternFly.getResources.ts- loads and indexes the PatternFly documentation catalog - Business logic layer:
tool.*+resource.*+patternFly.search.ts- implements search, filtering, and document retrieval - Infrastructure layer:
server.*+options.*+logger.ts- MCP protocol handling, transport, caching, configuration, logging
Changes to PatternFly content go through layer 1. New ways to query or present data go through layer 2. Server behavior changes go through layer 3.