@venizia/ignis-docs 0.0.1-1

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.
Files changed (123) hide show
  1. package/mcp-server/dist/common/config.d.ts +27 -0
  2. package/mcp-server/dist/common/config.d.ts.map +1 -0
  3. package/mcp-server/dist/common/config.js +27 -0
  4. package/mcp-server/dist/common/config.js.map +1 -0
  5. package/mcp-server/dist/common/index.d.ts +3 -0
  6. package/mcp-server/dist/common/index.d.ts.map +1 -0
  7. package/mcp-server/dist/common/index.js +19 -0
  8. package/mcp-server/dist/common/index.js.map +1 -0
  9. package/mcp-server/dist/common/paths.d.ts +13 -0
  10. package/mcp-server/dist/common/paths.d.ts.map +1 -0
  11. package/mcp-server/dist/common/paths.js +23 -0
  12. package/mcp-server/dist/common/paths.js.map +1 -0
  13. package/mcp-server/dist/helpers/docs.helper.d.ts +81 -0
  14. package/mcp-server/dist/helpers/docs.helper.d.ts.map +1 -0
  15. package/mcp-server/dist/helpers/docs.helper.js +171 -0
  16. package/mcp-server/dist/helpers/docs.helper.js.map +1 -0
  17. package/mcp-server/dist/helpers/index.d.ts +3 -0
  18. package/mcp-server/dist/helpers/index.d.ts.map +1 -0
  19. package/mcp-server/dist/helpers/index.js +19 -0
  20. package/mcp-server/dist/helpers/index.js.map +1 -0
  21. package/mcp-server/dist/helpers/logger.helper.d.ts +7 -0
  22. package/mcp-server/dist/helpers/logger.helper.d.ts.map +1 -0
  23. package/mcp-server/dist/helpers/logger.helper.js +22 -0
  24. package/mcp-server/dist/helpers/logger.helper.js.map +1 -0
  25. package/mcp-server/dist/index.d.ts +3 -0
  26. package/mcp-server/dist/index.d.ts.map +1 -0
  27. package/mcp-server/dist/index.js +62 -0
  28. package/mcp-server/dist/index.js.map +1 -0
  29. package/mcp-server/dist/tools/base.tool.d.ts +98 -0
  30. package/mcp-server/dist/tools/base.tool.d.ts.map +1 -0
  31. package/mcp-server/dist/tools/base.tool.js +47 -0
  32. package/mcp-server/dist/tools/base.tool.js.map +1 -0
  33. package/mcp-server/dist/tools/get-doc-content.tool.d.ts +30 -0
  34. package/mcp-server/dist/tools/get-doc-content.tool.d.ts.map +1 -0
  35. package/mcp-server/dist/tools/get-doc-content.tool.js +127 -0
  36. package/mcp-server/dist/tools/get-doc-content.tool.js.map +1 -0
  37. package/mcp-server/dist/tools/get-doc-metadata.tool.d.ts +40 -0
  38. package/mcp-server/dist/tools/get-doc-metadata.tool.d.ts.map +1 -0
  39. package/mcp-server/dist/tools/get-doc-metadata.tool.js +121 -0
  40. package/mcp-server/dist/tools/get-doc-metadata.tool.js.map +1 -0
  41. package/mcp-server/dist/tools/index.d.ts +8 -0
  42. package/mcp-server/dist/tools/index.d.ts.map +1 -0
  43. package/mcp-server/dist/tools/index.js +18 -0
  44. package/mcp-server/dist/tools/index.js.map +1 -0
  45. package/mcp-server/dist/tools/list-categories.tool.d.ts +20 -0
  46. package/mcp-server/dist/tools/list-categories.tool.d.ts.map +1 -0
  47. package/mcp-server/dist/tools/list-categories.tool.js +105 -0
  48. package/mcp-server/dist/tools/list-categories.tool.js.map +1 -0
  49. package/mcp-server/dist/tools/list-docs.tool.d.ts +32 -0
  50. package/mcp-server/dist/tools/list-docs.tool.d.ts.map +1 -0
  51. package/mcp-server/dist/tools/list-docs.tool.js +121 -0
  52. package/mcp-server/dist/tools/list-docs.tool.js.map +1 -0
  53. package/mcp-server/dist/tools/search-docs.tool.d.ts +32 -0
  54. package/mcp-server/dist/tools/search-docs.tool.d.ts.map +1 -0
  55. package/mcp-server/dist/tools/search-docs.tool.js +120 -0
  56. package/mcp-server/dist/tools/search-docs.tool.js.map +1 -0
  57. package/package.json +102 -0
  58. package/wiki/get-started/5-minute-quickstart.md +266 -0
  59. package/wiki/get-started/best-practices/api-usage-examples.md +222 -0
  60. package/wiki/get-started/best-practices/architectural-patterns.md +129 -0
  61. package/wiki/get-started/best-practices/code-style-standards.md +122 -0
  62. package/wiki/get-started/best-practices/common-pitfalls.md +136 -0
  63. package/wiki/get-started/best-practices/contribution-workflow.md +145 -0
  64. package/wiki/get-started/best-practices/deployment-strategies.md +121 -0
  65. package/wiki/get-started/best-practices/performance-optimization.md +88 -0
  66. package/wiki/get-started/best-practices/security-guidelines.md +97 -0
  67. package/wiki/get-started/best-practices/troubleshooting-tips.md +100 -0
  68. package/wiki/get-started/building-a-crud-api.md +717 -0
  69. package/wiki/get-started/core-concepts/application.md +168 -0
  70. package/wiki/get-started/core-concepts/components.md +96 -0
  71. package/wiki/get-started/core-concepts/controllers.md +441 -0
  72. package/wiki/get-started/core-concepts/dependency-injection.md +160 -0
  73. package/wiki/get-started/core-concepts/persistent.md +591 -0
  74. package/wiki/get-started/core-concepts/services.md +88 -0
  75. package/wiki/get-started/index.md +65 -0
  76. package/wiki/get-started/mcp-docs-server.md +840 -0
  77. package/wiki/get-started/philosophy.md +123 -0
  78. package/wiki/get-started/prerequisites.md +113 -0
  79. package/wiki/get-started/quickstart.md +382 -0
  80. package/wiki/index.md +48 -0
  81. package/wiki/references/base/application.md +67 -0
  82. package/wiki/references/base/components.md +80 -0
  83. package/wiki/references/base/controllers.md +361 -0
  84. package/wiki/references/base/datasources.md +105 -0
  85. package/wiki/references/base/dependency-injection.md +83 -0
  86. package/wiki/references/base/models.md +104 -0
  87. package/wiki/references/base/repositories.md +118 -0
  88. package/wiki/references/base/services.md +97 -0
  89. package/wiki/references/components/authentication.md +224 -0
  90. package/wiki/references/components/health-check.md +190 -0
  91. package/wiki/references/components/index.md +61 -0
  92. package/wiki/references/components/request-tracker.md +35 -0
  93. package/wiki/references/components/socket-io.md +127 -0
  94. package/wiki/references/components/swagger.md +175 -0
  95. package/wiki/references/helpers/cron.md +94 -0
  96. package/wiki/references/helpers/crypto.md +117 -0
  97. package/wiki/references/helpers/env.md +67 -0
  98. package/wiki/references/helpers/error.md +80 -0
  99. package/wiki/references/helpers/index.md +21 -0
  100. package/wiki/references/helpers/inversion.md +141 -0
  101. package/wiki/references/helpers/logger.md +98 -0
  102. package/wiki/references/helpers/network.md +143 -0
  103. package/wiki/references/helpers/queue.md +131 -0
  104. package/wiki/references/helpers/redis.md +121 -0
  105. package/wiki/references/helpers/socket-io.md +103 -0
  106. package/wiki/references/helpers/storage.md +130 -0
  107. package/wiki/references/helpers/testing.md +115 -0
  108. package/wiki/references/helpers/worker-thread.md +162 -0
  109. package/wiki/references/src-details/core.md +249 -0
  110. package/wiki/references/src-details/dev-configs.md +302 -0
  111. package/wiki/references/src-details/docs.md +61 -0
  112. package/wiki/references/src-details/helpers.md +211 -0
  113. package/wiki/references/src-details/inversion.md +345 -0
  114. package/wiki/references/src-details/mcp-server.md +726 -0
  115. package/wiki/references/utilities/crypto.md +39 -0
  116. package/wiki/references/utilities/date.md +72 -0
  117. package/wiki/references/utilities/index.md +12 -0
  118. package/wiki/references/utilities/module.md +40 -0
  119. package/wiki/references/utilities/parse.md +68 -0
  120. package/wiki/references/utilities/performance.md +64 -0
  121. package/wiki/references/utilities/promise.md +83 -0
  122. package/wiki/references/utilities/request.md +66 -0
  123. package/wiki/references/utilities/schema.md +88 -0
