Skip to main content
Glama
JWears

Local Docs MCP Server

by JWears

Local Docs MCP Server

A TypeScript-based Model Context Protocol (MCP) server that exposes multiple local documentation folders (namespaces) to AI assistants via tools and resources.

Features

  • šŸ”Œ HTTP Transport: Uses Streamable HTTP on POST /mcp (no stdio)

  • šŸ“ Multi-Namespace Support: Organize docs across multiple roots with namespace isolation

  • šŸ”— Resource Access: Dynamic resource template docs://{namespace}/{path} for file access

  • šŸ› ļø Three Tools:

    • list_files - List files matching glob patterns across namespaces

    • read_file - Read specific file contents from a namespace

    • search - Search for text across multiple files and namespaces

  • šŸ”’ Security: Path traversal prevention, symlink escape detection, binary file filtering, configurable file size limits

  • šŸ“ MIME Types: Automatic MIME type detection for all files

  • āš™ļø Flexible Configuration: Configure via environment variables or docs.config.json

Related MCP server: File Context MCP Server

Installation

Dependencies are already installed. If you need to reinstall:

npm install

Configuration

Method 1: Configuration File (docs.config.json)

Create a docs.config.json file in the project root:

{
  "roots": [
    {
      "ns": "docs",
      "path": "./docs"
    },
    {
      "ns": "api",
      "path": "./api-docs"
    },
    {
      "ns": "guides",
      "path": "C:/absolute/path/to/guides"
    }
  ],
  "maxFileKB": 256,
  "allowSymlinks": false,
  "ignore": [
    "**/node_modules/**",
    "**/.git/**",
    "**/dist/**",
    "**/build/**"
  ]
}

Method 2: Environment Variables

Set the DOCS_DIRS environment variable with comma-separated namespace:path pairs:

# Windows PowerShell
$env:DOCS_DIRS="docs:./docs,api:./api-docs,guides:C:/path/to/guides"
npm run dev

Note: Environment variables take precedence and will override/merge with docs.config.json.

Configuration Options

  • roots: Array of namespace definitions

    • ns: Namespace identifier (alphanumeric, hyphens, underscores)

    • path: Absolute or relative path to the root directory

  • maxFileKB: Maximum file size in kilobytes (default: 256)

  • allowSymlinks: Allow symlinks that point outside the namespace (default: false)

  • ignore: Glob patterns to ignore (default: node_modules, .git, etc.)

  • PORT: Server port via environment variable (default: 3000)

Running the Server

Development Mode (with auto-reload)

npm run dev

Production Mode

npm start

The server will print the MCP URL on startup:

šŸš€ Local Docs MCP Server running
šŸ“ Registered namespaces:
   - docs: C:\Users\...\mcp-day\docs
   - api: C:\Users\...\mcp-day\api-docs
šŸ”— MCP URL: http://localhost:3000/mcp
šŸ’š Health check: http://localhost:3000/health

Testing with MCP Inspector

  1. Install MCP Inspector (if not already installed):

    npx @modelcontextprotocol/inspector
  2. Start the server in one terminal:

    npm run dev
  3. Open MCP Inspector in another terminal:

    npx @modelcontextprotocol/inspector
  4. Connect to the server:

    • In the Inspector UI, enter the MCP URL: http://localhost:3000/mcp

    • Transport type: HTTP

  5. Test the tools:

    List Files (all namespaces):

    {
      "pattern": "**/*.md",
      "max": 50
    }

    List Files (specific namespace):

    {
      "pattern": "**/*.md",
      "ns": "docs",
      "max": 50
    }

    List Files (multiple namespaces):

    {
      "pattern": "**/*.md",
      "ns": ["docs", "api"],
      "max": 50
    }

    Read File:

    {
      "ns": "docs",
      "path": "welcome.md"
    }

    Search (all namespaces):

    {
      "query": "MCP",
      "glob": "**/*.md",
      "max": 100
    }

    Search (specific namespace):

    {
      "query": "MCP",
      "glob": "**/*.md",
      "ns": "docs",
      "max": 100
    }
  6. Test Resources:

    • Resources now use namespace URIs: docs://{namespace}/{path}

    • Example: docs://docs/welcome.md, docs://api/endpoints.md

    • Click on any resource link in the Inspector

    • The file content should appear with proper MIME type

Project Structure

mcp-day/
ā”œā”€ā”€ server.ts              # Main MCP server implementation
ā”œā”€ā”€ src/
│   └── roots.ts          # RootRegistry implementation
ā”œā”€ā”€ package.json          # Project configuration
ā”œā”€ā”€ tsconfig.json         # TypeScript configuration
ā”œā”€ā”€ docs.config.json      # Namespace configuration
ā”œā”€ā”€ README.md            # This file
└── docs/                # Default documentation namespace
    ā”œā”€ā”€ welcome.md       # Sample markdown file
    ā”œā”€ā”€ api.md           # API reference
    └── config.json      # Sample JSON file

