Skip to main content
Glama

pilot_set_useragent

Set a custom User-Agent string to simulate different browsers or devices, bypass bot detection, or test mobile user agents. Recreates browser context while preserving cookies and state.

Instructions

Set a custom browser User-Agent string, which recreates the browser context to apply the change while preserving cookies and page state. Use when the user wants to simulate a different browser or device, bypass bot detection, test mobile user agents, or debug User-Agent-dependent behavior. Note: this recreates the browser context, which may briefly interrupt in-progress requests.

Parameters:

  • useragent: The full User-Agent string (e.g., "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15")

Returns: Confirmation with the new User-Agent string.

Errors:

  • Context recreation warnings: If cookies or state could not be fully preserved during context recreation, a warning is included.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
useragentYesUser agent string

Implementation Reference

  • Registration of the 'pilot_set_useragent' tool on the MCP server with description and Zod schema for useragent parameter.
      server.tool(
        'pilot_set_useragent',
        `Set a custom browser User-Agent string, which recreates the browser context to apply the change while preserving cookies and page state.
    Use when the user wants to simulate a different browser or device, bypass bot detection, test mobile user agents, or debug User-Agent-dependent behavior. Note: this recreates the browser context, which may briefly interrupt in-progress requests.
    
    Parameters:
    - useragent: The full User-Agent string (e.g., "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15")
    
    Returns: Confirmation with the new User-Agent string.
    
    Errors:
    - Context recreation warnings: If cookies or state could not be fully preserved during context recreation, a warning is included.`,
          { useragent: z.string().describe('User agent string') },
        async ({ useragent }) => {
          await bm.ensureBrowser();
          try {
            bm.setUserAgent(useragent);
            const error = await bm.recreateContext();
            if (error) {
              return { content: [{ type: 'text' as const, text: `User agent set to "${useragent}" but: ${error}` }] };
            }
            return { content: [{ type: 'text' as const, text: `User agent set: ${useragent}` }] };
          } catch (err) {
            return { content: [{ type: 'text' as const, text: wrapError(err) }], isError: true };
          }
        }
      );
  • Handler function for pilot_set_useragent that calls bm.setUserAgent(useragent), then bm.recreateContext(), and returns confirmation or error.
      async ({ useragent }) => {
        await bm.ensureBrowser();
        try {
          bm.setUserAgent(useragent);
          const error = await bm.recreateContext();
          if (error) {
            return { content: [{ type: 'text' as const, text: `User agent set to "${useragent}" but: ${error}` }] };
          }
          return { content: [{ type: 'text' as const, text: `User agent set: ${useragent}` }] };
        } catch (err) {
          return { content: [{ type: 'text' as const, text: wrapError(err) }], isError: true };
        }
      }
    );
  • Zod schema defining useragent parameter as a required string.
    { useragent: z.string().describe('User agent string') },
  • BrowserManager.setUserAgent() stores the custom user agent string.
    setUserAgent(ua: string) {
      this.customUserAgent = ua;
    }
  • BrowserManager.recreateContext() saves state, closes old context, creates new context with customUserAgent, restores state.
    async recreateContext(): Promise<string | null> {
      if (!this.browser || !this.context) throw new Error('Browser not launched');
    
      try {
        const state = await this.saveState();
        for (const page of this.pages.values()) {
          await page.close().catch(() => {});
        }
        this.pages.clear();
        await this.context.close().catch(() => {});
    
        const contextOptions: BrowserContextOptions = {
          viewport: { width: 1280, height: 720 },
        };
        if (this.customUserAgent) {
          contextOptions.userAgent = this.customUserAgent;
        }
        this.context = await this.browser.newContext(contextOptions);
        if (Object.keys(this.extraHeaders).length > 0) {
          await this.context.setExtraHTTPHeaders(this.extraHeaders);
        }
        await this.restoreState(state);
        await this.applyRoutesFromConfig();
        return null;
      } catch (err: unknown) {
        try {
          this.pages.clear();
          if (this.context) await this.context.close().catch(() => {});
          const contextOptions: BrowserContextOptions = {
            viewport: { width: 1280, height: 720 },
          };
          if (this.customUserAgent) {
            contextOptions.userAgent = this.customUserAgent;
          }
          this.context = await this.browser!.newContext(contextOptions);
          await this.newTab();
          this.clearRefs();
        } catch {}
        return `Context recreation failed: ${err instanceof Error ? err.message : String(err)}. Browser reset to blank tab.`;
      }
    }
Behavior5/5

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

With no annotations, the description fully covers behavior: recreates browser context, preserves cookies and page state, but may interrupt in-progress requests. It also mentions error warnings about state preservation.

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

Conciseness4/5

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

The description is front-loaded with the main purpose, followed by use cases, notes, and parameter details. It is reasonably concise, though the structure could be slightly tighter.

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

Completeness5/5

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

Given there is no output schema, the description provides return value ('Confirmation with the new User-Agent string') and error conditions (context recreation warnings). It covers all essential aspects for a single-parameter tool.

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

Parameters4/5

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

Schema coverage is 100% and description provides an example User-Agent string ('Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15'), adding practical context beyond the basic schema type description.

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

Purpose5/5

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

The description clearly states 'Set a custom browser User-Agent string' and provides specific use cases (simulate browser/device, bypass bot detection, test mobile user agents). It effectively distinguishes this tool from siblings like pilot_set_header by focusing on the User-Agent header.

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

Usage Guidelines4/5

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

The description lists applicable scenarios (simulate browser/device, bypass bot detection, test mobile) and includes a caveat about context recreation. However, it does not explicitly state when not to use this tool or mention alternatives.

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/TacosyHorchata/Pilot'

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