1use choir_cli::mcp::{serve, HttpClient};
12
13const USAGE: &str = "usage: choir-mcp <api> [--auth-file <path>] [--auth-user <name>]
14
15 Speaks MCP over stdin and stdout. Point an agent's MCP configuration at
16 it; it is not meant to be run at a prompt.
17";
18
19fn usage() -> ! {
20 eprint!("{USAGE}");
21 std::process::exit(2);
22}
23
24fn main() {
25 let args: Vec<String> = std::env::args().skip(1).collect();
26 if args.iter().any(|a| a == "--help" || a == "-h") {
29 print!("{USAGE}");
30 std::process::exit(0);
31 }
32 let Some(api) = args.first() else {
33 usage();
34 };
35 let mut auth_file = None;
36 let mut auth_user = None;
37 let mut index = 1;
38 while index < args.len() {
39 let Some(value) = args.get(index + 1) else {
40 usage();
41 };
42 match args[index].as_str() {
43 "--auth-file" if auth_file.is_none() => auth_file = Some(value.as_str()),
44 "--auth-user" if auth_user.is_none() => auth_user = Some(value.as_str()),
45 _ => usage(),
46 }
47 index += 2;
48 }
49 let client = match HttpClient::new(api, auth_file.map(std::path::Path::new), auth_user) {
50 Ok(client) => client,
51 Err(error) => {
52 eprintln!("choir-mcp: {error}");
53 std::process::exit(2);
54 }
55 };
56 let stdin = std::io::stdin();
57 let stdout = std::io::stdout();
58 if let Err(error) = serve(stdin.lock(), stdout, &client) {
59 eprintln!("choir-mcp: stdio failed: {error}");
60 std::process::exit(1);
61 }
62}