npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

docusaurus-plugin-mcp-server

v0.10.2

Published

A Docusaurus plugin that exposes an MCP server endpoint for AI agents to search and retrieve documentation

Readme

docusaurus-plugin-mcp-server

CI Build npm version License

A Docusaurus plugin that exposes an MCP (Model Context Protocol) server endpoint, allowing AI agents like Claude, Cursor, and other MCP-compatible tools to search and retrieve your documentation.

Installation

npm install docusaurus-plugin-mcp-server

Quick Start

1. Add the Plugin

// docusaurus.config.js
module.exports = {
  plugins: [
    [
      'docusaurus-plugin-mcp-server',
      {
        server: {
          name: 'my-docs',
          version: '1.0.0',
        },
      },
    ],
  ],
};

2. Create the API Endpoint

Choose your deployment platform:

Create api/mcp.js:

import { createVercelHandler } from 'docusaurus-plugin-mcp-server/adapters';
import path from 'path';
import { fileURLToPath } from 'url';

const __dirname = path.dirname(fileURLToPath(import.meta.url));

export default createVercelHandler({
  docsPath: path.join(__dirname, '../build/mcp/docs.json'),
  indexPath: path.join(__dirname, '../build/mcp/search-index.json'),
  name: 'my-docs',
  baseUrl: 'https://docs.example.com',
});

Add to vercel.json:

{
  "functions": {
    "api/mcp.js": {
      "includeFiles": "build/mcp/**"
    }
  },
  "rewrites": [
    { "source": "/mcp", "destination": "/api/mcp" }
  ]
}

Create netlify/functions/mcp.js:

import { createNetlifyHandler } from 'docusaurus-plugin-mcp-server/adapters';
import path from 'path';
import { fileURLToPath } from 'url';

const __dirname = path.dirname(fileURLToPath(import.meta.url));

export const handler = createNetlifyHandler({
  docsPath: path.join(__dirname, '../../build/mcp/docs.json'),
  indexPath: path.join(__dirname, '../../build/mcp/search-index.json'),
  name: 'my-docs',
  baseUrl: 'https://docs.example.com',
});

Add to netlify.toml:

[build]
  publish = "build"

[functions]
  directory = "netlify/functions"
  included_files = ["build/mcp/**"]

[[redirects]]
  from = "/mcp"
  to = "/.netlify/functions/mcp"
  status = 200

Cloudflare Workers can't access the filesystem, so you need to import the data directly:

import { createCloudflareHandler } from 'docusaurus-plugin-mcp-server/adapters';
import docs from '../build/mcp/docs.json';
import searchIndex from '../build/mcp/search-index.json';

export default {
  fetch: createCloudflareHandler({
    docs,
    searchIndexData: searchIndex,
    name: 'my-docs',
    baseUrl: 'https://docs.example.com',
  }),
};

3. Build and Deploy

npm run build
# Deploy to your platform

4. Connect Your AI Tool

Claude Code:

claude mcp add --transport http my-docs https://docs.example.com/mcp

Cursor / VS Code:

{
  "mcpServers": {
    "my-docs": {
      "url": "https://docs.example.com/mcp"
    }
  }
}

5. Add an Install Button (Optional)

Add a dropdown button to your docs site so users can easily install the MCP server in their AI tool:

import { McpInstallButton } from 'docusaurus-plugin-mcp-server/theme';

function NavbarItems() {
  return (
    <McpInstallButton
      serverUrl="https://docs.example.com/mcp"
      serverName="my-docs"
    />
  );
}

The button shows a dropdown with copy-to-clipboard configurations for all supported MCP clients.

| Light Mode | Dark Mode | |:----------:|:---------:| | MCP Install Button - Light Mode | MCP Install Button - Dark Mode |

Props:

| Prop | Type | Default | Description | |------|------|---------|-------------| | serverUrl | string | required | Your MCP server endpoint URL | | serverName | string | required | Name for the MCP server | | label | string | (none) | Button label. If omitted, shows only the MCP icon | | headerText | string | "Choose your AI tool:" | Text shown at the top of the dropdown | | className | string | "" | Optional CSS class | | clients | ClientId[] | All HTTP-capable | Which clients to show |

MCP Tools

The server exposes two tools for AI agents:

docs_search

Search across documentation with relevance ranking. Returns matching documents with URLs, snippets, and relevance scores.

{
  "name": "docs_search",
  "arguments": {
    "query": "authentication",
    "limit": 5
  }
}

| Parameter | Type | Default | Description | |-----------|------|---------|-------------| | query | string | required | Search query | | limit | number | 5 | Max results (1-20) |

Response includes:

  • Full URL for each result (use with docs_fetch)
  • Title and relevance score
  • Snippet of matching content
  • Matching headings

docs_fetch

Retrieve full page content as markdown. Use this after searching to get the complete content of a specific page.

{
  "name": "docs_fetch",
  "arguments": {
    "url": "https://docs.example.com/docs/authentication"
  }
}

| Parameter | Type | Description | |-----------|------|-------------| | url | string | Full URL of the page (from search results) |

Response includes:

  • Page title and description
  • Table of contents with anchor links
  • Full markdown content

Plugin Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | outputDir | string | 'mcp' | Output directory for MCP artifacts (relative to build dir) | | contentSelectors | string[] | ['article', 'main', ...] | CSS selectors for finding content | | excludeSelectors | string[] | ['nav', 'header', ...] | CSS selectors for elements to remove | | minContentLength | number | 50 | Minimum content length to consider a page valid | | server.name | string | 'docs-mcp-server' | Name of the MCP server | | server.version | string | '1.0.0' | Version of the MCP server | | excludeRoutes | string[] | ['/404*', '/search*'] | Routes to exclude (glob patterns) |

Default Selectors

