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)
        };
      }
    }

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