A daemon that monitors configuration and llms.txt files and automatically reloads mcpdoc server when changes are detected
Project description
MCPDoc Daemon
A simple daemon that monitors configuration files and automatically reloads mcpdoc when changes are detected.
About MCPDoc
MCPDoc is a tool that serves documentation using the Model Context Protocol (MCP). It allows you to create
documentation servers that can be consumed by LLM applications, providing structured access to documentation from various
sources including local llms.txt files and direct URLs.
This daemon provides automated monitoring and reloading capabilities for the mcpdoc server, making it easy to provide
up-to-date documentation to LLMs using a single MCP server configuration.
Features
- Monitors a mounted directory for
config.yamland*.llms.txtfiles - Automatically restarts mcpdoc when configuration changes
- Supports dynamic URL discovery from
.llms.txtfiles - Uses file watching for immediate response to changes
- Container-ready with Podman/Docker support
- Uses
watchdoglibrary for file monitoring with debouncing - Executes mcpdoc CLI as a subprocess for better isolation and compatibility
Architecture Overview
graph TB
subgraph "MCPDoc Daemon Process"
D[MCPDocDaemon]
FH[MCPDocConfigHandler]
O[Watchdog Observer]
D --> |creates| FH
D --> |creates| O
FH --> |restart trigger| D
O --> |file events| FH
end
subgraph "File System"
CD[config Directory]
CY[config.yaml]
LT1[service1.llms.txt]
LT2[service2.llms.txt]
LTN[serviceN.llms.txt]
CD --> CY
CD --> LT1
CD --> LT2
CD --> LTN
end
subgraph "MCPDoc CLI Process"
CLI[python -m mcpdoc.cli]
SERVER[SSE Server :8080]
CLI --> |spawns| SERVER
end
subgraph "Client Access"
HTTP[HTTP Requests]
SSE[Server-Sent Events]
HTTP --> SERVER
SERVER --> SSE
end
%% Process Flow
O --> |monitors| CD
CD --> |file changes| O
D --> |subprocess.Popen| CLI
D --> |terminate/kill| CLI
%% Configuration Flow
D --> |load_config| CY
D --> |discover_llms_files| LT1
D --> |discover_llms_files| LT2
D --> |discover_llms_files| LTN
D --> |build_mcpdoc_command| CLI
%% Styling
classDef daemon fill:#e1f5fe
classDef fileSystem fill:#f3e5f5
classDef mcpdoc fill:#e8f5e8
classDef client fill:#fff3e0
class D,FH,O daemon
class CD,CY,LT1,LT2,LTN fileSystem
class CLI,SERVER mcpdoc
class HTTP,SSE client
Architecture Components
- MCPDocDaemon: Main daemon class that orchestrates the entire process
- MCPDocConfigHandler: File system event handler for configuration changes
- Watchdog Observer: Monitors the config directory for file changes
- MCPDoc CLI Process: Subprocess running the mcpdoc server
- Configuration Files: YAML config and .llms.txt documentation files
Process Flow
- Initialization: Daemon starts and creates file monitoring setup
- Configuration Loading: Reads config.yaml and discovers .llms.txt files
- Command Building: Constructs mcpdoc CLI command with appropriate flags
- Subprocess Launch: Starts mcpdoc CLI as a subprocess with SSE transport
- File Monitoring: Continuously watches for configuration file changes
- Auto-Restart: Gracefully terminates and restarts subprocess on changes
Installation
Using pipx
pipx install mcpdoc-daemon
Quick Start
- Create a config directory:
mkdir config
-
Add your configuration files to the
config/directory:config.yaml- mcpdoc configuration*.llms.txt- LLM text files (e.g.,fastapi.llms.txt,something.llms.txt)
-
Build and run the container:
Using Docker Compose / Podman Compose
podman compose up --build
# or
docker compose up --build
Local Development (Python)
poetry install
poetry run mcpdoc-daemon
Manual Container Usage
Build the container:
podman build -t mcpdoc-daemon .
Run the container:
podman run -d \
--name mcpdoc-daemon \
-p 8080:8080 \
-v ./config:/config:z,ro \
mcpdoc-daemon
Configuration Structure
Your config/ directory should contain:
config/
├── config.yaml # Main mcpdoc configuration (YAML format)
├── config.json # Alternative JSON configuration (if no YAML)
├── fastapi.llms.txt # FastAPI documentation URLs
├── something.llms.txt # Other service documentation URLs
└── ... # Additional .llms.txt files
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.
Generated Command
The daemon will automatically generate and execute a command similar to:
python -m mcpdoc.cli --yaml /config/config.yaml \
--urls "fastapi:/config/fastapi.llms.txt" "something:/config/something.llms.txt" \
--follow-redirects --timeout 10.0 \
--allowed-domains '*' \
--transport sse \
--host 0.0.0.0 \
--port 8080 \
--log-level INFO
File Monitoring
The daemon monitors the /config directory for:
- File modifications
- File creation/deletion
- File moves
The implementation uses the watchdog library with debouncing to prevent excessive restarts when multiple file changes
occur in rapid succession.
When relevant files (config.yaml, config.json, or *.llms.txt) change, mcpdoc is automatically restarted with the
updated configuration.
Containerization
The container uses multi-stage builds with Poetry for better caching and smaller final images:
Features:
- Multi-stage builds: Separate builder and runtime stages for optimal image size
- Layer caching: Poetry and pip caches are mounted for faster builds
- Configurable base image: Uses
ARG BASE_IMAGE=docker.io/python:3.13-slim - Runtime optimization: Minimal runtime image with only required dependencies
- Poetry integration: Uses Poetry for dependency management instead of pip
Build Stages:
base: Sets up Poetry and basic environmentbuilder: Installs dependencies and copies application filesruntime-base: Builds the wheel packageruntime(default): Production-ready minimal image
Implementation Details
The implementation (mcpdoc_daemon.py) offers several features:
- CLI Integration: Executes mcpdoc CLI as a subprocess for better isolation and compatibility
- SSE Transport: Uses Server-Sent Events transport for real-time communication
- Advanced Monitoring: Watchdog library provides robust cross-platform file monitoring
- Debouncing: Prevents excessive restarts during rapid file changes
- Configurability: Environment variables and command-line options
- Development Mode: Can run locally without containers
- Process Management: Graceful subprocess termination with fallback to force kill
Environment Variables
MCPDOC_CONFIG_DIR: Configuration directory (default:/config)MCPDOC_HOST: Server host (default:0.0.0.0)MCPDOC_PORT: Server port (default:8080)MCPDOC_LOG_LEVEL: Logging level (default:INFO)
Command Line Options
mcpdoc-daemon --help
Access
Once running, mcpdoc will be accessible at http://localhost:8080
Logs
View container logs:
podman logs -f mcpdoc-daemon
Stopping
Stop the daemon:
podman compose down
Or for manual container:
podman stop mcpdoc-daemon
Systemd User Service
You can run MCPDoc Daemon as a systemd user service. See systemd.md for more information.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mcpdoc_daemon-0.1.0.tar.gz.
File metadata
- Download URL: mcpdoc_daemon-0.1.0.tar.gz
- Upload date:
- Size: 9.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cff73f4155b5c83c1f71eee06b2cae828c9518f7bd27a74f8b348972a6a76ce7
|
|
| MD5 |
094e77aec305de1e1401ce8c45e09b37
|
|
| BLAKE2b-256 |
3b1beb28ac5344855cf384e7bc91b7c383771a5e73747b0ddeb03fb9c9e192da
|
Provenance
The following attestation bundles were made for mcpdoc_daemon-0.1.0.tar.gz:
Publisher:
publish-to-pypi.yml on abn/mcpdoc-daemon
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mcpdoc_daemon-0.1.0.tar.gz -
Subject digest:
cff73f4155b5c83c1f71eee06b2cae828c9518f7bd27a74f8b348972a6a76ce7 - Sigstore transparency entry: 242941206
- Sigstore integration time:
-
Permalink:
abn/mcpdoc-daemon@40f07fc212a65f38c367f4f5b17d45883d6cee14 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/abn
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-to-pypi.yml@40f07fc212a65f38c367f4f5b17d45883d6cee14 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file mcpdoc_daemon-0.1.0-py3-none-any.whl.
File metadata
- Download URL: mcpdoc_daemon-0.1.0-py3-none-any.whl
- Upload date:
- Size: 9.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5cf8d15a7ed8212cf870c00cd7a1ffae23886fb72bbaa92783cd30f6cb016585
|
|
| MD5 |
ad097d29862f252cd6566e23240f71de
|
|
| BLAKE2b-256 |
39ab7ad622f06b4c9441dc2770fa2a4de09449aaae7f690887cb0169468598e4
|
Provenance
The following attestation bundles were made for mcpdoc_daemon-0.1.0-py3-none-any.whl:
Publisher:
publish-to-pypi.yml on abn/mcpdoc-daemon
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mcpdoc_daemon-0.1.0-py3-none-any.whl -
Subject digest:
5cf8d15a7ed8212cf870c00cd7a1ffae23886fb72bbaa92783cd30f6cb016585 - Sigstore transparency entry: 242941223
- Sigstore integration time:
-
Permalink:
abn/mcpdoc-daemon@40f07fc212a65f38c367f4f5b17d45883d6cee14 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/abn
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-to-pypi.yml@40f07fc212a65f38c367f4f5b17d45883d6cee14 -
Trigger Event:
workflow_dispatch
-
Statement type: