MCP server for the Royal Render render farm manager. Exposes the render farm as MCP tools: query jobs/clients, control jobs and nodes, and submit new render jobs.
Royal Render MCP has 17 well-named tools with strong descriptions (avg 180 chars, well above 34-char baseline). All tools start with action verbs (list_, get_, job_, node_, build_, set_, client_). Input schemas are present and typed for all tools. However, output schemas are NOT documented, the code shows tools return `dict` with no schema specification, forcing LLMs to infer structure. Error handling is minimal; no recovery guidance or actionable error messages visible. Parameters lack enum constraints where applicable (e.g., 'status' accepts free-form strings instead of enum). Destructive tools (job_command, client_command, rerun_scripts) lack confirmation patterns in the schema itself. Overall solid naming and description quality, but schema documentation and error handling gaps prevent a higher score.
Build a submission spec from a preset, resolving the output VERSION. By default the version is the next unused one for this output, so a render never overwrites its predecessor. Passing `version` explicitly pins it, and if that version already exists the result carries a WARNING that the render will overwrite: an overwrite is a deliberate per-project choice, never a default inherited from a preset. Returns {spec, meta}. Feed `spec` to submit_job/submit_jobs (they accept these fields directly), or inspect it first.
Send a command to one or more render nodes (clients).
One-glance farm summary: nodes online, threads rendering, cores, average CPU.
Get full details for a single job by its RR short id (e.g. '{85Ob}').
Read a job's RR render/script log (from rrJobdata\<folder>\log). kind: 'post' (post-render/finished scripts - includes the previews stdout), 'render' (the per-frame render log), 'finished', or 'all'. Use contains to filter lines (e.g. 'OIIO' or 'ffmpeg'), tail for the last N lines.
Output schemas not documented. All tools return `dict` with no schema specification. LLMs cannot infer response structure, forcing them to guess field names and types for downstream tool calls.
Enum constraints missing for status, action, and kind parameters. 'status' accepts free-form strings (all|rendering|finished|disabled|idle|waiting) but is not declared as enum. LLMs may hallucinate invalid values.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 62 | 2026-07-28+ | v2 |
Read back which nodes a job is actually allowed to run on.
Send a command to one or more jobs. action: enable | disable | restart | clear_errors | approve | disapprove Destructive (require confirm=true): delete | abort | reset_delete_frames. Without confirm, destructive actions return a preview of what would be affected. Commands are applied server-side with a propagation delay (measured ~5-10s): a read issued immediately after can still show the old state, so re-read before concluding a command did not take. 'restart' resets the job into 'First Check' and leaves it DISABLED (verified live); follow with 'enable' to run it again. DELETING A JOB THAT IS RENDERING is not immediate: the call returns ok, the job moves to a disabled-but-present state, and it only leaves the queue once the node releases it (measured ~35s over several polls). Confirm a delete by re-querying until the job is gone rather than trusting the ok.
Classify a job's (or a filtered set's) failures into a cause taxonomy: NETWORK/UNC, DISK/SPACE, MEMORY, CRASH/FROZE, GPU/DRIVER, LICENSE, RENDER/APP, plus 'unclassified' for genuine failures the taxonomy does not recognise. Tallies per node, with sample messages. Failures are decided by log TEXT, never by the numeric event id, and routine job management (checks, dispatches, deliberate preemption) is excluded rather than counted as faults.
Ordered event timeline for one job: dispatches, completions, errors and aborts with timestamps and the node each came from. The raw material for "why is this shot late". Set failures_only=true to drop routine bookkeeping. Note the 'event' label is an observational name for the log entry's numeric id and is NOT authoritative (the same id appears with different meanings); 'text' is what decides.
Per-frame render timing and freeze events, for sizing freeze timeouts and capacity planning. Returns each job's average frame seconds plus a summary with the slowest observed frame, which is the FLOOR any freeze timeout must clear to avoid aborting healthy renders.
List all render nodes (clients) with hardware, status and per-thread activity.
List jobs in the Royal Render queue. status: one of all | rendering | finished | disabled | idle | waiting. user and project are EXACT matches (e.g. the full submitting account name, not a prefix); scene_contains is a substring word-match over the scene path and supports include/exclude words like 'shot34 beauty -background'. Filtering reduces load on large queues.
Available submission presets (render app, renderer, licenses) and what each is for. Renderer and license names vary per farm.
Per-node render outcomes from the farm's retained job logs: how often a machine has actually completed renders, when it last succeeded and last failed, filterable by render app or renderer. Script-phase logs (pre/post/finished) are counted separately and never as render successes: a node can keep running post scripts long after it stopped rendering, and conflating the two reports a broken node as healthy. Reads RETAINED logs only, so absence of an old success is not proof it never happened.
Which render nodes are healthy, and what is wrong with the ones that are not. Joins the queue's per-node failure buckets with the retained render logs, because either view alone misleads: a node can look busy and fault-free on the queue while having completed no render in days. Nodes are ranked worst first. A node with no retained history is reported 'unknown', never 'ok'.
Re-run a finished job's post-render (kind='post') or finished (kind='finished') scripts - e.g. to regenerate previews or A/B a post-script change. Re-runs ALL scripts of that phase, so ShotGrid/publish steps run again too.
Modify settings for one or more jobs: priority, frame range, division, max_clients (the 'maximum clients at a time' cap - set 1 to keep a job on a single node), and abort_lower_priority ('abort jobs with lower priority' - with a high priority this PREEMPTS running lower-priority jobs on the clients this job can use; their in-flight frames re-render later).
Destructive tools lack confirmation pattern. job_command, client_command, and rerun_scripts can delete/abort/reboot but have no dry-run or explicit confirmation mechanism in the schema. confirm=true flag exists but is not enforced at schema level.
No error handling guidance visible. Code does not show error responses, recovery hints, or actionable error messages. LLMs will not know how to recover from failures.
Parameter descriptions lack format/constraint details. 'job_id' is described as 'RR short job id (e.g. {85Ob})', the example is helpful but should be paired with a regex pattern or format constraint in the schema.