Portal Community

Tool Schema

{
  "name": "browser_navigate",
  "description": "Navigate the browser to a URL and wait for the page to load. " +
                 "Use this before any other browser tools. " +
                 "Only domains on the allowlist can be accessed.",
  "inputSchema": {
    "type": "object",
    "properties": {
      "url": {
        "type": "string",
        "format": "uri",
        "description": "The full URL to navigate to, including https:// (e.g. https://example.com/page)"
      },
      "wait_until": {
        "type": "string",
        "enum": ["load", "domcontentloaded", "networkidle"],
        "default": "load",
        "description": "When to consider navigation complete. 'networkidle' waits for no network activity."
      },
      "timeout_ms": {
        "type": "integer",
        "default": 30000,
        "description": "Maximum milliseconds to wait for navigation. Overrides the plugin default."
      }
    },
    "required": ["url"]
  }
}

Tool Handler Implementation

public async Task<string> HandleNavigateAsync(
    JsonElement input, ConversationContext ctx, IBrowserSession session, CancellationToken ct)
{
    var url      = input.GetProperty("url").GetString()!;
    var waitUntil = input.TryGetProperty("wait_until", out var wu)
        ? wu.GetString()! : "load";
    var timeoutMs = input.TryGetProperty("timeout_ms", out var t)
        ? t.GetInt32() : _config.NavigationTimeoutMs;

    // Domain allowlist check (security — see Security page)
    if (!_domainPolicy.IsAllowed(url))
        return JsonSerializer.Serialize(new
        {
            error  = "Navigation blocked",
            reason = $"The domain in '{url}' is not on the approved allowlist."
        });

    var page = await session.GetPageAsync(ct);

    var waitState = waitUntil switch
    {
        "domcontentloaded" => WaitUntilState.DOMContentLoaded,
        "networkidle"      => WaitUntilState.NetworkIdle,
        _                  => WaitUntilState.Load
    };

    var response = await page.GotoAsync(url, new PageGotoOptions
    {
        WaitUntil = waitState,
        Timeout   = timeoutMs
    });

    return JsonSerializer.Serialize(new
    {
        url         = page.Url,
        title       = await page.TitleAsync(),
        status_code = response?.Status ?? 0,
        ok          = response?.Ok ?? false
    });
}

Response Format

// Successful navigation
{
  "url":         "https://finance.yahoo.com/quote/AAPL",
  "title":       "Apple Inc. (AAPL) Stock Price, News, Quote & History - Yahoo Finance",
  "status_code": 200,
  "ok":          true
}

// Blocked navigation
{
  "error":  "Navigation blocked",
  "reason": "The domain in 'https://malicious.example.com/' is not on the approved allowlist."
}

// Timeout
{
  "error":  "NavigationTimeout",
  "reason": "Navigation to https://slow-site.com timed out after 30000ms."
}

waitUntil Strategies

StrategyWhen to UseTypical Latency
loadStandard pages — waits for the load event1–3 s
domcontentloadedSPAs where DOM is ready before resources finish loading0.5–1 s
networkidlePages with dynamic content loaded via AJAX after initial load3–10 s