Computer Use AI SDK

repository·main·Indexed 42 days ago

https://github.com/mediar-ai/mcp-server-client-computer-use-ai-sdk

An open-source SDK providing a Model Context Protocol (MCP) server that allows AI agents to control macOS desktop elements—such as launching apps, clicking, and entering text—using desktop-rendered elements instead of pixel-based vision. Includes a Rust-based backend server and reference client implementations via a CLI (hello-world-mcp-client) and a Next.js web application.

Tokens
16.4K
Snippets
49
Records
64
Agent score
52%

What's inside Computer Use AI SDK

  1. Overview of Computer Use AI SDK

    main

    The Computer Use AI SDK is an open-source alternative to proprietary computer-use capabilities (like Claude's computer use). It provides an MCP (Model Context Protocol) server that allows AI agents to control a computer natively on macOS.

    Unlike pixel-based vision models, this SDK relies on underlying desktop-rendered elements, making it faster and more reliable. It provides computational primitives for AI agents to perform tasks directly on the OS.

    Core MCP Server Tools:

    • Launch apps
    • Read content
    • Click
    • Enter text
    • Press keys
  2. Install and Setup Computer Use AI SDK

    main

    To get started, clone the repository and ensure you have Rust and Node.js installed.

    1. Clone the repository:
    git clone https://github.com/m13v/computer-use-ai-sdk.git
    cd MCP-server-client-computer-use-ai-sdk
    1. Install Rust (if needed):
    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
    1. Install Node.js and npm: Visit https://nodejs.org/ or use nvm.
    git clone https://github.com/m13v/computer-use-ai-sdk.git
    cd MCP-server-client-computer-use-ai-sdk
    
    # Install Rust
    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
  3. Use the Web App Interface (Next.js)

    main

    The Next.js app provides a web-based interface for the MCP client.

    1. Navigate and install dependencies:
    cd mcp-client-nextjs
    npm install
    1. Configure the Anthropic API key: Create a .env file in the directory:
    echo "ANTHROPIC_API_KEY=sk-ant-XXXXXXXX" > .env
    1. Run the development server:
    npm run dev
    1. Access the UI: Open the localhost URL provided in the terminal.
    cd mcp-client-nextjs
    npm install
    echo "ANTHROPIC_API_KEY=sk-ant-XXXXXXXX" > .env
    npm run dev
  4. Use the CLI Interface Client

    main

    The CLI interface is useful for debugging and quick testing. It requires an Anthropic API key.

    1. Navigate and install dependencies:
    cd mcp-client-cli-interface
    npm install
    1. Set your Anthropic API key:
    • macOS/Linux: export ANTHROPIC_API_KEY=sk-ant-xxxx
    • Windows: set ANTHROPIC_API_KEY=sk-ant-xxxx
    1. Run the client:
    npx tsx main.ts
    cd mcp-client-cli-interface
    npm install
    export ANTHROPIC_API_KEY=sk-ant-xxxx
    npx tsx main.ts
  5. Use mcp-bridge to bridge MCP STDIO to a Rust HTTP server

    main

    The mcp-bridge.ts utility acts as a proxy that allows an MCP client (communicating via stdio) to interact with a Rust-based MCP server that is running in HTTP mode. This is useful when your core logic is implemented in a language like Rust and exposed via an HTTP API, but you need to expose it to MCP clients that only support the Standard Input/Output transport.

    To use this bridge, you must:

    1. Point the RUST_BINARY constant to your compiled Rust server executable.
    2. Ensure the Rust server is configured to listen on a local HTTP endpoint (e.g., http://127.0.0.1:8080).
    3. Configure the server.setRequestHandler to forward specific MCP requests to the corresponding Rust HTTP endpoints using fetch.
    // Example of forwarding an MCP request to a Rust HTTP endpoint
    server.setRequestHandler(someHandler, async (request) => {
      const response = await fetch("http://127.0.0.1:8080/api/click-by-index", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(request.params),
      });
    
      const data = await response.json();
      return data;
    });
  6. How the AccessibilityEngine trait works

    main

    The AccessibilityEngine trait defines the interface for platform-specific accessibility engines (macOS, Windows, and Linux). It provides methods to interact with the OS-level UI tree, find elements, and manage applications.

    Key capabilities include:

    • UI Navigation: Accessing the root element, finding focused elements, or searching for elements using a Selector.
    • Application Management: Listing running applications, finding an application by name, or opening a new application.
    • Web Interaction: Opening a URL in a specific browser or the system default.

    Implementations are platform-specific, so certain methods (like get_element_by_id) may only be available on specific operating systems like Windows.

    /// The common trait that all platform-specific engines must implement
    pub trait AccessibilityEngine: Send + Sync {
        fn get_root_element(&self) -> UIElement;
        fn get_focused_element(&self) -> Result<UIElement, AutomationError>;
        fn find_element(&self, selector: &Selector, root: Option<&UIElement>) -> Result<UIElement, AutomationError>;
        fn open_application(&self, app_name: &str) -> Result<UIElement, AutomationError>;
        fn open_url(&self, url: &str, browser: Option<&str>) -> Result<UIElement, AutomationError>;
        // ... other methods
    }
  7. Understand the MCP protocol request/response structure

    main

    This project implements the Model Context Protocol (MCP). All communication follows the JSON-RPC pattern using these core types:

    • MCPRequest: The standard envelope containing jsonrpc, id, method, and params.
    • MCPResponse: The standard successful response containing result.
    • MCPErrorResponse: The error response containing an MCPError object.
    • MCPError: Contains a numeric code and a message.

    Tool execution is handled via ExecuteToolFunctionParams, which specifies the function name and its arguments (as a JSON Value).

    #[derive(Debug, Deserialize, Serialize)]
    pub struct MCPRequest {
        pub jsonrpc: String,
        pub id: Value,
        pub method: String,
        pub params: Option<Value>,
    }
    
    #[derive(Debug, Deserialize, Serialize)]
    pub struct MCPResponse {
        pub jsonrpc: String,
        pub id: Value,
        pub result: Value,
    }
    
    #[derive(Debug, Deserialize, Serialize)]
    pub struct MCPErrorResponse {
        pub jsonrpc: String,
        pub id: Value,
        pub error: MCPError,
    }
    
    #[derive(Debug, Deserialize, Serialize)]
    pub struct MCPError {
        pub code: i32,
        pub message: String,
        pub data: Option<Value>,
    }
    
    #[derive(Debug, Deserialize, Serialize)]
    pub struct ExecuteToolFunctionParams {
        pub function: String,
        pub arguments: Value,
    }
  8. Response Structure for Tool Execution

    main

    When a tool function is successfully executed via executeToolFunction, the server returns a JSON-RPC result containing the action outcome and the updated UI state.

    Common fields in the result object include:

    • ui_state_changed: A boolean indicating if the UI responded to the action.
    • elements: An updated list of interactable elements (crucial for the next step in an agentic loop).
    • action_timestamp: An RFC3339 formatted string of when the action occurred.
    • evaluation_hints: A list of strings suggesting how the client should verify the success of the action (e.g., "check if text field contains the typed content").
    • Action-specific results:
      • click: { "success": boolean, "message": string }
      • type_action: { "success": boolean, "message": string }
      • press_key: { "success": boolean, "message": string }
      • application: { "success": boolean, "message": string }
      • url: { "success": boolean, "message": string }
      • input: { "success": boolean }