use crate::sandbox::Sandbox;
use crate::server::{AppContext, FilesystemServer};
use anyhow::{Context, Result};
use rmcp::transport;
use std::sync::Arc;
use tracing_subscriber::EnvFilter;
pub mod sandbox;
pub mod server;
pub mod tools;
pub static DEFAULT_BIND_ADDRESS: &str = "0.0.0.0:8084";
pub static APP_NAME: &str = env!("CARGO_PKG_NAME");
pub static APP_VERSION: &str = env!("CARGO_PKG_VERSION");
pub static MAX_FILE_SIZE: u64 = 1024 * 1024;
pub fn init_tracing() {
let _ = tracing_subscriber::fmt()
.with_env_filter(EnvFilter::new("INFO"))
.with_ansi(true)
.try_init();
}
pub async fn build_router(roots: Vec<String>) -> Result<axum::Router> {
let sandbox = Arc::new(Sandbox::new(roots).await.context("Could not add roots")?);
let processed_roots = &sandbox.get_roots();
let ctx = Arc::new(AppContext { sandbox });
let service = transport::streamable_http_server::StreamableHttpService::new(
{
let ctx = ctx.clone();
move || Ok(FilesystemServer::new(ctx.clone()))
},
transport::streamable_http_server::session::local::LocalSessionManager::default().into(),
Default::default(),
);
print_startup_banner(processed_roots);
Ok(axum::Router::new().nest_service("/mcp", service))
}
pub fn print_startup_banner(roots: &Vec<String>) {
tracing::info!(
"----------- MCP SERVER -----------
App : {}
Version : {}
Roots : {:?}
Transport : Streamable-HTTP
Listening : http://{}/mcp
",
APP_NAME,
APP_VERSION,
roots,
DEFAULT_BIND_ADDRESS,
);
}