# mulmocast 2.12.1: an npm install that ignores the yarn pins, a Dockerfile that installs the published package, and a quick start still on 0.1.x

> MulmoCast turns a JSON script called MulmoScript into video, podcast, PDF and other outputs by calling hosted model providers. Its own files disagree about how it is built and installed: the README says npm while the security pins live in a yarn-only block, the container image installs mulmocast from npm rather than the checkout it was built from, and the quick start link still points at the 0.1.x beta notes.

**receptron/mulmocast-cli** — AI-powered podcast & video generator.

- Repository: https://github.com/receptron/mulmocast-cli
- Stars: 475 · Forks: 82
- Language: TypeScript
- License: not declared
- Published: 2026-08-23 · Updated: 2026-08-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/receptron-mulmocast-cli

## The quick start still sends you to the 0.1.x beta notes

The first section a reader meets is titled Quick Start Guide, and it offers two links for trying the beta: `./docs/beta1_en.md` and `./docs/beta1_ja.md`. The package those notes describe is numbered 0.1.x. The version in `package.json` is `2.12.1`, and the matching npm release is tagged `mulmocast@2.12.1`, dated 2026-09-24. So the instructions a newcomer is told to follow, the install command printed a few lines below them, and the published artifact are three different eras of the same tool. The install line itself carries no version and resolves to whatever npm currently serves:

```bash
npm install -g mulmocast
```

The tree keeps three changelog files at that version, `CHANGELOG-0.x.md`, `CHANGELOG-1.x.md`, and `CHANGELOG.md`, so the history between the beta notes and today is spread across separate documents rather than one.

## npm test and ci_test run disjoint suites, and one deletes from a missing directory

Two test entry points exist and they share nothing. `test` is a shell pipeline that starts by deleting files and then calls the real CLI three times:

```
"test": "rm -f scratchpad/test*.* && npx tsx ./src/cli/bin.ts audio scripts/test/test.json && npx tsx ./src/cli/bin.ts images scripts/test/test.json && npx tsx ./src/cli/bin.ts movie scripts/test/test.json"
```

`ci_test` is a different command entirely, running the Node test runner with coverage across `./test/*/test_*.ts` under `NODE_ENV=test`. The default `test` script sets no environment variable, so the two suites do not even share configuration, and a dedicated `tsconfig.test.json` sits beside `tsconfig.json` for the suite that `test` does not use. The first thing the default script does is `rm -f scratchpad/test*.*`, and `scratchpad` is not among the top level entries in the tree.

## The README says npm, the lockfile is yarn, and the pins live in resolutions

The install instruction is npm. The lockfile committed to the repository is `yarn.lock`. The three dependency overrides sit in a `resolutions` block:

```
"resolutions": {
    "minimatch": "^10.2.6",
    "tar": "7.5.22",
    "yauzl": "^3.4.0"
  },
```

`resolutions` is a yarn field. npm reads `overrides` instead, so installing `mulmocast` with the command the README gives you puts none of these three pins into effect. The block is also inconsistent with itself: `tar` is pinned to an exact version with no range marker, while `minimatch` and `yauzl` carry carets and will float within their major. Meanwhile the developer scripts reach for `npx tsx` and `cross-env`, both npm-flavoured runners. One repository, two package managers, and a security floor that only one of them applies.

## The Dockerfile installs the published package and ignores the checkout

The README offers a container route after the ffmpeg note:

```
docker build -t mulmo-cli .
```

The build file behind that command is three instructions on top of `FROM node:24`. The second line is `RUN apt update -y && apt install -y ffmpeg && npm install -g mulmocast`. That last clause pulls the released package off npm, so the image contains the registry build and none of the source you just cloned. Building from a feature branch produces an image that runs last week's code. The rest of the file has no `WORKDIR`, no `ENTRYPOINT`, no `CMD`, and no `USER`, which is why the run command has to name the binary by hand. There is no `.dockerignore` in the tree either, so the whole checkout becomes build context while the Dockerfile copies nothing from it. Note also that the same file reaches for the same update in two spellings, `apt update -y` on one line and `apt-get update -y` on another.

## A layer commented as optional is unconditional, and the run passes one key of seven

The third instruction in the Dockerfile carries a comment reading Optional: Install Google Cloud CLI to use Google's image generation models, and then installs it anyway, adding a repository line, fetching a key with curl, dearmoring it, and running two more update and install steps. A comment cannot make a build layer conditional, so every image carries the Cloud CLI whether or not Vertex AI is ever used. The example run then passes exactly one variable:

```
docker run -e OPENAI_API_KEY=<your_openai_api_key> -it mulmo-cli mulmo tool scripting -i -t children_book -o ./ -s story
```

The configuration section above it documents seven separate keys: `OPENAI_API_KEY` as required, then `DEFAULT_OPENAI_IMAGE_MODEL`, `GEMINI_API_KEY`, `ANTHROPIC_API_TOKEN`, `REPLICATE_API_TOKEN`, `ELEVENLABS_API_KEY`, and `BROWSERLESS_API_TOKEN`. One of the seven crosses into the container, and the image is tagged `mulmo-cli` while the package it installs is named `mulmocast`.

