npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

mcp-animation-inspector

v0.3.0

Published

MCP server that helps AI assistants understand website animations via Playwright, pluggable detectors, and frame capture

Readme

mcp-animation-inspector

MCP server that helps AI assistants understand website animations

npm version License: MIT


What It Does

AI assistants are blind to animations. They can read HTML and CSS, but they cannot see a GSAP timeline play, a Lottie animation loop, or a scroll-triggered reveal. When asked "how does this animation work?", they can only guess from static source code.

mcp-animation-inspector solves this by running a real browser via Playwright, detecting all animation systems on the page, capturing frame sequences at key scroll positions, extracting the relevant source code, and optionally generating Claude Vision descriptions of what was captured — all exposed as MCP tools that any AI assistant can call.

Pipeline: Navigate → Discover → Capture → Extract → Describe → Report


Quick Start

Run with npx (once published)

npx mcp-animation-inspector

Claude Code integration

Add to your ~/.claude.json or project .mcp.json:

{
  "mcpServers": {
    "animation-inspector": {
      "command": "npx",
      "args": ["mcp-animation-inspector"]
    }
  }
}

Local development

git clone https://github.com/Ak0096/mcp-animation-inspector
cd mcp-animation-inspector
npm install
npx playwright install chromium
npm run build
node dist/index.js

Available Tools

| Tool | Description | Key Parameters | |------|-------------|----------------| | inspect_animation | Full pipeline: discover, capture, extract, and describe all animations on a page | url | | discover_animations | Run detectors only — returns an inventory of animation systems found | url | | capture_frames | Take screenshots at specified scroll positions | url, inventory?, scroll_positions? | | extract_animation_code | Pull relevant source code snippets for detected animations | url, inventory?, filter? | | describe_animations | Generate Claude Vision descriptions of captured frames (requires ANTHROPIC_API_KEY) | url | | get_page_structure | Return a simplified DOM outline of the page | url |


Built-in Detectors

| Detector | What It Detects | |----------|-----------------| | CSS | @keyframes rules, transition properties longer than 200 ms | | GSAP | gsap.timeline(), gsap.to/from/fromTo(), ScrollTrigger | | Framer Motion | data-framer-* attributes, motion.* components | | Lottie | <lottie-player> elements, bodymovin.loadAnimation() calls | | WebGL | <canvas> with a WebGL context, Three.js scene presence | | Scroll Libraries | Lenis, Locomotive Scroll smooth-scroll instances | | Custom Cursors | cursor: none on body, fixed-position cursor overlay elements | | Page Transitions | View Transitions API usage, Barba.js, Swup |


Configuration

All options can be passed as environment variables or as JSON config. When running via npx, set environment variables before the command.

| Option | Default | Description | |--------|---------|-------------| | headless | true | Run browser in headless mode | | viewport | 1440x900 | Browser viewport width × height | | timeout | 30000 | Page load timeout in milliseconds | | scrollPositions | [0, 25, 50, 75, 100] | Scroll percentages at which to capture frames | | maxFramesPerAnimation | 10 | Maximum frames captured per detected animation | | maxTotalFrames | 50 | Hard cap on total frames across all animations | | imageFormat | jpeg | Frame image format (jpeg or png) | | imageQuality | 75 | JPEG quality (1–100) | | enabledDetectors | "all" | Comma-separated list of detectors to run, or "all" | | transport | stdio | MCP transport: stdio or http | | httpPort | 3100 | Port used when transport=http | | autoDescribe | false | Automatically run Vision descriptions after capture | | descriptionModel | claude-opus-4-5 | Anthropic model used for Vision descriptions | | ANTHROPIC_API_KEY | — | Required only for describe_animations / autoDescribe |


Architecture

┌─────────────────────────────────────────────────────────┐
│                    MCP Tool Request                      │
└────────────────────────┬────────────────────────────────┘
                         │
              ┌──────────▼──────────┐
              │   BrowserSession    │  Playwright Chromium
              │   (Navigate + Wait) │
              └──────────┬──────────┘
                         │
              ┌──────────▼──────────┐
              │  DetectorRegistry   │  8 pluggable detectors
              │  (Discover)         │  run in parallel
              └──────────┬──────────┘
                         │  AnimationInventory
              ┌──────────▼──────────┐
              │   FrameCapture      │  scroll + screenshot
              │   (Capture)         │  per scroll position
              └──────────┬──────────┘
                         │  Base64 frames
              ┌──────────▼──────────┐
              │   CodeExtractor     │  pulls CSS/JS snippets
              │   (Extract)         │  relevant to detections
              └──────────┬──────────┘
                         │
              ┌──────────▼──────────┐
              │  VisionDescriber    │  optional Claude Vision
              │  (Describe)         │  pass (needs API key)
              └──────────┬──────────┘
                         │
              ┌──────────▼──────────┐
              │   MCP Response      │  structured JSON report
              └─────────────────────┘

Each stage is independent. You can call discover_animations without capturing frames, or capture_frames with a pre-built inventory to skip re-detection.


Contributing

Adding a New Detector

  1. Create the detector file

    src/detectors/your-detector.ts

    Implement the AnimationDetector interface:

    import type { AnimationDetector, DetectionResult } from './types.js';
    
    export const yourDetector: AnimationDetector = {
      name: 'your-detector',
      detect(page): Promise<DetectionResult> {
        return page.evaluate(() => {
          // run inside the browser context
          const found = /* your detection logic */;
          return { detected: found, details: [] };
        });
      },
    };
  2. Register the detector

    Add it to ALL_DETECTORS in src/detectors/index.ts:

    import { yourDetector } from './your-detector.js';
    
    export const ALL_DETECTORS = [
      cssDetector,
      gsapDetector,
      // ...existing detectors...
      yourDetector,  // add here
    ];
  3. Add a test

    Create a fixture HTML file under tests/fixtures/ and a test file under tests/. The test should assert that your detector returns detected: true for the fixture and detected: false for an unrelated page.

Running Tests

npm test

Build

npm run build

License

MIT — see LICENSE