Skip to main content
Glama

start-browser

Launch a browser instance with customizable settings for testing or development workflows, including viewport configuration and URL navigation.

Instructions

Creates a new browser context with an auto-generated unique ID

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
typeNoBrowser type (default: chromium)
displayNameNoHuman-readable name for the browser
targetUrlNoURL to navigate to after starting
headlessNoRun browser in headless mode (default: false)
viewportNoBrowser viewport size (default: 1280x800)
tagsNoTags for organizing browsers
purposeNoDescription of what this browser is for

Implementation Reference

  • The MCP tool handler for 'start-browser'. Generates unique context ID, invokes ContextManager.createContext, formats response with browser details.
    async ({ type, displayName, targetUrl, headless, viewport, tags, purpose }) => {
      // Generate cryptographically secure unique browser ID
      const contextId = `context-${randomUUID()}`;
      
      try {
        const result = await contextManager.createContext({
          id: contextId,
          type: type as BrowserType | undefined,
          displayName,
          targetUrl,
          headless,
          viewport,
          tags,
          purpose
        });
    
        if (result.success) {
          return {
            content: [
              {
                type: 'text',
                text: `Browser created successfully!\nBrowser ID: ${contextId}\nType: ${result.data?.type || type || 'chromium'}\nURL: ${targetUrl || 'about:blank'}`
              }
            ],
            // Include the generated ID in the response for easy access
            contextId: contextId,
            browserInfo: {
              id: contextId,
              type: result.data?.type || type || 'chromium',
              displayName: displayName,
              targetUrl: targetUrl || 'about:blank'
            }
          };
        } else {
          return {
            content: [
              {
                type: 'text',
                text: `Failed to create browser: ${result.error}`
              }
            ],
            isError: true
          };
        }
      } catch (error) {
        const errorMessage = error instanceof Error ? error.message : String(error);
        Logger.error(`Failed to create browser ${contextId}:`, error);
        return {
          content: [
            {
              type: 'text',
              text: `Failed to create browser: ${errorMessage}`
            }
          ],
          isError: true
        };
      }
    }
  • Input validation schema (Zod) for the 'start-browser' tool parameters.
    {
      type: z.enum(['chromium', 'firefox', 'webkit']).optional().describe('Browser type (default: chromium)'),
      displayName: z.string().optional().describe('Human-readable name for the browser'),
      targetUrl: z.string().optional().describe('URL to navigate to after starting'),
      headless: z.boolean().optional().describe('Run browser in headless mode (default: false)'),
      viewport: z.object({
        width: z.number(),
        height: z.number()
      }).optional().describe('Browser viewport size (default: 1280x800)'),
      tags: z.array(z.string()).optional().describe('Tags for organizing browsers'),
      purpose: z.string().optional().describe('Description of what this browser is for')
    },
  • Direct registration of the 'start-browser' tool via server.tool() call, including name, description, schema, and handler.
    server.tool(
      'start-browser',
      'Creates a new browser context with an auto-generated unique ID',
      {
        type: z.enum(['chromium', 'firefox', 'webkit']).optional().describe('Browser type (default: chromium)'),
        displayName: z.string().optional().describe('Human-readable name for the browser'),
        targetUrl: z.string().optional().describe('URL to navigate to after starting'),
        headless: z.boolean().optional().describe('Run browser in headless mode (default: false)'),
        viewport: z.object({
          width: z.number(),
          height: z.number()
        }).optional().describe('Browser viewport size (default: 1280x800)'),
        tags: z.array(z.string()).optional().describe('Tags for organizing browsers'),
        purpose: z.string().optional().describe('Description of what this browser is for')
      },
      async ({ type, displayName, targetUrl, headless, viewport, tags, purpose }) => {
        // Generate cryptographically secure unique browser ID
        const contextId = `context-${randomUUID()}`;
        
        try {
          const result = await contextManager.createContext({
            id: contextId,
            type: type as BrowserType | undefined,
            displayName,
            targetUrl,
            headless,
            viewport,
            tags,
            purpose
          });
    
          if (result.success) {
            return {
              content: [
                {
                  type: 'text',
                  text: `Browser created successfully!\nBrowser ID: ${contextId}\nType: ${result.data?.type || type || 'chromium'}\nURL: ${targetUrl || 'about:blank'}`
                }
              ],
              // Include the generated ID in the response for easy access
              contextId: contextId,
              browserInfo: {
                id: contextId,
                type: result.data?.type || type || 'chromium',
                displayName: displayName,
                targetUrl: targetUrl || 'about:blank'
              }
            };
          } else {
            return {
              content: [
                {
                  type: 'text',
                  text: `Failed to create browser: ${result.error}`
                }
              ],
              isError: true
            };
          }
        } catch (error) {
          const errorMessage = error instanceof Error ? error.message : String(error);
          Logger.error(`Failed to create browser ${contextId}:`, error);
          return {
            content: [
              {
                type: 'text',
                text: `Failed to create browser: ${errorMessage}`
              }
            ],
            isError: true
          };
        }
      }
    );
  • src/index.ts:82-82 (registration)
    Top-level call to registerBrowserManagerTools(server), which registers all browser manager tools including 'start-browser'.
    const contextManager = registerBrowserManagerTools(server);
  • Core helper method implementing browser context creation: launches shared Playwright browser if needed, creates isolated context and page, handles navigation and persistence.
    async createContext(options: ContextCreateOptions): Promise<ContextOperationResult> {
      try {
        // Check context limit
        if (this.contexts.size >= this.MAX_CONTEXTS) {
          return {
            success: false,
            error: `Maximum number of contexts (${this.MAX_CONTEXTS}) reached`
          };
        }
    
        // Check if context ID already exists
        if (this.contexts.has(options.id)) {
          return {
            success: false,
            error: `Context with ID '${options.id}' already exists`
          };
        }
    
        const browserType = options.type || BrowserType.CHROMIUM;
        const headless = options.headless ?? false;
        const viewport = options.viewport || { width: 1280, height: 800 };
    
        Logger.info(`Creating context: ${options.id} (${browserType})`);
    
        // Get or create shared browser instance
        const browser = await this.ensureSharedBrowser(browserType, headless);
    
        // Create isolated context
        const context = await browser.newContext({
          viewport
        });
    
        // Always create a page (following Playwright standard pattern)
        const page = await context.newPage();
        
        // Navigate to targetUrl if provided, otherwise stays at default "about:blank"
        if (options.targetUrl) {
          await page.goto(options.targetUrl, { waitUntil: 'networkidle' });
        }
    
        const metadata: ContextMetadata = {
          tags: options.tags || [],
          purpose: options.purpose,
          targetUrl: options.targetUrl,
          viewport,
          headless
        };
    
        const contextInstance: ContextInstance = {
          id: options.id,
          type: browserType,
          displayName: options.displayName,
          context,
          page,
          metadata,
          createdAt: new Date(),
          lastUsedAt: new Date()
        };
    
        this.contexts.set(options.id, contextInstance);
        if (this.sharedBrowser) {
          this.sharedBrowser.contextCount++;
        }
    
        // Persist to database
        const db = getScreenshotDB();
        db.saveBrowserInstance( // TODO: rename to saveContextInstance
          options.id, 
          browserType, 
          options.displayName, 
          metadata
        );
    
        Logger.info(`Context created successfully: ${options.id}`);
    
        return {
          success: true,
          contextId: options.id,
          data: {
            id: options.id,
            type: browserType,
            displayName: options.displayName,
            targetUrl: options.targetUrl
          }
        };
    
      } catch (error) {
        Logger.error(`Failed to create context ${options.id}:`, error);
        return {
          success: false,
          error: error instanceof Error ? error.message : String(error)
        };
      }
    }
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden but only states the creation action without behavioral details. It doesn't disclose if this is a persistent resource, what happens on failure, if it requires cleanup, or any rate limits. 'Creates' implies mutation, but no further context is given.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence that front-loads the core action ('Creates a new browser context') and adds a key detail ('with an auto-generated unique ID'). There's no wasted verbiage or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool that creates a browser context with 7 parameters and no annotations or output schema, the description is incomplete. It doesn't explain the return value (e.g., the unique ID format), error conditions, or how this context integrates with sibling tools, leaving significant gaps for agent understanding.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema fully documents all 7 parameters. The description adds no parameter-specific information beyond what's in the schema, such as explaining interactions between parameters (e.g., how 'targetUrl' relates to 'viewport'). Baseline 3 is appropriate as the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Creates a new browser context') and specifies it generates a unique ID, which distinguishes it from simple browser launching. However, it doesn't explicitly differentiate from sibling tools like 'list-browsers' or 'get-context-info' beyond the creation aspect.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives like 'execute-browser-commands' or 'close-browser'. It doesn't mention prerequisites, such as needing this context for other browser operations, or when not to use it (e.g., for existing contexts).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

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/ESnark/blowback'

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