docusaurus-plugin-mcp-server 0.5.0 → 0.7.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/dist/index.d.mts CHANGED
@@ -1,10 +1,10 @@
1
1
  import { LoadContext, Plugin } from '@docusaurus/types';
2
- import { a as McpServerPluginOptions, M as McpServerConfig, P as ProcessedDoc, S as SearchResult, E as ExtractedContent, D as DocHeading, F as FlattenedRoute } from './index-CzA4FjeE.mjs';
3
- export { b as DEFAULT_OPTIONS, c as DocsGetPageParams, d as DocsGetSectionParams, e as DocsIndex, f as DocsSearchParams, g as McpManifest, h as McpServerDataConfig, i as McpServerFileConfig, R as ResolvedPluginOptions } from './index-CzA4FjeE.mjs';
2
+ import { a as McpServerPluginOptions, M as McpServerConfig, P as ProcessedDoc, S as SearchResult, E as ExtractedContent, D as DocHeading, F as FlattenedRoute } from './index-4g0ZZK3z.mjs';
3
+ export { b as DEFAULT_OPTIONS, c as DocsGetPageParams, d as DocsGetSectionParams, e as DocsIndex, f as DocsSearchParams, g as McpManifest, h as McpServerDataConfig, i as McpServerFileConfig, R as ResolvedPluginOptions } from './index-4g0ZZK3z.mjs';
4
4
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
5
  import { IncomingMessage, ServerResponse } from 'node:http';
6
- import { Root } from 'hast';
7
6
  import FlexSearch from 'flexsearch';
7
+ import { Root } from 'hast';
8
8
 
9
9
  /**
10
10
  * Docusaurus plugin that generates MCP server artifacts during build
@@ -25,8 +25,7 @@ declare function mcpServerPlugin(context: LoadContext, options: McpServerPluginO
25
25
  */
