Skip to main content

Docs MCP Server

Overview

The Docs MCP Server provides full-text search over the entire Docusaurus documentation tree. It uses the DocsIndexer class with an in-process weighted search index over all .mdx files under docusaurus-docs/docs/. This is the global docs server -- for per-domain scoped search, see Domain Docs Servers.

Server Metadata

PropertyValue
FactorycreateDocsMcpServer()
Sourcesrc/mastra/mcp-servers/docs-server.ts
Version1.0.0
Tool Count4
Skip FlagMASTRA_SKIP_DOCS_MCP
Tool Registrysrc/mastra/tools/docs-search/index.ts

Factory Implementation

// src/mastra/mcp-servers/docs-server.ts
import { MCPServer } from '@mastra/mcp';
import { docsSearchTools } from '../tools/docs-search/index.ts';

export function createDocsMcpServer(): MCPServer {
return new MCPServer({
name: 'Docs MCP Server',
version: '1.0.0',
description: 'Full-text search over Docusaurus project documentation.',
tools: docsSearchTools,
});
}

Tool Registry

All 4 tools are exported from src/mastra/tools/docs-search/index.ts:

Tool IDDescription
docs-searchFull-text search across all indexed documentation pages. Returns ranked results with snippets.
docs-listList all indexed documentation pages with their titles and paths.
docs-get-pageRetrieve the full content of a specific documentation page by path.
docs-refresh-indexForce a rebuild of the in-memory search index. Useful after documentation changes.

The MCP discovery contract requires each tool's outputSchema to be a top-level object schema. docs-get-page returns a success boolean plus optional page or error fields instead of exposing a top-level discriminated union, so MCP clients can safely call listTools.

DocsIndexer Implementation

The search functionality is powered by the DocsIndexer class in src/mastra/tools/docs-search/indexer.ts.

Index Construction

The indexer scans all .mdx files under docusaurus-docs/docs/, parses frontmatter and content, and builds a lightweight weighted full-text index.

// Simplified view of DocsIndexer
class DocsIndexer {
private index: LightweightDocsSearchIndex;

async buildIndex(): Promise<void> {
const files = glob('docusaurus-docs/docs/**/*.mdx');
for (const file of files) {
const { frontmatter, sections } = parseMarkdown(file);
for (const section of sections) {
this.index.addSection({
pageTitle: frontmatter.title,
pageDescription: frontmatter.description,
sectionHeading: section.heading,
content: section.content,
});
}
}
}
}

Search Ranking

The in-memory index applies field-level weighting to prioritize title and description matches:

FieldWeightPurpose
pageTitle5Highest priority -- matches on page titles rank first
pageDescription3Frontmatter description text
sectionHeading2Section headings within a page
content1Body content (lowest priority but largest volume)

Additional search options:

  • Prefix search: Partial word matches are supported (for example, "deploy" matches "deployment")
  • Typo tolerance: Long tokens tolerate one character mismatch for minor typos
  • MAX_CONTENT_LENGTH: 8000 characters -- returned result content is truncated to this limit

Index Lifecycle

  1. Startup: The index is built eagerly when the MCP server is created. The DocsIndexer instance starts indexing immediately.
  2. Caching: Once built, the index is cached in memory for all subsequent search calls. No disk persistence.
  3. Refresh: The docs-refresh-index tool forces a complete rebuild. This is useful after adding or editing documentation files without restarting the server.
  4. Concurrent safety: The buildIndex() method uses promise sharing to prevent duplicate concurrent builds. If two requests trigger a build simultaneously, both await the same promise.
// Promise-sharing pattern for concurrent safety
async buildIndex(): Promise<void> {
if (this._buildPromise) {
return this._buildPromise;
}
this._buildPromise = this._doBuildIndex();
try {
await this._buildPromise;
} finally {
this._buildPromise = null;
}
}

Implementation Notes

Local MCP Client Smoke

Use the committed stdio launcher when validating the server in Replit or a local MCP client. The launcher avoids npm lifecycle output on stdout, which can corrupt MCP stdio framing.

npm run mcp:docs:start -- docs
npm run docs:mcp:smoke -- --server docs

Global vs. Domain Scoped

The global Docs MCP Server indexes all documentation under docusaurus-docs/docs/. For clients that only need domain-specific documentation, the Domain Docs Servers provide scoped search restricted to a single subdirectory.

Skip Flag Scope

Setting MASTRA_SKIP_DOCS_MCP disables all documentation servers (global and per-domain). There is no way to selectively disable only the global server while keeping per-domain servers active.

No Database Dependencies

The Docs MCP Server has no database dependencies. It reads .mdx files from the local filesystem and maintains an in-memory index. This makes it self-contained and suitable for local development without a database connection.

Code Locations

  • Server factory: src/mastra/mcp-servers/docs-server.ts
  • Tool registry: src/mastra/tools/docs-search/index.ts
  • Indexer class: src/mastra/tools/docs-search/indexer.ts
  • Tests: tests/shared/unit/mcp-servers/mcp-servers.test.ts (Docs MCP Server describe block)
  • Indexer tests: tests/shared/unit/docs-search/indexer-class.test.ts