venice-video-mcp
v0.5.0
Published
Token-lean MCP server that wraps the Venice Video Harness CLI (v2.3.x with automatic Seedance R2V → Wan 2.7 keyframes, no-overlap audio scheduling, and continuity rules). 6 verb tools + companion skills for consistency-first AI video creation.
Maintainers
Readme
venice-video-mcp
A token-lean MCP server for the venice-video-harness: consistency-first AI video creation through Venice — series, branded content, narrative, or any multi-shot workflow.
The server exposes 7 verb tools (~700 always-loaded tokens) instead of 20+ granular ones. Workflow knowledge lives in 4 companion skills that the agent loads on demand — including an optional directing bridge to the Seedance 2.0 Skill OS.
Tracks venice-video-harness v2.3.x (2026-05-20 sync): automatic Seedance R2V → Wan 2.7 keyframe pipeline for dialogue shots (CLAUDE.md rule 32; locks character identity into Wan 2.7 i2v's single keyframe and inline-TTS-generates the dialogue MP3 if absent), global no-overlap spoken-audio scheduling from measured clip durations (rules 35-36), per-shot reference re-anchoring to prevent cross-shot continuity drift (rule 37), Seedance scene-level multi-shot default, motion-classified routing (Wan 2.7 lip-sync for low/medium-motion dialogue), per-act music cues with crossfade + new time-varying
gainStops[], LUFS audio mix, FCPXML / Premiere xmeml / DaVinci-tuned timeline export,insert-shotmid-script, an upfront series-creation questionnaire (audioStrategy,videoFamilyPreference) that drives model selection + audio routing for the whole series, and the current model families: Seedance 2.0 (+ Fast variant), HappyHorse 1.1 (#1 blind-preference T2V+I2V; 7-language lip-sync, R2V up to 9 refs) + 1.0, Wan 2.7 (i2v / R2V / Spicy), Wan 2.6 (+ R2V), Runway Gen-4.5, DaVinci MagiHuman (30s lip-sync), PixVerse C1, Kling O3 4K / V3 4K, Grok Imagine (now with R2V), Sora 2 Pro (now 20s + true 1080p), Veo 3.1, LTX Video 2.0, Longcat. The MCP shells out to the harness CLI, so it picks up new harness commits automatically — only the tool surface / schemas / skills need to follow when the harness changes shape.
What this is
The harness is a complete TypeScript CLI for driving Venice's video, image, and audio APIs with character consistency, multi-shot planning, vision-based QA, and ffmpeg assembly. This MCP server is a thin adapter that lets MCP-aware clients (Cursor, Claude Code, Claude Desktop) drive that pipeline through natural-language tool calls.
The MCP server shells out to the harness CLI — zero coupling, no code duplication. Pull the harness, build it, point the MCP at it, and you're done.
flowchart LR
Client["MCP client<br/>(Cursor / Claude Code)"]
Server["venice-video-mcp<br/>stdio"]
Harness["venice-video-harness CLI<br/>(unchanged)"]
Venice["Venice API"]
FS["output/<series>/...<br/>local filesystem"]
Client -->|"7 tools"| Server
Server -->|"child_process.spawn"| Harness
Harness -->|"HTTPS"| Venice
Harness -->|"reads/writes"| FS
Server -->|"progress notifs"| Client
Client -.->|"loads on demand"| Skills["companion skills"]Tool surface
| Tool | Actions | Long-running? |
|---|---|---|
| series | new, list, set_aesthetic, explore_aesthetic | no |
| character | add, audition_voices, lock, generate_voice_reference | sometimes |
| location | add, generate_references, list | sometimes |
| episode | new, workshop, approve, storyboard, qa, qa_approve, fix_panel, insert_shot | sometimes |
| media | generate_videos, override_audio, generate_music, generate_ambient, validate, loop | yes (loop returns fast + runs in background; the rest stream progress) |
| assemble | assemble, produce, mix_audio, edit_transcribe, edit_render, edit_timeline, export_timeline | yes (progress; export_timeline is a fast XML write) |
| inspect | list, series, episode, shot, models, voices | no |
Locations are first-class environment entities with generated reference images; tag shots with location: <slug> and the ref is folded into panels + video (Kling scene_image_urls; Seedance / HappyHorse reference_image_urls + @ImageN). Voice references (character.generate_voice_reference) attach a per-character voice-donor clip as reference_audio_urls (@AudioN) on dialogue shots that route to Seedance 2.0 R2V / HappyHorse 1.1 R2V, keeping the voice consistent across shots.
For exact per-action arguments see skills/venice-mcp-cookbook/SKILL.md.
What the underlying harness does for you (v2.3.x)
Several behaviours the MCP relied on the agent to orchestrate are now automatic inside the harness:
- Automatic Seedance R2V → Wan 2.7 keyframe pipeline (CLAUDE.md rule 32). Every shot the planner routes to Wan 2.7 i2v first renders a Seedance R2V identity-lock pass with all character refs (no audio), extracts frame 1, and uses that frame as the Wan 2.7
image_url. Wan 2.7 i2v has noreference_image_urls; this is the only reliable way to keep its single keyframe identity-locked. If the dialogue MP3 isn't on disk and the character has a locked voice, the generator inline-TTS-renders it at the canonicalaudio/dialogue-shot-NNN.mp3so the assembler picks it up later — meaningmedia.generate_videosworks whether or notmedia.override_audio --dialoguewas run first. ~$0.85/shot for matching shots, surfaced in the start-of-run summary. Opt-out:videoDefaults.seedanceKeyframeForWan: false(series),disableSeedanceKeyframe: true(per shot). - Scene-level Seedance multi-shot grouping of adjacent same-character / same-location shots, so a single Venice generation can cover multiple consecutive shots while keeping identity anchored. Set
mustStaySingle: trueon a shot inscript.jsonto opt out. - Motion-classified video routing — shots with
motion: 'low' | 'medium'andfaceVisible: trueroute towan-2-7-image-to-videofor lip-sync; high-motion or face-occluded shots stay on the R2V model.episode.insert_shotacceptsmotiondirectly. - Per-act music cues with crossfade + per-shot
musicHoldautomation whenscript.jsondefines amusicCues[]array. v2.3.0 wiresgainthrough to a real ffmpegvolume=filter (was metadata-only before) and addsgainStops[]for time-varying gain ("drop -20% at the florida porch shot"). The single-bedmedia.generate_musicpath still works for episodes that want one uniform mood. - LUFS audio mix — final pass to -16 LUFS integrated / -1 dBTP true peak; SFX trim to ≤2s with a 0.3s fade. Override per-episode via
script.audioMix. - Upfront questionnaire (v2.3.0) —
series.newacceptsaudioStrategy: 'native' | 'lip-sync' | 'narrator-vo'andvideoFamilyPreference: 'auto' | 'seedance' | 'wan-3-0' | 'happyhorse' | 'minimax-h3' | 'minimax-h3-max' | 'minimax-h3-max-turbo' | 'grok-imagine' | 'kling-o3'. Persisted on the series and used at every downstream call:narrator-voauto-setsaudioMix.suppressModelNarration: true(Seedance is queued withaudio: falsefor every dialogue shot, no competing AI narrator) and flipsassemble-episode --dialogue-replacedefault totruewith--native-volume 0. The pipeline skill instructs the LLM to ASK these questions before callingseries.new. - Wan 2.7 audio pre-flight —
audio_urlclips shorter than 3s are auto-padded. - Silent-rejection guard (per-resolution thresholds in v2.3.0) — Venice "200 OK but no output" responses are detected and retried. Threshold scales with the requested resolution (1K → 50 KB, 2K → 150 KB, 4K → 400 KB) instead of a flat 30 KB.
- Shot-duration preflight (v2.3.0) —
media.generate_videosrunsassertShotDurationsValidbefore any Venice call and fails fast with an aggregated error listing every shot whose duration violates its routed model's ceiling or stepped ladder (e.g. 16s on Seedance R2V's 15s cap, 8s on Wan 2.7 R2V whose ladder is[5s, 10s]). - No-overlap dialogue / VO scheduling (v2.3.0) — spoken clips are scheduled from measured
ffprobedurations with one global cursor for narrator + characters, so long narration cannot bleed into the next shot's dialogue. If a line runs longer than the shot, hold the picture or shorten/split the line. - Per-shot continuity re-anchoring (v2.3.0) — every separately rendered shot should reuse the same canonical refs and restate invariant traits (identity, palette, wardrobe, relative size, in-story size/presence state) to prevent drift between generations.
- NLE timeline export —
assemble.export_timelinewrites FCPXML 1.10, Premiere xmeml v5, or a DaVinci-tuned FCPXML using format-specific file extensions so multiple exports can coexist for the same episode.
inspect.series and inspect.episode surface the relevant fields (storyboardAspectRatio, videoDefaults.lipSyncModel, videoDefaults.audioStrategy, videoDefaults.videoFamilyPreference, videoDefaults.seedanceCompatibility, videoDefaults.seedanceKeyframeForWan, videoDefaults.imageDefaults, musicCueCount, audioMix, timelineExports[]) so the agent can plan around them without parsing series.json by hand.
Companion skills
Four Markdown skills are shipped under skills/:
venice-mcp-pipeline— natural-language → tool-call recipes for the common end-to-end workflows.venice-mcp-cookbook— every action with copy-paste argument examples.venice-mcp-troubleshooting— every known production gotcha (wrong aspect ratio, character drift, Seedance provenance, filler-trim rules) with cause + fix.venice-mcp-directing— the directing bridge. Where pipeline decides which tool to call, this decides what the creative content says (concept, per-shot prompts, dialogue delivery, retakes, continuity) by bridging the Seedance 2.0 Skill OS onto the tool surface: direct the scene, don't decorate it.
Skills load on demand — they cost zero tokens until the agent decides it needs them.
Directing layer (optional)
The pipeline is the production crew — it locks character identity, runs QA, mixes audio, assembles, and exports. It does not, by itself, make a shot feel directed. For that, install the Seedance 2.0 Skill OS alongside this MCP.
That package is pure directing/prompting knowledge (no execution code): read a scene's dramatic function, name one intention, and derive camera, light, blocking, performance, and sound from it — instead of stacking "cinematic" adjectives — then hold one directorial voice across an entire story. Venice ships Seedance 2.0 (+ Fast) as a video model family, so that knowledge applies almost verbatim.
The venice-mcp-directing companion skill is the seam. It maps each Seedance OS sub-skill (seedance-interview, directing-engine, retake-protocol, continuation-handoff, seedance-copyright, seedance-antislop, vocab/*, …) onto the venice-video-mcp field it feeds (episode.workshop concept, per-shot description, character.add voiceDesc, the episode.qa → fix_panel loop, episode.insert_shot), and reconciles the three places the two systems collide:
- Identity — the harness owns it (R2V refs + the Seedance → Wan keyframe pass), so you direct intention/camera/light/blocking/sound and don't hand-write identity locks or
[Image1]reference tags into prompts. - Audio — both systems agree: native model dialogue + suppress model music/SFX + add music/ambient in post.
- Duration & multi-shot — the harness duration preflight, the 15s-default rule, and its automatic scene-level multi-shot grouping are authoritative; ignore Seedance OS's surface-specific durations and cut grammar.
Install it
Seedance OS is referenced, not vendored — install it separately so it stays fresh via its own updates. Common targets (verify in your client):
# Cursor workspace
.cursor/skills/seedance-20/
# Claude Code (workspace or global)
.claude/skills/seedance-20/ or ~/.claude/skills/seedance-20/
# .agents/skills convention (Codex, Antigravity, OpenCode, Amp, Goose)
.agents/skills/seedance-20/Clone the repo into the target directory (its root is shaped as the seedance-20 skill), or use its own installer (python scripts/install_codex_skill.py --force for Codex). Then install this repo's companion skills as usual (node bin/install-skills.js …) — the venice-mcp-directing bridge is auto-discovered.
The directing engine also reaches the harness directly: venice-video-harness carries the same "direct, don't decorate" instruction inside its in-code workshop system prompt and its .claude/ agents/skills/commands, so both the MCP path and the harness CLI produce directed prompts. See the harness README's directing section.
If Seedance OS is not installed, venice-mcp-directing still applies its self-contained core rule and the three reconciliations — you just lose the deeper genre library and multilingual vocabulary.
Installation
Both this server and the harness are on npm, so the normal path is two global
installs — no clone, no npm link, no hand-written paths. Cloning is only for
developing the server itself (see From source).
Install from npm (recommended)
# The harness carries model support + consistency rules; the MCP wraps it in 7 tools.
npm install -g venice-video-harness venice-video-mcp
venice-video --help # confirm the harness is on PATHWith both installed globally, the server finds venice-video on your PATH
automatically — you do not set HARNESS_BIN or HARNESS_PATH. The only
required env is VENICE_API_KEY; set HARNESS_WORKSPACE too if you want projects
outside the cwd. Skip to Configure your MCP client.
Install the companion skills into your runner's skills directory (the bins are on
PATH after the global install):
venice-video-mcp-install-skills --global # Claude Code / Cursor: ~/.claude/skills/
venice-video-mcp-install-skills --target hermes # Hermes: ~/.hermes/skills/venice/
venice-video-mcp-install-skills --dir <path> # any other runner's skills dirThe installer creates symlinks into the target — running it again is idempotent.
Use --uninstall to remove them (the source skills are untouched).
From source (development)
Clone both repos only if you want to run the server (or the harness) ahead of its published release:
# Harness
git clone https://github.com/jordanurbs/venice-video-harness.git
cd venice-video-harness && npm install && npm run build && npm link # exposes `venice-video`
# MCP server
git clone https://github.com/jordanurbs/venice-video-mcp.git
cd venice-video-mcp && npm install && npm run build
node bin/install-skills.js --global # or --workspace ./ , or bothPoint the server at your build with HARNESS_BIN (a specific
dist/mini-drama/cli.js) or HARNESS_PATH (the clone root); see
Configuration.
Configure your MCP client
With a global install the command is just venice-video-mcp. Only
VENICE_API_KEY is required; add HARNESS_WORKSPACE to control where projects
land.
Hermes Agent
hermes mcp add venice-video --command venice-video-mcp
hermes mcp test venice-video # confirm the handshake
# set VENICE_API_KEY (and HARNESS_WORKSPACE) in the server env per Hermes' configCursor (.cursor/mcp.json) / Claude Desktop / any JSON-config runner
{
"mcpServers": {
"venice-video": {
"command": "venice-video-mcp",
"env": {
"VENICE_API_KEY": "vn_...",
"HARNESS_WORKSPACE": "/abs/path/to/your/venice-projects"
}
}
}
}No global install? Run it on demand with "command": "npx", "args": ["-y",
"venice-video-mcp"]. Claude Desktop uses the same shape in
~/Library/Application Support/Claude/claude_desktop_config.json (macOS).
examples/cursor.mcp.json and examples/claude-desktop.config.json ship this
recommended shape, with the npx and local-build variants noted in each file's
_comment.
Claude Code (CLI)
claude mcp add venice-video -- venice-video-mcp
# then set VENICE_API_KEY (and HARNESS_WORKSPACE) via shell or claude_code configPointing at a local build instead
For the from-source path, set command to node with
the clone's bin/venice-video-mcp.js, and add HARNESS_BIN or HARNESS_PATH to
the env so the server uses your checkout rather than a published global (each
example file's _comment shows this variant).
Configuration
The MCP server reads these environment variables:
| Variable | Required | Purpose |
|---|---|---|
| VENICE_API_KEY | yes | Venice API auth (forwarded to the harness) |
| HARNESS_WORKSPACE | recommended | Where the MCP looks for series; defaults to cwd. Resolves project slugs against <workspace>/output/<slug>/ |
| HARNESS_BIN | optional | Explicit path to a built harness CLI (dist/mini-drama/cli.js). Set only to pin a local build |
| HARNESS_PATH | optional | Absolute path to a harness clone (with built dist/). Fallback for a local build |
| VENICE_MCP_UPDATE_CHECK | optional | Set to 0 / false to disable the daily GitHub release check. See Staying up to date. |
| GITHUB_TOKEN | optional | If set, the update check uses authenticated GitHub API quota instead of the anonymous 60/hr bucket. Read-only public_repo scope is enough. |
Resolution order for the harness binary (fixed in 0.4.0 — HARNESS_PATH now
outranks an ambient PATH binary, and the resolved binary is logged to stderr on
the first tool call):
HARNESS_BINif set and exists.HARNESS_PATH/dist/mini-drama/cli.jsifHARNESS_PATHis set.venice-videoon PATH (a globalnpm install -g venice-video-harness, ornpm linkin a clone).
With both packages installed globally you set none of these — resolution falls to
step 3 and finds the global venice-video. Set HARNESS_BIN/HARNESS_PATH only
to deliberately use a local checkout.
Where your video projects land
HARNESS_WORKSPACE should be a dedicated directory you own (e.g. ~/venice-projects/), not the harness repo. All series materialize under <HARNESS_WORKSPACE>/output/<slug>/ — the output/ segment is hardcoded by the harness, so HARNESS_WORKSPACE controls the parent of output/, not its replacement. Pre-create the directory; the server refuses to start if it doesn't exist. If HARNESS_WORKSPACE is unset, the server falls back to process.cwd(), which is rarely what you want for GUI-launched MCP clients.
ffmpeg and ffprobe must be on PATH (used by assemble.assemble, produce, edit_render, edit_timeline).
Staying up to date
Both this MCP and the venice-video-harness evolve fast — Venice ships new video, image, and audio models on a near-weekly cadence, and each one comes with its own prompt conventions, aspect-ratio quirks, character-consistency tricks, and provenance gotchas. The harness encodes those techniques (model registry, voice catalog, QA prompts, edit-pipeline rules) and the MCP's skills document them. Running an old install means the agent will literally not know that newer models exist or how to drive them correctly.
To keep that pain manageable without making the project a black box, the server includes a passive update check. It is fully transparent — here is exactly what it does, when, and what it sends.
What runs
On startup the server:
Reads a local cache at
~/.venice-video-mcp/update-check.json(24h TTL on success, 1h on failure). If a fresh result exists, the cached "update available" line is appended to the MCP server'sinstructionsfield on theinitializeresponse, so the agent sees it immediately.After the stdio transport is connected, in the background it makes up to two HTTPS calls:
GET https://api.github.com/repos/jordanurbs/venice-video-mcp/releases/latestGET https://api.github.com/repos/jordanurbs/venice-video-harness/releases/latest(only ifHARNESS_PATHis set so the harness version is readable from<HARNESS_PATH>/package.json)
Compares the returned
tag_nameagainst the localpackage.json#versionof each repo (simple semver compare; pre-release tags ignored). Writes the result to the cache file.If anything is behind, sends one
notifications/messagewithlevel: "info",logger: "venice-video-mcp", and a JSON payload of the form:{ "kind": "update-available", "message": "Update available: venice-video-mcp 0.1.0 → 0.2.0, venice-video-harness 0.3.2 → 0.4.0. Run `venice-video-mcp-update`.", "components": [ { "name": "venice-video-mcp", "current": "0.1.0", "latest": "0.2.0", "behind": true, "releaseUrl": "..." }, { "name": "venice-video-harness", "current": "0.3.2", "latest": "0.4.0", "behind": true, "releaseUrl": "..." } ], "checkedAt": "2026-05-11T19:30:00.000Z", "docs": "https://github.com/jordanurbs/venice-video-mcp#staying-up-to-date" }Cursor and Claude Desktop both surface
notifications/messagein their MCP log panel. The notification only fires when at least one component is actually behind; on a fully up-to-date install nothing is ever sent.
What it does not do
- It never auto-modifies your install. No
git pull, nonpm install, no rebuild happens unless you explicitly runvenice-video-mcp-update. - It never reports anything about you to GitHub. The requests are anonymous public-API GETs (no payload, no telemetry); GitHub's standard rate-limit headers are the only thing they observe. Set
GITHUB_TOKENif you want them counted against your authenticated quota instead of the shared 60/hr unauthenticated bucket. - It writes one file (
~/.venice-video-mcp/update-check.json) and reads two (<this-repo>/package.json,<HARNESS_PATH>/package.json). Nothing else on disk is touched by the check. - All errors are swallowed. Offline, behind a proxy, GitHub API down, no releases tagged yet — the server starts normally and the check just doesn't fire that day.
Acting on the notification
When you see the notice, run:
venice-video-mcp-update # interactive: pulls + builds both repos
venice-video-mcp-update --yes # non-interactive
venice-video-mcp-update --dry-run # show the plan without executing
venice-video-mcp-update --mcp-only
venice-video-mcp-update --harness-onlyThe updater refuses to run if either working tree has uncommitted changes — it will not clobber local edits. After it finishes, restart your MCP client so the new build is picked up.
Disabling the check
Set VENICE_MCP_UPDATE_CHECK=0 (also accepts false / no / off) in the env block of your cursor.mcp.json / claude_desktop_config.json. The startup banner will print update check disabled and no network call is ever made.
Why two repos
The MCP shells out to the harness CLI, so the harness is the one carrying new model support and consistency techniques. The MCP itself only changes when a tool surface, schema, or skill needs to follow the harness. In practice the harness ships updates more often, and an out-of-date harness is the more common cause of "this newer Venice model isn't working." That's why the check tracks both and the updater pulls both by default.
Usage
Once configured, talk to your MCP client in natural language. The agent reads the venice-mcp-pipeline skill on demand to map your request to tool calls.
"List my Venice series."
Calls
inspect { action: 'list' }. Returns the series catalog from<workspace>/output/.
"Make a new series called 'The Audacity' about a sarcastic talk-show host."
Calls
series { action: 'new', name: 'The Audacity', concept: '…' }, then prompts you for aesthetic.
"Produce episode 1 of the-audacity."
Calls
assemble { action: 'produce', project: 'the-audacity', episode: 1 }with progress notifications streaming during the long render.
For more recipes see skills/venice-mcp-pipeline/SKILL.md.
Architecture
venice-video-mcp/
├── bin/
│ ├── venice-video-mcp.js # stdio entry shim (built dist)
│ ├── venice-video-mcp-update.js # manual updater shim (git pull + build)
│ └── install-skills.js # skill installer shim
├── src/
│ ├── server.ts # registers 7 tools, stdio transport, schedules update check
│ ├── update-check.ts # GitHub releases poll, 24h cache, semver compare
│ ├── config.ts # HARNESS_BIN / HARNESS_PATH resolution
│ ├── harness.ts # spawn wrapper, stdout streaming
│ ├── progress.ts # parses harness stdout → MCP progress
│ ├── schemas.ts # zod discriminated unions + flat shapes
│ ├── responses.ts # { ok, paths, message } helpers
│ └── tools/
│ ├── series.ts
│ ├── character.ts
│ ├── location.ts
│ ├── episode.ts
│ ├── media.ts
│ ├── assemble.ts # also wraps the harness's edit-pipeline scripts
│ └── inspect.ts # reads JSON state directly (no spawn)
├── skills/
│ ├── venice-mcp-pipeline/SKILL.md
│ ├── venice-mcp-cookbook/SKILL.md
│ ├── venice-mcp-troubleshooting/SKILL.md
│ └── venice-mcp-directing/SKILL.md # bridge to Seedance 2.0 Skill OS
├── scripts/
│ ├── install-skills.ts # workspace + global symlink installer
│ └── update.ts # `venice-video-mcp-update` implementation
└── examples/
├── cursor.mcp.json
└── claude-desktop.config.jsonWhy a single-file-per-tool, action-discriminated design?
- Token frugality. Seven tools with one-line descriptions cost ~700 tokens vs ~3K for granular per-command tools. Skills carry the rest of the knowledge on demand.
- Schema correctness. Each tool's input is a flat
z.objectwith action enum + optional fields, so MCP clients see real JSON Schema (not empty objects). Internal validation runs through zod discriminated unions for full type safety. - No coupling to harness internals. Adding a new harness CLI command? Add a
casein the right tool, an action to the schema, and a cookbook example. No SDK refactor, no harness changes.
Why shell out instead of importing harness modules?
- The harness is a normal CLI app, not a library. Re-exposing every internal function as a public API would be a meaningful breaking change.
- Spawning means the MCP picks up harness fixes automatically (
git pullin the harness repo, that's it). - Per-call overhead is ~50ms — negligible against multi-minute Venice generation calls.
Development
npm run dev # tsx watch mode against src/server.ts
npm run build # tsc → dist/
npm test # (TODO)Manual smoke test of the stdio protocol:
cat <<'EOF' | HARNESS_PATH=/abs/harness HARNESS_WORKSPACE=/abs/harness node bin/venice-video-mcp.js | python3 -m json.tool
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"smoke","version":"0"}}}
{"jsonrpc":"2.0","method":"notifications/initialized"}
{"jsonrpc":"2.0","id":2,"method":"tools/list"}
{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"inspect","arguments":{"action":"list"}}}
EOFLicense
MIT. See LICENSE.
See also
- The harness: venice-video-harness
- MCP spec: modelcontextprotocol.io
- Venice API: venice.ai
