1mod api_key_cmd;
6mod commands;
7mod config_cmd;
8mod health_cmd;
9mod list_api_keys_cmd;
10mod revoke_api_key_cmd;
11mod serve_cmd;
12mod test_cmd;
13mod version_cmd;
14
15use clap::Parser;
16use std::path::PathBuf;
17
18pub use api_key_cmd::run_generate_api_key_command;
19pub use commands::Commands;
20pub use config_cmd::run_config_command;
21pub use health_cmd::run_health_command;
22pub use list_api_keys_cmd::run_list_api_keys_command;
23pub use revoke_api_key_cmd::run_revoke_api_key_command;
24pub use serve_cmd::run_serve_command;
25pub use test_cmd::run_test_command;
26pub use version_cmd::run_version_command;
27
28#[derive(Parser)]
30#[command(name = "crates-docs")]
31#[command(version = env!("CARGO_PKG_VERSION"))]
32#[command(about = "High-performance Rust crate documentation query MCP server", long_about = None)]
33pub struct Cli {
34 #[command(subcommand)]
36 pub command: Commands,
37
38 #[arg(short, long, global = true, default_value = "config.toml")]
40 pub config: PathBuf,
41
42 #[arg(short, long, global = true)]
44 pub debug: bool,
45
46 #[arg(short, long, global = true)]
48 pub verbose: bool,
49}
50
51pub async fn run(cli: Cli) -> Result<(), Box<dyn std::error::Error>> {
53 match cli.command {
54 Commands::Serve {
55 mode,
56 host,
57 port,
58 enable_oauth,
59 oauth_client_id,
60 oauth_client_secret,
61 oauth_redirect_uri,
62 enable_api_key,
63 api_keys,
64 api_key_header,
65 api_key_query_param,
66 } => {
67 run_serve_command(
68 &cli.config,
69 cli.debug,
70 mode,
71 host,
72 port,
73 enable_oauth,
74 oauth_client_id,
75 oauth_client_secret,
76 oauth_redirect_uri,
77 enable_api_key,
78 api_keys,
79 api_key_header,
80 api_key_query_param,
81 )
82 .await?;
83 }
84 Commands::GenerateApiKey { prefix } => {
85 run_generate_api_key_command(&prefix)?;
86 }
87 Commands::ListApiKeys { config } => {
88 run_list_api_keys_command(&config)?;
89 }
90 Commands::RevokeApiKey { config, key } => {
91 run_revoke_api_key_command(&config, &key)?;
92 }
93 Commands::Config { output, force } => {
94 run_config_command(&output, force)?;
95 }
96 Commands::Test {
97 tool,
98 crate_name,
99 item_path,
100 query,
101 sort,
102 version,
103 limit,
104 format,
105 } => {
106 run_test_command(
107 &tool,
108 crate_name.as_deref(),
109 item_path.as_deref(),
110 query.as_deref(),
111 sort.as_deref(),
112 version.as_deref(),
113 limit,
114 &format,
115 )
116 .await?;
117 }
118 Commands::Health {
119 check_type,
120 verbose,
121 } => {
122 run_health_command(&check_type, verbose).await?;
123 }
124 Commands::Version => {
125 run_version_command();
126 }
127 }
128
129 Ok(())
130}