{"id":34574666,"url":"https://github.com/abn/mcpdoc-daemon","last_synced_at":"2026-04-19T20:34:26.618Z","repository":{"id":299504609,"uuid":"1003231642","full_name":"abn/mcpdoc-daemon","owner":"abn","description":"Auto-reloading deamon for MCPDoc Server","archived":false,"fork":false,"pushed_at":"2026-03-01T11:08:04.000Z","size":60,"stargazers_count":0,"open_issues_count":3,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-13T13:05:24.963Z","etag":null,"topics":["automation","container","daemon","llms-txt","mcp","mcp-server","podman","poetry","python"],"latest_commit_sha":null,"homepage":"https://void.abn.is/automating-llms-txt-context-for-the-lazy-engineer/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/abn.png","metadata":{"files":{"readme":"README.md","changelog":null,"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":"2025-06-16T20:38:18.000Z","updated_at":"2025-10-02T21:22:21.000Z","dependencies_parsed_at":"2025-06-16T22:39:06.550Z","dependency_job_id":"9c5c12f8-90d7-42f3-8937-bfb9e0ae16a7","html_url":"https://github.com/abn/mcpdoc-daemon","commit_stats":null,"previous_names":["abn/mcpdoc-daemon"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/abn/mcpdoc-daemon","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abn%2Fmcpdoc-daemon","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abn%2Fmcpdoc-daemon/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abn%2Fmcpdoc-daemon/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abn%2Fmcpdoc-daemon/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/abn","download_url":"https://codeload.github.com/abn/mcpdoc-daemon/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abn%2Fmcpdoc-daemon/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32022273,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T20:23:30.271Z","status":"online","status_checked_at":"2026-04-19T02:00:07.110Z","response_time":55,"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":["automation","container","daemon","llms-txt","mcp","mcp-server","podman","poetry","python"],"created_at":"2025-12-24T09:48:27.098Z","updated_at":"2026-04-19T20:34:26.611Z","avatar_url":"https://github.com/abn.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# MCPDoc Daemon\n\n[![PyPI](https://img.shields.io/pypi/v/mcpdoc-daemon.svg)](https://pypi.org/project/mcpdoc-daemon/)\n\nA simple daemon that monitors configuration files and automatically reloads [mcpdoc](https://github.com/langchain-ai/mcpdoc)\nwhen changes are detected.\n\n## About MCPDoc\n\n[MCPDoc](https://github.com/langchain-ai/mcpdoc) is a tool that serves documentation using the Model Context Protocol (MCP). It allows you to create\ndocumentation servers that can be consumed by LLM applications, providing structured access to documentation from various\nsources including local `llms.txt` files and direct URLs.\n\nThis daemon provides automated monitoring and reloading capabilities for the `mcpdoc` server, making it easy to provide\nup-to-date documentation to LLMs using a single MCP server configuration.\n\n## Features\n\n- Monitors a mounted directory for `config.yaml` and `*.llms.txt` files\n- Automatically restarts mcpdoc when configuration changes\n- Supports dynamic URL discovery from `.llms.txt` files\n- Uses file watching for immediate response to changes\n- Container-ready with Podman/Docker support\n- Uses `watchdog` library for file monitoring with debouncing\n- Executes mcpdoc CLI as a subprocess for better isolation and compatibility\n\n## Architecture Overview\n\n```mermaid\ngraph TB\n    subgraph \"MCPDoc Daemon Process\"\n        D[MCPDocDaemon]\n        FH[MCPDocConfigHandler]\n        O[Watchdog Observer]\n\n        D --\u003e |creates| FH\n        D --\u003e |creates| O\n        FH --\u003e |restart trigger| D\n        O --\u003e |file events| FH\n    end\n\n    subgraph \"File System\"\n        CD[config Directory]\n        CY[config.yaml]\n        LT1[service1.llms.txt]\n        LT2[service2.llms.txt]\n        LTN[serviceN.llms.txt]\n\n        CD --\u003e CY\n        CD --\u003e LT1\n        CD --\u003e LT2\n        CD --\u003e LTN\n    end\n\n    subgraph \"MCPDoc CLI Process\"\n        CLI[python -m mcpdoc.cli]\n        SERVER[SSE Server :8080]\n\n        CLI --\u003e |spawns| SERVER\n    end\n\n    subgraph \"Client Access\"\n        HTTP[HTTP Requests]\n        SSE[Server-Sent Events]\n\n        HTTP --\u003e SERVER\n        SERVER --\u003e SSE\n    end\n\n    %% Process Flow\n    O --\u003e |monitors| CD\n    CD --\u003e |file changes| O\n    D --\u003e |subprocess.Popen| CLI\n    D --\u003e |terminate/kill| CLI\n\n    %% Configuration Flow\n    D --\u003e |load_config| CY\n    D --\u003e |discover_llms_files| LT1\n    D --\u003e |discover_llms_files| LT2\n    D --\u003e |discover_llms_files| LTN\n    D --\u003e |build_mcpdoc_command| CLI\n\n    %% Styling\n    classDef daemon fill:#e1f5fe\n    classDef fileSystem fill:#f3e5f5\n    classDef mcpdoc fill:#e8f5e8\n    classDef client fill:#fff3e0\n\n    class D,FH,O daemon\n    class CD,CY,LT1,LT2,LTN fileSystem\n    class CLI,SERVER mcpdoc\n    class HTTP,SSE client\n```\n\n### Architecture Components\n\n1. **MCPDocDaemon**: Main daemon class that orchestrates the entire process\n2. **MCPDocConfigHandler**: File system event handler for configuration changes\n3. **Watchdog Observer**: Monitors the config directory for file changes\n4. **MCPDoc CLI Process**: Subprocess running the mcpdoc server\n5. **Configuration Files**: YAML config and .llms.txt documentation files\n\n### Process Flow\n\n1. **Initialization**: Daemon starts and creates file monitoring setup\n2. **Configuration Loading**: Reads config.yaml and discovers .llms.txt files\n3. **Command Building**: Constructs mcpdoc CLI command with appropriate flags\n4. **Subprocess Launch**: Starts mcpdoc CLI as a subprocess with SSE transport\n5. **File Monitoring**: Continuously watches for configuration file changes\n6. **Auto-Restart**: Gracefully terminates and restarts subprocess on changes\n\n## Installation\n\n### Using `pipx`\n\n```bash\npipx install mcpdoc-daemon\n```\n\n## Quick Start\n\n1. By default, the daemon will use a directory named `mcpdoc` in your platform's default config directory:\n   - On Linux: `~/.config/mcpdoc/`\n   - On macOS: `~/Library/Application Support/mcpdoc/`\n   - On Windows: `C:\\Users\\\u003cusername\u003e\\AppData\\Local\\mcpdoc\\`\n\n   You can create this directory if it doesn't exist:\n```bash\n# For Linux\nmkdir -p ~/.config/mcpdoc\n```\n\n2. Add your configuration files to this directory:\n   - `config.yaml` - mcpdoc configuration\n   - `*.llms.txt` - LLM text files (e.g., `fastapi.llms.txt`, `something.llms.txt`)\n\n   Alternatively, you can specify a custom config directory using the `--config-dir` option.\n\n3. Build and run the container:\n\n### Using Docker Compose / Podman Compose\n```bash\npodman compose up --build\n# or\ndocker compose up --build\n```\n\n### Local Development (Python)\n```bash\npoetry install\npoetry run mcpdoc-daemon\n```\n\n## Manual Container Usage\n\nBuild the container:\n```bash\npodman build -t mcpdoc-daemon .\n```\n\nRun the container:\n```bash\npodman run -d \\\n  --name mcpdoc-daemon \\\n  -p 8080:8080 \\\n  -v ./config:/config:z,ro \\\n  ghcr.io/abn/mcpdoc-daemon:latest --config-dir /config\n```\n\nNote: When using containers, you need to explicitly set the config directory to `/config` using the `--config-dir` option to use the mounted volume.\n\n## Configuration Structure\n\nYour configuration directory should contain:\n\n```\n\u003cconfig-dir\u003e/\n├── config.yaml          # Main mcpdoc configuration (YAML format)\n├── config.json          # Alternative JSON configuration (if no YAML)\n├── fastapi.llms.txt     # FastAPI documentation URLs\n├── something.llms.txt   # Other service documentation URLs\n└── ...                  # Additional .llms.txt files\n```\n\nWhere `\u003cconfig-dir\u003e` is either:\n- The platform's default config directory + `/mcpdoc` (default)\n- A custom directory specified with `--config-dir`\n- The `/config` directory when using containers with the appropriate volume mount\n\n**Note**: If both `config.yaml` and `config.json` exist, the daemon will prioritize `config.yaml` and pass it to mcpdoc using the `--yaml` flag. If only `config.json` exists, it will be passed using the `--json` flag.\n\n## Generated Command\n\nThe daemon will automatically generate and execute a command similar to:\n```bash\npython -m mcpdoc.cli --yaml \u003cconfig-dir\u003e/config.yaml \\\n  --urls \"fastapi:\u003cconfig-dir\u003e/fastapi.llms.txt\" \"something:\u003cconfig-dir\u003e/something.llms.txt\" \\\n  --follow-redirects --timeout 10.0 \\\n  --allowed-domains '*' \\\n  --transport sse \\\n  --host 0.0.0.0 \\\n  --port 8080 \\\n  --log-level INFO\n```\n\nWhere `\u003cconfig-dir\u003e` is the path to your configuration directory.\n\n## File Monitoring\n\nThe daemon monitors your configuration directory for:\n- File modifications\n- File creation/deletion\n- File moves\n\nThe implementation uses the `watchdog` library with debouncing to prevent excessive restarts when multiple file changes\noccur in rapid succession.\n\nWhen relevant files (`config.yaml`, `config.json`, or `*.llms.txt`) change, mcpdoc is automatically restarted with the\nupdated configuration.\n\n## Containerization\n\nThe container uses multi-stage builds with Poetry for better caching and smaller final images:\n\n### Features:\n- **Multi-stage builds**: Separate builder and runtime stages for optimal image size\n- **Layer caching**: Poetry and pip caches are mounted for faster builds\n- **Configurable base image**: Uses `ARG BASE_IMAGE=docker.io/python:3.13-slim`\n- **Runtime optimization**: Minimal runtime image with only required dependencies\n- **Poetry integration**: Uses Poetry for dependency management instead of pip\n\n### Build Stages:\n- **`base`**: Sets up Poetry and basic environment\n- **`builder`**: Installs dependencies and copies application files\n- **`runtime-base`**: Builds the wheel package\n- **`runtime`** (default): Production-ready minimal image\n\n## Implementation Details\n\nThe implementation (`mcpdoc_daemon.py`) offers several features:\n\n- **CLI Integration**: Executes mcpdoc CLI as a subprocess for better isolation and compatibility\n- **SSE Transport**: Uses Server-Sent Events transport for real-time communication\n- **Advanced Monitoring**: Watchdog library provides robust cross-platform file monitoring\n- **Debouncing**: Prevents excessive restarts during rapid file changes\n- **Configurability**: Environment variables and command-line options\n- **Development Mode**: Can run locally without containers\n- **Process Management**: Graceful subprocess termination with fallback to force kill\n\n### Environment Variables\n\n- `MCPDOC_CONFIG_DIR`: Configuration directory (default: `\u003cplatform config dir\u003e/mcpdoc`)\n- `MCPDOC_HOST`: Server host (default: `0.0.0.0`)\n- `MCPDOC_PORT`: Server port (default: `8080`)\n- `MCPDOC_LOG_LEVEL`: Logging level (default: `INFO`)\n- `MCPDOC_TRANSPORT`: Transport method (default: `sse`)\n\n### Command Line Options\n\n```bash\nmcpdoc-daemon --help\n```\n\n## Access\n\nOnce running, mcpdoc will be accessible at `http://localhost:8080`\n\n## Logs\n\nView container logs:\n```bash\npodman logs -f mcpdoc-daemon\n```\n\n## Stopping\n\nStop the daemon:\n```bash\npodman compose down\n```\n\nOr for manual container:\n```bash\npodman stop mcpdoc-daemon\n```\n\n## Systemd User Service\n\nYou can run MCPDoc Daemon as a systemd user service. See [systemd.md](./docs/systemd.md) for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fabn%2Fmcpdoc-daemon","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fabn%2Fmcpdoc-daemon","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fabn%2Fmcpdoc-daemon/lists"}