API reference
Use this page to look up shared Agent APIs and platform-specific constructors, options, actions, and helper methods.
This page documents API contracts. For installation, end-to-end workflows, and troubleshooting, follow the linked guides. Platform Agents inherit the Shared Agent APIs unless a platform section documents a difference.
This page retains a small number of complete examples to show how related APIs work together. For end-to-end integration and best practices, follow the guide links in each platform section.
Shared Agent APIs
Agent construction and options
Midscene provides agents for different automation environments. Each constructor accepts a target page or device and the shared options described below, including reporting, caching, AI configuration, and hooks. Platform-specific sections document additional options such as browser navigation controls and Android adb settings:
- In Puppeteer, use PuppeteerAgent
- In Playwright, use PlaywrightAgent
- In Bridge mode, use AgentOverChromeBridge
- On Android, use Android API reference
- On iOS, use iOS API reference
- For GUI agents integrating with your own interface, refer to Custom Interface Agent
Parameters
All agents share these base options:
-
generateReport: boolean— Whether Midscene generates a report file. Default:true. -
persistExecutionDump: boolean— Whether Midscene writes a JSON dump for each execution alongside the report. Default:false. This option requiresgenerateReportto betrue. -
reportFileName: string— Report output name. By default, Midscene generates the name. Its exact meaning depends onoutputFormat:single-html(default) — Midscene treats the value as a file name and writes<reportFileName>.htmlundermidscene_run/report/. If the name already ends in.html, Midscene preserves it.html-and-external-assets— Midscene treats the value as a directory name and writesindex.htmland related assets undermidscene_run/report/<reportFileName>/.
-
autoPrintReportMsg: boolean— Whether Midscene prints report messages. Default:true. -
cache?: false | { id: string; strategy?: 'read-only' | 'read-write' | 'write-only'; cacheDir?: string }— Cache configuration:false— Disable the cache.id— Required cache ID.strategy— Cache strategy. Default:'read-write'.cacheDir— Cache directory. When set, Midscene writes cache files here instead of<MIDSCENE_RUN_DIR>/cache. Relative paths are resolved from the current working directory, not fromMIDSCENE_RUN_DIR. This lets you use separate cache, log, and report directories.
-
cacheId: string | undefined(deprecated) — Legacy cache ID for backward compatibility. Prefercache.id. -
aiActContext: string— Background context sent to the AI model withagent.aiAct()calls. For example:'Close the cookie consent dialog first if it exists.'Default:undefined. This option was previously namedaiActionContext; the legacy name remains supported. -
modelConfig: Record<string, string | number>— Model configuration for this Agent. When provided, it replaces model-related system environment variables for this Agent. See the detailed configuration section below. -
replanningCycleLimit: number— Maximum number ofaiActreplanning cycles. Default:20for standard models,40for UI-TARS models, and100for AutoGLM models. Prefer this Agent option;MIDSCENE_REPLANNING_CYCLE_LIMITremains available only for backward compatibility. -
waitAfterAction: number— Delay in milliseconds after each action. This gives the UI time to settle before the next action. Default:300. -
useDeviceTime: boolean— Whether task timestamps use the target device's local time. The target interface must implementgetDeviceLocalTimeString; otherwise, Midscene logs a warning and uses the runtime system time. Default:false. -
onTaskStartTip: (tip: string) => void | Promise<void>— Optional hook called before each task begins. It receives a human-readable task summary. Default:undefined. -
createOpenAIClient: (openai, options) => Promise<OpenAI | undefined>— Optional factory for wrapping the OpenAI client with observability or custom middleware. See the detailed example below. -
onLLMUsage: (usage: AIUsageInfo) => void— Optional callback invoked once for each LLM call when usage data becomes available. Use it for real-time cost and usage tracking. -
outputFormat: 'single-html' | 'html-and-external-assets'— Report output format.'single-html'embeds all screenshots as base64 in one HTML file and usesreportFileNameas the file name.'html-and-external-assets'saves screenshots as separate PNG files and usesreportFileNameas the output directory. Default:'single-html'.Reports created with
'html-and-external-assets'must be served over HTTP; they cannot be opened through thefile://protocol because browsers block the relative asset requests. For local testing, open the report directory and run one of these commands:- Using Node.js:
npx serve - Using Python:
python -m http.serverorpython3 -m http.serverThen access the report viahttp://localhost:3000(or the port shown in the terminal).
- Using Node.js:
-
screenshotShrinkFactor: number— Factor used to reduce screenshot dimensions before sending them to the AI model. Default:1, which preserves the original size. A value of2halves both dimensions and reduces the image area to one quarter. Choose a value that balances image clarity and token usage.- On mobile devices,
2often reduces token usage while preserving enough detail. Values above3may make screenshots too blurry for reliable model interpretation. - For browser automation, prefer Puppeteer or Playwright's
deviceScaleFactorwhen possible. KeepscreenshotShrinkFactorlow for highly detailed pages.
- On mobile devices,
Difference between screenshotShrinkFactor and deviceScaleFactor:
-
screenshotShrinkFactoris a Midscene option that reduces a screenshot after capture. It can lower token usage and model latency, but excessive reduction can obscure important details. -
deviceScaleFactoris a Puppeteer and Playwright option that controls how many physical pixels render each CSS pixel. It therefore affects the original screenshot dimensions. A mismatch with the actual display scale can cause flickering in headed browsers.
Can they be used together?
- For browser automation, using both options usually provides little benefit. Prefer
deviceScaleFactorto control the original screenshot size.- One exception: when you configure
deviceScaleFactorto avoid browser flickering, but still do not want to send an oversized screenshot to the model. In that case, you can also usescreenshotShrinkFactorto compress the image before model consumption.
- One exception: when you configure
- On mobile and other non-web platforms,
deviceScaleFactoris unavailable. UsescreenshotShrinkFactorto reduce the screenshot sent to the model.
The device CLIs expose the same Agent behavior options for individual calls. Convert camelCase option names to kebab-case flags; for example, waitAfterAction becomes --wait-after-action. See Skills for platform-specific CLI entry points.
Custom model configuration
Use modelConfig: Record<string, string | number> to configure models directly in code instead of environment variables.
If
modelConfigis provided at agent initialization, all system environment variables for model config are ignored. Only the values in this object are used. The supported keys and values are listed in Model configuration. See Model strategy for guidance on choosing models.
Custom OpenAI client
createOpenAIClient: (openai, options) => Promise<OpenAI | undefined> lets you wrap the OpenAI client to integrate observability tools such as LangSmith and Langfuse, or to apply custom middleware.
Parameters
openai: OpenAI— Base OpenAI client created by Midscene with the configured API Key, base URL, proxy, and other settings.options: Record<string, unknown>— OpenAI initialization options, including:baseURL?: string— API endpoint URL.apiKey?: string— API Key.dangerouslyAllowBrowser: boolean— Alwaystruein Midscene.- Other OpenAI initialization options.
Return value
- Returns the wrapped OpenAI client, or
undefinedto use the original client.
Planning and interaction
Below are the main APIs available for the various Agents in Midscene. agent.ai() plans and executes a sequence of actions, while instant-action methods perform a specified action after locating its target.
aiAct() or ai()
This method allows you to perform a series of UI actions described in natural language. Midscene automatically plans the steps and executes them.
This method was previously named aiAction() in earlier versions. The current version supports both names for backward compatibility. We recommend using the new aiAct() method for code consistency.
- Type
-
Parameters:
prompt: string— A natural language description of the UI steps.options?: object— Optional configuration:cacheable?: boolean— Whether this call can use the cache. Default:true.deepThink?: 'unset' | true | false— Controls the planning implementation used by Midscene whenaiActperforms planning. When enabled,aiActfocuses more on task decomposition and separates task planning from UI element locating into different model calls. For compatibility,'unset'is accepted and treated the same asfalse. Learn more about deepThink.deepLocate?: boolean— Whether to enable Deep Locate. Default:false.fileChooserAccept?: string | string[]— When a file chooser pops up, specify the file path(s) to accept. Can be a single file path or an array of paths. Only available in web pages (Playwright, Puppeteer, or Chrome extension Bridge mode).- Note: If the file input does not support multiple files (no
multipleattribute) but multiple files are provided, an error will be thrown. - Note: If a file chooser is triggered but no
fileChooserAcceptparameter is provided, the file chooser will be ignored and the page can continue to operate normally. - Note: Chrome extension Bridge mode does not support directory upload inputs (
webkitdirectory/directory). Use Playwright for directory uploads.
- Note: If the file input does not support multiple files (no
abortSignal?: AbortSignal— Signal used to cancel theaiActcall. When aborted, Midscene stops the planning loop and throws an error. Use it to implement timeouts or user-initiated cancellation.
-
Return value:
- Returns the output text produced by the completed plan, or
undefinedwhen the plan does not produce output. If execution fails, an error is thrown.
- Returns the output text produced by the completed plan, or
-
Examples:
Midscene uses an AI model to split the instruction into a sequence of steps, then executes those steps in order. If it cannot complete an action, it throws an error.
For optimal results, please provide clear and detailed instructions for agent.aiAct().
Related documentation:
aiTap()
Tap an element.
- Type
-
Parameters:
locate: string | object— A natural language description of the element to tap, or prompting with images.options?: object— Optional configuration:deepLocate?: boolean— Whether to enable Deep Locate. The deprecateddeepThinkname remains supported. Default:false.xpath?: string— XPath for the target element. Midscene tries the XPath before consulting the cache or AI model. Default:undefined.cacheable?: boolean— Whether this call can use the cache. Default:true.fileChooserAccept?: string | string[]— When a file chooser pops up, specify the file path(s) to accept. Can be a single file path or an array of paths. Only available in web pages (Playwright, Puppeteer, or Chrome extension Bridge mode).- Note: If the file input does not support multiple files (no
multipleattribute) but multiple files are provided, an error will be thrown. - Note: If a file chooser is triggered but no
fileChooserAcceptparameter is provided, the file chooser will be ignored and the page can continue to operate normally. - Note: Chrome extension Bridge mode does not support directory upload inputs (
webkitdirectory/directory). Use Playwright for directory uploads.
- Note: If the file input does not support multiple files (no
-
Return value:
Promise<void>.
-
Examples:
aiHover()
Available on web pages and desktop (
@midscene/computer). Not available on mobile devices (Android, iOS, or HarmonyOS).
Move the pointer over an element.
- Type
-
Parameters:
locate: string | object— A natural language description of the element to hover over, or prompting with images.options?: object— Optional configuration:deepLocate?: boolean— Whether to enable Deep Locate. The deprecateddeepThinkname remains supported. Default:false.xpath?: string— XPath for the target element. Midscene tries the XPath before consulting the cache or AI model. Default:undefined.cacheable?: boolean— Whether this call can use the cache. Default:true.
-
Return value:
Promise<void>.
-
Examples:
aiInput()
Enter text into an input field.
- Type
-
Parameters:
Recommended usage:
locate: string | object— A natural language description of the target input field, or prompting with images.opt: object— Configuration:value: string | number— Required. Text to enter.- When
modeis'replace': The text will replace all existing content in the input field. - When
modeis'typeOnly': The text will be typed directly without clearing the field first. - When
modeis'clear': The text is ignored and the input field will be cleared.
- When
deepLocate?: boolean— Whether to enable Deep Locate. The deprecateddeepThinkname remains supported. Default:false.xpath?: string— XPath for the target element. Midscene tries the XPath before consulting the cache or AI model. Default:undefined.cacheable?: boolean— Whether this call can use the cache. Default:true.autoDismissKeyboard?: boolean— Whether to dismiss the on-screen keyboard after entering text. Available only on Android, iOS, and HarmonyOS. Default:true.keyboardTypeDelay?: number— Delay in milliseconds between keystrokes. When set, Midscene enters one character at a time. Use this option when an input field drops characters during fast input.mode?: 'replace' | 'clear' | 'typeOnly'— Input mode. Default:'replace'.'replace': Clear the input field first, then input the text.'typeOnly': Type the value directly without clearing the field first.'clear': Clear the input field without entering new text.
Backward-compatible usage (deprecated but still supported):
value: string | number— The text content to input.locate: string | object— A natural language description of the element, or prompting with images.options?: object— Optional configuration. The type is the same as theopttype in the recommended usage.
-
Return value:
Promise<void>.
-
Examples:
The recommended signature places the locate prompt first. The legacy signature aiInput(value, locate, options) remains supported, but new code should use the recommended signature.
aiClearInput()
Clear the content of an input field. Useful as a standalone step before typing, or when you need to remove existing text without immediately inputting a new value.
- Type
-
Parameters:
locate: string | object— A natural language description of the input field to clear, or prompting with images.opt?: object— Optional configuration:deepLocate?: boolean— Whether to enable Deep Locate. Default:false.xpath?: string— XPath for the target element. Default:undefined.cacheable?: boolean— Whether this call can use the cache. Default:true.
-
Return value:
Promise<void>.
-
Examples:
aiClearInput vs aiInput
aiInput(locate, { value: '...' }) already clears the field by default (via mode: 'replace'). Reach for aiClearInput when you need clearing as an independent step — for example, to test empty-state validation, or when you want to control clearing and typing as separate actions.
aiKeyboardPress()
Press a keyboard key.
- Type
-
Parameters:
Recommended usage:
locate: string | object— A natural language description of the element to press the key on, or prompting with images.opt: object— Configuration:keyName: string— Required. Keyboard key to press, such as'Enter','Tab', or'Escape'. Key combinations are not supported. See the complete list of supported key names.deepLocate?: boolean— Whether to enable Deep Locate. The deprecateddeepThinkname remains supported. Default:false.xpath?: string— XPath for the target element. Midscene tries the XPath before consulting the cache or AI model. Default:undefined.cacheable?: boolean— Whether this call can use the cache. Default:true.
Backward-compatible usage (deprecated but still supported):
key: string— Keyboard key to press, such as'Enter','Tab', or'Escape'. Key combinations are not supported.locate?: string | object— Optional natural-language description of the element, or prompting with images.options?: object— Optional configuration. The type is the same as theopttype in the recommended usage.
-
Return value:
Promise<void>.
-
Examples:
The recommended signature places the locate prompt first. The legacy signature aiKeyboardPress(key, locate, options) remains supported, but new code should use the recommended signature.
aiScroll()
Scroll a page or an element.
- Type
-
Parameters:
Recommended usage:
locate: string | object | undefined— A natural language description of the scroll target, or prompting with images. When omitted, Midscene scrolls at the current pointer position.opt: object— Configuration:scrollType?: 'singleAction' | 'scrollToBottom' | 'scrollToTop' | 'scrollToRight' | 'scrollToLeft'— Scroll behavior. Default:'singleAction'.direction?: 'down' | 'up' | 'right' | 'left'— Direction of content movement. Used only whenscrollTypeis'singleAction'. For example,'down'reveals content below the current viewport. Default:'down'.distance?: number | null— Scroll distance in pixels. Usenullto let Midscene choose the distance.deepLocate?: boolean— Whether to enable Deep Locate. The deprecateddeepThinkname remains supported. Default:false.xpath?: string— XPath for the target element. Midscene tries the XPath before consulting the cache or AI model. Default:undefined.cacheable?: boolean— Whether this call can use the cache. Default:true.
Backward-compatible usage (deprecated but still supported):
scrollParam: PlanningActionParamScroll— Legacy object containingscrollType,direction, anddistance.locate?: string | object— Optional natural-language description of the element, or prompting with images.options?: object— Optional configuration. The type is the same as theopttype in the recommended usage.
-
Return value:
Promise<void>.
-
Examples:
The recommended signature places the locate prompt first. The legacy signature aiScroll(scrollParam, locate, options) remains supported, but new code should use the recommended signature.
aiPinch()
Perform a two-finger pinch gesture to zoom in or out. This method supports Android, iOS, and Chromium-based web browsers.
- Type
-
Parameters:
locate: string | object | undefined— A natural-language description of the element to pinch, or prompting with images. When omitted, Midscene pinches at the center of the screen.opt: object— Configuration:direction: 'in' | 'out'— Required. Use'in'to pinch the fingers together and zoom out. Use'out'to spread them apart and zoom in.distance?: number— Distance each finger moves in pixels. Default: one quarter of the shorter screen dimension.duration?: number— Gesture duration in milliseconds. Default:500.deepLocate?: boolean— Whether to enable Deep Locate. Default:false.xpath?: string— XPath for the target element. Default:undefined.cacheable?: boolean— Whether this call can use the cache. Default:true.
-
Return value:
Promise<void>.
-
Examples:
- Android — Implemented via yadb
-pinchcommand. - iOS — Implemented via W3C Actions API with dual touch pointers.
- Web — Implemented through CDP touch events. Puppeteer and Playwright require
enableTouchEventsInActionSpace: true; Playwright support is limited to Chromium-based browsers. - HarmonyOS — Not supported. The
uitestframework does not provide multi-touch APIs.
aiLongPress()
Long-press (or click-and-hold) an element. Useful for opening context menus, selecting items, or triggering long-press gestures.
- Type
-
Parameters:
locate: string | object— A natural language description of the element to long-press on, or prompting with images.opt?: object— Optional configuration:duration?: number— How long to hold the press, in milliseconds. Defaults: Android2000, iOS1000, and web500. HarmonyOS uses the system long-click duration and ignores this option.deepLocate?: boolean— Whether to enable Deep Locate. Default:false.xpath?: string— XPath for the target element. Default:undefined.cacheable?: boolean— Whether this call can use the cache. Default:true.
-
Return value:
Promise<void>.
-
Examples:
- Android, iOS, HarmonyOS, Web (Chromium-based browsers via touch events). On HarmonyOS the
durationoption is ignored because the underlyinguitestAPI does not expose a custom hold time.
aiDoubleClick()
Double-click on an element.
- Type
-
Parameters:
locate: string | object— A natural language description of the element to double-click on, or prompting with images.options?: object— Optional configuration:deepLocate?: boolean— Whether to enable Deep Locate. The deprecateddeepThinkname remains supported. Default:false.xpath?: string— XPath for the target element. Midscene tries the XPath before consulting the cache or AI model. Default:undefined.cacheable?: boolean— Whether this call can use the cache. Default:true.
-
Return value:
Promise<void>.
-
Examples:
aiRightClick()
Available on web pages and desktop (
@midscene/computer). Not available on mobile devices (Android, iOS, or HarmonyOS).
Right-click an element. Midscene cannot interact with the browser's native context menu after the click. Use this method for elements that handle their own contextmenu events.
- Type
-
Parameters:
locate: string | object— A natural language description of the element to right-click on, or prompting with images.options?: object— Optional configuration:deepLocate?: boolean— Whether to enable Deep Locate. The deprecateddeepThinkname remains supported. Default:false.xpath?: string— XPath for the target element. Midscene tries the XPath before consulting the cache or AI model. Default:undefined.cacheable?: boolean— Whether this call can use the cache. Default:true.
-
Return value:
Promise<void>.
-
Examples:
Extraction, location, and assertions
aiAsk()
Ask the AI model a question about the current page. The method returns the model's answer as a string.
aiAsk() is fully equivalent to aiString().
- Type
-
Parameters:
prompt: string | object— A natural language description of the question, or prompting with images.options?: object— Optional configuration:domIncluded?: boolean | 'visible-only'— Whether to include simplified DOM data, which can expose attributes such as image URLs. Use'visible-only'to include only visible elements. Default:false.screenshotIncluded?: boolean— Whether to include a screenshot. Default:true.
-
Return value:
- Returns a Promise that resolves to the model's answer.
-
Examples:
Use aiQuery when you need structured data instead of a string.
aiQuery()
Extract structured data from the current page. Describe the expected shape in dataDemand, and Midscene returns a matching value.
- Type
-
Parameters:
dataDemand: string | object— A description of the expected data and its return format.options?: object— Optional configuration:domIncluded?: boolean | 'visible-only'— Whether to include simplified DOM data, which can expose attributes such as image URLs. Use'visible-only'to include only visible elements. Default:false.screenshotIncluded?: boolean— Whether to include a screenshot. Default:true.
-
Return value:
- Returns a value that matches the shape described in
dataDemand, such as a string, number, object, or array.
- Returns a value that matches the shape described in
-
Examples:
aiBoolean()
Extract a boolean value from the UI.
- Type
-
Parameters:
prompt: string | object— A natural language description of the expected value, or prompting with images.options?: object— Optional configuration:domIncluded?: boolean | 'visible-only'— Whether to include simplified DOM data, which can expose attributes such as image URLs. Use'visible-only'to include only visible elements. Default:false.screenshotIncluded?: boolean— Whether to include a screenshot. Default:true.
-
Return value:
- Returns a Promise that resolves to the boolean returned by the AI model.
-
Examples:
aiNumber()
Extract a number value from the UI.
- Type
-
Parameters:
prompt: string | object— A natural language description of the expected value, or prompting with images.options?: object— Optional configuration:domIncluded?: boolean | 'visible-only'— Whether to include simplified DOM data, which can expose attributes such as image URLs. Use'visible-only'to include only visible elements. Default:false.screenshotIncluded?: boolean— Whether to include a screenshot. Default:true.
-
Return value:
- Returns a Promise that resolves to the number returned by the AI model.
-
Examples:
aiString()
Extract a string value from the UI.
aiString() is fully equivalent to aiAsk().
- Type
-
Parameters:
prompt: string | object— A natural language description of the expected value, or prompting with images.options?: object— Optional configuration:domIncluded?: boolean | 'visible-only'— Whether to include simplified DOM data, which can expose attributes such as image URLs. Use'visible-only'to include only visible elements. Default:false.screenshotIncluded?: boolean— Whether to include a screenshot. Default:true.
-
Return value:
- Returns a Promise that resolves to the string returned by the AI model.
-
Examples:
aiLocate()
Locate an element using natural language.
- Type
-
Parameters:
locate: string | object— A natural language description of the element to locate, or prompting with images.options?: object— Optional configuration:deepLocate?: boolean— Whether to enable Deep Locate. The deprecateddeepThinkname remains supported. Default:false.xpath?: string— XPath for the target element. Midscene tries the XPath before consulting the cache or AI model. Default:undefined.cacheable?: boolean— Whether this call can use the cache. Default:true.
-
Return value:
- Returns a Promise that resolves to a location information object.
rectusually represents the matched element boundary.- Some models only support point grounding rather than boundary grounding. In those cases, such as AutoGLM,
rectwill be a small8x8box containing the element center instead of the true element boundary. - Because
rectcan vary significantly depending on model capability, it is not recommended to rely too heavily on this field for strict boundary semantics. - If you need a stable click target, prefer the
centerfield. dpris a Web-only compatibility field. It is the ratio between physical screenshot pixels and logical CSS pixels. Other Agent types do not guarantee this field.
-
Examples:
aiAssert()
Specify an assertion in natural language, and the AI determines whether the condition is true. If the assertion fails, the SDK throws an error that includes both the optional errorMsg and a detailed reason generated by the AI.
- Type
-
Parameters:
assertion: string | object— The assertion described in natural language, or prompting with images.errorMsg?: string— An optional error message to append if the assertion fails.options?: object— Optional configuration:domIncluded?: boolean | 'visible-only'— Whether to include simplified DOM data, which can expose attributes such as image URLs. Use'visible-only'to include only visible elements. Default:false.screenshotIncluded?: boolean— Whether to include a screenshot. Default:true.
-
Return value:
- Returns a Promise that resolves to void if the assertion passes; if it fails, an error is thrown with
errorMsgand additional AI-provided information.
- Returns a Promise that resolves to void if the assertion passes; if it fails, an error is thrown with
-
Example:
Assertions are critical in test scripts. To reduce the risk of model false positives or false negatives, combine .aiQuery with standard JavaScript assertions when you need deterministic checks.
For example, you might replace the above code with:
Observation and waiting
startObserving()
Observe the screen over a defined time window while other Agent calls run. A later assertion can then evaluate transient UI, such as toasts, banners, and screen transitions, that a single screenshot might miss.
The returned UIObserver provides:
observer.stop(): Promise<void>— Stop sampling and capture the final representative screenshot. Must be called before asserting.observer.aiAssert(assertion: string, msg?: string, opt?: object): Promise<void>— Assert against the observed window. All buffered frames (plus the representative) are sent to the model, and the assertion text determines whether the model should look for something that appeared at any point, the final state, or an ordered change.observer.aiBoolean(prompt: string, opt?: object): Promise<boolean>— Boolean query over the observed window.observer.frameCount: number— Number of frames currently buffered.
How it works and what it costs:
- Frames come from the device's continuous frame source when available: scrcpy on Android (
scrcpyConfig.enabled), WDA MJPEG on iOS (wdaMjpegFrameSource.enabled), or CDP screencast on the web. Otherwise, Midscene captures individual screenshots at a much lower effective frame rate on mobile. - Sampling stores lightweight frame references. Midscene decodes only the frames sent to the model, and only at assertion time.
- All buffered frames (up to
maxFrames, plus the final representative screenshot) are sent to the model so transient UI in long windows is not missed. To bound token cost, increaseintervalMs(lower frame density) or decreasemaxFrames(smaller buffer). The observed frames are shown in the report timeline with anObservedtag. - On iOS, observed frames come from the scaled, lower-quality MJPEG stream, while the final representative frame is a full-quality screenshot.
aiWaitFor()
Wait until a condition described in natural language becomes true. Midscene starts checks at least checkIntervalMs apart to avoid unnecessary AI calls.
- Type
-
Parameters:
assertion: string— The condition described in natural language.options?: object— Optional configuration:timeoutMs?: number— Maximum window in milliseconds for starting a new check. If the previous check began within this window, Midscene may complete it; otherwise the method times out. Default:15000.checkIntervalMs?: number— Minimum interval in milliseconds between the start of consecutive checks. Default:3000.
-
Return value:
- Returns a Promise that resolves to void if the condition is met; if not, an error is thrown when the timeout is reached.
-
Examples:
Because each check calls an AI model, .aiWaitFor() can be slower and more expensive than a fixed delay. Use a simple sleep when you only need to wait for a known amount of time.
Workflow execution and context
runYaml()
Execute an automation script written in YAML. Midscene parses and runs only the tasks section. The method returns the results of all .aiQuery calls in the script.
- Type
-
Parameters:
yamlScriptContent: string— The YAML-formatted script content.
-
Return value:
- Returns an object with a
resultproperty that includes the results of all.aiQuerycalls.
- Returns an object with a
-
Example:
For more information about YAML scripts, please refer to Automate with Scripts in YAML.
runGherkinScenario()
Run a single Gherkin scenario and map its steps to Midscene Agent calls.
This API has been available since Midscene 1.10 and remains in beta. It may change in future releases.
- Type
-
Parameters:
scenarioText: string— One Gherkin scenario, or a list of Gherkin steps without theScenario:header.options?: object— Optional runtime options.context?: string— Temporary context for this run.abortSignal?: AbortSignal— An optional signal for aborting the run.deepThink?: 'unset' | true | false— Passed toaiActforGivenandWhensteps.deepLocate?: boolean— Passed toaiActforGivenandWhensteps.
-
Return value:
Promise<void>— Resolves after all steps finish. If a step fails, the error message includes the Gherkin line, the original step, and the Midscene semantic action being executed.
-
Example:
For supported rules, limitations, cache behavior, and YAML usage, see BDD-style scripts with Gherkin.
setAIActContext()
Set the context sent with subsequent agent.aiAct() or agent.ai() calls. This replaces any existing context.
This setting does not affect instant-action APIs such as aiTap().
- Type
-
Parameters:
aiActContext: string— The background knowledge that should be sent to the AI model. The deprecatedaiActionContextname is still accepted.
-
Example:
agent.setAIActionContext() is deprecated. Please use agent.setAIActContext() instead. The deprecated method remains as an alias for compatibility.
evaluateJavaScript()
Available only for web agents.
Evaluate a JavaScript expression in the web page context.
- Type
-
Parameters:
script: string— The JavaScript expression to evaluate.
-
Return value:
- Returns the result of the JavaScript expression.
-
Example:
freezePageContext()
Freeze the current page context so subsequent operations reuse one snapshot instead of retrieving page state repeatedly. This can improve performance for a large batch of concurrent read operations.
Usage constraints:
-
Use this method only when context retrieval is a confirmed bottleneck.
-
Call
agent.unfreezePageContext()when you need live page state again. -
Do not perform interaction methods while the context is frozen. The model cannot observe state changes and may act on stale information.
-
Type
-
Return value:
Promise<void>.
-
Examples:
In the report, operations using frozen context will display a 🧊 icon in the Insight tab.
unfreezePageContext()
Unfreeze the page context and resume retrieving live page state.
- Type
-
Return value:
Promise<void>.
Reporting, metrics, and lifecycle
recordToReport()
Add a report entry using either a newly captured screenshot or screenshots provided by the caller.
- Type
-
Parameters:
title?: string— Optional title for the report entry. Default:'untitled'.options?: RecordToReportOptions— Optional configuration:content?: string— Description of the screenshot.screenshots?: Array<{ base64: string; description?: string }>— One or more screenshots to record under the same report entry. When this option is set, Midscene does not capture another screenshot automatically.base64accepts a PNG/JPEG data URI such asdata:image/png;base64,...or a raw base64 body, which Midscene treats as PNG.
-
Compatibility:
screenshotBase64?: stringis still accepted as a backward-compatible single-screenshot override. Preferscreenshots: [{ base64 }]for new code. Provide only one ofscreenshotsorscreenshotBase64. -
Return value:
Promise<void>.
-
Examples:
_unstableLogContent()
Retrieve the log content from the report file. The structure of the log object may change in future versions.
- Type
-
Return value:
- Returns an object that contains the log content.
-
Examples:
LLM usage metrics
Midscene records the token usage of every LLM call. You can read the aggregated totals from the agent at runtime, which is useful for cost observability with tools like Langfuse.
metrics
A getter that returns a snapshot of the LLM usage accumulated by the agent since it was created.
- Type
- Example
onLLMUsage option
For real-time tracking, pass an onLLMUsage callback when constructing the
agent. It is invoked once per LLM call as soon as the usage is available, with
the raw usage info (token counts, model name, intent, request id, etc.).
.reportFile
The path to the report file.
Shared types
Locate options: Deep Locate (deepLocate)
deepLocate is available on APIs that locate elements, including aiAct, aiTap, aiHover, aiInput, aiKeyboardPress, aiScroll, aiDoubleClick, aiRightClick, and aiLocate.
When enabled, Midscene calls the AI model twice to locate the element more precisely. This can improve accuracy for small targets or elements that are difficult to distinguish from their surroundings. Newer models such as Qwen3.x, Doubao 2.0, and Gemini 3.5 usually benefit less, so enable this option only when needed.
- Default:
false
Historically, the name deepThink has carried two different meanings across APIs:
- In
aiAct(),deepThinkhas always meant planning mode, guiding task decomposition and planning-focused reasoning. See aiAct deepThink documentation for details. - In single-step action methods such as
aiTapandaiHover, the olddeepThinkmeant enhanced element location, equivalent to today'sdeepLocate.
To separate these two meanings, deepThink has been reserved for planning mode since v1.5.1, while enhanced element location is consistently named deepLocate.
- For
aiAct(), you can use bothdeepThinkanddeepLocate:deepThinkcontrols planning mode, whiledeepLocatecontrols the Deep Locate behavior described in this section. - For single-step action methods such as
aiTapandaiHover, use the clearerdeepLocateparameter when you need to improve location precision. The olddeepThinkparameter remains compatible and is equivalent todeepLocate.
Prompt input with images
Include reference images when text alone cannot identify the target clearly.
Image-enabled prompts use the following shape:
- Example 1: use a reference image to identify a tap target.
- Example 2: use images to assert the page content.
Image size
Follow your model provider's image size and dimension limits. Oversized or very small images may be rejected. Check the provider documentation for exact limits.
Report utilities
Each automation workflow generates its own report. ReportMergingTool combines those reports into one file so you can review all workflows together.
new ReportMergingTool()
Create a ReportMergingTool instance.
- Example:
.append()
Add an automation report to the list to be merged, typically right after each workflow finishes.
- Type
-
Parameters:
reportInfo: ReportFileWithAttributes— Report to append:reportFilePath: string— Path to the report file, usuallyagent.reportFile.reportAttributes: object— Report metadata:testId: string— Unique workflow identifier.testTitle: string— Workflow title.testDescription: string— Workflow description.testDuration: number— Workflow duration in milliseconds.testStatus: 'passed' | 'failed' | 'timedOut' | 'skipped' | 'interrupted'— Workflow status.
-
Return value:
void
-
Example:
.mergeReports()
Merge all added reports into a single HTML file.
- Type
-
Parameters:
reportFileName?: 'AUTO' | string— Name of the merged report. Default:'AUTO', which tells Midscene to generate the name. A custom name does not need the.htmlsuffix.opts?: object— Optional configuration:rmOriginalReports?: boolean— Whether to delete the original report files after merging. Default:false.overwrite?: boolean— Whether to overwrite an existing target file. Default:false.
-
Return value:
- Returns the merged report path, or
nullif no reports have been added.
- Returns the merged report path, or
-
Examples:
.clear()
Clear the list of reports to be merged. Use this if you need to reuse the same instance for multiple merge operations.
- Type
-
Return value:
void
-
Example:
Web (@midscene/web)
Use this section to configure Midscene's browser agents and review browser-specific constructor options. For shared parameters such as reporting, hooks, and caching, see Shared Agent APIs.
Action space
PuppeteerAgent, PlaywrightAgent, and Chrome Bridge agents share the following action space:
Tap— Left-click an element.RightClick— Right-click an element.DoubleClick— Double-click an element.Hover— Hover over an element.Input— Enter text withreplace/typeOnly/clearmodes (appendis a deprecated alias fortypeOnly).KeyboardPress— Press a specified key (optionally focusing a target element first).Scroll— Scroll from an element or screen center; supports scroll-to-top/bottom/left/right helpers.DragAndDrop— Drag from one element to another.LongPress— Long-press a target element with optional duration.Swipe— Touch-style swipe gesture (available whenenableTouchEventsInActionSpaceistrue).Pinch— Two-finger pinch gesture for zoom in/out (available whenenableTouchEventsInActionSpaceistrue; Chromium-based browsers only for Playwright).ClearInput— Clear the contents of an input field.Navigate— Open a URL in the current tab.Reload— Reload the page.GoBack— Navigate back in history.
PuppeteerPageAgent / PuppeteerAgent
Use the Puppeteer integration to add AI actions to an existing Puppeteer workflow.
PuppeteerPageAgent is bound to one Puppeteer Page. PuppeteerAgent remains an alias for backward compatibility.
Import
Constructor
Browser-specific options
In addition to the base agent options, Puppeteer exposes:
forceSameTabNavigation: boolean— Whether to keep navigation in the current tab. Default:true.waitForNavigationTimeout: number— Maximum time in milliseconds to wait when an action triggers navigation. Set to0to skip the wait. Default:5000.waitForNetworkIdleTimeout: number— Maximum time in milliseconds to wait for network idle between actions. Set to0to skip the wait. Default:2000.enableTouchEventsInActionSpace: boolean— Whether to add touch gestures such as swipe to the action space. Default:false.keyboardTypeDelay: number— Per-character delay in milliseconds passed to Puppeteer'spage.keyboard.type. Increase this value only when a controlled input drops characters during fast input. Default:undefined, which uses Puppeteer's default.forceChromeSelectRendering: boolean— Whether to renderselectelements with Chrome's base-select styling so they remain visible in screenshots and element extraction. Requires a Puppeteer version later than24.6.0. Default:true.customActions: DeviceAction[]— Register bespoke actions defined viadefineActionso planning can call domain-specific steps.
Usage notes
- Use one page agent per page. With
forceSameTabNavigation: true, Midscene opens new links in the current tab. Set it tofalseto preserve normal new-tab behavior, then create a separate page agent for each page. PuppeteerAgentandPuppeteerPageAgentremain page-scoped for compatibility. UsePuppeteerBrowserAgentwhen one Agent must switch between pages.- For the full list of interaction methods, see Shared Agent APIs.
PuppeteerBrowserAgent
Use PuppeteerBrowserAgent when one Midscene Agent must switch between pages in a Puppeteer browser. It binds to a browser instance, tracks one active page, and can follow newly opened pages.
- Constructor:
new PuppeteerBrowserAgent(browser, page, options?)— Use this when you explicitly choose the initial active page. - Factory:
PuppeteerBrowserAgent.create(browser, options?)— Let Midscene choose or create the initial active page. It usesinitialPagewhen provided; otherwise it reuses the first existing page or creates a new one. initialPage: Page— Initial Puppeteer page for the factory.autoFollowNewPage: boolean— Automatically switch the active page when the browser opens a new page. Default:false.newPageTimeout: number— Timeout forwaitForNewPage. Default:5000.activePage: Page— Current page controlled by the Browser Agent.pages()— List pages from the bound browser.newPage()— Create a new page and make it active.setActivePage(page: Page)— Explicitly set which Puppeteer page the Browser Agent controls next.waitForNewPage(action?, options?)— Wait for a newly opened page without implicitly switching the active page.
See also
- Integrate with Puppeteer for installation, fixtures, and remote-CDP guidance.
PlaywrightPageAgent / PlaywrightAgent
Use Midscene inside a Playwright browser for AI-driven testing or automation alongside your Playwright flows.
PlaywrightPageAgent is bound to one Playwright Page. PlaywrightAgent remains an alias for backward compatibility.
Import
Constructor
Browser-specific options
forceSameTabNavigation: boolean— Whether to keep navigation in the current tab. Default:true.waitForNavigationTimeout: number— Maximum time in milliseconds to wait for navigation. Set to0to skip the wait. Default:5000.waitForNetworkIdleTimeout: number— Maximum time in milliseconds to wait for network idle between actions. Set to0to skip the wait. Default:2000.enableTouchEventsInActionSpace: boolean— Whether to add touch gestures such as swipe to the action space. Default:false.keyboardTypeDelay: number— Per-character delay in milliseconds passed to Playwright'spage.keyboard.type. Increase this value only when a controlled input drops characters during fast input. Default:undefined, which uses Playwright's default.forceChromeSelectRendering: boolean— Whether to renderselectelements with Chrome's base-select styling so they remain visible in screenshots and element extraction. Requires Playwright1.52.0or later. Default:true.customActions: DeviceAction[]— Extend planning with project-specific actions.
Usage notes
- Use one page agent per page. With
forceSameTabNavigation: true, Midscene intercepts new tabs for stability. Set it tofalseto preserve normal new-tab behavior, then create a separate page agent for each page. PlaywrightAgentandPlaywrightPageAgentremain page-scoped for compatibility. UsePlaywrightBrowserAgentwhen one Agent must switch between pages in a browser context.- For the full list of interaction methods, see Shared Agent APIs.
PlaywrightBrowserAgent
Use PlaywrightBrowserAgent when one Midscene Agent must switch between pages in a Playwright browser context. It binds to the context, tracks one active page, and can follow newly opened pages.
- Constructor:
new PlaywrightBrowserAgent(context, page, options?)— Use this when you explicitly choose the initial active page. - Factory:
PlaywrightBrowserAgent.create(context, options?)— Let Midscene choose or create the initial active page. It usesinitialPagewhen provided; otherwise it reuses the first existing page or creates a new one. initialPage: Page— Initial Playwright page for the factory.autoFollowNewPage: boolean— Automatically switch the active page when the context opens a new page. Default:false.newPageTimeout: number— Timeout forwaitForNewPage. Default:5000.activePage: Page— Current page controlled by the Browser Agent.pages()— List pages from the bound browser context.newPage()— Create a new page and make it active.setActivePage(page: Page)— Explicitly set which Playwright page the Browser Agent controls next.waitForNewPage(action?, options?)— Wait for a newly opened page without implicitly switching the active page.
See also
- Integrate with Playwright for setup, fixtures, and advanced configuration.
Chrome Bridge Agent
Bridge mode lets Midscene operate the active tab in desktop Chrome through the extension instead of launching a separate automation browser.
Import
Constructor
Bridge options
closeNewTabsAfterDisconnect?: boolean— Close any bridge-created tabs when the agent is destroyed. Default:false.allowRemoteAccess?: boolean— Whether to allow remote machines to attach. Default:false, which binds to127.0.0.1.host?: string— Override the interface for the bridge server. Takes precedence overallowRemoteAccess.port?: number— TCP port for the bridge server. Default:3766.enableWaterFlowAnimation?: boolean— Show the blue animated border and mouse pointer while Midscene controls the page. Defaults totrue; set it tofalsewhen taking screenshots without the visual overlay.
See Bridge mode by Chrome extension for full installation and capability details.
Usage notes
Call connectCurrentTab() or connectNewTabWithUrl() before calling other Agent methods. Each AgentOverChromeBridge instance can attach to only one tab. Create a new instance after calling destroy().
Bridge methods
connectCurrentTab()
options.forceSameTabNavigationintercepts new tabs and opens them in the current tab. Set it tofalseto preserve normal new-tab behavior, then create a separate agent for each tab. Default:true.- Resolves after a successful handshake with the active tab. Rejects if the extension cannot connect.
connectNewTabWithUrl()
url— Address to open in a new desktop tab before attaching.options— Same asconnectCurrentTab.- Resolves when the new tab is opened and the bridge is connected.
destroy()
closeNewTabsAfterDisconnect— Optional runtime override for the constructor setting;truecloses bridge-created tabs on teardown.- Resolves after the bridge connection and local server are fully cleaned up.
See also
- Shared Agent APIs for shared agent methods.
- Bridge mode for extension setup, command sequence, and YAML usage.
Android (@midscene/android)
Use this section to configure Midscene's Android automation and review Android-specific constructor options. For shared parameters such as reporting, hooks, and caching, see Shared Agent APIs.
Action space
AndroidDevice provides the following actions to the Midscene Agent:
Tap— Tap an element.DoubleClick— Double-tap an element.Input— Enter text withreplace/typeOnly/clearmodes (appendis a deprecated alias fortypeOnly). Supports optionalautoDismissKeyboardandkeyboardTypeDelayparameters.Scroll— Scroll from an element or screen center in any direction, with helpers to reach the top, bottom, left, or right.DragAndDrop— Drag from one element to another.KeyboardPress— Press a specified key.LongPress— Long-press a target element with optional duration.PullGesture— Pull up or down, for example to refresh, with optional distance and duration.Pinch— Two-finger pinch gesture. Usescale > 1to zoom in,scale < 1to zoom out.ClearInput— Clear the contents of an input field.Launch— Open a web URL orpackage/.Activitystring.Terminate— Force-stop an app by package name.RunAdbShell— Execute rawadb shellcommands.AndroidBackButton— Trigger the system back action.AndroidHomeButton— Return to the home screen.AndroidRecentAppsButton— Open the multitasking/recent apps view.
AndroidDevice
Create a connection to a device available through adb.
Import
Constructor
Device options
deviceId: string— Value returned byadb devicesorgetConnectedDevices().autoDismissKeyboard?: boolean— Whether to hide the on-screen keyboard after text input. Default:true.keyboardDismissStrategy?: 'esc-first' | 'back-first'— Key order used to dismiss the on-screen keyboard. Default:'esc-first'.keyboardTypeDelay?: number— Delay in milliseconds between keystrokes. When set, Midscene enters one character at a time instead of sending the entire string. Use this option when a device or input field drops characters during fast input. It applies only to theinput textpath and is ignored when yadb is used.androidAdbPath?: string— Custom path to the adb executable.remoteAdbHost?: string/remoteAdbPort?: number— Point to a remote adb server.imeStrategy?: 'always-yadb' | 'yadb-for-non-ascii'— When to invoke yadb for text input. Default:'yadb-for-non-ascii'.'yadb-for-non-ascii'— Uses yadb for accented Latin characters such as ö, é, and ñ; Chinese and Japanese text; and format specifiers such as%sand%d. Pure ASCII text uses the faster nativeadb input text.'always-yadb'— Uses yadb for all text input. This provides maximum compatibility but is slightly slower for pure ASCII text.
displayId?: number— Target a specific virtual display if the device mirrors multiple displays.screenshotResizeScale?: number— Deprecated. This option has been removed and no longer has any effect. UsescreenshotShrinkFactorinAgentOptinstead to control screenshot size sent to the AI model.minScreenshotBufferSize?: number— Minimum valid screenshot buffer size in bytes. Smaller buffers are treated as failed or corrupted captures. Set to0to skip this size check; Midscene still rejects empty buffers and invalid image formats. Default:1024(1 KB).alwaysRefreshScreenInfo?: boolean— Whether to query rotation and screen size before every step. Default:false.
scrcpyConfig?: object— High-performance scrcpy screenshot configuration:enabled?: boolean— Whether to enable scrcpy screenshots. Default:false.maxSize?: number— Maximum video dimension in pixels.0disables scaling. Default:0.videoBitRate?: number— H.264 encoding bitrate in bits per second. Default:2000000.idleTimeoutMs?: number— Idle time before disconnecting the scrcpy stream.0disables automatic disconnection. Default:30000.
device.getScrcpyStatus() returns the current enabled, connected, lastError, and retryAfter state. device.retryScrcpy() immediately retries the scrcpy connection and returns Promise<void>.
Usage notes
- Discover devices with
getConnectedDevices(); theudidmatchesadb devices. - Midscene supports remote
adbthroughremoteAdbHostandremoteAdbPort. SetandroidAdbPathifadbis not onPATH. - Use
screenshotShrinkFactorinAgentOptto reduce screenshot processing cost on high-DPI devices.
AndroidAgent
Connect Midscene's AI planner to an AndroidDevice.
Import
Constructor
Android-specific options
customActions?: DeviceAction[]— Extend planning with actions defined viadefineAction.appNameMapping?: Record<string, string>— Map friendly app names to package names. When you pass an app name tolaunch(target), the agent will look up the package name in this mapping. If no mapping is found, it will attempt to launchtargetas-is. User-provided mappings take precedence over default mappings.- All other fields match the common constructor parameters, including
generateReport,reportFileName,aiActContext,modelConfig,cache,createOpenAIClient, andonTaskStartTip.
Usage notes
- Use one agent per device connection.
- Android-only helpers such as
launch,terminate, andrunAdbShellare also exposed in YAML scripts. See Android platform-specific actions. - For shared interaction methods, see Shared Agent APIs.
Android-specific methods
agent.launch()
Launch a web URL, Android activity, or app package.
target: string— Web URL,package/.Activitystring such ascom.android.settings/.Settings, package name, or app name. IfappNameMappingcontains the app name, Midscene resolves it to the mapped package; otherwise, it launchestargetas provided.
agent.runAdbShell()
Run a raw adb shell command through the connected device. Pass only the shell command itself, without the adb shell prefix.
command: string— Command passed verbatim toadb shell. For example, useinput tap 100 200, notadb shell input tap 100 200.opt.timeout?: number— Optional command execution timeout in milliseconds.
agent.terminate()
Terminate (force-stop) a running Android app.
uri: string— Package name, app name inappNameMapping, orpackage/.Activity(only the package part is used).
Navigation helpers
agent.back(): Promise<void>— Trigger the Android system back action.agent.home(): Promise<void>— Return to the launcher.agent.recentApps(): Promise<void>— Open the recent apps screen.
Factory functions and utilities
agentFromAdbDevice()
Create an AndroidAgent from a connected adb device.
deviceId?: string— Connect to a specific device. Omit this value to use the first available device.opts?: AndroidAgentOpt & AndroidDeviceOpt— Agent options and AndroidDevice settings. When you omitdeviceId, Midscene discovers a device through adb. SetandroidAdbPath,remoteAdbHost, andremoteAdbPortinoptsto choose the adb configuration for device discovery and connection.
getConnectedDevices()
List the adb devices that Midscene can drive.
deviceOptions is optional. Omit it to use Midscene's default adb configuration. Set androidAdbPath to choose an adb executable, or set remoteAdbHost and remoteAdbPort to connect to a remote adb server:
getConnectedDevicesWithDetails()
This function works like getConnectedDevices() and also returns the device brand, model, resolution, and screen density. Unavailable fields are undefined.
See also
- Android getting started for setup and scripting steps.
iOS (@midscene/ios)
Use this section to configure iOS device behavior, integrate Midscene with WebDriverAgent workflows, and troubleshoot WDA requests. For shared parameters such as reporting, hooks, and caching, see Shared Agent APIs.
Action space
IOSDevice provides the following actions to the Midscene Agent:
Tap— Tap an element.DoubleClick— Double-tap an element.Input— Enter text withreplace/typeOnly/clearmodes (appendis a deprecated alias fortypeOnly). Supports optionalautoDismissKeyboardandkeyboardTypeDelayparameters.Scroll— Scroll from an element or screen center in any direction, including scroll-to-top/bottom/left/right helpers.DragAndDrop— Drag from one element to another.KeyboardPress— Press a specified key.LongPress— Long-press a target element with optional duration.Pinch— Two-finger pinch gesture. Usescale > 1to zoom in,scale < 1to zoom out.ClearInput— Clear the contents of an input field.Launch— Open a URL, bundle identifier, or URL scheme.Terminate— Close a running iOS app by its bundle identifier.RunWdaRequest— Call WebDriverAgent REST endpoints directly.IOSHomeButton— Trigger the iOS system Home action.IOSAppSwitcher— Open the iOS multitasking view.
IOSDevice
Create a WebDriverAgent-backed instance that an IOSAgent can drive.
Import
Constructor
Device options
wdaPort?: number— WebDriverAgent port. Default:8100.wdaHost?: string— WebDriverAgent host. Default:'localhost'.iOSDeviceClassOverride?: string— Optional npm module path that replaces the defaultIOSDevicewhen usingagentFromWebDriverAgent()or iOS Playground. The module must export anIOSDeviceclass or a default class.autoDismissKeyboard?: boolean— Whether to hide the on-screen keyboard after text input. Default:true.keyboardTypeDelay?: number— Delay in milliseconds between keystrokes. When set, Midscene enters one character at a time through WDA's/wda/keysendpoint. Use this option when an input field drops characters during fast input.customActions?: DeviceAction<any>[]— Additional device actions exposed to the agent.
Usage notes
- Ensure Developer Mode is enabled and WDA can reach the device; use
iproxywhen forwarding ports from a real device. - Use
wdaHost/wdaPortto target remote devices or custom WDA deployments. - For shared interaction methods, see Shared Agent APIs.
IOSAgent
Connect Midscene's AI planner to an IOSDevice through WebDriverAgent.
Import
Constructor
iOS-specific options
customActions?: DeviceAction<any>[]— Extend planning with actions defined viadefineAction.appNameMapping?: Record<string, string>— Map friendly app names to bundle identifiers. When you pass an app name tolaunch(target)orterminate(bundleId), the agent will look up the bundle ID in this mapping. If no mapping is found, it will attempt to usetargetas-is. User-provided mappings take precedence over default mappings.- All other fields match the common constructor parameters, including
generateReport,reportFileName,aiActContext,modelConfig,cache,createOpenAIClient, andonTaskStartTip.
Usage notes
- Use one agent per device connection.
- iOS-only helpers such as
launch,terminate, andrunWdaRequestare also exposed in YAML scripts. See iOS platform-specific actions. - For shared interaction methods, see Shared Agent APIs.
iOS-specific methods
agent.launch()
Launch a web URL, app bundle identifier, or custom URL scheme.
target: string— Web URL, bundle identifier, URL scheme such astel:ormailto:, or app name. IfappNameMappingcontains the app name, Midscene resolves it to the mapped bundle identifier; otherwise, it launchestargetas provided.
agent.terminate()
Terminate (close) a running iOS app by its bundle ID.
bundleId: string— Bundle identifier of the app to terminate, such ascom.apple.Preferences. If you pass an app name that exists inappNameMapping, Midscene resolves it to the mapped Bundle ID.
agent.runWdaRequest()
Send raw requests to WebDriverAgent REST endpoints when you need low-level control.
method: string— HTTP verb (GET,POST,DELETE, etc.).endpoint: string— WebDriverAgent endpoint path.data?: Record<string, any>— Optional JSON body.
Navigation helpers
agent.home(): Promise<void>— Return to the Home screen.agent.appSwitcher(): Promise<void>— Open the app switcher.
Factory functions and utilities
agentFromWebDriverAgent()
Connect to WebDriverAgent and return a ready-to-use IOSAgent.
opts?: IOSAgentOpt & IOSDeviceOpt— Combine iOS Agent options withIOSDevicesettings.- Set
MIDSCENE_IOS_DEVICE_CLASS_OVERRIDEto apply the same device class override through the environment. An explicit option takes precedence over the environment variable.
See also
- iOS getting started for setup and scripting steps.
- Integrate with any interface for custom actions and schemas.
HarmonyOS (@midscene/harmony)
Use this section to configure HarmonyOS device behavior, integrate Midscene with another framework, and troubleshoot HDC issues. For shared parameters such as reporting, hooks, and caching, see Shared Agent APIs.
Action space
HarmonyDevice provides the following actions to the Midscene Agent:
Tap— Tap an element.DoubleClick— Double-tap an element.Input— Enter text withreplace,typeOnly, orclearmode.Scroll— Scroll from an element or the screen center in any direction, including scroll-to-top, bottom, left, and right helpers.DragAndDrop— Drag from one element to another.KeyboardPress— Press a specific key.LongPress— Long-press a target element with an optional duration.ClearInput— Clear the contents of an input field.— Not supported. The HarmonyOSPinchuitestframework does not provide multi-touch input APIs.Launch— Open a HarmonyOS app (bundle name).Terminate— Force-stop a HarmonyOS app by bundle name.RunHdcShell— Execute a rawhdc shellcommand.HarmonyBackButton— Trigger the system back action.HarmonyHomeButton— Return to the home screen.HarmonyRecentAppsButton— Open the recent apps screen.
HarmonyDevice
Create an HDC-backed device instance that a HarmonyAgent can drive.
Import
Constructor
Device options
deviceId: string— Value fromhdc list targetsorgetConnectedDevices().hdcPath?: string— Custom path to the HDC executable. If omitted, Midscene checks theHDC_HOMEenvironment variable and common installation paths.autoDismissKeyboard?: boolean— Whether to hide the on-screen keyboard after text input. Default:true.keyboardDismissStrategy?: 'esc-first' | 'back-first'— Key used to dismiss the on-screen keyboard.'esc-first'sends Escape, while'back-first'sends Back. Default:'esc-first'.keyboardTypeDelay?: number— Delay in milliseconds between keystrokes. When set, Midscene enters one character at a time throughuitest uiInput inputText. Use this option when an input field drops characters during fast input.screenshotResizeScale?: number— Deprecated. This option has been removed and no longer has any effect. UsescreenshotShrinkFactorinAgentOptinstead to control screenshot size sent to the AI model.customActions?: DeviceAction[]— Extend the planner's available actions viadefineAction.
Usage notes
- Use
getConnectedDevices()to discover devices. The returneddeviceIdmatcheshdc list targetsoutput. - If HDC is not in your system PATH, specify it via the
HDC_HOMEenvironment variable or thehdcPathoption.
HarmonyAgent
Connect Midscene's AI planner to a HarmonyDevice.
Import
Constructor
HarmonyOS-specific options
customActions?: DeviceAction[]— Extend the planner's available actions viadefineAction.appNameMapping?: Record<string, string>— Map friendly app names to bundle names. When you pass an app name tolaunch(target), the Agent uses the mapped bundle name when available; otherwise, it launchestargetas provided.- All other fields match the common constructor parameters, including
generateReport,reportFileName,aiActContext,modelConfig,cache,createOpenAIClient, andonTaskStartTip.
Usage notes
- Use one Agent per device connection.
- HarmonyOS-specific helpers like
launch,terminate, andrunHdcShellcan also be used in YAML scripts. See HarmonyOS platform-specific actions. - For shared interaction methods, see Shared Agent APIs.
HarmonyOS-specific methods
agent.launch()
Launch a HarmonyOS app.
uri: string— App bundle name, app name registered inappNameMapping, or HTTP/HTTPS URL. Midscene opens HTTP and HTTPS URLs in the browser.
agent.runHdcShell()
Run a raw hdc shell command on the connected device.
command: string— The command passed directly tohdc shell.
agent.terminate()
Terminate (force-stop) a running HarmonyOS app.
uri: string— Bundle name, app name inappNameMapping, orbundle/Ability(only the bundle part is used).
Navigation helpers
agent.back(): Promise<void>— Trigger the HarmonyOS system back action.agent.home(): Promise<void>— Return to the home screen.agent.recentApps(): Promise<void>— Open the recent apps screen.
Factory functions and utilities
agentFromHdcDevice()
Create a HarmonyAgent from any connected HDC device.
deviceId?: string— Connect to a specific device. Omit this value to use the first available device.opts?: HarmonyAgentOpt & HarmonyDeviceOpt— Merge Agent options andHarmonyDevicesettings in a single object.
getConnectedDevices()
List HDC devices that Midscene can drive.
Related reading
- HarmonyOS getting started for setup and script examples.
Desktop (@midscene/computer)
This section documents the desktop-specific APIs provided by @midscene/computer.
For common APIs that work across all platforms, see Common API reference.
Agent factory functions
agentForComputer(opts?): Promise<ComputerAgent>
Create an agent for local desktop automation.
Backward compatibility:
agentFromComputeris still available as an alias.
agentForRDPComputer(opts): Promise<ComputerAgent<RDPDevice>>
Create an agent for remote Windows desktop automation over RDP.
Parameters
Local desktop options
displayId?: string— Display to control. UseComputerDevice.listDisplays()to list the available displays. Default: the primary display.customActions?: DeviceAction<any>[]— Custom device actions. Default:undefined.keyboardDriver?: 'applescript' | 'libnut'— On macOS, keyboard event backend. Use'applescript'for the default, more compatible behavior or'libnut'for faster input when the target application supports it. Default:'applescript'.headless?: boolean— On Linux, set this totrueto start a virtual display with Xvfb. This enables desktop automation on headless servers and in CI environments. You can also set theMIDSCENE_COMPUTER_HEADLESS_LINUX=trueenvironment variable. Default:false.xvfbResolution?: string— Resolution of the Xvfb virtual display. Default:'1920x1080x24'.
Keyboard input options
keyboardTypeDelay?: number— Minimum delay in milliseconds between keystrokes. A positive value makes local and RDP Computer Agents emit text one Unicode character at a time instead of using the default burst input. A local Computer Agent uses real key events in this mode; when this option is omitted or set to0, it uses clipboard paste to avoid interference from the active IME. An action-levelkeyboardTypeDelaypassed toaiInput()overrides the Agent-level default. Pass0to restore clipboard input for one action. Default:undefined.
The Agent-level option also applies to Input actions generated by agent.ai(), so the prompt does not need to call aiInput() explicitly:
RDP options
host: string— Remote Windows hostname or IP address.port?: number— RDP port. Default:3389.username?: string/password?: string— Credentials for the remote session.domain?: string— Windows domain. Default:undefined.localAddress?: string— Local source IP address for the RDP TCP connection. Use this when the machine has multiple outbound routes. Default:undefined.adminSession?: boolean— Whether to request the remote admin session when the server allows it. Default:false.ignoreCertificate?: boolean— Whether to skip certificate validation, which is useful for self-signed certificates. Default:false.securityProtocol?: 'auto' | 'tls' | 'nla' | 'rdp'— RDP security protocol. Default:'auto'.desktopWidth?: number/desktopHeight?: number— Requested remote desktop resolution. When omitted, the RDP client and server negotiate the session size.
See the complete Obsidian desktop automation demo for a CI example that uses @midscene/computer.
Example
Example: connect to a remote Windows desktop over RDP
See the runnable RDP automation demo, which connects to a remote Windows machine, opens Settings, navigates to Windows Update, and generates a structured report.
Use localAddress only when the machine running Midscene has multiple outbound
routes and the RDP server must be reached from a specific local source IP. Pass
an IP address, not a network interface name.
ComputerDevice
ComputerDevice.listDisplays(): Promise<DisplayInfo[]>
List all available displays.
Returns
Example
checkComputerEnvironment(): Promise<EnvironmentCheck>
Check if the computer environment is properly configured.
Returns
Example
ComputerAgent
ComputerAgent extends PageAgent<ComputerDevice> and inherits the shared Agent methods described in Shared Agent APIs, including:
aiAct(action: string)— Perform an AI-planned action.aiQuery(query: string)— Extract structured information.aiAssert(assertion: string)— Assert a condition.aiWaitFor(condition: string)— Wait for a condition.aiLocate(description: string)— Locate an element.
Instant actions provide direct control once Midscene locates an element:
aiTap(),aiDoubleClick(),aiRightClick(), andaiHover()— Mouse actions.aiInput(),aiClearInput(), andaiKeyboardPress()— Keyboard actions.aiScroll()— Scroll actions.
Action space
ComputerDevice supports the following actions.
Mouse actions
Tap (Click)
Single click at the target location.
DoubleClick
Double-click at the target location.
RightClick
Right-click to open context menu.
MouseMove (Hover)
Move the pointer to an element, for example to reveal a hover menu or tooltip.
DragAndDrop
Drag from one location and drop at another.
Keyboard actions
KeyboardPress
Press keyboard keys with optional modifiers.
Supported keys
- Regular keys:
a-z,0-9,Enter,Escape,Space,Tab, etc. - Arrow keys:
ArrowUp,ArrowDown,ArrowLeft,ArrowRight - Function keys:
F1-F12 - Modifiers:
Command/Cmd(macOS),Control/Ctrl,Alt,Shift,Win(Windows) - Media keys:
VolumeUp,VolumeDown,Mute, etc.
Examples
Input
Type text into an input field.
ClearInput
Clear the content of an input field.
Scroll actions
Scroll the screen or a specific area.
Display actions
ListDisplays
Get information about all connected displays.
With RDP, ListDisplays returns the current remote session as a single display.
See also
- Common API reference — APIs that work across all platforms
- Model configuration — Configure AI models
- Caching — Improve performance with caching

