Skip to main content
Glama
README.md
# MCP Media Orchestrator

A [FastMCP](https://github.com/jlowin/fastmcp) server that fronts several independent
image, video and audio generation backends behind **one capability-oriented tool
surface**.

An MCP client asks for "a 10 second video, at most 1080p". It does not ask for
Replicate, or Runway, or a specific model id. Routing, safety screening, job
lifecycle, concurrency limits and retention all live server-side, which is what makes
this an orchestration platform rather than a collection of adapters.

The design rationale is in [ARCHITECTURE.md](ARCHITECTURE.md). That document is the
point of this repository; the code is the proof it holds up.

## Quickstart

No credentials required. A deterministic in-process backend ships with the server, so
the full job lifecycle runs without a network call to any provider. FastMCP itself
performs a version check against PyPI on startup, which is its behaviour and not
this server's.

```bash
uv venv && uv pip install -e ".[dev]"
uv run pytest -q            # full lifecycle, routing, safety and timeout coverage
uv run mcp-media-orchestrator
```

Register it with an MCP client:

```json
{
  "mcpServers": {
    "media-orchestrator": {
      "command": "uv",
      "args": ["--directory", "/path/to/mcp-media-orchestrator", "run",
               "mcp-media-orchestrator"]
    }
  }
}
```

## Tools

| Tool | Purpose |
|---|---|
| `list_capabilities` | Every model reachable through this server, with cost, latency and ceilings |
| `generate_media` | Start a generation. Returns a `job_id` immediately, never blocks |
| `get_job` | Poll a job until `state` is terminal |
| `cancel_job` | Best effort provider-side, always terminal locally |
| `list_jobs` | Recent jobs, newest first, optionally filtered by state |

There is deliberately no `replicate_generate` or `elevenlabs_generate`. A client that
knows which provider to call is holding the platform's topology in its context, and
every provider change becomes a client change.

## Adding a backend

Implement four methods and register the adapter. Nothing else in the system changes.

```python
class MyBackend:
    name = "mybackend"

    def capabilities(self) -> Sequence[Capability]: ...
    async def submit(self, request, capability) -> str: ...
    async def poll(self, provider_ref) -> BackendStatus: ...
    async def cancel(self, provider_ref) -> None: ...
```

Backends publish capabilities synchronously so routing never blocks on a provider,
and they are submit/poll rather than await-to-completion because every serious media
generation API is already asynchronous underneath.

## Configuration

Environment variables, prefix `MEDIA_ORCH_`. See [.env.example](.env.example).

Credentials are read from the environment and never accepted as tool arguments. Tool
arguments are authored by a language model and travel through the client's context,
so a tool that takes an API key has already published it to the transcript.

## Status

Reference implementation. Job state is in-process, which is the first thing to
replace for a production deployment. See the scaling notes at the end of
[ARCHITECTURE.md](ARCHITECTURE.md).

MIT licensed.

TDQS

A4/5.0

Scored across 5 tools

Disambiguation5/5

Each tool maps to a distinct part of the media generation workflow: capability discovery, job submission, status polling, cancellation, and history listing. There is no meaningful overlap or risk of selecting the wrong tool for a given operation.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern using snake_case: list_capabilities, generate_media, get_job, cancel_job, list_jobs. The verbs clearly indicate the action and the nouns clearly indicate the target resource.

Tool Count5/5

Five tools is well-scoped for an orchestration server handling asynchronous media generation. Each tool covers a necessary part of the workflow without redundant or excessive surface area.

Completeness5/5

The toolset covers the full asynchronous job lifecycle: discover capabilities, create a job, poll for completion, cancel if needed, and list past jobs. There are no obvious dead ends for the stated purpose of routing and orchestrating media generation.

Maintenance

ActivityMaintained
ResponsivenessNo issues