FrameJam

Frame-accurate video and storyboard review for coding agents, plus style and playbook presets

By Moritz Kremb (individual) TypeScript Local · stdio, Streamable HTTP MediaDeveloper tools

50 popularity score ★ 69 ↓ 321/wk

Connect your client

Local (once it is running)

Add in one click

Opens the app, which asks before it adds the server.

Or add it by command or config

Claude CodeTerminal
claude mcp add --transport http framejam http://localhost:2400/mcp
Cursor~/.cursor/mcp.json
{
  "mcpServers": {
    "framejam": {
      "url": "http://localhost:2400/mcp"
    }
  }
}
VS Code.vscode/mcp.json
{
  "servers": {
    "framejam": {
      "type": "http",
      "url": "http://localhost:2400/mcp"
    }
  }
}
Codex~/.codex/config.toml
[mcp_servers.framejam]
url = "http://localhost:2400/mcp"
Gemini CLITerminal
gemini mcp add --scope user --transport http framejam http://localhost:2400/mcp
Local (npm)

Add in one click

Opens the app, which asks before it adds the server.

Or add it by command or config

Claude CodeTerminal
claude mcp add framejam -- npx -y framejam --stdio
Claude Desktopclaude_desktop_config.json
{
  "mcpServers": {
    "framejam": {
      "command": "npx",
      "args": [
        "-y",
        "framejam",
        "--stdio"
      ]
    }
  }
}
Cursor~/.cursor/mcp.json
{
  "mcpServers": {
    "framejam": {
      "command": "npx",
      "args": [
        "-y",
        "framejam",
        "--stdio"
      ]
    }
  }
}
VS Code.vscode/mcp.json
{
  "servers": {
    "framejam": {
      "type": "stdio",
      "command": "npx",
      "args": [
        "-y",
        "framejam",
        "--stdio"
      ]
    }
  }
}
Codex~/.codex/config.toml
[mcp_servers.framejam]
command = "npx"
args = ["-y", "framejam", "--stdio"]
Gemini CLITerminal
gemini mcp add --scope user framejam npx -- -y framejam --stdio
Local (from source)

Add in one click

Opens the app, which asks before it adds the server. Then replace each <NAME> in its settings with your value.

Or add it by command or config

FirstTerminal
git clone https://github.com/moritzkremb/framejam.git
cd framejam
npm install
npm run build
Claude CodeTerminal
claude mcp add framejam -- node '<ABSOLUTE_PATH_TO_CLONE>/dist/server/cli.js' --stdio
Claude Desktopclaude_desktop_config.json
{
  "mcpServers": {
    "framejam": {
      "command": "node",
      "args": [
        "<ABSOLUTE_PATH_TO_CLONE>/dist/server/cli.js",
        "--stdio"
      ]
    }
  }
}
Cursor~/.cursor/mcp.json
{
  "mcpServers": {
    "framejam": {
      "command": "node",
      "args": [
        "<ABSOLUTE_PATH_TO_CLONE>/dist/server/cli.js",
        "--stdio"
      ]
    }
  }
}
VS Code.vscode/mcp.json
{
  "servers": {
    "framejam": {
      "type": "stdio",
      "command": "node",
      "args": [
        "<ABSOLUTE_PATH_TO_CLONE>/dist/server/cli.js",
        "--stdio"
      ]
    }
  }
}
Codex~/.codex/config.toml
[mcp_servers.framejam]
command = "node"
args = ["<ABSOLUTE_PATH_TO_CLONE>/dist/server/cli.js", "--stdio"]
Gemini CLITerminal
gemini mcp add --scope user framejam node -- '<ABSOLUTE_PATH_TO_CLONE>/dist/server/cli.js' --stdio

Settings 4

FRAMEJAM_PORT Optional: Port for the review page and HTTP MCP endpoint (also --port). FRAMEJAM_HOST sets the address. Default 2400.
FRAMEJAM_HOME Optional: Data folder for projects and custom presets (also --data-dir). Default ~/.framejam.
FRAMEJAM_CATALOG_URL Optional: Where style and playbook updates come from. off turns them off. Default https://www.framejam.ai/catalog/v1. For catalog updates.
FRAMEJAM_NO_UPDATE_CHECK Optional: Set to stop the npm version check and the catalog updates.

What it does

FrameJam gives a person and a coding agent a shared place to review a video the agent is making. The agent renders an mp4 with whatever the project already uses (Hyperframes, Remotion, ffmpeg) and calls `open_review`. That opens a local page with the player, a filmstrip and a comment box. You pause, click a spot in the frame or drag over part of the timeline, type a note, and press Finish review when the round is done. The agent gets every comment back with its time, its position and a JPEG of the frame with your pin drawn on it, then makes its edits and sends the next render through `add_version`. Old rounds keep a copy of their video. Storyboards work the same way, with still panels instead of a video.

For videos with speech the agent can now pass `transcriptPath` (an .srt, .vtt or word-timings JSON) to either tool. The words then sit under the timeline and you can comment on a phrase. Without one, the page can transcribe on your machine if whisper.cpp is installed.

