cdp-mcp 0.1.2 → 0.2.0

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 (53) hide show
  1. package/README.md +100 -37
  2. package/dist/contract.d.ts +11 -0
  3. package/dist/contract.js +11 -0
  4. package/dist/contract.js.map +1 -0
  5. package/dist/index.d.ts +18 -0
  6. package/dist/locator.d.ts +108 -0
  7. package/dist/locator.js +176 -0
  8. package/dist/locator.js.map +1 -0
  9. package/dist/server.d.ts +2 -0
  10. package/dist/server.js +4 -0
  11. package/dist/server.js.map +1 -1
  12. package/dist/session/browser.d.ts +29 -0
  13. package/dist/session/browser.js +17 -2
  14. package/dist/session/browser.js.map +1 -1
  15. package/dist/session/buffers.d.ts +48 -0
  16. package/dist/session/pause.d.ts +21 -0
  17. package/dist/session/state.d.ts +53 -0
  18. package/dist/sourcemap/loader.d.ts +4 -0
  19. package/dist/sourcemap/normalize.d.ts +2 -0
  20. package/dist/sourcemap/store.d.ts +57 -0
  21. package/dist/tools/_locator_runtime.d.ts +31 -0
  22. package/dist/tools/_locator_runtime.js +243 -0
  23. package/dist/tools/_locator_runtime.js.map +1 -0
  24. package/dist/tools/_register.d.ts +2 -0
  25. package/dist/tools/breakpoints.d.ts +4 -0
  26. package/dist/tools/console.d.ts +2 -0
  27. package/dist/tools/dom.d.ts +2 -0
  28. package/dist/tools/dom.js +3 -221
  29. package/dist/tools/dom.js.map +1 -1
  30. package/dist/tools/execution.d.ts +29 -0
  31. package/dist/tools/forms.d.ts +8 -0
  32. package/dist/tools/forms.js +256 -0
  33. package/dist/tools/forms.js.map +1 -0
  34. package/dist/tools/inspect.d.ts +2 -0
  35. package/dist/tools/nav.d.ts +2 -0
  36. package/dist/tools/network.d.ts +2 -0
  37. package/dist/tools/session.d.ts +2 -0
  38. package/dist/tools/session.js +1 -1
  39. package/dist/tools/session.js.map +1 -1
  40. package/dist/tools/source.d.ts +2 -0
  41. package/dist/tools/storage.d.ts +2 -0
  42. package/dist/tools/storage.js +296 -0
  43. package/dist/tools/storage.js.map +1 -0
  44. package/dist/util/browser-resolve.d.ts +19 -0
  45. package/dist/util/errors.d.ts +7 -0
  46. package/dist/util/format.d.ts +20 -0
  47. package/dist/util/log.d.ts +6 -0
  48. package/docs/chromium-sandboxing.md +197 -0
  49. package/docs/known-chromium-gaps.md +138 -0
  50. package/docs/launchd-service.md +217 -0
  51. package/docs/local-l3-e2e-setup.md +199 -0
  52. package/docs/systemd-service.md +233 -0
  53. package/package.json +18 -2
package/README.md CHANGED
@@ -4,11 +4,13 @@ A Model Context Protocol (MCP) server that exposes the Chrome DevTools Protocol
4
4
 
5
5
  Designed for agents running in CLIs (Claude Code, GitHub Copilot CLI) that have local source + source-map access. Coordinates flow in TS terms; the server translates to JS for CDP under the hood.
6
6
 
7
- **Status:** alpha (v0.1.0). **License:** [MIT](./LICENSE).
7
+ **Status:** alpha. **License:** [MIT](./LICENSE).
8
+
9
+ **Last updated: 2026-06-09**
8
10
 
9
11
  ## What it gives an agent
10
12
 
11
- Across 39 tools:
13
+ Across 48 tools:
12
14
 
13
15
  - **Breakpoints in TS source** — `set_breakpoint(file="src/foo.ts", line=42, condition?, log_message?)`. The server matches source maps and binds in every script that maps back to that file.
14
16
  - **Stepping** — `step_over`, `step_into`, `step_out`, `resume`, `pause`, plus the authoritative sync point `wait_for_pause`.
@@ -16,12 +18,42 @@ Across 39 tools:
16
18
  - **Buffered console + network** — pull-based, paginated by monotonic `seq`. Bodies are lazy-loaded via `get_request_body` / `get_response_body`.
17
19
  - **Light DOM interaction** — `query_selector`, `click`, `type_text`, `press_key`, `screenshot` so the agent can drive a flow to a breakpoint.
18
20
  - **Structured DOM querying** — Playwright-inspired `locate` (LocatorSpec: CSS, text, role, test-id, label, placeholder, name), `wait_for` (poll until DOM state), `get_form_state` (read named form fields).
21
+ - **Form driving** — `fill`, `check` / `uncheck`, `select_option`, plus `suggest_locator` to get a robust semantic locator for an element.
22
+ - **Session portability** — `export_storage_state` / `load_storage_state` carry a logged-in session (cookies + localStorage) across runs; `get_cookies` / `set_cookies` read and set cookies directly (`get_cookies` redacts likely-auth / HttpOnly values for safe logging).
19
23
  - **Source-map diagnostics** — `list_scripts`, `resolve_source_position`, `get_script_source`.
20
24
 
21
25
  Auto-attaches to iframes and workers via `Target.setAutoAttach({ flatten: true })`.
22
26
 
23
27
  ## Install / build
24
28
 
29
+ ### Runtime install from npm
30
+
31
+ Requires Node.js 20+ and a local Chrome/Chromium browser.
32
+
33
+ ```sh
34
+ npm install -g cdp-mcp
35
+ cdp-mcp # stdio MCP transport
36
+ cdp-mcp --port 9719 # SSE MCP transport on 127.0.0.1:9719
37
+ cdp-mcp --host 0.0.0.0 --port 9719 --allow-remote
38
+ ```
39
+
40
+ The npm package ships prebuilt `dist/`, so there is no build step for runtime
41
+ use. If `launch_chrome` cannot find Chrome/Chromium automatically, set
42
+ `CHROME_PATH` to the browser binary.
43
+
44
+ For MCP clients that support SSE, you can run `cdp-mcp` as a persistent local
45
+ service:
46
+
47
+ - [macOS launchd user service](docs/launchd-service.md)
48
+ - [Linux systemd user service](docs/systemd-service.md)
49
+
50
+ Persistent service mode keeps the `cdp-mcp` process and current browser/CDP
51
+ session alive across MCP client restarts or reconnects. It does **not** persist
52
+ state across service-process restarts. SSE mode is single-client today; if a
53
+ new client should start fresh, call `close_session` first.
54
+
55
+ ### Build from source
56
+
25
57
  ```sh
26
58
  npm install
27
59
  npm run build
@@ -39,9 +71,11 @@ SSE mode caveats:
39
71
  tears down client A's session).
40
72
  - **Non-loopback bind requires opt-in.** `--allow-remote` (or
41
73
  `CDP_MCP_ALLOW_REMOTE=1`) is required to bind to anything other than
42
- loopback. MCP tools include `evaluate` (in-page code exec) and a
43
- `screenshot path=` filesystem write; the gate makes remote exposure
44
- a deliberate operator decision rather than a default.
74
+ loopback. MCP tools include `evaluate` (in-page code exec), a
75
+ `screenshot path=` filesystem write, `export_storage_state` (writes full
76
+ cookie values including HttpOnly auth secrets — to a server-side file) and
77
+ `load_storage_state` (reads an arbitrary server-side file); the gate makes
78
+ remote exposure a deliberate operator decision rather than a default.
45
79
  - **Host / Origin headers are validated on loopback binds** to block
46
80
  DNS-rebinding against `127.0.0.1` / `localhost` / `[::1]`. On
47
81
  non-loopback binds the operator has already accepted exposure via
@@ -62,11 +96,10 @@ Unit + L2 contract tests (~640ms, no browser, no LLM):
62
96
  npm test
63
97
  ```
64
98
 
65
- Currently 299 tests across 22 files. The `test/` tree is the L2 contract
66
- layer (every tool exercised against a fake CDP — see `test/fake-cdp.ts`);
67
- the inline `src/**/*.test.ts` files are L1 pure-data tests; `evals/**/
68
- *.test.ts` cover the L4 harness's grader/trace/oracle units (21 tests).
69
- See `docs/test-eval-plan.md` for the full pyramid.
99
+ The `test/` tree is the L2 contract layer (every tool exercised against a fake
100
+ CDP — see `test/fake-cdp.ts`); the inline `src/**/*.test.ts` files are L1
101
+ pure-data tests; `evals/**/*.test.ts` cover the L4 harness's
102
+ grader/trace/oracle units. See `docs/test-eval-plan.md` for the full pyramid.
70
103
 
71
104
  ### L3 — real-browser end-to-end
72
105
 
@@ -74,10 +107,10 @@ See `docs/test-eval-plan.md` for the full pyramid.
74
107
  npm run test:e2e
