use std::num::{NonZeroU32, NonZeroUsize};
use clap::Parser;
use hdbconnect_mcp::{Config, ServerHandler, create_pool};
use rmcp::ServiceExt;
use rmcp::transport::io::stdio;
use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::util::SubscriberInitExt;
use url::Url;
#[derive(Parser, Debug)]
#[command(name = "hdbconnect-mcp")]
#[command(about = "MCP server for SAP HANA database", long_about = None)]
struct Args {
#[arg(short, long)]
url: String,
#[arg(short, long, default_value_t = true)]
read_only: bool,
#[arg(short = 'l', long, default_value = "10000")]
row_limit: u32,
#[arg(short, long, default_value = "4")]
pool_size: usize,
#[arg(short, long)]
verbose: bool,
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let args = Args::parse();
let log_level = if args.verbose {
tracing::Level::DEBUG
} else {
tracing::Level::INFO
};
tracing_subscriber::registry()
.with(tracing_subscriber::EnvFilter::from_default_env().add_directive(log_level.into()))
.with(tracing_subscriber::fmt::layer())
.init();
let url = Url::parse(&args.url).map_err(|e| anyhow::anyhow!("Invalid connection URL: {e}"))?;
let config = Config::builder()
.connection_url(url)
.pool_size(NonZeroUsize::new(args.pool_size).unwrap_or(NonZeroUsize::new(4).unwrap()))
.read_only(args.read_only)
.row_limit(NonZeroU32::new(args.row_limit))
.build()?;
let pool = create_pool(args.url.clone(), args.pool_size);
let handler = ServerHandler::new(pool, config);
tracing::info!("Starting MCP server for SAP HANA");
tracing::info!("Read-only mode: {}", args.read_only);
tracing::info!("Row limit: {}", args.row_limit);
let transport = stdio();
let server = handler.serve(transport).await?;
server.waiting().await?;
Ok(())
}