symposium_crate_sources_proxy/
lib.rs

1//! Rust Crate Sources Proxy
2//!
3//! An ACP proxy that provides the `rust_crate_query` MCP tool for researching
4//! Rust crate sources via dedicated sub-agent sessions.
5
6mod crate_sources_mcp;
7mod eg;
8mod research_agent;
9mod state;
10
11use anyhow::Result;
12use sacp::component::Component;
13use sacp::mcp_server::McpServiceRegistry;
14use sacp::ProxyToConductor;
15use state::ResearchState;
16use std::sync::Arc;
17
18/// Run the proxy as a standalone binary connected to stdio
19pub async fn run() -> Result<()> {
20    // Initialize tracing
21    tracing_subscriber::fmt()
22        .with_env_filter(
23            tracing_subscriber::EnvFilter::try_from_default_env()
24                .unwrap_or_else(|_| tracing_subscriber::EnvFilter::new("info")),
25        )
26        .init();
27
28    tracing::info!("Starting rust-crate-sources-proxy");
29
30    CrateSourcesProxy.serve(sacp_tokio::Stdio::new()).await?;
31
32    Ok(())
33}
34
35/// A proxy which forwards all messages to its successor, adding access to the rust-crate-query MCP server.
36pub struct CrateSourcesProxy;
37
38impl Component for CrateSourcesProxy {
39    async fn serve(self, client: impl Component) -> Result<(), sacp::Error> {
40        // Create shared state for tracking active research sessions
41        let state = Arc::new(ResearchState::new());
42
43        // Create MCP service registry with the user-facing service
44        let mcp_registry = McpServiceRegistry::new().with_mcp_server(
45            "rust-crate-query",
46            research_agent::build_server(state.clone()),
47        )?;
48
49        ProxyToConductor::builder()
50            .name("rust-crate-sources-proxy")
51            .with_handler(mcp_registry)
52            .with_handler(research_agent::PermissionAutoApprover::new(state.clone()))
53            .serve(client)
54            .await
55    }
56}