Skip to main content
Glama

snapshot

Retrieve the accessibility tree snapshot of a webpage to read its content. Returns element references, roles, names, and values for analysis.

Instructions

Get accessibility tree snapshot — the PRIMARY way to read page content. Returns element refs, roles, names and values. Token-efficient. Always prefer over screenshot. Refs come from the accessibility tree, so custom SPA elements may be missing; fall back to CSS selectors, camofox_wait_for_selector, or camofox_get_page_html when needed.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
tabIdYesTab ID from create_tab
offsetNoOffset for paginating large snapshots. Use nextOffset from previous response.

Implementation Reference

  • MCP tool handler for 'snapshot' - the primary tool for reading page content via accessibility tree. Calls deps.client.snapshot() and returns snapshot text, refs count, URL, and optional truncation info.
    server.tool(
      "snapshot",
      "Get accessibility tree snapshot — the PRIMARY way to read page content. Returns element refs, roles, names and values. Token-efficient. Always prefer over screenshot. Refs come from the accessibility tree, so custom SPA elements may be missing; fall back to CSS selectors, camofox_wait_for_selector, or camofox_get_page_html when needed.",
      {
        tabId: z.string().min(1).describe("Tab ID from create_tab"),
        offset: z.number().optional().describe("Offset for paginating large snapshots. Use nextOffset from previous response.")
      },
      async (input: unknown) => {
        try {
          const parsed = z.object({
            tabId: z.string().min(1).describe("Tab ID from create_tab"),
            offset: z.number().optional().describe("Offset for paginating large snapshots. Use nextOffset from previous response.")
          }).parse(input);
          const tracked = getTrackedTab(parsed.tabId);
          const response = await deps.client.snapshot(parsed.tabId, tracked.userId, parsed.offset);
          incrementToolCall(parsed.tabId);
          updateTabUrl(parsed.tabId, response.url);
          updateRefsCount(parsed.tabId, response.refsCount);
    
          const result: {
            url: string;
            snapshot: string;
            refsCount: number;
            truncated?: boolean;
            totalChars?: number;
            hasMore?: boolean;
            nextOffset?: number | null;
            truncationInfo?: string;
          } = {
            url: response.url,
            snapshot: response.snapshot,
            refsCount: response.refsCount
          };
    
          if (response.truncated) {
            result.truncated = response.truncated;
            result.totalChars = response.totalChars;
            result.hasMore = response.hasMore;
            result.nextOffset = response.nextOffset;
            result.truncationInfo = response.hasMore
              ? `TRUNCATED (${response.totalChars ?? "unknown"} total chars) | next offset: ${response.nextOffset ?? "unknown"}`
              : `TRUNCATED (${response.totalChars ?? "unknown"} total chars)`;
          }
    
          return okResult(result);
        } catch (error) {
          return toErrorResult(error);
        }
      }
  • Input schema for snapshot tool: tabId (required string) and offset (optional number for pagination).
    {
      tabId: z.string().min(1).describe("Tab ID from create_tab"),
      offset: z.number().optional().describe("Offset for paginating large snapshots. Use nextOffset from previous response.")
    },
  • Client method snapshot() - makes GET request to /tabs/:tabId/snapshot?userId=&offset= and returns parsed SnapshotResponse.
    async snapshot(tabId: string, userId: string, offset?: number): Promise<SnapshotResponse> {
      const params = new URLSearchParams({ userId });
      if (offset !== undefined) {
        params.set("offset", String(offset));
      }
    
      const response = await this.requestJson(
        `/tabs/${encodeURIComponent(tabId)}/snapshot?${params.toString()}`,
        {
        method: "GET"
        }
      , SnapshotRawResponseSchema);
    
      return {
        url: response.url ?? "",
        snapshot: response.snapshot ?? "",
        refsCount: response.refsCount ?? 0,
        truncated: response.truncated,
        totalChars: response.totalChars,
        hasMore: response.hasMore,
        nextOffset: response.nextOffset
      };
    }
  • SnapshotResponse TypeScript interface defining the return shape: url, snapshot, refsCount, truncated, totalChars, hasMore, nextOffset.
    export interface SnapshotResponse {
      url: string;
      snapshot: string;
      refsCount: number;
      truncated?: boolean;
      totalChars?: number;
      hasMore?: boolean;
      nextOffset?: number | null;
    }
  • src/server.ts:44-44 (registration)
    Registration of registerObservationTools which contains the snapshot tool.
    registerObservationTools(server, deps);
Behavior4/5

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

Discloses key behavioral trait: refs come from accessibility tree, so custom SPA elements may be missing. Also mentions token-efficiency. However, no annotations exist, and the description does not cover auth requirements, side effects, or whether the tool works on non-loaded tabs. Still, it provides useful operational context.

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?

Three sentences with no redundancy: first states purpose, second lists return values, third gives fallback guidance. Compact and information-dense, perfectly front-loaded.

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?

Despite no output schema, the description adequately explains return format (element refs, roles, names, values) and mentions token-efficiency. It also addresses known limitations (missing SPA elements) and provides fallback options, making it complete for the tool's complexity.

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 coverage is 100%, so baseline is 3. The description does not add new parameter-level details beyond what the schema already provides for 'tabId' and 'offset'. The mention of 'Use nextOffset from previous response' is already in the schema's offset description, so no added value.

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?

Clearly states 'Get accessibility tree snapshot' and distinguishes as 'the PRIMARY way to read page content'. Unlike siblings like screenshot or camofox_get_page_html, it specifically mentions returning element refs, roles, names, and values, making its purpose unambiguous.

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

Usage Guidelines5/5

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

Explicitly recommends using this tool over screenshot and provides specific fallback alternatives when custom SPA elements are missing: 'fall back to CSS selectors, camofox_wait_for_selector, or camofox_get_page_html when needed.' This gives clear when-to-use and when-not-to-use guidance.

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/redf0x1/camofox-mcp'

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