Skip to main content
Glama

MVR — Marketing Workflow & Visual Reference Vault

MVR is a self-hosted, local-first workspace and MCP server for keeping AI-assisted marketing work consistent with reusable brand context, visual references, evaluation rules, and human approval.

MVR is not a video or image generation provider. It stores and governs the context around creative work. Generation can be delegated to an external provider through a future or custom provider adapter.

What MVR provides

  • Reusable creative Elements referenced with @tags.

  • Versioned PNG reference assets organized into named slots.

  • Prompt resolution with missing-Element and incomplete-slot warnings.

  • A typed marketing workflow powered by LangGraphJS.

  • Deterministic evaluation with explainable issues and recommendations.

  • Human-review routing with persisted decisions and feedback.

  • Workflow checkpoints and event history in SQLite.

  • Draft-provider abstraction with a safe local deterministic provider.

  • MCP tools over stdio and authenticated Streamable HTTP.

  • REST endpoints and a local dashboard for operating the workflow.

  • Local filesystem or S3-compatible asset storage.

  • Encrypted provider credentials with masked API-key responses.

Related MCP server: LemGen AI Design MCP

Product flow

Creative references + marketing brief
                    ↓
          Resolve @Element context
                    ↓
              Create a draft
                    ↓
          Evaluate issues and risks
                    ↓
       Complete or request human review

Current workflow

The runnable vertical slice is:

Marketing brief
  → normalizeBrief
  → loadBrandContext
  → createDraft
  → evaluateDraft
  → decideNextStep
  → completed / waiting_for_human / failed

MVR marketing workflow graph

The graph is implemented in src/workflows/marketing-graph.ts with LangGraphJS StateGraph. Each business node follows this application-owned contract:

(state, context) → partial state update

Node responsibilities

Node

Responsibility

normalizeBrief

Trim and validate objective, audience, channel, and request.

loadBrandContext

Resolve @Element tags and collect assets, missing tags, and completeness warnings.

createDraft

Call the injected DraftProvider; the default provider creates a deterministic local draft.

evaluateDraft

Check unknown Elements and missing required slots.

decideNextStep

Complete clean runs or create a pending ReviewTask.

Every node checkpoint is persisted. The latest workflow state and the ordered event history can be inspected after a restart.

Architecture

MVR is a modular monolith. HTTP and MCP are adapters; application behavior is kept behind domain and application modules.

flowchart TD
    User[Marketing team]
    Web[Local dashboard]
    Client[MCP-compatible AI client]
    REST[REST adapter]
    MCP[MCP adapter]
    Service[MarketingWorkflowService]
    Graph[LangGraphJS StateGraph]
    Vault[(SQLite Vault)]
    Assets[(Local or S3 assets)]
    Provider[Injected DraftProvider]

    User --> Web
    User --> Client
    Web --> REST
    Client --> MCP
    REST --> Service
    MCP --> Service
    Service --> Graph
    Graph --> Vault
    Graph --> Provider
    Vault --> Assets

Main modules

Module

Role

src/index.ts

HTTP server, dashboard route, REST routes, and stdio entry point.

src/mcp.ts

MCP tool definitions and MCP adapter.

src/dashboard.ts

Self-contained local HTML dashboard.

src/vault.ts

SQLite facade, migrations, persistence, asset coordination, and event history.

src/storage.ts

Local and S3-compatible AssetStorage implementations.

src/crypto.ts

AES-GCM provider-secret encryption and masking.

src/workflows/marketing-graph.ts

Typed workflow state, nodes, graph assembly, and runner.

src/workflows/marketing-service.ts

Shared application boundary for REST, MCP, and web clients.

src/workflows/draft-provider.ts

Draft provider contract and deterministic local implementation.

Boundary rules

  1. REST and MCP handlers call MarketingWorkflowService, not graph internals.

  2. Business logic is not duplicated between adapters.

  3. Vault owns SQLite-backed persistence coordination.

  4. AssetStorage hides local filesystem and S3 implementation details.

  5. Provider secrets are encrypted at rest and never returned in plaintext.

  6. Evaluation returns explainable issues, not only a score.

  7. Missing creative context is surfaced as a warning and can route to review.

  8. External generation providers must be accessed through an adapter.

  9. Do not add queues, microservices, PostgreSQL, or vector infrastructure without measured operational requirements.

Core concepts

Elements

An Element is a reusable creative reference:

  • character

  • prop

  • location

  • style

  • audio

  • other

Example:

Create a product video featuring @hero and @headphones.

