Skip to content

feat: single-instance daemon for shared hyperd across MCP clients#26

Open
StefanSteiner wants to merge 1 commit into
tableau:mainfrom
StefanSteiner:ssteiner/single-instance-hyper
Open

feat: single-instance daemon for shared hyperd across MCP clients#26
StefanSteiner wants to merge 1 commit into
tableau:mainfrom
StefanSteiner:ssteiner/single-instance-hyper

Conversation

@StefanSteiner
Copy link
Copy Markdown
Contributor

Summary

  • Adds a lightweight daemon that manages a single shared hyperd process per user, so multiple AI clients (Claude Code, Cursor, VS Code Copilot, etc.) share one database engine instead of each spawning their own
  • MCP clients auto-discover or auto-spawn the daemon transparently; persistent databases become accessible across all concurrent sessions
  • Ephemeral databases are properly cleaned up (DETACH + delete) when sessions end, including on Windows where file locks would otherwise prevent deletion

Architecture

┌──────────────┐  ┌──────────────┐  ┌──────────────┐
│ MCP Client 1 │  │ MCP Client 2 │  │ MCP Client 3 │
└──────┬───────┘  └──────┬───────┘  └──────┬───────┘
       └─────────────────┼─────────────────┘
                         │ libpq (TCP 127.0.0.1)
              ┌──────────┴──────────┐
              │   hyperdb daemon    │
              │  (single instance)  │
              └──────────┬──────────┘
              ┌──────────┴──────────┐
              │       hyperd        │
              └─────────────────────┘

Key design decisions:

  • TCP port binding as cross-platform single-instance lock (works identically on Windows/macOS/Linux)
  • Discovery file at ~/.hyperdb/daemon.json (overridable via HYPERDB_STATE_DIR)
  • Health protocol (PING/HEARTBEAT/STOP/STATUS) for liveness checks and idle tracking
  • Idle timeout (30 min default) with debounced heartbeats from active clients
  • --no-daemon flag to opt out and use legacy per-client hyperd

New CLI commands

hyperdb-mcp daemon              # Run as daemon (usually auto-spawned)
hyperdb-mcp daemon stop         # Gracefully shut down running daemon
hyperdb-mcp daemon status       # Show running daemon info
hyperdb-mcp --no-daemon         # Legacy mode: private hyperd per session

Test plan

  • 26 new tests in daemon_tests.rs covering:
    • DaemonState idle tracking and shutdown flag
    • Discovery file write/read/overwrite/remove/stale-cleanup
    • Health protocol (PING, HEARTBEAT, STOP, STATUS, unknown command, multi-command)
    • Single-instance lock (second bind fails with AddrInUse)
    • Idle timeout triggers shutdown; heartbeats prevent it
    • Full integration: engine connects to shared daemon, two engines share one hyperd
    • Persistent database file survives engine drop
    • Ephemeral database cleaned up on drop (DETACH + delete)
  • All existing workspace tests pass unchanged
  • cargo clippy and cargo fmt clean
  • Manual: start two MCP clients, load data in one, query from other
  • Manual: verify --no-daemon spawns private hyperd
  • Manual: verify idle timeout shuts down daemon after inactivity

A lightweight daemon manages one shared hyperd process per user so
multiple AI clients (Claude Code, Cursor, VS Code, etc.) can access the
same persistent databases simultaneously with reduced resource overhead.

Architecture:
- TCP port binding as cross-platform single-instance lock
- Discovery file at ~/.hyperdb/daemon.json (overridable via HYPERDB_STATE_DIR)
- Health protocol (PING/HEARTBEAT/STOP/STATUS) for liveness and idle tracking
- Auto-spawn: MCP clients transparently start the daemon if none is running
- Idle timeout (default 30 min) with heartbeat-based keep-alive
- Ephemeral databases DETACH + delete on session end (Windows-safe)
- --no-daemon flag to opt out and use legacy per-client hyperd

New files:
- hyperdb-mcp/src/daemon/{mod,discovery,health,run,spawn}.rs
- hyperdb-mcp/tests/daemon_tests.rs (26 tests: unit + integration)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant