Skip to main content
Glama
andytango
by andytango

scroll

Scroll web pages or specific elements in any direction with configurable pixel amounts and smooth scrolling options for automated browser navigation.

Instructions

Scroll the page or a specific element

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
directionNodown
amountNoScroll amount in pixels
selectorNoElement to scroll (scrolls page if not specified)
smoothNoUse smooth scrolling
tabIdNoTab ID to operate on (uses active tab if not specified)

Implementation Reference

  • Handler function that executes the scroll tool logic: calculates scroll deltas based on direction and amount, scrolls either a specific element or the page using scrollBy API with smooth option.
    async ({ direction, amount, selector, smooth, tabId }) => {
      const pageResult = await getPageForOperation(tabId);
      if (!pageResult.success) {
        return handleResult(pageResult);
      }
    
      const page = pageResult.data;
      const scrollDirection = (direction ?? 'down') as ScrollDirection;
      const scrollAmount = amount ?? 100;
      const useSmooth = smooth ?? true;
    
      try {
        // Calculate scroll deltas
        let deltaX = 0;
        let deltaY = 0;
    
        switch (scrollDirection) {
          case 'up':
            deltaY = -scrollAmount;
            break;
          case 'down':
            deltaY = scrollAmount;
            break;
          case 'left':
            deltaX = -scrollAmount;
            break;
          case 'right':
            deltaX = scrollAmount;
            break;
        }
    
        if (selector) {
          // Scroll specific element
          const element = await page.$(selector);
    
          if (!element) {
            return handleResult(err(selectorNotFound(selector)));
          }
    
          await element.evaluate(
            (el, dx, dy, smoothScroll) => {
              el.scrollBy({
                left: dx,
                top: dy,
                behavior: smoothScroll ? 'smooth' : 'auto',
              });
            },
            deltaX,
            deltaY,
            useSmooth
          );
        } else {
          // Scroll page
          await page.evaluate(
            (dx, dy, smoothScroll) => {
              window.scrollBy({
                left: dx,
                top: dy,
                behavior: smoothScroll ? 'smooth' : 'auto',
              });
            },
            deltaX,
            deltaY,
            useSmooth
          );
        }
    
        return handleResult(ok({
          scrolled: true,
          direction: scrollDirection,
          amount: scrollAmount,
          selector,
        }));
      } catch (error) {
        return handleResult(err(normalizeError(error)));
      }
    }
  • Zod schema defining the input parameters for the scroll tool, including direction, amount, optional selector and smooth flag.
    export const scrollSchema = z.object({
      direction: z.enum(['up', 'down', 'left', 'right']).optional().default('down'),
      amount: z.number().int().min(1).optional().default(100).describe('Scroll amount in pixels'),
      selector: z.string().optional().describe('Element to scroll (scrolls page if not specified)'),
      smooth: z.boolean().optional().default(true).describe('Use smooth scrolling'),
      tabId: tabIdSchema,
    });
  • Registration of the scroll tool via server.tool call within registerInputTools function, specifying name, description, schema, and inline handler.
    // Scroll
    server.tool(
      'scroll',
      'Scroll the page or a specific element',
      scrollSchema.shape,
      async ({ direction, amount, selector, smooth, tabId }) => {
        const pageResult = await getPageForOperation(tabId);
        if (!pageResult.success) {
          return handleResult(pageResult);
        }
    
        const page = pageResult.data;
        const scrollDirection = (direction ?? 'down') as ScrollDirection;
        const scrollAmount = amount ?? 100;
        const useSmooth = smooth ?? true;
    
        try {
          // Calculate scroll deltas
          let deltaX = 0;
          let deltaY = 0;
    
          switch (scrollDirection) {
            case 'up':
              deltaY = -scrollAmount;
              break;
            case 'down':
              deltaY = scrollAmount;
              break;
            case 'left':
              deltaX = -scrollAmount;
              break;
            case 'right':
              deltaX = scrollAmount;
              break;
          }
    
          if (selector) {
            // Scroll specific element
            const element = await page.$(selector);
    
            if (!element) {
              return handleResult(err(selectorNotFound(selector)));
            }
    
            await element.evaluate(
              (el, dx, dy, smoothScroll) => {
                el.scrollBy({
                  left: dx,
                  top: dy,
                  behavior: smoothScroll ? 'smooth' : 'auto',
                });
              },
              deltaX,
              deltaY,
              useSmooth
            );
          } else {
            // Scroll page
            await page.evaluate(
              (dx, dy, smoothScroll) => {
                window.scrollBy({
                  left: dx,
                  top: dy,
                  behavior: smoothScroll ? 'smooth' : 'auto',
                });
              },
              deltaX,
              deltaY,
              useSmooth
            );
          }
    
          return handleResult(ok({
            scrolled: true,
            direction: scrollDirection,
            amount: scrollAmount,
            selector,
          }));
        } catch (error) {
          return handleResult(err(normalizeError(error)));
        }
      }
    );
  • TypeScript type definition for scroll tool input inferred from the schema.
    export type ScrollInput = z.infer<typeof scrollSchema>;
  • Type definition for scroll direction enum used in the tool.
    export type ScrollDirection = 'up' | 'down' | 'left' | 'right';
Behavior2/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It states what the tool does but doesn't describe important behavioral aspects like whether scrolling is immediate or animated, what happens if the selector doesn't exist, whether it waits for page load, or what the return value is. The description is minimal and lacks 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?

The description is extremely concise at just 6 words, front-loaded with the core functionality. Every word serves a purpose: 'scroll' defines the action, 'the page or a specific element' defines the scope. There's zero wasted verbiage.

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

Completeness2/5

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

For a tool with 5 parameters, no annotations, and no output schema, the description is insufficiently complete. It doesn't explain the tool's behavior in different scenarios, error conditions, or what constitutes successful execution. The minimal description leaves too many operational questions unanswered.

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 description mentions scrolling 'the page or a specific element' which hints at the 'selector' parameter's purpose, but doesn't add meaningful semantics beyond what the 80% schema coverage already provides. The schema descriptions adequately explain each parameter's function, so the description doesn't significantly enhance parameter understanding.

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

Purpose4/5

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

The description clearly states the action ('scroll') and specifies what can be scrolled ('the page or a specific element'), which provides a specific verb+resource combination. However, it doesn't explicitly differentiate from sibling tools like 'navigate' or 'go_back' which involve page movement but not scrolling.

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

Usage Guidelines2/5

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

The description provides no guidance on when to use this tool versus alternatives. It doesn't mention when scrolling is appropriate compared to navigation tools, nor does it specify prerequisites like needing an active page or tab context.

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/andytango/puppeteer-mcp'

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