use std::path::PathBuf;
use anyhow::Result;
use clap::Parser;
#[derive(Parser)]
#[command(name = "dynamic-backends-example")]
struct Cli {
#[arg(short, long, default_value = "proxy.toml")]
config: PathBuf,
}
#[tokio::main]
async fn main() -> Result<()> {
tracing_subscriber::fmt()
.with_env_filter("tower_mcp=info,mcp_proxy=info")
.init();
let cli = Cli::parse();
let mut config = mcp_proxy::ProxyConfig::load(&cli.config)?;
config.resolve_env_vars();
let addr = format!("{}:{}", config.proxy.listen.host, config.proxy.listen.port);
let proxy = mcp_proxy::Proxy::from_config(config).await?;
let mcp_proxy = proxy.mcp_proxy().clone();
tokio::spawn(async move {
tokio::time::sleep(std::time::Duration::from_secs(2)).await;
let namespaces = mcp_proxy.backend_namespaces();
tracing::info!(backends = ?namespaces, "Current backends");
let transport = tower_mcp::client::HttpClientTransport::new("http://localhost:9999");
match mcp_proxy.add_backend("dynamic-api", transport).await {
Ok(()) => tracing::info!("Added 'dynamic-api' backend"),
Err(e) => {
tracing::warn!(error = %e, "Failed to add backend (expected if no server at :9999)")
}
}
let namespaces = mcp_proxy.backend_namespaces();
tracing::info!(backends = ?namespaces, "Backends after add");
if mcp_proxy.remove_backend("dynamic-api").await {
tracing::info!("Removed 'dynamic-api' backend");
}
let namespaces = mcp_proxy.backend_namespaces();
tracing::info!(backends = ?namespaces, "Backends after remove");
});
tracing::info!(listen = %addr, "Dynamic backends example ready");
proxy.serve().await
}