75
108
  ```
76
109
 
77
- Drives the 39 MCP tools against a real headless Chromium attached to a
78
- built copy of `examples/sample-app/`. Nine specs cover lifecycle, breakpoints,
79
- stepping, exceptions, console, network, workers, screenshot, and DOM
80
- interaction. Sequential (one Chrome shared across specs, isolated by a
110
+ Drives the 48 MCP tools against a real headless Chromium attached to a
111
+ built copy of `examples/sample-app/`. Eleven specs cover lifecycle, breakpoints,
112
+ stepping, exceptions, console, network, workers, screenshot, DOM
113
+ interaction, form driving, and storage portability. Sequential (one Chrome shared across specs, isolated by a
81
114
  shared `afterEach(close_session)`). Run time is a few seconds on a warm
82
115
  machine.
83
116
 
@@ -113,14 +146,17 @@ pretest hook) enforces this.
113
146
  `launch_chrome` defaults to `--no-sandbox` for Ubuntu/Playwright-Chromium
114
147
  compatibility. See [`docs/chromium-sandboxing.md`](docs/chromium-sandboxing.md)
115
148
  before changing that default or relying on `sandbox: true`, AppArmor, snap
116
- confinement, or Bubblewrap.
149
+ confinement, or Bubblewrap. For the step-by-step setup that gets local
150
+ `npm run test:e2e` passing with the sandbox **on** (install Playwright Chromium
151
+ + attach the AppArmor profile), see
152
+ [`docs/local-l3-e2e-setup.md`](docs/local-l3-e2e-setup.md).
117
153
 
118
154
  ### L4 — LLM agent evals
119
155
 
120
156
  ```sh
121
157
  export ANTHROPIC_API_KEY=...
122
- npm run eval:quick # 1 scenario × 1 trial (~$0.50–2 at default Opus-4.7-medium; ~$0.05 with EVAL_MODEL_OVERRIDE=claude-sonnet-4-6)
123
- npm run eval # all scenarios × 3 trials (first observed ~$4 at default Opus-4.7-medium on a reference host one data point, not the steady-state band)
158
+ npm run eval:quick # 1 scenario × 1 trial (~$0.50–2 at default Opus-4.8-medium; ~$0.05 with EVAL_MODEL_OVERRIDE=claude-sonnet-4-6)
159
+ npm run eval # all scenarios × 3 trials (~$4 full pass — first observed on Opus-4.7-medium, the prior default; 4.8 shares its rate card)
124
160
  npm run eval -- --scenarios=compute-step --trials=1
125
161
  ```
126
162
 
@@ -128,8 +164,10 @@ Use `npm run eval` (or `npm run eval:quick`) — NOT `npx tsx evals/cli.ts` dire
128
164
 
129
165
  Drives the cdp-mcp tool surface through an LLM agent via the
130
166
  `VendorAdapter` seam (`evals/harness/vendor.ts`); the Anthropic adapter
131
- backed by `@anthropic-ai/sdk` is the default and only production path
132
- today. Each trial spawns a fresh `dist/index.js` MCP subprocess + a
167
+ backed by `@anthropic-ai/sdk` is the default; OpenAI, Vertex, DeepSeek,
168
+ and Moonshot/Kimi are also shipped production adapters (plus an LM Studio
169
+ reference adapter for local models), each selected via `EVAL_PROVIDER`.
170
+ Each trial spawns a fresh `dist/index.js` MCP subprocess + a
133
171
  static server for the scenario's sample-app variant; the tool-use loop
134
172
  drives the page, sets source-level breakpoints, inspects pauses, and
135
173
  produces a natural-language final answer. NDJSON traces land under
@@ -138,7 +176,7 @@ produces a natural-language final answer. NDJSON traces land under
138
176
  exercise the debugger workflow under test) + **correctness** (did the
139
177
  final answer name the bug) — plus efficiency ratio and recovery count.
140
178
 
141
- **Default model**: `claude-opus-4-7` with adaptive thinking at
179
+ **Default model**: `claude-opus-4-8` with adaptive thinking at
142
180
  `effort=medium` (set in `evals/harness/model.ts`). Adaptive-style models
143
181
  (Opus 4.7+) default to medium-effort thinking when no env override is
144
182
  set; budget-style models (Sonnet 4.6, selectable via
@@ -172,23 +210,27 @@ each `t:"usage"` trace entry (the Anthropic adapter populates
172
210
  `cacheTokens.cacheReadInputTokens` and `cacheTokens.cacheCreationInputTokens`
173
211
  verbatim from the SDK's `cache_read_input_tokens` / `cache_creation_input_tokens`).
174
212
 
175
- Non-Anthropic backends: the OpenAI vendor adapter ships with #50/#58
176
- (target: GPT-5.5) — `EVAL_PROVIDER=openai` plus `OPENAI_API_KEY`
177
- + `EVAL_OPENAI_MODEL` activates it. Reasoning-off trials route to
178
- `/v1/chat/completions` (#50); reasoning-on trials route to
179
- `/v1/responses` (#58), the only OpenAI surface that supports tools
180
- × reasoning_effort on GPT-5.5. An LM Studio investigation artifact
181
- is wired behind the same seam for issue #45. See
182
- [evals/README.md](evals/README.md) for full `EVAL_PROVIDER` /
183
- `EVAL_OPENAI_*` / `EVAL_LM_STUDIO_*` details. Vertex (#51) is the last
184
- backend adapter still pending.
185
-
186
- Currently registered scenarios (8): `compute-step` and
187
- `adversarial-out-of-order` ship against the canonical `examples/sample-app/`;
188
- `network-bug`, `console-error`, `event-binding`, `deep-source-map`,
189
- `worker-bug`, and `conditional-bp` have committed per-scenario forks
190
- under `evals/sample-app-variants/<name>/` and build via
191
- `npm run sample:build` (`scripts/build-variants.mjs`).
213
+ Non-Anthropic backends ship behind the same seam, each selected via
214
+ `EVAL_PROVIDER`: OpenAI / GPT-5.5 (#50/#58) — reasoning-off trials route to
215
+ `/v1/chat/completions` (#50), reasoning-on trials to `/v1/responses` (#58),
216
+ the only OpenAI surface that supports tools × reasoning_effort on GPT-5.5;
217
+ Vertex / Gemini (#51); and DeepSeek + Moonshot/Kimi (GH #8), remote
218
+ OpenAI-compatible `/v1` vendors. An LM Studio investigation artifact is
219
+ wired behind the seam for local models (issue #45). See
220
+ [evals/README.md](evals/README.md) for full `EVAL_PROVIDER` / `EVAL_OPENAI_*`
221
+ / `EVAL_VERTEX_*` / `EVAL_DEEPSEEK_*` / `EVAL_MOONSHOT_*` / `EVAL_LM_STUDIO_*`
222
+ details.
223
+
224
+ Currently registered scenarios (14) 8 **debugger** scenarios
225
+ (`compute-step`, `adversarial-out-of-order`, `network-bug`, `console-error`,
226
+ `event-binding`, `deep-source-map`, `worker-bug`, `conditional-bp`) plus 6
227
+ **driving + session-portability** scenarios from issue #12 (`form-drive`,
228
+ `clearing-fill`, `idempotent-toggle`, `robust-locator`, `session-resume`,
229
+ `cookie-redaction`). `compute-step` is the canonical `npm run eval:quick`
230
+ target; some scenarios run against the stock `examples/sample-app/`, others
231
+ against per-scenario forks under `evals/sample-app-variants/<name>/` built via
232
+ `npm run sample:build` (`scripts/build-variants.mjs`). See
233
+ [evals/README.md](evals/README.md) for the full scenario table.
192
234
 
193
235
  ## Wire into Claude Code
194
236
 
@@ -226,6 +268,27 @@ Or via `~/.claude.json`:
226
268
  - **Errors** come back as `isError: true` with a structured `{ error, message }` JSON payload.
227
269
  - **Compact returns**: previews trimmed to ~200 chars, lists capped at sensible defaults — bodies lazy-loaded via dedicated tools.
228
270
 
271
+ ## Programmatic contract (`cdp-mcp/contract`)
272
+
273
+ The structured `LocatorSpec` that `locate`, `wait_for`, and the form-driving tools
274
+ accept is published as a side-effect-free subpath export, so external tooling can
275
+ *produce and validate* specs without duplicating the shape or pulling in the CLI:
276
+
277
+ ```ts
278
+ import { locatorSchema, parseLocator, serializeLocator } from "cdp-mcp/contract";
279
+ import type { LocatorSpec } from "cdp-mcp/contract";
280
+
281
+ const spec = parseLocator({ by: "role", role: "button", name: "Submit" });
282
+ locatorSchema.parse(spec); // throws on an invalid shape
283
+ serializeLocator(spec); // stable, normalized JSON
284
+ ```
285
+
286
+ Exports: `LocatorSpec` (type), `LocatorBy`, `locatorSchema` / `locatorShape` /
287
+ `locatorBySchema` (Zod), and `normalizeLocator` / `parseLocator` / `serializeLocator`
288
+ / `LocatorError`. This module imports only `zod`. The subpath is **ESM-only** (the
289
+ `exports` map defines `import`, not `require`) — consume it from an ESM module or a
290
+ bundler.
291
+
229
292
  ## Prior art
230
293
 
231
294
  If `cdp-mcp` doesn't fit your workflow, look at:
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Public package contract, published under the `cdp-mcp/contract` subpath export.
3
+ *
4
+ * Keep this a thin, side-effect-free barrel: it must only re-export from modules
5
+ * (like `./locator.js`) whose import graph never reaches the CLI/server entry
6
+ * (`./index.js`, `./server.js`, `./session/*`). That guarantee is what lets a
7
+ * downstream consumer `import { locatorSchema } from "cdp-mcp/contract"` without
8
+ * dragging in the executable's transport/shebang side effects.
9
+ */
10
+ export { LocatorError, locatorBySchema, locatorShape, locatorSchema, normalizeLocator, parseLocator, serializeLocator, } from "./locator.js";
11
+ export type { LocatorBy, LocatorSpec } from "./locator.js";
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Public package contract, published under the `cdp-mcp/contract` subpath export.
3
+ *
4
+ * Keep this a thin, side-effect-free barrel: it must only re-export from modules
5
+ * (like `./locator.js`) whose import graph never reaches the CLI/server entry
6
+ * (`./index.js`, `./server.js`, `./session/*`). That guarantee is what lets a
7
+ * downstream consumer `import { locatorSchema } from "cdp-mcp/contract"` without
8
+ * dragging in the executable's transport/shebang side effects.
9
+ */
10
+ export { LocatorError, locatorBySchema, locatorShape, locatorSchema, normalizeLocator, parseLocator, serializeLocator, } from "./locator.js";
11
+ //# sourceMappingURL=contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.js","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EACL,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,GACjB,MAAM,cAAc,CAAC"}
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ import { type IncomingMessage, type ServerResponse } from "node:http";
3
+ import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
4
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5
+ export interface SseClient {
6
+ server: McpServer;
7
+ transport: SSEServerTransport;
8
+ }
9
+ export declare function handleSseRequest({ req, res, clients, host, port, validateHostOrigin, allowedHosts, allowedOrigins, }: {
10
+ req: IncomingMessage;
11
+ res: ServerResponse;
12
+ clients: Map<string, SseClient>;
13
+ host: string;
14
+ port: number;
15
+ validateHostOrigin: boolean;
16
+ allowedHosts: Set<string>;
17
+ allowedOrigins: Set<string>;
18
+ }): Promise<void>;
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Canonical `LocatorSpec` contract for cdp-mcp.
3
+ *
4
+ * This module is the single source of truth for the structured element-locator
5
+ * shape that `locate`, `wait_for`, and the form-driving tools accept. It is
6
+ * deliberately **side-effect free** and depends only on `zod`, so external
7
+ * consumers can import it (via `cdp-mcp/contract`) to produce and validate specs
8
+ * without pulling in the CLI/server. Tool code re-imports these symbols rather
9
+ * than redefining them, so the published contract can never silently drift from
10
+ * what the tools actually accept.
11
+ */
12
+ import { z } from "zod";
13
+ /**
14
+ * Error thrown by {@link normalizeLocator} / {@link parseLocator} for an invalid
15
+ * spec. `code` mirrors the cdp-mcp tool error codes so tool handlers can re-wrap it
16
+ * structurally: `"missing_arg"` when a spec is under-specified for its strategy,
17
+ * `"invalid_locator"` for an unsupported strategy.
18
+ */
19
+ export declare class LocatorError extends Error {
20
+ readonly code: string;
21
+ constructor(message: string, code?: string);
22
+ }
23
+ /** The locator strategies cdp-mcp understands. `css` is the default when a selector is given. */
24
+ export declare const locatorBySchema: z.ZodEnum<["css", "text", "role", "test_id", "testId", "label", "placeholder", "name"]>;
25
+ /**
26
+ * The raw Zod shape for a LocatorSpec. Spread into tool input schemas
27
+ * (`{ ...locatorShape, ... }`) so the field docs stay identical everywhere.
28
+ */
29
+ export declare const locatorShape: {
30
+ by: z.ZodOptional<z.ZodEnum<["css", "text", "role", "test_id", "testId", "label", "placeholder", "name"]>>;
31
+ selector: z.ZodOptional<z.ZodString>;
32
+ css: z.ZodOptional<z.ZodString>;
33
+ text: z.ZodOptional<z.ZodString>;
34
+ role: z.ZodOptional<z.ZodString>;
35
+ name: z.ZodOptional<z.ZodString>;
36
+ test_id: z.ZodOptional<z.ZodString>;
37
+ testId: z.ZodOptional<z.ZodString>;
38
+ label: z.ZodOptional<z.ZodString>;
39
+ placeholder: z.ZodOptional<z.ZodString>;
40
+ exact: z.ZodOptional<z.ZodBoolean>;
41
+ };
42
+ /** A standalone `ZodObject` for a LocatorSpec — external consumers can `.parse()`/`.safeParse()`. */
43
+ export declare const locatorSchema: z.ZodObject<{
44
+ by: z.ZodOptional<z.ZodEnum<["css", "text", "role", "test_id", "testId", "label", "placeholder", "name"]>>;
45
+ selector: z.ZodOptional<z.ZodString>;
46
+ css: z.ZodOptional<z.ZodString>;
47
+ text: z.ZodOptional<z.ZodString>;
48
+ role: z.ZodOptional<z.ZodString>;
49
+ name: z.ZodOptional<z.ZodString>;
50
+ test_id: z.ZodOptional<z.ZodString>;
51
+ testId: z.ZodOptional<z.ZodString>;
52
+ label: z.ZodOptional<z.ZodString>;
53
+ placeholder: z.ZodOptional<z.ZodString>;
54
+ exact: z.ZodOptional<z.ZodBoolean>;
55
+ }, "strip", z.ZodTypeAny, {
56
+ css?: string | undefined;
57
+ text?: string | undefined;
58
+ role?: string | undefined;
59
+ test_id?: string | undefined;
60
+ testId?: string | undefined;
61
+ label?: string | undefined;
62
+ placeholder?: string | undefined;
63
+ name?: string | undefined;
64
+ exact?: boolean | undefined;
65
+ by?: "css" | "text" | "role" | "test_id" | "testId" | "label" | "placeholder" | "name" | undefined;
66
+ selector?: string | undefined;
67
+ }, {
68
+ css?: string | undefined;
69
+ text?: string | undefined;
70
+ role?: string | undefined;
71
+ test_id?: string | undefined;
72
+ testId?: string | undefined;
73
+ label?: string | undefined;
74
+ placeholder?: string | undefined;
75
+ name?: string | undefined;
76
+ exact?: boolean | undefined;
77
+ by?: "css" | "text" | "role" | "test_id" | "testId" | "label" | "placeholder" | "name" | undefined;
78
+ selector?: string | undefined;
79
+ }>;
80
+ export type LocatorBy = z.infer<typeof locatorBySchema>;
81
+ export interface LocatorSpec {
82
+ by?: LocatorBy;
83
+ selector?: string;
84
+ css?: string;
85
+ text?: string;
86
+ role?: string;
87
+ name?: string;
88
+ test_id?: string;
89
+ testId?: string;
90
+ label?: string;
91
+ placeholder?: string;
92
+ exact?: boolean;
93
+ }
94
+ /**
95
+ * Validate and canonicalize a spec: infer `by` from selector/css, enforce the
96
+ * required field for the chosen strategy, and fold the `name` fallback into the
97
+ * strategy-specific field. Throws {@link LocatorError} on an under-specified spec.
98
+ */
99
+ export declare function normalizeLocator(input: LocatorSpec): LocatorSpec;
100
+ /** Validate an unknown value as a LocatorSpec (shape + strategy requirements). */
101
+ export declare function parseLocator(input: unknown): LocatorSpec;
102
+ /**
103
+ * Serialize a LocatorSpec to a stable, normalized JSON string. Equivalent specs
104
+ * serialize identically regardless of which alias the caller used — e.g.
105
+ * `{ css: ".x" }` and `{ selector: ".x" }` both yield `{"by":"css","selector":".x"}`
106
+ * — so the output is safe to use as a cache key or for equality checks.
107
+ */
108
+ export declare function serializeLocator(spec: LocatorSpec): string;
@@ -0,0 +1,176 @@
1
+ /**
2
+ * Canonical `LocatorSpec` contract for cdp-mcp.
3
+ *
4
+ * This module is the single source of truth for the structured element-locator
5
+ * shape that `locate`, `wait_for`, and the form-driving tools accept. It is
6
+ * deliberately **side-effect free** and depends only on `zod`, so external
7
+ * consumers can import it (via `cdp-mcp/contract`) to produce and validate specs
8
+ * without pulling in the CLI/server. Tool code re-imports these symbols rather
9
+ * than redefining them, so the published contract can never silently drift from
10
+ * what the tools actually accept.
11
+ */
12
+ import { z } from "zod";
13
+ /**
14
+ * Error thrown by {@link normalizeLocator} / {@link parseLocator} for an invalid
15
+ * spec. `code` mirrors the cdp-mcp tool error codes so tool handlers can re-wrap it
16
+ * structurally: `"missing_arg"` when a spec is under-specified for its strategy,
17
+ * `"invalid_locator"` for an unsupported strategy.
18
+ */
19
+ export class LocatorError extends Error {
20
+ code;
21
+ constructor(message, code = "missing_arg") {
22
+ super(message);
23
+ this.name = "LocatorError";
24
+ this.code = code;
25
+ }
26
+ }
27
+ /** The locator strategies cdp-mcp understands. `css` is the default when a selector is given. */
28
+ export const locatorBySchema = z.enum([
29
+ "css",
30
+ "text",
31
+ "role",
32
+ "test_id",
33
+ "testId",
34
+ "label",
35
+ "placeholder",
36
+ "name",
37
+ ]);
38
+ /**
39
+ * The raw Zod shape for a LocatorSpec. Spread into tool input schemas
40
+ * (`{ ...locatorShape, ... }`) so the field docs stay identical everywhere.
41
+ */
42
+ export const locatorShape = {
43
+ by: locatorBySchema.optional().describe("Locator strategy. Omit when passing selector/css for a CSS lookup."),
44
+ selector: z.string().optional().describe("CSS selector. Equivalent to by=css."),
45
+ css: z.string().optional().describe("CSS selector. Equivalent to selector."),
46
+ text: z.string().optional().describe("Text to match for by=text."),
47
+ role: z.string().optional().describe("ARIA/implicit role for by=role, e.g. button, link, textbox."),
48
+ name: z.string().optional().describe("Accessible name, field name, or fallback value depending on the locator strategy."),
49
+ test_id: z.string().optional().describe("Value for data-testid, data-test-id, or data-test."),
50
+ // Both snake_case (`test_id`) and camelCase (`testId`) are accepted so callers
51
+ // can use whichever matches their convention; `normalizeLocator` /
52
+ // `serializeLocator` fold them to the canonical `test_id`. Likewise `name` is a
53
+ // cross-strategy fallback that gets folded into the strategy-specific field.
54
+ testId: z.string().optional().describe("CamelCase alias for test_id."),
55
+ label: z.string().optional().describe("Label text for by=label."),
56
+ placeholder: z.string().optional().describe("Placeholder text for by=placeholder."),
57
+ exact: z.boolean().optional().describe("Default false: substring match for text/name-like fields."),
58
+ };
59
+ /** A standalone `ZodObject` for a LocatorSpec — external consumers can `.parse()`/`.safeParse()`. */
60
+ export const locatorSchema = z.object(locatorShape);
61
+ /**
62
+ * Validate and canonicalize a spec: infer `by` from selector/css, enforce the
63
+ * required field for the chosen strategy, and fold the `name` fallback into the
64
+ * strategy-specific field. Throws {@link LocatorError} on an under-specified spec.
65
+ */
66
+ export function normalizeLocator(input) {
67
+ const by = input.by ?? (input.selector || input.css ? "css" : undefined);
68
+ if (!by)
69
+ throw new LocatorError("by is required unless selector/css is supplied");
70
+ switch (by) {
71
+ case "css": {
72
+ const selector = input.selector ?? input.css;
73
+ if (!selector)
74
+ throw new LocatorError("selector or css is required for by=css");
75
+ return { ...input, by, selector };
76
+ }
77
+ case "role":
78
+ if (!input.role)
79
+ throw new LocatorError("role is required for by=role");
80
+ return { ...input, by };
81
+ case "text":
82
+ if (!input.text && !input.name)
83
+ throw new LocatorError("text or name is required for by=text");
84
+ return { ...input, by, text: input.text ?? input.name };
85
+ case "test_id":
86
+ case "testId": {
87
+ const testId = input.test_id ?? input.testId ?? input.name;
88
+ if (!testId)
89
+ throw new LocatorError(`test_id, testId, or name is required for by=${by}`);
90
+ return { ...input, by, test_id: testId };
91
+ }
92
+ case "label": {
93
+ const label = input.label ?? input.name;
94
+ if (!label)
95
+ throw new LocatorError("label or name is required for by=label");
96
+ return { ...input, by, label };
97
+ }
98
+ case "placeholder": {
99
+ const placeholder = input.placeholder ?? input.name;
100
+ if (!placeholder)
101
+ throw new LocatorError("placeholder or name is required for by=placeholder");
102
+ return { ...input, by, placeholder };
103
+ }
104
+ case "name":
105
+ if (!input.name)
106
+ throw new LocatorError("name is required for by=name");
107
+ return { ...input, by };
108
+ default: {
109
+ // Compile-time exhaustiveness: if `locatorBySchema` gains a strategy and a
110
+ // case here is missed, `by` is no longer `never` and this fails to build
111
+ // (pairs with `noFallthroughCasesInSwitch`).
112
+ const _exhaustive = by;
113
+ throw new LocatorError(`unsupported locator strategy: ${String(_exhaustive)}`, "invalid_locator");
114
+ }
115
+ }
116
+ }
117
+ /** Validate an unknown value as a LocatorSpec (shape + strategy requirements). */
118
+ export function parseLocator(input) {
119
+ return normalizeLocator(locatorSchema.parse(input));
120
+ }
121
+ /**
122
+ * Serialize a LocatorSpec to a stable, normalized JSON string. Equivalent specs
123
+ * serialize identically regardless of which alias the caller used — e.g.
124
+ * `{ css: ".x" }` and `{ selector: ".x" }` both yield `{"by":"css","selector":".x"}`
125
+ * — so the output is safe to use as a cache key or for equality checks.
126
+ */
127
+ export function serializeLocator(spec) {
128
+ return JSON.stringify(canonicalLocator(spec));
129
+ }
130
+ /**
131
+ * Reduce a spec to only its canonical fields, in a fixed key order, dropping
132
+ * alias inputs (`css`, `testId`, and the cross-strategy `name` fallback). This is
133
+ * what makes {@link serializeLocator} stable across equivalent inputs — the raw
134
+ * `normalizeLocator` result still carries whichever aliases the caller passed.
135
+ */
136
+ function canonicalLocator(spec) {
137
+ const n = normalizeLocator(spec);
138
+ const out = {};
139
+ switch (n.by) {
140
+ case "css":
141
+ out.by = "css";
142
+ out.selector = n.selector;
143
+ break;
144
+ case "role":
145
+ out.by = "role";
146
+ out.role = n.role;
147
+ if (n.name !== undefined)
148
+ out.name = n.name;
149
+ break;
150
+ case "text":
151
+ out.by = "text";
152
+ out.text = n.text;
153
+ break;
154
+ case "test_id":
155
+ case "testId":
156
+ out.by = "test_id";
157
+ out.test_id = n.test_id;
158
+ break;
159
+ case "label":
160
+ out.by = "label";
161
+ out.label = n.label;
162
+ break;
163
+ case "placeholder":
164
+ out.by = "placeholder";
165
+ out.placeholder = n.placeholder;
166
+ break;
167
+ case "name":
168
+ out.by = "name";
169
+ out.name = n.name;
170
+ break;
171
+ }
172
+ if (n.exact !== undefined)
173
+ out.exact = n.exact;
174
+ return out;
175
+ }
176
+ //# sourceMappingURL=locator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locator.js","sourceRoot":"","sources":["../src/locator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function buildServer(): McpServer;
package/dist/server.js CHANGED
@@ -8,6 +8,8 @@ import { registerInspectTools } from "./tools/inspect.js";
8
8
  import { registerConsoleTools } from "./tools/console.js";
