roku-mcp 1.2.0 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +82 -24
- package/dist/index.js +1 -1
- package/dist/roku-config.d.ts +1 -0
- package/dist/roku-config.d.ts.map +1 -1
- package/dist/roku-config.js +25 -3
- package/dist/roku-config.js.map +1 -1
- package/dist/tools/console.d.ts.map +1 -1
- package/dist/tools/console.js +26 -13
- package/dist/tools/console.js.map +1 -1
- package/dist/tools/deploy.d.ts.map +1 -1
- package/dist/tools/deploy.js +22 -10
- package/dist/tools/deploy.js.map +1 -1
- package/dist/tools/ecp.d.ts.map +1 -1
- package/dist/tools/ecp.js +9 -17
- package/dist/tools/ecp.js.map +1 -1
- package/dist/tools/screenshot.d.ts.map +1 -1
- package/dist/tools/screenshot.js +2 -3
- package/dist/tools/screenshot.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,15 +8,17 @@ A [Model Context Protocol](https://modelcontextprotocol.io/) (MCP) server for Ro
|
|
|
8
8
|
npm install -g roku-mcp
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
Or run directly with npx:
|
|
11
|
+
Or run directly with npx (no install required):
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
14
|
npx roku-mcp
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
##
|
|
17
|
+
## Client Configuration
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
### Cursor
|
|
20
|
+
|
|
21
|
+
1. Create `.cursor/mcp.json` in your project root:
|
|
20
22
|
|
|
21
23
|
```json
|
|
22
24
|
{
|
|
@@ -33,42 +35,59 @@ Add the following to your project's `.cursor/mcp.json`:
|
|
|
33
35
|
}
|
|
34
36
|
```
|
|
35
37
|
|
|
36
|
-
|
|
38
|
+
2. Reload the window: `Cmd+Shift+P` (macOS) / `Ctrl+Shift+P` (Windows/Linux) → **Developer: Reload Window**
|
|
39
|
+
3. Go to **Cursor Settings → MCP** and verify the "roku" server shows a green status. If it appears disabled, click the toggle to enable it.
|
|
37
40
|
|
|
38
|
-
|
|
41
|
+
### VS Code
|
|
39
42
|
|
|
40
|
-
|
|
41
|
-
|---|---|
|
|
42
|
-
| `ROKU_DEVICE_HOST` | IP address or hostname of the Roku device |
|
|
43
|
-
| `ROKU_DEVICE_PASSWORD` | Developer password for the Roku device |
|
|
44
|
-
|
|
45
|
-
Both can also be passed as parameters on each tool call, which override the environment variables.
|
|
43
|
+
Requires VS Code **1.99+** with the GitHub Copilot extension.
|
|
46
44
|
|
|
47
|
-
|
|
45
|
+
1. Create `.vscode/mcp.json` in your project root:
|
|
48
46
|
|
|
49
|
-
|
|
47
|
+
```json
|
|
48
|
+
{
|
|
49
|
+
"servers": {
|
|
50
|
+
"roku": {
|
|
51
|
+
"command": "npx",
|
|
52
|
+
"args": ["-y", "roku-mcp"],
|
|
53
|
+
"env": {
|
|
54
|
+
"ROKU_DEVICE_HOST": "192.168.1.XXX",
|
|
55
|
+
"ROKU_DEVICE_PASSWORD": "your-password"
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
```
|
|
50
61
|
|
|
51
|
-
|
|
62
|
+
2. Reload the window: `Cmd+Shift+P` / `Ctrl+Shift+P` → **Developer: Reload Window**
|
|
63
|
+
3. Open Copilot Chat and switch to **Agent mode** (select from the chat mode dropdown). The roku tools will be available there.
|
|
52
64
|
|
|
53
|
-
|
|
65
|
+
### Claude Desktop
|
|
54
66
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
```
|
|
67
|
+
Add to your Claude Desktop config file:
|
|
68
|
+
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
69
|
+
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
59
70
|
|
|
60
71
|
```json
|
|
61
72
|
{
|
|
62
73
|
"mcpServers": {
|
|
63
74
|
"roku": {
|
|
64
75
|
"command": "npx",
|
|
65
|
-
"args": ["-y", "roku-mcp"]
|
|
76
|
+
"args": ["-y", "roku-mcp"],
|
|
77
|
+
"env": {
|
|
78
|
+
"ROKU_DEVICE_HOST": "192.168.1.XXX",
|
|
79
|
+
"ROKU_DEVICE_PASSWORD": "your-password"
|
|
80
|
+
}
|
|
66
81
|
}
|
|
67
82
|
}
|
|
68
83
|
}
|
|
69
84
|
```
|
|
70
85
|
|
|
71
|
-
|
|
86
|
+
Restart Claude Desktop after saving.
|
|
87
|
+
|
|
88
|
+
### Windsurf
|
|
89
|
+
|
|
90
|
+
Create `.windsurf/mcp.json` in your project root:
|
|
72
91
|
|
|
73
92
|
```json
|
|
74
93
|
{
|
|
@@ -77,21 +96,60 @@ If your project uses different variable names (e.g. `ROKU_IP`, `ROKU_DEV_PASSWOR
|
|
|
77
96
|
"command": "npx",
|
|
78
97
|
"args": ["-y", "roku-mcp"],
|
|
79
98
|
"env": {
|
|
80
|
-
"ROKU_DEVICE_HOST": "
|
|
81
|
-
"ROKU_DEVICE_PASSWORD": "
|
|
99
|
+
"ROKU_DEVICE_HOST": "192.168.1.XXX",
|
|
100
|
+
"ROKU_DEVICE_PASSWORD": "your-password"
|
|
82
101
|
}
|
|
83
102
|
}
|
|
84
103
|
}
|
|
85
104
|
}
|
|
86
105
|
```
|
|
87
106
|
|
|
88
|
-
|
|
107
|
+
Reload the window after saving.
|
|
108
|
+
|
|
109
|
+
### Any MCP-compatible client
|
|
110
|
+
|
|
111
|
+
The server uses **stdio transport**. Any client that supports MCP can launch it with:
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
command: npx
|
|
115
|
+
args: ["-y", "roku-mcp"]
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Pass `ROKU_DEVICE_HOST` and `ROKU_DEVICE_PASSWORD` as environment variables, or omit the host to use SSDP auto-discovery.
|
|
119
|
+
|
|
120
|
+
## Environment Variables
|
|
121
|
+
|
|
122
|
+
| Variable | Description |
|
|
123
|
+
|---|---|
|
|
124
|
+
| `ROKU_DEVICE_HOST` | IP address or hostname of the Roku device |
|
|
125
|
+
| `ROKU_DEVICE_PASSWORD` | Developer password for the Roku device |
|
|
126
|
+
|
|
127
|
+
Both can also be passed as parameters on each tool call, which override the environment variables.
|
|
128
|
+
|
|
129
|
+
### Auto-discovery
|
|
130
|
+
|
|
131
|
+
If `ROKU_DEVICE_HOST` is not set and no `host` parameter is provided, the server automatically discovers Roku devices on the local network using SSDP and uses the first one found. You can also use the `roku_discover` tool to list all available devices. Note that the password cannot be discovered and must still be configured.
|
|
132
|
+
|
|
133
|
+
### `.env` file support
|
|
134
|
+
|
|
135
|
+
The server automatically loads a `.env` file from the current working directory using [dotenv](https://www.npmjs.com/package/dotenv). If your project's `.env` already uses `ROKU_DEVICE_HOST` and `ROKU_DEVICE_PASSWORD`, the server picks them up with no extra configuration — just omit the `env` block from your MCP config:
|
|
89
136
|
|
|
90
137
|
```
|
|
91
138
|
ROKU_DEVICE_HOST=192.168.1.100
|
|
92
139
|
ROKU_DEVICE_PASSWORD=my-password
|
|
93
140
|
```
|
|
94
141
|
|
|
142
|
+
If your project uses different variable names (e.g. `ROKU_IP`, `ROKU_DEV_PASSWORD`), you can map them in the `env` block:
|
|
143
|
+
|
|
144
|
+
```json
|
|
145
|
+
"env": {
|
|
146
|
+
"ROKU_DEVICE_HOST": "${ROKU_IP}",
|
|
147
|
+
"ROKU_DEVICE_PASSWORD": "${ROKU_DEV_PASSWORD}"
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Or simply add the two expected variables to your `.env` alongside your existing ones.
|
|
152
|
+
|
|
95
153
|
## Available Tools
|
|
96
154
|
|
|
97
155
|
### Deploy
|
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import { registerScreenshotTools } from './tools/screenshot.js';
|
|
|
8
8
|
import { registerConsoleTools } from './tools/console.js';
|
|
9
9
|
const server = new McpServer({
|
|
10
10
|
name: 'roku-mcp',
|
|
11
|
-
version: '1.
|
|
11
|
+
version: '1.2.2',
|
|
12
12
|
});
|
|
13
13
|
registerDeployTools(server);
|
|
14
14
|
registerEcpTools(server);
|
package/dist/roku-config.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roku-config.d.ts","sourceRoot":"","sources":["../src/roku-config.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,aAAa,CAAC,MAAM,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAgB3G;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAQ5E"}
|
|
1
|
+
{"version":3,"file":"roku-config.d.ts","sourceRoot":"","sources":["../src/roku-config.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,aAAa,CAAC,MAAM,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAgB3G;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAQ5E;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAuBpD"}
|
package/dist/roku-config.js
CHANGED
|
@@ -3,18 +3,40 @@ export async function resolveConfig(params) {
|
|
|
3
3
|
const host = params.host || process.env.ROKU_DEVICE_HOST || await discoverFirstHost();
|
|
4
4
|
const password = params.password || process.env.ROKU_DEVICE_PASSWORD;
|
|
5
5
|
if (!host) {
|
|
6
|
-
throw new Error('Roku device
|
|
6
|
+
throw new Error('No Roku device found. Please provide the device IP as a parameter, set ROKU_DEVICE_HOST in your .env file, or make sure a Roku device is powered on and connected to the same network.');
|
|
7
7
|
}
|
|
8
8
|
if (!password) {
|
|
9
|
-
throw new Error('Roku
|
|
9
|
+
throw new Error('Roku developer password is required. Please provide the password as a parameter or set ROKU_DEVICE_PASSWORD in your .env file.');
|
|
10
10
|
}
|
|
11
11
|
return { host, password };
|
|
12
12
|
}
|
|
13
13
|
export async function resolveHost(params) {
|
|
14
14
|
const host = params.host || process.env.ROKU_DEVICE_HOST || await discoverFirstHost();
|
|
15
15
|
if (!host) {
|
|
16
|
-
throw new Error('Roku device
|
|
16
|
+
throw new Error('No Roku device found. Please provide the device IP as a parameter, set ROKU_DEVICE_HOST in your .env file, or make sure a Roku device is powered on and connected to the same network.');
|
|
17
17
|
}
|
|
18
18
|
return host;
|
|
19
19
|
}
|
|
20
|
+
export function friendlyError(error) {
|
|
21
|
+
const raw = error instanceof Error ? error.message : String(error);
|
|
22
|
+
if (/401|unauthorized/i.test(raw)) {
|
|
23
|
+
return 'Authentication failed — the Roku developer password is incorrect. Please provide the correct password.';
|
|
24
|
+
}
|
|
25
|
+
if (/403|forbidden/i.test(raw)) {
|
|
26
|
+
return 'Access denied by the Roku device. Make sure Developer Mode is enabled and the password is correct.';
|
|
27
|
+
}
|
|
28
|
+
if (/ECONNREFUSED/i.test(raw)) {
|
|
29
|
+
return `Connection refused — the Roku device is not reachable. Verify the IP address is correct and the device is powered on.`;
|
|
30
|
+
}
|
|
31
|
+
if (/ETIMEDOUT|ESOCKETTIMEDOUT|timeout/i.test(raw)) {
|
|
32
|
+
return 'Connection timed out — the Roku device did not respond. Check that it is on the same network and not blocked by a firewall.';
|
|
33
|
+
}
|
|
34
|
+
if (/ENOTFOUND|getaddrinfo/i.test(raw)) {
|
|
35
|
+
return `Could not resolve the Roku device hostname. Verify the host address is correct.`;
|
|
36
|
+
}
|
|
37
|
+
if (/No screen shot url/i.test(raw)) {
|
|
38
|
+
return 'Screenshot failed — no sideloaded dev channel is currently running on the device. Deploy an app first.';
|
|
39
|
+
}
|
|
40
|
+
return raw;
|
|
41
|
+
}
|
|
20
42
|
//# sourceMappingURL=roku-config.js.map
|
package/dist/roku-config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roku-config.js","sourceRoot":"","sources":["../src/roku-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAOnD,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,MAA4C;IAC9E,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,MAAM,iBAAiB,EAAE,CAAC;IACtF,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC;IAErE,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CACb,
|
|
1
|
+
{"version":3,"file":"roku-config.js","sourceRoot":"","sources":["../src/roku-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAOnD,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,MAA4C;IAC9E,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,MAAM,iBAAiB,EAAE,CAAC;IACtF,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC;IAErE,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CACb,wLAAwL,CACzL,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CACb,gIAAgI,CACjI,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AAC5B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAAyB;IACzD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,MAAM,iBAAiB,EAAE,CAAC;IACtF,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CACb,wLAAwL,CACzL,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAEnE,IAAI,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAClC,OAAO,wGAAwG,CAAC;IAClH,CAAC;IACD,IAAI,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/B,OAAO,oGAAoG,CAAC;IAC9G,CAAC;IACD,IAAI,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9B,OAAO,uHAAuH,CAAC;IACjI,CAAC;IACD,IAAI,oCAAoC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACnD,OAAO,6HAA6H,CAAC;IACvI,CAAC;IACD,IAAI,wBAAwB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACvC,OAAO,iFAAiF,CAAC;IAC3F,CAAC;IACD,IAAI,qBAAqB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACpC,OAAO,wGAAwG,CAAC;IAClH,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../../src/tools/console.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAcpE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../../src/tools/console.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAcpE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA2L5D"}
|
package/dist/tools/console.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import net from 'net';
|
|
3
|
-
import { resolveHost } from '../roku-config.js';
|
|
3
|
+
import { resolveHost, friendlyError } from '../roku-config.js';
|
|
4
4
|
let session = null;
|
|
5
5
|
export function registerConsoleTools(server) {
|
|
6
6
|
server.registerTool('roku_console_connect', {
|
|
@@ -29,7 +29,7 @@ export function registerConsoleTools(server) {
|
|
|
29
29
|
const timeout = setTimeout(() => {
|
|
30
30
|
socket.destroy();
|
|
31
31
|
resolve({
|
|
32
|
-
content: [{ type: 'text', text: `Connection to ${host}:${port} timed out
|
|
32
|
+
content: [{ type: 'text', text: `Connection to ${host}:${port} timed out — make sure the Roku device is on the same network and has a sideloaded dev channel running.` }],
|
|
33
33
|
isError: true,
|
|
34
34
|
});
|
|
35
35
|
}, 10_000);
|
|
@@ -58,7 +58,7 @@ export function registerConsoleTools(server) {
|
|
|
58
58
|
}
|
|
59
59
|
if (!newSession.connected) {
|
|
60
60
|
resolve({
|
|
61
|
-
content: [{ type: 'text', text: `
|
|
61
|
+
content: [{ type: 'text', text: `Console connection failed: ${friendlyError(err)}` }],
|
|
62
62
|
isError: true,
|
|
63
63
|
});
|
|
64
64
|
}
|
|
@@ -66,15 +66,14 @@ export function registerConsoleTools(server) {
|
|
|
66
66
|
});
|
|
67
67
|
}
|
|
68
68
|
catch (error) {
|
|
69
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
70
69
|
return {
|
|
71
|
-
content: [{ type: 'text', text: `Console connect failed: ${
|
|
70
|
+
content: [{ type: 'text', text: `Console connect failed: ${friendlyError(error)}` }],
|
|
72
71
|
isError: true,
|
|
73
72
|
};
|
|
74
73
|
}
|
|
75
74
|
});
|
|
76
75
|
server.registerTool('roku_console_read', {
|
|
77
|
-
description: 'Read buffered output from the BrightScript debug console since the last read.
|
|
76
|
+
description: 'Read buffered output from the BrightScript debug console since the last read. Automatically disconnects after reading.',
|
|
78
77
|
}, async () => {
|
|
79
78
|
if (!session?.connected) {
|
|
80
79
|
return {
|
|
@@ -85,17 +84,20 @@ export function registerConsoleTools(server) {
|
|
|
85
84
|
await new Promise((r) => setTimeout(r, 200));
|
|
86
85
|
const output = session.buffer;
|
|
87
86
|
session.buffer = '';
|
|
87
|
+
const host = session.host;
|
|
88
|
+
session.socket.destroy();
|
|
89
|
+
session = null;
|
|
88
90
|
if (output.length === 0) {
|
|
89
91
|
return {
|
|
90
|
-
content: [{ type: 'text', text:
|
|
92
|
+
content: [{ type: 'text', text: `(no new output) — disconnected from ${host}` }],
|
|
91
93
|
};
|
|
92
94
|
}
|
|
93
95
|
return {
|
|
94
|
-
content: [{ type: 'text', text: output }],
|
|
96
|
+
content: [{ type: 'text', text: output + `\n\n--- disconnected from ${host} ---` }],
|
|
95
97
|
};
|
|
96
98
|
});
|
|
97
99
|
server.registerTool('roku_console_send', {
|
|
98
|
-
description: 'Send a command to the BrightScript debug console. Common commands: bt (backtrace), var (variables), cont (continue), step, over, out, exit, print <expr>.',
|
|
100
|
+
description: 'Send a command to the BrightScript debug console and return the response. Automatically disconnects after receiving the response. Common commands: bt (backtrace), var (variables), cont (continue), step, over, out, exit, print <expr>.',
|
|
99
101
|
inputSchema: {
|
|
100
102
|
command: z.string().describe('Command to send to the debug console'),
|
|
101
103
|
},
|
|
@@ -111,8 +113,13 @@ export function registerConsoleTools(server) {
|
|
|
111
113
|
session.buffer = '';
|
|
112
114
|
session.socket.write(params.command + '\r\n', (err) => {
|
|
113
115
|
if (err) {
|
|
116
|
+
const host = session?.host ?? 'unknown';
|
|
117
|
+
if (session) {
|
|
118
|
+
session.socket.destroy();
|
|
119
|
+
session = null;
|
|
120
|
+
}
|
|
114
121
|
resolve({
|
|
115
|
-
content: [{ type: 'text', text: `Failed to send command: ${err.message}` }],
|
|
122
|
+
content: [{ type: 'text', text: `Failed to send command: ${err.message} — disconnected from ${host}` }],
|
|
116
123
|
isError: true,
|
|
117
124
|
});
|
|
118
125
|
return;
|
|
@@ -120,17 +127,23 @@ export function registerConsoleTools(server) {
|
|
|
120
127
|
setTimeout(() => {
|
|
121
128
|
const output = session.buffer;
|
|
122
129
|
session.buffer = '';
|
|
130
|
+
const host = session.host;
|
|
131
|
+
session.socket.destroy();
|
|
132
|
+
session = null;
|
|
123
133
|
resolve({
|
|
124
|
-
content: [{ type: 'text', text: output || '(command sent, no output received)' }],
|
|
134
|
+
content: [{ type: 'text', text: (output || '(command sent, no output received)') + `\n\n--- disconnected from ${host} ---` }],
|
|
125
135
|
});
|
|
126
136
|
}, 500);
|
|
127
137
|
});
|
|
128
138
|
});
|
|
129
139
|
}
|
|
130
140
|
catch (error) {
|
|
131
|
-
|
|
141
|
+
if (session) {
|
|
142
|
+
session.socket.destroy();
|
|
143
|
+
session = null;
|
|
144
|
+
}
|
|
132
145
|
return {
|
|
133
|
-
content: [{ type: 'text', text: `Console send failed: ${
|
|
146
|
+
content: [{ type: 'text', text: `Console send failed: ${friendlyError(error)}` }],
|
|
134
147
|
isError: true,
|
|
135
148
|
};
|
|
136
149
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"console.js","sourceRoot":"","sources":["../../src/tools/console.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"console.js","sourceRoot":"","sources":["../../src/tools/console.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/tools/deploy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/tools/deploy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAQpE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA8E3D"}
|
package/dist/tools/deploy.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import fs from 'fs/promises';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import os from 'os';
|
|
2
5
|
import { rokuDeploy } from 'roku-deploy';
|
|
3
|
-
import { resolveConfig } from '../roku-config.js';
|
|
6
|
+
import { resolveConfig, friendlyError } from '../roku-config.js';
|
|
4
7
|
export function registerDeployTools(server) {
|
|
5
8
|
server.registerTool('roku_deploy', {
|
|
6
|
-
description: 'Sideload (deploy) a Roku application to the device. A dev channel must not already be running, or it will be replaced.',
|
|
9
|
+
description: 'Sideload (deploy) a Roku application to the device. Packages all files in the project directory and uploads them. A dev channel must not already be running, or it will be replaced.',
|
|
7
10
|
inputSchema: {
|
|
8
11
|
host: z.string().optional().describe('IP address or hostname of the Roku device'),
|
|
9
12
|
password: z.string().optional().describe('Developer password for the Roku device'),
|
|
@@ -11,28 +14,38 @@ export function registerDeployTools(server) {
|
|
|
11
14
|
files: z
|
|
12
15
|
.array(z.string())
|
|
13
16
|
.optional()
|
|
14
|
-
.describe('Glob patterns for files to include. Defaults to
|
|
17
|
+
.describe('Glob patterns for files to include. Defaults to all files in rootDir (**/*).'),
|
|
15
18
|
},
|
|
16
19
|
}, async (params) => {
|
|
17
20
|
try {
|
|
21
|
+
const manifestPath = path.join(params.rootDir, 'manifest');
|
|
22
|
+
try {
|
|
23
|
+
await fs.access(manifestPath);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return {
|
|
27
|
+
content: [{ type: 'text', text: `Deploy failed: No manifest file found at ${manifestPath}. The rootDir must point to the Roku project directory that contains the manifest file.` }],
|
|
28
|
+
isError: true,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
18
31
|
const config = await resolveConfig(params);
|
|
32
|
+
const outDir = path.join(os.tmpdir(), 'roku-mcp-deploy');
|
|
19
33
|
const deployOptions = {
|
|
20
34
|
host: config.host,
|
|
21
35
|
password: config.password,
|
|
22
36
|
rootDir: params.rootDir,
|
|
37
|
+
outDir,
|
|
38
|
+
files: params.files && params.files.length > 0 ? params.files : ['**/*'],
|
|
39
|
+
retainStagingDir: false,
|
|
23
40
|
};
|
|
24
|
-
if (params.files && params.files.length > 0) {
|
|
25
|
-
deployOptions.files = params.files;
|
|
26
|
-
}
|
|
27
41
|
await rokuDeploy.deploy(deployOptions);
|
|
28
42
|
return {
|
|
29
43
|
content: [{ type: 'text', text: `Successfully deployed app from ${params.rootDir} to ${config.host}` }],
|
|
30
44
|
};
|
|
31
45
|
}
|
|
32
46
|
catch (error) {
|
|
33
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
34
47
|
return {
|
|
35
|
-
content: [{ type: 'text', text: `Deploy failed: ${
|
|
48
|
+
content: [{ type: 'text', text: `Deploy failed: ${friendlyError(error)}` }],
|
|
36
49
|
isError: true,
|
|
37
50
|
};
|
|
38
51
|
}
|
|
@@ -55,9 +68,8 @@ export function registerDeployTools(server) {
|
|
|
55
68
|
};
|
|
56
69
|
}
|
|
57
70
|
catch (error) {
|
|
58
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
59
71
|
return {
|
|
60
|
-
content: [{ type: 'text', text: `Delete dev channel failed: ${
|
|
72
|
+
content: [{ type: 'text', text: `Delete dev channel failed: ${friendlyError(error)}` }],
|
|
61
73
|
isError: true,
|
|
62
74
|
};
|
|
63
75
|
}
|
package/dist/tools/deploy.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deploy.js","sourceRoot":"","sources":["../../src/tools/deploy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"deploy.js","sourceRoot":"","sources":["../../src/tools/deploy.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/ecp.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ecp.d.ts","sourceRoot":"","sources":["../../src/tools/ecp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAapE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"ecp.d.ts","sourceRoot":"","sources":["../../src/tools/ecp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAapE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA4OxD"}
|
package/dist/tools/ecp.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import axios from 'axios';
|
|
3
3
|
import { XMLParser } from 'fast-xml-parser';
|
|
4
|
-
import { resolveHost } from '../roku-config.js';
|
|
4
|
+
import { resolveHost, friendlyError } from '../roku-config.js';
|
|
5
5
|
import { discoverRokuDevices } from '../discovery.js';
|
|
6
6
|
const xmlParser = new XMLParser({ ignoreAttributes: false, attributeNamePrefix: '@_' });
|
|
7
7
|
function ecpUrl(host, path) {
|
|
@@ -27,9 +27,8 @@ export function registerEcpTools(server) {
|
|
|
27
27
|
};
|
|
28
28
|
}
|
|
29
29
|
catch (error) {
|
|
30
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
31
30
|
return {
|
|
32
|
-
content: [{ type: 'text', text: `Discovery failed: ${
|
|
31
|
+
content: [{ type: 'text', text: `Discovery failed: ${friendlyError(error)}` }],
|
|
33
32
|
isError: true,
|
|
34
33
|
};
|
|
35
34
|
}
|
|
@@ -49,9 +48,8 @@ export function registerEcpTools(server) {
|
|
|
49
48
|
};
|
|
50
49
|
}
|
|
51
50
|
catch (error) {
|
|
52
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
53
51
|
return {
|
|
54
|
-
content: [{ type: 'text', text: `Key press failed: ${
|
|
52
|
+
content: [{ type: 'text', text: `Key press failed: ${friendlyError(error)}` }],
|
|
55
53
|
isError: true,
|
|
56
54
|
};
|
|
57
55
|
}
|
|
@@ -82,9 +80,8 @@ export function registerEcpTools(server) {
|
|
|
82
80
|
};
|
|
83
81
|
}
|
|
84
82
|
catch (error) {
|
|
85
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
86
83
|
return {
|
|
87
|
-
content: [{ type: 'text', text: `Key sequence failed: ${
|
|
84
|
+
content: [{ type: 'text', text: `Key sequence failed: ${friendlyError(error)}` }],
|
|
88
85
|
isError: true,
|
|
89
86
|
};
|
|
90
87
|
}
|
|
@@ -111,9 +108,8 @@ export function registerEcpTools(server) {
|
|
|
111
108
|
};
|
|
112
109
|
}
|
|
113
110
|
catch (error) {
|
|
114
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
115
111
|
return {
|
|
116
|
-
content: [{ type: 'text', text: `Launch failed: ${
|
|
112
|
+
content: [{ type: 'text', text: `Launch failed: ${friendlyError(error)}` }],
|
|
117
113
|
isError: true,
|
|
118
114
|
};
|
|
119
115
|
}
|
|
@@ -133,9 +129,8 @@ export function registerEcpTools(server) {
|
|
|
133
129
|
};
|
|
134
130
|
}
|
|
135
131
|
catch (error) {
|
|
136
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
137
132
|
return {
|
|
138
|
-
content: [{ type: 'text', text: `Query device info failed: ${
|
|
133
|
+
content: [{ type: 'text', text: `Query device info failed: ${friendlyError(error)}` }],
|
|
139
134
|
isError: true,
|
|
140
135
|
};
|
|
141
136
|
}
|
|
@@ -155,9 +150,8 @@ export function registerEcpTools(server) {
|
|
|
155
150
|
};
|
|
156
151
|
}
|
|
157
152
|
catch (error) {
|
|
158
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
159
153
|
return {
|
|
160
|
-
content: [{ type: 'text', text: `Query active app failed: ${
|
|
154
|
+
content: [{ type: 'text', text: `Query active app failed: ${friendlyError(error)}` }],
|
|
161
155
|
isError: true,
|
|
162
156
|
};
|
|
163
157
|
}
|
|
@@ -176,9 +170,8 @@ export function registerEcpTools(server) {
|
|
|
176
170
|
};
|
|
177
171
|
}
|
|
178
172
|
catch (error) {
|
|
179
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
180
173
|
return {
|
|
181
|
-
content: [{ type: 'text', text: `Query app UI failed: ${
|
|
174
|
+
content: [{ type: 'text', text: `Query app UI failed: ${friendlyError(error)}` }],
|
|
182
175
|
isError: true,
|
|
183
176
|
};
|
|
184
177
|
}
|
|
@@ -212,9 +205,8 @@ export function registerEcpTools(server) {
|
|
|
212
205
|
};
|
|
213
206
|
}
|
|
214
207
|
catch (error) {
|
|
215
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
216
208
|
return {
|
|
217
|
-
content: [{ type: 'text', text: `Query SG nodes failed: ${
|
|
209
|
+
content: [{ type: 'text', text: `Query SG nodes failed: ${friendlyError(error)}` }],
|
|
218
210
|
isError: true,
|
|
219
211
|
};
|
|
220
212
|
}
|
package/dist/tools/ecp.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ecp.js","sourceRoot":"","sources":["../../src/tools/ecp.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"ecp.js","sourceRoot":"","sources":["../../src/tools/ecp.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"screenshot.d.ts","sourceRoot":"","sources":["../../src/tools/screenshot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAOpE,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"screenshot.d.ts","sourceRoot":"","sources":["../../src/tools/screenshot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAOpE,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAsD/D"}
|
package/dist/tools/screenshot.js
CHANGED
|
@@ -2,7 +2,7 @@ import { z } from 'zod';
|
|
|
2
2
|
import { rokuDeploy } from 'roku-deploy';
|
|
3
3
|
import fs from 'fs/promises';
|
|
4
4
|
import path from 'path';
|
|
5
|
-
import { resolveConfig } from '../roku-config.js';
|
|
5
|
+
import { resolveConfig, friendlyError } from '../roku-config.js';
|
|
6
6
|
export function registerScreenshotTools(server) {
|
|
7
7
|
server.registerTool('roku_screenshot', {
|
|
8
8
|
description: 'Capture a screenshot of the current screen on the Roku device. A sideloaded dev channel must be running. Returns the image as base64-encoded content and the file path where it was saved.',
|
|
@@ -45,9 +45,8 @@ export function registerScreenshotTools(server) {
|
|
|
45
45
|
};
|
|
46
46
|
}
|
|
47
47
|
catch (error) {
|
|
48
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
49
48
|
return {
|
|
50
|
-
content: [{ type: 'text', text: `Screenshot failed: ${
|
|
49
|
+
content: [{ type: 'text', text: `Screenshot failed: ${friendlyError(error)}` }],
|
|
51
50
|
isError: true,
|
|
52
51
|
};
|
|
53
52
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"screenshot.js","sourceRoot":"","sources":["../../src/tools/screenshot.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"screenshot.js","sourceRoot":"","sources":["../../src/tools/screenshot.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEjE,MAAM,UAAU,uBAAuB,CAAC,MAAiB;IACvD,MAAM,CAAC,YAAY,CACjB,iBAAiB,EACjB;QACE,WAAW,EAAE,4LAA4L;QACzM,WAAW,EAAE;YACX,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,2CAA2C,CAAC;YACjF,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wCAAwC,CAAC;YAClF,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kEAAkE,CAAC;YAC1G,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kEAAkE,CAAC;SAC5G;KACF,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,MAAM,CAAC,CAAC;YAC3C,MAAM,OAAO,GAA4B;gBACvC,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ;aAC1B,CAAC;YAEF,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;gBAClB,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;YACjC,CAAC;YACD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,OAAO,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;YACnC,CAAC;YAED,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,cAAc,CAAC,OAAc,CAAC,CAAC;YACjE,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;YACjD,MAAM,QAAQ,GAAG,GAAG,KAAK,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC;YAC7D,MAAM,WAAW,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAChD,MAAM,MAAM,GAAG,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAE9C,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,OAAgB;wBACtB,IAAI,EAAE,MAAM;wBACZ,QAAQ;qBACT;oBACD;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,wBAAwB,QAAQ,EAAE;qBACzC;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,sBAAsB,aAAa,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;gBAC/E,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|