MCP server by patrickfreitasdev
HB Optimizer MCP Server v2.0
MCP (Model Context Protocol) server for diagnosing and fixing Hummingbird WordPress performance plugin issues. Uses Playwright for browser automation, pixel-diff screenshot comparison, and binary search to find minimal exclusion sets.
Works with any MCP-compatible client (Claude Desktop, Claude Code, etc.) and exports clean functions for programmatic use.
Prerequisites
- Node.js >= 18
- Playwright Chromium browser
- WordPress site with Hummingbird Pro active and the HB Optimizer Companion plugin installed
Quick Start
# 1. Install dependencies
npm install
# 2. Install Playwright browser
npx playwright install chromium
# 3. Build
npm run build
# 4. Verify
echo '{}' | node dist/index.js # Should start without errors
Connect to Your AI Client
Claude Desktop
Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"hb-optimizer": {
"command": "node",
"args": ["/absolute/path/to/mcp-server/dist/index.js"]
}
}
}
Restart Claude Desktop after saving.
Claude Code
Add to .claude/settings.json:
{
"mcpServers": {
"hb-optimizer": {
"command": "node",
"args": ["/absolute/path/to/mcp-server/dist/index.js"]
}
}
}
MCP Inspector (Manual Testing)
npx @modelcontextprotocol/inspector node dist/index.js
Verify Setup
SITE_URL="https://your-site.com"
KEY="your-api-key"
# Test REST API
curl "$SITE_URL/?rest_route=/hb-optimizer/v1/status&hb_key=$KEY"
# Test via AI assistant
# Ask: "Use hb_check_site to check https://your-site.com with API key abc123"
AI Agent Prompt
Copy this block into your AI assistant's system instructions or CLAUDE.md:
You have access to the **HB Optimizer MCP server** (v2.0) for diagnosing and fixing
Hummingbird WordPress performance plugin issues. All tool names are prefixed with `hb_`.
## Investigation Workflow
Always follow this order:
1. **`hb_check_site`** — START HERE. One-call health check that fetches HB module status,
diagnoses the homepage (console errors, delayed scripts, Critical CSS, popups),
and lists all scripts/styles. Returns a summary and actionable recommendations.
Parameters: site_url (WordPress URL), hb_key (API key from wp option hb_companion_key).
2. **`hb_diagnose_page`** — If you need to check a SPECIFIC page (not homepage).
Same diagnostics as check_site but for any URL.
3. **`hb_list_scripts` / `hb_list_styles`** — Get the full asset list with handles
and source URLs. Use the src values when building exclusion patterns.
4. **`hb_test_exclusion`** — Verify a suspected fix. Pass specific exclusion patterns
and it compares a baseline (HB disabled) vs test (HB active + exclusions).
For Delay JS: use script src patterns (e.g., "slider.min.js").
For Critical CSS: use stylesheet patterns.
For Minify: use WordPress handle names.
5. **`hb_build_exclusion_url`** — Generate a shareable test link the site owner
can open in their browser to verify the fix visually.
6. **`hb_audit_site`** — Full automated binary search across all modules.
ONLY use this when manual investigation with the above tools isn't enough.
## Key Concepts
- Hummingbird has 3 optimization modules: **Delay JS** (defers script execution
until user interaction), **Critical CSS** (inlines above-the-fold styles),
and **Minify** (combines/minifies assets).
- Each module can break pages. Delay JS is the most common culprit.
- The fix is adding **exclusions** — telling HB to skip specific scripts/styles.
- All testing is non-destructive. Query string parameters control exclusions
per-request. Nothing is written to the database.
- The companion plugin requires an **API key** (hb_key). Ask the user for it
or tell them to find it at Settings > HB Optimizer in WordPress admin.
## Common Patterns
- "jQuery is not defined" -> Exclude `jquery.min.js` from Delay JS
- Broken sliders/carousels -> Find the script via hb_list_scripts, exclude from Delay JS
- Flash of unstyled content -> Test excluding stylesheets from Critical CSS
- Broken layout -> Test with disable_minify=true
- Empty script lists -> Tell user: Dashboard > Hummingbird > Asset Optimization > Re-Check Files
## Exclusion Pattern Format
- **Delay JS** (delay_exclusions): src URL substrings like "slider.min.js"
- **Critical CSS** (critical_exclusions): stylesheet handle names or URL patterns
- **Minify** (minify_exclusions): WordPress handle names like "jquery-core"
MCP Tools Reference
All 10 tools are prefixed with hb_.
hb_check_site
Full health check in one call. Fetches HB status, diagnoses the homepage, and lists all assets.
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| site_url | string (URL) | Yes | WordPress site base URL |
| hb_key | string | Yes | API key |
hb_diagnose_page
Single-page diagnostic. Captures console errors, detects delayed scripts, Critical CSS status, and popup overlays.
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| url | string (URL) | Yes | - | Page URL to diagnose |
| viewport_width | integer | No | 1920 | Viewport width (320-3840) |
| viewport_height | integer | No | 1080 | Viewport height (320-3840) |
hb_get_status
HB module states and current DB exclusion settings.
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| site_url | string (URL) | Yes | WordPress site base URL |
| hb_key | string | Yes | API key |
hb_list_scripts / hb_list_styles
All JS/CSS handles and source URLs from HB's Asset Optimization Sources_Collector.
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| site_url | string (URL) | Yes | WordPress site base URL |
| hb_key | string | Yes | API key |
hb_test_exclusion
Compare baseline (HB disabled) vs test (HB active + exclusions) with pixel-diff screenshots.
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| page_url | string (URL) | Yes | - | Page URL to test |
| hb_key | string | Yes | - | API key |
| delay_exclusions | string[] | No | [] | Scripts to exclude from Delay JS |
| critical_exclusions | string[] | No | [] | Styles to exclude from Critical CSS |
| minify_exclusions | string[] | No | [] | Handles to exclude from minification |
| viewport_width | integer | No | 1920 | Viewport width |
| viewport_height | integer | No | 1080 | Viewport height |
| diff_threshold | number | No | 10 | Max acceptable visual diff % |
hb_audit_site
Full automated audit with binary search. Tests each module independently, then finds minimal exclusion sets.
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| site_url | string (URL) | Yes | - | WordPress site base URL |
| hb_key | string | Yes | - | API key |
| diff_threshold | number | No | 10 | Max visual diff % |
| viewports | object[] | No | desktop + mobile | [{w, h, label}] |
| max_exclusion_attempts | integer | No | 10 | Binary search limit (1-50) |
| test_pages | string[] | No | [homepage] | Page URLs to test |
hb_build_exclusion_url
Generate a shareable URL with exclusion query params for browser testing.
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| page_url | string (URL) | Yes | - | Base page URL |
| delay_exclusions | string[] | No | [] | Delay JS exclusion patterns |
| critical_exclusions | string[] | No | [] | Critical CSS exclusion patterns |
| minify_exclusions | string[] | No | [] | Minify exclusion handles |
| disable_delay | boolean | No | false | Disable Delay JS entirely |
| disable_critical | boolean | No | false | Disable Critical CSS entirely |
| disable_minify | boolean | No | false | Disable minification entirely |
hb_capture_page
Take a full-page screenshot. Auto-scrolls, triggers Delay JS via mouse simulation, dismisses popups.
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| url | string (URL) | Yes | - | URL to screenshot |
| viewport_width | integer | No | 1920 | Viewport width |
| viewport_height | integer | No | 1080 | Viewport height |
| output_path | string | No | auto | Save path for PNG |
hb_compare_screenshots
Pixel-by-pixel comparison of two images with diff heatmap generation.
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| baseline_path | string | Yes | Path to baseline screenshot |
| test_path | string | Yes | Path to test screenshot |
| diff_output_path | string | No | Path to save diff image |
Programmatic API
All tools are exported as clean functions:
import {
checkSite,
diagnosePage,
getHBStatus,
listScripts,
listStyles,
testExclusion,
auditSite,
buildExclusionUrl,
capturePage,
compareScreenshots,
} from "hb-optimizer-mcp/functions";
// One-call health check
const report = await checkSite("https://example.com", "your-api-key");
console.log(report.summary);
console.log(report.recommendations);
// Test an exclusion
const result = await testExclusion(
"https://example.com",
"your-api-key",
{ delay: ["slider.min.js", "popup.js"] },
);
console.log(result.fixed); // true or false
// Generate shareable test URL
const url = buildExclusionUrl("https://example.com", {
delay: ["slider.min.js"],
});
Function Signatures
checkSite(siteUrl: string, apiKey: string): Promise<SiteCheckResult>
diagnosePage(url: string, viewport?: ViewportConfig): Promise<DiagnoseResult>
getHBStatus(siteUrl: string, apiKey: string): Promise<HBStatusResponse>
listScripts(siteUrl: string, apiKey: string): Promise<HBScriptsResponse>
listStyles(siteUrl: string, apiKey: string): Promise<HBStylesResponse>
testExclusion(pageUrl: string, apiKey: string, exclusions: ExclusionSet, options?: TestOptions): Promise<TestExclusionResult>
auditSite(siteUrl: string, apiKey: string, options?: AuditOptions): Promise<AuditReport>
buildExclusionUrl(pageUrl: string, exclusions?: ExclusionSet, disableModules?: DisableFlags): string
capturePage(url: string, viewport?: ViewportConfig, outputPath?: string): Promise<CaptureResult>
compareScreenshots(baselinePath: string, testPath: string, diffOutputPath?: string): Promise<DiffResult>
Project Structure
mcp-server/
├── src/
│ ├── index.ts # MCP server entry + registerTool() calls
│ ├── functions.ts # Clean function re-exports
│ ├── types.ts # TypeScript interfaces
│ ├── config.ts # Constants (timeouts, defaults)
│ ├── errors.ts # Custom error classes
│ ├── cleanup.ts # Temp file cleanup on exit
│ ├── declarations.d.ts # Type declarations for untyped deps
│ ├── schemas/
│ │ └── tool-schemas.ts # Zod input validation schemas
│ └── tools/
│ ├── hb-client.ts # WordPress REST API client
│ ├── screenshot.ts # Playwright browser automation
│ ├── diff.ts # Pixel-by-pixel image comparison
│ ├── diagnose.ts # Single-page diagnostics
│ ├── test-exclusion.ts # Exclusion pattern testing
│ ├── audit.ts # 4-phase audit with binary search
│ ├── check-site.ts # Combined health check
│ └── build-exclusion-url.ts
├── dist/ # Compiled output (gitignored)
├── tsconfig.json
└── package.json
Development
npm run build # Compile TypeScript
npm run dev # Watch mode
npm start # Run compiled server
Troubleshooting
"Cannot find module" on start — Run npm run build first.
401 API key rejected — Verify: wp option get hb_companion_key. If using Authorization header, some hosts strip it; the client falls back to query param automatically.
Request timeouts — Check the WordPress site is reachable from the machine running the MCP server.
Empty script/style lists — HB's Asset Optimization hasn't been scanned. Go to Dashboard > Hummingbird > Asset Optimization > Re-Check Files.
Playwright errors — Run npx playwright install chromium.