loading…
Search for a command to run...
loading…
A Docusaurus plugin that exposes an MCP server endpoint for AI agents to search and retrieve documentation
A Docusaurus plugin that exposes an MCP server endpoint for AI agents to search and retrieve documentation
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.
npm install docusaurus-plugin-mcp-server
// docusaurus.config.js
module.exports = {
plugins: [
[
'docusaurus-plugin-mcp-server',
{
server: {
name: 'my-docs',
version: '1.0.0',
},
},
],
],
};
The MCP server runs on any web-standard serverless or edge runtime — Cloudflare Workers, modern Netlify functions, Vercel Edge, Deno, Bun. Import the build artifacts and pass them to createWebRequestHandler, which returns a standard (request: Request) => Promise<Response>. (These runtimes can't read the filesystem, so the data is imported as modules rather than loaded from disk.)
import { createWebRequestHandler } from 'docusaurus-plugin-mcp-server/adapters';
import docs from '../build/mcp/docs.json';
import searchIndex from '../build/mcp/search-index.json';
export default {
fetch: createWebRequestHandler({
docs,
searchIndexData: searchIndex,
name: 'my-docs',
baseUrl: 'https://docs.example.com',
}),
};
The export default { fetch } form works on Cloudflare Workers, Deno, and Bun. Other runtimes use their own entry convention (e.g. modern Netlify functions export default async (request) => Response) — the handler is identical, only the export wrapper differs.
For local development, run the server over Node's http with createNodeServer (see Adapter Exports).
npm run build
# Deploy to your platform
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"
}
}
}
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 |
|---|---|
![]() |
![]() |
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 |
The server exposes two tools for AI agents:
docs_searchSearch across documentation with relevance ranking. Returns matching documents with URLs, snippets, and relevance scores.
{
"name": "docs_search",
"arguments": {
"query": "authentication",
"limit": 16
}
}
| Parameter | Type | Default | Description |
|---|---|---|---|
query |
string |
required | Search query |
limit |
number |
16 |
Max results (1-20) |
Response includes:
docs_fetch)docs_fetchRetrieve 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:
| 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) |
indexers |
string[] | false |
['flexsearch'] |
Indexers to run during build. Use false to disable. Supports built-in ('flexsearch'), relative paths, or npm packages. |
search |
string |
'flexsearch' |
Search provider module for runtime queries. Supports built-in ('flexsearch'), relative paths, or npm packages. |
Content selectors (in priority order):
['article', 'main', '.main-wrapper', '[role="main"]'];
Exclude selectors:
[
'nav',
'header',
'footer',
'aside',
'[role="navigation"]',
'[role="banner"]',
'[role="contentinfo"]',
];
The plugin uses a two-phase provider model: indexers run at build time to process documents, and search providers handle queries at runtime. Both are pluggable.
Implement ContentIndexer to push documents to an external system during build:
import type { ContentIndexer, ProviderContext, ProcessedDoc } from 'docusaurus-plugin-mcp-server';
export default class AlgoliaIndexer implements ContentIndexer {
readonly name = 'algolia';
shouldRun(): boolean {
return process.env.ALGOLIA_SYNC === 'true';
}
async initialize(context: ProviderContext): Promise<void> {
console.log(`[Algolia] Initializing for ${context.baseUrl}`);
}
async indexDocuments(docs: ProcessedDoc[]): Promise<void> {
// Push docs to Algolia
}
async finalize(): Promise<Map<string, unknown>> {
// No local artifacts needed
return new Map();
}
}
Implement SearchProvider to delegate runtime search to an external service:
import type {
SearchProvider,
ProviderContext,
SearchOptions,
SearchResult,
} from 'docusaurus-plugin-mcp-server';
export default class GleanSearchProvider implements SearchProvider {
readonly name = 'glean';
private apiEndpoint = process.env.GLEAN_API_ENDPOINT!;
private apiToken = process.env.GLEAN_API_TOKEN!;
async initialize(context: ProviderContext): Promise<void> {
if (!this.apiEndpoint || !this.apiToken) {
throw new Error('GLEAN_API_ENDPOINT and GLEAN_API_TOKEN required');
}
}
isReady(): boolean {
return !!this.apiEndpoint && !!this.apiToken;
}
async search(query: string, options?: SearchOptions): Promise<SearchResult[]> {
// Call Glean Search API and transform results
return [];
}
}
// docusaurus.config.js
module.exports = {
plugins: [
[
'docusaurus-plugin-mcp-server',
{
// Run both the built-in FlexSearch indexer and a custom one
indexers: ['flexsearch', './my-algolia-indexer.js'],
// Use a custom search provider at runtime
search: '@myorg/glean-search',
},
],
],
};
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 (web handler) |
searchIndexData |
object |
Yes* | Pre-loaded search index (web handler) |
name |
string |
Yes | Server name |
version |
string |
No | Server version |
baseUrl |
string |
No | Base URL for full page URLs in responses |
instructions |
string |
No | Instructions describing how to use the server, surfaced to MCP clients in the initialize response |
tools |
object |
No | Per-tool overrides. Supports docs_search.description and docs_fetch.description to customize tool descriptions |
*Use file paths (createNodeServer, local dev) or pre-loaded data (createWebRequestHandler, serverless/edge).
Example with extended configuration:
export default {
fetch: createWebRequestHandler({
docs,
searchIndexData: searchIndex,
name: 'my-docs',
baseUrl: 'https://docs.example.com',
instructions: 'Search the Acme product docs. Use docs_search to find pages, then docs_fetch for full content.',
tools: {
docs_search: { description: 'Search the Acme product documentation.' },
docs_fetch: { description: 'Fetch the full markdown of an Acme docs page.' },
},
}),
};
After running npm run build, use the included CLI to verify the MCP output:
npx docusaurus-mcp-verify
This checks that:
docs.json, search-index.json, manifest.json)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!
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:
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"}
}
}'
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.
Run a local MCP server for testing using the built-in Node adapter:
// mcp-server.mjs
import { createNodeServer } from 'docusaurus-plugin-mcp-server/adapters';
createNodeServer({
docsPath: './build/mcp/docs.json',
indexPath: './build/mcp/search-index.json',
name: 'my-docs',
baseUrl: 'http://localhost:3000',
}).listen(3456, () => {
console.log('MCP server at http://localhost:3456');
});
The Node adapter handles CORS, preflight requests, and health checks (GET) automatically.
Connect Claude Code:
claude mcp add --transport http my-docs http://localhost:3456
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';
import {
createWebRequestHandler,
createNodeServer,
createNodeHandler,
} from 'docusaurus-plugin-mcp-server/adapters';
createNodeServer(options) — Creates a complete Node.js HTTP server for local development. Returns an http.Server ready to .listen().createNodeHandler(options) — Creates a request handler function compatible with http.createServer(). Use this when you need to integrate with an existing server.import {
McpInstallButton,
type McpInstallButtonProps,
useMcpRegistry,
createDocsRegistry,
createDocsRegistryOptions,
type McpConfig,
} from 'docusaurus-plugin-mcp-server/theme';
McpInstallButton — Dropdown button for users to install the MCP server in their AI tool.useMcpRegistry() — React hook that returns the MCP config registry from plugin global data. Returns undefined if the plugin is not installed.createDocsRegistry(config) — Creates a pre-configured MCPConfigRegistry for documentation servers.createDocsRegistryOptions(config) — Returns registry options without creating the registry.McpConfig — Type for { serverUrl: string; serverName: string }.MIT
This repository ships agent skill(s) under skills/. Install them into your
AI agent with npx skills:
npx skills add -g scalvert/docusaurus-plugin-mcp-server # global — available in every repo
npx skills add scalvert/docusaurus-plugin-mcp-server # or scoped to the current repo
Run in your terminal:
claude mcp add docusaurus-plugin-mcp-server --env ALGOLIA_SYNC="" --env GLEAN_API_ENDPOINT="" --env GLEAN_API_TOKEN="" -- npx -y docusaurus-plugin-mcp-serverYes, Docusaurus Plugin Mcp Server MCP is free — one-click install via Unyly at no cost.
Yes, it requires environment variables: ALGOLIA_SYNC, GLEAN_API_ENDPOINT, GLEAN_API_TOKEN. Unyly injects them into the config during install.
Self-hosted: the server runs locally on your machine via the install command above.
Open Docusaurus Plugin Mcp Server on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.
pro tip
Just installed Docusaurus Plugin Mcp Server? Say to Claude: "remember why I installed Docusaurus Plugin Mcp Serverand what I want to try" — it'll save into your Vault.
how this works →CSA PROJECT - FZCO © 2026 IFZA Business Park, DDP, Premises Number 31174 - 001
Security
Review before useWill ask for:
GLEAN_API_ENDPOINTGLEAN_API_TOKENAutomated heuristic from public metadata — not a security guarantee.