Skip to content

Commit ab34c75

Browse files
committed
feat: integrate daemon mode with MCP server via --watch flag
Add automatic file watching to MCP server startup: - DaemonConfig in codegraph-core for daemon settings - DaemonManager wrapper coordinates daemon lifecycle with MCP server - CLI flags: --watch, --watch-path, --no-watch for stdio/http transports - Non-blocking startup: daemon runs in background tokio task - Error isolation: daemon failures don't crash MCP server - Graceful cleanup: daemon stops when MCP server exits - Config support: [daemon].auto_start_with_mcp enables by default - Environment variables: CODEGRAPH_DAEMON_AUTO_START, CODEGRAPH_DAEMON_WATCH_PATH Usage: codegraph start stdio --watch
1 parent 41dd679 commit ab34c75

File tree

6 files changed

+676
-3
lines changed

6 files changed

+676
-3
lines changed

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2222
- **Event coalescing**: Batches rapid file changes to avoid redundant re-indexing
2323
- **Feature flag**: `daemon` feature enables this functionality
2424

25+
#### **MCP Server Integration with Daemon (`--watch`)**
26+
- **Integrated daemon with MCP server**: `codegraph start stdio --watch` starts the daemon automatically
27+
- **Non-blocking startup**: Daemon runs in background task, MCP server starts immediately
28+
- **Error isolation**: Daemon failures don't crash MCP server
29+
- **CLI flags for MCP server**:
30+
- `--watch` - Enable automatic file watching (also via `CODEGRAPH_DAEMON_AUTO_START` env var)
31+
- `--watch-path <PATH>` - Specify directory to watch (also via `CODEGRAPH_DAEMON_WATCH_PATH` env var)
32+
- `--no-watch` - Explicitly disable daemon even if config enables it
33+
- **Configuration support**: `[daemon].auto_start_with_mcp` in config.toml to enable by default
34+
- **DaemonConfig**: New configuration struct in `codegraph-core` for daemon settings
35+
- **DaemonManager**: Coordinates daemon lifecycle with MCP server lifecycle
36+
- **Graceful cleanup**: Daemon stops automatically when MCP server exits
37+
2538
### Removed
2639
- Dropped the transactional/versioning/branch N-API bindings plus their documentation; the native TypeScript surface now focuses on semantic search, graph analysis, and cloud configuration so it matches the Surreal-only architecture.
2740
- Replaced the native addon example with a semantic-search walkthrough and removed CLI-centric integration snippets that referenced the deleted CodeGraph CLI.

README.md

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,34 @@ codegraph daemon stop /path/to/project
581581

582582
**Note:** Requires the `daemon` feature flag:
583583
```bash
584-
cargo build --release -p codegraph-mcp --features "daemon,ai-enhanced,ollama"
584+
cargo build --release -p codegraph-mcp --features "daemon,ai-enhanced"
585+
```
586+
587+
### MCP Server with Auto-Watching (`--watch`)
588+
589+
Start the MCP server with automatic file watching - the daemon runs in the background:
590+
591+
```bash
592+
# Start MCP server with file watching
593+
codegraph start stdio --watch
594+
595+
# Watch a specific directory
596+
codegraph start stdio --watch --watch-path /path/to/project
597+
598+
# Disable watching even if enabled in config
599+
codegraph start stdio --no-watch
600+
601+
# Via environment variable
602+
CODEGRAPH_DAEMON_AUTO_START=true codegraph start stdio
603+
```
604+
605+
**Configuration in `~/.codegraph/config.toml`:**
606+
```toml
607+
[daemon]
608+
auto_start_with_mcp = true # Auto-start daemon when MCP server starts
609+
debounce_ms = 30
610+
batch_timeout_ms = 200
611+
exclude_patterns = ["**/node_modules/**", "**/target/**"]
585612
```
586613

587614
**Note:** HTTP transport is not yet implemented with the official rmcp SDK. Use STDIO transport for all MCP integrations.

crates/codegraph-core/src/config_manager.rs

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ pub struct CodeGraphConfig {
3939
/// Logging configuration
4040
#[serde(default)]
4141
pub logging: LoggingConfig,
42+
43+
/// Daemon configuration for automatic file watching
44+
#[serde(default)]
45+
pub daemon: DaemonConfig,
4246
}
4347

4448
/// Embedding provider configuration
@@ -287,6 +291,57 @@ impl Default for LoggingConfig {
287291
}
288292
}
289293

