Skip to main content
Glama

fetch_chunk

Retrieve the plain-text content of a specific webpage section using a CSS anchor. Reduce token costs by fetching only relevant content through structure-aware selection.

Instructions

Fetch the plain-text content of a specific section of a webpage by its CSS anchor. Call get_manifest first to discover available anchors. Uses a three-stage anchor resolution: getElementById → querySelector → fuzzy heading match.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
urlYesFully-qualified URL of the webpage
anchorYesCSS anchor of the target section (e.g. "#introduction" or "#wasp-003")

Implementation Reference

  • The main handler function `fetchChunk` that fetches a chunk's plain-text content by URL and CSS anchor. It fetches the page HTML via getManifest, parses it with JSDOM, finds the element by anchor (using getElementById → querySelector → fuzzy heading match), and if it's a heading returns the section text, otherwise returns the element's text content.
    export async function fetchChunk(url: string, anchor: string): Promise<string> {
      const { html } = await getManifest(url);
      const dom = new JSDOM(html, { url });
      const document = dom.window.document;
    
      const el = findElement(document, anchor);
      if (!el) return "";
    
      if (isHeading(el)) {
        return collectSectionText(document, el);
      }
    
      // Non-heading anchor (from native manifest) — return element's own text
      return el.textContent?.trim() ?? "";
    }
  • The input schema definition for the fetch_chunk tool. It declares two required parameters: `url` (a fully-qualified URL string) and `anchor` (a CSS anchor string like '#introduction').
    inputSchema: {
      type: "object",
      properties: {
        url: {
          type: "string",
          description: "Fully-qualified URL of the webpage",
        },
        anchor: {
          type: "string",
          description:
            'CSS anchor of the target section (e.g. "#introduction" or "#wasp-003")',
        },
      },
      required: ["url", "anchor"],
    },
  • index.ts:101-112 (registration)
    The registration of the fetch_chunk tool handler in the CallToolRequestSchema. When name === 'fetch_chunk', it extracts url and anchor from args, calls fetchChunk from chunks.ts, and returns the content.
    if (name === "fetch_chunk") {
      const { url, anchor } = args as { url: string; anchor: string };
      const content = await fetchChunk(url, anchor);
      return {
        content: [
          {
            type: "text",
            text: content || "(no content found for this anchor)",
          },
        ],
      };
    }
  • The `findElement` helper that resolves an anchor to a DOM element using a three-stage strategy: getElementById first, then querySelector, then fuzzy heading text match.
    function findElement(document: Document, anchor: string): Element | null {
      // Stage 1: getElementById — handles CSS-special chars in IDs
      const id = anchor.startsWith("#") ? anchor.slice(1) : anchor;
      const byId = document.getElementById(id);
      if (byId) return byId;
    
      // Stage 2: querySelector — handles non-id selectors from native manifests
      try {
        const byQuery = document.querySelector(anchor);
        if (byQuery) return byQuery;
      } catch {
        // Invalid selector — fall through
      }
    
      // Stage 3: fuzzy slug match on heading text
      return fuzzyFindHeading(document, anchor);
    }
  • The `collectSectionText` helper that extracts all text content under a heading element until the next heading at the same or higher level. Uses Range API first, then falls back to a document-order text node walk.
    function collectSectionText(document: Document, headingEl: Element): string {
      const depth = getHeadingDepth(headingEl);
    
      // Find the next heading at the same depth or shallower (lower number = higher)
      const allHeadings = Array.from(document.querySelectorAll("h1,h2,h3,h4"));
      const idx = allHeadings.indexOf(headingEl);
      let nextStop: Element | null = null;
      for (let i = idx + 1; i < allHeadings.length; i++) {
        if (getHeadingDepth(allHeadings[i]) <= depth) {
          nextStop = allHeadings[i];
          break;
        }
      }
    
      // Primary: Range API (same approach as browser content.js)
      try {
        const range = document.createRange();
        range.setStartAfter(headingEl);
        if (nextStop) {
          range.setEndBefore(nextStop);
        } else {
          const body = document.body ?? document.documentElement;
          range.setEndAfter(body);
        }
        const text = range.toString().trim();
        if (text) return text;
      } catch {
        // Range API inconsistency in JSDOM — fall through to sibling walk
      }
    
      // Fallback: document-order text node walk using compareDocumentPosition
      const body = document.body ?? document.documentElement;
      // SHOW_TEXT = 4
      const walker = document.createTreeWalker(body, 4);
      const parts: string[] = [];
      let node: Node | null = walker.nextNode();
    
      while (node) {
        const posFromHeading = headingEl.compareDocumentPosition(node);
        if (posFromHeading & FOLLOWING) {
          if (nextStop) {
            const posFromStop = nextStop.compareDocumentPosition(node);
            // Stop when node is no longer preceding nextStop
            if (!(posFromStop & PRECEDING)) break;
          }
          const text = node.textContent?.trim();
          if (text) parts.push(text);
        }
        node = walker.nextNode();
      }
    
      return parts.join(" ").trim();
    }
Behavior3/5

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

Reveals the three-stage anchor resolution (getElementById → querySelector → fuzzy heading match), which adds transparency beyond basic description. However, no annotations are provided, and the description omits error handling, permission needs, or rate limits.

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 concise sentences with no redundancy. Purpose is front-loaded, and every sentence adds value (purpose, prerequisite, resolution algorithm).

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

Completeness4/5

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

Covers the key usage pattern (prerequisite, resolution logic) for a 2-parameter read operation. Lacks details on return format (only says 'plain-text content') and potential edge cases, but overall sufficient for typical use.

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?

The input schema already describes both parameters (url and anchor) with 100% coverage. The description adds context about anchor being a CSS anchor and the resolution stages, but no significant extra meaning beyond the schema.

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 it fetches plain-text content of a webpage section by CSS anchor. Distinguishes from siblings by mentioning the prerequisite get_manifest and the specific anchor resolution method.

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?

Explicitly instructs to call get_manifest first to discover anchors, and describes the three-stage resolution process. However, does not specify when not to use the tool or 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/sfeeney1897/wasp-mcp'

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