## Three bin names, an undocumented MCP server, and one command with four unexplained flags

The package publishes three executables from two files: `mulmo` and `mulmocast` both point at `lib/cli/bin.js`, and `mulmo-mcp` points at `lib/mcp/server.js`. The README's single example command uses the shortest of those names. The third binary is a Model Context Protocol server, and no part of the README mentions it, even though the tree carries both a `CLAUDE.md` and a `.claude/` directory. That one example is also the whole command reference: `-i`, `-t`, `-o`, and `-s` appear in it and are never defined anywhere in the visible documentation, while the output formats in the architecture diagram list video, podcast, slideshow, PDF, manga, and swipe anime. The developer scripts in `package.json` cover a smaller set, with `audio`, `translate`, `movie`, `images`, `preprocess`, and `pdf`.

## The export map promises subpaths the files array never publishes

The package publishes six export subpaths: `.`, `./browser`, `./data`, `./assets/*`, `./scripts/*`, and `./tools/complete_script`. Two problems sit inside that map. The `./data` entry has a `default` condition and no `types` condition, while `.` and `./browser` each carry both, so a TypeScript consumer of the data entry point gets no declarations where the other two give them. The two wildcard entries are wider than the published files. The `files` array includes `./scripts/templates` and `./scripts/test` under scripts, and seven specific entries under `./assets/`, including `./assets/audio/silent60sec.mp3` and directories for html, images, schemas, slide_themes, styles, and templates. Any other path under `./scripts/` or `./assets/` is an advertised subpath with no file behind it. The map also offers no CommonJS condition at all, while the package sets `"type": "module"`.

## An empty npm description, no license field, and no LICENSE in the tree

The published metadata is thin in three ways. The `description` field is an empty string, while the repository carries a one line summary of its own and the README opens with a different title again. No `license` key appears in the visible part of `package.json`, the repository license is recorded as unknown, and the top level entries contain no `LICENSE` file: they are `.claude/`, `.gitattributes`, `.github/`, `.gitignore`, `.prettierrc`, three changelog files, `CLAUDE.md`, `CONTRIBUTING.md`, `Dockerfile`, `README.md`, `assets/`, `automation/`, `batch/`, `docs/`, `eslint.config.mjs`, `mulmo.config.json.sample`, `package.json`, `plans/`, `prompts/`, `scripts/`, `src/`, `test/`, two tsconfig files, `types/`, and `yarn.lock`. A separate slip lives in the `directories` field, which maps the test directory to `tests` while the tree and the `ci_test` glob both use `test`. Nothing states which of the two the tooling follows.

## Conclusion

MulmoCast is a real tool with a wide provider surface, and MulmoScript is a legible intermediate format worth reading before you decide. Judge the packaging first, though. Building the documented image gives you the npm release rather than your working tree, the npm install path ignores the yarn resolution pins that carry the three security overrides, and the two test scripts exercise disjoint code paths with one of them calling live providers. If you plan to hack on it, install from a clone with the package manager the lockfile belongs to, write your own Dockerfile that copies `src/` and builds it, and read the beta notes linked from the quick start before trusting the top of the README.

## FAQ

### How do I install mulmocast from the command line?

`npm install -g mulmocast` globally, and you also need ffmpeg, which on macOS comes from `brew install ffmpeg`. A Docker route is offered as well, building the bundled `Dockerfile` as `mulmo-cli`.

### Which environment variables does mulmocast need?

Only `OPENAI_API_KEY` is required. Optional ones are `DEFAULT_OPENAI_IMAGE_MODEL`, `GEMINI_API_KEY`, `ANTHROPIC_API_TOKEN`, `REPLICATE_API_TOKEN`, `ELEVENLABS_API_KEY`, `BROWSERLESS_API_TOKEN`, and `MULMOCAST_DUMP_USAGE`, which takes either `1` to print a JSON usage dump to stdout or a file path.

### What is MulmoScript and how does mulmocast read it?

It is a JSON or YAML format describing multi-modal content, with the smallest example being a `$mulmocast` block carrying `version` `1.1` and a `beats` array holding one beat of text. Generated by a language model, it is what the tool turns into video, podcast, PDF and other outputs.

### Does mulmocast support Azure OpenAI instead of OpenAI?

Yes, through separate key and base URL pairs for image generation, text to speech, and the LLM: `IMAGE_OPENAI_API_KEY`, `TTS_OPENAI_API_KEY`, and `LLM_OPENAI_API_KEY` with matching `*_OPENAI_BASE_URL` values, plus an optional `LLM_OPENAI_API_VERSION`. Azure deployment names must match the model names exactly.

## Sources

- [Official README](https://github.com/receptron/mulmocast-cli#readme)
- [Project repository](https://github.com/receptron/mulmocast-cli)
- [Release notes](https://github.com/receptron/mulmocast-cli/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/receptron-mulmocast-cli
