browser_use/mcp/
mod.rs

1//! MCP (Model Context Protocol) server implementation for browser automation
2//!
3//! This module provides rmcp-compatible tools by wrapping the existing tool implementations.
4
5pub mod handler;
6pub use handler::BrowserServer;
7
8use crate::tools::{self, Tool, ToolContext, ToolResult as InternalToolResult};
9use rmcp::{
10    ErrorData as McpError,
11    handler::server::wrapper::Parameters,
12    model::{CallToolResult, Content},
13    tool, tool_router,
14};
15
16/// Convert internal ToolResult to MCP CallToolResult
17fn convert_result(result: InternalToolResult) -> Result<CallToolResult, McpError> {
18    if result.success {
19        let text = if let Some(data) = result.data {
20            serde_json::to_string_pretty(&data).unwrap_or_else(|_| data.to_string())
21        } else {
22            "Success".to_string()
23        };
24        Ok(CallToolResult::success(vec![Content::text(text)]))
25    } else {
26        let error_msg = result.error.unwrap_or_else(|| "Unknown error".to_string());
27        Err(McpError::internal_error(error_msg, None))
28    }
29}
30
31/// Macro to register MCP tools by automatically generating wrapper functions
32macro_rules! register_mcp_tools {
33    ($($mcp_name:ident => $tool_type:ty, $description:expr);* $(;)?) => {
34        #[tool_router]
35        impl BrowserServer {
36            $(
37                #[tool(description = $description)]
38                fn $mcp_name(
39                    &self,
40                    params: Parameters<<$tool_type as Tool>::Params>,
41                ) -> Result<CallToolResult, McpError> {
42                    let session = self.session();
43                    let mut context = ToolContext::new(&*session);
44                    let tool = <$tool_type>::default();
45                    let result = tool.execute_typed(params.0, &mut context)
46                        .map_err(|e| McpError::internal_error(e.to_string(), None))?;
47                    convert_result(result)
48                }
49            )*
50        }
51    };
52}
53
54// Register all MCP tools using the macro
55register_mcp_tools! {
56    browser_navigate => tools::navigate::NavigateTool, "Navigate to a specified URL in the browser";
57    browser_click => tools::click::ClickTool, "Click on an element specified by CSS selector or index";
58    browser_form_input_fill => tools::input::InputTool, "Type text into an input element";
59    browser_get_text => tools::extract::ExtractContentTool, "Extract text or HTML content from the page or an element";
60    browser_screenshot => tools::screenshot::ScreenshotTool, "Capture a screenshot of the current page";
61    browser_evaluate => tools::evaluate::EvaluateTool, "Execute JavaScript code in the browser context";
62    browser_wait => tools::wait::WaitTool, "Wait for an element to appear on the page";
63    browser_get_markdown => tools::markdown::GetMarkdownTool, "Get the markdown content of the current page";
64    browser_read_links => tools::read_links::ReadLinksTool, "Read all links on the current page";
65    browser_get_clickable_elements => tools::get_clickable_elements::GetClickableElementsTool, "Get all clickable/interactive elements on the page";
66}