docusaurus-plugin-mcp-server 0.10.2 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -206,7 +206,7 @@ Search across documentation with relevance ranking. Returns matching documents w
206
206
  "name": "docs_search",
207
207
  "arguments": {
208
208
  "query": "authentication",
209
- "limit": 5
209
+ "limit": 16
210
210
  }
211
211
  }
212
212
  ```
@@ -214,7 +214,7 @@ Search across documentation with relevance ranking. Returns matching documents w
214
214
  | Parameter | Type | Default | Description |
215
215
  |-----------|------|---------|-------------|
216
216
  | `query` | `string` | required | Search query |
217
- | `limit` | `number` | `5` | Max results (1-20) |
217
+ | `limit` | `number` | `16` | Max results (1-20) |
218
218
 
219
219
  **Response includes:**
220
220
  - Full URL for each result (use with `docs_fetch`)
@@ -255,6 +255,8 @@ Retrieve full page content as markdown. Use this after searching to get the comp
255
255
  | `server.name` | `string` | `'docs-mcp-server'` | Name of the MCP server |
256
256
  | `server.version` | `string` | `'1.0.0'` | Version of the MCP server |
257
257
  | `excludeRoutes` | `string[]` | `['/404*', '/search*']` | Routes to exclude (glob patterns) |
258
+ | `indexers` | `string[] \| false` | `['flexsearch']` | Indexers to run during build. Use `false` to disable. Supports built-in (`'flexsearch'`), relative paths, or npm packages. |
259
+ | `search` | `string` | `'flexsearch'` | Search provider module for runtime queries. Supports built-in (`'flexsearch'`), relative paths, or npm packages. |
258
260
 
259
261
  ### Default Selectors
260
262
 
@@ -268,6 +270,90 @@ Retrieve full page content as markdown. Use this after searching to get the comp
268
270
  ['nav', 'header', 'footer', 'aside', '[role="navigation"]', '[role="banner"]', '[role="contentinfo"]']
269
271
  ```
270
272
 
273
+ ## Custom Providers
274
+
275
+ 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.
276
+
277
+ ### ContentIndexer
278
+
279
+ Implement `ContentIndexer` to push documents to an external system during build:
280
+
281
+ ```typescript
282
+ import type { ContentIndexer, ProviderContext } from 'docusaurus-plugin-mcp-server';
283
+ import type { ProcessedDoc } from 'docusaurus-plugin-mcp-server';
284
+
285
+ export default class AlgoliaIndexer implements ContentIndexer {
286
+ readonly name = 'algolia';
287
+
288
+ shouldRun(): boolean {
289
+ return process.env.ALGOLIA_SYNC === 'true';
290
+ }
291
+
292
+ async initialize(context: ProviderContext): Promise<void> {
293
+ console.log(`[Algolia] Initializing for ${context.baseUrl}`);
294
+ }
295
+
296
+ async indexDocuments(docs: ProcessedDoc[]): Promise<void> {
297
+ // Push docs to Algolia
298
+ }
299
+
300
+ async finalize(): Promise<Map<string, unknown>> {
301
+ // No local artifacts needed
302
+ return new Map();
303
+ }
304
+ }
305
+ ```
306
+
307
+ ### SearchProvider
308
+
309
+ Implement `SearchProvider` to delegate runtime search to an external service:
310
+
311
+ ```typescript
312
+ import type { SearchProvider, ProviderContext, SearchOptions } from 'docusaurus-plugin-mcp-server';
313
+ import type { SearchResult } from 'docusaurus-plugin-mcp-server';
314
+
315
+ export default class GleanSearchProvider implements SearchProvider {
316
+ readonly name = 'glean';
317
+
318
+ private apiEndpoint = process.env.GLEAN_API_ENDPOINT!;
319
+ private apiToken = process.env.GLEAN_API_TOKEN!;
320
+
321
+ async initialize(context: ProviderContext): Promise<void> {
322
+ if (!this.apiEndpoint || !this.apiToken) {
323
+ throw new Error('GLEAN_API_ENDPOINT and GLEAN_API_TOKEN required');
324
+ }
325
+ }
326
+
327
+ isReady(): boolean {
328
+ return !!this.apiEndpoint && !!this.apiToken;
329
+ }
330
+
331
+ async search(query: string, options?: SearchOptions): Promise<SearchResult[]> {
332
+ // Call Glean Search API and transform results
333
+ return [];
334
+ }
335
+ }
336
+ ```
337
+
338
+ ### Configuring Custom Providers
339
+
340
+ ```javascript
341
+ // docusaurus.config.js
342
+ module.exports = {
343
+ plugins: [
344
+ [
345
+ 'docusaurus-plugin-mcp-server',
346
+ {
347
+ // Run both the built-in FlexSearch indexer and a custom one
348
+ indexers: ['flexsearch', './my-algolia-indexer.js'],
349
+ // Use a custom search provider at runtime
350
+ search: '@myorg/glean-search',
351
+ },
352
+ ],
353
+ ],
354
+ };
355
+ ```
356
+
271
357
  ## Server Configuration
272
358
 
273
359
  For the runtime adapters:
@@ -408,47 +494,24 @@ The plugin operates in two phases:
408
494
 
409
495
  ## Local Development
410
496
 
411
- Run a local HTTP server for testing:
497
+ Run a local MCP server for testing using the built-in Node adapter:
412
498
 