Content selectors (in priority order):

['article', 'main', '.main-wrapper', '[role="main"]']

Exclude selectors:

['nav', 'header', 'footer', 'aside', '[role="navigation"]', '[role="banner"]', '[role="contentinfo"]']

Server Configuration

For the runtime adapters:

| Option | Type | Required | Description | |--------|------|----------|-------------| | docsPath | string | Yes* | Path to docs.json | | indexPath | string | Yes* | Path to search-index.json | | docs | object | Yes* | Pre-loaded docs (Cloudflare) | | searchIndexData | object | Yes* | Pre-loaded search index (Cloudflare) | | name | string | Yes | Server name | | version | string | No | Server version | | baseUrl | string | No | Base URL for full page URLs in responses |

*Use either file paths (Node.js) or pre-loaded data (Workers).

Verifying Your Build

After running npm run build, use the included CLI to verify the MCP output:

npx docusaurus-mcp-verify

This checks that:

  • All required files exist (docs.json, search-index.json, manifest.json)
  • Document structure is valid
  • The MCP server can initialize and load the content

You can specify a custom build directory:

npx docusaurus-mcp-verify ./custom-build

Example output:

🔍 MCP Build Verification
==================================================
Build directory: /path/to/your/project/build

📁 Checking build output...
   ✓ Found 42 documents
   ✓ All required files present
   ✓ File structure valid

🚀 Testing MCP server...
   ✓ Server initialized with 42 documents

✅ All checks passed!

Testing the Endpoint

The easiest way to test your MCP server is with the official MCP Inspector:

npx @modelcontextprotocol/inspector

This opens a visual interface where you can:

  • Connect to your server URL
  • Browse available tools
  • Execute tool calls interactively
  • View responses in a formatted display

Alternatively, test with curl:

# List available tools
curl -X POST https://docs.example.com/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

# Search documentation
curl -X POST https://docs.example.com/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc":"2.0",
    "id":2,
    "method":"tools/call",
    "params":{
      "name":"docs_search",
      "arguments":{"query":"getting started"}
    }
  }'

How It Works

flowchart LR
    subgraph Build["Build Time"]
        A[Docusaurus Build] --> B[postBuild Hook]
        B --> C[Extract Content]
        C --> D[Build Search Index]
        D --> E[Write Artifacts]
    end

    subgraph Artifacts["build/mcp/"]
        F[docs.json]
        G[search-index.json]
        H[manifest.json]
    end

    subgraph Runtime["Runtime"]
        I[Serverless Function]
        J[MCP Server]
    end

    subgraph Clients["AI Agents"]
        K[Claude]
        L[Cursor]
        M[Other MCP Clients]
    end

    E --> F & G & H
    F & G --> I
    I --> J
    K & L & M <-->|MCP Protocol| J

The plugin operates in two phases:

Build Time: During docusaurus build, the plugin's postBuild hook processes all rendered HTML pages, extracts content, converts to markdown, builds a FlexSearch index, and outputs artifacts to build/mcp/.

Runtime: A serverless function loads the pre-built artifacts and handles MCP JSON-RPC requests from AI agents. The server is stateless and fast since all indexing happens at build time.

Features

  • Full-text Search - FlexSearch-powered search with relevance ranking
  • Page Retrieval - Get complete page content as clean markdown
  • Platform Adapters - Pre-built adapters for Vercel, Netlify, and Cloudflare Workers
  • CORS Support - All adapters include CORS headers for browser-based clients
  • Build-time Processing - Extracts content from rendered HTML, capturing React component output
  • Zero Runtime Docusaurus Dependency - The MCP server runs independently

Local Development

Run a local HTTP server for testing:

// mcp-server.mjs
import http from 'http';
import { McpDocsServer } from 'docusaurus-plugin-mcp-server';
import path from 'path';
import { fileURLToPath } from 'url';

const __dirname = path.dirname(fileURLToPath(import.meta.url));

const server = new McpDocsServer({
  docsPath: path.join(__dirname, 'build/mcp/docs.json'),
  indexPath: path.join(__dirname, 'build/mcp/search-index.json'),
  name: 'my-docs',
  baseUrl: 'http://localhost:3000',
});

http.createServer(async (req, res) => {
  if (req.method === 'OPTIONS') {
    res.writeHead(204, {
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
      'Access-Control-Allow-Headers': 'Content-Type',
    });
    res.end();
    return;
  }

  if (req.method !== 'POST') {
    res.writeHead(405);
    res.end();
    return;
  }

  await server.handleHttpRequest(req, res);
}).listen(3456, () => {
  console.log('MCP server at http://localhost:3456');
});

Connect Claude Code:

claude mcp add --transport http my-docs http://localhost:3456

API Reference

Main Exports

import {
  // Docusaurus plugin (default export)
  mcpServerPlugin,

  // MCP Server class
  McpDocsServer,

  // Tool definitions
  docsSearchTool,
  docsFetchTool,

  // Utilities
  htmlToMarkdown,
  extractContent,
  extractHeadingsFromMarkdown,
  buildSearchIndex,

  // Provider types (for custom implementations)
  loadIndexer,
  loadSearchProvider,
  FlexSearchIndexer,
  FlexSearchProvider,

  // Default options
  DEFAULT_OPTIONS,
} from 'docusaurus-plugin-mcp-server';

Adapter Exports

import {
  createVercelHandler,
  createNetlifyHandler,
  createCloudflareHandler,
  generateAdapterFiles,
} from 'docusaurus-plugin-mcp-server/adapters';

Theme Exports

import {
  McpInstallButton,
  type McpInstallButtonProps,
} from 'docusaurus-plugin-mcp-server/theme';

Requirements

  • Node.js >= 20
  • Docusaurus 3.x

License

MIT