# Poietra for developers

Turn editable Poietra projects into SVG, PNG and MP4. Connect your agent through OpenAPI or a local MCP server.

**Self-hosted HTTP API · Local stdio MCP**

poietra.com serves documentation and schemas. Start the renderer where your agent runs; there is no hosted render API or remote MCP endpoint.

- [OpenAPI](https://poietra.com/openapi.json)
- [Project schema](https://poietra.com/schemas/project.json)
- [Starter project](https://poietra.com/examples/hello.poietra.json)
- [MCP configuration example](https://poietra.com/developers/mcp-config.json)

## Start the render service

Use Node 24+, pnpm 10.23.0 and Python 3.12+. These POSIX shell commands install the pinned MoonBit compiler and build the renderer. Runtime rendering does not need Chromium, FFmpeg or an OpenAI key.

~~~sh
git clone https://github.com/Poietra/poietra.git
cd poietra
pnpm install --frozen-lockfile
curl -fsSL https://cli.moonbitlang.com/install/unix.sh -o /tmp/install-moonbit.sh
bash /tmp/install-moonbit.sh "$(cat .moon-version)"
export PATH="$HOME/.moon/bin:$PATH"
node scripts/moon.mjs update
pnpm build:moonbit
pnpm render:api
~~~

Keep that process running. In another terminal, inspect and render the sample below. The file contains one second of editable text.

~~~sh
curl -fsS https://poietra.com/examples/hello.poietra.json -o hello.poietra.json
curl -fsS http://127.0.0.1:8799/inspect \
  -H 'Content-Type: application/json' \
  --data-binary @hello.poietra.json
curl -fsS 'http://127.0.0.1:8799/render?format=mp4&width=1280&fps=30' \
  -H 'Content-Type: application/json' \
  --data-binary @hello.poietra.json \
  -o hello.mp4
~~~

- [hello.poietra.json](https://poietra.com/examples/hello.poietra.json)

## HTTP / OpenAPI

Send the complete .poietra.json file directly as the application/json body. Output settings go in the query string. A successful render returns the actual file bytes with the matching Content-Type.

- GET /capabilities — Read supported formats, source media and limits
- POST /inspect — Validate a portable project and report compatibility
- POST /render — Render a portable project to SVG, PNG or MP4

~~~text
format=svg|png|mp4
width=1280&height=720
fps=24|30|60
timeMs=1200
~~~

The default format is PNG. timeMs selects a still frame and must be zero for MP4. One supplied dimension preserves the first Scene's aspect ratio. MP4 requires even dimensions.

- [OpenAPI 3.1.1](https://poietra.com/openapi.json)
- [Project JSON Schema](https://poietra.com/schemas/project.json)

The downloadable OpenAPI targets http://127.0.0.1:8799. Your running server also exposes /openapi.json with its actual origin. A public poietra.com URL is not a render server.

## Connect a local MCP client

After building, let your MCP client launch apps/render/mcp.mjs over stdio. This is an example for clients with an mcpServers configuration. Replace the absolute path and adapt the surrounding configuration to your client. The HTTP server does not need to be running.

~~~json
{
  "mcpServers": {
    "poietra": {
      "command": "node",
      "args": [
        "/absolute/path/to/poietra/apps/render/mcp.mjs"
      ]
    }
  }
}
~~~

- [Download example configuration](https://poietra.com/developers/mcp-config.json)

- poietra_capabilities — Read formats, source types and limits.
- poietra_inspect — Inspect a local inputPath.
- poietra_render — Render inputPath to a new outputPath. Existing files are never overwritten.

~~~json
{
  "inputPath": "/absolute/path/to/hello.poietra.json",
  "outputPath": "/absolute/path/to/hello.mp4",
  "format": "mp4",
  "fps": 30
}
~~~

Use MCP resources/list and resources/read to retrieve the same specification, project schema and starter file. Paths refer to the machine running the MCP process. There is currently no remote /mcp endpoint.

~~~text
poietra://docs/openapi
poietra://docs/project-schema
poietra://examples/hello
~~~

## Keep the project editable

An agent edits the project data, inspects it, then renders it. Keep stable object IDs. A Scene holds shared object identities and parent links; each Composition holds its own appearance and transforms. Transitions connect adjacent Compositions and contain timing, easing and intermediate values.

The project schema is generated from the file decoder. Inspection additionally checks references and timing. An empty issues array is a compatibility preflight, not proof that every embedded asset can decode. Correct reported errors before retrying a render.

- [Source and extension guide](https://github.com/Poietra/poietra#add-a-feature)

## Formats and limits

- Output: SVG, PNG and H.264 MP4; audio uses MP3 inside MP4.
- Input media: embedded PNG/JPEG and PCM WAV. Imported video, WebP, compressed audio and external asset URLs are unsupported.
- Input ≤ 32 MiB; output ≤ 64 MiB. Each side ≤ 1920 px; total ≤ 2,073,600 pixels.
- MP4: up to 60 seconds and 1800 frames. At most 32 audible tracks.
- One HTTP inspection/render at a time. Requests wait for completion; there is no job queue, job ID or hosted result storage.
- Default render timeout: 120 seconds. Disconnecting HTTP or cancelling MCP stops the job.

## Authentication and errors

The service listens on loopback by default. Configure POIETRA_RENDER_TOKEN before binding to another interface, and send Authorization: Bearer <token>. A configured token is also required on loopback. These credentials are separate from studio login.

- 400 — Unknown or repeated query options.
- 401 / 403 — Authentication, Origin or Host rejected.
- 413 / 415 — Input too large or wrong Content-Type.
- 422 — Invalid data, unsupported media or rendering failure. Read the error message.
- 429 — Busy. Retry after the current operation finishes.
- 504 — Render timeout. Reduce the workload before retrying.

~~~json
{"error":"format must be svg, png or mp4."}
~~~