26
26
  declare class McpDocsServer {
27
27
  private config;
28
- private docs;
29
- private searchIndex;
28
+ private searchProvider;
30
29
  private mcpServer;
31
30
  private initialized;
32
31
  constructor(config: McpServerConfig);
@@ -35,7 +34,11 @@ declare class McpDocsServer {
35
34
  */
36
35
  private registerTools;
37
36
  /**
38
- * Load docs and search index
37
+ * Get a document by route using the search provider
38
+ */
39
+ private getDocument;
40
+ /**
41
+ * Load docs and search index using the configured search provider
39
42
  *
40
43
  * For file-based config: reads from disk
41
44
  * For data config: uses pre-loaded data directly
@@ -73,6 +76,7 @@ declare class McpDocsServer {
73
76
  initialized: boolean;
74
77
  docCount: number;
75
78
  baseUrl?: string;
79
+ searchProvider?: string;
76
80
  }>;
77
81
  /**
78
82
  * Get the underlying McpServer instance
@@ -82,6 +86,253 @@ declare class McpDocsServer {
82
86
  getMcpServer(): McpServer;
83
87
  }
84
88
 
89
+ /**
90
+ * Context passed to providers during initialization
91
+ */
92
+ interface ProviderContext {
93
+ /** Site base URL (e.g., https://docs.example.com) */
94
+ baseUrl: string;
95
+ /** MCP server name */
96
+ serverName: string;
97
+ /** MCP server version */
98
+ serverVersion: string;
99
+ /** Output directory for artifacts */
100
+ outputDir: string;
101
+ }
102
+ /**
103
+ * Build-time provider that indexes extracted documents.
104
+ *
105
+ * Consumers implement this to push docs to external systems (Glean, Algolia, etc.)
106
+ * or to transform the extraction output for their own pipelines.
107
+ *
108
+ * @example
109
+ * ```typescript
110
+ * import type { ContentIndexer, ProviderContext } from 'docusaurus-plugin-mcp-server';
111
+ * import type { ProcessedDoc } from 'docusaurus-plugin-mcp-server';
112
+ *
113
+ * export default class AlgoliaIndexer implements ContentIndexer {
114
+ * readonly name = 'algolia';
115
+ *
116
+ * shouldRun(): boolean {
117
+ * // Only run when ALGOLIA_SYNC=true is set
118
+ * return process.env.ALGOLIA_SYNC === 'true';
119
+ * }
120
+ *
121
+ * async initialize(context: ProviderContext): Promise<void> {
122
+ * console.log(`[Algolia] Initializing for ${context.baseUrl}`);
123
+ * }
124
+ *
125
+ * async indexDocuments(docs: ProcessedDoc[]): Promise<void> {
126
+ * // Push docs to Algolia
127
+ * }
128
+ *
129
+ * async finalize(): Promise<Map<string, unknown>> {
130
+ * // No local artifacts needed
131
+ * return new Map();
132
+ * }
133
+ * }
134
+ * ```
135
+ */
136
+ interface ContentIndexer {
137
+ /** Unique name for this indexer */
138
+ readonly name: string;
139
+ /**
140
+ * Check if this indexer should run.
141
+ * Use this to gate execution on environment variables.
142
+ * Default: true if not implemented.
143
+ *
144
+ * @example
145
+ * shouldRun() {
146
+ * if (process.env.GLEAN_SYNC !== 'true') {
147
+ * console.log('[Glean] Skipping sync (set GLEAN_SYNC=true to enable)');
148
+ * return false;
149
+ * }
150
+ * return true;
151
+ * }
152
+ */
153
+ shouldRun?(): boolean;
154
+ /**
155
+ * Initialize the indexer with context about the build.
156
+ * Called once before indexDocuments.
157
+ */
158
+ initialize(context: ProviderContext): Promise<void>;
159
+ /**
160
+ * Index the extracted documents.
161
+ * Called once with all processed documents.
162
+ */
163
+ indexDocuments(docs: ProcessedDoc[]): Promise<void>;
164
+ /**
165
+ * Return artifacts to write to outputDir.
166
+ * Map of filename -> JSON-serializable content.
167
+ * Return empty map to skip local artifact generation.
168
+ */
169
+ finalize(): Promise<Map<string, unknown>>;
170
+ /**
171
+ * Optional metadata to include in manifest.json
172
+ */
173
+ getManifestData?(): Promise<Record<string, unknown>>;
174
+ }
175
+ /**
176
+ * Data passed to search provider during initialization.
177
+ * Supports both file-based and pre-loaded data modes.
178
+ */
179
+ interface SearchProviderInitData {
180
+ /** Path to docs.json (file mode) */
181
+ docsPath?: string;
182
+ /** Path to search-index.json (file mode) */
183
+ indexPath?: string;
184
+ /** Pre-loaded docs (data mode) */
185
+ docs?: Record<string, ProcessedDoc>;
186
+ /** Pre-loaded index data (data mode) */
187
+ indexData?: Record<string, unknown>;
188
+ }
189
+ /**
190
+ * Options for search queries
191
+ */
192
+ interface SearchOptions {
193
+ /** Maximum number of results to return */
194
+ limit?: number;
195
+ }
196
+ /**
197
+ * Runtime provider that handles search queries from MCP tools.
198
+ *
199
+ * Consumers implement this to delegate search to external systems (Glean, Algolia, etc.).
200
+ *
201
+ * @example
202
+ * ```typescript
203
+ * import type { SearchProvider, ProviderContext, SearchOptions } from 'docusaurus-plugin-mcp-server';
204
+ * import type { SearchResult, ProcessedDoc } from 'docusaurus-plugin-mcp-server';
205
+ *
206
+ * export default class GleanSearchProvider implements SearchProvider {
207
+ * readonly name = 'glean';
208
+ *
209
+ * private apiEndpoint = process.env.GLEAN_API_ENDPOINT!;
210
+ * private apiToken = process.env.GLEAN_API_TOKEN!;
211
+ *
212
+ * async initialize(context: ProviderContext): Promise<void> {
213
+ * if (!this.apiEndpoint || !this.apiToken) {
214
+ * throw new Error('GLEAN_API_ENDPOINT and GLEAN_API_TOKEN required');
215
+ * }
216
+ * }
217
+ *
218
+ * isReady(): boolean {
219
+ * return !!this.apiEndpoint && !!this.apiToken;
220
+ * }
221
+ *
222
+ * async search(query: string, options?: SearchOptions): Promise<SearchResult[]> {
223
+ * // Call Glean Search API and transform results
224
+ * return [];
225
+ * }
226
+ * }
227
+ * ```
228
+ */
229
+ interface SearchProvider {
230
+ /** Unique name for this provider */
231
+ readonly name: string;
232
+ /**
233
+ * Initialize the search provider.
234
+ * Called once before any search queries.
235
+ */
236
+ initialize(context: ProviderContext, initData?: SearchProviderInitData): Promise<void>;
237
+ /**
238
+ * Check if the provider is ready to handle search queries.
239
+ */
240
+ isReady(): boolean;
241
+ /**
242
+ * Search for documents matching the query.
243
+ */
244
+ search(query: string, options?: SearchOptions): Promise<SearchResult[]>;
245
+ /**
246
+ * Get a document by its route.
247
+ * Used by docs_get_page and docs_get_section tools.
248
+ */
249
+ getDocument?(route: string): Promise<ProcessedDoc | null>;
250
+ /**
251
+ * Check if the provider is healthy.
252
+ * Used for health checks and debugging.
253
+ */
254
+ healthCheck?(): Promise<{
255
+ healthy: boolean;
256
+ message?: string;
257
+ }>;
258
+ }
259
+ /**
260
+ * Type for module that exports a ContentIndexer
261
+ */
262
+ type ContentIndexerModule = {
263
+ default: new () => ContentIndexer;
264
+ };
265
+ /**
266
+ * Type for module that exports a SearchProvider
267
+ */
268
+ type SearchProviderModule = {
269
+ default: new () => SearchProvider;
270
+ };
271
+
272
+ /**
273
+ * Load an indexer by name or module path.
274
+ *
275
+ * @param specifier - Either 'flexsearch' for the built-in indexer, or a module path
276
+ * (relative path like './my-indexer.js' or npm package like '@myorg/indexer')
277
+ * @returns Instantiated ContentIndexer
278
+ *
279
+ * @example
280
+ * ```typescript
281
+ * // Built-in
282
+ * const indexer = await loadIndexer('flexsearch');
283
+ *
284
+ * // Custom relative path
285
+ * const indexer = await loadIndexer('./src/providers/algolia-indexer.js');
286
+ *
287
+ * // Custom npm package
288
+ * const indexer = await loadIndexer('@myorg/custom-indexer');
289
+ * ```
290
+ */
291
+ declare function loadIndexer(specifier: string): Promise<ContentIndexer>;
292
+ /**
293
+ * Load a search provider by name or module path.
294
+ *
295
+ * @param specifier - Either 'flexsearch' for the built-in provider, or a module path
296
+ * (relative path like './my-search.js' or npm package like '@myorg/search')
297
+ * @returns Instantiated SearchProvider
298
+ *
299
+ * @example
300
+ * ```typescript
301
+ * // Built-in
302
+ * const provider = await loadSearchProvider('flexsearch');
303
+ *
304
+ * // Custom relative path
305
+ * const provider = await loadSearchProvider('./src/providers/glean-search.js');
306
+ *
307
+ * // Custom npm package
308
+ * const provider = await loadSearchProvider('@myorg/glean-search');
309
+ * ```
310
+ */
311
+ declare function loadSearchProvider(specifier: string): Promise<SearchProvider>;
312
+
313
+ /**
314
+ * Built-in FlexSearch content indexer.
315
+ *
316
+ * This indexer builds a local FlexSearch index and produces:
317
+ * - docs.json: All processed documents keyed by route
318
+ * - search-index.json: Exported FlexSearch index for runtime search
319
+ */
320
+ declare class FlexSearchIndexer implements ContentIndexer {
321
+ readonly name = "flexsearch";
322
+ private docsIndex;
323
+ private exportedIndex;
324
+ private docCount;
325
+ /**
326
+ * FlexSearch indexer always runs by default.
327
+ * It respects the indexers configuration - if not included, it won't run.
328
+ */
329
+ shouldRun(): boolean;
330
+ initialize(_context: ProviderContext): Promise<void>;
331
+ indexDocuments(docs: ProcessedDoc[]): Promise<void>;
332
+ finalize(): Promise<Map<string, unknown>>;
333
+ getManifestData(): Promise<Record<string, unknown>>;
334
+ }
335
+
85
336
  /**
86
337
  * Document structure for FlexSearch indexing
87
338
  */
@@ -122,6 +373,35 @@ declare function exportSearchIndex(index: FlexSearchDocument): Promise<unknown>;
122
373
  */
123
374
  declare function importSearchIndex(data: Record<string, unknown>): Promise<FlexSearchDocument>;
124
375
 
376
+ /**
377
+ * Built-in FlexSearch search provider.
378
+ *
379
+ * This provider uses the local FlexSearch index for search queries.
380
+ * Supports both file-based loading (Node.js) and pre-loaded data (Workers).
381
+ */
382
+ declare class FlexSearchProvider implements SearchProvider {
383
+ readonly name = "flexsearch";
384
+ private docs;
385
+ private searchIndex;
386
+ private ready;
387
+ initialize(_context: ProviderContext, initData?: SearchProviderInitData): Promise<void>;
388
+ isReady(): boolean;
389
+ search(query: string, options?: SearchOptions): Promise<SearchResult[]>;
390
+ getDocument(route: string): Promise<ProcessedDoc | null>;
391
+ healthCheck(): Promise<{
392
+ healthy: boolean;
393
+ message?: string;
394
+ }>;
395
+ /**
396
+ * Get all loaded documents (for compatibility with existing server code)
397
+ */
398
+ getDocs(): Record<string, ProcessedDoc> | null;
399
+ /**
400
+ * Get the FlexSearch index (for compatibility with existing server code)
401
+ */
402
+ getSearchIndex(): FlexSearchDocument | null;
403
+ }
404
+
125
405
  /**
126
406
  * Tool definition for docs_search
127
407
  */
@@ -231,4 +511,4 @@ declare function discoverHtmlFiles(outDir: string): Promise<FlattenedRoute[]>;
231
511
  */
232
512
  declare function collectRoutes(outDir: string, excludePatterns: string[]): Promise<FlattenedRoute[]>;
233
513
 
234
- export { DocHeading, ExtractedContent, FlattenedRoute, type FlexSearchDocument, McpDocsServer, McpServerConfig, McpServerPluginOptions, ProcessedDoc, SearchResult, buildSearchIndex, collectRoutes, mcpServerPlugin as default, discoverHtmlFiles, docsGetPageTool, docsGetSectionTool, docsSearchTool, exportSearchIndex, extractContent, extractHeadingsFromMarkdown, extractSection, htmlToMarkdown, importSearchIndex, mcpServerPlugin, parseHtml, parseHtmlFile, searchIndex };
514
+ export { type ContentIndexer, type ContentIndexerModule, DocHeading, ExtractedContent, FlattenedRoute, type FlexSearchDocument, FlexSearchIndexer, FlexSearchProvider, McpDocsServer, McpServerConfig, McpServerPluginOptions, ProcessedDoc, type ProviderContext, type SearchOptions, type SearchProvider, type SearchProviderInitData, type SearchProviderModule, SearchResult, buildSearchIndex, collectRoutes, mcpServerPlugin as default, discoverHtmlFiles, docsGetPageTool, docsGetSectionTool, docsSearchTool, exportSearchIndex, extractContent, extractHeadingsFromMarkdown, extractSection, htmlToMarkdown, importSearchIndex, loadIndexer, loadSearchProvider, mcpServerPlugin, parseHtml, parseHtmlFile, searchIndex };
package/dist/index.d.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  import { LoadContext, Plugin } from '@docusaurus/types';
2
- import { a as McpServerPluginOptions, M as McpServerConfig, P as ProcessedDoc, S as SearchResult, E as ExtractedContent, D as DocHeading, F as FlattenedRoute } from './index-CzA4FjeE.js';
3
- export { b as DEFAULT_OPTIONS, c as DocsGetPageParams, d as DocsGetSectionParams, e as DocsIndex, f as DocsSearchParams, g as McpManifest, h as McpServerDataConfig, i as McpServerFileConfig, R as ResolvedPluginOptions } from './index-CzA4FjeE.js';
2
+ import { a as McpServerPluginOptions, M as McpServerConfig, P as ProcessedDoc, S as SearchResult, E as ExtractedContent, D as DocHeading, F as FlattenedRoute } from './index-4g0ZZK3z.js';
3
+ export { b as DEFAULT_OPTIONS, c as DocsGetPageParams, d as DocsGetSectionParams, e as DocsIndex, f as DocsSearchParams, g as McpManifest, h as McpServerDataConfig, i as McpServerFileConfig, R as ResolvedPluginOptions } from './index-4g0ZZK3z.js';
4
4
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
5
  import { IncomingMessage, ServerResponse } from 'node:http';
6
- import { Root } from 'hast';
7
6
  import FlexSearch from 'flexsearch';
7
+ import { Root } from 'hast';
8
8
 
9
9
  /**
10
10
  * Docusaurus plugin that generates MCP server artifacts during build
@@ -25,8 +25,7 @@ declare function mcpServerPlugin(context: LoadContext, options: McpServerPluginO
25
25
  */
26
26
  declare class McpDocsServer {
27
27
  private config;
28
- private docs;
29
- private searchIndex;
28
+ private searchProvider;
30
29
  private mcpServer;
31
30
  private initialized;
32
31
  constructor(config: McpServerConfig);
@@ -35,7 +34,11 @@ declare class McpDocsServer {
35
34
  */
36
35
  private registerTools;
37
36
  /**
38
- * Load docs and search index
37
+ * Get a document by route using the search provider
38
+ */
39
+ private getDocument;
40
+ /**
41
+ * Load docs and search index using the configured search provider
39
42
  *
40
43
  * For file-based config: reads from disk
41
44
  * For data config: uses pre-loaded data directly
@@ -73,6 +76,7 @@ declare class McpDocsServer {
73
76
  initialized: boolean;
74
77
  docCount: number;
75
78
  baseUrl?: string;
79
+ searchProvider?: string;
76
80
  }>;
77
81
  /**
78
82
  * Get the underlying McpServer instance
@@ -82,6 +86,253 @@ declare class McpDocsServer {
82
86
  getMcpServer(): McpServer;
83
87
  }
84
88
 
89
+ /**
90
+ * Context passed to providers during initialization
91
+ */
92
+ interface ProviderContext {
93
+ /** Site base URL (e.g., https://docs.example.com) */
94
+ baseUrl: string;
95
+ /** MCP server name */
96
+ serverName: string;
97
+ /** MCP server version */
98
+ serverVersion: string;
99
+ /** Output directory for artifacts */
100
+ outputDir: string;
101
+ }
102
+ /**
103
+ * Build-time provider that indexes extracted documents.
104
+ *
105
+ * Consumers implement this to push docs to external systems (Glean, Algolia, etc.)
106
+ * or to transform the extraction output for their own pipelines.
107
+ *
108
+ * @example
109
+ * ```typescript
110
+ * import type { ContentIndexer, ProviderContext } from 'docusaurus-plugin-mcp-server';
111
+ * import type { ProcessedDoc } from 'docusaurus-plugin-mcp-server';
112
+ *
113
+ * export default class AlgoliaIndexer implements ContentIndexer {
114
+ * readonly name = 'algolia';
115
+ *
116
+ * shouldRun(): boolean {
117
+ * // Only run when ALGOLIA_SYNC=true is set
118
+ * return process.env.ALGOLIA_SYNC === 'true';
119
+ * }
120
+ *
121
+ * async initialize(context: ProviderContext): Promise<void> {
122
+ * console.log(`[Algolia] Initializing for ${context.baseUrl}`);
123
+ * }
124
+ *
125
+ * async indexDocuments(docs: ProcessedDoc[]): Promise<void> {
126
+ * // Push docs to Algolia
127
+ * }
128
+ *
129
+ * async finalize(): Promise<Map<string, unknown>> {
130
+ * // No local artifacts needed
131
+ * return new Map();
132
+ * }
133
+ * }
134
+ * ```
135
+ */
136
+ interface ContentIndexer {
137
+ /** Unique name for this indexer */
138
+ readonly name: string;
139
+ /**
140
+ * Check if this indexer should run.
141
+ * Use this to gate execution on environment variables.
142
+ * Default: true if not implemented.
143
+ *
144
+ * @example
145
+ * shouldRun() {
146
+ * if (process.env.GLEAN_SYNC !== 'true') {
147
+ * console.log('[Glean] Skipping sync (set GLEAN_SYNC=true to enable)');
148
+ * return false;
149
+ * }
150
+ * return true;
151
+ * }
152
+ */
153
+ shouldRun?(): boolean;
154
+ /**
155
+ * Initialize the indexer with context about the build.
156
+ * Called once before indexDocuments.
157
+ */
158
+ initialize(context: ProviderContext): Promise<void>;
159
+ /**
160
+ * Index the extracted documents.
161
+ * Called once with all processed documents.
162
+ */
163
+ indexDocuments(docs: ProcessedDoc[]): Promise<void>;
164
+ /**
165
+ * Return artifacts to write to outputDir.
166
+ * Map of filename -> JSON-serializable content.
167
+ * Return empty map to skip local artifact generation.
168
+ */
169
+ finalize(): Promise<Map<string, unknown>>;
170
+ /**
171
+ * Optional metadata to include in manifest.json
172
+ */
173
+ getManifestData?(): Promise<Record<string, unknown>>;
174
+ }
175
+ /**
176
+ * Data passed to search provider during initialization.
177
+ * Supports both file-based and pre-loaded data modes.
178
+ */
179
+ interface SearchProviderInitData {
180
+ /** Path to docs.json (file mode) */
181
+ docsPath?: string;
182
+ /** Path to search-index.json (file mode) */
183
+ indexPath?: string;
184
+ /** Pre-loaded docs (data mode) */
185
+ docs?: Record<string, ProcessedDoc>;
186
+ /** Pre-loaded index data (data mode) */
187
+ indexData?: Record<string, unknown>;
188
+ }
189
+ /**
190
+ * Options for search queries
191
+ */
192
+ interface SearchOptions {
193
+ /** Maximum number of results to return */
194
+ limit?: number;
195
+ }
196
+ /**
197
+ * Runtime provider that handles search queries from MCP tools.
198
+ *
199
+ * Consumers implement this to delegate search to external systems (Glean, Algolia, etc.).
200
+ *
201
+ * @example
202
+ * ```typescript
203
+ * import type { SearchProvider, ProviderContext, SearchOptions } from 'docusaurus-plugin-mcp-server';
204
+ * import type { SearchResult, ProcessedDoc } from 'docusaurus-plugin-mcp-server';
205
+ *
206
+ * export default class GleanSearchProvider implements SearchProvider {
207
+ * readonly name = 'glean';
208
+ *
209
+ * private apiEndpoint = process.env.GLEAN_API_ENDPOINT!;
210
+ * private apiToken = process.env.GLEAN_API_TOKEN!;
211
+ *
212
+ * async initialize(context: ProviderContext): Promise<void> {
213
+ * if (!this.apiEndpoint || !this.apiToken) {
214
+ * throw new Error('GLEAN_API_ENDPOINT and GLEAN_API_TOKEN required');
215
+ * }
216
+ * }
217
+ *
218
+ * isReady(): boolean {
219
+ * return !!this.apiEndpoint && !!this.apiToken;
220
+ * }
221
+ *
222
+ * async search(query: string, options?: SearchOptions): Promise<SearchResult[]> {
223
+ * // Call Glean Search API and transform results
224
+ * return [];
225
+ * }
226
+ * }
227
+ * ```
228
+ */
229
+ interface SearchProvider {
230
+ /** Unique name for this provider */
231
+ readonly name: string;
232
+ /**
233
+ * Initialize the search provider.
234
+ * Called once before any search queries.
235
+ */
236
+ initialize(context: ProviderContext, initData?: SearchProviderInitData): Promise<void>;
237
+ /**
238
+ * Check if the provider is ready to handle search queries.
239
+ */
240
+ isReady(): boolean;
241
+ /**
242
+ * Search for documents matching the query.
243
+ */
244
+ search(query: string, options?: SearchOptions): Promise<SearchResult[]>;
245
+ /**
246
+ * Get a document by its route.
247
+ * Used by docs_get_page and docs_get_section tools.
248
+ */
249
+ getDocument?(route: string): Promise<ProcessedDoc | null>;
250
+ /**
251
+ * Check if the provider is healthy.
252
+ * Used for health checks and debugging.
253
+ */
254
+ healthCheck?(): Promise<{
255
+ healthy: boolean;
256
+ message?: string;
257
+ }>;
258
+ }
259
+ /**
260
+ * Type for module that exports a ContentIndexer
261
+ */
262
+ type ContentIndexerModule = {
263
+ default: new () => ContentIndexer;
264
+ };
265
+ /**
266
+ * Type for module that exports a SearchProvider
267
+ */
268
+ type SearchProviderModule = {
269
+ default: new () => SearchProvider;
270
+ };
271
+
272
+ /**
273
+ * Load an indexer by name or module path.
274
+ *
275
+ * @param specifier - Either 'flexsearch' for the built-in indexer, or a module path
276
+ * (relative path like './my-indexer.js' or npm package like '@myorg/indexer')
277
+ * @returns Instantiated ContentIndexer
278
+ *
279
+ * @example
280
+ * ```typescript
281
+ * // Built-in
282
+ * const indexer = await loadIndexer('flexsearch');
283
+ *
284
+ * // Custom relative path
285
+ * const indexer = await loadIndexer('./src/providers/algolia-indexer.js');
286
+ *
287
+ * // Custom npm package
288
+ * const indexer = await loadIndexer('@myorg/custom-indexer');
289
+ * ```
290
+ */
291
+ declare function loadIndexer(specifier: string): Promise<ContentIndexer>;
292
+ /**
293
+ * Load a search provider by name or module path.
294
+ *
295
+ * @param specifier - Either 'flexsearch' for the built-in provider, or a module path
296
+ * (relative path like './my-search.js' or npm package like '@myorg/search')
297
+ * @returns Instantiated SearchProvider
298
+ *
299
+ * @example
300
+ * ```typescript
301
+ * // Built-in
302
+ * const provider = await loadSearchProvider('flexsearch');
303
+ *
304
+ * // Custom relative path
305
+ * const provider = await loadSearchProvider('./src/providers/glean-search.js');
306
+ *
307
+ * // Custom npm package
308
+ * const provider = await loadSearchProvider('@myorg/glean-search');
309
+ * ```
310
+ */
311
+ declare function loadSearchProvider(specifier: string): Promise<SearchProvider>;
312
+
313
+ /**
314
+ * Built-in FlexSearch content indexer.
315
+ *
316
+ * This indexer builds a local FlexSearch index and produces:
317
+ * - docs.json: All processed documents keyed by route
318
+ * - search-index.json: Exported FlexSearch index for runtime search
319
+ */
320
+ declare class FlexSearchIndexer implements ContentIndexer {
321
+ readonly name = "flexsearch";
322
+ private docsIndex;
323
+ private exportedIndex;
324
+ private docCount;
325
+ /**
326
+ * FlexSearch indexer always runs by default.
327
+ * It respects the indexers configuration - if not included, it won't run.
328
+ */
329
+ shouldRun(): boolean;
330
+ initialize(_context: ProviderContext): Promise<void>;
331
+ indexDocuments(docs: ProcessedDoc[]): Promise<void>;
332
+ finalize(): Promise<Map<string, unknown>>;
333
+ getManifestData(): Promise<Record<string, unknown>>;
334
+ }
335
+
85
336
  /**
86
337
  * Document structure for FlexSearch indexing
87
338
  */
@@ -122,6 +373,35 @@ declare function exportSearchIndex(index: FlexSearchDocument): Promise<unknown>;
122
373
  */
123
374
  declare function importSearchIndex(data: Record<string, unknown>): Promise<FlexSearchDocument>;
124
375
 
376
+ /**
377
+ * Built-in FlexSearch search provider.
378
+ *
379
+ * This provider uses the local FlexSearch index for search queries.
380
+ * Supports both file-based loading (Node.js) and pre-loaded data (Workers).
381
+ */
382
+ declare class FlexSearchProvider implements SearchProvider {
383
+ readonly name = "flexsearch";
384
+ private docs;
385
+ private searchIndex;
386
+ private ready;
387
+ initialize(_context: ProviderContext, initData?: SearchProviderInitData): Promise<void>;
388
+ isReady(): boolean;
389
+ search(query: string, options?: SearchOptions): Promise<SearchResult[]>;
390
+ getDocument(route: string): Promise<ProcessedDoc | null>;
391
+ healthCheck(): Promise<{
392
+ healthy: boolean;
393
+ message?: string;
394
+ }>;
395
+ /**
396
+ * Get all loaded documents (for compatibility with existing server code)
397
+ */
398
+ getDocs(): Record<string, ProcessedDoc> | null;
399
+ /**
400
+ * Get the FlexSearch index (for compatibility with existing server code)
401
+ */
402
+ getSearchIndex(): FlexSearchDocument | null;
403
+ }
404
+
125
405
  /**
126
406
  * Tool definition for docs_search
127
407
  */
@@ -231,4 +511,4 @@ declare function discoverHtmlFiles(outDir: string): Promise<FlattenedRoute[]>;
231
511
  */
232
512
  declare function collectRoutes(outDir: string, excludePatterns: string[]): Promise<FlattenedRoute[]>;
233
513
 
234
- export { DocHeading, ExtractedContent, FlattenedRoute, type FlexSearchDocument, McpDocsServer, McpServerConfig, McpServerPluginOptions, ProcessedDoc, SearchResult, buildSearchIndex, collectRoutes, mcpServerPlugin as default, discoverHtmlFiles, docsGetPageTool, docsGetSectionTool, docsSearchTool, exportSearchIndex, extractContent, extractHeadingsFromMarkdown, extractSection, htmlToMarkdown, importSearchIndex, mcpServerPlugin, parseHtml, parseHtmlFile, searchIndex };
514
+ export { type ContentIndexer, type ContentIndexerModule, DocHeading, ExtractedContent, FlattenedRoute, type FlexSearchDocument, FlexSearchIndexer, FlexSearchProvider, McpDocsServer, McpServerConfig, McpServerPluginOptions, ProcessedDoc, type ProviderContext, type SearchOptions, type SearchProvider, type SearchProviderInitData, type SearchProviderModule, SearchResult, buildSearchIndex, collectRoutes, mcpServerPlugin as default, discoverHtmlFiles, docsGetPageTool, docsGetSectionTool, docsSearchTool, exportSearchIndex, extractContent, extractHeadingsFromMarkdown, extractSection, htmlToMarkdown, importSearchIndex, loadIndexer, loadSearchProvider, mcpServerPlugin, parseHtml, parseHtmlFile, searchIndex };