-
Notifications
You must be signed in to change notification settings - Fork 146
docs(openspec): add daemon management proposal #329
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,157 @@ | ||||||||
| # Design: Daemon Management | ||||||||
|
|
||||||||
| ## Context | ||||||||
|
|
||||||||
| The docs-mcp-server needs to run as a persistent background process to provide continuous MCP service to AI clients. Currently, users must manually start the server in a terminal, which is inconvenient for daily use and doesn't survive system reboots. | ||||||||
|
|
||||||||
| **Stakeholders**: End users running docs-mcp-server locally or on servers. | ||||||||
|
|
||||||||
| **Constraints**: | ||||||||
| - Must support macOS, Windows, and Linux | ||||||||
| - Must not require native module compilation (pure JavaScript) | ||||||||
| - Must work with the existing CLI framework (Yargs) | ||||||||
| - Service management requires elevated privileges | ||||||||
|
|
||||||||
| ## Goals / Non-Goals | ||||||||
|
|
||||||||
| ### Goals | ||||||||
| - Provide simple CLI commands to install/uninstall the server as a system daemon | ||||||||
| - Support all three major platforms with native service mechanisms | ||||||||
| - Allow configuration of server options (port, host) at install time | ||||||||
| - Provide status, start, stop, restart commands for lifecycle management | ||||||||
| - Handle permission requirements gracefully with clear error messages | ||||||||
|
|
||||||||
| ### Non-Goals | ||||||||
| - Container/Docker orchestration (separate concern) | ||||||||
| - Cluster/multi-instance management | ||||||||
| - GUI installer | ||||||||
| - Auto-update mechanism | ||||||||
|
|
||||||||
| ## Decisions | ||||||||
|
|
||||||||
| ### Decision 1: Use node-windows/node-mac/node-linux Package Family | ||||||||
|
|
||||||||
| **What**: Use the established `node-windows`, `node-mac`, and `node-linux` packages by Corey Butler for cross-platform daemon management. | ||||||||
|
|
||||||||
| **Why**: | ||||||||
| - Mature, battle-tested packages (2.9k+ stars for node-windows) | ||||||||
| - Pure JavaScript (no native compilation required) | ||||||||
| - Consistent API across all three packages | ||||||||
| - MIT licensed | ||||||||
| - Handles platform-specific details (launchd, Windows Services, systemd/init.d) | ||||||||
| - Built-in service monitoring with configurable restart behavior | ||||||||
|
|
||||||||
| **Alternatives considered**: | ||||||||
| 1. **Manual platform scripts**: Would require maintaining separate bash/powershell/plist scripts. High maintenance burden. | ||||||||
| 2. **PM2**: Designed for Node.js process management but not native OS services. Adds complexity and another background process. | ||||||||
| 3. **systemd-only on Linux**: Would limit Linux support to systemd-based distros. | ||||||||
|
|
||||||||
| ### Decision 2: Subcommand Pattern (`daemon <action>`) | ||||||||
|
|
||||||||
| **What**: Group all daemon operations under a `daemon` parent command. | ||||||||
|
|
||||||||
| **Why**: | ||||||||
| - Aligns with existing CLI patterns (though current commands are flat, `daemon` is a logical grouping) | ||||||||
| - Avoids namespace conflicts (`install`, `start`, `stop`, `status` are generic terms) | ||||||||
| - Enables discoverability (`docs-mcp-server daemon --help`) | ||||||||
| - Follows precedent from Docker, systemctl, npm, etc. | ||||||||
|
|
||||||||
| **Command structure**: | ||||||||
| ``` | ||||||||
| daemon install [--port] [--host] [--resume] [--read-only] [--store-path] | ||||||||
| daemon uninstall | ||||||||
| daemon status | ||||||||
| daemon start | ||||||||
| daemon stop | ||||||||
| daemon restart | ||||||||
| ``` | ||||||||
|
|
||||||||
| ### Decision 3: Configuration Persistence via Environment Variables | ||||||||
|
|
||||||||
| **What**: Pass server configuration to the daemon via environment variables set in the service definition. | ||||||||
|
|
||||||||
| **Why**: | ||||||||
| - The node-* packages natively support environment variable configuration | ||||||||
| - Avoids needing a separate config file for daemon-specific settings | ||||||||
| - Consistent with 12-factor app principles | ||||||||
| - Configuration travels with the service definition | ||||||||
|
|
||||||||
| **Implementation**: | ||||||||
| ```javascript | ||||||||
| const svc = new Service({ | ||||||||
| name: 'docs-mcp-server', | ||||||||
| script: '/path/to/dist/index.js', | ||||||||
| env: [ | ||||||||
| { name: 'DOCS_MCP_PORT', value: '3000' }, | ||||||||
| { name: 'DOCS_MCP_HOST', value: '0.0.0.0' }, | ||||||||
| { name: 'DOCS_MCP_STORE_PATH', value: '/path/to/store' }, | ||||||||
| ] | ||||||||
| }); | ||||||||
| ``` | ||||||||
|
|
||||||||
| ### Decision 4: Platform-Agnostic DaemonService Abstraction | ||||||||
|
|
||||||||
| **What**: Create a `DaemonService` class that provides a unified API across all platforms. | ||||||||
|
|
||||||||
| **Why**: | ||||||||
| - Encapsulates platform detection and package selection | ||||||||
| - Single interface for CLI commands to use | ||||||||
| - Easier testing via dependency injection | ||||||||
| - Future-proofs against package API changes | ||||||||
|
|
||||||||
| **Structure**: | ||||||||
| ``` | ||||||||
| src/daemon/ | ||||||||
| ├── DaemonService.ts # Main abstraction class | ||||||||
| ├── types.ts # DaemonOptions, DaemonStatus interfaces | ||||||||
|
||||||||
| ├── types.ts # DaemonOptions, DaemonStatus interfaces | |
| ├── types.ts # DaemonOptions, DaemonStatus interfaces | |
| ├── index.ts # Barrel export |
Copilot
AI
Feb 5, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor terminology inconsistency: The spec (line 191) uses "5 restarts per 60 seconds" while the design uses "5 restarts in 60 seconds". Consider using "per" instead of "in" to match the spec's terminology.
| - **Mitigation**: Use the built-in `maxRestarts` and `maxRetries` configuration to cap restart attempts. Default to sensible limits (e.g., 5 restarts in 60 seconds). | |
| - **Mitigation**: Use the built-in `maxRestarts` and `maxRetries` configuration to cap restart attempts. Default to sensible limits (e.g., 5 restarts per 60 seconds). |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,52 @@ | ||||||
| # Change: Add Daemon Management CLI Commands | ||||||
|
|
||||||
| ## Why | ||||||
|
|
||||||
| Currently, users must manually start the docs-mcp-server by running `./dist/index.js` or `docs-mcp-server` in a terminal window. This requires keeping the terminal open and remembering to restart the server after reboots. A daemon/service installation feature would allow the server to run as a persistent background process that starts automatically on system boot, providing a seamless always-on experience. | ||||||
|
|
||||||
| ## What Changes | ||||||
|
|
||||||
| - **New CLI command group**: `daemon` with subcommands (`install`, `uninstall`, `status`, `start`, `stop`, `restart`) | ||||||
| - **New dependencies**: `node-mac`, `node-windows`, `node-linux` packages for cross-platform service management | ||||||
| - **New module**: `src/daemon/` containing platform-agnostic daemon service abstraction | ||||||
| - **Configuration storage**: Persist daemon configuration (port, host, etc.) for service startup | ||||||
|
|
||||||
| ### Command Structure | ||||||
|
|
||||||
| ``` | ||||||
| docs-mcp-server daemon install [options] # Install as system service | ||||||
| docs-mcp-server daemon uninstall # Remove system service | ||||||
| docs-mcp-server daemon status # Show daemon running status | ||||||
| docs-mcp-server daemon start # Start the daemon | ||||||
| docs-mcp-server daemon stop # Stop the daemon | ||||||
| docs-mcp-server daemon restart # Restart the daemon | ||||||
| ``` | ||||||
|
|
||||||
| ### Platform Support | ||||||
|
|
||||||
| | Platform | Mechanism | Service Location | | ||||||
| |----------|-----------|------------------| | ||||||
| | macOS | launchd | `/Library/LaunchDaemons/` (plist) | | ||||||
| | Windows | Windows Service Manager | Windows Services (winsw) | | ||||||
|
||||||
| | Windows | Windows Service Manager | Windows Services (winsw) | | |
| | Windows | Windows Service Manager | Windows Services | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The example environment variable configuration is incomplete. According to tasks.md (lines 51-57), the daemon should also support
DOCS_MCP_RESUMEandDOCS_MCP_READ_ONLYenvironment variables. Consider updating this example to include all the environment variables that will be passed to the daemon service, or reference tasks.md section 4.1 for the complete list.