Skip to main content

MastraBrowser class

The MastraBrowser class is the abstract base class for browser automation providers. It defines the common interface for launching browsers, managing thread isolation, streaming screencasts, and handling input events.

You don't instantiate MastraBrowser directly. Instead, use a provider implementation:

Usage example
Direct link to Usage example

src/mastra/agents/index.ts
import { Agent } from '@mastra/core/agent'
import { AgentBrowser } from '@mastra/agent-browser'

const browser = new AgentBrowser({
headless: true,
viewport: { width: 1280, height: 720 },
scope: 'thread',
})

export const browserAgent = new Agent({
name: 'browser-agent',
instructions: 'You can browse the web to find information.',
model: 'openai/gpt-5.4',
browser,
})

Constructor parameters
Direct link to Constructor parameters

headless?:

boolean
= true
Whether to run the browser in headless mode (no visible UI).

viewport?:

{ width: number; height: number }
= { width: 1280, height: 720 }
Browser viewport dimensions. Controls the size of the browser window.

timeout?:

number
= 10000
Default timeout in milliseconds for browser operations.

cdpUrl?:

string | (() => string | Promise<string>)
CDP WebSocket URL, HTTP endpoint, or sync/async provider function. When provided, connects to an existing browser instead of launching a new one. HTTP endpoints are resolved to WebSocket internally. Can't be used with scope: 'thread' (automatically uses shared scope).

scope?:

'shared' | 'thread'
= 'thread' (or 'shared' when cdpUrl is provided)
Browser instance scope across threads. 'shared' means all threads share a single browser instance. 'thread' means each thread gets its own browser instance (full isolation).

onLaunch?:

(args: { browser: MastraBrowser }) => void | Promise<void>
Callback invoked after the browser reaches 'ready' status.

onClose?:

(args: { browser: MastraBrowser }) => void | Promise<void>
Callback invoked before the browser is closed.

screencast?:

ScreencastOptions
Configuration for streaming browser frames.
ScreencastOptions

format?:

'jpeg' | 'png'
Image format for screencast frames.

quality?:

number
Image quality (1-100). Only applies to JPEG format.

maxWidth?:

number
Maximum width for screencast frames.

maxHeight?:

number
Maximum height for screencast frames.

everyNthFrame?:

number
Capture every Nth frame to reduce bandwidth.

Properties
Direct link to Properties

The following properties (id, name, provider) are abstract and must be defined by concrete provider implementations:

id:

string
Unique identifier for this browser instance. Abstract - defined by provider.

name:

string
Human-readable name of the browser provider (e.g., 'AgentBrowser', 'StagehandBrowser'). Abstract - defined by provider.

provider:

string
Provider identifier (e.g., 'vercel-labs/agent-browser', 'browserbase/stagehand'). Abstract - defined by provider.

headless:

boolean
Whether the browser is running in headless mode.

status:

BrowserStatus
Current browser status: 'pending', 'launching', 'ready', 'error', 'closing', or 'closed'.

Methods
Direct link to Methods

Lifecycle
Direct link to Lifecycle

ensureReady()
Direct link to ensureready

Ensures the browser is launched and ready for use. Automatically called before tool execution. Implemented in the base class.

await browser.ensureReady()

close()
Direct link to close

Closes the browser and cleans up all resources. Implemented in the base class with race-condition-safe handling.

await browser.close()

isBrowserRunning()
Direct link to isbrowserrunning

Checks if the browser is currently running.

const isRunning = browser.isBrowserRunning()

Returns: boolean

Thread management
Direct link to Thread management

setCurrentThread(threadId)
Direct link to setcurrentthreadthreadid

Sets the current thread ID for browser operations. Used internally by the agent runtime.

browser.setCurrentThread('thread-123')

getCurrentThread()
Direct link to getcurrentthread

Gets the current thread ID.

const threadId = browser.getCurrentThread()

Returns: string

hasThreadSession(threadId)
Direct link to hasthreadsessionthreadid

Checks if a thread has an active browser session.

const hasSession = browser.hasThreadSession('thread-123')

Returns: boolean

closeThreadSession(threadId)
Direct link to closethreadsessionthreadid

Closes a specific thread's browser session. For 'thread' scope, this closes that thread's browser instance. For 'shared' scope, this clears the thread's state.

await browser.closeThreadSession('thread-123')

Tools
Direct link to Tools

getTools()
Direct link to gettools

Returns the browser tools for use with agents. Each provider returns different tools based on its paradigm.

const tools = browser.getTools()

Returns: Record<string, Tool>

Screencast
Direct link to Screencast

startScreencast(options?, threadId?)
Direct link to startscreencastoptions-threadid

Starts streaming browser frames. Returns a ScreencastStream that emits frame events.

const stream = await browser.startScreencast({ format: 'jpeg', quality: 80 }, 'thread-123')

stream.on('frame', frame => {
console.log('Frame received:', frame.data.length, 'bytes')
})

stream.on('stop', reason => {
console.log('Screencast stopped:', reason)
})

Returns: Promise<ScreencastStream>

Input injection
Direct link to Input injection

injectMouseEvent(params, threadId?)
Direct link to injectmouseeventparams-threadid

Injects a mouse event into the browser. Used by Studio for live interaction.

await browser.injectMouseEvent({
type: 'mousePressed',
x: 100,
y: 200,
button: 'left',
clickCount: 1,
})

injectKeyboardEvent(params, threadId?)
Direct link to injectkeyboardeventparams-threadid

Injects a keyboard event into the browser. Used by Studio for live interaction.

await browser.injectKeyboardEvent({
type: 'keyDown',
key: 'Enter',
code: 'Enter',
})

State
Direct link to State

getState(threadId?)
Direct link to getstatethreadid

Gets the current browser state including URL and tabs.

const state = await browser.getState('thread-123')
console.log('Current URL:', state.currentUrl)
console.log('Tabs:', state.tabs)

Returns: Promise<BrowserState>

interface BrowserState {
currentUrl: string | null
tabs: BrowserTabState[]
activeTabIndex: number
}

interface BrowserTabState {
id: string
url: string
title: string
}

getCurrentUrl(threadId?)
Direct link to getcurrenturlthreadid

Gets the current page URL.

const url = await browser.getCurrentUrl()

Returns: Promise<string | null>

Browser scope
Direct link to Browser scope

The scope option controls how browser instances are shared across conversation threads:

ScopeDescriptionUse case
'shared'All threads share a single browser instanceCost-efficient for non-conflicting tasks
'thread'Each thread gets its own browser instanceFull isolation for concurrent users
// Shared browser for all threads
const sharedBrowser = new AgentBrowser({
scope: 'shared',
})

// Isolated browser per thread
const isolatedBrowser = new AgentBrowser({
scope: 'thread',
})

When using cdpUrl to connect to an external browser, the scope automatically falls back to 'shared' since you can't spawn new browser instances.

Cloud browser providers
Direct link to Cloud browser providers

Connect to cloud browser services using the cdpUrl option:

// Static CDP URL
const browser = new AgentBrowser({
cdpUrl: 'wss://browser.example.com/ws',
})

// Dynamic CDP URL (e.g., session-based)
const browser = new AgentBrowser({
cdpUrl: async () => {
const session = await createBrowserSession()
return session.wsUrl
},
})