mod mcp;
mod error;
mod bluesky;
mod tools;
mod http;
mod cli;
mod car;
use anyhow::Result;
use clap::Parser;
use cli::{Cli, Commands};
use tracing::info;
use tracing_subscriber;
#[tokio::main]
async fn main() -> Result<()> {
let args: Vec<String> = std::env::args().collect();
if args.len() > 1 {
run_cli_mode().await
} else {
run_mcp_mode().await
}
}
async fn run_cli_mode() -> Result<()> {
let cli = Cli::parse();
let log_level = if cli.quiet {
"error"
} else if cli.verbose {
"debug"
} else {
"info"
};
tracing_subscriber::fmt()
.with_env_filter(log_level)
.with_writer(std::io::stderr) .init();
let result = match cli.command {
Some(Commands::Profile(args)) => {
execute_profile_cli(args).await
}
Some(Commands::Search(args)) => {
execute_search_cli(args).await
}
None => {
eprintln!("Error: No command specified. Use --help for usage information.");
std::process::exit(1);
}
};
match result {
Ok(output) => {
println!("{}", output);
Ok(())
}
Err(e) => {
eprintln!("Error: {}", e);
std::process::exit(get_exit_code(&e));
}
}
}
async fn execute_profile_cli(args: cli::ProfileArgs) -> Result<String> {
use tokio::time::{timeout, Duration};
let result = timeout(Duration::from_secs(120), tools::profile::execute_profile(args)).await;
match result {
Ok(Ok(tool_result)) => {
Ok(tool_result.content.first()
.map(|c| c.text.clone())
.unwrap_or_default())
}
Ok(Err(e)) => Err(anyhow::anyhow!(e.message())),
Err(_) => Err(anyhow::anyhow!("Request exceeded 120 second timeout")),
}
}
async fn execute_search_cli(args: cli::SearchArgs) -> Result<String> {
use tokio::time::{timeout, Duration};
let result = timeout(Duration::from_secs(120), tools::search::execute_search(args)).await;
match result {
Ok(Ok(tool_result)) => {
Ok(tool_result.content.first()
.map(|c| c.text.clone())
.unwrap_or_default())
}
Ok(Err(e)) => Err(anyhow::anyhow!(e.message())),
Err(_) => Err(anyhow::anyhow!("Request exceeded 120 second timeout")),
}
}
fn get_exit_code(err: &anyhow::Error) -> i32 {
let err_str = err.to_string().to_lowercase();
if err_str.contains("invalid") || err_str.contains("usage") {
1 } else if err_str.contains("network") || err_str.contains("connection") {
2 } else if err_str.contains("not found") {
3 } else if err_str.contains("timeout") {
4 } else {
5 }
}
async fn run_mcp_mode() -> Result<()> {
tracing_subscriber::fmt::init();
info!("Starting autoreply MCP Server");
mcp::handle_stdio().await?;
Ok(())
}