Skip to main content
Glama
paramount-engineering

Roku Dev Studio MCP Server

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault

No arguments

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": false
}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}

Tools

Functions exposed to the LLM to take actions

NameDescription
list_action_typesA

Return every supported Action Script step type (with label, description, required / optional fields). Read-only. Start here when authoring a script, then call get_action_schema for one type's exact fields, and validate_script before send_script_to_builder. For the full authoring contract in one call use get_capability_bundle or read resource roku-dev-studio://action-script-contract.md.

get_action_schemaA

Return the authoring schema (label, description, required and optional fields) for ONE Action Script step type. Read-only. Call this after list_action_types (which enumerates every type) when you are about to author or fix a specific step and need its exact field names before running validate_script. Required argument type — one of the values from list_action_types (also enumerated in this tool's inputSchema). For the whole authoring contract at once, prefer get_capability_bundle.

get_capability_bundleA

Single payload of every static capability (actions, vocabularies, RALE built-ins, presets, authoring rules, op directory, actionScriptAgentContract). Load once before authoring scripts, then cache. Same JSON is also available as resource roku-dev-studio://capability-bundle.json.

validate_scriptA

Validate an Action Script before send_script_to_builder. Argument script: JSON object or JSON string. Response: ok, errors[] (path, code, message, expected?), stepCounts, humanSummary, referenceTools. ok=false is returned as isError. Contract: resource roku-dev-studio://action-script-contract.md. Only author a script for multi-step / conditional / polling / saved-or-reviewed flows — for a single action use the matching direct op (keypress, launch_app, rale_command, ecp_query, ecp_post, screenshot, …).

probe_bridgeA

Returns { live, port, pid, startedAt } or { live: false, reason }. Call once per session before the first bridge-dependent tool; once live=true, call direct ops (keypress, launch_app, ecp_query, rale_command, …) and send_script_to_builder freely without re-probing.

get_selected_deviceA

Return the single device tab the user currently has focused in Dev Studio (ip, serial, modelName, friendlyDeviceName, …), or an empty/null result when no tab is focused. Read-only. Call this to resolve the implicit target before a device op when the user says "this device" / "the current one" and gave no IP. For the full inventory (all connected / discovered / remembered devices) use list_devices instead; to change the focus use connect_device.

list_devicesA

Return every device Dev Studio already knows about — connected, discovered, remembered, or remote — without running a network scan. Read-only. Each entry: ip, serial, modelName, friendlyDeviceName, softwareVersion, source, isConnected, isFocused. Use this as the first step to resolve a device argument (IP or serial) for other tools. Related tools: get_selected_device returns only the one focused device; scan_devices actively probes the network for NEW devices not yet known; connect_device opens/focuses a tab for one of these entries.

connect_deviceA

Open (or focus, if already open) a Dev Studio device tab for the given Roku, making it the active target for renderer-routed tools (rale_command, telnet_*, app_function, get_telnet_log). Required device: Roku IP or serial from list_devices / scan_devices. Idempotent — a no-op if that device is already connected and focused. Not needed for main-direct ECP ops (keypress, launch_app, ecp_query, …), which accept a device argument directly; use test_connection to verify reachability without opening a tab.

list_app_connector_functionsA

Live functionName + parameter metadata from RALE getExternalControlFunctions. Each entry has name, params: [{ name, type }, …], and an optional description string when the channel includes one in its payload — surface that description verbatim to the user when explaining what a function does. Call before authoring appFunction steps so names and param keys/order match. Optional device (IP or serial).

rale_get_node_by_idA

Read-only convenience wrapper over rale_command getNodeById: fetch one SceneGraph node (its fields / children) by its id from the running Dev App via the App Connector. Requires a connected App Connector session (auto-connects if needed). Use this — not the general rale_command — for the common "inspect one node" case; drop to rale_command only for other RALE built-ins (registry, focus, other queries). Required id (the node's id field as authored in XML/BrightScript). Optional path (array of child indices/ids to disambiguate when the id is not globally unique; omit or [] for a global lookup) and device (IP or serial; omit for the focused tab).

send_script_to_builderA

Drop a validated Action Script into Dev Studio Builder for human review (does not auto-run). Runs the same validation as validate_script. Arguments: script (object or JSON string), optional device. Use only for multi-step / conditional / saved-or-reviewed flows — if the task is a single deterministic action (one keypress, one launch, one RALE command, one ECP query/POST, one screenshot), call the matching direct op (keypress, launch_app, rale_command, ecp_query, ecp_post, screenshot, …) directly instead of wrapping it in a one-step script.

network_inspector_statusA

Report whether Dev Studio's Network Inspector is enabled and actively capturing, plus connected Roku clients, packet/event counts, MITM (HTTPS decryption) state, and prerequisites[] remediation. Call this first before the other network_inspector_* tools — if ready is false, relay notice / remediation to the user (enable the feature, grant capture access, connect the Roku to the hotspot). Reads return nothing useful until ready is true.

network_inspector_list_eventsA

List captured network events as lightweight summaries (no full headers/body — drill down with network_inspector_get_event_detail using an event id). Summary-first by design to protect context. All filters optional and AND-combined across fields; give a field an array to OR within it (e.g. status: [404, 500]): device (IP or serial; omit for all Rokus on the hotspot), host (case-insensitive substring of hostname/SNI/URL), method (GET/POST/…), type (one of the network event types), status (exact HTTP response status code(s)), statusClass ('2xx'|'3xx'|'4xx'|'5xx'), contentType (case-insensitive substring against the response Content-Type, e.g. "json"), errorsOnly (HTTP status >= 400 — a shortcut for statusClass 4xx+5xx), mitmOnly (decrypted-HTTPS transactions only), limit (default 200, max 2000). Returns most-recent events. Requires Network Inspector enabled (see network_inspector_status).

network_inspector_get_event_detailA

Fetch the full headers and body for one captured event by id (from network_inspector_list_events). Bodies are capped at maxBodyChars (default 4096) and the response lists warnings when truncated; pass includeFullBody: true to override. DNS/TLS/TCP events have no body and may return 404. Requires Network Inspector enabled.

network_inspector_analyzeA

Aggregate the captured buffer into hotspots and rollups in one call — counts by event type, by HTTP status class (2xx/3xx/4xx/5xx), top hosts (with error counts), top content types, total HTTP/MITM transactions, error count, and the largest responses. Use this to orient on a session before drilling into individual events. Accepts the same optional filters as network_inspector_list_events (device, host, method, type, status, statusClass, contentType, errorsOnly, mitmOnly). Requires Network Inspector enabled.

network_inspector_findA

Search the FULL content of captured transactions — request/response URL, headers, and bodies — for query, unlike network_inspector_list_events' host filter which only matches hostname/SNI/URL. This is the tool for "which request(s) contain X" (a session id, an error string, a specific JSON field/value) across the whole buffer, without paging through every event with get_event_detail. Each result carries total (match count), scopes (per-scope breakdown: url/reqHeaders/reqBody/respHeaders/respBody), and the matching event's summary (host/url/method/status) inline. query is required; scopes optionally narrows which parts are searched (omit for all); caseSensitive (default false); regex treats query as a JS regex (a dangerous/over-long pattern safely degrades to a literal search rather than erroring). device optional — omit to search every Roku with captured traffic. limit caps results (default 50, max 500). Requires Network Inspector enabled (see network_inspector_status).

network_inspector_get_ca_infoA

Return the Dev Studio MITM CA fingerprint, proxy host:port, and the BrightScript snippet needed to trust the proxy so HTTPS request/response bodies become visible to the Network Inspector. Use when network_inspector_list_events shows TLS handshakes but no decrypted HTTP bodies, to guide the user through enabling HTTPS decryption for their sideloaded dev channel.

debugger_attachA

Open a BrightScript debug session to the Roku on control port 8081. REQUIRED FIRST — every other debugger_* tool needs an attached session. Prefer calling the read-only debugger_status before this one: if it already reports attached/running/stopped, skip this call entirely and go straight to the debugger_* operation you need. The port is only open when the channel was launched with debugging (sideload "with Debugging", or a STOP in the source auto-enables it); a plain sideload/relaunch does NOT open it, and attach returns an actionable error explaining that. Safe to call anyway even when already attached: if a healthy session for this device already exists (e.g. the user attached via the app's own debugger UI), this is a no-op that returns success without touching it — it only tears down and reconnects when there is no session, or the existing one is stale/errored (the control port is single-client, so a doomed reconnect would otherwise kill a working session for nothing). On success returns { ip, state }.

debugger_detachA

Close the debug session for a device (releases the 8081 control socket). Idempotent — a no-op if not attached. The running channel keeps executing.

debugger_statusA

Return the session state for a device WITHOUT blocking: one of disconnected (not attached), connecting, attached, running, stopped (HALTED — safe to inspect), or error. Call this before debugger_attach — if it already reports attached/running/stopped, a session is already up (maybe from the app's own debugger UI) and you can skip straight to the operation you need. Also poll this to decide whether inspection tools will work; to block until the next halt use debugger_wait_for_stop instead.

debugger_wait_for_stopA

Block (server-side poll) until the target HALTS at a breakpoint / STOP / step-completion / runtime error, then return { stopped: true, stop: { reason, detail, threads, stackFrames, variables } } — the top-frame snapshot. Returns { stopped: false, timedOut: true } if it is still running at the deadline, or { stopped:false, state } if the session ended. Call this right after debugger_continue / debugger_step, or after triggering the app, to know when you can inspect. Optional timeoutMs (default 15000, max 30000).

debugger_continueA

Resume execution from a halted state (run until the next breakpoint / STOP / error). After calling this, use debugger_wait_for_stop to catch the next halt. Only meaningful while stopped.

debugger_pauseA

Request a halt of a running channel (best-effort). Follow with debugger_wait_for_stop to get the snapshot once it stops. Only meaningful while running.

debugger_stepA

Single-step the halted thread. kind: "over" (default — next line, skipping calls), "in" (into the call), or "out" (finish the current function). Requires the target to be HALTED. Follow with debugger_wait_for_stop to get the new location.

debugger_get_callstackA

Return the call-stack frames (function, file, line — top frame first) for the halted thread. Requires the target to be HALTED. Optional threadIndex (default the stopped/primary thread). A frame index from here feeds stackFrameIndex in debugger_get_variables / debugger_evaluate.

debugger_get_variablesA

Return variables in scope at a stack frame while HALTED. With no variablePath, returns the frame's locals (incl. m); each entry has name, type, value, and for containers a childCount. To drill into a container, pass its variablePath (e.g. ["m","top"]; a quoted "key" segment forces a case-sensitive AA lookup, a bare number indexes an array) — the response is [container] whose .children is the next level. Optional stackFrameIndex (default 0 = top) and threadIndex.

debugger_evaluateA

Run a BrightScript expression/statement in the halted frame (the debug-console REPL) — e.g. print m.top.count or print type(node). Output streams to the device console; the result reports compile/runtime errors if any. Requires the target to be HALTED. Can have side effects (it executes code), so it is not read-only. For a plain variable read prefer debugger_get_variables. Optional stackFrameIndex / threadIndex select the scope.

debugger_set_breakpointsA

Add breakpoints. breakpoints: array of { path, line, condition?, hitCount? }path is a pkg:/… source path (a bare path is prefixed with pkg:/), condition is an optional BrightScript expression (Roku OS 11.5+), hitCount skips that many hits first. IMPORTANT: the device only registers breakpoints while HALTED — one added while the channel is running comes back pending:true and is queued to register at the next stop. Each result carries a breakpointId (registered) or an error. Existing conditions are replaced on re-add.

debugger_remove_breakpointsA

Remove breakpoints by location. locations: array of { filePath, lineNumber } (matching what debugger_list_breakpoints reports). Removal is by file:line so it also clears a still-queued breakpoint that has no device id yet. Returns { removed }.

debugger_list_breakpointsA

List the breakpoints the debugger is tracking for a device: each with filePath, lineNumber, conditionalExpression?, hitCount?, verified (registered on the device), queued (waiting for the next halt to register), and breakpointId?. Read-only.

keypressA

Send one ECP remote key (e.g. "Home", "Up", "Select", "Play") to a Roku device — mirrors a physical remote press. Mutates on-screen state: each key advances the UI, so repeated calls are NOT a no-op. Use keypress for navigation/transport keys; to type characters into a focused text field use input_text (far faster than sending "Lit_" keys one at a time).

launch_appA

Launch a channel / app on the device to its home screen by app id. Discover ids with ecp_query "/query/apps"; "dev" is the sideloaded Dev App. Changes device state (foregrounds the app). To open the app directly on a specific title use deep_link instead; optional launch params are passed through as ECP query params.

input_textA

Type a literal text string into whatever input field is currently focused on the device (ECP /input endpoint). Requires a text field to already be focused — use keypress to navigate into one first. Mutates the focused field: repeated calls append, so this is NOT read-only or idempotent. Use this instead of sending characters as individual keypress keys.

deep_linkA

Launch an app straight into a specific piece of content via ECP Deep-Link (contentId + mediaType, plus any extra params the channel expects). Equivalent to /launch/?contentId=...&mediaType=...&. Changes device state (foregrounds the app on the requested content). Use this when you have a content id to open; to just open an app to its home screen use launch_app instead.

ecp_queryA

Run a read-only ECP GET against a device (device info, installed apps, active app, media player state, …). Pick an endpoint from list_query_presets or pass any /query/* path. Read-only — does not change device state. This is the go-to inspection tool; for state-changing POSTs use ecp_post, and to enumerate app ids call this with "/query/apps".

ecp_postA

POST to an arbitrary ECP endpoint (e.g. /sgrendezvous/track). Side-effecting — agents should use list_post_presets for safe defaults. For read-only lookups use ecp_query instead.

test_connectionA

Probe one known device IP for ECP reachability and return basic device info. Does not require a Dev Studio tab to be open — use it to confirm a specific IP is a reachable Roku before connect_device. Read-only. Differs from its siblings: probe_bridge checks whether Dev Studio itself is running (not a device); scan_devices discovers unknown devices on the network; test_connection verifies one address you already have.

get_app_iconA

Fetch the 336x210 app icon for one installed channel on the device, returned as base64 / data URL (ECP /query/icon/). Read-only. Discover valid app ids with ecp_query "/query/apps" (or launch_app's notes); "dev" is the sideloaded Dev App. Use this to preview a channel's branding — for a picture of the current screen use screenshot instead.

sideloadA

Upload and install a .zip channel package on the device. Destructive: replaces any currently sideloaded Dev App (readOnly false; not safe for autonomous use without user intent). Provide the zip in ONE of two ways: (1) filePath — an absolute path to a .zip on the SAME machine that runs Roku Dev Studio. Do NOT use this when running in a remote agent sandbox (Claude.ai, ChatGPT web) where files only exist inside the agent's container — the path will not resolve on the user's machine. (2) contentBase64 + filename — the .zip bytes inline; this server writes them to a temp file on the user's machine, sideloads, and cleans up. Use this whenever the agent has file content but no shared filesystem with Roku Dev Studio. Password is optional when Dev Studio has remembered it for this device.

delete_sideloadA

Remove the currently sideloaded Dev App from the device. Password optional when Dev Studio has remembered it for this device. Destructive; idempotent (deleting when nothing is sideloaded still ends with no Dev App). To install/replace a Dev App use sideload — you do not need to delete first, since sideload overwrites.

screenshotA

Capture a screenshot of the current device screen and return it inline as an MCP image content block (JPEG, base64). Hosts (Cursor, Claude Desktop, etc.) render this image to the user, so for any human-facing capture let returnImageBase64 default to true (or omit it). Set returnImageBase64: false ONLY for batch / metadata-only flows where no one will view the screenshot; in that case the response is just { success, filename, bytes } and the image will not appear in the chat. Password is optional when Dev Studio has remembered it for this device.

scan_devicesA

Discover Roku devices on the local network via SSDP (multicast) and, optionally, a subnet HTTP sweep. Read-only; does not connect devices — follow up with connect_device to open a tab. Use this to FIND unknown devices; to list devices Dev Studio already knows (connected / remembered) without a network scan, use list_devices instead.

rale_commandA

Run any built-in RALE command against the active App Connector session — including destructive ones (addRegistryField, removeRegistrySection, clearRegistry, …). Use list_rale_builtins for the catalog. Every call surfaces as a toast in Dev Studio. Some commands read (getNodeById, getRegistry) and some write; the tool as a whole is not read-only — for a plain read prefer rale_get_node_by_id.

app_connector_connectA

Open a RALE / App Connector session against the device's running Dev App. Mutates session state (establishes a connection), so it is not read-only; idempotent — reconnecting an open session is a no-op. You rarely need to call this explicitly: rale_command, app_function, and rale_get_node_by_id auto-connect on demand. Use it only to pre-warm the session or surface connection errors early.

app_connector_disconnectA

Close the RALE / App Connector session on the targeted device. Mutates session state (tears down the connection), so it is not read-only; idempotent — closing an already-closed session is a no-op. Use it to free the session or force a clean reconnect; normal RALE tools do not require you to disconnect between calls.

app_functionA

Invoke a single function on the sideloaded channel through the App Connector. Use this for any one-off function call exposed by the channel; only wrap it in an appFunction Action Script step when the call is part of a multi-step flow. The set of available functions is channel-specific — every sideloaded app exports its own. Always call list_app_connector_functions first to discover the exact name and the declared parameter list (params: [{ name, type }, …]) for the running channel before calling this tool. functionParams is a positional array with one entry per declared parameter, in declaration order. Each entry's value matches the declared type: String/Integer/Boolean/number types are primitives; roAssociativeArray is a JSON object (still wrapped in the outer array slot); roArray / roList is a JSON array (also wrapped). For a zero-arg function pass []. A named object ({ <paramName>: value }, keyed by names from list_app_connector_functions) is accepted for backward compatibility and rewritten to a positional array before the call is sent. Authors should still emit positional form: a typo in a key silently passes undefined for that slot. Auto-connects the App Connector session if needed; surfaces the call as a toast in Dev Studio. Invokes channel code, so it is not read-only and not assumed idempotent — a function may mutate app state.

get_telnet_logA

Read lines from the BrightScript debug console (port 8085) buffer that Dev Studio holds in memory. Returns { lines, cursor, totalLines, connected }. Pass afterCursor (the cursor from a previous call) to get only new lines — use this for polling. maxLines caps the response (default 500, max 2000). Lines only accumulate while the console is connected: if connected is false call telnet_connect first, then re-run this tool. The Roku 8085 telnet socket only allows one client at a time — telnet_connect will close any existing telnet session held by another tool/IDE before attaching. Read-only — it drains the buffer Dev Studio already holds and never touches the device.

telnet_connectB

Open the BrightScript debug console (TCP 8085) for the targeted device, exactly as if the user had clicked the Connect button on the Telnet Console tab. Idempotent: returns { connected: true, already: true } when already attached. Lines do not accumulate until this is called. After it returns successfully, poll the buffer with get_telnet_log({ afterCursor }). Roku's 8085 socket is single-client: connecting here will displace another tool (e.g. an IDE telnet session) that may currently hold it. Opening the socket is a side effect (displaces other clients), so this is not read-only; idempotent — already-attached returns { already: true }.

telnet_disconnectB

Close the BrightScript debug console (TCP 8085) for the targeted device, mirroring the Disconnect button. Idempotent: returns { connected: false, already: true } when no session is open. Use this to release the 8085 socket so another tool can attach, or to stop log accumulation. Closing the socket is a side effect, so this is not read-only; idempotent — already-closed returns { already: true }.

console_monitor_findingsA

Analyze the in-memory BrightScript debug console (port 8085) buffer and return the recognized BrightScript ISSUES and CRASHES — the same data the Console Monitor UI shows. Returns { connected, scannedLines, totalCaptured, totalIssues, issueTypeCount, byCategory, findings, crashes }, where each finding is { id, title, category, severity, meaning, cause, fix, docsUrl?, count, lines } and lines is that issue's unique console lines with per-line count and (when present) file/line. crashes are Micro Debugger dumps (uncaught runtime errors): each is { message, code?, file?, line?, backtrace[], count, exited?, app?, raw } where backtrace is the stack ({ depth, func, file?, line? }, innermost first) and exited marks a fatal EXIT_BRIGHTSCRIPT_CRASH. Only Roku/BrightScript-emitted diagnostics (BRIGHTSCRIPT: ERROR:/WARNING:, rendezvous, FormatJSON, roUrlEvent, …) are recognized — NOT arbitrary app log output. Data only accumulates while the console is connected: if connected is false call telnet_connect first. Read-only — it analyzes the buffer Dev Studio already holds and never touches the device.

device_performance_metricsA

Time-series Device Performance metrics — the same chanperf/r2d2-bitmaps/app-object-counts data the Remote tab's CPU/Memory/BrightScript Objects quad charts poll and plot, returned as compact per-timestamp entries with a decoding legend. Requires "Show Device Performance" (quad layout) to have been turned on for this device tab at some point this session, with the sideloaded Dev channel as the foreground app — if it never was, devicePerformanceEnabled is false and samples is empty (never an error). charts selects which of cpu/memory/objects to include (default: all three) — each requested type appears as its own key per sample (c=cpu, m=memory, o=objects; see legend for field meanings). windowSec (default 60) sets how far back from now to report; if the device's retained history is shorter, actualWindowSec/sampleCount reflect what was actually available. A window whose natural sample count exceeds maxSamples (default 120, max 500) is evenly downsampled across the window (not truncated from one end) and downsampled is set true. cpuProcessSnapshot (only present when cpu is requested) is a single latest-value object (process state, channel uptime, CPU time, cumulative fault counts) — Roku's <proc-stat> block has no historical series of its own, only the fault-rate numbers inside each cpu sample do. Read-only.

Prompts

Interactive templates invoked by user choice

NameDescription
roku-one-shot-actionPrimes the agent to perform a single deterministic action (keypress, launch, ecp_query/post, rale_command, screenshot, …) via a direct op — **not** by authoring an Action Script.
roku-action-script-quickstartPrimes the agent to author an Action Script for multi-step / conditional / saved-or-reviewed flows (bridge probe → capability load → validate → send to Builder). For single actions, prefer `roku-one-shot-action`.
roku-debug-devicePrimes the agent to inspect a Roku using read-only tools (probe_bridge → list_devices → get_selected_device → ecp_query / rale_get_node_by_id).

Resources

Contextual data attached and managed by the client

NameDescription
quick-startOne-page primer: bridge probe, capability loading, device selection, and the validate → send workflow. Read first.
action-script-contractCanonical shape for validate_script / send_script_to_builder inputs (root, appFunction params, wait / if conditions).
capability-bundleEvery static catalog the agent needs in one JSON: actions, presets, vocabularies, RALE built-ins, authoring rules, op directory, and the agent contract.
authoring-rulesConstraints the agent must obey when generating Action Scripts (version, password handling, wait vs delay, …).

TDQS

A3.9/5.0

Scored across 51 tools

Disambiguation5/5

Every tool has a clearly distinct purpose, with detailed descriptions that eliminate ambiguity. Related tools (e.g., device discovery vs. connection vs. testing) are well-separated, and overlapping functions like rale_command vs. rale_get_node_by_id are explicitly distinguished.

Naming Consistency4/5

Tool names follow a mostly consistent verb_noun pattern (e.g., get_selected_device, list_devices, connect_device, debugger_continue). Minor deviations like 'keypress', 'sideload', and 'app_function' are understandable and do not cause confusion, but the pattern is not perfectly uniform.

Tool Count1/5

With 51 tools, the count far exceeds the 25+ threshold and even the 50+ extreme mismatch line. While the server covers a broad Roku development domain, the sheer number of tools is excessive and likely overwhelming for agents, suggesting a need for consolidation or modularization.

Completeness5/5

The toolset covers the full Roku development lifecycle: device discovery/connection, ECP control, debugging, app connector operations, telnet logging, network inspection, performance metrics, action scripting, and sideloading. There are no obvious gaps or dead ends; every operation an agent would need for Roku development is represented.

Maintenance

ActivityActive
ResponsivenessUnresponsive