Tools Reference

list_files

Lists files in the docs directory matching a glob pattern. Can filter by namespace(s).

Input:

  • pattern (optional): Glob pattern (default: **/*.{md,mdx,txt,json})

  • ns (optional): Namespace(s) to search - string or array. If omitted, searches all namespaces

  • max (optional): Maximum results (default: 200)

Output:

  • count: Number of files returned

  • namespaces: Array of searched namespaces

  • files: Array with ns, path, uri, size, mtime, mimeType

  • Resource links for each file as docs://{ns}/{path}

read_file

Reads a file from a specific namespace in the docs directory.

Input:

  • ns (required): Namespace to read from

  • path (required): Relative path to the file within the namespace

Output:

  • ns: Namespace

  • path: File path

  • bytes: File size

  • lines: Line count

  • Resource link to the file content as docs://{ns}/{path}

Searches for text in files. Can filter by namespace(s).

Input:

  • query (required): Search text

  • glob (optional): File pattern to search

  • ns (optional): Namespace(s) to search - string or array. If omitted, searches all namespaces

  • max (optional): Maximum matches (default: 100)

  • contextLines (optional): Context lines (default: 1)

Output:

  • query: Search term

  • namespaces: Array of searched namespaces

  • matchCount: Number of matches

  • matches: Array with ns, path, lineNumber, line, start, end, uri

  • Resource links to matched files as docs://{ns}/{path}

Resources

The server exposes dynamic resource templates for each namespace:

  • URI Pattern: docs://{namespace}/{path}

  • Examples:

    • docs://docs/welcome.md

    • docs://api/endpoints.md

    • docs://guides/tutorial.md

  • Returns: File content with correct MIME type

Resources are automatically linked in tool responses and can be opened directly in the MCP Inspector.

Security Features

  1. Path Traversal Protection: All paths are validated to ensure they're within the namespace root

  2. Symlink Escape Detection: By default, symlinks pointing outside the namespace are blocked (configurable)

  3. Binary File Rejection: Binary files are automatically skipped

  4. Configurable File Size Limits: Files larger than the configured limit are rejected (default: 256KB)

  5. Namespace Validation: Namespace identifiers are validated (alphanumeric, hyphens, underscores only)

  6. Ignore Patterns: Automatically skip node_modules, .git, and other configured patterns

  7. Sanitized Errors: Error messages don't expose internal paths

Customization

Using Multiple Namespaces

Example 1: Via environment variable

# Windows PowerShell
$env:DOCS_DIRS="docs:./docs,api:./api-docs,guides:C:/guides"
npm run dev

Example 2: Via docs.config.json

{
  "roots": [
    { "ns": "docs", "path": "./docs" },
    { "ns": "api", "path": "./api-docs" },
    { "ns": "guides", "path": "C:/absolute/path/to/guides" }
  ]
}

To add new namespaces, edit the docs.config.json file and restart the server.

Configuring File Size Limits

Edit docs.config.json:

{
  "maxFileKB": 512,
  "roots": [...]
}

Edit docs.config.json:

{
  "allowSymlinks": true,
  "roots": [...]
}

Warning: Only enable if you trust the symlink targets. This allows symlinks to point outside namespace roots.

Custom Ignore Patterns

Edit docs.config.json:

{
  "ignore": [
    "**/node_modules/**",
    "**/.git/**",
    "**/dist/**",
    "**/build/**",
    "**/*.log",
    "**/tmp/**"
  ],
  "roots": [...]
}

Troubleshooting

Server won't start:

  • Check if port 3000 is already in use

  • Try a different port: $env:PORT="3001"; npm start

  • Check TypeScript compilation errors

Files not appearing:

  • Verify namespace configuration in docs.config.json or DOCS_DIRS

  • Check that namespace paths exist and are accessible

  • Ensure files match the glob pattern

  • Check file permissions

  • Review ignore patterns

Namespace not found errors:

  • Run roots.list tool to see registered namespaces

  • Check namespace spelling (case-sensitive)

  • Verify docs.config.json is valid JSON

  • Check console logs for initialization warnings

Inspector can't connect:

  • Verify the server is running

  • Check the MCP URL is correct: http://localhost:3000/mcp

  • Ensure no firewall is blocking the connection

  • Check health endpoint: http://localhost:3000/health

Path traversal or symlink errors:

  • Ensure paths are relative to the namespace root

  • Check allowSymlinks setting if using symlinks

  • Verify symlinks don't escape the namespace directory

File too large errors:

  • Increase maxFileKB in docs.config.json

  • Or filter out large files using ignore patterns

License

ISC

Maintenance

ActivityInactive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides direct access to local documentation files through simple search and overview tools, enabling LLMs to query project-specific markdown documentation without requiring vector databases or RAG pipelines.
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables AI assistants to read, search, and analyze local file systems with tools for reading file contents, listing directories, searching by patterns, and analyzing folder structures for context-aware queries.
    -