@@ -0,0 +1,726 @@
1
+ # MCP Docs Server: Deep Dive
2
+
3
+ This document provides a detailed look into the architecture, features, and internal workings of the Ignis Documentation MCP Server. For a guide on how to use the server, see the [MCP Docs Server Quickstart](/get-started/mcp-docs-server).
4
+
5
+ ---
6
+
7
+ ## Architecture Overview
8
+
9
+ ### System Architecture
10
+
11
+ ```mermaid
12
+ graph TB
13
+ AI[AI Assistant / MCP Client]
14
+ MCP[MCPServer Entry Point]
15
+ Tools[MCP Tools Layer]
16
+ Helpers[Business Logic Layer]
17
+ Cache[In-Memory Cache]
18
+ FS[File System / Wiki Docs]
19
+
20
+ AI -->|MCP Protocol| MCP
21
+ MCP --> Tools
22
+ Tools --> Helpers
23
+ Helpers --> Cache
24
+ Cache -.->|Cache Miss| FS
25
+
26
+ style AI fill:#e1f5ff
27
+ style MCP fill:#fff4e1
28
+ style Tools fill:#f0f0f0
29
+ style Helpers fill:#e8f5e9
30
+ style Cache fill:#fce4ec
31
+ style FS fill:#f3e5f5
32
+ ```
33
+
34
+ ### Component Responsibilities
35
+
36
+ | Component | Responsibility | Key Features |
37
+ |-----------|---------------|--------------|
38
+ | **MCP Server** | Protocol handling, request routing | Stdio transport, tool registration |
39
+ | **Tools Layer** | Input validation, output formatting | Zod schemas, type safety |
40
+ | **DocsHelper** | Business logic, search, caching | Fuse.js search, memory cache |
41
+ | **File System** | Documentation storage | Markdown files with frontmatter |
42
+
43
+ ---
44
+
45
+ ## Data Flow
46
+
47
+ ### Search Request Flow
48
+
49
+ ```mermaid
50
+ sequenceDiagram
51
+ participant AI as AI Assistant
52
+ participant MCP as MCP Server
53
+ participant Tool as SearchDocsTool
54
+ participant Helper as DocsHelper
55
+ participant Cache as Memory Cache
56
+ participant FS as File System
57
+
58
+ AI->>MCP: searchDocs("dependency injection")
59
+ MCP->>Tool: Route to tool handler
60
+ Tool->>Tool: Validate input with Zod
61
+ Tool->>Helper: DocsHelper.searchDocs()
62
+
63
+ alt Cache Empty (First Call)
64
+ Helper->>FS: Load all .md files
65
+ FS-->>Helper: Raw markdown files
66
+ Helper->>Helper: Parse frontmatter
67
+ Helper->>Helper: Build Fuse.js index
68
+ Helper->>Cache: Store docs + index
69
+ end
70
+
71
+ Helper->>Cache: Query Fuse.js index
72
+ Cache-->>Helper: Matching documents
73
+ Helper->>Helper: Generate smart snippets
74
+ Helper-->>Tool: Search results
75
+ Tool->>Tool: Validate output with Zod
76
+ Tool-->>MCP: Formatted response
77
+ MCP-->>AI: JSON results
78
+ ```
79
+
80
+ ---
81
+
82
+ ## Tools Reference
83
+
84
+ ### Tool Comparison Table
85
+
86
+ | Tool | Purpose | Input Complexity | Use Case |
87
+ |------|---------|------------------|----------|
88
+ | `searchDocs` | Find docs by keyword | Simple (query + limit) | "How do I use Redis?" |
89
+ | `getDocContent` | Get full document | Simple (id only) | Retrieve specific guide |
90
+ | `listDocs` | Browse all docs | Simple (optional filter) | Explore documentation |
91
+ | `listCategories` | List all categories | None | Understand structure |
92
+ | `getDocMetadata` | Get doc stats | Simple (id only) | Check length before reading |
93
+
94
+ ### 1. searchDocs
95
+
96
+ **What it does:** Fuzzy searches across all documentation titles and content.
97
+
98
+ **Parameters:**
99
+
100
+ | Parameter | Type | Required | Default | Description |
101
+ |-----------|------|----------|---------|-------------|
102
+ | `query` | string | Yes | - | Search keywords (min 2 chars) |
103
+ | `limit` | number | No | 10 | Max results (1-50) |
104
+
105
+ **Returns:**
106
+
107
+ ```typescript
108
+ Array<{
109
+ id: string; // "get-started/intro.md"
110
+ title: string; // "Introduction to Ignis"
111
+ category: string; // "Getting Started"
112
+ snippet: string; // First 300 chars preview
113
+ score: number; // 0-1 relevance (lower = better)
114
+ }>
115
+ ```
116
+
117
+ **Example Request:**
118
+
119
+ ```json
120
+ {
121
+ "query": "dependency injection",
122
+ "limit": 5
123
+ }
124
+ ```
125
+
126
+ **Example Response:**
127
+
128
+ ```json
129
+ [
130
+ {
131
+ "id": "core-concepts/dependency-injection.md",
132
+ "title": "Dependency Injection",
133
+ "category": "Core Concepts",
134
+ "snippet": "Ignis uses a powerful dependency injection system that allows you to...",
135
+ "score": 0.12
136
+ }
137
+ ]
138
+ ```
139
+
140
+ ---
141
+
142
+ ### 2. getDocContent
143
+
144
+ **What it does:** Retrieves the full markdown content of a specific document.
145
+
146
+ **Parameters:**
147
+
148
+ | Parameter | Type | Required | Description |
149
+ |-----------|------|----------|-------------|
150
+ | `id` | string | Yes | Document ID from search/list |
151
+
152
+ **Returns:**
153
+
154
+ ```typescript
155
+ {
156
+ content: string; // Full markdown content
157
+ id: string; // Document ID
158
+ error?: string; // Error message if not found
159
+ }
160
+ ```
161
+
162
+ **Example Request:**
163
+
164
+ ```json
165
+ {
166
+ "id": "get-started/intro.md"
167
+ }
168
+ ```
169
+
170
+ ---
171
+
172
+ ### 3. listDocs
173
+
174
+ **What it does:** Lists all documentation files with their metadata.
175
+
176
+ **Parameters:**
177
+
178
+ | Parameter | Type | Required | Description |
179
+ |-----------|------|----------|-------------|
180
+ | `category` | string | No | Filter by category name |
181
+
182
+ **Returns:**
183
+
184
+ ```typescript
185
+ {
186
+ count: number;
187
+ docs: Array<{
188
+ id: string;
189
+ title: string;
190
+ category: string;
191
+ }>;
192
+ }
193
+ ```
194
+
195
+ **Example Response:**
196
+
197
+ ```json
198
+ {
199
+ "count": 15,
200
+ "docs": [
201
+ {
202
+ "id": "get-started/intro.md",
203
+ "title": "Introduction",
204
+ "category": "Getting Started"
205
+ }
206
+ ]
207
+ }
208
+ ```
209
+
210
+ ---
211
+
212
+ ### 4. listCategories
213
+
214
+ **What it does:** Lists all unique categories, sorted alphabetically.
215
+
216
+ **Parameters:** None
217
+
218
+ **Returns:**
219
+
220
+ ```typescript
221
+ {
222
+ count: number;
223
+ categories: string[]; // ["Core Concepts", "Getting Started", ...]
224
+ }
225
+ ```
226
+
227
+ **Example Response:**
228
+
229
+ ```json
230
+ {
231
+ "count": 6,
232
+ "categories": [
233
+ "Core Concepts",
234
+ "Getting Started",
235
+ "Helpers",
236
+ "References"
237
+ ]
238
+ }
239
+ ```
240
+
241
+ ---
242
+
243
+ ### 5. getDocMetadata
244
+
245
+ **What it does:** Retrieves statistics about a document without loading full content.
246
+
247
+ **Parameters:**
248
+
249
+ | Parameter | Type | Required | Description |
250
+ |-----------|------|----------|-------------|
251
+ | `id` | string | Yes | Document ID |
252
+
253
+ **Returns:**
254
+
255
+ ```typescript
256
+ {
257
+ id: string;
258
+ title: string;
259
+ category: string;
260
+ wordCount: number;
261
+ charCount: number;
262
+ lastModified?: string;
263
+ size?: number; // Bytes
264
+ }
265
+ ```
266
+
267
+ **Example Response:**
268
+
269
+ ```json
270
+ {
271
+ "id": "core-concepts/dependency-injection.md",
272
+ "title": "Dependency Injection",
273
+ "category": "Core Concepts",
274
+ "wordCount": 2500,
275
+ "charCount": 15234,
276
+ "size": 15234
277
+ }
278
+ ```
279
+
280
+ ---
281
+
282
+ ## Resources
283
+
284
+ The server exposes documentation as MCP resources for direct access:
285
+
286
+ | Property | Value |
287
+ |----------|-------|
288
+ | **URI Format** | `ignis://docs/{document-id}` |
289
+ | **MIME Type** | `text/markdown` |
290
+ | **Metadata** | Category and word count in description |
291
+
292
+ **Example Resource:**
293
+
294
+ ```json
295
+ {
296
+ "uri": "ignis://docs/get-started/intro.md",
297
+ "name": "Introduction",
298
+ "description": "Getting Started - 450 words",
299
+ "mimeType": "text/markdown"
300
+ }
301
+ ```
302
+
303
+ ---
304
+
305
+ ## Search Configuration
306
+
307
+ ### Fuse.js Settings
308
+
309
+ The search engine uses optimized Fuse.js configuration:
310
+
311
+ | Setting | Value | Explanation |
312
+ |---------|-------|-------------|
313
+ | **threshold** | 0.4 | Balance between strict and fuzzy matching |
314
+ | **ignoreLocation** | true | Match anywhere in document, not just at start |
315
+ | **findAllMatches** | true | Return all relevant matches, not just first |
316
+ | **minMatchCharLength** | 2 | Minimum characters to trigger a match |
317
+
318
+ ### Search Weights
319
+
320
+ ```mermaid
321
+ pie
322
+ title Search Weight Distribution
323
+ "Title" : 70
324
+ "Content" : 30
325
+ ```
326
+
327
+ | Field | Weight | Rationale |
328
+ |-------|--------|-----------|
329
+ | Title | 70% | Document titles are highly relevant |
330
+ | Content | 30% | Body content provides context |
331
+
332
+ **Why this matters:** When you search for "dependency injection", documents with that phrase in the title will rank higher than those with it only in the content.
333
+
334
+ ---
335
+
336
+ ## Project Structure
337
+
338
+ ```
339
+ mcp-server/
340
+ ├── common/
341
+ │ ├── config.ts # Configuration constants
342
+ │ ├── logger.ts # Logging infrastructure
343
+ │ ├── paths.ts # Path resolution
344
+ │ └── index.ts # Common exports
345
+ ├── helpers/
346
+ │ ├── docs.helper.ts # Documentation loading and searching
347
+ │ └── index.ts # Helper exports
348
+ ├── tools/
349
+ │ ├── base.tool.ts # Abstract base class for tools
350
+ │ ├── search-docs.tool.ts
351
+ │ ├── get-doc-content.tool.ts
352
+ │ ├── list-docs.tool.ts
353
+ │ ├── list-categories.tool.ts
354
+ │ ├── get-doc-metadata.tool.ts
355
+ │ └── index.ts
356
+ ├── index.ts # Server entry point
357
+ └── README.md
358
+ ```
359
+
360
+ ### File Responsibilities
361
+
362
+ | File | Purpose | Key Exports |
363
+ |------|---------|-------------|
364
+ | `index.ts` | Server initialization, tool registration | `main()`, `mcpServer` |
365
+ | `tools/base.tool.ts` | Abstract tool class, singleton pattern | `BaseTool`, `createTool` |
366
+ | `helpers/docs.helper.ts` | Documentation loading, search, cache | `DocsHelper` class |
367
+ | `common/config.ts` | Centralized configuration | `MCP_CONFIG` object |
368
+ | `common/logger.ts` | Structured logging | `Logger` class |
369
+ | `common/paths.ts` | Path resolution | `PATHS` object |
370
+
371
+ ---
372
+
373
+ ## Performance Characteristics
374
+
375
+ ### Caching Strategy
376
+
377
+ ```mermaid
378
+ graph LR
379
+ A[First Request] --> B{Cache Empty?}
380
+ B -->|Yes| C[Load from FS]
381
+ C --> D[Parse Frontmatter]
382
+ D --> E[Build Fuse Index]
383
+ E --> F[Store in Memory]
384
+ F --> G[Return Results]
385
+ B -->|No| G
386
+
387
+ style C fill:#ffcdd2
388
+ style F fill:#c8e6c9
389
+ style G fill:#bbdefb
390
+ ```
391
+
392
+ ### Performance Metrics
393
+
394
+ | Operation | First Call | Subsequent Calls | Notes |
395
+ |-----------|-----------|------------------|-------|
396
+ | **Load Docs** | ~50-200ms | 0ms | Cached in memory |
397
+ | **Search** | ~100-300ms | ~5-20ms | Includes initial load |
398
+ | **Get Content** | ~50-200ms | ~1-5ms | Fast lookup by ID |
399
+ | **List Docs** | ~50-200ms | ~1-3ms | Pre-cached metadata |
400
+ | **Memory Usage** | ~5-10MB | ~5-10MB | Scales with doc count |
401
+
402
+ **Optimization Tips:**
403
+
404
+ - First search is slower (loads all docs)
405
+ - Subsequent searches are cached (very fast)
406
+ - Memory usage is constant after first load
407
+ - No disk I/O after initialization
408
+
409
+ ---
410
+
411
+ ## Error Handling
412
+
413
+ ### Error Response Format
414
+
415
+ All tools return consistent error responses:
416
+
417
+ ```json
418
+ {
419
+ "error": "Document not found",
420
+ "id": "requested-id"
421
+ }
422
+ ```
423
+
424
+ ### Common Errors
425
+
426
+ | Error | Cause | Solution |
427
+ |-------|-------|----------|
428
+ | "Document not found" | Invalid document ID | Use `listDocs` to find valid IDs |
429
+ | "Query too short" | Query < 2 characters | Use longer search query |
430
+ | "Limit out of range" | Limit > 50 or < 1 | Use default (10) or valid range |
431
+ | "Failed to load documentation" | File system error | Check wiki directory exists |
432
+
433
+ ### Logging Levels
434
+
435
+ | Level | Usage | Example |
436
+ |-------|-------|---------|
437
+ | **info** | General information | "Server started", "Docs loaded" |
438
+ | **warn** | Non-critical issues | "Document not found" |
439
+ | **error** | Critical errors | "Failed to load docs" |
440
+ | **debug** | Development details | Search queries, cache hits |
441
+
442
+ **Enable debug logging:**
443
+
444
+ ```bash
445
+ DEBUG=1 ignis-docs-mcp
446
+ ```
447
+
448
+ ---
449
+
450
+ ## Development Guide
451
+
452
+ ### Tool Architecture Pattern
453
+
454
+ All tools extend the `BaseTool` abstract class:
455
+
456
+ ```typescript
457
+ export abstract class BaseTool<
458
+ TInputSchema extends z.ZodType,
459
+ TOutputSchema extends z.ZodType
460
+ > {
461
+ // Singleton pattern
462
+ static getInstance<T extends BaseTool>(this: new () => T): T {
463
+ // Returns cached instance or creates new one
464
+ }
465
+
466
+ // Required implementations
467
+ abstract readonly id: string;
468
+ abstract readonly description: string;
469
+ abstract readonly inputSchema: TInputSchema;
470
+ abstract readonly outputSchema: TOutputSchema;
471
+
472
+ abstract execute(input: z.infer<TInputSchema>): Promise<z.infer<TOutputSchema>>;
473
+ abstract getTool(): MastraTool;
474
+ }
475
+ ```
476
+
477
+ ### Adding a New Tool
478
+
479
+ **Step 1: Create Tool File**
480
+
481
+ Create `tools/my-new-tool.tool.ts`:
482
+
483
+ ```typescript
484
+ import { z } from 'zod';
485
+ import { BaseTool, createTool, type MastraTool } from './base.tool';
486
+ import { DocsHelper } from '../helpers';
487
+
488
+ // Define schemas
489
+ const InputSchema = z.object({
490
+ param: z.string().describe('Parameter description'),
491
+ });
492
+
493
+ const OutputSchema = z.object({
494
+ result: z.string().describe('Result description'),
495
+ });
496
+
497
+ // Implement tool class
498
+ export class MyNewTool extends BaseTool<typeof InputSchema, typeof OutputSchema> {
499
+ readonly id = 'myNewTool';
500
+ readonly description = 'What this tool does';
501
+ readonly inputSchema = InputSchema;
502
+ readonly outputSchema = OutputSchema;
503
+
504
+ async execute(input: z.infer<typeof InputSchema>) {
505
+ // Your logic here
506
+ return { result: 'output' };
507
+ }
508
+
509
+ getTool(): MastraTool {
510
+ return createTool({
511
+ id: this.id,
512
+ description: this.description,
513
+ inputSchema: InputSchema,
514
+ outputSchema: OutputSchema,
515
+ execute: async ({ context }) => this.execute(context),
516
+ });
517
+ }
518
+ }
519
+ ```
520
+
521
+ **Step 2: Export from Index**
522
+
523
+ Add to `tools/index.ts`:
524
+
525
+ ```typescript
526
+ export { MyNewTool } from './my-new-tool.tool';
527
+ ```
528
+
529
+ **Step 3: Register in Server**
530
+
531
+ Add to `index.ts`:
532
+
533
+ ```typescript
534
+ import { MyNewTool } from './tools';
535
+
536
+ const mcpServer = new MCPServer({
537
+ tools: {
538
+ myNewTool: new MyNewTool().getTool(),
539
+ // ... other tools
540
+ },
541
+ });
542
+ ```
543
+
544
+ ### Configuration Updates
545
+
546
+ Modify `common/config.ts` to adjust global settings:
547
+
548
+ ```typescript
549
+ export const MCP_CONFIG = {
550
+ server: {
551
+ name: 'ignis-docs',
552
+ version: '0.0.1',
553
+ },
554
+ search: {
555
+ defaultLimit: 10, // Change default result count
556
+ maxLimit: 50, // Change maximum result count
557
+ minQueryLength: 2, // Change minimum query length
558
+ snippetLength: 300, // Change snippet preview length
559
+ },
560
+ fuse: {
561
+ threshold: 0.4, // Adjust fuzzy matching strictness
562
+ keys: [
563
+ { name: 'title', weight: 0.7 }, // Adjust title weight
564
+ { name: 'content', weight: 0.3 }, // Adjust content weight
565
+ ],
566
+ },
567
+ };
568
+ ```
569
+
570
+ **Configuration Impact:**
571
+
572
+ | Setting | Low Value | High Value |
573
+ |---------|-----------|------------|
574
+ | `threshold` | Stricter matches | More fuzzy matches |
575
+ | `title weight` | Less title importance | More title importance |
576
+ | `snippetLength` | Shorter previews | Longer previews |
577
+
578
+ ---
579
+
580
+ ## Best Practices
581
+
582
+ ### For AI Assistants
583
+
584
+ 1. **Search First**: Use `searchDocs` to find relevant documentation before fetching full content
585
+ 2. **Filter Smart**: Use `listCategories` → `listDocs(category)` for category-specific browsing
586
+ 3. **Check Size**: Use `getDocMetadata` before `getDocContent` for large documents
587
+ 4. **Batch Queries**: If you need multiple docs, fetch IDs first then retrieve content
588
+ 5. **Handle Errors**: Always check for error field in responses
589
+
590
+ ### For Developers
591
+
592
+ 1. **Document IDs**: Always use relative paths from wiki root (e.g., "get-started/intro.md")
593
+ 2. **Frontmatter**: Ensure all markdown files have `title` and `category` in frontmatter
594
+ 3. **Search Queries**: Use descriptive queries for better results (minimum 2 characters)
595
+ 4. **Result Limits**: Adjust limit parameter based on needs (default: 10, max: 50)
596
+ 5. **Logging**: Enable DEBUG mode during development for detailed logs
597
+
598
+ ### Workflow Examples
599
+
600
+ **Example 1: Answer "How do I use Redis?"**
601
+
602
+ ```
603
+ 1. searchDocs("Redis") → Find relevant docs
604
+ 2. Review snippets → Identify best match (e.g., "helpers/redis.md")
605
+ 3. getDocContent("helpers/redis.md") → Retrieve full guide
606
+ 4. Extract and format answer for user
607
+ ```
608
+
609
+ **Example 2: Browse helpers documentation**
610
+
611
+ ```
612
+ 1. listCategories() → Get all categories
613
+ 2. listDocs({ category: "Helpers" }) → Get all helper docs
614
+ 3. Present list to user → Let them choose
615
+ 4. getDocContent(selectedId) → Show full documentation
616
+ ```
617
+
618
+ **Example 3: Check document before reading**
619
+
620
+ ```
621
+ 1. getDocMetadata("references/api.md") → Check length
622
+ 2. If wordCount > 5000 → Warn user it's long
623
+ 3. getDocContent("references/api.md") → Fetch full content
624
+ ```
625
+
626
+ ---
627
+
628
+ ## Debugging
629
+
630
+ ### Enable Debug Mode
631
+
632
+ ```bash
633
+ # Show all debug logs
634
+ DEBUG=1 ignis-docs-mcp
635
+
636
+ # Show specific component logs
637
+ DEBUG=docs:search ignis-docs-mcp
638
+ DEBUG=docs:cache ignis-docs-mcp
639
+ ```
640
+
641
+ ### Debug Output Examples
642
+
643
+ ```
644
+ [debug] Loading documentation from: /path/to/wiki
645
+ [debug] Found 45 markdown files
646
+ [debug] Building Fuse.js search index
647
+ [debug] Cache populated with 45 documents
648
+ [debug] Search query: "dependency injection"
649
+ [debug] Found 3 matches in 12ms
650
+ ```
651
+
652
+ ### Common Debug Tasks
653
+
654
+ | Task | Command | Expected Output |
655
+ |------|---------|----------------|
656
+ | Verify docs load | `DEBUG=1 ignis-docs-mcp` | "Cache populated with N documents" |
657
+ | Check search | Use searchDocs tool | "Found N matches in Xms" |
658
+ | Inspect cache | Check memory usage | ~5-10MB after first load |
659
+
660
+ ---
661
+
662
+ ## Roadmap
663
+
664
+ ### Planned Features
665
+
666
+ - [ ] **Prompts Support** - When @mastra/mcp library adds support
667
+ - [ ] **Incremental Search** - Real-time search as user types
668
+ - [ ] **Semantic Search** - AI-powered semantic matching
669
+ - [ ] **Document Versioning** - Track documentation changes
670
+ - [ ] **Multi-language Support** - i18n documentation support
671
+
672
+ ### Contributing
673
+
674
+ Want to add features or fix bugs? See the main Ignis repository:
675
+
676
+ - **Repository**: https://github.com/venizia-ai/ignis
677
+ - **Issues**: Report bugs or request features
678
+ - **Pull Requests**: Submit improvements
679
+
680
+ ---
681
+
682
+ ## FAQ
683
+
684
+ ### How does caching work?
685
+
686
+ Documentation is loaded into memory on the first request and stays cached for the lifetime of the server process. This means:
687
+ - First search: ~100-300ms (loads all docs)
688
+ - Subsequent searches: ~5-20ms (cached)
689
+ - Memory usage: ~5-10MB (constant)
690
+
691
+ ### Can I use this with other frameworks?
692
+
693
+ Yes! The MCP server architecture is framework-agnostic. You can fork this repo and adapt it to serve documentation for any project by:
694
+ 1. Replacing the wiki directory
695
+ 2. Updating the server name/version
696
+ 3. Adjusting configuration as needed
697
+
698
+ ### How do I update the documentation?
699
+
700
+ If you installed via npm:
701
+ ```bash
702
+ npm update -g @venizia/ignis-docs
703
+ ```
704
+
705
+ The package includes bundled documentation that updates with each release.
706
+
707
+ ### What if a document isn't found?
708
+
709
+ The tool returns an error object:
710
+ ```json
711
+ {
712
+ "error": "Document not found",
713
+ "id": "invalid-id"
714
+ }
715
+ ```
716
+
717
+ Use `listDocs()` to get valid document IDs.
718
+
719
+ ### How accurate is the fuzzy search?
720
+
721
+ The search uses a threshold of 0.4, which balances between strict and fuzzy matching:
722
+ - Exact matches: Always ranked first
723
+ - Close matches: Tolerate 1-2 character typos
724
+ - Partial matches: Find substrings anywhere in title/content
725
+
726
+ Adjust `MCP_CONFIG.fuse.threshold` to make it stricter (lower) or fuzzier (higher).