Skip to main content
Glama

MVR — My Video Resource

A self-hosted MCP server and local dashboard for building a reusable AI-video reference library.

MVR stores named Elements — characters, products, locations, styles — as structured, versioned reference images (not just text prompts), and hands that context to any MCP-compatible agent through @tags. It is a creative library and agent-context layer, not a video-generation model: the connected agent still does the actual generation, using its own provider integration.

MVR dashboard overview


Table of contents


Related MCP server: engram

Why MVR

AI video prompts repeat the same character, product, and location descriptions constantly. A small wording difference between scenes is often enough to make a character's face or a product's shape drift. Standard practice among AI video creators is to build a reference sheet for every recurring asset — a locked close-up of a face, a front/back turnaround of a body, a multi-angle sheet for a product — and reuse those exact images in every scene instead of re-describing them in words.

MVR turns that practice into a small, self-hosted service:

  • Reference images live in one place, organized by named Element and slot (angle/view), not scattered across chat history.

  • Each Element kind (character, prop, location, style) comes with a seeded checklist of which angles it needs, based on what actually keeps AI video output consistent.

  • Any MCP-compatible agent — Claude Desktop, Claude Code, Cursor, or a custom agent — can query the same library, so the work of building a character or product sheet is done once and reused everywhere.


How it works

Architecture

flowchart TD
    Creator(["🎬 Creator"])
    UI["Local Dashboard\nlocalhost:8080"]
    Agent["MCP-compatible Agent\nClaude · Cursor · custom"]
    MVR["MVR Server\nMCP tools + REST API"]
    DB[("SQLite Vault\nElements · Configs · Providers")]
    Assets[("Asset Storage\nlocal volume or S3")]
    Provider["External AI Provider\nimage / video generation"]
    Output(["🎥 Generated video / image"])

    Creator -->|manages library, keys| UI
    Creator -->|"chats: use @hero + @headphones"| Agent
    UI -->|REST, bearer token| MVR
    Agent -->|MCP tools, stdio or HTTP| MVR
    MVR --> DB
    MVR --> Assets
    Agent -->|its own provider integration| Provider
    Provider --> Output
    Output -.->|shown back to| Creator

The key boundary: MVR never calls the production generation API itself. It resolves @tags into reference assets and a saved model preference, and returns that to the agent — the agent performs the actual call to Higgsfield, OpenAI, or whichever provider it's configured with.

A typical request, step by step

sequenceDiagram
    participant C as Creator
    participant A as AI Agent
    participant M as MVR Server
    participant P as External Provider

    C->>A: "Generate a shot of @hero putting on @headphones"
    A->>M: resolve_prompt(text)
    M-->>A: resolved_text, elements_used (with asset paths),<br/>completeness_warnings
    A->>M: get_active_model("video-generation")
    M-->>A: provider, model, settings
    A->>P: generate(resolved prompt, references, settings)
    P-->>A: generated video / image
    A-->>C: result, plus any "you're missing @hero's back view" reminder

If an Element referenced in the prompt is missing a required reference angle, MVR does not block the request — it attaches a completeness_warnings entry so the agent can pass the reminder along, and the creator decides whether to fix it now or accept the risk.

Agent calling MVR tools

How an Element is structured

An Element is not one text field — it's a named record plus a set of slots, where each slot is a real, versioned reference image. The required slots depend on the Element's kind:

flowchart LR
    subgraph Element["Element: @hero (kind: character)"]
        direction LR
        S1["face_closeup\n✅ uploaded"]
        S2["body_front\n✅ uploaded"]
        S3["body_back\n⬜ missing"]
    end
    Element --> Check{"check_element_completeness"}
    Check -->|missing required slot| Warn["completeness_warnings\nreturned to agent"]
    Check -->|all required slots present| OK["Element ready to use"]

Kind

Required slots

Optional slots

character

face_closeup, body_front, body_back

variants via variantOf

prop

front, three_quarter

lateral, medial, top, rear, bottom

location

establishing_3_4

schematic_map

style

reference_image

audio, other

These recipes are seeded on first run and can be inspected at any time via get_kind_template.

Element slot uploader


Core concepts

Concept

What it is

Element

A reusable character, product, location, style, or other creative asset, referenced as @tag.

Element asset

A real, versioned PNG stored for one slot of an Element (e.g. face_closeup). Locking an asset prevents accidental overwrites.

Kind template

The seeded recipe of required/optional slots and best practices for a given kind.

Prompt format template

The model-specific structure a resolved prompt should follow (e.g. the Style/Characters/Scene/CUT blocks Seedance 2.0 expects). Kept separate from Element recipes, so a new model only needs a new format entry.

Model config

A saved provider + model + settings preference for one task, e.g. video-generation → Seedance → 2.0.

Provider

An encrypted API key stored for future evaluation features. Not used for production generation calls today.

Vault

The local SQLite database backing all of the above.


Quickstart

Local

