@postward-cc/creative-mcp
v0.3.0
Published
Local-first MCP server for video and image editing — ffmpeg and ImageMagick driven by natural language. 100% offline: no keys, no network calls, no uploads, no account.
Maintainers
Readme
postward-creative-mcp
Video and image editing on your own machine, driven by the AI assistant you already use. ffmpeg and ImageMagick under natural language — with zero network calls: no API keys, no account, no watermark, no telemetry, no uploads. Ever.
postward-creative-mcp is a local MCP server (Model Context Protocol —
the standard way AI assistants like Claude, ChatGPT, Cursor or Codex talk
to external tools). Once connected, your AI assistant can trim, merge,
crop, caption, speed up, reverse, watermark and convert your videos and
images — by simply asking for it in plain language.
You: "Cut the first 15 seconds, add my logo bottom-right and burn these subtitles."
AI: → trim_video + add_watermark + burn_subtitles (ffmpeg, 100% local)
→ "Done: /tmp/postward-creative/launch-final.mp4"Need AI generation (images, video, voiceovers)? That is Postward's hosted Creative — see How it fits with Postward.
Two products, one ecosystem
Postward ships two MCP servers with different jobs:
| | postward-creative-mcp (this repo) | Postward MCP (postward.cc) | |---|---|---| | What it does | Edits media on your machine (ffmpeg/ImageMagick) | Generates media (hosted AI with your keys) plus storage, review, scheduling and publishing | | Runs on | Your computer (Docker) | Postward's servers | | Network calls | None — 100% offline | Only to your AI providers, from Postward's servers | | API keys | None needed | Yours, sealed server-side | | Output | Local files + metadata | Workspace assets in Postward storage | | Cost | Free, open source, no account | Paid plans with credit metering | | Publishing | ❌ never | ✅ via review + approval | | Account required | ❌ never | ✅ |
This server never publishes, never uploads, and never talks to
Postward — it doesn't even go online. It is a complete standalone
product. If you later want AI generation, durable asset storage, team
review, approval flows, scheduling or social publishing, the
Postward MCP picks up exactly where this tool
ends — one of its tools (prepare_for_postward) even formats your
file's metadata for that handoff. But that's optional, and nothing in
this repo nags you about it.
Installation
The only dependency is Docker. The image ships ffmpeg, ImageMagick and
fonts — nothing to install on your machine, no Node.js, no keys, no accounts.
Generated files persist through the named volume (postward-creative-output)
shown below; you can also bind-mount any local folder instead.
Step 0 — install Docker (once)
If you don't have it yet:
- Windows / macOS: install Docker Desktop (free for personal use) and start it once — it must be running for your assistant to reach the tools.
- Linux: install Docker Engine —
curl -fsSL https://get.docker.com | sh— and add yourself to the docker group so you can run it without sudo:sudo usermod -aG docker $USER(log out and back in).
Check it works:
docker --versionIf that prints a version, you're ready. Without Docker running, the server cannot start and no tools appear in your assistant — that is expected; there is no fallback (this is what keeps your machine clean and your files local).
Step 1 — connect the server to your assistant
Option A — one command (Claude Code)
claude mcp add postward-creative -- docker run -i --rm -v postward-creative-output:/tmp/postward-creative ghcr.io/postward-cc/postward-creative-mcp:latestFor Codex CLI, add the same server to ~/.codex/config.toml:
[mcp_servers.postward-creative]
command = "docker"
args = ["run", "-i", "--rm", "-v", "postward-creative-output:/tmp/postward-creative", "ghcr.io/postward-cc/postward-creative-mcp:latest"]Option B — config file (Claude Desktop, Cursor, anything that speaks MCP)
Add to claude_desktop_config.json or .cursor/mcp.json and restart the app:
{
"mcpServers": {
"postward-creative": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"-v", "postward-creative-output:/tmp/postward-creative",
"ghcr.io/postward-cc/postward-creative-mcp:latest"
]
}
}
}Restart your AI assistant. That's it — ask it "what tools do you have for video editing?" and it will discover this server. There is nothing to configure after that — no keys, no accounts.
Prefer to avoid Docker? It's possible to run the bundle directly with Node.js 22+, but then you must provide ffmpeg, ffprobe, ImageMagick and fonts on your PATH — that's why Docker is the supported path. See Development if you want to go this route.
Your first edit
With the server connected and your assistant restarted, just talk to it.
Grab any video (say, ~/Videos/demo.mp4) and try:
Trim ~/Videos/demo.mp4 to the first 20 seconds, add the text
"MY LAUNCH" in white at the bottom, and burn subtitles from
~/Videos/legendas.srtYour assistant will chain trim_video → overlay_text → burn_subtitles
and answer with something like:
{
"filePath": "/tmp/postward-creative/7f3a….mp4",
"mimeType": "video/mp4",
"bytes": 2411724,
"sha256": "9f86d081884c7d65…"
}Two things to know:
- Where the files are. Outputs live inside the container's
/tmp/postward-creative, which the named volume keeps across restarts. Want them in a normal folder? Bind-mount one in the config instead —"postward-creative-output:/tmp/postward-creative"becomes"/Users/you/Videos/out:/tmp/postward-creative"— and every result lands in that folder directly. - Errors are loud. If something can't be done (wrong path, invalid parameter, unsupported aspect), the tool fails with a machine-readable error your assistant can read and correct — it never silently produces the wrong video.
More one-liners to try: "make a 3-second GIF from clip.mp4 starting at 0:05"
(create_gif), "normalize this to vertical 9:16" (transcode_video),
"what's in this file?" (probe_media), "join these two clips"
(concat_videos).
What your assistant can do
Video editing (ffmpeg — 16 tools, free, 100% local)
trim_video, concat_videos, transcode_video (9:16 / 1:1 / 16:9),
extract_frame, extract_audio, create_gif, add_watermark,
burn_subtitles, add_fade, change_speed, reverse_video, flip_video,
crop_video, adjust_volume, replace_audio, overlay_text
Image tools (ImageMagick — 4 tools, free, 100% local)
resize_image, convert_format (PNG ↔ JPEG ↔ WebP), image_thumbnail,
image_info
Utilities
| Tool | What it does |
|---|---|
| probe_media | Duration, resolution, codecs, bitrate of any media file |
| checksum_file | SHA-256 of any file |
| list_tools | Everything this server offers, in one list |
The optional Postward bridge
| Tool | What it does |
|---|---|
| prepare_for_postward | Formats a local file's metadata (path, MIME, bytes, SHA-256) for Postward's upload flow. No upload, no auth — just the handoff info. |
Every result is portable
Every edit returns:
{
"filePath": "/tmp/postward-creative/a1b2….mp4",
"mimeType": "video/mp4",
"bytes": 1048576,
"sha256": "9f86d081884c7d65…"
}The file is yours — a plain local file with a checksum and its MIME type. No account needed to open it, no watermark on it, no strings attached.
Non-negotiable principles
- The server makes zero network calls. Not "telemetry-free": the editing tools cannot phone home. The only network touch in the whole project is the launcher's explicit update check at container start.
- No API keys, no account — editing is local compute, forever free.
- No watermark on any output — ever.
- No uploads — your media never leaves your machine through this server.
- No feature gating behind Postward signup — every tool works standalone.
- No silent fallbacks — errors carry machine codes and sanitized messages; wrong inputs fail loudly instead of degrading.
How it differs from hosted AI tools
- Your machine, your files. Media never sits on someone else's server — this server has no network stack usage at all.
- Standard MCP. Works with any MCP-capable assistant — Claude Desktop, ChatGPT desktop, Cursor, Codex CLI, and anything else that speaks MCP.
- Open source, MIT licensed. Audit it, fork it, self-host it.
How it fits with Postward
The moment content needs to leave your laptop — AI generation, scheduling
to multiple social accounts, a teammate reviewing before anything goes
out, an approval trail for clients, one library of every asset — that's
Postward. This tool edits locally; Postward
generates, governs and publishes. The handoff is one step
(prepare_for_postward), and it's optional forever.
Development
git clone https://github.com/postward-cc/postward-creative-mcp
cd postward-creative-mcp
npm install
npm run typecheck # strict TypeScript
npm test # unit suite (arg builders, contracts, server surface)
npm run build # typecheck + esbuild bundle → dist/index.cjs
node scripts/e2e.mjs # e2e: drives the bundled server through every toolThe e2e harness spawns the real server, calls all 23 tools on generated
fixtures plus a multi-tool pipeline (trim → caption → brand → fade → speed →
checksum → handoff), and asserts on the actual output files. CI runs it
inside the Docker image (.github/workflows/e2e.yml), so the artifact
users pull is exactly what gets exercised — on GitHub-hosted runners, with
layer cache.
On top of that, .github/workflows/client-smoke.yml (manual dispatch +
weekly schedule) runs a real third-party MCP client: it installs
oh-my-pi in a container, registers
the bundled server via project .mcp.json, and has the omp agent execute
all 23 tools, asserting a 24/24 PASS report. Needs an OMP_MODEL_API_KEY
secret (an LLM key with credits); without it the job self-skips.
The same flow works locally: point a project .mcp.json at the server and
run any MCP client — omp -p, Claude Desktop, Cursor, mcode, …
- Stack: TypeScript, Node.js 22+, official MCP SDK, esbuild.
- Releases: pushing a
v*tag publishes the Docker image toghcr.io/postward-cc/postward-creative-mcpand the package to npm (@postward-cc/creative-mcp).
The pure FFmpeg argument primitives are also exported as a typed package subpath for other Postward tools to share:
import {
atempoChain,
concatListContent,
escapeFilterValue,
parseTimestamp,
} from "@postward-cc/creative-mcp/ffmpeg-args"This subpath has no filesystem or process effects: callers provide paths,
consume argument/filter strings, and keep their own I/O, validation policy and
error presentation. The Creative MCP adapts shared input errors to
CreativeError; other consumers can adapt them to their own domain.
License
MIT — © Postward
Updating
Already handled: every start, the launcher checks ghcr for a newer image, pulls it when one exists, and falls back to the cached image when offline. New releases reach you on the next assistant restart, with zero action.
Manual option (or to refresh while offline-then-online without restarting):
scripts/update.shTo know which version a session is running: ask your assistant — the server
reports its version in the MCP handshake. (Windows users with the plain
docker run config: docker pull <image> + restart.)
