use clap::Parser;
use hyperdb_mcp::engine::{resolve_log_dir, CLIENT_LOG_FILE_NAME};
use hyperdb_mcp::server::HyperMcpServer;
use rmcp::ServiceExt;
use tracing_subscriber::{fmt, prelude::*, EnvFilter};
const VERSION: &str = concat!(env!("CARGO_PKG_VERSION"), ".r", env!("HYPERDB_GIT_HASH"));
#[derive(Parser)]
#[command(
name = "hyperdb-mcp",
version = VERSION,
about = "MCP server for Hyper database analytics"
)]
struct Cli {
#[arg(long)]
workspace: Option<String>,
#[arg(long)]
read_only: bool,
#[arg(long)]
bare: bool,
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let cli = Cli::parse();
let log_dir = resolve_log_dir(cli.workspace.as_deref());
if let Err(e) = std::fs::create_dir_all(&log_dir) {
eprintln!(
"warning: failed to create log directory {}: {e} — client logs will go to stderr only",
log_dir.display()
);
}
let file_appender = tracing_appender::rolling::never(&log_dir, CLIENT_LOG_FILE_NAME);
let (file_writer, _file_guard) = tracing_appender::non_blocking(file_appender);
let filter = EnvFilter::try_from_default_env()
.unwrap_or_else(|_| EnvFilter::new("info,hyperdb_mcp=debug"));
tracing_subscriber::registry()
.with(filter)
.with(fmt::layer().with_writer(std::io::stderr))
.with(fmt::layer().with_writer(file_writer).with_ansi(false))
.init();
tracing::info!(
log_dir = %log_dir.display(),
workspace = cli.workspace.as_deref().unwrap_or("<ephemeral>"),
read_only = cli.read_only,
bare = cli.bare,
"hyperdb-mcp starting"
);
let server = HyperMcpServer::new(cli.workspace, cli.read_only, cli.bare);
let service = server.serve(rmcp::transport::io::stdio()).await?;
service.waiting().await?;
Ok(())
}