craftdriver 0.0.3 → 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.
- package/CHANGELOG.md +104 -0
- package/README.md +186 -10
- package/bin/craftdriver.mjs +26 -0
- package/dist/cli/client.d.ts +17 -0
- package/dist/cli/client.d.ts.map +1 -0
- package/dist/cli/client.js +88 -0
- package/dist/cli/client.js.map +1 -0
- package/dist/cli/daemon.d.ts +15 -0
- package/dist/cli/daemon.d.ts.map +1 -0
- package/dist/cli/daemon.js +145 -0
- package/dist/cli/daemon.js.map +1 -0
- package/dist/cli/defaults.d.ts +10 -0
- package/dist/cli/defaults.d.ts.map +1 -0
- package/dist/cli/defaults.js +42 -0
- package/dist/cli/defaults.js.map +1 -0
- package/dist/cli/dispatcher.d.ts +28 -0
- package/dist/cli/dispatcher.d.ts.map +1 -0
- package/dist/cli/dispatcher.js +319 -0
- package/dist/cli/dispatcher.js.map +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +404 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init.d.ts +24 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +192 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/mcp/artifacts.d.ts +43 -0
- package/dist/cli/mcp/artifacts.d.ts.map +1 -0
- package/dist/cli/mcp/artifacts.js +104 -0
- package/dist/cli/mcp/artifacts.js.map +1 -0
- package/dist/cli/mcp/server.d.ts +34 -0
- package/dist/cli/mcp/server.d.ts.map +1 -0
- package/dist/cli/mcp/server.js +214 -0
- package/dist/cli/mcp/server.js.map +1 -0
- package/dist/cli/mcp/tools.d.ts +34 -0
- package/dist/cli/mcp/tools.d.ts.map +1 -0
- package/dist/cli/mcp/tools.js +236 -0
- package/dist/cli/mcp/tools.js.map +1 -0
- package/dist/cli/parseArgs.d.ts +37 -0
- package/dist/cli/parseArgs.d.ts.map +1 -0
- package/dist/cli/parseArgs.js +215 -0
- package/dist/cli/parseArgs.js.map +1 -0
- package/dist/cli/protocol.d.ts +34 -0
- package/dist/cli/protocol.d.ts.map +1 -0
- package/dist/cli/protocol.js +2 -0
- package/dist/cli/protocol.js.map +1 -0
- package/dist/cli/selector.d.ts +29 -0
- package/dist/cli/selector.d.ts.map +1 -0
- package/dist/cli/selector.js +100 -0
- package/dist/cli/selector.js.map +1 -0
- package/dist/cli/snapshot.d.ts +48 -0
- package/dist/cli/snapshot.d.ts.map +1 -0
- package/dist/cli/snapshot.js +179 -0
- package/dist/cli/snapshot.js.map +1 -0
- package/dist/index.d.ts +14 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/a11y.d.ts +81 -0
- package/dist/lib/a11y.d.ts.map +1 -0
- package/dist/lib/a11y.js +171 -0
- package/dist/lib/a11y.js.map +1 -0
- package/dist/lib/bidi/connection.d.ts +62 -0
- package/dist/lib/bidi/connection.d.ts.map +1 -0
- package/dist/lib/bidi/connection.js +227 -0
- package/dist/lib/bidi/connection.js.map +1 -0
- package/dist/lib/bidi/index.d.ts +101 -0
- package/dist/lib/bidi/index.d.ts.map +1 -0
- package/dist/lib/bidi/index.js +163 -0
- package/dist/lib/bidi/index.js.map +1 -0
- package/dist/lib/bidi/logs.d.ts +104 -0
- package/dist/lib/bidi/logs.d.ts.map +1 -0
- package/dist/lib/bidi/logs.js +273 -0
- package/dist/lib/bidi/logs.js.map +1 -0
- package/dist/lib/bidi/network.d.ts +165 -0
- package/dist/lib/bidi/network.d.ts.map +1 -0
- package/dist/lib/bidi/network.js +477 -0
- package/dist/lib/bidi/network.js.map +1 -0
- package/dist/lib/bidi/storage.d.ts +83 -0
- package/dist/lib/bidi/storage.d.ts.map +1 -0
- package/dist/lib/bidi/storage.js +299 -0
- package/dist/lib/bidi/storage.js.map +1 -0
- package/dist/lib/bidi/types.d.ts +323 -0
- package/dist/lib/bidi/types.d.ts.map +1 -0
- package/dist/lib/bidi/types.js +6 -0
- package/dist/lib/bidi/types.js.map +1 -0
- package/dist/lib/browser.d.ts +776 -13
- package/dist/lib/browser.d.ts.map +1 -1
- package/dist/lib/browser.js +1547 -70
- package/dist/lib/browser.js.map +1 -1
- package/dist/lib/browserContext.d.ts +486 -0
- package/dist/lib/browserContext.d.ts.map +1 -0
- package/dist/lib/browserContext.js +937 -0
- package/dist/lib/browserContext.js.map +1 -0
- package/dist/lib/builder.d.ts +3 -0
- package/dist/lib/builder.d.ts.map +1 -1
- package/dist/lib/builder.js +31 -4
- package/dist/lib/builder.js.map +1 -1
- package/dist/lib/by.d.ts +18 -2
- package/dist/lib/by.d.ts.map +1 -1
- package/dist/lib/by.js +20 -2
- package/dist/lib/by.js.map +1 -1
- package/dist/lib/chrome.d.ts +13 -1
- package/dist/lib/chrome.d.ts.map +1 -1
- package/dist/lib/chrome.js +13 -17
- package/dist/lib/chrome.js.map +1 -1
- package/dist/lib/clock.d.ts +115 -0
- package/dist/lib/clock.d.ts.map +1 -0
- package/dist/lib/clock.js +407 -0
- package/dist/lib/clock.js.map +1 -0
- package/dist/lib/driver.d.ts +45 -0
- package/dist/lib/driver.d.ts.map +1 -1
- package/dist/lib/driver.js +129 -1
- package/dist/lib/driver.js.map +1 -1
- package/dist/lib/driverManager.d.ts +25 -0
- package/dist/lib/driverManager.d.ts.map +1 -0
- package/dist/lib/driverManager.js +399 -0
- package/dist/lib/driverManager.js.map +1 -0
- package/dist/lib/elementHandle.d.ts +69 -2
- package/dist/lib/elementHandle.d.ts.map +1 -1
- package/dist/lib/elementHandle.js +215 -40
- package/dist/lib/elementHandle.js.map +1 -1
- package/dist/lib/errors.d.ts +71 -0
- package/dist/lib/errors.d.ts.map +1 -0
- package/dist/lib/errors.js +73 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/expect.d.ts +6 -1
- package/dist/lib/expect.d.ts.map +1 -1
- package/dist/lib/expect.js +55 -37
- package/dist/lib/expect.js.map +1 -1
- package/dist/lib/firefox.d.ts +18 -0
- package/dist/lib/firefox.d.ts.map +1 -0
- package/dist/lib/firefox.js +33 -0
- package/dist/lib/firefox.js.map +1 -0
- package/dist/lib/frame.d.ts +57 -0
- package/dist/lib/frame.d.ts.map +1 -0
- package/dist/lib/frame.js +277 -0
- package/dist/lib/frame.js.map +1 -0
- package/dist/lib/keyboard.d.ts +1 -1
- package/dist/lib/keyboard.d.ts.map +1 -1
- package/dist/lib/keyboard.js +1 -1
- package/dist/lib/keyboard.js.map +1 -1
- package/dist/lib/locator.d.ts +71 -2
- package/dist/lib/locator.d.ts.map +1 -1
- package/dist/lib/locator.js +289 -31
- package/dist/lib/locator.js.map +1 -1
- package/dist/lib/mouse.d.ts +1 -1
- package/dist/lib/mouse.d.ts.map +1 -1
- package/dist/lib/mouse.js +1 -1
- package/dist/lib/mouse.js.map +1 -1
- package/dist/lib/page.d.ts +107 -0
- package/dist/lib/page.d.ts.map +1 -0
- package/dist/lib/page.js +388 -0
- package/dist/lib/page.js.map +1 -0
- package/dist/lib/tracing.d.ts +128 -0
- package/dist/lib/tracing.d.ts.map +1 -0
- package/dist/lib/tracing.js +272 -0
- package/dist/lib/tracing.js.map +1 -0
- package/dist/lib/wait.d.ts.map +1 -1
- package/dist/lib/wait.js +14 -1
- package/dist/lib/wait.js.map +1 -1
- package/dist/lib/webelement.d.ts +2 -0
- package/dist/lib/webelement.d.ts.map +1 -1
- package/dist/lib/webelement.js +18 -0
- package/dist/lib/webelement.js.map +1 -1
- package/docs/accessibility.md +177 -0
- package/docs/api-reference.md +71 -0
- package/docs/assertions.md +182 -0
- package/docs/bidi-features.md +462 -0
- package/docs/browser-api.md +673 -0
- package/docs/browser-context.md +522 -0
- package/docs/cli.md +233 -0
- package/docs/clock.md +245 -0
- package/docs/dialogs.md +143 -0
- package/docs/driver-configuration.md +64 -0
- package/docs/element-api.md +219 -0
- package/docs/emulation.md +155 -0
- package/docs/error-codes.md +67 -0
- package/docs/getting-started.md +168 -0
- package/docs/keyboard-mouse.md +250 -0
- package/docs/mcp.md +250 -0
- package/docs/mobile-emulation.md +194 -0
- package/docs/screenshots.md +146 -0
- package/docs/selectors.md +382 -0
- package/docs/session-management.md +229 -0
- package/docs/tracing.md +282 -0
- package/package.json +25 -5
- package/skills/craftdriver/SKILL.md +84 -0
- package/skills/craftdriver/cheatsheet.md +194 -0
- package/skills/craftdriver/cli.md +104 -0
- package/skills/craftdriver/patterns.md +139 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export interface ArtifactWriteResult {
|
|
2
|
+
path: string;
|
|
3
|
+
bytes: number;
|
|
4
|
+
}
|
|
5
|
+
export declare class ArtifactStore {
|
|
6
|
+
private dir;
|
|
7
|
+
private ready;
|
|
8
|
+
private counter;
|
|
9
|
+
constructor(rootOverride?: string);
|
|
10
|
+
/** Absolute path to the artifact directory (may not exist yet). */
|
|
11
|
+
get directory(): string;
|
|
12
|
+
private ensure;
|
|
13
|
+
/**
|
|
14
|
+
* Write a payload to a numbered file. `nameHint` is used to build a
|
|
15
|
+
* human-readable filename (`0001-<hint>`); pass something like
|
|
16
|
+
* `screenshot.png` or `eval.json`.
|
|
17
|
+
*/
|
|
18
|
+
write(nameHint: string, data: Buffer | string): Promise<ArtifactWriteResult>;
|
|
19
|
+
/**
|
|
20
|
+
* Allocate a path for an artifact the caller will write itself (e.g.
|
|
21
|
+
* pass to `browser.screenshot({ path })`). Doesn't touch the disk
|
|
22
|
+
* beyond `mkdir -p` of the directory.
|
|
23
|
+
*/
|
|
24
|
+
allocate(nameHint: string): Promise<string>;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Spill threshold in bytes. Content blocks longer than this are
|
|
28
|
+
* written to an artifact and replaced inline with a short preview.
|
|
29
|
+
*
|
|
30
|
+
* Default 2 KB ≈ 500 tokens — enough room for a typical short
|
|
31
|
+
* snapshot diff or a small JSON result, but well below the cost of a
|
|
32
|
+
* full 80-node snapshot or a verbose eval payload.
|
|
33
|
+
*/
|
|
34
|
+
export declare const DEFAULT_SPILL_BYTES = 2048;
|
|
35
|
+
export declare function resolveSpillBytes(): number;
|
|
36
|
+
/**
|
|
37
|
+
* Build the short inline replacement shown in place of a spilled
|
|
38
|
+
* payload. Keeps the first ~5 lines (or 240 chars, whichever is
|
|
39
|
+
* shorter) so the agent still sees the head of the data without
|
|
40
|
+
* having to read the file for a quick glance.
|
|
41
|
+
*/
|
|
42
|
+
export declare function spillPreview(text: string, written: ArtifactWriteResult): string;
|
|
43
|
+
//# sourceMappingURL=artifacts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifacts.d.ts","sourceRoot":"","sources":["../../../src/cli/mcp/artifacts.ts"],"names":[],"mappings":"AA8BA,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,KAAK,CAA8B;IAC3C,OAAO,CAAC,OAAO,CAAK;gBAER,YAAY,CAAC,EAAE,MAAM;IAQjC,mEAAmE;IACnE,IAAI,SAAS,IAAI,MAAM,CAEtB;YAEa,MAAM;IAOpB;;;;OAIG;IACG,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAUlF;;;;OAIG;IACG,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAMlD;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,OAAO,CAAC;AAExC,wBAAgB,iBAAiB,IAAI,MAAM,CAK1C;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,GAAG,MAAM,CAI/E"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-session artifact store for the MCP server.
|
|
3
|
+
*
|
|
4
|
+
* Why this exists: MCP content blocks count against the model's
|
|
5
|
+
* context window. A 100 KB screenshot or a 4 KB full a11y snapshot
|
|
6
|
+
* costs the agent real tokens on every turn. We'd rather spill the
|
|
7
|
+
* payload to disk and hand back a short preview + absolute path.
|
|
8
|
+
* Hosts that can read files (Claude Code, Cursor, Windsurf, Zed,
|
|
9
|
+
* Goose, Gemini CLI, …) just open it; hosts that can't can still
|
|
10
|
+
* fetch via MCP resources once we expose them.
|
|
11
|
+
*
|
|
12
|
+
* Directory layout:
|
|
13
|
+
* <root>/craftdriver-mcp-<pid>-<ts>/
|
|
14
|
+
* 0001-screenshot.png
|
|
15
|
+
* 0002-snapshot.txt
|
|
16
|
+
* 0003-eval.json
|
|
17
|
+
*
|
|
18
|
+
* Root resolution order:
|
|
19
|
+
* 1. $CRAFTDRIVER_MCP_ARTIFACTS_DIR if set
|
|
20
|
+
* 2. os.tmpdir()
|
|
21
|
+
*
|
|
22
|
+
* Lifetime: the directory is **not** deleted on shutdown. Agents may
|
|
23
|
+
* still be holding paths to past artifacts; OS-level temp cleanup
|
|
24
|
+
* reclaims them eventually. Override the root if you need a custom
|
|
25
|
+
* cleanup policy.
|
|
26
|
+
*/
|
|
27
|
+
import { mkdir, writeFile } from 'fs/promises';
|
|
28
|
+
import { join, resolve } from 'path';
|
|
29
|
+
import { tmpdir } from 'os';
|
|
30
|
+
export class ArtifactStore {
|
|
31
|
+
dir;
|
|
32
|
+
ready = null;
|
|
33
|
+
counter = 0;
|
|
34
|
+
constructor(rootOverride) {
|
|
35
|
+
const root = rootOverride
|
|
36
|
+
?? process.env.CRAFTDRIVER_MCP_ARTIFACTS_DIR
|
|
37
|
+
?? tmpdir();
|
|
38
|
+
const stamp = `${process.pid}-${Date.now().toString(36)}`;
|
|
39
|
+
this.dir = resolve(root, `craftdriver-mcp-${stamp}`);
|
|
40
|
+
}
|
|
41
|
+
/** Absolute path to the artifact directory (may not exist yet). */
|
|
42
|
+
get directory() {
|
|
43
|
+
return this.dir;
|
|
44
|
+
}
|
|
45
|
+
async ensure() {
|
|
46
|
+
if (!this.ready) {
|
|
47
|
+
this.ready = mkdir(this.dir, { recursive: true }).then(() => undefined);
|
|
48
|
+
}
|
|
49
|
+
await this.ready;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Write a payload to a numbered file. `nameHint` is used to build a
|
|
53
|
+
* human-readable filename (`0001-<hint>`); pass something like
|
|
54
|
+
* `screenshot.png` or `eval.json`.
|
|
55
|
+
*/
|
|
56
|
+
async write(nameHint, data) {
|
|
57
|
+
await this.ensure();
|
|
58
|
+
this.counter += 1;
|
|
59
|
+
const seq = this.counter.toString().padStart(4, '0');
|
|
60
|
+
const path = join(this.dir, `${seq}-${nameHint}`);
|
|
61
|
+
const buf = typeof data === 'string' ? Buffer.from(data, 'utf8') : data;
|
|
62
|
+
await writeFile(path, buf);
|
|
63
|
+
return { path, bytes: buf.length };
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Allocate a path for an artifact the caller will write itself (e.g.
|
|
67
|
+
* pass to `browser.screenshot({ path })`). Doesn't touch the disk
|
|
68
|
+
* beyond `mkdir -p` of the directory.
|
|
69
|
+
*/
|
|
70
|
+
async allocate(nameHint) {
|
|
71
|
+
await this.ensure();
|
|
72
|
+
this.counter += 1;
|
|
73
|
+
const seq = this.counter.toString().padStart(4, '0');
|
|
74
|
+
return join(this.dir, `${seq}-${nameHint}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Spill threshold in bytes. Content blocks longer than this are
|
|
79
|
+
* written to an artifact and replaced inline with a short preview.
|
|
80
|
+
*
|
|
81
|
+
* Default 2 KB ≈ 500 tokens — enough room for a typical short
|
|
82
|
+
* snapshot diff or a small JSON result, but well below the cost of a
|
|
83
|
+
* full 80-node snapshot or a verbose eval payload.
|
|
84
|
+
*/
|
|
85
|
+
export const DEFAULT_SPILL_BYTES = 2048;
|
|
86
|
+
export function resolveSpillBytes() {
|
|
87
|
+
const env = process.env.CRAFTDRIVER_MCP_SPILL_BYTES;
|
|
88
|
+
if (!env)
|
|
89
|
+
return DEFAULT_SPILL_BYTES;
|
|
90
|
+
const n = Number.parseInt(env, 10);
|
|
91
|
+
return Number.isFinite(n) && n > 0 ? n : DEFAULT_SPILL_BYTES;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Build the short inline replacement shown in place of a spilled
|
|
95
|
+
* payload. Keeps the first ~5 lines (or 240 chars, whichever is
|
|
96
|
+
* shorter) so the agent still sees the head of the data without
|
|
97
|
+
* having to read the file for a quick glance.
|
|
98
|
+
*/
|
|
99
|
+
export function spillPreview(text, written) {
|
|
100
|
+
const head = text.split('\n').slice(0, 5).join('\n');
|
|
101
|
+
const trimmed = head.length > 240 ? head.slice(0, 237) + '…' : head;
|
|
102
|
+
return `${trimmed}\n…\n(full output: ${written.path}, ${written.bytes} bytes)`;
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=artifacts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifacts.js","sourceRoot":"","sources":["../../../src/cli/mcp/artifacts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP server — JSON-RPC 2.0 over stdio.
|
|
3
|
+
*
|
|
4
|
+
* Hand-rolled because the spec we use (initialize / tools/list /
|
|
5
|
+
* tools/call) is ~6 methods, and pulling `@modelcontextprotocol/sdk`
|
|
6
|
+
* would multiply our runtime-dep footprint. If the spec grows we can
|
|
7
|
+
* swap in the SDK without changing tool definitions in `tools.ts`.
|
|
8
|
+
*
|
|
9
|
+
* Protocol version we advertise: 2024-11-05. If the client offers a
|
|
10
|
+
* newer one we just echo theirs back — the methods we implement are
|
|
11
|
+
* stable across versions to date.
|
|
12
|
+
*
|
|
13
|
+
* Lifecycle:
|
|
14
|
+
* client → initialize → server returns capabilities + info
|
|
15
|
+
* client → notifications/initialized (no response)
|
|
16
|
+
* client ⇆ tools/list, tools/call, ...
|
|
17
|
+
* stdin EOF (or SIGINT/SIGTERM) → close browser, exit 0
|
|
18
|
+
*/
|
|
19
|
+
import { type LaunchOptions } from '../../lib/browser.js';
|
|
20
|
+
export interface McpServerOptions {
|
|
21
|
+
launch: LaunchOptions;
|
|
22
|
+
/** Stream for incoming messages; defaults to process.stdin. */
|
|
23
|
+
input?: NodeJS.ReadableStream;
|
|
24
|
+
/** Stream for outgoing messages; defaults to process.stdout. */
|
|
25
|
+
output?: NodeJS.WritableStream;
|
|
26
|
+
/** Disable snapshots for tests that want a deterministic payload. */
|
|
27
|
+
snapshot?: 'auto' | 'none';
|
|
28
|
+
/** Override the artifact directory root (defaults to $CRAFTDRIVER_MCP_ARTIFACTS_DIR or os.tmpdir()). */
|
|
29
|
+
artifactsDir?: string;
|
|
30
|
+
/** Override the spill threshold in bytes (default 2048; env: $CRAFTDRIVER_MCP_SPILL_BYTES). */
|
|
31
|
+
spillBytes?: number;
|
|
32
|
+
}
|
|
33
|
+
export declare function runMcpServer(opts: McpServerOptions): Promise<void>;
|
|
34
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/cli/mcp/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAW,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAiDnE,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,aAAa,CAAC;IACtB,+DAA+D;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC9B,gEAAgE;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC/B,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,wGAAwG;IACxG,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+FAA+F;IAC/F,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoHxE"}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP server — JSON-RPC 2.0 over stdio.
|
|
3
|
+
*
|
|
4
|
+
* Hand-rolled because the spec we use (initialize / tools/list /
|
|
5
|
+
* tools/call) is ~6 methods, and pulling `@modelcontextprotocol/sdk`
|
|
6
|
+
* would multiply our runtime-dep footprint. If the spec grows we can
|
|
7
|
+
* swap in the SDK without changing tool definitions in `tools.ts`.
|
|
8
|
+
*
|
|
9
|
+
* Protocol version we advertise: 2024-11-05. If the client offers a
|
|
10
|
+
* newer one we just echo theirs back — the methods we implement are
|
|
11
|
+
* stable across versions to date.
|
|
12
|
+
*
|
|
13
|
+
* Lifecycle:
|
|
14
|
+
* client → initialize → server returns capabilities + info
|
|
15
|
+
* client → notifications/initialized (no response)
|
|
16
|
+
* client ⇆ tools/list, tools/call, ...
|
|
17
|
+
* stdin EOF (or SIGINT/SIGTERM) → close browser, exit 0
|
|
18
|
+
*/
|
|
19
|
+
import { Browser } from '../../lib/browser.js';
|
|
20
|
+
import { CraftdriverError, ErrorCode } from '../../lib/errors.js';
|
|
21
|
+
import { createBrowserHandle } from '../dispatcher.js';
|
|
22
|
+
import { TOOLS, getTool, runTool } from './tools.js';
|
|
23
|
+
import { renderDelta, renderFull, takeSnapshot } from '../snapshot.js';
|
|
24
|
+
import { ArtifactStore, resolveSpillBytes, spillPreview, } from './artifacts.js';
|
|
25
|
+
const PROTOCOL_VERSION = '2024-11-05';
|
|
26
|
+
const SERVER_NAME = 'craftdriver';
|
|
27
|
+
const SERVER_VERSION = '0.1.0';
|
|
28
|
+
export async function runMcpServer(opts) {
|
|
29
|
+
const input = opts.input ?? process.stdin;
|
|
30
|
+
const output = opts.output ?? process.stdout;
|
|
31
|
+
const handle = createBrowserHandle(() => Browser.launch(opts.launch));
|
|
32
|
+
const ctx = { handle, launchOptions: opts.launch };
|
|
33
|
+
// Snapshot state: one most-recent snapshot per session for diffing.
|
|
34
|
+
let lastSnapshot = null;
|
|
35
|
+
const snapshotsOn = opts.snapshot !== 'none';
|
|
36
|
+
// Artifact store: large content blocks spill here so they don't burn
|
|
37
|
+
// context tokens on every turn.
|
|
38
|
+
const artifacts = new ArtifactStore(opts.artifactsDir);
|
|
39
|
+
const spillBytes = opts.spillBytes ?? resolveSpillBytes();
|
|
40
|
+
function send(msg) {
|
|
41
|
+
output.write(JSON.stringify(msg) + '\n');
|
|
42
|
+
}
|
|
43
|
+
async function handleRequest(req) {
|
|
44
|
+
const id = req.id ?? null;
|
|
45
|
+
try {
|
|
46
|
+
switch (req.method) {
|
|
47
|
+
case 'initialize':
|
|
48
|
+
return ok(id, {
|
|
49
|
+
protocolVersion: req.params?.protocolVersion ?? PROTOCOL_VERSION,
|
|
50
|
+
capabilities: { tools: {} },
|
|
51
|
+
serverInfo: { name: SERVER_NAME, version: SERVER_VERSION },
|
|
52
|
+
instructions: 'craftdriver browser automation. Probe selectors with browser_exists ' +
|
|
53
|
+
'before acting; errors carry a stable `code` field; the post-action ' +
|
|
54
|
+
'a11y snapshot diff tells you what changed.',
|
|
55
|
+
});
|
|
56
|
+
case 'notifications/initialized':
|
|
57
|
+
return null; // notification — no response
|
|
58
|
+
case 'ping':
|
|
59
|
+
return ok(id, {});
|
|
60
|
+
case 'tools/list':
|
|
61
|
+
return ok(id, {
|
|
62
|
+
tools: TOOLS.map((t) => ({
|
|
63
|
+
name: t.name,
|
|
64
|
+
description: t.description,
|
|
65
|
+
inputSchema: t.inputSchema,
|
|
66
|
+
})),
|
|
67
|
+
});
|
|
68
|
+
case 'tools/call': {
|
|
69
|
+
const name = req.params?.name;
|
|
70
|
+
const args = req.params?.arguments ?? {};
|
|
71
|
+
if (!name)
|
|
72
|
+
return rpcError(id, -32602, 'tools/call: missing "name"');
|
|
73
|
+
const tool = getTool(name);
|
|
74
|
+
if (!tool) {
|
|
75
|
+
return ok(id, toolError(`unknown tool: ${name}`, ErrorCode.INVALID_ARGUMENT));
|
|
76
|
+
}
|
|
77
|
+
const result = await callTool(ctx, tool, args, {
|
|
78
|
+
snapshotsOn,
|
|
79
|
+
getPrev: () => lastSnapshot,
|
|
80
|
+
setLast: (s) => {
|
|
81
|
+
lastSnapshot = s;
|
|
82
|
+
},
|
|
83
|
+
artifacts,
|
|
84
|
+
spillBytes,
|
|
85
|
+
});
|
|
86
|
+
return ok(id, result);
|
|
87
|
+
}
|
|
88
|
+
case 'resources/list':
|
|
89
|
+
// Resources land with Item 7 (trace summaries). Empty list now
|
|
90
|
+
// keeps clients that probe for resource capability happy.
|
|
91
|
+
return ok(id, { resources: [] });
|
|
92
|
+
default:
|
|
93
|
+
return rpcError(id, -32601, `method not found: ${req.method}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
catch (e) {
|
|
97
|
+
return rpcError(id, -32000, e.message ?? String(e));
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
// Line-delimited JSON over stdin. Tolerate \r\n and trailing whitespace.
|
|
101
|
+
let buf = '';
|
|
102
|
+
input.setEncoding?.('utf8');
|
|
103
|
+
input.on('data', (chunk) => {
|
|
104
|
+
buf += typeof chunk === 'string' ? chunk : chunk.toString('utf8');
|
|
105
|
+
let nl;
|
|
106
|
+
while ((nl = buf.indexOf('\n')) !== -1) {
|
|
107
|
+
const line = buf.slice(0, nl).trim();
|
|
108
|
+
buf = buf.slice(nl + 1);
|
|
109
|
+
if (!line)
|
|
110
|
+
continue;
|
|
111
|
+
let parsed;
|
|
112
|
+
try {
|
|
113
|
+
parsed = JSON.parse(line);
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
send({ jsonrpc: '2.0', id: null, error: { code: -32700, message: 'parse error' } });
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
// Run async; responses may interleave but each carries its own id.
|
|
120
|
+
void handleRequest(parsed).then((resp) => {
|
|
121
|
+
if (resp)
|
|
122
|
+
send(resp);
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
await new Promise((resolve) => {
|
|
127
|
+
const done = () => resolve();
|
|
128
|
+
input.once('end', done);
|
|
129
|
+
input.once('close', done);
|
|
130
|
+
process.once('SIGINT', done);
|
|
131
|
+
process.once('SIGTERM', done);
|
|
132
|
+
});
|
|
133
|
+
await handle.close();
|
|
134
|
+
}
|
|
135
|
+
async function callTool(ctx, tool, args, snap) {
|
|
136
|
+
// Screenshot path allocation: if the caller didn't supply a path,
|
|
137
|
+
// give them one inside the artifact directory so the PNG bytes are
|
|
138
|
+
// actually persisted somewhere they can read.
|
|
139
|
+
if (tool.name === 'browser_screenshot' && !args.path) {
|
|
140
|
+
args = { ...args, path: await snap.artifacts.allocate('screenshot.png') };
|
|
141
|
+
}
|
|
142
|
+
let value;
|
|
143
|
+
try {
|
|
144
|
+
value = await runTool(ctx, tool, args);
|
|
145
|
+
}
|
|
146
|
+
catch (e) {
|
|
147
|
+
if (e instanceof CraftdriverError) {
|
|
148
|
+
return toolError(e.message, e.code, e.hint);
|
|
149
|
+
}
|
|
150
|
+
return toolError(e.message ?? String(e), ErrorCode.DRIVER_ERROR);
|
|
151
|
+
}
|
|
152
|
+
const content = [];
|
|
153
|
+
// Render result. The snapshot tool returns a structured shape we
|
|
154
|
+
// know how to print compactly; everything else falls through to
|
|
155
|
+
// the generic summariser. Both paths run through `maybeSpill` so
|
|
156
|
+
// large payloads land on disk instead of in the context window.
|
|
157
|
+
let primaryText;
|
|
158
|
+
if (tool.name === 'browser_snapshot' && value && typeof value === 'object' && 'lines' in value) {
|
|
159
|
+
primaryText = await maybeSpill(renderFull(value), 'snapshot.txt', snap.artifacts, snap.spillBytes);
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
primaryText = await summariseValue(tool.name, value, snap.artifacts, snap.spillBytes);
|
|
163
|
+
}
|
|
164
|
+
content.push({ type: 'text', text: primaryText });
|
|
165
|
+
// Post-action a11y diff, when this tool changed page state.
|
|
166
|
+
if (tool.mutating && snap.snapshotsOn) {
|
|
167
|
+
const next = await takeSnapshot(await ctx.handle.get()).catch(() => null);
|
|
168
|
+
const delta = renderDelta(snap.getPrev(), next);
|
|
169
|
+
if (delta) {
|
|
170
|
+
const block = await maybeSpill(delta, 'snapshot.txt', snap.artifacts, snap.spillBytes);
|
|
171
|
+
content.push({ type: 'text', text: block });
|
|
172
|
+
}
|
|
173
|
+
snap.setLast(next);
|
|
174
|
+
}
|
|
175
|
+
return { content, structuredContent: { result: value } };
|
|
176
|
+
}
|
|
177
|
+
async function summariseValue(toolName, value, artifacts, spillBytes) {
|
|
178
|
+
if (value === null || value === undefined)
|
|
179
|
+
return `${toolName}: ok`;
|
|
180
|
+
const text = typeof value === 'string' ? value : safeJson(value);
|
|
181
|
+
return maybeSpill(text, `${toolName}.txt`, artifacts, spillBytes);
|
|
182
|
+
}
|
|
183
|
+
async function maybeSpill(text, nameHint, artifacts, spillBytes) {
|
|
184
|
+
const size = Buffer.byteLength(text, 'utf8');
|
|
185
|
+
if (size <= spillBytes)
|
|
186
|
+
return text;
|
|
187
|
+
const written = await artifacts.write(nameHint, text);
|
|
188
|
+
return spillPreview(text, written);
|
|
189
|
+
}
|
|
190
|
+
function safeJson(value) {
|
|
191
|
+
try {
|
|
192
|
+
return JSON.stringify(value);
|
|
193
|
+
}
|
|
194
|
+
catch {
|
|
195
|
+
return String(value);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
function toolError(message, code, hint) {
|
|
199
|
+
const lines = [`error: ${message}`, `code: ${code}`];
|
|
200
|
+
if (hint)
|
|
201
|
+
lines.push(`hint: ${hint}`);
|
|
202
|
+
return {
|
|
203
|
+
isError: true,
|
|
204
|
+
content: [{ type: 'text', text: lines.join('\n') }],
|
|
205
|
+
structuredContent: { error: { code, message, hint } },
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
function ok(id, result) {
|
|
209
|
+
return { jsonrpc: '2.0', id, result };
|
|
210
|
+
}
|
|
211
|
+
function rpcError(id, code, message) {
|
|
212
|
+
return { jsonrpc: '2.0', id, error: { code, message } };
|
|
213
|
+
}
|
|
214
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/cli/mcp/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP tool registry.
|
|
3
|
+
*
|
|
4
|
+
* Each tool: a JSON Schema for the model + a thin handler that maps
|
|
5
|
+
* the arguments onto the existing dispatcher. The dispatcher already
|
|
6
|
+
* speaks `{ cmd, args }` and throws `CraftdriverError` with stable
|
|
7
|
+
* codes — we reuse it untouched so library, CLI, and MCP all behave
|
|
8
|
+
* identically when given the same selector.
|
|
9
|
+
*
|
|
10
|
+
* Compact set per §6 of the AI-productivity plan: ~12 tools, one-line
|
|
11
|
+
* descriptions, merged variants behind options. `browser_trace` is
|
|
12
|
+
* intentionally absent in v1 — it ships with Item 7 (trace summaries).
|
|
13
|
+
*/
|
|
14
|
+
import type { DispatchContext } from '../dispatcher.js';
|
|
15
|
+
export interface ToolDef {
|
|
16
|
+
name: string;
|
|
17
|
+
description: string;
|
|
18
|
+
/** JSON Schema, restricted to types MCP clients reliably support. */
|
|
19
|
+
inputSchema: Record<string, unknown>;
|
|
20
|
+
/** Map MCP args → dispatcher args. Defaults to identity. */
|
|
21
|
+
toDispatch: (args: Record<string, unknown>) => {
|
|
22
|
+
cmd: string;
|
|
23
|
+
args: Record<string, unknown>;
|
|
24
|
+
};
|
|
25
|
+
/** When true, this action mutates page state — caller should take a snapshot. */
|
|
26
|
+
mutating: boolean;
|
|
27
|
+
/** When true, the result includes binary content (image bytes). */
|
|
28
|
+
returnsImage?: boolean;
|
|
29
|
+
}
|
|
30
|
+
export declare const TOOLS: ToolDef[];
|
|
31
|
+
export declare function getTool(name: string): ToolDef | undefined;
|
|
32
|
+
/** Run a tool against the dispatcher. Throws CraftdriverError on failure. */
|
|
33
|
+
export declare function runTool(ctx: DispatchContext, tool: ToolDef, args: Record<string, unknown>): Promise<unknown>;
|
|
34
|
+
//# sourceMappingURL=tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../src/cli/mcp/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAGxD,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,qEAAqE;IACrE,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,4DAA4D;IAC5D,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;IAC9F,iFAAiF;IACjF,QAAQ,EAAE,OAAO,CAAC;IAClB,mEAAmE;IACnE,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAUD,eAAO,MAAM,KAAK,EAAE,OAAO,EAkO1B,CAAC;AAIF,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAEzD;AAED,6EAA6E;AAC7E,wBAAsB,OAAO,CAC3B,GAAG,EAAE,eAAe,EACpB,IAAI,EAAE,OAAO,EACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC,OAAO,CAAC,CAGlB"}
|