@bezda/rhp-mcp 0.0.0-stage → 0.1.1

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.
Files changed (64) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +222 -2
  3. package/bin/rhp-mcp.js +129 -0
  4. package/package.json +62 -4
  5. package/skill/SKILL.md +450 -0
  6. package/skill/recipes/area.html +156 -0
  7. package/skill/recipes/bar.html +145 -0
  8. package/skill/recipes/box-plot.html +164 -0
  9. package/skill/recipes/bubble.html +188 -0
  10. package/skill/recipes/bullet.html +138 -0
  11. package/skill/recipes/candlestick.html +179 -0
  12. package/skill/recipes/column.html +138 -0
  13. package/skill/recipes/dial.html +349 -0
  14. package/skill/recipes/diverging-bars.html +150 -0
  15. package/skill/recipes/donut.html +231 -0
  16. package/skill/recipes/dumbbell.html +137 -0
  17. package/skill/recipes/gantt.html +196 -0
  18. package/skill/recipes/grouped-bars.html +142 -0
  19. package/skill/recipes/heatmap.html +183 -0
  20. package/skill/recipes/histogram.html +199 -0
  21. package/skill/recipes/line.html +170 -0
  22. package/skill/recipes/live.html +255 -0
  23. package/skill/recipes/log-line.html +493 -0
  24. package/skill/recipes/lollipop.html +152 -0
  25. package/skill/recipes/multi-line.html +228 -0
  26. package/skill/recipes/pyramid.html +162 -0
  27. package/skill/recipes/race.html +278 -0
  28. package/skill/recipes/radial-bars.html +157 -0
  29. package/skill/recipes/scatter.html +199 -0
  30. package/skill/recipes/silhouettes.html +352 -0
  31. package/skill/recipes/slope.html +199 -0
  32. package/skill/recipes/sparklines.html +175 -0
  33. package/skill/recipes/stacked-100.html +158 -0
  34. package/skill/recipes/stacked-bars.html +150 -0
  35. package/skill/recipes/strip.html +221 -0
  36. package/skill/recipes/unit-stack.html +276 -0
  37. package/skill/recipes/violin.html +169 -0
  38. package/skill/recipes/waffle.html +165 -0
  39. package/skill/recipes/waterfall.html +127 -0
  40. package/skill/references/api.md +1684 -0
  41. package/skill/references/design.md +740 -0
  42. package/skill/references/environments.md +1577 -0
  43. package/skill/references/forms.md +197 -0
  44. package/skill/references/interaction.md +794 -0
  45. package/skill/references/looks.md +267 -0
  46. package/skill/references/pitfalls.md +202 -0
  47. package/src/check/README.md +176 -0
  48. package/src/check/browser.js +92 -0
  49. package/src/check/build.js +439 -0
  50. package/src/check/colors.js +324 -0
  51. package/src/check/findings.js +247 -0
  52. package/src/check/index.js +508 -0
  53. package/src/check/inpage.js +1332 -0
  54. package/src/check/interact.js +266 -0
  55. package/src/check/png.js +98 -0
  56. package/src/check/report.js +106 -0
  57. package/src/check/source.js +387 -0
  58. package/src/check/sourcemap.js +75 -0
  59. package/src/guard/note.js +30 -0
  60. package/src/guard/render.js +17 -0
  61. package/src/guard/rhp.js +612 -0
  62. package/src/guard/rules.js +125 -0
  63. package/src/server.js +266 -0
  64. package/src/skill.js +140 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Anas Bouzid
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,223 @@
1
- # Temporary Holding Version
1
+ # @bezda/rhp-mcp
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Make charts with [rhp](https://rhp.vercel.app) from any AI agent.
4
+ rhp 2 came out in September 2026, after the training data of today's models, so an agent knows nothing about it until it reads rhp's guide.
5
+ This package carries that guide (the workflow, the references and the tested recipes) and a checker that renders the agent's chart in a browser and reports what is wrong, with a fix for each problem and screenshots to look at.
6
+
7
+ ## Start here: the rhp skill
8
+
9
+ In a coding agent (Claude Code, Cursor, Copilot, Codex, Gemini CLI and others), run this in your project:
10
+
11
+ ```sh
12
+ npx skills add bezda-team/rhp
13
+ ```
14
+
15
+ Then ask for a chart.
16
+ The skill teaches the agent rhp and runs this package's checker by itself with `npx`, so you install nothing else.
17
+
18
+ ## The checker on the command line
19
+
20
+ ```sh
21
+ npx -y @bezda/rhp-mcp check chart.html
22
+ ```
23
+
24
+ It renders the chart at 1280px and 390px wide, tries its interactions, and prints what is wrong, each problem with what to change, then where it saved the screenshots.
25
+ The exit code is 1 when the chart has errors.
26
+ It checks an `.html` page, a Solid or React `.jsx` or `.tsx` component, or a `.js` module that uses `@bezda/rhp/standalone`.
27
+
28
+ | Option | What it does |
29
+ |---|---|
30
+ | `--widths 1280,390` | The page widths to check; the interactions are tried at the first, and slats are tapped at phone widths (600px or less). |
31
+ | `--dark` | Renders with a dark color scheme. |
32
+ | `--no-interact` | Skips the interactions. |
33
+ | `--settle-timeout <ms>` | How long the page may take to come to rest before it is measured, 100 to 30000 ms (10000 by default); raise it on a slow machine. |
34
+ | `--format <format>` | `html`, `solid`, `react` or `module`, when the file's extension and code leave it unclear. |
35
+ | `--json` | Prints the whole result as JSON. |
36
+ | `--out <dir>` | Where the screenshots go (a folder in the system's temp folder by default). |
37
+
38
+ `npx -y @bezda/rhp-mcp guide` prints the guide, for an agent that can run commands but has no skill installed.
39
+
40
+ ## The MCP server
41
+
42
+ The server gives an agent the same guide, references, recipes and checker as four tools, and returns the checker's screenshots as images the agent sees.
43
+ Use it in a client that has no shell (Claude Desktop), or when you would rather give the agent tools than a skill.
44
+ The server alone is enough: its instructions tell the agent to read the guide before it writes any rhp code.
45
+
46
+ Every client starts it with `npx -y @bezda/rhp-mcp`, which needs Node.js 20 or later.
47
+ The first start downloads the package and its dependencies (about 80 MB).
48
+ If your client gives up before the server is ready, run `npx -y @bezda/rhp-mcp --version` once in a terminal and restart the client.
49
+
50
+ ### Claude Code
51
+
52
+ ```sh
53
+ claude mcp add rhp -- npx -y @bezda/rhp-mcp
54
+ ```
55
+
56
+ Add `-s user` to have it in every project, or `-s project` to write it to the project's `.mcp.json` for everyone who works on it.
57
+
58
+ Or install the Claude Code plugin, which carries the skill and this server together:
59
+
60
+ ```sh
61
+ claude plugin marketplace add bezda-team/rhp
62
+ claude plugin install rhp@rhp
63
+ ```
64
+
65
+ The plugin's skill needs Claude Code 2.1.160 or later (2.1.141 loads only the server).
66
+
67
+ ### Claude Desktop
68
+
69
+ Open Settings > Developer > Edit Config, and add the server to `claude_desktop_config.json` (in `~/Library/Application Support/Claude/` on macOS, `%APPDATA%\Claude\` on Windows):
70
+
71
+ ```json
72
+ {
73
+ "mcpServers": {
74
+ "rhp": { "command": "npx", "args": ["-y", "@bezda/rhp-mcp"] }
75
+ }
76
+ }
77
+ ```
78
+
79
+ ### Cursor
80
+
81
+ Open this link in a browser to install it in one click (Cursor's documented install link):
82
+
83
+ ```
84
+ cursor://anysphere.cursor-deeplink/mcp/install?name=rhp&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBiZXpkYS9yaHAtbWNwIl19
85
+ ```
86
+
87
+ Or add the `mcpServers` entry shown for Claude Desktop to `~/.cursor/mcp.json` (every project) or `.cursor/mcp.json` (one project).
88
+
89
+ ### VS Code (GitHub Copilot)
90
+
91
+ ```sh
92
+ code --add-mcp "{\"name\":\"rhp\",\"command\":\"npx\",\"args\":[\"-y\",\"@bezda/rhp-mcp\"]}"
93
+ ```
94
+
95
+ Or add the `mcpServers` entry shown for Claude Desktop to `.mcp.json` at the workspace's root, or to `~/.copilot/mcp-config.json` for every workspace.
96
+ The older `.vscode/mcp.json` takes the same entry under `servers`.
97
+
98
+ ### Windsurf (Devin Desktop)
99
+
100
+ With the Devin CLI or the Devin Local agent:
101
+
102
+ ```sh
103
+ devin mcp add -s user rhp -- npx -y @bezda/rhp-mcp
104
+ ```
105
+
106
+ For the Cascade agent, add the `mcpServers` entry shown for Claude Desktop to `~/.config/devin/mcp_config.json` (`%APPDATA%\devin\mcp_config.json` on Windows).
107
+
108
+ ### Copilot CLI
109
+
110
+ Type `/mcp add` in a session, or add the `mcpServers` entry shown for Claude Desktop to `~/.copilot/mcp-config.json`.
111
+
112
+ ### Zed
113
+
114
+ Add the server to Zed's settings file (the command **zed: open settings file** opens it):
115
+
116
+ ```json
117
+ {
118
+ "context_servers": {
119
+ "rhp": { "command": "npx", "args": ["-y", "@bezda/rhp-mcp"], "env": {} }
120
+ }
121
+ }
122
+ ```
123
+
124
+ ### Codex
125
+
126
+ ```sh
127
+ codex mcp add rhp -- npx -y @bezda/rhp-mcp
128
+ ```
129
+
130
+ It writes this to `~/.codex/config.toml`:
131
+
132
+ ```toml
133
+ [mcp_servers.rhp]
134
+ command = "npx"
135
+ args = ["-y", "@bezda/rhp-mcp"]
136
+ ```
137
+
138
+ ### Gemini CLI
139
+
140
+ ```sh
141
+ gemini mcp add --scope user rhp npx -- -y @bezda/rhp-mcp
142
+ ```
143
+
144
+ Without `--scope user` it goes to the project's `.gemini/settings.json`.
145
+
146
+ ### The tools
147
+
148
+ | Tool | What it returns |
149
+ |---|---|
150
+ | `rhp_guide` | The workflow from a request to a checked chart, the rules that prevent most bugs, and the names of the references and recipes. The agent calls it first. |
151
+ | `rhp_reference` | One reference by `name`: `api`, `design`, `environments`, `forms`, `interaction`, `looks` or `pitfalls`. A long one comes back as its list of sections, and `section` (a number or a title) returns one of them. |
152
+ | `rhp_recipe` | With no `type`, the list of recipes with what each is for; with a `type` such as `bar`, that recipe's whole HTML file, a tested chart page to start from. |
153
+ | `rhp_check` | Renders the chart at `file` (an absolute path) or the `code` given, and returns the report (errors and warnings, each with a fix, and the interactions it tried) and the screenshots as images. Options: `format`, `widths` (`[1280, 390]` by default, up to six), `dark`, `interact`, `settleTimeout`. |
154
+
155
+ `rhp_check` takes absolute paths only: some clients (Codex) start the server in its own folder, where a relative path would point at the wrong file.
156
+ The server also has one prompt, `chart`, which clients show as a slash command: it asks for a chart and tells the agent to follow `rhp_guide` and to check with `rhp_check` until the report is clean.
157
+
158
+ ## The browser
159
+
160
+ The checker renders charts in the first browser it finds:
161
+
162
+ 1. the executable in the `RHP_CHECK_BROWSER` environment variable;
163
+ 2. Playwright's Chromium (its headless shell first);
164
+ 3. Google Chrome;
165
+ 4. Microsoft Edge.
166
+
167
+ With none of them, the check still reports what it can find without a browser, and says to run:
168
+
169
+ ```sh
170
+ npx -y @bezda/rhp-mcp install-browser
171
+ ```
172
+
173
+ It downloads Chromium's headless shell into Playwright's usual folder and leaves the other browsers there alone.
174
+ Other options go to Playwright's installer: on Linux, `install-browser --with-deps` also installs the system libraries the browser needs.
175
+
176
+ ## Nothing leaves your machine
177
+
178
+ The checker renders your chart in a browser on your machine, and your chart's code and screenshots stay there.
179
+ It answers the page's requests for `@bezda/rhp` from the copy of rhp it ships with.
180
+ The only other requests are the ones your chart's page makes itself, such as its Google Fonts, and each gets 5 seconds before the check goes on without it.
181
+ There is no telemetry.
182
+
183
+ ## For maintainers
184
+
185
+ ```
186
+ bin/rhp-mcp.js the command: no arguments starts the server
187
+ src/server.js the MCP server: four tools, one prompt, one browser shared by every check
188
+ src/skill.js reads the skill: SKILL.md, the references (whole or by section) and the recipes
189
+ src/check/ the checker (its README lists every finding and how each is tested)
190
+ src/guard/ the wrapper around rhp that checks how a chart uses it, in the page
191
+ scripts/build.js copies ../skills/rhp into skill/ and rhp's LICENSE into this folder (npm pack runs it first)
192
+ test/mcp.js the build, the package, the Claude Code plugin's manifests, and the server through the SDK's client
193
+ test/run.js the checker
194
+ ```
195
+
196
+ **Tests.**
197
+ `npm test` runs `test/mcp.js`, then `test/run.js`.
198
+
199
+ **The skill.**
200
+ It lives in `skills/rhp/` at the repository's root.
201
+ Inside the repository the server reads it there, so it is never stale; the published package reads its copy in `skill/`.
202
+
203
+ **No `structuredContent`.**
204
+ Claude Code shows the model a tool's `structuredContent` in place of its text, and Codex in place of all of its content, images included.
205
+ The report or the screenshots would then never reach the agent, so `rhp_check` returns them as content only.
206
+
207
+ **Publishing.**
208
+ `@bezda/rhp` is `file:..` here, so that the tests check charts against this repository's build; an install from npm cannot resolve it.
209
+ Publish this package after every rhp release, with the range set to that release and a new version of its own.
210
+ The checker carries its own copy of rhp, and a page loads the latest rhp 2 from jsDelivr, so this keeps the two the same rhp; a new version also makes `npx` fetch the new pair:
211
+
212
+ ```sh
213
+ npm pkg set dependencies.@bezda/rhp=^2.0.1 # the rhp version just published
214
+ npm version patch --no-git-tag-version
215
+ npm publish
216
+ git checkout package.json
217
+ ```
218
+
219
+ `npm publish` runs the build first, and `publishConfig` makes the package public.
220
+
221
+ **The MCP SDK.**
222
+ The server uses `@modelcontextprotocol/sdk` 1.x (the v1 line), because clients speak v1 today; v1 gets fixes for at least six months after v2's release in July 2026.
223
+ Moving to v2 means importing `McpServer` from `@modelcontextprotocol/server`, giving each tool's `inputSchema` as `z.object({ ... })`, and starting the server with `serveStdio` from `@modelcontextprotocol/server/stdio`.
package/bin/rhp-mcp.js ADDED
@@ -0,0 +1,129 @@
1
+ #!/usr/bin/env node
2
+ // rhp-mcp: the MCP server (no arguments), or a command (rhp-mcp --help lists them).
3
+ import { fileURLToPath } from "url";
4
+ import path from "path";
5
+ import fs from "fs";
6
+
7
+ const here = path.dirname(fileURLToPath(import.meta.url));
8
+ const [command, ...args] = process.argv.slice(2);
9
+
10
+ const USAGE = `rhp-mcp: make charts with rhp from an AI agent.
11
+
12
+ rhp-mcp the MCP server, over stdio
13
+ rhp-mcp check <file> render a chart and report what is wrong with it (exit code 1 when it has errors)
14
+ --widths 1280,390 page widths to check (the interaction pass runs at the first)
15
+ --dark emulate a dark color scheme
16
+ --no-interact skip the interaction pass
17
+ --settle-timeout <ms> readiness wait budget, 100 to 30000 ms (default 10000)
18
+ --format <format> html, solid, react or module (found from the file when left out)
19
+ --json print the whole result as JSON
20
+ --out <dir> where the screenshots go (left out: a folder in the system's temp dir, so nothing is
21
+ written next to the chart; the report gives each screenshot's path)
22
+ rhp-mcp guide print the rhp skill's guide (SKILL.md), for an agent with no skill installed
23
+ rhp-mcp install-browser download Chromium's headless shell for checking (when no Chrome, Edge or Chromium is found)
24
+ rhp-mcp --version print this package's version
25
+ `;
26
+
27
+ const FLAGS = ["--dark", "--no-interact", "--json"];
28
+ const VALUES = ["--widths", "--format", "--out", "--settle-timeout"];
29
+ const FORMATS = ["html", "solid", "react", "module"];
30
+
31
+ function usageError(message) {
32
+
33
+ process.stderr.write(`rhp-mcp: ${message}\n\n${USAGE}`);
34
+
35
+ return 2;
36
+ }
37
+
38
+ async function runCheck(argv) {
39
+
40
+ if (argv.includes("--help") || argv.includes("-h")) {
41
+ process.stdout.write(USAGE);
42
+ return 0;
43
+ }
44
+
45
+ const files = [];
46
+ const value = {};
47
+
48
+ for (let i = 0; i < argv.length; i++) {
49
+ const arg = argv[i];
50
+ if (VALUES.includes(arg)) {
51
+ if (argv[i + 1] === undefined || argv[i + 1].startsWith("--")) return usageError(`${arg} needs a value`);
52
+ value[arg] = argv[++i];
53
+ } else if (arg.startsWith("-") && !FLAGS.includes(arg)) {
54
+ return usageError(`check has no option ${arg}`);
55
+ } else if (!arg.startsWith("-")) {
56
+ files.push(arg);
57
+ }
58
+ }
59
+
60
+ const widths = value["--widths"]?.split(",").map(Number);
61
+ const settleTimeout = value["--settle-timeout"] === undefined ? undefined : Number(value["--settle-timeout"]);
62
+ if (files.length !== 1) return usageError(files.length ? `check takes one file, not ${files.length}` : "check needs the chart's file");
63
+ if (widths && !widths.every((w) => Number.isInteger(w) && w >= 200 && w <= 2560)) return usageError("--widths takes page widths in px from 200 to 2560, for example 1280,390");
64
+ if (value["--format"] && !FORMATS.includes(value["--format"])) return usageError(`--format is one of ${FORMATS.join(", ")}`);
65
+ if (settleTimeout !== undefined && (!Number.isInteger(settleTimeout) || settleTimeout < 100 || settleTimeout > 30000)) return usageError("--settle-timeout takes milliseconds from 100 to 30000");
66
+
67
+ const { check } = await import("../src/check/index.js");
68
+ const result = await check({
69
+ file: files[0],
70
+ format: value["--format"],
71
+ widths,
72
+ dark: argv.includes("--dark"),
73
+ interact: !argv.includes("--no-interact"),
74
+ settleTimeout,
75
+ outDir: value["--out"],
76
+ });
77
+
78
+ process.stdout.write(argv.includes("--json") ? JSON.stringify(result, null, 2) + "\n" : result.text);
79
+
80
+ return result.ok ? 0 : 1;
81
+ }
82
+
83
+ // SKILL.md's body, after a line that says where the files it links are
84
+ async function printGuide() {
85
+
86
+ const { SKILL_DIR, skillBody } = await import("../src/skill.js");
87
+ process.stdout.write(`The references/ and recipes/ this guide links are in ${SKILL_DIR}\n\n${skillBody()}`);
88
+
89
+ return 0;
90
+ }
91
+
92
+ // Playwright's Chromium headless shell, for the version of playwright-core this package uses (other browsers are kept)
93
+ async function installBrowser(argv) {
94
+
95
+ const { spawnSync } = await import("child_process");
96
+ const { createRequire } = await import("module");
97
+ const cli = path.join(path.dirname(createRequire(import.meta.url).resolve("playwright-core/package.json")), "cli.js");
98
+ const r = spawnSync(process.execPath, [cli, "install", "--only-shell", "--no-remove", ...argv, "chromium"], { stdio: "inherit" });
99
+
100
+ return r.status ?? 1;
101
+ }
102
+
103
+ async function main() {
104
+
105
+ if (command === undefined) {
106
+ await import("../src/server.js");
107
+ return null;
108
+ }
109
+ if (command === "check") return runCheck(args);
110
+ if (command === "guide") return printGuide();
111
+ if (command === "install-browser") return installBrowser(args);
112
+ if (command === "--version" || command === "-v") {
113
+ process.stdout.write(JSON.parse(fs.readFileSync(path.join(here, "../package.json"), "utf8")).version + "\n");
114
+ return 0;
115
+ }
116
+ if (command === "--help" || command === "-h" || command === "help") {
117
+ process.stdout.write(USAGE);
118
+ return 0;
119
+ }
120
+
121
+ return usageError(`no command "${command}"`);
122
+ }
123
+
124
+ main().then((code) => {
125
+ if (code != null) process.exitCode = code;
126
+ }, (e) => {
127
+ process.stderr.write(`rhp-mcp: ${e.stack ?? e}\n`);
128
+ process.exitCode = 2;
129
+ });
package/package.json CHANGED
@@ -1,6 +1,64 @@
1
1
  {
2
2
  "name": "@bezda/rhp-mcp",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.1",
4
+ "description": "Make charts with rhp from any AI agent: an MCP server with rhp's guide, references and recipes, and a checker that renders a chart in a browser and reports what is wrong, with screenshots",
5
+ "keywords": [
6
+ "rhp",
7
+ "charts",
8
+ "data-visualization",
9
+ "mcp",
10
+ "mcp-server",
11
+ "model-context-protocol",
12
+ "ai",
13
+ "agent",
14
+ "solidjs",
15
+ "checker"
16
+ ],
17
+ "author": {
18
+ "name": "Bouzid Anas",
19
+ "email": "anas.bouzid@bezda.net"
20
+ },
21
+ "license": "MIT",
22
+ "homepage": "https://rhp.vercel.app/ai/",
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "git+https://github.com/bezda-team/rhp.git",
26
+ "directory": "mcp"
27
+ },
28
+ "type": "module",
29
+ "bin": {
30
+ "rhp-mcp": "bin/rhp-mcp.js"
31
+ },
32
+ "exports": {
33
+ ".": "./src/check/index.js"
34
+ },
35
+ "files": [
36
+ "bin",
37
+ "src",
38
+ "skill",
39
+ "README.md"
40
+ ],
41
+ "engines": {
42
+ "node": ">=20"
43
+ },
44
+ "publishConfig": {
45
+ "access": "public"
46
+ },
47
+ "scripts": {
48
+ "build": "node scripts/build.js",
49
+ "prepack": "npm run build",
50
+ "test": "node test/settle-regression.js && node test/mcp.js && node test/run.js"
51
+ },
52
+ "dependencies": {
53
+ "@babel/core": "^7.29.7",
54
+ "@bezda/rhp": "^2.0.3",
55
+ "@modelcontextprotocol/sdk": "^1.32.0",
56
+ "babel-preset-solid": "^1.9.15",
57
+ "esbuild": "^0.28.2",
58
+ "playwright-core": "^1.63.0",
59
+ "react": "^19.3.0",
60
+ "react-dom": "^19.3.0",
61
+ "solid-js": "^1.9.15",
62
+ "zod": "^4.6.5"
63
+ }
64
+ }