# Keyframer Inspector (npm · @keyframerdev/inspector)

Give your agent eyes for motion: record, slow down and test animations in mobile apps

- Trust score: 73/100 (medium)
- Change this week: +3
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-11-05

## Components

- npm · `@keyframerdev/inspector`: 73/100 (this document), [markdown](https://verifymcp.io/servers/dev-keyframer-inspector/keyframerdev-inspector.md), [page](https://verifymcp.io/servers/dev-keyframer-inspector/keyframerdev-inspector)

## Channel facts

- Registry: `npm`
- Package: `@keyframerdev/inspector`
- Version: `0.4.0`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-11-05.

- **Supply Chain Security**: 100/100
  - No malware found by supply-chain analysis.
  - No known CVEs affecting this package version or its production dependencies.
  - No install/post-install scripts declared.
  - 2 of 18 dependencies flagged as unhealthy.
- **Provenance & Transparency**: 32/100
  - Source repository is publicly reachable at the declared URL.
  - Provenance check failed: no build-provenance attestation is published.
  - Licence could not be checked: the licence is shipped as a file inside the package, not declared as a standard (SPDX) licence identifier, so we cannot tell whether it is OSI-approved.
  - Actively maintained (last published 12 days ago).
  - Disclosure check failed: no security disclosure policy was found in the source repository.
- **Schema Quality & AI Usability**: 76/100
  - 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).
  - AI-judged instruction clarity (good).
  - Context-footprint check failed: tool/resource definitions use about 3102 tokens (~141/item across 22 items; 22 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 43/100
  - Stability observed for 13 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 91/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 73% of tool parameters carry a description.
- **Tool Safety**: 100/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - We read all 22 captured tool definition(s), and no name or description among them implies an irreversible operation.
  - An AI judge read all 23 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### How do I install the Keyframer Inspector MCP server?

Keyframer Inspector runs locally as an npm package, launched with npx -y @keyframerdev/inspector. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add dev-keyframer-inspector -- npx -y @keyframerdev/inspector
```

### Cursor

```json
{
  "mcpServers": {
    "dev-keyframer-inspector": {
      "command": "npx",
      "args": [
        "-y",
        "@keyframerdev/inspector"
      ]
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "dev-keyframer-inspector": {
      "command": "npx",
      "args": [
        "-y",
        "@keyframerdev/inspector"
      ]
    }
  }
}
```

### Codex

```bash
codex mcp add dev-keyframer-inspector -- npx -y @keyframerdev/inspector
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "dev-keyframer-inspector": {
      "type": "local",
      "command": [
        "npx",
        "-y",
        "@keyframerdev/inspector"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add dev-keyframer-inspector --command npx --arg -y --arg @keyframerdev/inspector
```

### Hermes

```yaml
mcp_servers:
  dev-keyframer-inspector:
    command: "npx"
    args: ["-y", "@keyframerdev/inspector"]
```

### Netclaw

```json
{
  "McpServers": {
    "dev-keyframer-inspector": {
      "Transport": "stdio",
      "Command": "npx",
      "Arguments": [
        "-y",
        "@keyframerdev/inspector"
      ]
    }
  }
}
```

### Vellum

```bash
assistant mcp add dev-keyframer-inspector -t stdio -c npx -a -y @keyframerdev/inspector
```

### Other

```json
{
  "mcpServers": {
    "dev-keyframer-inspector": {
      "command": "npx",
      "args": [
        "-y",
        "@keyframerdev/inspector"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-11-03 (score 73, +1)

No change was recorded against any check on this day. Stability & Change Management went from 33 to 37. That category is still filling its 30-day observation window: 10 days of observed history at the previous scan, 11 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-11-01 (score 72, +1)

No change was recorded against any check on this day. Stability & Change Management went from 27 to 30. That category is still filling its 30-day observation window: 8 days of observed history at the previous scan, 9 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-30 (score 71, +1)

No change was recorded against any check on this day. Stability & Change Management went from 20 to 23. That category is still filling its 30-day observation window: 6 days of observed history at the previous scan, 7 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-28 (score 70, +1)

No change was recorded against any check on this day. Stability & Change Management went from 13 to 17. That category is still filling its 30-day observation window: 4 days of observed history at the previous scan, 5 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-26 (score 69, +1)

No change was recorded against any check on this day. Stability & Change Management went from 7 to 10. That category is still filling its 30-day observation window: 2 days of observed history at the previous scan, 3 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-25 (score 68, +1)

- [functional improvement] Stability: unverified → 0.07

### 2026-10-24 (score 67, +26)

- [security improvement] Malware scan: unverified → pass
- [security improvement] Known CVEs: unverified → pass
- [functional improvement] Dependency health: unverified → 0.96

### 2026-10-23 (score 41, +5)

- [security regression] Malware scan: pass → unverified
- [security regression] Known CVEs: pass → unverified
- [security improvement] Injection markers: unverified → pass
- [security] First check of Judged manipulation: pass
- [security] Stability: Stability not yet verified: not enough scan history yet (needs a 30-day window).
- [functional regression] Dependency health: 1.00 → unverified
- [functional improvement] Tool coverage: unverified → 100
- [functional improvement] MCP protocol: unverified → pass
- [functional improvement] Schema quality: unverified → 100
- [functional] First check of Schema quality: fail
- [functional] First check of Destructive annotations: pass
- [functional] First check of Schema quality: fail
- [functional] First check of Schema quality: good
- [functional] First check of Tool coverage: 73
- [functional] Package version: 0.3.0 → 0.4.0

## MCP tools (22)

### `inspector_status` (~100 tokens)

Which app is connected through Metro, the scenarios it registered, the recorded sessions, the shared values (useSharedValue) it has rendered, the worklet mistakes in its code that crash it (with the fix), and what animates now as the app counts it: animated styles and shared values mounted on the screen, what each value drives (fan-out), animation starts per frame by call site, rows that remount, and the cost per list cell.

### `record` (~231 tokens)

Record the app for a while: every shared value (also ones that mount mid-recording), both threads' frame rates and long frames, animations with call sites and stacks, React commits with why components rendered, JS tasks (handlers, effects, timers) and UI-thread worklet time. A person interacts with the app meanwhile (or pass replay: true). Returns the problems found, ranked, each with where it is written and how to fix it. It blocks for durationMs: when you drive the app yourself with another tool (Argent, agent-device, a Maestro flow), use start_recording and stop_recording instead. Prefer run_scenario when the app registered one for the interaction: it is reproducible, so a fix can be checked with compare.

Input parameters:

- `durationMs` (number): How long to record, in ms. Default 4000, at most 60000.
- `replay` (boolean): Run the app's registered replay once recording starts.
- `signals` (array): Names or ids of shared values. Omit to record all of them, including ones that mount while recording.

### `start_recording` (~160 tokens)

Start recording the app and return at once, so you can drive it with another tool between this call and stop_recording: taps, swipes and flows from a simulator agent (Argent, agent-device, Maestro) or anything else. Records what record does (every shared value, both threads' frame rates and long frames, animations with call sites, React commits, JS tasks, UI-thread worklet time). One recording at a time; it stops by itself after 5 minutes. Use record instead for a fixed stretch while a person uses the app, and run_scenario when the app registered the interaction.

Input parameters:

- `signals` (array): Names or ids of shared values. Omit to record all of them, including ones that mount while recording.

### `stop_recording` (~80 tokens)

Stop the recording start_recording began and report the problems found, ranked, each with where it is written and how to fix it: the same report as record. The session is kept for get_trace, compare, save_recording and export_recording. Says so when the recording stopped early: the app disconnected or restarted, or the cap was reached.

### `run_scenario` (~100 tokens)

Run one of the app's registered scenarios (registerScenario: a reproducible interaction, like opening a sheet or scrolling a feed) while recording, and report the problems. Run it before and after a change, then compare the two sessions to check the fix.

Input parameters:

- `name` (string, required): The scenario, as inspector_status lists it.
- `settleMs` (number): Keep recording this long after it finishes, for animations it started. Default 800.

### `compare` (~72 tokens)

Compare two recorded sessions (ids from record / stop_recording / run_scenario, default the last two): frame rates, frames lost, longest frames, rendering, JS task and worklet time, and which problems were fixed, remain or are new.

Input parameters:

- `after` (string)
- `before` (string)

### `get_trace` (~94 tokens)

A session as a timeline: frame drops, JS tasks with where they are written, UI worklets over 2 ms a frame, React commits with the components that rendered and why, animations with symbolicated stacks, logs.

Input parameters:

- `fromMs` (number)
- `libraryFrames` (boolean): Include stack frames from node_modules.
- `session` (string): Default the last one.
- `toMs` (number)

### `scrub` (~38 tokens)

Set every recorded shared value to its value at a moment of the last recording, so the app shows that frame.

Input parameters:

- `atMs` (number, required)

### `play` (~35 tokens)

Play the last recording back into the app in real time, from a moment (default the start).

Input parameters:

- `fromMs` (number)

### `capture_frame` (~69 tokens)

A screenshot of the app. With atMs, first shows that moment of the last recording. Needs an app that can capture its screen (inspector_status says how to set it up).

Input parameters:

- `atMs` (number)
- `width` (number): Image width in pixels, default 390.

### `export_recording` (~142 tokens)

Render the last recording to a GIF or MP4 file, frame by frame from the app (needs captureScreen). MP4 needs ffmpeg on the PATH; GIF does not.

Input parameters:

- `format` (string, required)
- `fps` (number): Default 30.
- `fromMs` (number)
- `path` (string): Output file. Default keyframer-<time>.<format> in the project.
- `toMs` (number)
- `touches` (boolean): Draw where the fingers were (default true when the recording has touches).
- `width` (number): Pixels, default 390 for GIF and 720 for MP4.

### `list_recordings` (~86 tokens)

The recordings in this project's library (.keyframer/recordings), newest first: ones made on a device, saved in the panel or with save_recording, and the ones kept automatically when a recording stops (the panel's, record's, stop_recording's and run_scenario's; marked automatic, only the newest are kept), with the titles they were renamed to.

### `open_recording` (~110 tokens)

Open a recording file (.kfrec.json) made on a device (Motion Scan record button) or saved from the panel. It becomes the recording every other tool reads; returns its report. A recording from a build without Metro (an internal preview build) has raw stacks: pass that build's source map to map them to source lines.

Input parameters:

- `path` (string, required)
- `sourceMap` (string): The .map file of the bundle the recording's build embeds, for recordings from preview builds.

### `save_recording` (~98 tokens)

Keep the last recording for good in the library, as a .kfrec.json file the dev tools panel can open. record, stop_recording and run_scenario keep each recording automatically (only the newest automatic ones stay): saving one of those keeps that copy instead of writing a second one.

Input parameters:

- `path` (string): Default: the library, as <app>-<time>.kfrec.json. A path elsewhere writes a copy there.

### `get_screenshot` (~43 tokens)

A screenshot the recording took on the device (recordings made on the device carry a few): the one shown at atMs.

Input parameters:

- `atMs` (number, required)

### `replay` (~28 tokens)

Run the app's registered replay (registerReplay): re-mount the screen, re-run its entrance.

### `set_time` (~207 tokens)

Slow down, pause or step the app's animations on the device, to watch a fast animation or a glitch frame by frame (capture_frame shows the screen). scale: 1 is normal speed, 0.5 half, 0.25 a quarter, 0.1 a tenth, 0 paused. step, with scale 0: advance that many frames at the display's refresh rate, then hold again. Returns the speed the app says it runs at now; every panel shows the same. Recordings made while slowed carry time markers and their durations are stretched by 1 / scale: set scale 1 again before measuring. Needs an app that lists the time capability (inspector_status says).

Input parameters:

- `scale` (number, required): 1 normal speed, 0.5, 0.25, 0.1, or 0 to pause.
- `step` (number): With scale 0: frames to advance (1 to 120), then hold.

### `check` (~439 tokens)

Start a fix loop: measure the app and keep the result as the baseline recheck compares with. Scenarios (default all the app registered) run the median of several runs after a warm-up, each from a clean start (the app's reload). Or a recording: a .kfrec.json file (with sourceMap for a preview build), or "current" for the last recording; each of its problems is then verified by a scenario that reproduces it, by playing the recording back (UI-thread, rendering and layout problems only), or marked Not verifiable. Returns the problems ranked, each with a short ref (P1…), where it is, evidence, the fix, how it will be verified, and the motion that must keep working. With field (a Motion Vitals problem id from field_problems, like SHOP-12), it also says whether that call site dropped frames here: reproduced or not reproduced. Takes minutes on a big app.

Input parameters:

- `field` (string): A Motion Vitals field problem id (SHOP-12): say whether its call site dropped frames in this check. Needs KEYFRAMER_VITALS_READ_KEY.
- `recording` (string): A .kfrec.json file (a name in .keyframer/recordings, or a path), or "current" for the last recording.
- `reload` (boolean): Reload the app before each scenario (default true; apps that cannot reload run their replay).
- `runs` (number): Measured runs per scenario; the median counts. Default 3.
- `scenarioStub` (string): With a recording: write a registerScenario stub made from its screens and gestures to this file, when some problems have no scenario.
- `scenarios` (array): Scenario names (inspector_status lists them). Default: all. With recording: the scenarios that may verify it.
- `settleMs` (number): Keep recording after each run. Default 800.
- `sourceMap` (string): With a recording from a preview build: that build's .map file.
- `warmup` (number): Runs thrown away first. Default 1.

### `recheck` (~101 tokens)

Measure what check measured again, the same way, and compare with check's baseline. Returns Fixed (gone, and its animations still start and its values still move), Still there, New, Removed (gone because its animation or value stopped: not a fix), Not verifiable, the numbers before and after, and done: true or false with the reason. Call it after a change has reloaded in the app (Fast Refresh, hot reload or a rebuild).

### `field_problems` (~258 tokens)

The top field problems of a Motion Vitals project (slow frames from production, keyframer.dev/app/vitals), most frames lost first, in the dashboard's words: where each is (call site and screen), how many frames it drops while it runs against its screen's baseline, the devices and OS where it is worst, the causes of its slow frames, its status (New, Came back, Worse, Ongoing, Resolving, Fixed, Ignored), the check command and the dashboard's agent prompt. Then check with field: "<id>" measures it here. Needs KEYFRAMER_VITALS_READ_KEY: a workspace read key (kfw_) or a kf_ API key.

Input parameters:

- `limit` (number): How many problems, with their details. Default 5, at most 20.
- `os` (string)
- `project` (string, required): The project: its code (SHOP, as in SHOP-12) or its id.
- `status` (string): Default unresolved (new, came back, worse and ongoing); regressed is Came back; all for every status.
- `version` (string): Only this app version. Default: every version over the last 30 days.

### `field_compare` (~160 tokens)

Compare two versions of a Motion Vitals project, the way its Versions page does: hitch time, slow and frozen frames, janky sessions, and every problem call site as Worse, Came back, New, Still there, Better, Fixed or Ignored, with its drop rate in each version. Default: the latest version against the one before it with enough sessions. After a fix ships, it says whether the field problem is Fixed. Needs KEYFRAMER_VITALS_READ_KEY.

Input parameters:

- `from` (string): The older version. Default: the one before to with enough sessions.
- `project` (string, required): The project: its code (SHOP) or its id.
- `to` (string): The newer version. Default: the latest.

### `lint_project` (~255 tokens)

Read the project's source for the mistakes the inspector's Babel plugin finds while Metro builds it, without running the app (keyframer-inspect lint): worklet crashes (a worklet using a value declared after it, or calling a JS function on the UI thread; severity crash, always listed) and motion mistakes that do not crash (a descending interpolate range, scheduleOnRN on every frame, a spring config without mass, a shared value read while rendering, deprecated APIs…; severity error, warning or info). Over the project root this server was started with, or files and folders inside it; node_modules, build output and native folders are skipped. Returns each finding as file:line, severity, rule, message and its fix, most severe first. No app needs to be connected. React Native (Reanimated, worklets, Gesture Handler) only.

Input parameters:

- `limit` (number): Findings listed at most, most severe first. Default 50, at most 500.
- `paths` (array): Files or folders inside the project root, relative to it. Default: all of it.
- `severity` (string): The least severe motion finding listed. Default info (all). Worklet crashes are always listed.

## Diagnostics

Captured diagnostic sections: Provenance, Dependencies. The full working is on the page: https://verifymcp.io/servers/dev-keyframer-inspector/keyframerdev-inspector#diagnostics

## Score history

- 2026-11-05: 73
- 2026-11-04: 73
- 2026-11-03: 73
- 2026-11-02: 72
- 2026-11-01: 72
- 2026-10-31: 71
- 2026-10-30: 71
- 2026-10-29: 70
- 2026-10-28: 70
- 2026-10-27: 69
- 2026-10-26: 69
- 2026-10-25: 68
- 2026-10-24: 67
- 2026-10-23: 41
- 2026-10-22: 36
- 2026-10-21: 36

## Common questions

### What is the Keyframer Inspector MCP server?

Keyframer Inspector is an MCP server listed in the public MCP registry as dev.keyframer/inspector. Give your agent eyes for motion: record, slow down and test animations in mobile apps. This page covers its npm package (@keyframerdev/inspector).

### Is the Keyframer Inspector MCP server safe to use?

Keyframer Inspector scores 73 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 5 November 2026. It declares no install or post-install scripts. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the Keyframer Inspector MCP server expose?

Keyframer Inspector exposes 22 tools: inspector_status, record, start_recording, stop_recording, run_scenario, and 17 more. Their descriptions and schemas cost roughly 2,906 tokens of context every time the server is loaded.

### Is the Keyframer Inspector MCP server still maintained?

Keyframer Inspector is still listed as active in the MCP registry. We last reached this channel on 5 November 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

## Links

- npm package: https://www.npmjs.com/package/@keyframerdev/inspector
- Socket report: https://socket.dev/npm/package/@keyframerdev/inspector
- Repository: https://github.com/keyframer-dev/inspector
- Website: https://keyframer.dev/inspector
- Changelog RSS feed: https://verifymcp.io/servers/dev-keyframer-inspector/keyframerdev-inspector.xml
- Changelog JSON feed: https://verifymcp.io/servers/dev-keyframer-inspector/keyframerdev-inspector.json
- HTML version of this page: https://verifymcp.io/servers/dev-keyframer-inspector/keyframerdev-inspector
