Content
# singular-mcp-server
A comprehensive [Model Context Protocol](https://modelcontextprotocol.io) server
for **reading, controlling, and orchestrating [Singular.live](https://singular.live)
live broadcast graphics compositions** from Claude Desktop or any MCP client.
It lets an agent discover a control app's structure, fill its control nodes
(text, images, colors…), animate sub-compositions in and out, push low-latency
data, and run a newsroom **rundown → graphics** workflow over templates you build
once in Composer.
> ### What this is (and isn't)
> Singular's public API **controls** compositions; it does **not author** them.
> You build the graphics (lower-thirds, full-frames, tickers, bugs) once in the
> browser **Composer**, and this server lets agents fill and sequence that kit of
> parts in real time. Authoring composition structure, account listing, token
> minting, media upload, and webhooks are not exposed by any public Singular API.
> See [docs/SINGULAR_API.md](docs/SINGULAR_API.md) for the API reference.
## Installation
**Prerequisites:** Node.js ≥ 18 (developed on Node 22) and npm.
```bash
# 1. Clone
git clone https://github.com/dqbuilds/singular-mcp-server.git
cd singular-mcp-server
# 2. Install dependencies
npm install
# 3. Build (compiles TypeScript to dist/)
npm run build
# 4. (optional) Verify — runs the mock-API integration test; no Singular account needed
npm test
```
This produces the runnable server at `dist/index.js`. Next, configure a Singular
app token and point your MCP client at it (below).
> **Install globally (optional).** From the repo, `npm link` puts a
> `singular-mcp-server` command on your PATH; then your MCP client can use
> `"command": "singular-mcp-server"` instead of an absolute `node dist/index.js` path.
## Configuration
Secrets come **only** from the environment. Copy `.env.example` → `.env` (the
server itself reads real environment variables; use your process manager or the
MCP client config to set them).
| Variable | Required | Default | Purpose |
|---|---|---|---|
| `SINGULAR_APP_TOKEN` | no | — | Default control-app token when a tool omits `app`/`appToken`. |
| `SINGULAR_API_BASE` | no | `https://app.singular.live/apiv2/controlapps` | Control REST base. |
| `SINGULAR_DATASTREAM_BASE` | no | `https://datastream.singular.live/datastreams` | Data Stream base. |
| `SINGULAR_DEFAULT_SUBCOMPOSITION` | no | — | Optional default sub-composition name. |
| `SINGULAR_REGISTRY_PATH` | no | `~/.singular-mcp/registry.json` | On-disk alias→token registry (owner-only perms). |
| `SINGULAR_HTTP_TIMEOUT_MS` | no | `30000` | Per-request timeout. |
| `LOG_LEVEL` | no | `info` | `debug`\|`info`\|`warn`\|`error` (logs go to **stderr**). |
Where do tokens come from? Copy each app token from the Singular **Dashboard**
(inspector "i" → *URLs and Token*; UNO `</>`; or Studio → *Manage Access → App
Token*). The API cannot mint them.
### Claude Desktop
Add to `claude_desktop_config.json`:
```json
{
"mcpServers": {
"singular": {
"command": "node",
"args": ["/absolute/path/to/singular-mcp-server/dist/index.js"],
"env": { "SINGULAR_APP_TOKEN": "your-token-here" }
}
}
}
```
You can omit `SINGULAR_APP_TOKEN` and instead register apps by alias at runtime
with `singular_register_app`.
## Tools (25)
Every tool takes `response_format` (`markdown` default, or `json`) and returns
both human text and `structuredContent`. App-targeting tools accept an `app`
alias (from the registry) or a raw `appToken`, falling back to the env default.
**Discovery & read**
- `singular_get_app_metadata` — ids, name, output/preview URLs.
- `singular_get_model` — structural model: sub-compositions + typed control nodes.
- `singular_get_control_state` — current live state + values.
- `singular_list_subcompositions` — model + live values joined (best overview).
- `singular_find_nodes` — filter nodes by `type` (e.g. `image`) / title.
**Content control**
- `singular_update_content` — fill nodes across one or more sub-comps in one PATCH.
- `singular_set_image` — set an image node by URL (validates it's an image node + URL reachability).
- `singular_reset_nodes` — reset nodes to their reset values (clear a template).
**Animation & playout**
- `singular_animate_state` — take sub-comps In/Out (multiple targets per call).
- `singular_update_and_animate` — fill + take to air atomically (no stale flash).
- `singular_take_out_all` — clear the whole app (`TakeOutAllOutput`).
**Data streams**
- `singular_register_data_stream` — store a stream's private token by alias.
- `singular_list_data_streams` — list registered stream aliases.
- `singular_push_datastream` — PUT low-latency JSON (≤ 60 KB) to a stream.
**Media & output**
- `singular_get_output_urls` — live output / broadcast / thumbnail URLs.
- `singular_check_image_url` — pre-flight an image URL.
**Orchestration & rundown**
- `singular_register_app` / `singular_list_apps` / `singular_remove_app` — the alias registry.
- `singular_map_rundown_template` — bind an item type → sub-comp + field map.
- `singular_list_rundown_templates` — list mappings.
- `singular_prepare_item` — dry-run: resolve a story item to a payload, no air.
- `singular_play_rundown_item` — take an item to air (optional server-side auto-out).
- `singular_poll_onair_state` — poll what's on air (+ diff since last poll).
- `singular_server_info` — server config/health (no secrets).
## For agents
The server sends usage guidance to clients as its MCP `instructions` at connect
time, and every tool has a self-contained description with its args and return
shape. The full playbook — the discover-before-write rule, the canonical flow,
value formats, and gotchas — is in [AGENTS.md](AGENTS.md).
## Newsroom workflow example
```text
1. singular_register_app { alias: "evening-news", token: "…" }
2. singular_find_nodes { app: "evening-news", type: "image" } # discover the kit
3. singular_map_rundown_template {
name: "lower-third", appAlias: "evening-news",
subCompositionName: "LowerThird",
fieldMap: { headline: "titleNode", photo: "bannerImage" } }
4. singular_prepare_item { template: "lower-third",
fields: { headline: "Markets rally", photo: "https://cdn/…jpg" } } # verify
5. singular_play_rundown_item { template: "lower-third",
fields: { headline: "Markets rally", photo: "https://cdn/…jpg" },
auto_out_ms: 8000 } # to air
6. singular_poll_onair_state { app: "evening-news" }
```
An agent can drive this from a rundown/PDF: extract stories + image URLs, map them
to templates, and play them to air.
## Security
- App tokens are **bearer-equivalent secrets**. They are stored server-side in the
registry (file mode `0600`, dir `0700`), **never returned to the model**, and
**redacted from logs** (including inside request URLs).
- Host images on your own reachable URL; there is no upload API.
- stdio logging is on **stderr** only (stdout is the JSON-RPC channel).
## Limitations (from Singular's API, not this server)
Authoring compositions, listing an account's assets, minting tokens, uploading
media, server-side rendering, and webhooks are all unavailable via public API.
On-air awareness is by polling. Auto-out scheduling is in-memory (not restart-safe).
See [docs/SINGULAR_API.md](docs/SINGULAR_API.md).
## Roadmap
- Optional Streamable HTTP transport.
- Data Node tools over the `apiv1` Data Node API.
- Batch rundown ingestion helpers (PDF/rundown → items).
- In-memory control-model cache with TTL.
## Development
```bash
npm run dev # tsx watch
npm run typecheck # tsc --noEmit
npm run inspector # MCP Inspector against the built server
```
Connection Info
You Might Also Like
Train-in-Silence
The first Task-Aware MCP server and automated VRAM calculator for LLM...
stacklit
108,000 lines of code. 4,000 tokens of index. One command makes any repo...
AppClaw
AI-powered mobile automation agent — describe what you want in plain...
pdf-mcp
Production-ready MCP server for PDF processing with intelligent caching....
kotadb
Local-only code intelligence API for AI developer workflows (Bun +...
gemini-api-docs-mcp
A remote HTTP MCP server for searching Google Gemini API documentation.