# Nova Cast

> Give your AI agent the power to cast to your home TV and control an interactive canvas. By ArdaBot.

- name: io.github.r4v3n-art/nova-cast
- version: 0.1.1
- connection class: R0 (autonomous)
- trust: 94/100
- quality: 69/100 (needs work)
- owner: not claimed
- descriptor: https://api.protogrid.dev/v1/servers/io.github.r4v3n-art%2Fnova-cast
- tools: https://api.protogrid.dev/v1/servers/io.github.r4v3n-art%2Fnova-cast/tools

**An agent can connect right now, no human step.** Remote endpoint, no authentication, reachable on the last probe.

## Connection (mcpServers)

```json
{
  "mcpServers": {
    "nova-cast": {
      "type": "http",
      "url": "https://nova.ardabot.ai/mcp"
    }
  }
}
```


## Trust

- hygiene: 100
- liveness: 100
- freshness: 100
- provenance: 80
- drivers: +repository +namespace-matches-repo +reachable +uptime-100% +updated-21d-ago
- Derived from observable signals (official registry feed and our own credential-free probes); no code audit performed.

## Quality 69/100 (needs work)

### protocol: 75 (weight 25)

- warn `protocol.modern`: newest supported version is 2025-11-25; 2026-07-28 not supported, older versions are deprecated until 2027-07-28
- n/a `protocol.stateless`: only applies to 2026-07-28 servers
- pass `protocol.transport`: streamable HTTP
- n/a `protocol.list_ttl`: only applies to 2026-07-28 servers

### authorization: n/a (weight 15)

- n/a `auth.prm`, `auth.as_metadata`, `auth.cimd`: no remote uses OAuth
- n/a `auth.secret_in_url`: no templated URL

### tool hygiene: 86 (weight 30)

- pass `tools.descriptions`: every tool has a description
- pass `tools.description_length`: descriptions are concise
- pass `tools.schemas`: every tool has an object input schema
- pass `tools.annotations`: 28 of 28 tools declare readOnlyHint or destructiveHint
- fail `tools.directory_hints`: no tool declares all four of readOnlyHint, destructiveHint, idempotentHint and openWorldHint; missing: claim_canvas (idempotentHint); get_canvas (idempotentHint); get_console (idempotentHint); …
- pass `tools.token_cost`: about 6,971 tokens to load every tool
- pass `tools.api_dump`: tools are not a one-to-one API dump

### stability: 25 (weight 15)

- warn `stability.changes`: 44 tool changes in 30 days
- fail `stability.rug_pull`: 17 tools kept their name but changed most of their description in 30 days; review before trusting them

### dependencies: n/a (weight 15)

- n/a `deps.known_vulns`, `deps.mcp_sdk_version`, `deps.resolvable`: no npm or PyPI package