An Element can have versioned assets in slots:

@hero
├── face_closeup
├── body_front
└── body_back

Kind templates define required and optional slots. A character, for example, requires face_closeup, body_front, and body_back. Missing required slots produce completeness warnings.

Prompt resolution

resolve_prompt and Vault.resolvePrompt() replace known @tags with reusable context and expose:

  • resolvedText

  • elementsUsed

  • attached reference assets

  • missing unknown tags

  • completenessWarnings

Unknown or incomplete context is not silently discarded.

Workflow state

A workflow run is persisted under a caller-provided or generated runId.

The state contains:

  • marketing brief

  • resolved prompt context

  • draft

  • draft provenance (provider, model, generatedAt)

  • evaluation result

  • human-review requirement

  • structured ReviewTask

  • current node

  • status and errors

Statuses are:

running
completed
waiting_for_human
failed

The workflow_events table stores ordered node snapshots such as:

start
normalizeBrief
loadBrandContext
createDraft
evaluateDraft
decideNextStep

Draft providers

The graph depends on the DraftProvider interface rather than a specific model vendor:

interface DraftProvider {
  createDraft(request: DraftRequest): Promise<DraftResult>;
}

The default DeterministicDraftProvider is intentionally local and predictable. It does not call an external model. A real provider can be injected through MarketingWorkflowService without changing the graph or adapters.

Evaluation

The current evaluator is deterministic and checks:

  • unknown @Elements

  • incomplete required Element slots

A clean context receives score 1 and completes. Incomplete context receives score 0.5 and waits for human review. Future evaluators can add brand voice, channel fit, factuality, compliance, and model-based judging while retaining the deterministic gate.

Dashboard

The local dashboard is served from / and supports:

  • create and delete Elements

  • inspect required and optional slots

  • upload versioned PNG assets

  • lock an asset slot after approval

  • save encrypted provider credentials

  • configure task-specific models

  • submit a marketing brief

  • inspect workflow status, draft, evaluation, errors, and provenance

  • inspect checkpoint history

  • approve or reject pending human review with feedback

Open it after starting the server:

http://localhost:8080

MCP tools

The server supports MCP over stdio and authenticated Streamable HTTP.

Creative library

Tool

Purpose

list_elements

List reusable Elements.

get_element

Get an Element and version history.

create_element

Create a character, prop, location, style, audio, or other Element.

update_element

Update Element metadata or summary.

delete_element

Delete an Element and its records.

upload_element_asset

Upload a PNG to a named Element slot.

list_element_assets

List the current asset in each filled slot.

check_element_completeness

Check required slots against the kind template.

get_kind_template

Get slot recipes and best practices.

get_prompt_format

Get a provider/model prompt format template.

resolve_prompt

Resolve @tags into context and asset references.

Workflow

Tool

Purpose

run_marketing_workflow

Run and persist the marketing graph.

get_workflow_run

Read one persisted workflow run.

list_workflow_runs

List runs ordered by recent update.

get_workflow_events

Read ordered node checkpoint history.

resume_marketing_workflow

Approve or reject a pending human review.

Provider and model configuration

Tool

Purpose

list_model_configs

List task-specific model configurations.

set_model_config

Save a provider/model configuration.

get_active_model

Get the active model for a task.

delete_model_config

Delete a model configuration.

list_providers

List providers with masked API keys.

Example workflow input:

{
  "objective": "Introduce the campaign hero",
  "audience": "Existing customers",
  "channel": "social",
  "request": "Create a short post featuring @hero."
}

REST API

All REST routes are under /api. If MVR_AUTH_TOKEN is configured, they require a Bearer token.

Method

Endpoint

Purpose

GET, POST

/elements

List or create Elements.

DELETE

/elements/:tagOrId

Delete an Element.

GET, POST

/elements/:tagOrId/assets

List or upload Element assets.

GET

/elements/:tagOrId/completeness

Check required slots.

GET

/kind-templates/:kind

Get an Element kind template.

GET

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

Get a prompt format.

GET, POST

/providers

List or save encrypted provider credentials.

DELETE

/providers/:name

Delete a provider.

GET, POST

/model-configs

List or save model configurations.

DELETE

/model-configs/:task

Delete a model configuration.

POST

/workflows/marketing

Start a workflow run.

GET

/workflows/marketing

List workflow runs.

GET

/workflows/marketing/:runId

Read a workflow run.

GET

/workflows/marketing/:runId/events

Read checkpoint/event history.

POST

/workflows/marketing/:runId/review

