{"id":51432998,"url":"https://github.com/michaelkrauty/mcp-docs","last_synced_at":"2026-07-05T05:03:04.743Z","repository":{"id":359822784,"uuid":"1129453611","full_name":"michaelkrauty/mcp-docs","owner":"michaelkrauty","description":"MCP server for document management — multi-format extraction, semantic search, OCR, hash-based deduplication","archived":false,"fork":false,"pushed_at":"2026-07-04T22:23:02.000Z","size":509,"stargazers_count":1,"open_issues_count":3,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-05T00:07:44.646Z","etag":null,"topics":["claude","document-management","mcp","mcp-server","ocr","pdf","python","semantic-search"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/michaelkrauty.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-07T05:41:47.000Z","updated_at":"2026-07-04T22:23:00.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/michaelkrauty/mcp-docs","commit_stats":null,"previous_names":["michaelkrauty/mcp-docs"],"tags_count":49,"template":false,"template_full_name":null,"purl":"pkg:github/michaelkrauty/mcp-docs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaelkrauty%2Fmcp-docs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaelkrauty%2Fmcp-docs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaelkrauty%2Fmcp-docs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaelkrauty%2Fmcp-docs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/michaelkrauty","download_url":"https://codeload.github.com/michaelkrauty/mcp-docs/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaelkrauty%2Fmcp-docs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35143802,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-05T02:00:06.290Z","response_time":100,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["claude","document-management","mcp","mcp-server","ocr","pdf","python","semantic-search"],"created_at":"2026-07-05T05:03:03.757Z","updated_at":"2026-07-05T05:03:04.731Z","avatar_url":"https://github.com/michaelkrauty.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# mcp-docs\n\nMCP server for document management with multi-format extraction, semantic search, and source integrity tracking.\n\n## Prerequisites\n\n- **Python 3.12+**\n- **Linux or macOS** (uses POSIX file locking via vector-core; not compatible with Windows)\n- [Qdrant](https://qdrant.tech/) vector database (default: `localhost:6333`)\n- An OpenAI-compatible embedding API (e.g., llama.cpp, Ollama, or any `/v1/embeddings` endpoint; default: `localhost:8080`)\n- **Vision endpoint** *(optional)* — OpenAI-compatible vision model for automatic OCR fallback on scanned PDFs\n- **poppler** *(optional, for OCR)* — `apt install poppler-utils` (Linux) or `brew install poppler` (macOS)\n\n## Installation\n\nRequires [vector-core](https://github.com/michaelkrauty/vector-core).\n\n```bash\npip install git+https://github.com/michaelkrauty/vector-core.git@v1.2.11\npip install git+https://github.com/michaelkrauty/mcp-docs.git\n```\n\nOr clone both repos and install locally:\n\n```bash\ngit clone https://github.com/michaelkrauty/vector-core.git\ngit clone https://github.com/michaelkrauty/mcp-docs.git\npip install -e vector-core/\npip install -e mcp-docs/\n```\n\n## Quick Start\n\n```bash\n# Register with Claude Code (set env vars to match your setup):\nclaude mcp add docs \\\n  -e VECTOR_QDRANT_URL=http://localhost:6333 \\\n  -e VECTOR_EMBEDDING_URL=http://localhost:8080 \\\n  -e VECTOR_EMBEDDING_MODEL=your-model-name \\\n  -e VECTOR_COLLECTION_NAME=my-documents \\\n  -- mcp-docs\n\n# Or add to your MCP client config (e.g., claude_desktop_config.json):\n# {\n#   \"mcpServers\": {\n#     \"docs\": {\n#       \"command\": \"mcp-docs\",\n#       \"env\": {\n#         \"VECTOR_QDRANT_URL\": \"http://localhost:6333\",\n#         \"VECTOR_EMBEDDING_URL\": \"http://localhost:8080\",\n#         \"VECTOR_EMBEDDING_MODEL\": \"your-model-name\",\n#         \"VECTOR_COLLECTION_NAME\": \"my-documents\"\n#       }\n#     }\n#   }\n# }\n```\n\n## Features\n\n- **Multi-Format Extraction**: PDF, DOCX, PPTX, XLSX, CSV, EPUB, XML, TXT, Markdown, Jupyter (`.ipynb`), HTML, RTF\n- **Directory Scanning**: Register root directories for automatic discovery\n- **Semantic Search**: Hybrid dense + sparse vector search via Qdrant\n- **Keyword Search**: Exact keyword/phrase matching in filenames and content\n- **Hash Deduplication**: SHA-256 content hashes prevent duplicate ingestion\n- **Source Tracking**: Verify document references for fact integrity\n- **Background Processing**: Async extraction/indexing with worker queue\n- **Filesystem Operations**: Move files/directories with automatic registry updates\n- **Glossary**: Shared term definitions (same store as mcp-notes)\n\n## Tools (36 total)\n\n### Documents (6)\n| Tool | Description |\n|------|-------------|\n| `register_document` | Register file for indexing with deduplication |\n| `get_document` | Retrieve document by UUID |\n| `get_document_by_hash` | Lookup by SHA-256 content hash |\n| `update_document_tags` | Modify document tags |\n| `delete_document` | Remove from registry |\n| `list_documents` | List with tag/status/type/root filters |\n\n### Processing (4)\n| Tool | Description |\n|------|-------------|\n| `get_processing_status` | Check extraction/indexing progress |\n| `list_queued_documents` | View processing queue |\n| `wait_for_document` | Block until processing completes |\n| `cancel_processing` | Stop processing for a document |\n\n### Search (4)\n| Tool | Description |\n|------|-------------|\n| `search_documents` | Hybrid semantic search with filters |\n| `keyword_search` | Exact keyword/phrase matching in filenames and content |\n| `find_similar_documents` | Content-based similarity matching |\n| `get_document_chunks` | Retrieve indexed chunks |\n\n### Indexing (2)\n| Tool | Description |\n|------|-------------|\n| `index_document` | Index single document |\n| `index_all_documents` | Batch index with two-pass vocabulary |\n\n### Root Management (6)\n| Tool | Description |\n|------|-------------|\n| `add_document_root` | Register directory for scanning |\n| `list_document_roots` | View all roots |\n| `get_document_root` | Info on specific root |\n| `remove_document_root` | Unregister a root |\n| `scan_document_root` | Scan specific root for changes |\n| `scan_all_roots` | Scan all enabled roots |\n\n### Hash Verification (3)\n| Tool | Description |\n|------|-------------|\n| `lookup_hash` | Find document by SHA-256 |\n| `verify_document_reference` | Check document exists and unchanged |\n| `batch_verify_references` | Verify multiple hashes |\n\n### Glossary (6)\n| Tool | Description |\n|------|-------------|\n| `add_glossary_entry` | Add term with expansion, definition, domain |\n| `lookup_term` | Exact lookup by term or alias |\n| `search_glossary` | Semantic glossary search |\n| `list_glossary` | List entries with optional domain filter |\n| `update_glossary_entry` | Modify entry metadata |\n| `delete_glossary_entry` | Delete entry |\n\n### Filesystem (5)\n| Tool | Description |\n|------|-------------|\n| `move_file` | Move a file and update document registry |\n| `create_directory` | Create a directory within a document root |\n| `rename_directory` | Rename a directory and update all document paths |\n| `move_directory` | Move a directory and update all document paths |\n| `delete_directory` | Delete an empty directory |\n\n## Supported Formats\n\n| Format | Extensions | Notes |\n|--------|------------|-------|\n| PDF | `.pdf` | Text extraction via MarkItDown; automatic OCR fallback via vision LLM for scanned/image-based PDFs |\n| Word | `.docx` | Full text via MarkItDown + metadata via python-docx |\n| Word (legacy) | `.doc` | RTF-disguised files only; true DOC requires conversion |\n| PowerPoint | `.pptx` | Slide text via MarkItDown + metadata via python-pptx |\n| PowerPoint (legacy) | `.ppt` | Best-effort via MarkItDown; may require conversion |\n| Excel | `.xlsx`, `.xls` | Spreadsheet to markdown table via MarkItDown |\n| CSV | `.csv` | Markdown table via the csv module, with encoding fallback (utf-8-sig, utf-8, cp1252, latin-1) for non-ASCII exports |\n| EPUB | `.epub` | E-book text extraction via MarkItDown |\n| XML | `.xml` | XML content extraction via MarkItDown |\n| Text | `.txt`, `.md` | Direct text / markdown with title extraction |\n| Jupyter | `.ipynb` | Markdown cells as prose, code cells as language-tagged fenced blocks; outputs and raw cells skipped; title from first H1 |\n| HTML | `.html`, `.htm` | Markdown conversion via MarkItDown |\n| RTF | `.rtf` | Rich text via striprtf |\n| OpenDocument | `.odt` | Not supported; raises error advising conversion to DOCX |\n\n## Document Status\n\n| Status | Meaning |\n|--------|---------|\n| `Active` | Path exists, hash matches |\n| `Modified` | Path exists, different hash |\n| `Relocated` | Found at different path (same hash) |\n| `Deleted` | File not found anywhere |\n\n## Extraction Pipeline\n\n```\nQueued → Processing → Extracted → Indexed\n                  ↘ Failed (with error message)\n```\n\n## Data Model\n\n### Document\n```python\nid: UUID\npath: \"/path/to/document.pdf\"\ncontent_hash: \"sha256:...\"\ndoc_type: \"pdf\"\nstatus: \"active\"\nextraction_status: \"indexed\"\ntags: [\"research\", \"2024\"]\ncreated_at: datetime\nindexed_at: datetime\n```\n\n### DocumentRoot\n```python\npath: \"/home/user/documents\"\nname: \"My Documents\"\nrecursive: True\nenabled: True\nadded_at: datetime\nlast_scanned: datetime\nfile_count: 42\n```\n\n## Storage\n\n| Data | Location |\n|------|----------|\n| Document registry | `documents.db` in data dir |\n| Extracted content | Qdrant collection (set via `VECTOR_COLLECTION_NAME`) |\n| Glossary | `glossary.db` in vector-core's shared data dir |\n\n## Configuration\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `VECTOR_COLLECTION_NAME` | (required) | Qdrant collection name |\n| `DOCS_OCR_VISION_URL` | `\"\"` | OpenAI-compatible vision endpoint for OCR (empty = OCR disabled) |\n| `DOCS_OCR_VISION_MODEL` | `\"\"` | Vision model name (empty = let endpoint decide) |\n| `DOCS_OCR_DPI` | `300` | DPI for PDF page rendering |\n| `DOCS_OCR_TIMEOUT` | `180` | Per-page OCR timeout in seconds |\n| `DOCS_OCR_MAX_PAGES` | `200` | Maximum pages to OCR per document |\n| `DOCS_OCR_IMAGE_MAX_DIMENSION` | `1536` | Max image width/height sent to vision model |\n| `DOCS_OCR_IMAGE_FORMAT` | `jpeg` | Image format: `jpeg` (smaller) or `png` (lossless) |\n| `DOCS_OCR_JPEG_QUALITY` | `90` | JPEG quality (1-100) if using jpeg format |\n| `DOCS_OCR_CACHE_ENABLED` | `true` | Cache OCR results by file metadata |\n| `DOCS_OCR_CONCURRENCY` | `4` | Max concurrent OCR page requests |\n| `DOCS_MAX_CHUNK_CHARS` | `80000` | Chunk size (~20k tokens) |\n| `DOCS_CHUNK_OVERLAP_CHARS` | `500` | Overlap between chunks |\n| `DOCS_MAX_WORKERS` | `2` | Background processing workers |\n| `DOCS_MAX_TAGS_PER_DOCUMENT` | `20` | Tag limit |\n| `DOCS_MAX_TAG_LENGTH` | `50` | Maximum length of a single tag |\n\nPlus inherited vector-core settings (`VECTOR_QDRANT_URL`, `VECTOR_EMBEDDING_URL`, etc.).\n\n## Integration with mcp-notes\n\n- **Shared glossary**: Same `glossary.db`, same terms\n- **Shared facts.db**: Documents can be sources for facts\n- **Hash verification**: mcp-docs verifies document sources haven't changed\n\nWhen a fact references a document:\n1. Source stores `source_type: \"document\"`, `source_hash: \"sha256:...\"`\n2. `verify_document_reference` checks if hash still exists\n3. If file modified/deleted, fact marked as having stale source\n\n## Dependencies\n\nRequires vector-core components:\n- EmbeddingClient, GlobalVocabulary (search)\n- QdrantStorage, HybridSearcher (storage)\n- GlossaryStore (glossary)\n- SourceIntegrityManager (fact verification)\n\nExternal libraries:\n- pypdf (PDF extraction)\n- python-docx (DOCX metadata)\n- python-pptx (PPTX metadata)\n- markitdown (unified text conversion for DOCX, PPTX, XLSX, EPUB, XML, HTML, TXT)\n- Python standard-library csv module (CSV tables, with encoding fallback across utf-8-sig, utf-8, cp1252, and latin-1)\n- striprtf (RTF extraction)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmichaelkrauty%2Fmcp-docs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmichaelkrauty%2Fmcp-docs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmichaelkrauty%2Fmcp-docs/lists"}