Local Docs MCP Server
by JWears
README.md
# 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`
## Installation
Dependencies are already installed. If you need to reinstall:
```bash
npm install
```
## Configuration
### Method 1: Configuration File (`docs.config.json`)
Create a `docs.config.json` file in the project root:
```json
{
"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:
```bash
# 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)
```bash
npm run dev
```
### Production Mode
```bash
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):
```bash
npx @modelcontextprotocol/inspector
```
2. **Start the server** in one terminal:
```bash
npm run dev
```
3. **Open MCP Inspector** in another terminal:
```bash
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):**
```json
{
"pattern": "**/*.md",
"max": 50
}
```
**List Files (specific namespace):**
```json
{
"pattern": "**/*.md",
"ns": "docs",
"max": 50
}
```
**List Files (multiple namespaces):**
```json
{
"pattern": "**/*.md",
"ns": ["docs", "api"],
"max": 50
}
```
**Read File:**
```json
{
"ns": "docs",
"path": "welcome.md"
}
```
**Search (all namespaces):**
```json
{
"query": "MCP",
"glob": "**/*.md",
"max": 100
}
```
**Search (specific namespace):**
```json
{
"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}`
### search
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**
```bash
# Windows PowerShell
$env:DOCS_DIRS="docs:./docs,api:./api-docs,guides:C:/guides"
npm run dev
```
**Example 2: Via docs.config.json**
```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`:
```json
{
"maxFileKB": 512,
"roots": [...]
}
```
### Allowing Symlinks
Edit `docs.config.json`:
```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`:
```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
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues