Skip to main content
Glama

BrowserStack MCP server

Official
live.ts4.76 kB
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { z } from "zod"; import logger from "../logger.js"; import { startBrowserSession } from "./live-utils/start-session.js"; import { PlatformType } from "./live-utils/types.js"; import { trackMCP } from "../lib/instrumentation.js"; import { BrowserStackConfig } from "../lib/types.js"; import globalConfig from "../config.js"; // Define the schema shape const LiveArgsShape = { platformType: z .nativeEnum(PlatformType) .describe("Must be 'desktop' or 'mobile'"), desiredURL: z.string().url().describe("The URL to test"), desiredOS: z .enum(["Windows", "OS X", "android", "ios", "winphone"]) .describe( "Desktop OS ('Windows' or 'OS X') or mobile OS ('android','ios','winphone')", ), desiredOSVersion: z .string() .describe( "The OS version must be specified as a version number (e.g., '10', '14.0') or as a keyword such as 'latest' or 'oldest'. Normalize variations like 'newest' or 'most recent' to 'latest', and terms like 'earliest' or 'first' to 'oldest'. For macOS, version names (e.g., 'Sequoia') must be used instead of numeric versions.", ), desiredBrowser: z .enum(["chrome", "firefox", "safari", "edge", "ie"]) .describe("Browser for desktop (Chrome, IE, Firefox, Safari, Edge)"), desiredBrowserVersion: z .string() .optional() .describe( "Browser version for desktop (e.g. '133.2', 'latest'). If the user says 'latest', 'newest', or similar, normalize it to 'latest'. Likewise, convert terms like 'earliest' or 'oldest' to 'oldest'.", ), desiredDevice: z.string().optional().describe("Device name for mobile"), }; const LiveArgsSchema = z.object(LiveArgsShape); /** * Launches a desktop browser session */ async function launchDesktopSession( args: z.infer<typeof LiveArgsSchema>, config: BrowserStackConfig, ): Promise<string> { if (!args.desiredBrowser) throw new Error("You must provide a desiredBrowser"); if (!args.desiredBrowserVersion) throw new Error("You must provide a desiredBrowserVersion"); return startBrowserSession( { platformType: PlatformType.DESKTOP, url: args.desiredURL, os: args.desiredOS, osVersion: args.desiredOSVersion, browser: args.desiredBrowser, browserVersion: args.desiredBrowserVersion, }, config, ); } /** * Launches a mobile browser session */ async function launchMobileSession( args: z.infer<typeof LiveArgsSchema>, config: BrowserStackConfig, ): Promise<string> { if (!args.desiredDevice) throw new Error("You must provide a desiredDevice"); return startBrowserSession( { platformType: PlatformType.MOBILE, browser: args.desiredBrowser, url: args.desiredURL, os: args.desiredOS, osVersion: args.desiredOSVersion, device: args.desiredDevice, }, config, ); } /** * Handles the core logic for running a browser session */ async function runBrowserSession(rawArgs: any, config: BrowserStackConfig) { // Validate and narrow const args = LiveArgsSchema.parse(rawArgs); // Branch desktop vs mobile and delegate const launchUrl = args.platformType === PlatformType.DESKTOP ? await launchDesktopSession(args, config) : await launchMobileSession(args, config); let response = [ { type: "text" as const, text: `✅ Session started. If it didn't open automatically, visit:\n${launchUrl}`, }, ]; if (globalConfig.REMOTE_MCP) { response = [ { type: "text" as const, text: `✅ To start the session. Click on ${launchUrl}`, }, ]; } return { content: response, }; } export default function addBrowserLiveTools( server: McpServer, config: BrowserStackConfig, ) { const tools: Record<string, any> = {}; tools.runBrowserLiveSession = server.tool( "runBrowserLiveSession", "Launch a BrowserStack Live session (desktop or mobile).", LiveArgsShape, async (args) => { try { trackMCP( "runBrowserLiveSession", server.server.getClientVersion()!, undefined, config, ); return await runBrowserSession(args, config); } catch (error) { logger.error("Live session failed: %s", error); trackMCP( "runBrowserLiveSession", server.server.getClientVersion()!, error, config, ); return { content: [ { type: "text" as const, text: `Failed to start a browser live session. Error: ${error}`, isError: true, }, ], isError: true, }; } }, ); return tools; }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/browserstack/mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server