294+
/// Daemon configuration for automatic file watching and re-indexing
295+
#[derive(Debug, Clone, Serialize, Deserialize)]
296+
pub struct DaemonConfig {
297+
/// Enable automatic daemon startup with MCP server
298+
#[serde(default)]
299+
pub auto_start_with_mcp: bool,
300+
301+
/// Project path to watch (defaults to current directory)
302+
#[serde(default)]
303+
pub project_path: Option<PathBuf>,
304+
305+
/// Debounce duration for file changes (ms)
306+
#[serde(default = "default_daemon_debounce_ms")]
307+
pub debounce_ms: u64,
308+
309+
/// Batch timeout for collecting changes (ms)
310+
#[serde(default = "default_daemon_batch_timeout_ms")]
311+
pub batch_timeout_ms: u64,
312+
313+
/// Health check interval (seconds)
314+
#[serde(default = "default_daemon_health_check_interval")]
315+
pub health_check_interval_secs: u64,
316+
317+
/// Languages to watch (empty = all detected)
318+
#[serde(default)]
319+
pub languages: Vec<String>,
320+
321+
/// Exclude patterns (gitignore format)
322+
#[serde(default = "default_daemon_exclude_patterns")]
323+
pub exclude_patterns: Vec<String>,
324+
325+
/// Include patterns (gitignore format)
326+
#[serde(default)]
327+
pub include_patterns: Vec<String>,
328+
}
329+
330+
impl Default for DaemonConfig {
331+
fn default() -> Self {
332+
Self {
333+
auto_start_with_mcp: false, // Opt-in by default
334+
project_path: None,
335+
debounce_ms: default_daemon_debounce_ms(),
336+
batch_timeout_ms: default_daemon_batch_timeout_ms(),
337+
health_check_interval_secs: default_daemon_health_check_interval(),
338+
languages: vec![],
339+
exclude_patterns: default_daemon_exclude_patterns(),
340+
include_patterns: vec![],
341+
}
342+
}
343+
}
344+
290345
// Default value functions
291346
fn default_embedding_provider() -> String {
292347
"auto".to_string()
@@ -353,6 +408,28 @@ fn default_log_format() -> String {
353408
"pretty".to_string()
354409
}
355410

411+
// Daemon default functions
412+
fn default_daemon_debounce_ms() -> u64 {
413+
30
414+
}
415+
fn default_daemon_batch_timeout_ms() -> u64 {
416+
200
417+
}
418+
fn default_daemon_health_check_interval() -> u64 {
419+
30
420+
}
421+
fn default_daemon_exclude_patterns() -> Vec<String> {
422+
vec![
423+
"**/node_modules/**".to_string(),
424+
"**/target/**".to_string(),
425+
"**/.git/**".to_string(),
426+
"**/build/**".to_string(),
427+
"**/.codegraph/**".to_string(),
428+
"**/dist/**".to_string(),
429+
"**/__pycache__/**".to_string(),
430+
]
431+
}
432+
356433
/// Configuration manager with smart defaults and auto-detection
357434
pub struct ConfigManager {
358435
config: CodeGraphConfig,
@@ -553,6 +630,25 @@ impl ConfigManager {
553630
config.logging.level = level;
554631
}
555632

633+
// Daemon configuration
634+
if let Ok(auto_start) = std::env::var("CODEGRAPH_DAEMON_AUTO_START") {
635+
config.daemon.auto_start_with_mcp =
636+
auto_start.to_lowercase() == "true" || auto_start == "1";
637+
}
638+
if let Ok(path) = std::env::var("CODEGRAPH_DAEMON_WATCH_PATH") {
639+
config.daemon.project_path = Some(PathBuf::from(path));
640+
}
641+
if let Ok(debounce) = std::env::var("CODEGRAPH_DAEMON_DEBOUNCE_MS") {
642+
if let Ok(ms) = debounce.parse() {
643+
config.daemon.debounce_ms = ms;
644+
}
645+
}
646+
if let Ok(batch) = std::env::var("CODEGRAPH_DAEMON_BATCH_TIMEOUT_MS") {
647+
if let Ok(ms) = batch.parse() {
648+
config.daemon.batch_timeout_ms = ms;
649+
}
650+
}
651+
556652
config
557653
}
558654

0 commit comments

Comments
 (0)