Document Search MCP Server
by weatherills
README.md
# Document Search MCP Server
A **local MCP server** that provides read-only access to documents (Word, PDF, Excel, CSV, Visio, PNG, JPG, PowerPoint, Text, Markdown, EPUB) via the [Model Context Protocol (MCP)](https://github.com/modelcontextprotocol).
## Features
- **Read-only access**: Enforced at the code level.
- **Recursive scanning**: Scans all subdirectories of configured directories.
- **File type validation**: Uses magic numbers to validate file types.
- **Metadata extraction**: Extracts metadata from all supported file types.
- **Logging**: Logs all actions to a file (configurable).
- **Timeout for file operations**: Configurable timeout (default: 180 seconds) to prevent hanging on large or corrupt files.
- **Full MCP compliance**: Supports `initialize`, `resources/list`, `resources/read`, and `tools/call` methods.
- **YAML configuration**: Supports both CLI arguments and YAML configuration files.
- **Extensive file type support**: PDF, Word, Excel, CSV, Visio, Images, PowerPoint, Text, Markdown, EPUB.
## Installation
1. Clone the repository:
```bash
git clone https://github.com/bpweatherill/Document-Search-MCP-server.git
cd Document-Search-MCP-server
```
2. Install dependencies:
```bash
pip install -r requirements.txt
```
For **full file type support**, install all optional dependencies:
```bash
pip install PyPDF2 python-docx openpyxl Pillow textract xlrd PyYAML pdfplumber pypandoc python-pptx ebooklib
```
## Usage
### Start the Server
```bash
# Default: Scans ~/Documents
python -m src.main
# With custom directories and settings
python -m src.main --dir "C:\Users\Me\Documents" --dir "C:\Users\Me\Desktop" --max-file-size 50000000 --log-file "C:\logs\mcp.log" --log-level DEBUG --file-operation-timeout 180
# With a custom YAML config file
python -m src.main --config-file /path/to/custom_config.yaml
```
### YAML Configuration
The server supports **YAML configuration files** in addition to CLI arguments. CLI arguments take precedence over YAML config.
**Configuration file locations** (checked in order):
1. `mcp_server_config.yaml` in the current directory
2. `~/.mcp_server/config.yaml` in the user's home directory
3. `/etc/mcp_server/config.yaml` for system-wide config
4. Custom path specified with `--config-file`
**Example YAML configuration:**
```yaml
# List of directories to scan (recursive)
allowed_dirs:
- "~/Documents"
- "/path/to/other/directory"
# Maximum file size in bytes (100MB default)
max_file_size: 104857600
# Path to the log file
log_file: "~/.mcp_server/log.txt"
# Logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
log_level: "INFO"
# Timeout for file operations in seconds
file_operation_timeout: 180
# Additional file extensions to allow
allowed_extensions:
- ".txt"
- ".md"
- ".pptx"
- ".ppt"
- ".epub"
```
### MCP Client Interaction
Send JSON-RPC requests over **stdio**. The server supports the following MCP methods:
#### 1. Initialize
```json
{
"id": 1,
"method": "initialize",
"params": {}
}
```
**Response:**
```json
{
"id": 1,
"result": {
"protocolVersion": "2024-11-05",
"capabilities": {
"resources": {
"list": {"description": "List available document resources"},
"read": {"description": "Read a document resource"}
}
},
"serverInfo": {
"name": "Document-Search-MCP-Server",
"version": "1.0.0"
}
}
}
```
#### 2. List Resources
```json
{
"id": 2,
"method": "resources/list",
"params": {}
}
```
#### 3. Read Resource
```json
{
"id": 3,
"method": "resources/read",
"params": {
"uri": "file:///path/to/document.pdf"
}
}
```
#### 4. Call Tools
##### List Files
```json
{
"id": 4,
"method": "tools/call",
"params": {
"name": "list_files",
"arguments": {}
}
}
```
##### Read File
```json
{
"id": 5,
"method": "tools/call",
"params": {
"name": "read_file",
"arguments": {
"path": "/path/to/file.pdf"
}
}
}
```
##### Get Metadata
```json
{
"id": 6,
"method": "tools/call",
"params": {
"name": "get_metadata",
"arguments": {
"path": "/path/to/file.pdf"
}
}
}
```
#### 5. Ping (Health Check)
```json
{
"id": 7,
"method": "ping",
"params": {}
}
```
## Configuration
| Argument | Default | Description |
|----------|---------|-------------|
| `--dir` | `~/Documents` | Directories to scan (recursive). Can be specified multiple times. |
| `--max-file-size` | 100MB | Skip files larger than this. |
| `--log-file` | `~/.mcp_server/log.txt` | Path to the log file. |
| `--log-level` | `INFO` | Logging level (`DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`). |
| `--file-operation-timeout` | 180 (seconds) | Timeout for file operations. |
| `--config-file` | None | Path to a custom YAML configuration file. |
| `--allowed-extensions` | None | Additional file extensions to allow (e.g., `--allowed-extensions .txt .md`). |
## Security
- **Read-only**: All file operations are read-only.
- **Path validation**: Prevents directory traversal attacks.
- **File type validation**: Ensures files match their extensions.
- **Race condition protection**: Files are re-validated before each read operation.
- **Timeout protection**: File operations will not hang indefinitely.
## MCP Compliance
This server fully implements the following MCP methods:
- `initialize`: Returns server capabilities and info.
- `resources/list`: Lists all available document resources.
- `resources/read`: Reads and returns the content of a resource.
- `tools/call`: Executes a tool (list_files, read_file, get_metadata).
- `ping`: Health check endpoint.
## Testing
Run unit tests:
```bash
python -m unittest discover tests
```
## Dependencies
### Required
- **PyPDF2**: For PDF text extraction.
- **python-docx**: For Word document text extraction (.docx).
- **openpyxl**: For Excel file parsing (.xlsx).
- **Pillow**: For image metadata extraction (PNG, JPG, JPEG).
- **PyYAML**: For YAML configuration file support.
### Optional (for extended file type support)
- **pdfplumber**: Better PDF text extraction (fallback to PyPDF2 if not available).
- **textract**: For binary Word document text extraction (.doc).
- **xlrd**: For binary Excel file parsing (.xls).
- **pypandoc**: For Markdown to HTML/plain text conversion.
- **python-pptx**: For PowerPoint file text extraction.
- **ebooklib**: For EPUB file text extraction.
- **visio-python**: For Visio file metadata extraction.
## Supported File Types
| File Type | Extension | MIME Type | Notes |
|-----------|-----------|-----------|-------|
| PDF | .pdf | application/pdf | Uses pdfplumber (better) or PyPDF2 |
| Word | .docx | application/vnd.openxmlformats-officedocument.wordprocessingml.document | Uses python-docx |
| Word | .doc | application/msword | Uses textract (fallback to raw bytes) |
| Excel | .xlsx | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet | Uses openpyxl |
| Excel | .xls | application/vnd.ms-excel | Uses xlrd (fallback to raw bytes) |
| CSV | .csv | text/csv | Uses Python's csv module |
| Visio | .vsdx, .vsd | application/vnd.ms-visio.viewer, application/vnd.visio | Uses visio-python (fallback to raw bytes) |
| Image | .png, .jpg, .jpeg | image/png, image/jpeg | Uses Pillow for metadata |
| PowerPoint | .pptx, .ppt | application/vnd.openxmlformats-officedocument.presentationml.presentation, application/vnd.ms-powerpoint | Uses python-pptx (fallback to raw bytes) |
| Text | .txt | text/plain | Read as plain text |
| Markdown | .md | text/markdown | Uses pypandoc or read as plain text |
| EPUB | .epub | application/epub+zip | Uses ebooklib (fallback to raw bytes) |
## Configuration File Example
Create a file named `config.yaml` (or use the provided `example.yaml`):
```yaml
# Directories to scan
allowed_dirs:
- "~/Documents"
- "/path/to/other/directory"
# Maximum file size in bytes
max_file_size: 104857600
# Log file path
log_file: "~/.mcp_server/log.txt"
# Logging level
log_level: "INFO"
# File operation timeout in seconds
file_operation_timeout: 180
# Additional file extensions
allowed_extensions:
- ".txt"
- ".md"
- ".pptx"
- ".ppt"
- ".epub"
```
Then start the server with:
```bash
python -m src.main
```
Or specify a custom config file:
```bash
python -m src.main --config-file /path/to/custom_config.yaml
```
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessSyncing