mod server;
mod tools;
use std::path::PathBuf;
use anyhow::{Context, Result};
use rmcp::{transport::stdio, ServiceExt};
use vestige_config::discover_config;
use vestige_store::Store;
pub use server::VestigeServer;
pub use tools::expand::ExpandParams;
pub use tools::get_candidate::GetCandidateParams;
pub use tools::list_candidates::ListCandidatesParams;
pub use tools::propose_candidate::{ProposeCandidateParams, ProposeSource};
pub use tools::search::SearchParams;
pub use tools::trace::TraceParams;
pub struct McpOptions {
pub read_only: bool,
}
pub async fn run(opts: McpOptions) -> Result<()> {
let cwd = std::env::current_dir().context("reading current directory")?;
let (config_path, config) = discover_config(&cwd).context(
"no Vestige project found from this directory — run `vestige init` to create one",
)?;
let project_id = config.project_id()?;
let storage_path: PathBuf = config.resolved_storage_path()?;
let store = Store::open(&storage_path).context("opening project store")?;
tracing::info!(
project = %project_id,
config = %config_path.display(),
storage = %storage_path.display(),
read_only = opts.read_only,
"starting MCP server"
);
let server = VestigeServer::new(store, config, project_id, opts.read_only);
let service = server.serve(stdio()).await.context("MCP serve")?;
service.waiting().await.context("MCP wait")?;
Ok(())
}