Files
Lumotia/crates/mcp/src/main.rs
Jake ce6dc1e728
Some checks failed
check / cargo check (macos-latest) (push) Has been cancelled
check / cargo check (ubuntu-22.04) (push) Has been cancelled
check / cargo check (windows-latest) (push) Has been cancelled
check / svelte build + lint (push) Has been cancelled
agent: lumotia-rebrand — fix QC blockers for phase 2
Phase 2 QC found three explicit blockers + a broader sweep needed:

Explicit (QC-named):
- crates/mcp/src/lib.rs:15 — SERVER_NAME public MCP wire identity
- crates/transcription/build.rs:59 — panic message prefix
- crates/llm/tests/content_tags_smoke.rs:7 — docstring -p flag

Swept (string literals + dev env vars + doc comments + test fixtures):
- crates/mcp/src/main.rs — eprintln log prefixes
- src-tauri/src/commands/diagnostics.rs — diagnostic filename + MAGNOTIA_VERSION
- src-tauri/src/commands/audio.rs — recording filename pattern lumotia-<secs>-...wav
- src-tauri/src/commands/fs.rs — test placeholder path
- crates/transcription/src/model_manager.rs — .lumotia-verified marker
- crates/storage/src/database.rs — lumotia-storage-ro-<pid> temp dirs + doc comments
- crates/cloud-providers/src/keystore.rs — LUMOTIA_API_KEY_<PROVIDER> env var
- crates/audio/src/{wav,decode}.rs — lumotia_test_* / lumotia_decode_* test fixtures
- crates/core/src/tuning.rs — LUMOTIA_INFERENCE_THREADS env var
- All MAGNOTIA_LLM_TEST_MODEL / MAGNOTIA_WHISPER_TEST_* env vars
- Doc comments referencing crate names

Excluded (intentional Phase 4/5 scope):
- magnotia_preferences, magnotia_history, magnotia_morning_triage_last_shown
  DB setting keys (Phase 5 paths.rs migration)
- magnotia_startup tracing target (Phase 4)
- crates/core/src/paths.rs (Phase 5 wholesale rewrite + migration shim)

cargo build --workspace passes. cargo test --workspace: 330 pass, 0 fail.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 08:52:47 +01:00

54 lines
2.2 KiB
Rust

//! Stdio entry point for lumotia-mcp. Reads newline-delimited JSON-RPC messages
//! from stdin, dispatches via `lumotia_mcp::handle_message`, writes responses to
//! stdout. Logs land on stderr so they don't collide with the JSON-RPC stream.
use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader};
#[tokio::main(flavor = "current_thread")]
async fn main() -> anyhow::Result<()> {
let db_path = lumotia_storage::database_path();
eprintln!(
"[lumotia-mcp] opening Lumotia database at {} (read-only)",
db_path.display()
);
// Open read-only at the connection level so the MCP server cannot write
// to the user's database, regardless of which tools the dispatcher
// exposes. Migrations are deliberately skipped — this binary never owns
// the schema; the main app is the single migration writer.
let pool = lumotia_storage::init_readonly(&db_path).await?;
eprintln!("[lumotia-mcp] ready, waiting for JSON-RPC on stdin");
let mut lines = BufReader::new(tokio::io::stdin()).lines();
let mut stdout = tokio::io::stdout();
while let Some(line) = lines.next_line().await? {
let trimmed = line.trim();
if trimmed.is_empty() {
continue;
}
let response = match serde_json::from_str::<serde_json::Value>(trimmed) {
Ok(raw) => match lumotia_mcp::handle_message(&pool, raw).await {
Some(response) => response,
None => continue, // notification — no reply
},
Err(err) => {
// Per JSON-RPC 2.0 §5.1: a Parse Error responds with
// code -32700 and id null. Previously this branch
// logged and continued, dropping the response —
// clients saw silence instead of a structured error
// (2026-04-22 review MAJOR).
eprintln!("[lumotia-mcp] parse error: {err}");
lumotia_mcp::parse_error_response(&err.to_string())
}
};
let payload = serde_json::to_string(&response)?;
stdout.write_all(payload.as_bytes()).await?;
stdout.write_all(b"\n").await?;
stdout.flush().await?;
}
Ok(())
}