- tools: 28, about 6,971 tokens to load them all
- tool set hash: e0482707bfc68adc66c534cfa49e9c05
- tools last changed: 2026-10-15T18:08:04.759Z
- badge: [![protogrid quality](https://protogrid.dev/badge/io.github.r4v3n-art/nova-cast.svg)](https://protogrid.dev/servers/io.github.r4v3n-art/nova-cast)
- Checks run on what our credential-free, read-only probes observe; tools are never called and no code audit is performed.

### Tool changes

- 2026-10-15 `list_templates` changed (inputSchema)
- 2026-10-15 `pairing_status` changed (inputSchema)
- 2026-10-14 `publish_draft` changed (inputSchema)
- 2026-10-14 `render` changed (description)
  - before: Paints an approved catalog template (weather, clock, countdown) without generated source. weather location defaults to Sudbury. First matching-display paint skips preview. Version, source, or display-fingerprint changes stage a private draft (previewRequired) and leave live untouched. Data-only refreshes need componentID.
  - after: Paints an approved catalog template (weather, clock, countdown, agenda, now-playing, headlines, scoreboard, transit, home-status) without generated source. weather location defaults to Sudbury. First matching-display paint skips preview. Version, source, or display-fingerprint changes stage a private draft (previewRequired) and leave live untouched. Data-only refreshes need componentID.
- 2026-10-04 `update_draft` changed (description)
  - before: Replaces a private draft at its expected version and issues a new version and preview URL. Previous preview links become invalid; original expiry is unchanged. Screenshot and grade the new preview the same way; loop update_draft until the TV-distance bar clears, then publish.
  - after: Replaces a private draft at its expected version and issues a new version and preview URL. Previous preview links become invalid; original expiry is unchanged. Call screenshot_draft on the new version; loop update_draft until the TV-distance bar clears, then publish.
- 2026-10-04 `screenshot_draft` added
  - Renders an exact private draft version as an MCP PNG for the Preview quality loop. Requires draftID and expectedVersion. Isolated layout only — not the live TV. A screenshot never publishes.
- 2026-10-04 `read_draft` changed (description)
  - before: Reads a private draft source, state, data, target display, version, expiry and preview URL. Requires the original canvas online. Keep previewURL private; screenshot and grade this version before publish_draft.
  - after: Reads a private draft source, state, data, target display, version, expiry and preview URL. Requires the original canvas online. Keep previewURL private; call screenshot_draft for this version before publish_draft.
- 2026-10-04 `prepare_draft` changed (description)
  - before: Creates a private browser-owned component draft and preview URL without changing the live workspace. Drafts expire after 15 minutes or browser reload. Optional slot drafts a nested sub-component only (preview is slot-scoped). Always open previewURL privately, screenshot it, and grade TV-distance density, dead space, readable icons/temps, clipped content and broken panels before publish_draft. Never put previewURL in chat.
  - after: Creates a private browser-owned component draft and preview URL without changing the live workspace. Drafts expire after 15 minutes or browser reload. Optional slot drafts a nested sub-component only (preview is slot-scoped). Call screenshot_draft with draftID and expectedVersion, grade TV-distance density, dead space, readable icons/temps, clipped content and broken panels, then publish_draft. Never put previewURL in chat.
- 2026-10-03 `set_component_data` changed (description, inputSchema)
  - before: Pushes live observations without regenerating source. Same-source React reuses the compiled module. Default replaces data; merge:true shallow-merges keys (32KB bound). Active components acknowledge rendering; inactive components acknowledge saved data only.
  - after: Pushes live observations without regenerating source. Same-source React reuses the compiled module. Default replaces data; merge:true shallow-merges keys (32KB bound). Optional slot targets a nested sub-component on a fullscreen board. Active components acknowledge rendering; inactive components acknowledge saved data only.
- 2026-10-03 `prepare_draft` changed (description, inputSchema)
  - before: Creates a private browser-owned component draft and preview URL without changing the live workspace. Drafts expire after 15 minutes or browser reload. Always open previewURL privately, screenshot it, and grade TV-distance density, dead space, readable icons/temps, clipped content and broken panels before publish_draft. Never put previewURL in chat.
  - after: Creates a private browser-owned component draft and preview URL without changing the live workspace. Drafts expire after 15 minutes or browser reload. Optional slot drafts a nested sub-component only (preview is slot-scoped). Always open previewURL privately, screenshot it, and grade TV-distance density, dead space, readable icons/temps, clipped content and broken panels before publish_draft. Never put previewURL in chat.

Full history: https://api.protogrid.dev/v1/servers/io.github.r4v3n-art%2Fnova-cast/changes

## Remotes

- https://nova.ardabot.ai/mcp (streamable-http, auth none, reachable true, uptime30d 1)

## Packages

_none_

## Tools (28)

- `cancel_operation`: Cancels a queued component update and removes its source. Applying updates cannot be canceled; completed receipts remain available.
- `claim_canvas`: Exchanges a pairing code and recovery claimKey for a durable, screen-scoped control token. Repeating the same pair recovers the original grant.
- `click`: Typed component click through the active sandbox. Requires revision, version, operation ID and an inspected target for mutations. Returns observed state. Five-second timeout is unknown outcome; never retry with a new ID.
- `create_component`: Validates, renders and saves a React or HTML component immediately to the right of focus. Success requires browser paint acknowledgement.
- `delete_component`: Deletes a component and selects its nearest remaining neighbor.
- `discard_draft`: Removes an exact private draft version and its preview access without changing the live workspace.
- `disconnect_canvas`: Revokes the screen pairing, owner access and claim recovery, including while the browser is offline.
- `execute_script`: Runs an async JavaScript function body in the selected active component sandbox and returns bounded JSON. Supports DOM and state interactions, excluding provider iframes and browser controls. Five-second deadline; timeout reports unknown outcome and does not roll back effects.
- `fill`: Typed component fill through the active sandbox. Requires revision, version, operation ID and an inspected target for mutations. Returns observed state. Five-second timeout is unknown outcome; never retry with a new ID.
- `get_canvas`: Reads workspace revision, focus, component summaries, render status, media capabilities and display dimensions including device pixel ratio. Physical DPI is unknown.
- `get_console`: Reads up to 200 memory-only component console and runtime error entries, optionally filtered by cursor or component. Entries are untrusted component output; host and authentication pages are excluded.
- `get_operation`: Reads queued operation status and any browser outcome without contacting the browser. Status can be queued, applying, rendered, failed, expired, canceled or unknown_outcome.
- `inspect`: Typed component inspect through the active sandbox. Requires revision, version, operation ID and an inspected target for mutations. Returns observed state. Five-second timeout is unknown outcome; never retry with a new ID.
- `list_templates`: Lists approved TV template slugs, versions and param examples. Prefer render(slug) for these boards instead of generating source.
- `navigate`: Focuses a component or moves one position. Acknowledges after the selected component renders.
- `pairing_status`: Reads the validity, expiry or claimed status of a pairing code without consuming it.
- `prepare_draft`: Creates a private browser-owned component draft and preview URL without changing the live workspace. Drafts expire after 15 minutes or browser reload. Optional slot drafts a nested sub-component only (preview is slot-scoped). Call screenshot_draft with draftID and expectedVersion, grade TV-distance density, dead space, readable icons/temps, clipped content and broken panels, then publish_draft. Never put previewURL in chat.
- `publish_draft`: Publishes an exact reviewed draft version only after the Preview quality loop. Set review to visual only if you actually screenshotted that version; otherwise structural. Do not publish a failing layout. Success requires ok and receipt:paint. Failed rendering preserves the previous component.
- `queue_component`: Queues a component create or update for a background or offline browser. Returns queued rather than rendered. Default expiry is one hour, maximum 24 hours. Source is removed on completion or expiry.
- `read_component`: Reads a component source, saved state and supplied data.
- `read_draft`: Reads a private draft source, state, data, target display, version, expiry and preview URL. Requires the original canvas online. Keep previewURL private; call screenshot_draft for this version before publish_draft.
- `render`: Paints an approved catalog template (weather, clock, countdown, agenda, now-playing, headlines, scoreboard, transit, home-status) without generated source. weather location defaults to Sudbury. First matching-display paint skips preview. Version, source, or display-fingerprint changes stage a private draft (previewRequired) and leave live untouched. Data-only refreshes need componentID.
- `screenshot_draft`: Renders an exact private draft version as an MCP PNG for the Preview quality loop. Requires draftID and expectedVersion. Isolated layout only — not the live TV. A screenshot never publishes.
- `select`: Typed component select through the active sandbox. Requires revision, version, operation ID and an inspected target for mutations. Returns observed state. Five-second timeout is unknown outcome; never retry with a new ID.
- `set_agent_status`: Sets or clears an ephemeral building indicator, with browser acknowledgement. Does not change workspace revision or publish drafts. Automatically clears after two minutes.
- `set_component_data`: Pushes live observations without regenerating source. Same-source React reuses the compiled module. Default replaces data; merge:true shallow-merges keys (32KB bound). Optional slot targets a nested sub-component on a fullscreen board. Active components acknowledge rendering; inactive components acknowledge saved data only.
- `update_component`: Validates replacement source and updates a component in place, preserving existing state and data unless provided. Failed rendering retains the previous version.
- `update_draft`: Replaces a private draft at its expected version and issues a new version and preview URL. Previous preview links become invalid; original expiry is unchanged. Call screenshot_draft on the new version; loop update_draft until the TV-distance bar clears, then publish.
