Run a world model locally, and let any LLM agent call it as a tool. V-JEPA 2 as an MCP server.
Project description
wm
Run a world model locally, and let any LLM agent call it as a tool.
Live and unedited: Claude calls the surprise tool; V-JEPA 2 watches the clip and
reports where its predictions broke (3.0–4.9s, z≈2 — the test video's splice is at
exactly 4.0s). Wait time hidden, output verbatim.
LLMs can describe what happens when a cup gets knocked off a table. A world model
can watch it happen and tell you, frame by frame, where reality stopped matching
its prediction. wm puts Meta's V-JEPA 2
(MIT-licensed, 0.3B params) behind an MCP server,
so Claude, or any MCP client, can consult a video world model the way it consults a
database.
uvx wm-mcp serve
That's the whole install. First run downloads PyTorch and ~1.2GB of model weights — minutes of downloading, not a hang.
The demo
Ask your agent:
"Where does this clip stop being predictable? /path/to/video.mp4"
The agent calls surprise(), the world model slides a window over the video,
predicts each window's second half from its first, and reports the segment where
its prediction failed hardest — z-scored per video, so scores mean something.
The three tools
| Tool | What it does |
|---|---|
embed_video(source, start_s?, end_s?) |
Video, video slice, or still image → latent sequence, stored server-side under an opaque handle. Images become static clips — useful as goals. |
predict(handle, horizon_frames, target_handle?) |
Predict the trailing frames of a clip from its leading context (masked in-window prediction — horizon capped at clip length, this is not open-ended rollout). With target_handle, also returns cosine similarity between the prediction and a target embedding — "does this video end up looking like this photo?", computed server-side. |
surprise(source, window, stride, fps, start_s?, end_s?, max_windows) |
Streams over video of any length; per-segment "how wrong was the model" scores with timestamps in seconds + the most surprising segment. Long videos get an explicit compute budget (max_windows, default 120) and a resume_s cursor to continue — never a silent cap. |
compare(handle_a, handle_b) |
Cosine similarity between any two embeddings. "Are these two clips the same scene?", near-duplicate detection, frame-vs-reference matching. |
Latents never cross the wire: tools exchange handle IDs, tensors stay in the server.
Setup with Claude Code
Do it in this order — step 1 downloads PyTorch and the model weights (~4GB total) so your MCP client doesn't time out waiting on a first-run download:
uvx wm-mcp warmup # 1. one-time: pull deps + weights (minutes)
claude mcp add wm -- uvx wm-mcp serve # 2. register the server
Then: "embed this video and tell me how surprising the ending is".
Also usable directly, no agent:
uvx wm-mcp surprise clip.mp4
uvx wm-mcp embed clip.mp4
uvx wm-mcp warmup # pre-download weights so first real call is fast
uvx wm-mcp doctor # environment diagnostic + timed inference — paste into bug reports
uvx wm-mcp info
HTTP API (non-MCP consumers)
The same three primitives over localhost HTTP — for scripts, notebooks, or anything that doesn't speak MCP:
uvx wm-mcp serve --http # 127.0.0.1:8642
curl -s localhost:8642/health
curl -s -X POST localhost:8642/surprise -H 'content-type: application/json' \
-d '{"source": "clip.mp4"}'
Endpoints: GET /health, GET /info, POST /embed, POST /predict,
POST /surprise — one-to-one with the MCP tools. Binds to localhost, no auth;
don't expose it to the internet.
Things to ask your agent
- "Where does this clip stop being predictable? ~/Downloads/dashcam.mp4"
- "Scan the last 10 minutes of warehouse.mp4 and tell me if anything unexpected happens." (long footage scans in budgeted chunks — the agent resumes automatically via
resume_s) - "Here's a photo of the finished assembly (goal.jpg). Does assembly-run-3.mp4 end up looking like it?"
- "Are clip_a.mp4 and clip_b.mp4 the same scene?"
- "Embed the first 30 seconds and the last 30 seconds of the match and tell me how similar they are."
Hardware & honest numbers
- Apple Silicon (MPS): ≥16GB unified memory. Measured on an M2 Pro / 16GB:
surpriseon a 6s clip = ~10-18s end to end (fp16, 8fps sampling);wm-mcp doctorreports model load 9.3s, ~1.7s encode + ~1.1s predict per 16-frame window. A full 64-frameembed_videois the heavyweight case — expect minutes, not seconds. - NVIDIA (≥8GB VRAM): expected to work and to be faster — currently untested
by the author. Run
wm-mcp doctorand open an issue with the output; first confirmed CUDA report gets a thank-you in this README. - CPU works; it's just slow.
- The model loads in fp16 on GPU devices (fp32 attention over 8k tokens will swap a 16GB machine — we measured it, you don't want it).
- Bigger machine?
WM_MODEL=facebook/vjepa2-vitg-fpc64-256 wm-mcp serveswaps in a larger checkpoint (same V-JEPA 2 family only).
Known limitations
- Handles don't survive server restarts. Embeddings live in process memory; a new MCP session starts empty. Re-embed (it's seconds) rather than storing handles long-term.
- NVIDIA and Windows are untested. Linux CPU is exercised in CI; macOS/MPS is the developed-on path.
predictis masked in-window prediction, capped at clip length. It is not open-ended future simulation, and we won't pretend otherwise.- First run downloads ~4GB (PyTorch + weights).
wm-mcp warmupfront-loads this; don't skip it before registering the MCP server.
What this is (and isn't)
This is a probe — the smallest useful bridge between LLM agents and video world
models, shipped to find out whether anyone wants that bridge. It is not a robotics
stack, not a leaderboard, not a hosted service, and predict is honest about what
V-JEPA 2's predictor actually does (masked latent prediction within a clip), not a
marketing claim about simulating the future.
Public kill criteria, decided before launch: if by day 14 this has under 200 stars AND under 10 substantive issues/PRs from strangers AND under 3 unprompted integrations — it gets archived with a public retro. If it resonates, the next step is a protocol, not a feature list.
License
MIT. V-JEPA 2 weights are MIT-licensed by Meta FAIR.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file wm_mcp-0.10.0.tar.gz.
File metadata
- Download URL: wm_mcp-0.10.0.tar.gz
- Upload date:
- Size: 430.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1eec96e240cb246eef980e9dcf200d7b61f8cce0a90979df30de1ecbf6da8055
|
|
| MD5 |
c866473f58ffb746db1b48c231430aa3
|
|
| BLAKE2b-256 |
44b767e67c29fd52445ac6e1cb7cb9cde67506276104f7009bc5bce151190b16
|
Provenance
The following attestation bundles were made for wm_mcp-0.10.0.tar.gz:
Publisher:
ci.yml on rian-one/wm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
wm_mcp-0.10.0.tar.gz -
Subject digest:
1eec96e240cb246eef980e9dcf200d7b61f8cce0a90979df30de1ecbf6da8055 - Sigstore transparency entry: 2138846172
- Sigstore integration time:
-
Permalink:
rian-one/wm@2ce21ccdfb88d95e77bcee556ba400fbd7565a5f -
Branch / Tag:
refs/tags/v0.10.0 - Owner: https://github.com/rian-one
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@2ce21ccdfb88d95e77bcee556ba400fbd7565a5f -
Trigger Event:
push
-
Statement type:
File details
Details for the file wm_mcp-0.10.0-py3-none-any.whl.
File metadata
- Download URL: wm_mcp-0.10.0-py3-none-any.whl
- Upload date:
- Size: 24.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
66633aaa1321731011e92e7b9b79cdc84063d3edeb3ba8a210ffe7f8cff06982
|
|
| MD5 |
773e827f9f23396ceff72effb22b5e7b
|
|
| BLAKE2b-256 |
6c47edd4362c9a688d61a67c7b0257ad3300707b5ce9e74802fb12b8d9797cc1
|
Provenance
The following attestation bundles were made for wm_mcp-0.10.0-py3-none-any.whl:
Publisher:
ci.yml on rian-one/wm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
wm_mcp-0.10.0-py3-none-any.whl -
Subject digest:
66633aaa1321731011e92e7b9b79cdc84063d3edeb3ba8a210ffe7f8cff06982 - Sigstore transparency entry: 2138846178
- Sigstore integration time:
-
Permalink:
rian-one/wm@2ce21ccdfb88d95e77bcee556ba400fbd7565a5f -
Branch / Tag:
refs/tags/v0.10.0 - Owner: https://github.com/rian-one
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@2ce21ccdfb88d95e77bcee556ba400fbd7565a5f -
Trigger Event:
push
-
Statement type: