roku-mcp 1.7.0 → 1.8.3

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 CHANGED
@@ -11,6 +11,17 @@ npm install -g roku-mcp # optional, global install
11
11
  # or just point your client at: npx -y roku-mcp
12
12
  ```
13
13
 
14
+ ### Plugin mode (Claude Code and Cursor)
15
+
16
+ > Unofficial community tool. Not affiliated with or endorsed by Roku, Inc.
17
+
18
+ The repo also ships as a plugin: the MCP server, workflow skills (`skills/`), and Cursor rules, registered together.
19
+
20
+ - **Claude Code:** `/plugin marketplace add jack1590/RokuMCP` then `/plugin install roku-mcp@roku-mcp-marketplace`. Manifests: `.claude-plugin/`, `.mcp.json`.
21
+ - **Cursor:** manifests in `.cursor-plugin/` and `mcp.json`. Skills in `skills/`, rules in `rules/cursor/`.
22
+
23
+ Claude Code asks for the device host and developer password when the plugin is enabled (the password is stored as sensitive). Both clients use the entry point `bootstrap.mjs`. Both run `npm ci` and `npm run build` on first start (Node 18+). Outside plugin mode, `ROKU_DEVICE_HOST` / `ROKU_DEVICE_PASSWORD` or a project `.env` still work.
24
+
14
25
  Configure your AI client below. Every platform uses the same launch line; only the config file and reload step change.
15
26
 
16
27
  <details>
package/dist/index.js CHANGED
@@ -12,7 +12,7 @@ import { registerStreamTools } from './tools/stream.js';
12
12
  export default function createServer(_options) {
13
13
  const server = new McpServer({
14
14
  name: 'roku-mcp',
15
- version: '1.7.0',
15
+ version: '1.8.3',
16
16
  });
17
17
  registerDeployTools(server);
18
18
  registerEcpTools(server);
@@ -32,7 +32,7 @@ if (isDirectRun) {
32
32
  const { StdioServerTransport } = await import('@modelcontextprotocol/sdk/server/stdio.js');
33
33
  const server = new McpServer({
34
34
  name: 'roku-mcp',
35
- version: '1.7.0',
35
+ version: '1.8.3',
36
36
  });
37
37
  registerDeployTools(server);
38
38
  registerEcpTools(server);
@@ -1,3 +1,7 @@
1
1
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { ParsedProfile, HeaderInfo } from 'bsprof-cli';
3
+ export declare function getProfile(filePath: string): ParsedProfile;
4
+ /** Cheaply read header metadata without parsing the 73M-entry body (duration omitted). */
5
+ export declare function readHeaderInfo(filePath: string): HeaderInfo;
2
6
  export declare function registerBsprofTools(server: McpServer): void;
3
7
  //# sourceMappingURL=bsprof.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"bsprof.d.ts","sourceRoot":"","sources":["../../src/tools/bsprof.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAsCpE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA6I3D"}
1
+ {"version":3,"file":"bsprof.d.ts","sourceRoot":"","sources":["../../src/tools/bsprof.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAcpE,OAAO,KAAK,EAA8C,aAAa,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAwBxG,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,CAQ1D;AAED,0FAA0F;AAC1F,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAuB3D;AAoCD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAkJ3D"}
@@ -1,10 +1,73 @@
1
1
  import { z } from 'zod';
2
- import { readFileSync } from 'fs';
3
- import { parseBsprof, analyzeMemory, analyzeCpu, compareBsprof, buildHeaderInfo, buildParseStats, aggregate, rankFunctions, } from 'bsprof-cli';
2
+ import { readFileSync, statSync } from 'fs';
3
+ import { parseBsprof, analyzeMemory, analyzeCpu, compareBsprof, buildHeaderInfo, buildParseStats, aggregate, rankFunctions, BsprofParser, } from 'bsprof-cli';
4
4
  import { friendlyError } from '../roku-config.js';
5
5
  function jsonify(value) {
6
6
  return JSON.stringify(value, (_k, v) => (typeof v === 'bigint' ? Number(v) : v), 2);
7
7
  }
8
+ /**
9
+ * Parsing a .bsprof is O(entries): a 645 MB file (~73M entries) takes minutes and
10
+ * the parsed profile is ~180 MB resident. To avoid re-parsing the same file across
11
+ * back-to-back tool calls (e.g. info → summary → full, or memory then cpu), cache the
12
+ * most recent parse keyed by path + size + mtime.
13
+ *
14
+ * ponytail: single-entry cache (the parsed profile is large, so we keep only one).
15
+ * Upgrade path: bump to a small size-bounded LRU if multi-file workflows get common.
16
+ */
17
+ const LARGE_FILE_BYTES = 200 * 1024 * 1024;
18
+ let parseCache;
19
+ function cacheKey(filePath) {
20
+ const st = statSync(filePath);
21
+ return `${filePath}:${st.size}:${st.mtimeMs}`;
22
+ }
23
+ export function getProfile(filePath) {
24
+ const key = cacheKey(filePath);
25
+ if (parseCache && parseCache.key === key) {
26
+ return parseCache.profile;
27
+ }
28
+ const profile = parseBsprof(readFileSync(filePath));
29
+ parseCache = { key, profile };
30
+ return profile;
31
+ }
32
+ /** Cheaply read header metadata without parsing the 73M-entry body (duration omitted). */
33
+ export function readHeaderInfo(filePath) {
34
+ const st = statSync(filePath);
35
+ const key = `${filePath}:${st.size}:${st.mtimeMs}`;
36
+ if (parseCache && parseCache.key === key) {
37
+ return buildHeaderInfo(parseCache.profile);
38
+ }
39
+ const buffer = readFileSync(filePath);
40
+ const { header, fileSize } = new BsprofParser(buffer).parseHeaderOnly();
41
+ // The footer timestamp can only be located reliably by reaching it through the
42
+ // body (a back-scan from EOF lands mid-record and decodes garbage). So duration
43
+ // is left at 0 here; it requires a full analyze_bsprof pass to compute.
44
+ const profile = {
45
+ header,
46
+ timestampEnd: undefined,
47
+ fileSize,
48
+ strings: new Map(),
49
+ modules: new Map(),
50
+ pathElements: new Map(),
51
+ parseResult: { count: 0, errors: 0, memoryByPE: new Map(), cpuByPE: new Map() },
52
+ };
53
+ return buildHeaderInfo(profile);
54
+ }
55
+ function largeFileNote(filePath) {
56
+ try {
57
+ const { size } = statSync(filePath);
58
+ if (size >= LARGE_FILE_BYTES) {
59
+ const mb = (size / 1048576).toFixed(0);
60
+ const cached = parseCache && parseCache.key === cacheKey(filePath);
61
+ return cached
62
+ ? undefined
63
+ : `Large profile (${mb} MB): the first analysis parses tens of millions of entries and can take several minutes. The parse is cached, so follow-up analyses of the same file return quickly.`;
64
+ }
65
+ }
66
+ catch {
67
+ // statSync failure surfaces later as a friendlier read error.
68
+ }
69
+ return undefined;
70
+ }
8
71
  function buildOptions(params) {
9
72
  return {
10
73
  top: params.top ?? 30,
@@ -38,8 +101,8 @@ export function registerBsprofTools(server) {
38
101
  },
39
102
  }, async (params) => {
40
103
  try {
41
- const buffer = readFileSync(params.filePath);
42
- const profile = parseBsprof(buffer);
104
+ const note = largeFileNote(params.filePath);
105
+ const profile = getProfile(params.filePath);
43
106
  const options = buildOptions(params);
44
107
  let report;
45
108
  switch (params.mode) {
@@ -72,9 +135,10 @@ export function registerBsprofTools(server) {
72
135
  break;
73
136
  }
74
137
  }
75
- return {
76
- content: [{ type: 'text', text: jsonify(report) }],
77
- };
138
+ const content = [{ type: 'text', text: jsonify(report) }];
139
+ if (note)
140
+ content.unshift({ type: 'text', text: note });
141
+ return { content };
78
142
  }
79
143
  catch (error) {
80
144
  return {
@@ -98,15 +162,17 @@ export function registerBsprofTools(server) {
98
162
  },
99
163
  }, async (params) => {
100
164
  try {
101
- const beforeBuf = readFileSync(params.beforePath);
102
- const afterBuf = readFileSync(params.afterPath);
103
- const before = parseBsprof(beforeBuf);
104
- const after = parseBsprof(afterBuf);
165
+ const note = largeFileNote(params.beforePath) ?? largeFileNote(params.afterPath);
166
+ // ponytail: single-entry cache means comparing two distinct files re-parses
167
+ // each on every call. Parse the larger file second so it's the one left cached.
168
+ const before = getProfile(params.beforePath);
169
+ const after = getProfile(params.afterPath);
105
170
  const options = buildOptions(params);
106
171
  const diff = compareBsprof(before, after, params.beforePath, params.afterPath, options);
107
- return {
108
- content: [{ type: 'text', text: jsonify(diff) }],
109
- };
172
+ const content = [{ type: 'text', text: jsonify(diff) }];
173
+ if (note)
174
+ content.unshift({ type: 'text', text: note });
175
+ return { content };
110
176
  }
111
177
  catch (error) {
112
178
  return {
@@ -116,17 +182,21 @@ export function registerBsprofTools(server) {
116
182
  }
117
183
  });
118
184
  server.registerTool('bsprof_info', {
119
- description: 'Get header metadata from a .bsprof file without full analysis — target name, device model, firmware, format version, duration, file size, and enabled features.',
185
+ description: 'Get header metadata from a .bsprof file without full analysis — target name, device model, firmware, format version, duration, file size, and enabled features. Reads only the header/footer, so it is instant even on multi-hundred-MB profiles.',
120
186
  inputSchema: {
121
187
  filePath: z.string().describe('Absolute path to the .bsprof file'),
122
188
  },
123
189
  }, async (params) => {
124
190
  try {
125
- const buffer = readFileSync(params.filePath);
126
- const profile = parseBsprof(buffer);
127
- const info = buildHeaderInfo(profile);
191
+ const info = readHeaderInfo(params.filePath);
128
192
  return {
129
- content: [{ type: 'text', text: jsonify(info) }],
193
+ content: [
194
+ { type: 'text', text: jsonify(info) },
195
+ {
196
+ type: 'text',
197
+ text: 'Note: duration is reported as 0 here — bsprof_info reads only the header for speed. Run analyze_bsprof for the full profile (and the duration, when the file has a footer timestamp).',
198
+ },
199
+ ],
130
200
  };
131
201
  }
132
202
  catch (error) {
@@ -1 +1 @@
1
- {"version":3,"file":"bsprof.js","sourceRoot":"","sources":["../../src/tools/bsprof.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bsprof.js","sourceRoot":"","sources":["../../src/tools/bsprof.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "roku-mcp",
3
- "version": "1.7.0",
3
+ "version": "1.8.3",
4
4
  "description": "MCP server for Roku device automation — deploy, ECP control, screenshots, debug console, and BrightScript profiler analysis",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -37,7 +37,7 @@
37
37
  "watch": "tsc --watch",
38
38
  "start": "node dist/index.js",
39
39
  "build:test": "tsc -p tsconfig.test.json && node -e \"const fs=require('fs');fs.copyFileSync('src/stream/roku-specs.json','dist-test/src/stream/roku-specs.json')\"",
40
- "test": "npm run build:test && node --test dist-test/test/diagnose.regression.test.js",
40
+ "test": "npm run build:test && node --test \"dist-test/test/*.test.js\"",
41
41
  "prepublishOnly": "npm test",
42
42
  "prepare": "npm run build"
43
43
  },
@@ -47,7 +47,7 @@
47
47
  "axios": "^1.13.6",
48
48
  "bsprof-cli": "^1.0.0",
49
49
  "dotenv": "^17.3.1",
50
- "fast-xml-parser": "^5.5.9",
50
+ "fast-xml-parser": "^5.7.0",
51
51
  "roku-deploy": "^3.16.3",
52
52
  "roku-perfetto": "^1.0.2",
53
53
  "zod": "^4.3.6"
@@ -55,5 +55,8 @@
55
55
  "devDependencies": {
56
56
  "@types/node": "^25.5.0",
57
57
  "typescript": "^6.0.2"
58
+ },
59
+ "overrides": {
60
+ "fast-xml-parser": "^5.7.0"
58
61
  }
59
62
  }