9
9
  import { registerNetworkTools } from "./tools/network.js";
10
10
  import { registerDomTools } from "./tools/dom.js";
11
+ import { registerFormTools } from "./tools/forms.js";
12
+ import { registerStorageTools } from "./tools/storage.js";
11
13
  export function buildServer() {
12
14
  const server = new McpServer({
13
15
  name: "cdp-mcp",
@@ -22,6 +24,8 @@ export function buildServer() {
22
24
  registerConsoleTools(server);
23
25
  registerNetworkTools(server);
24
26
  registerDomTools(server);
27
+ registerFormTools(server);
28
+ registerStorageTools(server);
25
29
  // The SDK advertises `tools: { listChanged: true }` as soon as any tool is
26
30
  // registered, but never emits the matching notification on its own. Some
27
31
  // clients (e.g. GitHub Copilot CLI over SSE) gate their first `tools/list`
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,MAAM,UAAU,WAAW;IACzB,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IAEH,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC7B,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACzB,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC5B,uBAAuB,CAAC,MAAM,CAAC,CAAC;IAChC,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAC/B,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC7B,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC7B,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC7B,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAEzB,2EAA2E;IAC3E,yEAAyE;IACzE,2EAA2E;IAC3E,4EAA4E;IAC5E,2EAA2E;IAC3E,yEAAyE;IACzE,iEAAiE;IACjE,MAAM,CAAC,MAAM,CAAC,aAAa,GAAG,GAAG,EAAE;QACjC,MAAM,CAAC,mBAAmB,EAAE,CAAC;IAC/B,CAAC,CAAC;IAEF,OAAO,MAAM,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE1D,MAAM,UAAU,WAAW;IACzB,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IAEH,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC7B,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACzB,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC5B,uBAAuB,CAAC,MAAM,CAAC,CAAC;IAChC,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAC/B,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC7B,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC7B,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC7B,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACzB,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC1B,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAE7B,2EAA2E;IAC3E,yEAAyE;IACzE,2EAA2E;IAC3E,4EAA4E;IAC5E,2EAA2E;IAC3E,yEAAyE;IACzE,iEAAiE;IACjE,MAAM,CAAC,MAAM,CAAC,aAAa,GAAG,GAAG,EAAE;QACjC,MAAM,CAAC,mBAAmB,EAAE,CAAC;IAC/B,CAAC,CAAC;IAEF,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,29 @@
1
+ export interface LaunchArgs {
2
+ url?: string;
3
+ headless?: boolean;
4
+ userDataDir?: string;
5
+ args?: string[];
6
+ chromePath?: string;
7
+ sandbox?: boolean;
8
+ }
9
+ export interface AttachArgs {
10
+ port?: number;
11
+ host?: string;
12
+ targetFilter?: {
13
+ type?: string;
14
+ urlIncludes?: string;
15
+ };
16
+ }
17
+ export declare function launchChrome(opts?: LaunchArgs): Promise<{
18
+ targetId: string;
19
+ url: string;
20
+ }>;
21
+ export declare function attachChrome(opts?: AttachArgs): Promise<{
22
+ targetId: string;
23
+ url: string;
24
+ }>;
25
+ export declare function closeSession(): Promise<void>;
26
+ export declare function switchTarget(targetId: string): Promise<{
27
+ targetId: string;
28
+ url: string;
29
+ }>;