browser_control/cli/
mcp.rs1use anyhow::{anyhow, Result};
4
5use crate::cli::env_resolver::{self, ResolvedBrowser};
6use crate::mcp::server::{run, ServerState, ToolRegistry};
7use crate::registry::Registry;
8
9pub async fn run_cli(
11 browser_arg: Option<String>,
12 playwright_version: Option<String>,
13) -> Result<()> {
14 let resolved = resolve_browser(browser_arg).await?;
15 let sidecar_config = crate::sidecar::SidecarConfig {
16 version: playwright_version,
17 };
18 let state = ServerState::with_sidecar_config(resolved, sidecar_config);
19 let tools = ToolRegistry::new();
20 crate::mcp::tools::register_all(&tools);
21 run(state, tools).await
22}
23
24pub async fn resolve_browser(browser_arg: Option<String>) -> Result<ResolvedBrowser> {
33 let registry = Registry::open()?;
34 if let Some(arg) = browser_arg.as_deref().filter(|s| !s.is_empty()) {
35 let sel = env_resolver::parse(arg)?;
36 return env_resolver::resolve(sel, ®istry).await;
37 }
38 if let Some(value) = crate::config::load()?.default {
39 let sel = env_resolver::parse(&value)?;
40 return env_resolver::resolve(sel, ®istry).await;
41 }
42 Err(anyhow!(
43 "no browser selected: pass a browser argument, set BROWSER_CONTROL, or run `browser-control set default <value>`"
44 ))
45}
46
47pub fn acquire_bidi_lock_if_needed(
52 registry: &crate::registry::Registry,
53 resolved: &ResolvedBrowser,
54) -> Result<Option<crate::registry::BidiLockGuard>> {
55 use crate::detect::Engine;
56 if resolved.engine != Engine::Bidi {
57 return Ok(None);
58 }
59 let name = match &resolved.source {
60 crate::cli::env_resolver::Source::Registered { name } => name.clone(),
61 crate::cli::env_resolver::Source::External => return Ok(None),
62 };
63 let guard = registry.bidi_lock_acquire(&name, std::time::Duration::from_secs(30))?;
64 Ok(Some(guard))
65}