The agent can also read visual styles and playbooks before building. A playbook describes how one kind of video gets made, like a lyric video or a math explainer. A picker page lets you choose them by clicking. Since this release the styles and playbooks also update from a signed catalog on framejam.ai, checked at start and every 6 hours, so new ones can arrive without a new npm version.

It all runs as one Node process and keeps projects as JSON in `~/.framejam`. The npm package is mostly an installer for plugins in Claude Code, ChatGPT and Cursor. Other clients run `npx -y framejam --stdio`, and the same process serves MCP over HTTP at `http://localhost:2400/mcp`.

From the source, beyond the README: `open_review` also takes `playbookId` and `styleId` so later versions keep the chosen look. Both wait tools accept `timeoutSeconds` up to 300. Every setting is also read under the old `FRAMECUT_` prefix. And the catalog stays off in a source checkout unless `FRAMEJAM_CATALOG_URL` is set.

What it needs

RuntimeNode.js 22+
Runs onmacOS, Windows, Linux
Also
  • ffmpeg on the PATH
  • a web browser for the review page
  • whisper.cpp, optional, for transcripts the agent does not supply

The installer (`npx -y framejam install`) sets up plugins for Claude Code, the ChatGPT desktop app (Work and Codex) and Cursor. Any other client can use the stdio command. ChatGPT chat-mode connectors need the HTTP server (`npm start` from a clone) and, where an https address is required, a tunnel plus `FRAMEJAM_PUBLIC_URL`. Local transcription needs whisper.cpp (`brew install whisper-cpp` on macOS) and downloads a 574 MB model from Hugging Face the first time unless one is already present.

Limits

  • Not covered Reviews renders only. Making or editing the video is done by the agent with another tool.
  • Limit Only one process hosts the web page per port. Other stdio instances reuse it, and if the host exits one has to be restarted.
  • Early release The page is a plain web page and is not yet embedded as an MCP App.
  • Limit wait_for_feedback returns pending after 50 seconds by default (up to 300 with timeoutSeconds). After 12 pending results the agent is told to stop.
  • Limit wait_for_pick tells the agent to stop after 6 pending results in a row and ask in chat instead.
  • Not covered FrameJam Cloud (framejam login, framejam cloud on, share_project, guest voice comments) is on the main branch only. The 0.6.0 release has none of it.
  • Limit The main branch README describes wait_for_feedback with a cursor and a waiting status. The published release still returns pending.
  • Limit The npm package leaves out preview videos and streams them from framejam.ai. Some styles and playbooks only appear once the catalog has been fetched.
  • Platform Desktop apps started from the Dock may not find npx. The docs say to give its full path.

It reviews renders only; the agent makes and edits the video with another tool. The README's v1 limitations: only one process hosts the web page per port (other stdio instances reuse it through the shared data folder; if the host exits, one must be restarted), and the page is not yet embedded as an MCP App. `wait_for_feedback` returns pending after about 50 seconds by default; after 12 pending results in a row the agent is told to stop and the user must ask it to apply the feedback later. Desktop apps started from the Dock may not find `npx`; the docs say to use its full path. The npm package leaves out preview videos and streams them from framejam.ai.

Who it suits

Suits developers who already have an agent building videos in code (Hyperframes, Remotion, ffmpeg scripts) and would rather point at a frame than describe timestamps in chat. It is local, needs no account and keeps videos on the machine, which fits private footage. It writes only to its own data folder. Look elsewhere if you need the server to render or cut video itself, or a hosted review page other people can open: in the release on npm the page is served on localhost, bound to 127.0.0.1 unless --host is given.

Tools 14

9 only read, 5 change things. A ? marks an optional parameter.

open_review changes
Start a review of a render or a set of storyboard panels and return its local URL. The same title adds a versiontitle?: stringvideoPath?: stringpanels?: arraypanelsDir?: stringtranscriptPath?: stringreviewId?: stringnote?: stringplaybookId?: stringstyleId?: string
wait_for_feedback
Block until the reviewer finishes a round, or return pending after the timeoutreviewId: stringtimeoutSeconds?: number
get_feedback changes
Fetch the newest round of comments at once and lock that versionreviewId?: stringinclude?: enum
list_reviews
List reviews with their URLs and the state of each round
add_version changes
Attach a new render or new panels as the next round, with a note for the reviewerreviewId: stringvideoPath?: stringpanels?: arraypanelsDir?: stringtranscriptPath?: stringnote?: string
resolve_comments changes
Mark comments as handled, as bookkeeping for the agentreviewId: stringids: arraynote?: string
list_presets
List the style presets, filtered by mood, pacing, format or textmood?: stringpacing?: enumformat?: enumquery?: string
get_preset
Return one style's look rules and example file list, optionally with the example sourceid: stringincludeTemplate?: boolean
list_playbooks
List the playbooks with inputs, outputs, cost and creatorquery?: string
get_playbook
Return a playbook's method, local files and how a chosen style fits itid: stringstyleId?: string
open_picker changes
Open a page where the user picks a playbook, a style or bothkinds?: arraytitle?: string
wait_for_pick
Wait for the picker result and return the chosen playbook and stylepickId: stringtimeoutSeconds?: number
get_selected_preset
Legacy tool kept for older skills. Points the agent to open_picker
get_selected_playbook
Legacy tool kept for older skills. Points the agent to open_picker

Similar servers