cp .env.example .env
# Replace MVR_ENCRYPTION_KEY and MVR_AUTH_TOKEN with your own secrets.
npm install
npm run build
npm start
npm run dev       # watch mode
npm run build     # TypeScript build
npm test          # Vitest suite
npm run stdio     # run only the stdio MCP server

Docker

cp .env.example .env
# Replace MVR_ENCRYPTION_KEY and MVR_AUTH_TOKEN.
docker compose up --build

Docker Compose persists the database in the mvr-data volume and bind-mounts ./data/assets to /app/data/assets, so reference images stay inspectable on the host.

docker compose up

Connecting an MCP client

stdio (Claude Desktop, Claude Code, and similar):

{
  "mcpServers": {
    "mvr": {
      "command": "node",
      "args": ["/absolute/path/to/MVR/dist/index.js", "--stdio"],
      "env": {
        "MVR_DB_PATH": "/absolute/path/to/MVR/data/mvr.db",
        "MVR_ASSET_PATH": "/absolute/path/to/MVR/data/assets",
        "MVR_ENCRYPTION_KEY": "your-long-random-secret"
      }
    }
  }
}
Authorization: Bearer your-long-random-token
Accept: application/json, text/event-stream

MVR connected in Claude Desktop


MCP tools

Tool

Purpose

list_elements

List Elements.

get_element

Get an Element and its summary-version history.

create_element

Create an Element (tag, kind, displayName, summary, variantOf?, metadata?).

update_element

Update Element metadata or summary.

delete_element

Permanently delete an Element and its records.

upload_element_asset

Upload a PNG to a named slot (tag, slotName, image, sourcePrompt?, locked?).

list_element_assets

Return the current version of every filled slot.

check_element_completeness

Return { complete, missing: [{ slot, required, rationale }] }.

get_kind_template

Get a kind's slot recipe and best practices.

resolve_prompt

Resolve @tags into references, plus non-blocking completeness warnings.

get_prompt_format

Get a model-specific prompt format by provider and model.

list_model_configs / set_model_config / get_active_model / delete_model_config

Manage per-task model preferences.

list_providers

List provider names with masked API keys.


HTTP API

All endpoints are under /api and require the bearer token when MVR_AUTH_TOKEN is set.

Method

Endpoint

Purpose

GET, POST

/elements

List or create Elements.

DELETE

/elements/:tagOrId

Delete an Element.

GET, POST

/elements/:tagOrId/assets

List assets or upload one PNG.

GET

/elements/:tagOrId/completeness

Check required slots.

GET

/kind-templates/:kind

Get a seeded kind template.

GET

/prompt-formats?provider=Seedance&model=2.0

Get a prompt format template.

GET, POST

/providers

List masked providers or save a key.

DELETE

/providers/:name

Delete a provider.

GET, POST

/model-configs

List or save model configurations.

DELETE

/model-configs/:task

Delete a model configuration.


Storage

Local (default):

MVR_STORAGE_DRIVER=local
MVR_ASSET_PATH=/app/data/assets
MVR_ASSET_IMPORT_PATH=/app/data/imports

S3-compatible:

MVR_STORAGE_DRIVER=s3
MVR_S3_BUCKET=your-bucket
MVR_S3_REGION=us-east-1
MVR_S3_ACCESS_KEY_ID=...
MVR_S3_SECRET_ACCESS_KEY=...
MVR_S3_ENDPOINT=https://your-s3-compatible-endpoint   # optional

The SQLite database defaults to data/mvr.db locally and /app/data/mvr.db in Docker. Startup automatically migrates an existing Phase 1 database and seeds any missing templates without touching existing ones.


Security and operations

Area

Behavior

Operator responsibility

Provider keys

AES-256-GCM encrypted at rest; list output is masked.

Set and protect MVR_ENCRYPTION_KEY — changing it makes existing keys unreadable.

Authentication

API and MCP routes require a bearer token when configured.

Set MVR_AUTH_TOKEN before exposing MVR beyond a trusted network.

Assets

Real reference PNGs live on the configured local/S3 backend.

Back them up and control filesystem/bucket access.

File-reference uploads

Paths are constrained beneath MVR_ASSET_IMPORT_PATH.

Treat that directory as trusted local input only.

Generation

MVR never calls production image/video providers itself.

The connected agent owns provider calls and their security.


Current scope

Implemented

  • Multi-slot Elements with real, versioned, optionally locked PNG assets

  • Completeness checks and non-blocking prompt-resolution warnings

  • Seeded kind recipes and a seeded Seedance 2.0 prompt format

  • Local and S3-compatible asset storage

  • MCP over stdio and authenticated Streamable HTTP

  • Local dashboard, encrypted provider-key storage, per-task model configurations

Not yet implemented

  • Video/image generation orchestration

  • Automated evaluation runs or evaluation-driven template updates

  • Multi-user authentication and authorization

See ROADMAP.md for what's planned next.


License

A
license - permissive license
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/dannyhoang249-hub/Self-host-MCP-server-for-AI-video-reference-library'

If you have feedback or need assistance with the MCP directory API, please join our Discord server