# Embedded Browser Live UI Source: https://docs.anchorbrowser.io/advanced/browser-live-view Embed interactive browser sessions directly into your application ## Overview Anchor Browser offers a live view feature that allows you to embed an interactive frame of a website as a web element. The `live_view_url` is received when creating a session with `headless: false` (which is the default mode). ## Headful Mode (Default) Headful mode provides a single URL to view the full chrome view, including the address bar. This ensures the presented tab is always the active tab and provides the best user experience. Browser Live View in Headful Mode To create a browser in headful mode, set the `headless` parameter to `false` when [creating a session](/api-reference/sessions/create-session): ```javascript node.js const axios = require('axios'); const ANCHOR_API_KEY = process.env.ANCHOR_API_KEY; (async () => { const response = await axios.post("https://api.anchorbrowser.io/v1/sessions", { browser: { headless: { active: false } } }, { headers: { "anchor-api-key": ANCHOR_API_KEY, "Content-Type": "application/json", }, }); const session = response.data.data; const liveViewUrl = session.live_view_url; })().catch(console.error); ``` ```python python import os import requests ANCHOR_API_KEY = os.getenv("ANCHOR_API_KEY") response = requests.post( "https://api.anchorbrowser.io/v1/sessions", json={ "browser": { "headless": {"active": False} } }, headers={ "anchor-api-key": ANCHOR_API_KEY, "Content-Type": "application/json", }, ) response.raise_for_status() session = response.json()["data"] live_view_url = session["live_view_url"] ``` Then, use the `live_view_url` from the response to embed the live view directly into an iframe: ```html ``` ## Advanced Embedding Configuration ### Embed in Fullscreen View (Hide Navigation Bar) To use the fullscreen view, replace the live view URL with the following: ```html ``` ### Disable Browser Interactivity To prevent the end user from interacting with the browser, add the `style="pointer-events: none;"` attribute to the iframe: ```html ``` This feature is available for both headful and headless modes. In headless mode, you would use the `session_url` instead of `live_view_url`. ## Headless Mode (Legacy) Headless mode is being deprecated and will be removed in a future version. We recommend using headful mode for all new implementations. To obtain the browser live session URL in headless mode, start by [creating a session](/api-reference/sessions/create-session) with `headless: true`: Browser Live View in Headless Mode The session\_url points to the browser default first page. If your browser process involves creating a **new page**, collect the corresponding URL by using the [live view URLs](/api-reference/sessions/get-pages-for-a-session) endpoint. Then, use the **create-session** response to embed the live view URL directly into an iframe: ```html ``` # Captcha Solving Source: https://docs.anchorbrowser.io/advanced/captcha-solving ### Visual CAPTCHA solving Anchor browser solves CAPTCHA challenges using a vision-based approach, along with extension-based fallbacks. The vision-based approach imitates human behavior to solve any CAPTCHA (including Cloudflare) without mulitple challenges. CAPTCHA solving works best with proxy enabled. Bot detectors would likely fail CAPTCHA solving attempts that are performed without Proxy. For the full list of available options, view the [interactive api documentation](/api-reference) ### Code Example ```bash curl --request POST \ --url https://api.anchorbrowser.io/v1/sessions \ --header 'Content-Type: application/json' \ --header 'anchor-api-key: ' \ --data '{ "browser": { "captcha_solver": { "active": true } } }' ``` # Dedicated Sticky IP Source: https://docs.anchorbrowser.io/advanced/dedicated-sticky-ip Reserve a fixed IP address for a specific profile. A **Dedicated Sticky IP** ensures that a specific profile uses by default the same IP address, reserved exclusively for that profile. This is helpful when IP consistency is required across sessions. Use the [Create Profile API](https://docs.anchorbrowser.io/api-reference/profiles/create-profile?playground=open) to create a profile with a dedicated sticky IP by setting: ```json { "dedicated_sticky_ip": true } ``` This allocates a dedicated IP that is not shared with other profiles. Any browser session started using this profile will automatically use the reserved sticky IP. To override the default sticky IP, set the `proxy` field when using the [Start Browser Session API](https://docs.anchorbrowser.io/api-reference/browser-sessions/start-browser-session). # Browser Extensions Source: https://docs.anchorbrowser.io/advanced/extensions Upload and use custom browser extensions in your sessions Anchor allows you to upload and use Chrome extensions in your browser sessions. This lets you add ad blockers, privacy tools, or any other extension to enhance your browsing automation. For uploading, listing, and managing extensions, see the [interactive API documentation](/api-reference/extensions). ## Getting Extensions from Chrome Web Store To use extensions from the Chrome Web Store, you'll need to download and inspect their files: ### Download Extension Files 1. **Install CRX Extractor/Downloader** - Add this extension to your browser to download .crx files 2. **Navigate to the extension** you want on the Chrome Web Store 3. **Click the CRX Extractor icon** and download the .crx file 4. **Rename the file** from `.crx` to `.zip` 5. **Extract the ZIP** to inspect the contents ### Inspect Extension Contents Once extracted, you'll see the extension's files: * `manifest.json` - Contains extension metadata and permissions * `background.js` or `service_worker.js` - Background scripts * `content_scripts/` - Scripts that run on web pages * `popup.html` - Extension popup interface * `icons/` - Extension icons ### Repackage for Upload After inspecting (and optionally modifying) the files: 1. **Select all files and folders** in the extracted directory 2. **Create a new ZIP file** containing all the extension files 3. **Upload this ZIP** to AnchorBrowser using the API ## Extension Requirements Your extension ZIP file must contain a valid `manifest.json` with basic extension information like name and version. ### Example Manifest ```json { "manifest_version": 3, "name": "My Extension", "version": "1.0.0", "description": "Extension description", "permissions": ["activeTab", "storage"], "background": { "service_worker": "background.js" }, "content_scripts": [{ "matches": [""], "js": ["content.js"] }] } ``` ## Code Examples ### JavaScript/Node.js ```tsx node.js import fs from 'fs'; import FormData from 'form-data'; async function uploadExtension() { const form = new FormData(); form.append('name', 'My Custom Extension'); form.append('file', fs.createReadStream('./my-extension.zip')); const response = await fetch('https://api.anchorbrowser.io/v1/extensions', { method: 'POST', headers: { 'anchor-api-key': 'your_api_key_here', ...form.getHeaders() }, body: form }); const result = await response.json(); return result.data.id; } // Use the extension in a session async function createSessionWithExtension(extensionId) { const response = await fetch('https://api.anchorbrowser.io/v1/sessions', { method: 'POST', headers: { 'Content-Type': 'application/json', 'anchor-api-key': 'your_api_key_here' }, body: JSON.stringify({ browser: { extensions: [extensionId] } }) }); return response.json(); } ``` ```python python import requests def upload_extension(api_key, extension_path, name): with open(extension_path, 'rb') as f: files = {'file': f} data = {'name': name} response = requests.post( 'https://api.anchorbrowser.io/v1/extensions', headers={'anchor-api-key': api_key}, files=files, data=data ) return response.json() # Use the extension in a session def create_session_with_extension(api_key, extension_id): response = requests.post( 'https://api.anchorbrowser.io/v1/sessions', headers={ 'anchor-api-key': api_key, 'Content-Type': 'application/json' }, json={ 'browser': { 'extensions': [extension_id] } } ) return response.json() # Usage result = upload_extension('your_api_key', './my-extension.zip', 'My Extension') extension_id = result['data']['id'] # Create session with the extension session = create_session_with_extension('your_api_key', extension_id) ``` ## Limitations * Maximum extension size: 50MB per ZIP file * Extensions must be valid Chrome extensions # File Download Source: https://docs.anchorbrowser.io/advanced/file-download Anchor Browser supports two methods for downloading files during your browser sessions: 1. **Traditional Downloads**: Files are downloaded to the browser instance and then uploaded to S3 for retrieval 2. **P2P Downloads**: Files are captured directly in the browser using peer-to-peer technology, bypassing S3 storage ## Traditional File Downloads The following examples demonstrate how to download a file using the traditional method and retrieve it from the browser session. Use the [create session](api-reference/browser-sessions/start-browser-session) API to create a new browser session. Use the following example to perform a file download ```tsx node.js await page.goto("https://browser-tests-alpha.vercel.app/api/download-test"); await Promise.all([page.waitForEvent("download"), page.locator("#download").click()]); // The download has completed ``` ```python python await page.goto("https://browser-tests-alpha.vercel.app/api/download-test") async with page.expect_download() as download_info: await page.locator("#download").click() download = await download_info.value ``` You can retrieve the downloaded file from the browser session using the [get session downloads](/api-reference/browser-sessions/list-session-downloads) API ## P2P Downloads For enhanced performance and direct file capture without S3 storage, see our [P2P Download Guide](/advanced/p2p-downloads) which provides complete implementation examples and best practices. # File Upload Source: https://docs.anchorbrowser.io/advanced/file-upload Anchor Browser allows you to upload files during your browser sessions, enabling you to interact with web applications/forms that require files as input. The following examples demonstrate how to upload a file, either from your local development environment or one downloaded during the browser session. ## Using a local file ### Playwright example ```tsx node.js await page.goto('https://browser-tests-alpha.vercel.app/api/upload-test') const input = await page.$("#fileUpload") await input.setInputFiles('/tmp/my-files/google.png'); // Reference the local file path ``` ```python python page.goto('https://browser-tests-alpha.vercel.app/api/upload-test') input = page.locator("#fileUpload") input.set_input_files('/tmp/my-files/google.png') # Reference the local file path ``` # MCP - Hosted Version Source: https://docs.anchorbrowser.io/advanced/mcp Use Anchor with Model Context Protocol (MCP) in your preferred agentic tools via our hosted service Model Context Protocol ## Overview Anchor provides a **hosted** Model Context Protocol (MCP) integration, allowing you to use browser automation directly from your preferred AI tools without any local setup. Our hosted MCP server runs on our infrastructure and is available to all users with an Anchor API key. This enables seamless browser control from Cursor, VS Code, Claude, ChatGPT, and other MCP-compatible tools without managing any local dependencies. ## What is MCP? Model Context Protocol (MCP) is an open standard that allows AI assistants to interact with external tools and data sources. In our case, it enables AI-powered tools to access and control our browser automation capabilities directly within your IDE, agent apps, or CI/CD pipelines. ## Hosted vs Self-Hosted Our **hosted MCP service** provides: * ✅ Zero setup - just add your API key * ✅ Always up-to-date with latest features * ✅ Managed infrastructure and updates * ✅ Built-in scaling and reliability * ✅ Direct integration with Anchor's cloud browsers For advanced customization needs, see our [Open Source MCP Server](/advanced/mcp-open-source) documentation. ## Setup in Cursor Other MCP-compatible tools follow about the same pattern. The MCP server runs on our servers ([https://api.anchorbrowser.io/mcp](https://api.anchorbrowser.io/mcp)), and is available to all users providing their Anchor API Key. ### Configure MCP in Cursor Press Command+Shift+P (Mac) or Ctrl+Shift+P (Linux/Windows) and select "Open MCP Configuration File" Get Cursor MCP Settings Click on "Add Custom MCP" or "New MCP Server" if you already have some preconfigured. Add Custom MCP Server Add inside the `mcpServers` object the following: ```json "Anchor Browser Agent": { "url": "https://api.anchorbrowser.io/mcp", "headers": { "anchor-api-key": "YOUR_ANCHOR_API_KEY" } } ``` If you don't have your Anchor API key yet, you can get it from [Anchor UI](https://app.anchorbrowser.io/api-key). You should now see Anchor MCP server in the list of MCP servers in Cursor. It should say '24 tools enabled'. If you don't see it, disable and re-enable Anchor MCP server, or wait a little longer. ## Setup in VS Code Install the MCP extension for VS Code from the marketplace. Add to your VS Code MCP configuration file: ```json { "mcpServers": { "anchor-browser": { "url": "https://api.anchorbrowser.io/mcp", "headers": { "anchor-api-key": "YOUR_ANCHOR_API_KEY" } } } } ``` Restart VS Code to load the new MCP server configuration. ## Setup in Claude Desktop Open Claude Desktop's configuration file (`claude_desktop_config.json`). Add the following to your configuration: ```json { "mcpServers": { "anchor-browser": { "url": "https://api.anchorbrowser.io/mcp", "headers": { "anchor-api-key": "YOUR_ANCHOR_API_KEY" } } } } ``` Restart Claude Desktop to apply the configuration. # Usage Once configured, you can use Anchor Browser directly in your conversations with your AI assistant. ## Available Tools The hosted MCP integration provides access to all main Anchor capabilities: MCP Tools ### Test Generator Example ``` - You are a playwright test generator. - You are given a scenario and you need to generate a playwright test for it. - DO NOT generate test code based on the scenario alone. - DO run steps one by one using the tools provided by the Anchor Browser Agent MCP. - Only after all steps are completed, emit a Playwright TypeScript test that uses @playwright/test based on message history - Save generated test file in the tests directory - Execute the test file and iterate until the test passes Generate a Playwright test for the following scenario: 1. Navigate to https://www.imdb.com/ 2. search for 'Garfield' 3. return the director of the last movie ``` ## Programmatic Usage (Python SDK) You can also use the hosted MCP service programmatically in your Python applications using the MCP client library: ### Installation ```bash pip install mcp ``` ### Basic Example ```python import asyncio from mcp.client.streamable_http import streamablehttp_client from mcp import ClientSession async def list_tools(): async with streamablehttp_client( url="https://api.anchorbrowser.io/mcp", headers={"anchor-api-key": "sk-your-key"} ) as ( read_stream, write_stream, _, ): async with ClientSession(read_stream, write_stream) as session: await session.initialize() tools = await session.list_tools() for tool in tools.tools: print(f"{tool.name}: {getattr(tool, 'description', '')}") asyncio.run(list_tools()) ``` ## CI/CD Integration The hosted MCP service works in CI/CD environments without requiring local browser installations: ```yaml # GitHub Actions example name: AI Browser Testing on: [push, pull_request] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Run AI tests env: ANCHOR_API_KEY: ${{ secrets.ANCHOR_API_KEY }} run: | python ai_test_runner.py ``` ## Getting Help If you encounter issues with the hosted MCP integration: 1. **Check API Key**: Ensure your API key is valid 2. **Restart MCP Client**: Disable and re-enable the MCP server in your client 3. **Contact Support**: Reach out at [support@anchorbrowser.io](mailto:support@anchorbrowser.io) ## Migration from Self-Hosted Moving from a self-hosted MCP server to our hosted service: 1. **Update Configuration**: Change your MCP client to use `https://api.anchorbrowser.io/mcp` 2. **Add API Key**: Include your Anchor API key in the headers 3. **Remove Local Dependencies**: Uninstall local MCP server and dependencies 4. **Test Integration**: Verify all your existing MCP workflows still work # MCP - Open Source Source: https://docs.anchorbrowser.io/advanced/mcp-open-source Self-host Anchor MCP server with customizable Playwright integration for your specific needs # Anchor MCP Server (Open Source) Model Context Protocol A Model Context Protocol (MCP) server that provides browser automation capabilities using [Anchor Browser](https://anchorbrowser.io)'s remote browser service with [Playwright](https://playwright.dev). This server enables LLMs to interact with web pages through Anchor's cloud-based browsers with built-in proxies, stealth features, and advanced capabilities. This is based on the open source repository at [browsermcp-com/mcp](https://github.com/browsermcp-com/mcp), which extends Microsoft's Playwright MCP with Anchor Browser's cloud infrastructure. Looking for our hosted MCP service? Check out [MCP - Hosted Version](/advanced/mcp) for zero-setup integration. ## When to Use Open Source MCP Choose the open source version when you need: * **Custom tool modifications** - Modify browser automation tools for specific use cases * **Advanced configuration** - Fine-tune browser settings and behaviors * **Local development** - Test MCP integrations during development * **Compliance requirements** - Run MCP server within your infrastructure * **Integration with existing systems** - Connect MCP to your internal tools and workflows ## Key Features * **Remote Browser Execution**: Uses Anchor Browser's cloud infrastructure instead of local browsers * **Built-in Proxies**: Automatic residential proxy rotation and geo-targeting * **Stealth & Anti-Detection**: Advanced browser fingerprinting and anti-bot detection * **Fast and lightweight**: Uses Playwright's accessibility tree, not pixel-based input * **LLM-friendly**: No vision models needed, operates purely on structured data * **Deterministic tool application**: Avoids ambiguity common with screenshot-based approaches * **Customizable**: Modify and extend tools for your specific needs ## Requirements * Node.js 18 or newer * **Anchor Browser API Key** ([Get one here](https://anchorbrowser.io)) * VS Code, Cursor, Windsurf, Claude Desktop, Goose or any other MCP client ## Getting Started ### 1. Clone and Build Since this is a custom Anchor MCP server, you need to build it locally: ```bash # Clone the repository git clone https://github.com/browsermcp-com/mcp.git cd mcp # Install dependencies and build npm install npm run build ``` ### 2. Get Your Anchor API Key 1. Sign up at [anchorbrowser.io](https://anchorbrowser.io) 2. Get your API key from the dashboard 3. Copy your API key (starts with `sk-`) ### 3. Configure MCP Client #### Cursor Add to your `~/.cursor/mcp.json`: ```json { "mcpServers": { "anchor-browser": { "command": "node", "args": [ "/path/to/mcp/cli.js" ], "env": { "ANCHOR_API_KEY": "sk-your-api-key-here" } } } } ``` #### VS Code Add to your MCP configuration: ```json { "mcpServers": { "anchor-browser": { "command": "node", "args": [ "/path/to/mcp/cli.js" ], "env": { "ANCHOR_API_KEY": "sk-your-api-key-here" } } } } ``` #### Claude Desktop Add to your `claude_desktop_config.json`: ```json { "mcpServers": { "anchor-browser": { "command": "node", "args": [ "/path/to/mcp/cli.js" ], "env": { "ANCHOR_API_KEY": "sk-your-api-key-here" } } } } ``` ### 4. Restart Your MCP Client After updating the configuration, restart your MCP client (Cursor, VS Code, etc.) to load the new server. ## Configuration Options The Anchor MCP server supports essential configuration options: ```bash node cli.js --help ``` ### Available Options: * `--host ` - Host to bind server to (default: localhost, use 0.0.0.0 for all interfaces) * `--port ` - Port to listen on for HTTP transport (Docker/server mode) ### Example with Options: ```json { "mcpServers": { "anchor-browser": { "command": "node", "args": [ "/path/to/mcp/cli.js" ], "env": { "ANCHOR_API_KEY": "sk-your-api-key-here" } } } } ``` ## How It Works 1. **Browser Session Creation**: When you use browser tools, the MCP server calls Anchor's API to create a remote browser session 2. **Remote Connection**: Connects to the remote browser via WebSocket using Chrome DevTools Protocol (CDP) 3. **Tool Execution**: All browser automation happens in Anchor's cloud infrastructure 4. **Proxy & Stealth**: Automatic residential proxy rotation and advanced anti-detection features 5. **Session Management**: Each session is isolated and can be viewed live via Anchor's dashboard ## Production & CI/CD Usage ### Self-Hosted in Production The open source MCP server can be deployed in production environments: * **Docker Containers** - Run in containerized environments * **CI/CD Pipelines** - Integrate with Jenkins, GitHub Actions, GitLab CI * **Serverless Functions** - Deploy as microservices or serverless functions * **Kubernetes** - Scale horizontally in Kubernetes clusters ### CI/CD Integration Example ```yaml # GitHub Actions with self-hosted MCP name: E2E Testing on: [push, pull_request] jobs: test: runs-on: ubuntu-latest services: anchor-mcp: image: your-registry/anchor-mcp:latest env: ANCHOR_API_KEY: ${{ secrets.ANCHOR_API_KEY }} ports: - 8931:8931 steps: - uses: actions/checkout@v3 - name: Run AI tests against MCP server run: | python ai_test_runner.py --mcp-url http://localhost:8931/mcp ``` ## Benefits Over Local Browsers ### 🌐 **Global Proxy Network** * Automatic residential proxy rotation * Geo-targeting for different regions * No proxy configuration needed ### 🛡️ **Advanced Stealth** * Browser fingerprinting protection * Anti-bot detection bypass * Real browser environments ### ☁️ **Cloud Infrastructure** * No local browser dependencies * Consistent browser versions * Scalable execution ### 📊 **Monitoring & Debugging** * Live view of browser sessions * Session recordings and traces * Network request logging # MFA Source: https://docs.anchorbrowser.io/advanced/mfa Real-time event signaling and coordination between external systems and browser instances # Event Coordination Event coordination allows you to send real-time messages between external systems and active browser instances. This is particularly useful for **multi-factor authentication (MFA)** where you need to inject authentication codes during browser automation. ## Overview The system provides two operations: * **Signal Event**: Send data to an event channel * **Wait for Event**: Listen for data on an event channel with timeout Events are user-scoped and work across multiple browser instances. ## API Endpoints ### Signal an Event ```http POST https://api.anchorbrowser.io/api/v1/events/{eventName} ``` ### Wait for an Event ```http POST https://api.anchorbrowser.io/api/v1/events/{eventName}/wait ``` Both endpoints require `anchor-api-key` header and accept JSON payloads. ## MFA Use Case Handle MFA codes during automated login flows: ```javascript // In your browser automation script async function handleMFAFlow() { await page.fill('#username', 'user@example.com'); await page.fill('#password', 'password'); await page.click('#login-button'); // Wait for MFA code from external system const mfaEvent = await waitForEvent('mfa_code', 30000); if (mfaEvent?.data?.code) { await page.fill('#mfa-code', mfaEvent.data.code); await page.click('#verify-button'); } } ``` ```javascript // In your external system (mobile app, webhook, etc.) async function sendMFACode(code) { await signalEvent('mfa_code', { code }); } ``` ## Implementation ### JavaScript Helper Functions ```javascript const apiKey = 'your-api-key'; const apiBase = 'https://api.anchorbrowser.io'; async function signalEvent(eventName, data) { const response = await fetch(`${apiBase}/api/v1/events/${eventName}`, { method: 'POST', headers: { 'anchor-api-key': apiKey, 'Content-Type': 'application/json', }, body: JSON.stringify({ data: data || {} }), }); if (!response.ok) throw new Error(`Failed to signal event: ${response.status}`); return await response.json(); } async function waitForEvent(eventName, timeoutMs = 60000) { const response = await fetch(`${apiBase}/api/v1/events/${eventName}/wait`, { method: 'POST', headers: { 'anchor-api-key': apiKey, 'Content-Type': 'application/json', }, body: JSON.stringify({ timeoutMs }), }); if (response.status === 408) return null; // Timeout if (!response.ok) throw new Error(`Failed to wait for event: ${response.status}`); return await response.json(); } ``` ## Event Flow Patterns **Signal First, Wait Later** (immediate consumption): ```javascript await signalEvent("data", { value: "preloaded" }); const data = await waitForEvent("data", 1000); // Short timeout ``` **Wait First, Signal Later** (typical MFA flow): ```javascript const waitPromise = waitForEvent("mfa_code", 60000); // ... other operations ... const mfaData = await waitPromise; ``` ## Best Practices * Use descriptive event names: `mfa_code_login`, `mfa_code_transfer` * Always set appropriate timeouts * Validate received event data * Handle timeout scenarios gracefully ```javascript const mfaEvent = await waitForEvent('mfa_code', 30000); if (mfaEvent?.data?.code && /^\d{6}$/.test(mfaEvent.data.code)) { // Use validated MFA code } else { throw new Error('Invalid or missing MFA code'); } ``` # OS-Level Control Source: https://docs.anchorbrowser.io/advanced/os-level-control Direct operating system control for precise browser automation and AI agent interactions # OS-Level Control OS-level control provides direct access to operating system primitives like mouse movements, keyboard input, and screen interactions within your browser sessions. This approach offers more precise control than traditional web automation methods and is particularly powerful when combined with AI agents and vision-based models. ## Why OS-Level Control? ### Superior AI Agent Performance **Vision-based AI models perform significantly better** when they can interact with the browser using the same primitives humans use: * **Keyboard shortcuts work naturally**: `Ctrl+F` for searching, `Ctrl+L` for browser navbar interaction, `Ctrl+T` for new tabs * **OS-level UI elements**: Dropdowns, context menus, and system dialogs that aren't part of the webpage DOM * **Visual coordinate targeting**: AI agents can directly click on elements they see in screenshots ### Beyond Traditional Web Automation ## Core Capabilities ### Mouse Operations Control mouse interactions with pixel-level precision: ```javascript Basic Click // Single click at coordinates const response = await axios.post(`https://api.anchorbrowser.io/v1/sessions/${sessionId}/mouse/click`, { x: 400, y: 300, button: 'left' // 'left', 'middle', 'right' }, { headers: { 'anchor-api-key': 'your-api-key', 'Content-Type': 'application/json' } }); ``` ```javascript Advanced Mouse Control // Double-click for text selection await axios.post(`https://api.anchorbrowser.io/v1/sessions/${sessionId}/mouse/doubleClick`, { x: 500, y: 200 }, { headers: { 'anchor-api-key': 'your-api-key', 'Content-Type': 'application/json' } }); // Mouse down and up for custom gestures await axios.post(`https://api.anchorbrowser.io/v1/sessions/${sessionId}/mouse/down`, { x: 100, y: 100, button: 'left' }, { headers: { 'anchor-api-key': 'your-api-key', 'Content-Type': 'application/json' } }); // Move while holding down (drag) await axios.post(`https://api.anchorbrowser.io/v1/sessions/${sessionId}/mouse/move`, { x: 300, y: 300 }, { headers: { 'anchor-api-key': 'your-api-key', 'Content-Type': 'application/json' } }); // Release await axios.post(`https://api.anchorbrowser.io/v1/sessions/${sessionId}/mouse/up`, { x: 300, y: 300 }, { headers: { 'anchor-api-key': 'your-api-key', 'Content-Type': 'application/json' } }); ``` ### Drag and Drop Perform complex drag and drop operations in a single command: ```javascript // Drag file from desktop to upload area const response = await axios.post(`https://api.anchorbrowser.io/v1/sessions/${sessionId}/drag-and-drop`, { startX: 200, startY: 150, endX: 600, endY: 400, button: 'left' }, { headers: { 'anchor-api-key': 'your-api-key', 'Content-Type': 'application/json' } }); ``` ### Keyboard Input Send text and keyboard shortcuts with human-like timing: ```javascript Text Input // Type text with optional delay between keystrokes const response = await axios.post(`https://api.anchorbrowser.io/v1/sessions/${sessionId}/keyboard/type`, { text: "Hello, world!", delay: 50 // milliseconds between keystrokes }, { headers: { 'anchor-api-key': 'your-api-key', 'Content-Type': 'application/json' } }); ``` ```javascript Keyboard Shortcuts // Execute keyboard shortcuts const response = await axios.post(`https://api.anchorbrowser.io/v1/sessions/${sessionId}/keyboard/shortcut`, { keys: ['Ctrl', 'a'], // Select all holdTime: 100 // Hold keys for 100ms }, { headers: { 'anchor-api-key': 'your-api-key', 'Content-Type': 'application/json' } }); // Common shortcuts const shortcuts = { selectAll: ['Ctrl', 'a'], copy: ['Ctrl', 'c'], paste: ['Ctrl', 'v'], undo: ['Ctrl', 'z'], newTab: ['Ctrl', 't'], closeTab: ['Ctrl', 'w'], focusAddressBar: ['Ctrl', 'l'] }; ``` ### Scrolling Control page scrolling with precision: ```javascript // Scroll at specific coordinates const response = await axios.post(`https://api.anchorbrowser.io/v1/sessions/${sessionId}/scroll`, { x: 400, // Where to perform scroll (cursor position) y: 300, // Where to perform scroll (cursor position) deltaX: 0, // Horizontal scroll amount (does not correlate with pixels) deltaY: 200, // Vertical scroll amount (does not correlate with pixels, positive = down) steps: 5 // Number of steps for smooth scrolling }, { headers: { 'anchor-api-key': 'your-api-key', 'Content-Type': 'application/json' } }); ``` ### Screenshots Capture visual state for AI analysis: ```javascript // Take screenshot of current browser state const response = await axios.get(`https://api.anchorbrowser.io/v1/sessions/${sessionId}/screenshot`, { headers: { 'anchor-api-key': 'your-api-key' }, responseType: 'arraybuffer' }); const imageBuffer = response.data; // Process screenshot with vision AI model ``` ### Clipboard Operations Manage clipboard content programmatically: ```javascript Reading Clipboard // Get current clipboard content const response = await axios.get(`https://api.anchorbrowser.io/v1/sessions/${sessionId}/clipboard`, { headers: { 'anchor-api-key': 'your-api-key' } }); const { data } = response.data; console.log('Clipboard content:', data.text); ``` ```javascript Setting Clipboard // Set clipboard content await axios.post(`https://api.anchorbrowser.io/v1/sessions/${sessionId}/clipboard`, { text: "Content to copy" }, { headers: { 'anchor-api-key': 'your-api-key', 'Content-Type': 'application/json' } }); // Trigger copy operation (copies selected text) const copyResponse = await axios.post(`https://api.anchorbrowser.io/v1/sessions/${sessionId}/copy`, {}, { headers: { 'anchor-api-key': 'your-api-key' } }); // Trigger paste operation await axios.post(`https://api.anchorbrowser.io/v1/sessions/${sessionId}/paste`, { text: "Text to paste" }, { headers: { 'anchor-api-key': 'your-api-key', 'Content-Type': 'application/json' } }); ``` ### Navigation Direct URL navigation at the OS level on the currently selected tab: ```javascript // Navigate to a specific URL (completely OS-level, operates on selected tab) const response = await axios.post(`https://api.anchorbrowser.io/v1/sessions/${sessionId}/goto`, { url: "https://example.com" }, { headers: { 'anchor-api-key': 'your-api-key', 'Content-Type': 'application/json' } }); ``` ## AI Agent Integration Patterns ### OpenAI Computer Use Integration Anchor includes an integrated **OpenAI Computer Use agent** that leverages OS-level control for enhanced AI interactions. This agent can perform complex tasks by combining vision models with precise OS-level operations. ```python class AnchorBrowser(BasePlaywrightComputer): """ Computer implementation for Anchor browser (https://anchorbrowser.io) Uses OS-level control endpoints for browser automation within the container. IMPORTANT: The `goto` and navigation tools are already implemented and recommended when using the Anchor computer to help the agent navigate more effectively. """ def __init__(self, width: int = 1024, height: int = 900, session_id: str = None): """Initialize the Anchor browser session""" super().__init__() self.dimensions = (width, height) self.session_id = session_id self.base_url = "http://localhost:8484/api/os-control" def screenshot(self) -> str: """ Capture a screenshot using OS-level control API. Returns: str: A base64 encoded string of the screenshot for AI model consumption. """ try: response = requests.get(f"{self.base_url}/screenshot") if not response.ok: print(f"OS-level screenshot failed, falling back to standard screenshot") return super().screenshot() # OS-level API returns binary PNG data, encoded for AI models return base64.b64encode(response.content).decode('utf-8') except Exception as error: print(f"OS-level screenshot failed, falling back: {error}") return super().screenshot() def click(self, x: int, y: int, button: str = "left") -> None: """ Click at the specified coordinates using OS-level control. Args: x: The x-coordinate to click. y: The y-coordinate to click. button: The mouse button to use ('left', 'right'). """ try: response = requests.post( f"{self.base_url}/mouse/click", json={"x": x, "y": y, "button": button} ) if not response.ok: print(f"OS-level click failed, falling back to standard click") super().click(x, y, button) except Exception as error: print(f"OS-level click failed, falling back: {error}") super().click(x, y, button) def type(self, text: str) -> None: """ Type text using OS-level control with realistic delays. """ try: response = requests.post( f"{self.base_url}/keyboard/type", json={"text": text, "delay": 30} ) if not response.ok: print(f"OS-level type failed, falling back to standard type") super().type(text) except Exception as error: print(f"OS-level type failed, falling back: {error}") super().type(text) def keypress(self, keys: List[str]) -> None: """ Press keyboard shortcut using OS-level control. Args: keys: List of keys to press simultaneously (e.g., ['Ctrl', 'c']). """ try: response = requests.post( f"{self.base_url}/keyboard/shortcut", json={"keys": keys, "holdTime": 100} ) if not response.ok: print(f"OS-level keyboard shortcut failed, falling back") # Fallback to standard implementation for key in keys: self._page.keyboard.down(key) for key in reversed(keys): self._page.keyboard.up(key) except Exception as error: print(f"OS-level keyboard shortcut failed: {error}") ``` ### Usage with OpenAI Models The integrated computer use agent works seamlessly with OpenAI's vision models: ```python # Initialize the agent with your session agent = AnchorBrowser(width=1440, height=900, session_id="your-session-id") # The agent can now: # 1. Take screenshots for AI analysis screenshot = agent.screenshot() # 2. Perform precise clicks based on AI vision agent.click(x=400, y=300) # 3. Type text naturally agent.type("Hello from AI agent!") # 4. Execute keyboard shortcuts agent.keypress(['Ctrl', 'l']) # Focus address bar agent.keypress(['Ctrl', 'f']) # Open search ``` The computer use integration provides **automatic fallbacks** to standard browser automation if OS-level operations aren't available, ensuring reliability across different environments. ## Limitations and Considerations ### Session Requirements * **Headful Sessions Only**: OS-level control requires a visible desktop environment * **Performance Impact**: Screenshots and precise positioning may be slower than DOM-based automation *** OS-level control opens up powerful possibilities for AI-driven browser automation, enabling more natural and effective interactions that mirror human behavior while providing the precision needed for reliable automation workflows. # P2P Download Source: https://docs.anchorbrowser.io/advanced/p2p-downloads Capture files directly in the browser without cloud storage ## What is P2P Download? P2P (Peer-to-Peer) downloads capture files directly in the browser memory without ever uploading them to cloud storage. When a user downloads a file in your browser session, instead of the file going to Anchor's servers, it's intercepted and made available to you immediately through browser hooks. ## How It Works Traditional downloads follow this path: * User clicks download → File goes to browser → File uploads to Anchor's servers → You fetch from Anchor's servers P2P downloads work differently: * User clicks download → File captured in browser memory → You fetch from the browser The browser intercept download events, allowing you to extract the file data directly without any cloud storage involved. ## Implementation Example ```tsx node.js import { promises as fs, existsSync } from "node:fs"; import { chromium } from "playwright"; const { ANCHOR_API_KEY } = process.env; /** * Save a download to disk. * Handles three possible formats: * 1. Playwright Download object * 2. Base‑64 string * 3. Fallback text scraped from the page */ async function saveDownload(download, filePath, page) { // 1. Playwright Download object if (download && typeof download.path === "function") { try { const tmpPath = await download.path(); if (tmpPath && existsSync(tmpPath)) { await download.saveAs(filePath); return filePath; } } catch { /* ignore and fall through */ } } // 2. Raw base64 string if (typeof download === "string") { try { await fs.writeFile(filePath, Buffer.from(download, "base64")); return filePath; } catch { /* ignore and fall through */ } } // 3. Fallback – ask the page for data or capture visible text if (page) { try { const blob = await page.evaluate(() => window._anchorExtractDownloadData()); return saveDownload(blob, filePath); } catch { /* ignore and fall through */ } const fallbackText = await page.evaluate(() => { const el = document.querySelector("main") || document.body; return el.innerText || ""; }); await fs.writeFile(filePath, fallbackText, "utf8"); return filePath; } throw new Error("Failed to save download"); } const downloadHandler = (filePath) => async (page, info) => { if (info?.value) { try { return await saveDownload(info.value, filePath); } catch { /* ignore and fall through */ } } return saveDownload(null, filePath, page); }; async function createSession() { const res = await fetch("https://api.anchorbrowser.io/v1/sessions", { method: "POST", headers: { "Content-Type": "application/json", "anchor-api-key": ANCHOR_API_KEY, }, body: JSON.stringify({ browser: { p2p_download: { active: true } } }), }); if (!res.ok) throw new Error(`Anchor API error ${res.status}: ${await res.text()}`); const { data } = await res.json(); return data; } (async () => { const session = await createSession(); if (!session?.cdp_url) throw new Error("No CDP URL in session"); const browser = await chromium.connectOverCDP(session.cdp_url); const context = browser.contexts()[0]; const page = context.pages()[0]; await page.goto("https://v0-download-and-upload-text.vercel.app/"); await page.waitForSelector("button"); const [download] = await Promise.all([ page.waitForEvent("download", { timeout: 5000 }), page.click("button"), page.waitForTimeout(500), // allow JS to finish ]); const filename = download.suggestedFilename(); await downloadHandler(filename)(page, { value: download }); const content = await fs.readFile(filename, "utf8"); console.log(`Downloaded '${filename}', content:\n${content}`); await browser.close(); })(); ``` ```python python import os, base64, json, requests from playwright.sync_api import sync_playwright ANCHOR_API_KEY = os.getenv("ANCHOR_API_KEY") def save_download(src, path, page=None): """Persist a Playwright Download object or base‑64 string to *path*. Falls back to blob extraction or page text when needed. """ if hasattr(src, "path"): try: tmp = src.path() if tmp and os.path.exists(tmp): src.save_as(path) return path except Exception: pass if isinstance(src, str): try: with open(path, "wb") as f: f.write(base64.b64decode(src)) return path except Exception: pass if page: try: blob = page.evaluate("() => window._anchorExtractDownloadData()") return save_download(blob, path) except Exception: # As a last resort, dump visible page text text = page.evaluate( "() => (document.querySelector('main')||document.body).innerText" ) with open(path, "w") as f: f.write(text) return path raise RuntimeError("Failed to save download") def download_handler(path): """Return a function (page, download_info) that writes to *path*.""" def _handle(page, info=None): if info and hasattr(info, "value"): try: return save_download(info.value, path) except Exception: pass # Fallback to blob extraction return save_download(None, path, page) return _handle def create_session(): resp = requests.post( "https://api.anchorbrowser.io/v1/sessions", headers={ "Content-Type": "application/json", "anchor-api-key": ANCHOR_API_KEY, }, json={ "browser": { "p2p_download": { "active": True } } } ) if resp.status_code != 200: raise Exception(f"Anchor API error {resp.status_code}: {resp.text}") return resp.json().get("data") with sync_playwright() as p: session = create_session() if not session or "cdp_url" not in session: print("Could not obtain a valid browser session – exiting.") raise SystemExit(1) browser = p.chromium.connect_over_cdp(session["cdp_url"]) page = browser.contexts[0].pages[0] page.goto("https://v0-download-and-upload-text.vercel.app/") page.wait_for_selector("button", state="visible") with page.expect_download(timeout=5000) as dl: page.click("button") page.wait_for_timeout(500) # allow JS to finish filename = dl.value.suggested_filename handler = download_handler(filename) handler(page, dl) with open(filename) as f: snippet = f.read() print(f"Downloaded '{filename}', content:\n{snippet}") ``` # Proxy Source: https://docs.anchorbrowser.io/advanced/proxy Anchor provides 4 types of proxy configurations: * [Anchor Residential Proxy](/advanced/proxy#use-anchor-residential-proxy) - anchor\_residential * [Anchor Mobile Proxy](/advanced/proxy#use-anchor-mobile-proxy) - anchor\_mobile * [Anchor Gov Proxy](/advanced/proxy#use-anchor-gov-proxy) - anchor\_gov * [Custom Proxy](/advanced/proxy#use-a-custom-proxy) - custom To experiment with different proxy types, visit our [Interactive API Reference](/api-reference/browser-sessions/start-browser-session) ### Use Anchor Residential Proxy Create your session with a residential proxy to access websites as if you're browsing from a computer in that country. ```bash curl curl --request POST \ --url https://api.anchorbrowser.io/v1/sessions \ --header 'Content-Type: application/json' \ --header 'anchor-api-key: ' \ --data '{ "session": { "proxy": { "type": "anchor_residential", "country_code": "us", "active": true } } }' ``` ```javascript node.js const axios = require('axios'); (async () => { const response = await axios.post('https://api.anchorbrowser.io/v1/sessions', { session: { proxy: { type: 'anchor_residential', country_code: 'us', active: true } } }, { headers: { 'anchor-api-key': process.env.ANCHOR_API_KEY, 'Content-Type': 'application/json' } }); console.log('Session created:', response.data); })().catch(console.error); ``` ```python python import os import requests import json ANCHOR_API_KEY = os.getenv('ANCHOR_API_KEY') response = requests.post( 'https://api.anchorbrowser.io/v1/sessions', json={ 'session': { 'proxy': { 'type': 'anchor_residential', 'country_code': 'us', 'active': True } } }, headers={ 'anchor-api-key': ANCHOR_API_KEY, 'Content-Type': 'application/json' } ) response.raise_for_status() print('Session created:') print(json.dumps(response.json()['data'], indent=2)) ``` ### Use Anchor Mobile Proxy Create your session with a mobile proxy to access websites as if you're browsing from a mobile device in that country. ```bash curl curl --request POST \ --url https://api.anchorbrowser.io/v1/sessions \ --header 'Content-Type: application/json' \ --header 'anchor-api-key: ' \ --data '{ "session": { "proxy": { "type": "anchor_mobile", "country_code": "us", "active": true } } }' ``` ```javascript node.js const axios = require('axios'); (async () => { const response = await axios.post('https://api.anchorbrowser.io/v1/sessions', { session: { proxy: { type: 'anchor_mobile', country_code: 'us', active: true } } }, { headers: { 'anchor-api-key': process.env.ANCHOR_API_KEY, 'Content-Type': 'application/json' } }); console.log('Session created:', response.data); })().catch(console.error); ``` ```python python import os import requests import json ANCHOR_API_KEY = os.getenv('ANCHOR_API_KEY') response = requests.post( 'https://api.anchorbrowser.io/v1/sessions', json={ 'session': { 'proxy': { 'type': 'anchor_mobile', 'country_code': 'us', 'active': True } } }, headers={ 'anchor-api-key': ANCHOR_API_KEY, 'Content-Type': 'application/json' } ) response.raise_for_status() print('Session created:') print(json.dumps(response.json()['data'], indent=2)) ``` ### Use Anchor Gov Proxy Create your session with a residential proxy to access websites as if you're browsing from a computer in that country. This option reduces the chance of being blocked by governmental websites. ```bash curl curl --request POST \ --url https://api.anchorbrowser.io/v1/sessions \ --header 'Content-Type: application/json' \ --header 'anchor-api-key: ' \ --data '{ "session": { "proxy": { "type": "anchor_gov", "country_code": "us", "active": true } } }' ``` ```javascript node.js const axios = require('axios'); (async () => { const response = await axios.post('https://api.anchorbrowser.io/v1/sessions', { session: { proxy: { type: 'anchor_gov', country_code: 'us', active: true } } }, { headers: { 'anchor-api-key': process.env.ANCHOR_API_KEY, 'Content-Type': 'application/json' } }); console.log('Session created:', response.data); })().catch(console.error); ``` ```python python import os import requests import json ANCHOR_API_KEY = os.getenv('ANCHOR_API_KEY') response = requests.post( 'https://api.anchorbrowser.io/v1/sessions', json={ 'session': { 'proxy': { 'type': 'anchor_gov', 'country_code': 'us', 'active': True } } }, headers={ 'anchor-api-key': ANCHOR_API_KEY, 'Content-Type': 'application/json' } ) response.raise_for_status() print('Session created:') print(json.dumps(response.json()['data'], indent=2)) ``` ### Use a Custom Proxy ```bash curl curl --request POST \ --url https://api.anchorbrowser.io/v1/sessions \ --header 'Content-Type: application/json' \ --header 'anchor-api-key: ' \ --data '{ "session": { "proxy": { "type": "custom", "server": "proxy.example.com", "username": "myUser", "password": "myPassword", "active": true } } }' ``` ```javascript node.js const axios = require('axios'); (async () => { const response = await axios.post('https://api.anchorbrowser.io/v1/sessions', { session: { proxy: { type: 'custom', server: 'proxy.example.com', username: 'myUser', password: 'myPassword', active: true } } }, { headers: { 'anchor-api-key': process.env.ANCHOR_API_KEY, 'Content-Type': 'application/json' } }); console.log('Session created:', response.data); })().catch(console.error); ``` ```python python import os import requests import json ANCHOR_API_KEY = os.getenv('ANCHOR_API_KEY') response = requests.post( 'https://api.anchorbrowser.io/v1/sessions', json={ 'session': { 'proxy': { 'type': 'custom', 'server': 'proxy.example.com', 'username': 'myUser', 'password': 'myPassword', 'active': True } } }, headers={ 'anchor-api-key': ANCHOR_API_KEY, 'Content-Type': 'application/json' } ) response.raise_for_status() print('Session created:') print(json.dumps(response.json()['data'], indent=2)) ``` ## Localization You can specify a country code for your proxy to route traffic through a specific geographic location. This is useful for accessing region-specific content or testing localized experiences. The `country_code` parameter accepts the following country codes in lowercase: ### Supported Countries with their Country Codes | | | | | | | | ---------------------- | -- | ------------- | -- | ------------------------ | -- | | Afghanistan | af | Gambia | gm | Oman | om | | Albania | al | Georgia | ge | Pakistan | pk | | Algeria | dz | Germany | de | Panama | pa | | Andorra | ad | Ghana | gh | Papua New Guinea | pg | | Angola | ao | Greece | gr | Paraguay | py | | Antigua and Barbuda | ag | Grenada | gd | Peru | pe | | Argentina | ar | Guatemala | gt | Philippines | ph | | Armenia | am | Guinea | gn | Poland | pl | | Aruba | aw | Guyana | gy | Portugal | pt | | Australia | au | Haiti | ht | Puerto Rico | pr | | Austria | at | Honduras | hn | Qatar | qa | | Azerbaijan | az | Hong Kong | hk | Romania | ro | | Bahamas | bs | Hungary | hu | Russia | ru | | Bahrain | bh | Iceland | is | Rwanda | rw | | Bangladesh | bd | India | in | Saint Lucia | lc | | Barbados | bb | Indonesia | id | Samoa | ws | | Belarus | by | Iran | ir | San Marino | sm | | Belgium | be | Iraq | iq | Saudi Arabia | sa | | Belize | bz | Ireland | ie | Senegal | sn | | Benin | bj | Israel | il | Serbia | rs | | Bermuda | bm | Italy | it | Sierra Leone | sl | | Bolivia | bo | Jamaica | jm | Singapore | sg | | Bosnia and Herzegovina | ba | Japan | jp | Slovakia | sk | | Botswana | bw | Jordan | jo | Slovenia | si | | Brazil | br | Kazakhstan | kz | Somalia | so | | Brunei Darussalam | bn | Kenya | ke | South Africa | za | | Bulgaria | bg | Kuwait | kw | South Korea | kr | | Burkina Faso | bf | Kyrgyzstan | kg | South Sudan | ss | | Burundi | bi | Laos | la | Spain | es | | Cambodia | kh | Latvia | lv | Sri Lanka | lk | | Cameroon | cm | Lebanon | lb | Sudan | sd | | Canada | ca | Lesotho | ls | Suriname | sr | | Cape Verde | cv | Liberia | lr | Sweden | se | | Chad | td | Libya | ly | Switzerland | ch | | Chile | cl | Lithuania | lt | Syria | sy | | China | cn | Luxembourg | lu | São Tomé and Príncipe | st | | Colombia | co | Macedonia | mk | Taiwan | tw | | Congo | cg | Madagascar | mg | Tajikistan | tj | | Costa Rica | cr | Malawi | mw | Tanzania | tz | | Côte d’Ivoire | ci | Malaysia | my | Thailand | th | | Croatia | hr | Maldives | mv | Timor Leste (East Timor) | tl | | Cuba | cu | Mali | ml | Turkey | tr | | Cyprus | cy | Malta | mt | Togo | tg | | Czech Republic | cz | Mauritania | mr | Trinidad and Tobago | tt | | Denmark | dk | Mexico | mx | Tunisia | tn | | Djibouti | dj | Moldova | md | Turkmenistan | tm | | Dominica | dm | Mongolia | mn | Uganda | ug | | Dominican Republic | do | Montenegro | me | Ukraine | ua | | Ecuador | ec | Morocco | ma | United Kingdom | gb | | Egypt | eg | Mozambique | mz | United States | us | | El Salvador | sv | Myanmar | mm | Uruguay | uy | | Equatorial Guinea | gq | Namibia | na | Uzbekistan | uz | | Estonia | ee | Nepal | np | Vanuatu | vu | | Eswatini | sz | Netherlands | nl | Venezuela | ve | | Ethiopia | et | New Caledonia | nc | Vietnam | vn | | Fiji | fj | New Zealand | nz | Yemen | ye | | Finland | fi | Nicaragua | ni | Zambia | zm | | France | fr | Niger | ne | Zimbabwe | zw | | French Polynesia | pf | Nigeria | ng | | | | Gabon | ga | Norway | no | | | | | | | | | | | ---------------------- | -- | ------------- | -- | -------------------- | -- | | Afghanistan | af | Georgia | ge | Nigeria | ng | | Albania | al | Germany | de | Norway | no | | Algeria | dz | Ghana | gh | Oman | om | | Angola | ao | Greece | gr | Pakistan | pk | | Antigua and Barbuda | ag | Guatemala | gt | Panama | pa | | Argentina | ar | Guinea-Bissau | gw | Paraguay | py | | Armenia | am | Guyana | gy | Peru | pe | | Australia | au | Haiti | ht | Philippines | ph | | Austria | at | Honduras | hn | Poland | pl | | Azerbaijan | az | Hungary | hu | Portugal | pt | | Bahamas | bs | Iceland | is | Qatar | qa | | Bahrain | bh | India | in | Romania | ro | | Bangladesh | bd | Indonesia | id | Russia | ru | | Barbados | bb | Iraq | iq | Rwanda | rw | | Belgium | be | Ireland | ie | Saudi Arabia | sa | | Belize | bz | Israel | il | Senegal | sn | | Benin | bj | Italy | it | Serbia | rs | | Bhutan | bt | Jamaica | jm | Sierra Leone | sl | | Bolivia | bo | Japan | jp | Singapore | sg | | Bosnia and Herzegovina | ba | Jordan | jo | Slovakia | sk | | Botswana | bw | Kazakhstan | kz | Slovenia | si | | Brazil | br | Kenya | ke | South Africa | za | | Bulgaria | bg | Kuwait | kw | South Korea | kr | | Burkina Faso | bf | Kyrgyzstan | kg | Spain | es | | Cambodia | kh | Laos | la | Sri Lanka | lk | | Cameroon | cm | Latvia | lv | Sudan | sd | | Canada | ca | Lebanon | lb | Sweden | se | | Cape Verde | cv | Liberia | lr | Switzerland | ch | | Chile | cl | Libya | ly | Syria | sy | | China | cn | Lithuania | lt | Taiwan | tw | | Colombia | co | Macedonia | mk | Tajikistan | tj | | Congo | cg | Malawi | mw | Tanzania | tz | | Côte d’Ivoire | ci | Malaysia | my | Thailand | th | | Croatia | hr | Maldives | mv | Togo | tg | | Cuba | cu | Mali | ml | Trinidad and Tob | | | Cyprus | cy | Malta | mt | Tunisia | tn | | Czech Republic | cz | Mauritius | mu | Turkey | tr | | Denmark | dk | Mexico | mx | Uganda | ug | | Dominican Republic | do | Moldova | md | Ukraine | ua | | Ecuador | ec | Mongolia | mn | United Arab Emirates | ae | | Egypt | eg | Montenegro | me | United Kingdom | gb | | El Salvador | sv | Morocco | ma | United States | us | | Estonia | ee | Mozambique | mz | Uruguay | uy | | Ethiopia | et | Nepal | np | Uzbekistan | uz | | Fiji | fj | Netherlands | nl | Venezuela | ve | | Finland | fi | New Caledonia | nc | Vietnam | vn | | France | fr | New Zealand | nz | Yemen | ye | | Gabon | ga | Namibia | na | Zambia | zm | | Gambia | gm | Nicaragua | ni | Zimbabwe | zw | | | | | | | | | ---------------------- | -- | ---------------- | -- | ------------------------ | -- | | Afghanistan | af | France | fr | Netherlands | nl | | Albania | al | French Guiana | gf | New Zealand | nz | | Algeria | dz | French Polynesia | pf | Nicaragua | ni | | Andorra | ad | Gabon | ga | Nigeria | ng | | Angola | ao | Gambia | gm | Norway | no | | American Samoa | as | Georgia | ge | Pakistan | pk | | Antigua and Barbuda | ag | Germany | de | Panama | pa | | Argentina | ar | Ghana | gh | Paraguay | py | | Armenia | am | Gibraltar | gi | Peru | pe | | Aruba | aw | Greece | gr | Philippines | ph | | Australia | au | Grenada | gd | Poland | pl | | Austria | at | Guadeloupe | gp | Portugal | pt | | Azerbaijan | az | Guatemala | gt | Puerto Rico | pr | | Bahamas | bs | Guernsey | gg | Qatar | qa | | Bahrain | bh | Guinea | gn | Romania | ro | | Barbados | bb | Guinea-Bissau | gw | Saint Lucia | lc | | Belarus | by | Guyana | gy | San Marino | sm | | Belgium | be | Haiti | ht | Saudi Arabia | sa | | Belize | bz | Honduras | hn | Senegal | sn | | Benin | bj | Hungary | hu | Serbia | rs | | Bermuda | bm | Iceland | is | Seychelles | sc | | Bolivia | bo | India | in | Sierra Leone | sl | | Bosnia and Herzegovina | ba | Iran | ir | Slovakia | sk | | Brazil | br | Iraq | iq | Slovenia | si | | Bulgaria | bg | Ireland | ie | Somalia | so | | Burkina Faso | bf | Israel | il | South Africa | za | | Cameroon | cm | Italy | it | South Korea | kr | | Canada | ca | Jamaica | jm | Spain | es | | Cape Verde | cv | Japan | jp | Suriname | sr | | Chad | td | Jordan | jo | Sweden | se | | Chile | cl | Kazakhstan | kz | Switzerland | ch | | Colombia | co | Kuwait | kw | Syria | sy | | Congo | cg | Kyrgyzstan | kg | São Tomé and Príncipe | st | | Costa Rica | cr | Latvia | lv | Taiwan | tw | | Côte d’Ivoire | ci | Lebanon | lb | Tajikistan | tj | | Croatia | hr | Libya | ly | Togo | tg | | Cuba | cu | Liechtenstein | li | Trinidad and Tobago | tt | | Cyprus | cy | Lithuania | lt | Tunisia | tn | | Czech Republic | cz | Luxembourg | lu | Turkey | tr | | Denmark | dk | Macedonia | mk | Turks and Caicos Islands | tc | | Dominica | dm | Mali | ml | Ukraine | ua | | Dominican Republic | do | Malta | mt | United Arab Emirates | ae | | Ecuador | ec | Martinique | mq | United States | us | | Egypt | eg | Mauritania | mr | Uruguay | uy | | El Salvador | sv | Mexico | mx | Uzbekistan | uz | | Estonia | ee | Moldova | md | Venezuela | ve | | Ethiopia | et | Monaco | mc | Yemen | ye | | Faroe Islands | fo | Montenegro | me | | | | Finland | fi | Morocco | ma | | | {/* # Gov Proxy |Afghanistan|af| |Albania|al| |Algeria|dz| |Andorra|ad| |Angola|ao| |American Samoa|as| |Antigua and Barbuda|ag| |Argentina|ar| |Armenia|am| |Aruba|aw| |Australia|au| |Austria|at| |Azerbaijan|az| |Bahamas|bs| |Bahrain|bh| |Barbados|bb| |Belarus|by| |Belgium|be| |Belize|bz| |Benin|bj| |Bermuda|bm| |Bolivia|bo| |Bosnia and Herzegovina|ba| |Brazil|br| |Bulgaria|bg| |Burkina Faso|bf| |Cameroon|cm| |Canada|ca| |Cape Verde|cv| |Chad|td| |Chile|cl| |Colombia|co| |Congo|cg| |Costa Rica|cr| |Côte d’Ivoire|ci| |Croatia|hr| |Cuba|cu| |Cyprus|cy| |Czech Republic|cz| |Denmark|dk| |Dominica|dm| |Dominican Republic|do| |Ecuador|ec| |Egypt|eg| |El Salvador|sv| |Estonia|ee| |Ethiopia|et| |Faroe Islands|fo| |Finland|fi| |France|fr| |French Guiana|gf| |French Polynesia|pf| |Gabon|ga| |Gambia|gm| |Georgia|ge| |Germany|de| |Ghana|gh| |Gibraltar|gi| |Greece|gr| |Grenada|gd| |Guadeloupe|gp| |Guatemala|gt| |Guernsey|gg| |Guinea|gn| |Guinea-Bissau|gw| |Guyana|gy| |Haiti|ht| |Honduras|hn| |Hungary|hu| |Iceland|is| |India|in| |Iran|ir| |Iraq|iq| |Ireland|ie| |Israel|il| |Italy|it| |Jamaica|jm| |Japan|jp| |Jordan|jo| |Kazakhstan|kz| |Kuwait|kw| |Kyrgyzstan|kg| |Latvia|lv| |Lebanon|lb| |Libya|ly| |Liechtenstein|li| |Lithuania|lt| |Luxembourg|lu| |Macedonia|mk| |Mali|ml| |Malta|mt| |Martinique|mq| |Mauritania|mr| |Mexico|mx| |Moldova|md| |Monaco|mc| |Montenegro|me| |Morocco|ma| |Netherlands|nl| |New Zealand|nz| |Nicaragua|ni| |Nigeria|ng| |Norway|no| |Pakistan|pk| |Panama|pa| |Paraguay|py| |Peru|pe| |Philippines|ph| |Poland|pl| |Portugal|pt| |Puerto Rico|pr| |Qatar|qa| |Romania|ro| |Saint Lucia|lc| |San Marino|sm| |Saudi Arabia|sa| |Senegal|sn| |Serbia|rs| |Seychelles|sc| |Sierra Leone|sl| |Slovakia|sk| |Slovenia|si| |Somalia|so| |South Africa|za| |South Korea|kr| |Spain|es| |Suriname|sr| |Sweden|se| |Switzerland|ch| |Syria|sy| |São Tomé and Príncipe|st| |Taiwan|tw| |Tajikistan|tj| |Togo|tg| |Trinidad and Tobago|tt| |Tunisia|tn| |Turkey|tr| |Turks and Caicos Islands|tc| |Ukraine|ua| |United Arab Emirates|ae| |United States|us| |Uruguay|uy| |Uzbekistan|uz| |Venezuela|ve| |Yemen|ye| */} {/* #### Mobile Proxy |Afghanistan|af| |Albania|al| |Algeria|dz| |Angola|ao| |Antigua and Barbuda|ag| |Argentina|ar| |Armenia|am| |Australia|au| |Austria|at| |Azerbaijan|az| |Bahamas|bs| |Bahrain|bh| |Bangladesh|bd| |Barbados|bb| |Belgium|be| |Belize|bz| |Benin|bj| |Bhutan|bt| |Bolivia|bo| |Bosnia and Herzegovina|ba| |Botswana|bw| |Brazil|br| |Bulgaria|bg| |Burkina Faso|bf| |Cambodia|kh| |Cameroon|cm| |Canada|ca| |Cape Verde|cv| |Chile|cl| |China|cn| |Colombia|co| |Congo|cg| |Côte d’Ivoire|ci| |Croatia|hr| |Cuba|cu| |Cyprus|cy| |Czech Republic|cz| |Denmark|dk| |Dominican Republic|do| |Ecuador|ec| |Egypt|eg| |El Salvador|sv| |Estonia|ee| |Ethiopia|et| |Fiji|fj| |Finland|fi| |France|fr| |Gabon|ga| |Gambia|gm| |Georgia|ge| |Germany|de| |Ghana|gh| |Greece|gr| |Guatemala|gt| |Guinea-Bissau|gw| |Guyana|gy| |Haiti|ht| |Honduras|hn| |Hungary|hu| |Iceland|is| |India|in| |Indonesia|id| |Iraq|iq| |Ireland|ie| |Israel|il| |Italy|it| |Jamaica|jm| |Japan|jp| |Jordan|jo| |Kazakhstan|kz| |Kenya|ke| |Kuwait|kw| |Kyrgyzstan|kg| |Laos|la| |Latvia|lv| |Lebanon|lb| |Liberia|lr| |Libya|ly| |Lithuania|lt| |Macedonia|mk| |Malawi|mw| |Malaysia|my| |Maldives|mv| |Mali|ml| |Malta|mt| |Mauritius|mu| |Mexico|mx| |Moldova|md| |Mongolia|mn| |Montenegro|me| |Morocco|ma| |Mozambique|mz| |Nepal|np| |Netherlands|nl| |New Caledonia|nc| |New Zealand|nz| |Namibia|na| |Nicaragua|ni| |Nigeria|ng| |Norway|no| |Oman|om| |Pakistan|pk| |Panama|pa| |Paraguay|py| |Peru|pe| |Philippines|ph| |Poland|pl| |Portugal|pt| |Qatar|qa| |Romania|ro| |Russia|ru| |Rwanda|rw| |Saudi Arabia|sa| |Senegal|sn| |Serbia|rs| |Sierra Leone|sl| |Singapore|sg| |Slovakia|sk| |Slovenia|si| |South Africa|za| |South Korea|kr| |Spain|es| |Sri Lanka|lk| |Sudan|sd| |Sweden|se| |Switzerland|ch| |Syria|sy| |Taiwan|tw| |Tajikistan|tj| |Tanzania|tz| |Thailand|th| |Togo|tg| |Trinidad and Tobago|tt| |Tunisia|tn| |Turkey|tr| |Uganda|ug| |Ukraine|ua| |United Arab Emirates|ae| |United Kingdom|gb| |United States|us| |Uruguay|uy| |Uzbekistan|uz| |Venezuela|ve| |Vietnam|vn| |Yemen|ye| |Zambia|zm| |Zimbabwe|zw| #### Residential Proxy |Afghanistan|af| |Albania|al| |Algeria|dz| |Andorra|ad| |Angola|ao| |Antigua and |Argentina|ar| |Armenia|am| |Aruba|aw| |Australia|au| |Austria|at| |Azerbaijan|az| |Bahamas|bs| |Bahrain|bh| |Bangladesh|bd| |Barbados|bb| |Belarus|by| |Belgium|be| |Belize|bz| |Benin|bj| |Bermuda|bm| |Bolivia|bo| |Bosnia and Herzegovina|ba| |Botswana|bw| |Brazil|br| |Brunei Darussalam|bn| |Bulgaria|bg| |Burkina Faso|bf| |Burundi|bi| |Cambodia|kh| |Cameroon|cm| |Canada|ca| |Cape Verde|cv| |Chad|td| |Chile|cl| |China|cn| |Colombia|co| |Congo|cg| |Costa Rica|cr| |Côte d’Ivoire|ci| |Croatia|hr| |Cuba|cu| |Cyprus|cy| |Czech Republic|cz| |Denmark|dk| |Djibouti|dj| |Dominica|dm| |Dominican Republic|do| |Ecuador|ec| |Egypt|eg| |El Salvador|sv| |Equatorial Guinea|gq| |Estonia|ee| |Eswatini|sz| |Ethiopia|et| |Fiji|fj| |Finland|fi| |France|fr| |French Polynesia|pf| |Gabon|ga| |Gambia|gm| |Georgia|ge| |Germany|de| |Ghana|gh| |Greece|gr| |Grenada|gd| |Guatemala|gt| |Guinea|gn| |Guyana|gy| |Haiti|ht| |Honduras|hn| |Hong Kong|hk| |Hungary|hu| |Iceland|is| |India|in| |Indonesia|id| |Iran|ir| |Iraq|iq| |Ireland|ie| |Israel|il| |Italy|it| |Jamaica|jm| |Japan|jp| |Jordan|jo| |Kazakhstan|kz| |Kenya|ke| |Kuwait|kw| |Kyrgyzstan|kg| |Laos|la| |Latvia|lv| |Lebanon|lb| |Lesotho|ls| |Liberia|lr| |Libya|ly| |Lithuania|lt| |Luxembourg|lu| |Macedonia|mk| |Madagascar|mg| |Malawi|mw| |Malaysia|my| |Maldives|mv| |Mali|ml| |Malta|mt| |Mauritania|mr| |Mexico|mx| |Moldova|md| |Mongolia|mn| |Montenegro|me| |Morocco|ma| |Mozambique|mz| |Myanmar|mm| |Namibia|na| |Nepal|np| |Netherlands|nl| |New Caledonia|nc| |New Zealand|nz| |Nicaragua|ni| |Niger|ne| |Nigeria|ng| |Norway|no| |Oman|om| |Pakistan|pk| |Panama|pa| |Papua New Guinea|pg| |Paraguay|py| |Peru|pe| |Philippines|ph| |Poland|pl| |Portugal|pt| |Puerto Rico|pr| |Qatar|qa| |Romania|ro| |Russia|ru| |Rwanda|rw| |Saint Lucia|lc| |Samoa|ws| |San Marino|sm| |Saudi Arabia|sa| |Senegal|sn| |Serbia|rs| |Sierra Leone|sl| |Singapore|sg| |Slovakia|sk| |Slovenia|si| |Somalia|so| |South Africa|za| |South Korea|kr| |South Sudan|ss| |Spain|es| |Sri Lanka|lk| |Sudan|sd| |Suriname|sr| |Sweden|se| |Switzerland|ch| |Syria|sy| |São Tomé and Príncipe|st| |Taiwan|tw| |Tajikistan|tj| |Tanzania|tz| |Thailand|th| |Timor Leste (East Timor)|tl| |Turkey|tr| |Togo|tg| |Trinidad and Tobago|tt| |Tunisia|tn| |Turkmenistan|tm| |Uganda|ug| |Ukraine|ua| |United Kingdom|gb| |United States|us| |Uruguay|uy| |Uzbekistan|uz| |Vanuatu|vu| |Venezuela|ve| |Vietnam|vn| |Yemen|ye| |Zambia|zm| |Zimbabwe|zw| */} # Session Timeout Source: https://docs.anchorbrowser.io/advanced/session-timeout ### Managing Browser Session Lifetime Anchor provides multiple ways to control and terminate browser sessions. In addition to manually stopping sessions via the [stop session API](/api-reference/browser-sessions/end-browser-session), you can configure two types of automatic timeout mechanisms to manage session lifetime effectively. For the full list of available options, view the [interactive api documentation](/api-reference/browser-sessions). ### Timeout Configuration Options The API offers two distinct timeout parameters through the `session.timeout` object to automatically manage browser session termination. #### Idle Timeout The `idle_timeout` parameter automatically terminates sessions after a period of inactivity. This timer starts after the last connection to the browser has disconnected, and any new connection will restart the timer. This includes live view sessions, CDP (Chrome DevTools Protocol) connections, and OS-level control connections. The idle timeout is particularly useful for sessions with unknown length, allowing users to interact with browsers for as long as they need without keeping stale browsers alive unnecessarily. When set to `3` minutes for example, the session will terminate after 3 minutes with no active connections. The default value is `5` minutes, and you can disable automatic termination for idle sessions by setting it to `-1`. #### Maximum Duration The `max_duration` parameter sets a hard limit on total session lifetime. Unlike the idle timeout, this will automatically terminate the session after the specified duration regardless of activity level. This acts as a safety mechanism to ensure sessions don't run indefinitely. The default maximum duration is `180` minutes (3 hours), but you can adjust this based on your needs. Setting `max_duration` to `10` will terminate the session after exactly 10 minutes, whether the browser is actively being used or not. There is no upper limit on how long you can set the maximum duration. ### Implementation Example ```bash curl --request POST \ --url https://api.anchorbrowser.io/v1/sessions \ --header 'Content-Type: application/json' \ --header 'anchor-api-key: your_api_key_here' \ --data '{ "session": { "timeout": { "max_duration": 10, "idle_timeout": 3 } } }' ``` In this example, replace `"your_api_key_here"` with your actual API key. The configuration sets a 10-minute hard session limit with `max_duration`, while `idle_timeout` ensures the session terminates after 3 minutes of no active connections. These two timeout mechanisms work independently, so the session will end when whichever condition is met first. # CrewAI Source: https://docs.anchorbrowser.io/agent-frameworks/crewai AI agents can leverage browser sessions to complete tasks in the web. The ways to use the browser in CrewAI agent platform are: * **As a Flexible Browser Tool**: Enable the CrewAI agent to explore the web freely using a general-purpose browser tool. * **As a Specific-Flow Tool Defined in CrewAI**: Create custom tools by writing CrewAI code to define specific workflows tailored to your needs. * **As a Specific-Flow Tool Defined in Anchor Browser**: Define tools using the Anchor platform, which CrewAI agents can then use through the Official Anchor Tool. ## Quick start - Use Anchor Browser as a flexible browser tool You can connect your CrewAI agent directly to Anchor Browser, allowing it to use browser sessions for various tasks, leveraging the power of browser automation without the need for complex integration code. Below is a quick guide to setting up and using Anchor Browser as a tool for your CrewAI agent. ```python python import crewai from playwright.sync_api import sync_playwright ANCHOR_API_KEY = "YOUR_ANCHOR_API_KEY" # Replace with your actual API key # Register Anchor Browser as a tool in CrewAI class AnchorBrowserTool(crewai.Tool): name = "AnchorBrowser" description = "Use Anchor Browser to perform web-based tasks." def __init__(self): super().__init__() def run(self, command): with sync_playwright() as p: browser = p.chromium.connect_over_cdp( f"wss://connect.anchorbrowser.io?apiKey={ANCHOR_API_KEY}" ) page = browser.new_page() page.goto(command['url']) # Perform specific actions as needed if command.get('action') == 'search': page.fill(command['search_box'], command['search_text']) page.click(command['search_button']) # Extract and return data if needed result = page.content() browser.close() return result # Add AnchorBrowserTool to CrewAI agent my_agent = crewai.Agent(name="Web Agent") my_agent.add_tool(AnchorBrowserTool()) # Use the agent to perform actions on the web result = my_agent.act({ 'tool': 'AnchorBrowser', 'command': { 'url': 'https://example.com', 'action': 'search', 'search_box': 'input[name="q"]', 'search_text': 'Anchor Browser', 'search_button': 'button[type="submit"]' } }) print(result) ``` ```jsx node.js import crewai from 'crewai'; import { chromium } from 'playwright-core'; const ANCHOR_API_KEY = process.env.ANCHOR_API_KEY; // Replace with your actual API key stored in environment variables // Define a custom tool in CrewAI that uses Anchor Browser class AnchorBrowserTool { name = "AnchorBrowser"; description = "Use Anchor Browser to perform web-based tasks."; async run(command) { // Connect to Anchor Browser session const browser = await chromium.connectOverCDP( `wss://connect.anchorbrowser.io?apiKey=${ANCHOR_API_KEY}` ); const page = await browser.newPage(); await page.goto(command.url); // Perform specific actions as needed if (command.action === 'search') { await page.fill(command.search_box, command.search_text); await page.click(command.search_button); } // Extract and return data if needed const result = await page.content(); await browser.close(); return result; } } // Create a CrewAI agent a ``` ## Use Anchor Browser as a specific-flow tool defined in CrewAI CrewAI can integrate closely with Anchor Browser to define tools for particular workflows. For example, if you need a customized process to interact with an authenticated application, you can create that flow as a reusable tool that CrewAI agents can use for automation. Here is an example of creating a specific workflow tool using Anchor Browser that can be utilized by CrewAI to automate targeted tasks. ```python python import crewai from playwright.sync_api import sync_playwright ANCHOR_API_KEY = "YOUR_ANCHOR_API_KEY" # Replace with your actual API key # Register Anchor Browser as a specific application tool in CrewAI class AnchorSpecificTool(crewai.Tool): name = "SpecificAnchorTool" description = "Custom tool for interacting with a specific application." def __init__(self): super().__init__() def run(self, command): with sync_playwright() as p: # Connect to Anchor Browser session browser = p.chromium.connect_over_cdp( f"wss://connect.anchorbrowser.io?apiKey={ANCHOR_API_KEY}" ) page = browser.new_page() page.goto(command['url']) # Perform specific actions based on command if command.get('action') == 'extract': result = page.text_content(command['selector']) browser.close() return result browser.close() # Add custom AnchorBrowserTool to CrewAI agent my_agent = crewai.Agent(name="Web Automation Agent") my_agent.add_tool(AnchorSpecificTool()) # Use the agent to perform a specific task result = my_agent.act({ 'tool': 'SpecificAnchorTool', 'command': { 'url': 'https://example.com', 'action': 'extract', 'selector': '#data' } }) print(result) ``` ```jsx node.js import crewai from 'crewai'; import { chromium } from 'playwright-core'; const ANCHOR_API_KEY = process.env.ANCHOR_API_KEY; // Replace with your actual API key stored in environment variables // Define a custom specific-flow tool in CrewAI that uses Anchor Browser class AnchorSpecificTool { name = "SpecificAnchorTool"; description = "Custom tool for interacting with a specific application."; async run(command) { // Connect to Anchor Browser session const browser = await chromium.connectOverCDP( `wss://connect.anchorbrowser.io?apiKey=${ANCHOR_API_KEY}` ); const page = await browser.newPage(); await page.goto(command.url); // Perform specific actions based on the command if (command.action === 'extract') { const result = await page.textContent(command.selector); await browser.close(); return result; } await browser.close(); } } // Create a CrewAI agent and add the custom specific-flow Anchor Browser tool const agent = new crewai.Agent({ name: "Web Automation Agent" }); const anchorSpecificTool = new AnchorSpecificTool(); agent.addTool(anchorSpecificTool); // Use the tool through the CrewAI agent const result = await agent.act({ tool: 'SpecificAnchorTool', command: { url: 'https://example.com', action: 'extract', selector: '#data' } }); console.log(result); ``` # Custom Integration Source: https://docs.anchorbrowser.io/agent-frameworks/custom-agent-framework Anchor Browser enables integration with custom AI frameworks to empower agents with the ability to navigate and interact with the web effectively. You can leverage browser sessions within your own custom AI framework to automate workflows, explore the web, or interact with web content dynamically. The integration methods for a custom AI framework include: * **As a Flexible Browser Tool**: Utilize Anchor Browser as a general-purpose browser tool that allows your AI agent to freely explore the web and perform dynamic interactions. * **As a Specific-Flow Tool Defined in Your Custom Framework**: Create reusable, custom tools in your AI framework to handle specific workflows or sequences of interactions. * **As a Specific-Flow Tool Defined in Anchor Browser**: Define tools on the Anchor platform and invoke them using your custom AI framework through the Anchor API, allowing your agent to use predefined browser sessions and tools. ## Quick Start - Use Anchor Browser as a Flexible Browser Tool Your custom AI framework can directly integrate with Anchor Browser, allowing your agent to interact with the web dynamically. Below is an example of how you can connect your custom AI framework to Anchor Browser, enabling the agent to perform various tasks. ```python python import requests from playwright.sync_api import sync_playwright ANCHOR_API_KEY = "YOUR_ANCHOR_API_KEY" # Replace with your actual API key # Define a function to use Anchor Browser as a tool for web-based tasks def use_anchor_browser(command): with sync_playwright() as p: # Connect to Anchor Browser session browser = p.chromium.connect_over_cdp( f"wss://connect.anchorbrowser.io?apiKey={ANCHOR_API_KEY}" ) page = browser.new_page() page.goto(command['url']) # Perform specific actions as needed if command.get('action') == 'search': page.fill(command['search_box'], command['search_text']) page.click(command['search_button']) # Extract and return data if needed result = page.content() browser.close() return result # Example usage in your custom AI framework command = { 'url': 'https://example.com', 'action': 'search', 'search_box': 'input[name="q"]', 'search_text': 'Anchor Browser', 'search_button': 'button[type="submit"]' } result = use_anchor_browser(command) print(result) ``` ```jsx node.js import { chromium } from 'playwright-core'; const ANCHOR_API_KEY = process.env.ANCHOR_API_KEY; // Replace with your actual API key stored in environment variables // Define a function to use Anchor Browser as a tool for web-based tasks async function useAnchorBrowser(command) { // Connect to Anchor Browser session const browser = await chromium.connectOverCDP( `wss://connect.anchorbrowser.io?apiKey=${ANCHOR_API_KEY}` ); const page = await browser.newPage(); await page.goto(command.url); // Perform specific actions as needed if (command.action === 'search') { await page.fill(command.search_box, command.search_text); await page.click(command.search_button); } // Extract and return data if needed const result = await page.content(); await browser.close(); return result; } // Example usage in your custom AI framework const command = { url: 'https://example.com', action: 'search', search_box: 'input[name="q"]', search_text: 'Anchor Browser', search_button: 'button[type="submit"]' }; const result = await useAnchorBrowser(command); console.log(result); ``` ## Use Anchor Browser as a Specific-Flow Tool Defined in a Custom Framework Anchor Browser can also be integrated into your custom AI framework to create specific workflow tools. These tools can handle specialized tasks that your agent needs to perform repeatedly, providing consistency and reducing the need for writing duplicate code. Here is an example of creating a specific tool using Anchor Browser that can be utilized by your custom AI framework for automating targeted tasks. ```python python import requests from playwright.sync_api import sync_playwright ANCHOR_API_KEY = "YOUR_ANCHOR_API_KEY" # Replace with your actual API key # Define a custom tool for interacting with a specific web application def specific_anchor_tool(command): with sync_playwright() as p: # Connect to Anchor Browser session browser = p.chromium.connect_over_cdp( f"wss://connect.anchorbrowser.io?apiKey={ANCHOR_API_KEY}" ) page = browser.new_page() page.goto(command['url']) # Perform specific actions based on the command if command.get('action') == 'extract': result = page.text_content(command['selector']) browser.close() return result browser.close() # Example usage in your custom AI framework command = { 'url': 'https://example.com', 'action': 'extract', 'selector': '#data' } result = specific_anchor_tool(command) print(result) ``` ```jsx node.js import { chromium } from 'playwright-core'; const ANCHOR_API_KEY = process.env.ANCHOR_API_KEY; // Replace with your actual API key stored in environment variables // Define a custom specific-flow tool for interacting with a specific web application async function specificAnchorTool(command) { // Connect to Anchor Browser session const browser = await chromium.connectOverCDP( `wss://connect.anchorbrowser.io?apiKey=${ANCHOR_API_KEY}` ); const page = await browser.newPage(); await page.goto(command.url); // Perform specific actions based on the command if (command.action === 'extract') { const result = await page.textContent(command.selector); await browser.close(); return result; } await browser.close(); } // Example usage in your custom AI framework const command = { url: 'https://example.com', action: 'extract', selector: '#data' }; const result = await specificAnchorTool(command); console.log(result); ``` # Langchain Source: https://docs.anchorbrowser.io/agent-frameworks/langchain AI agents can leverage browser sessions to complete tasks on the web using Langchain, a framework that provides easy integration for AI-driven workflows. The ways to use Anchor Browser in the Langchain platform are: * **As a Flexible Browser Tool**: Enable the Langchain agent to explore the web freely using a general-purpose browser tool. * **As a Specific-Flow Tool Defined in Langchain**: Create custom tools by writing Langchain code to define specific workflows tailored to your needs. * **As a Specific-Flow Tool Defined in Anchor Browser**: Define tools using the Anchor platform, which Langchain agents can then use through the Official Anchor Tool. ## Quick Start - Use Anchor Browser as a Flexible Browser Tool You can connect your Langchain agent directly to Anchor Browser, allowing it to use browser sessions for various tasks, leveraging the power of browser automation without the need for complex integration code. Below is a quick guide to setting up and using Anchor Browser as a tool for your Langchain agent. ```python python from langchain.tools import Tool from playwright.sync_api import sync_playwright ANCHOR_API_KEY = "YOUR_ANCHOR_API_KEY" # Replace with your actual API key # Register Anchor Browser as a tool in Langchain class AnchorBrowserTool(Tool): name = "AnchorBrowser" description = "Use Anchor Browser to perform web-based tasks." def __init__(self): super().__init__() def _run(self, command): with sync_playwright() as p: # Connect to Anchor Browser session browser = p.chromium.connect_over_cdp( f"wss://connect.anchorbrowser.io?apiKey={ANCHOR_API_KEY}" ) page = browser.new_page() page.goto(command['url']) # Perform specific actions as needed if command.get('action') == 'search': page.fill(command['search_box'], command['search_text']) page.click(command['search_button']) # Extract and return data if needed result = page.content() browser.close() return result # Use the AnchorBrowserTool in a Langchain agent my_agent = LangchainAgent() my_agent.add_tool(AnchorBrowserTool()) # Use the agent to perform actions on the web result = my_agent.run({ 'tool': 'AnchorBrowser', 'command': { 'url': 'https://example.com', 'action': 'search', 'search_box': 'input[name="q"]', 'search_text': 'Anchor Browser', 'search_button': 'button[type="submit"]' } }) print(result) ``` ```jsx node.js import { Tool } from 'langchain'; import { chromium } from 'playwright-core'; const ANCHOR_API_KEY = process.env.ANCHOR_API_KEY; // Replace with your actual API key stored in environment variables // Define a custom tool in Langchain that uses Anchor Browser class AnchorBrowserTool extends Tool { constructor() { super(); this.name = "AnchorBrowser"; this.description = "Use Anchor Browser to perform web-based tasks."; } async _run(command) { // Connect to Anchor Browser session const browser = await chromium.connectOverCDP( `wss://connect.anchorbrowser.io?apiKey=${ANCHOR_API_KEY}` ); const page = await browser.newPage(); await page.goto(command.url); // Perform specific actions as needed if (command.action === 'search') { await page.fill(command.search_box, command.search_text); await page.click(command.search_button); } // Extract and return data if needed const result = await page.content(); await browser.close(); return result; } } // Use the AnchorBrowserTool in a Langchain agent const agent = new LangchainAgent(); agent.addTool(new AnchorBrowserTool()); // Use the agent to perform actions on the web const result = await agent.run({ tool: 'AnchorBrowser', command: { url: 'https://example.com', action: 'search', search_box: 'input[name="q"]', search_text: 'Anchor Browser', search_button: 'button[type="submit"]' } }); console.log(result); ``` ## Use Anchor Browser as a Specific-Flow Tool Defined in Langchain Langchain can integrate closely with Anchor Browser to define tools for particular workflows. For example, if you need a customized process to interact with an authenticated application, you can create that flow as a reusable tool that Langchain agents can use for automation. Here is an example of creating a specific workflow tool using Anchor Browser that can be utilized by Langchain to automate targeted tasks. ```python python from langchain.tools import Tool from playwright.sync_api import sync_playwright ANCHOR_API_KEY = "YOUR_ANCHOR_API_KEY" # Replace with your actual API key # Register Anchor Browser as a specific application tool in Langchain class AnchorSpecificTool(Tool): name = "SpecificAnchorTool" description = "Custom tool for interacting with a specific application." def __init__(self): super().__init__() def _run(self, command): with sync_playwright() as p: # Connect to Anchor Browser session browser = p.chromium.connect_over_cdp( f"wss://connect.anchorbrowser.io?apiKey={ANCHOR_API_KEY}" ) page = browser.new_page() page.goto(command['url']) # Perform specific actions based on command if command.get('action') == 'extract': result = page.text_content(command['selector']) browser.close() return result browser.close() # Use the AnchorSpecificTool in a Langchain agent my_agent = LangchainAgent() my_agent.add_tool(AnchorSpecificTool()) # Use the agent to perform a specific task result = my_agent.run({ 'tool': 'SpecificAnchorTool', 'command': { 'url': 'https://example.com', 'action': 'extract', 'selector': '#data' } }) print(result) ``` ```jsx node.js import { Tool } from 'langchain'; import { chromium } from 'playwright-core'; const ANCHOR_API_KEY = process.env.ANCHOR_API_KEY; // Replace with your actual API key stored in environment variables // Define a custom specific-flow tool in Langchain that uses Anchor Browser class AnchorSpecificTool extends Tool { constructor() { super(); this.name = "SpecificAnchorTool"; this.description = "Custom tool for interacting with a specific application."; } async _run(command) { // Connect to Anchor Browser session const browser = await chromium.connectOverCDP( `wss://connect.anchorbrowser.io?apiKey=${ANCHOR_API_KEY}` ); const page = await browser.newPage(); await page.goto(command.url); // Perform specific actions based on the command if (command.action === 'extract') { const result = await page.textContent(command.selector); await browser.close(); return result; } await browser.close(); } } // Use the AnchorSpecificTool in a Langchain agent const agent = new LangchainAgent(); agent.addTool(new AnchorSpecificTool()); // Use the tool through the Langchain agent const result = await agent.run({ tool: 'SpecificAnchorTool', command: { url: 'https://example.com', action: 'extract', selector: '#data' } }); console.log(result); ``` # Agentic File Usage Source: https://docs.anchorbrowser.io/agentic-browser-control/agentic-file-usage Upload ZIP files to browser sessions for AI agents to use **Compatibility Note**: Only works with the `browser-use` agent framework. Not supported with OpenAI CUA. ## Quick Start Upload a ZIP file containing resources that your AI agent can use to complete tasks. The ZIP file is automatically extracted and made available to the agent. ## Example: Upload ZIP File ```javascript import { chromium } from 'playwright'; // 1. Create a test ZIP file with content const testContent = 'Hello from Anchor!\nThis is a test file for the agent.'; const blob = new Blob([testContent], { type: 'text/plain' }); const formData = new FormData(); formData.append('file', blob, 'test-data.zip'); // 2. Upload to browser session const response = await fetch(`https://api.anchorbrowser.io/v1/sessions/${sessionId}/agent/files`, { method: 'POST', headers: { 'anchor-api-key': apiKey }, body: formData }); const result = await response.json(); console.log('Upload result:', result); // 3. Connect to the browser session and use uploaded files with AI agent const browser = await chromium.connectOverCDP( `wss://connect.anchorbrowser.io?apiKey=${apiKey}&sessionId=${sessionId}` ); const context = browser.contexts()[0]; const page = context.pages()[0]; // Navigate to a website where you want to use the uploaded files await page.goto('https://v0-download-and-upload-text.vercel.app/'); // Use AI agent to interact with the page using uploaded files const ai = context.serviceWorkers()[0]; const aiResult = await ai.evaluate("upload a file to the server"); console.log('AI agent result:', aiResult); ``` That's it! The agent can now access all uploaded files and use them to complete web tasks. # AI Task Completion Source: https://docs.anchorbrowser.io/agentic-browser-control/ai-task-completion Anchor Browser delivers a state-of-the-art 89% Score on the industry-standard benchmark WebVoyager, leveraging browser-use as a core component of the automation capability.