413
499
  ```javascript
414
500
  // mcp-server.mjs
415
- import http from 'http';
416
- import { McpDocsServer } from 'docusaurus-plugin-mcp-server';
417
- import path from 'path';
418
- import { fileURLToPath } from 'url';
501
+ import { createNodeServer } from 'docusaurus-plugin-mcp-server/adapters';
419
502
 
420
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
421
-
422
- const server = new McpDocsServer({
423
- docsPath: path.join(__dirname, 'build/mcp/docs.json'),
424
- indexPath: path.join(__dirname, 'build/mcp/search-index.json'),
503
+ createNodeServer({
504
+ docsPath: './build/mcp/docs.json',
505
+ indexPath: './build/mcp/search-index.json',
425
506
  name: 'my-docs',
426
507
  baseUrl: 'http://localhost:3000',
427
- });
428
-
429
- http.createServer(async (req, res) => {
430
- if (req.method === 'OPTIONS') {
431
- res.writeHead(204, {
432
- 'Access-Control-Allow-Origin': '*',
433
- 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
434
- 'Access-Control-Allow-Headers': 'Content-Type',
435
- });
436
- res.end();
437
- return;
438
- }
439
-
440
- if (req.method !== 'POST') {
441
- res.writeHead(405);
442
- res.end();
443
- return;
444
- }
445
-
446
- await server.handleHttpRequest(req, res);
447
508
  }).listen(3456, () => {
448
509
  console.log('MCP server at http://localhost:3456');
449
510
  });
450
511
  ```
451
512
 
513
+ The Node adapter handles CORS, preflight requests, and health checks (GET) automatically.
514
+
452
515
  Connect Claude Code:
453
516
  ```bash
454
517
  claude mcp add --transport http my-docs http://localhost:3456
@@ -494,19 +557,34 @@ import {
494
557
  createVercelHandler,
495
558
  createNetlifyHandler,
496
559
  createCloudflareHandler,
560
+ createNodeServer,
561
+ createNodeHandler,
497
562
  generateAdapterFiles,
498
563
  } from 'docusaurus-plugin-mcp-server/adapters';
499
564
  ```
500
565
 
566
+ - `createNodeServer(options)` — Creates a complete Node.js HTTP server for local development. Returns an `http.Server` ready to `.listen()`.
567
+ - `createNodeHandler(options)` — Creates a request handler function compatible with `http.createServer()`. Use this when you need to integrate with an existing server.
568
+
501
569
  ### Theme Exports
502
570
 
503
571
  ```tsx
504
572
  import {
505
573
  McpInstallButton,
506
574
  type McpInstallButtonProps,
575
+ useMcpRegistry,
576
+ createDocsRegistry,
577
+ createDocsRegistryOptions,
578
+ type McpConfig,
507
579
  } from 'docusaurus-plugin-mcp-server/theme';
508
580
  ```
509
581
 
582
+ - `McpInstallButton` — Dropdown button for users to install the MCP server in their AI tool.
583
+ - `useMcpRegistry()` — React hook that returns the MCP config registry from plugin global data. Returns `undefined` if the plugin is not installed.
584
+ - `createDocsRegistry(config)` — Creates a pre-configured `MCPConfigRegistry` for documentation servers.
585
+ - `createDocsRegistryOptions(config)` — Returns registry options without creating the registry.
586
+ - `McpConfig` — Type for `{ serverUrl: string; serverName: string }`.
587
+
510
588
  ## Requirements
511
589
 
512
590
  - Node.js >= 20
@@ -1,5 +1,5 @@
1
1
  import { IncomingMessage, ServerResponse, Server } from 'node:http';
2
- import { M as McpServerConfig, P as ProcessedDoc, a as McpServerFileConfig } from './index-j-CdaS6k.js';
2
+ import { M as McpServerFileConfig, P as ProcessedDoc } from './index-BhwLRGxJ.js';
3
3
 
4
4
  /**
5
5
  * Vercel adapter for MCP server
@@ -40,7 +40,9 @@ interface VercelResponse extends ServerResponse {
40
40
  *
41
41
  * Uses the MCP SDK's StreamableHTTPServerTransport for proper protocol handling.
42
42
  */
43
- declare function createVercelHandler(config: McpServerConfig): (req: VercelRequest, res: VercelResponse) => Promise<void>;
43
+ declare function createVercelHandler(config: McpServerFileConfig & {
44
+ corsOrigin?: string;
45
+ }): (req: VercelRequest, res: VercelResponse) => Promise<void>;
44
46
 
45
47
  /**
46
48
  * Netlify adapter for MCP server
@@ -103,7 +105,9 @@ interface NetlifyResponse {
103
105
  * Uses the MCP SDK's WebStandardStreamableHTTPServerTransport for
104
106
  * proper protocol handling.
105
107
  */
106
- declare function createNetlifyHandler(config: McpServerConfig): (event: NetlifyEvent, _context: NetlifyContext) => Promise<NetlifyResponse>;
108
+ declare function createNetlifyHandler(config: McpServerFileConfig & {
109
+ corsOrigin?: string;
110
+ }): (event: NetlifyEvent, _context: NetlifyContext) => Promise<NetlifyResponse>;
107
111
 
108
112
  /**
109
113
  * Cloudflare Workers adapter for MCP server
@@ -145,6 +149,8 @@ interface CloudflareAdapterConfig {
145
149
  version?: string;
146
150
  /** Base URL for constructing full page URLs */
147
151
  baseUrl?: string;
152
+ /** CORS origin to allow. Defaults to '*' (all origins). */
153
+ corsOrigin?: string;
148
154
  }
149
155
  /**
150
156
  * Create a Cloudflare Workers fetch handler for the MCP server