Approve or reject human review.

Example:

curl -X POST http://localhost:8080/api/workflows/marketing \
  -H 'Content-Type: application/json' \
  -d '{
    "objective": "Launch the hero",
    "audience": "Existing customers",
    "channel": "social",
    "request": "Create a post featuring @hero."
  }'

Quickstart

Local

cp .env.example .env
# Set MVR_ENCRYPTION_KEY and MVR_AUTH_TOKEN in .env.
npm ci
npm run build
npm start

The server listens on 0.0.0.0:8080 by default.

Development mode:

npm run dev

Run tests and build:

npm test
npm run build

Run the stdio MCP server:

npm run stdio

Docker

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

Docker Compose persists SQLite data in the mvr-data volume and binds local assets through ./data/assets.

MCP client configuration

For a stdio-compatible client:

{
  "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"
      }
    }
  }
}

For Streamable HTTP:

http://localhost:8080/mcp
Authorization: Bearer your-long-random-token
Accept: application/json, text/event-stream

Configuration

Variable

Purpose

Default

PORT

HTTP port.

8080

MVR_AUTH_TOKEN

Bearer token for HTTP and MCP.

unset

MVR_ENCRYPTION_KEY

Key for encrypted provider credentials.

development fallback; set in production

MVR_DB_PATH

SQLite database path.

data/mvr.db

MVR_STORAGE_DRIVER

local or s3.

local

MVR_ASSET_PATH

Local asset root.

data/assets

MVR_ASSET_IMPORT_PATH

Trusted local PNG import directory.

data/imports

MVR_S3_BUCKET

S3-compatible bucket.

unset

MVR_S3_REGION

S3-compatible region.

us-east-1

MVR_S3_ACCESS_KEY_ID

S3-compatible access key.

unset

MVR_S3_SECRET_ACCESS_KEY

S3-compatible secret.

unset

MVR_S3_ENDPOINT

Optional S3-compatible endpoint.

unset

MVR_MIN_EVAL_RUNS_BEFORE_AUTO_UPDATE

Reserved threshold for future automatic recipe updates.

10

Security and operational notes

  • Set MVR_AUTH_TOKEN before exposing the server beyond localhost.

  • Set a high-entropy MVR_ENCRYPTION_KEY in production and back it up securely.

  • Changing the encryption key makes existing encrypted credentials unreadable.

  • Provider keys are encrypted at rest and masked in responses.

  • Only valid PNG assets up to 10 MB are accepted.

  • File references are constrained to MVR_ASSET_IMPORT_PATH.

  • Asset versions are preserved; locked slots cannot be overwritten.

  • Use the human-review route before publishing or taking irreversible actions.

  • The current local dashboard is intended for a trusted local workspace; multi-user authorization is not implemented by default.

Tests

The test suite covers:

  • Element versioning and prompt resolution.

  • Provider encryption and masking.

  • Model configuration.

  • Asset versioning, PNG validation, and locking.

  • Kind templates and completeness warnings.

  • Successful, failed, and human-review workflow paths.

  • LangGraph execution and node checkpoints.

  • Draft-provider injection and provenance.

  • Workflow event history.

  • Idempotent run IDs and brief-conflict protection.

  • SQLite persistence across vault reopen.

Run:

npm test
npm run build

Roadmap

Next

  • Replace the deterministic provider with external LLM/video provider adapters.

  • Add prompt/model version hashes and richer generation provenance.

  • Use LangGraph interrupt/checkpointer resume semantics for a true durable human-in-the-loop pause.

  • Add optimistic locking and stronger concurrency controls.

  • Add brand, campaign, and brief entities.

  • Add brand voice, compliance, factuality, and channel-fit evaluators.

Later

  • Bounded revise loops after human feedback.

  • Multiple AI provider adapters.

  • Integrations for Slack, Notion, Drive, Figma, HubSpot, and analytics.

  • Golden examples and regression evaluation datasets.

  • Brand drift detection and campaign-performance feedback.

  • Multi-user roles and approval policies.

Scope boundary

MVR currently does not:

  • generate videos or images by itself

  • replace external AI generation providers

  • automatically publish marketing content

  • automatically modify brand rules from model output

  • provide multi-user authorization by default

License

See the repository license for usage terms.

A
license - permissive license
Not graded
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.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • MCP server for Wan AI video generation

  • MCP server for Clipkit — gives AI agents a video toolbox via the Clipkit schema.

  • MCP server for Google Veo AI video generation

View all MCP Connectors

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