1use crate::commands::build_auth;
15use crate::commands::safety::SafetyProfile;
16use crate::core::ConfigLoader;
17use anyhow::Result;
18use clap::Args;
19
20#[derive(Args, Debug, Clone)]
21pub struct McpArgs {
22 #[arg(long)]
24 pub readonly: bool,
25}
26
27pub async fn run_mcp(args: McpArgs) -> Result<()> {
28 let config = ConfigLoader::load().await?;
29 let auth = build_auth(&config).await?;
30 let readonly = args.readonly;
31 let profile = SafetyProfile {
32 readonly,
33 ..SafetyProfile::default()
34 };
35 let server = crate::mcp::McpServer::new(auth, profile);
36
37 eprintln!(
39 "grr mcp: {} tools over stdio (JSON-RPC 2.0, newline-delimited){}",
40 server.tool_count(),
41 if readonly {
42 "; --readonly: writes refused"
43 } else {
44 ""
45 }
46 );
47
48 let reader = tokio::io::BufReader::new(tokio::io::stdin());
49 let mut writer = tokio::io::stdout();
50 crate::mcp::serve(&server, reader, &mut writer).await
51}