@hyperbrowser/sdk 1.1.0 → 1.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/README.md +34 -0
- package/dist/services/sessions.d.ts +2 -0
- package/dist/services/sessions.js +2 -0
- package/dist/services/webmcp.d.ts +16 -0
- package/dist/services/webmcp.js +60 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +15 -0
- package/dist/types/session.d.ts +3 -0
- package/dist/types/webmcp.d.ts +84 -0
- package/dist/types/webmcp.js +2 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -16,6 +16,40 @@ or
|
|
|
16
16
|
yarn add @hyperbrowser/sdk
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
+
## WebMCP page tools
|
|
20
|
+
|
|
21
|
+
Create a session with `enableWebMcp: true` (default: false), then navigate to a page
|
|
22
|
+
that exposes WebMCP tools using Playwright or Puppeteer. With that session open:
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
const discovery = await client.sessions.webmcp.listTools(session.id);
|
|
26
|
+
// Select a tool using its name, source page/frame, and input schema.
|
|
27
|
+
const tool = discovery.tools.find((tool) => tool.name === "search");
|
|
28
|
+
if (!tool) throw new Error("The page has no search tool");
|
|
29
|
+
const result = await client.sessions.webmcp.invoke(session.id, {
|
|
30
|
+
toolRef: tool.toolRef,
|
|
31
|
+
input: { query: "flights to Tokyo" }, // Match the selected tool's schema.
|
|
32
|
+
});
|
|
33
|
+
console.log(result.status, result.output);
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
For long-running tools or forms awaiting human submission, use
|
|
37
|
+
`sessions.webmcp.start(sessionId, params)`, then
|
|
38
|
+
`sessions.webmcp.getResult(sessionId, invocationId, { waitSeconds: 30 })` until the
|
|
39
|
+
status is terminal. `sessions.webmcp.cancel(sessionId, invocationId)` requests
|
|
40
|
+
best-effort cancellation. Blocking invocation defaults to 60 seconds (maximum
|
|
41
|
+
120); `start` defaults to 300 seconds (maximum 3,600) via `timeoutSeconds`.
|
|
42
|
+
|
|
43
|
+
Discover tools again after navigation. Invocations never automatically retry;
|
|
44
|
+
losing a response can leave an unknown outcome. Handles are ephemeral and
|
|
45
|
+
terminal results expire after 10 minutes or earlier eviction. Check result
|
|
46
|
+
status and truncation metadata before using output. Public types, including
|
|
47
|
+
`WebMCPTool`, `WebMCPInvocation`, and the request types, are exported from
|
|
48
|
+
`@hyperbrowser/sdk/types`.
|
|
49
|
+
|
|
50
|
+
See the [WebMCP guide](https://hyperbrowser.ai/docs/sessions/webmcp) for complete
|
|
51
|
+
examples, cancellation behavior, human submission, and limits.
|
|
52
|
+
|
|
19
53
|
## Usage
|
|
20
54
|
|
|
21
55
|
### Playwright
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { BasicResponse, CaptchaEvaluationParams, CaptchaEvaluationResponse, CreateSessionParams, CreateSessionSnapshotResponse, GetActiveSessionsCountResponse, GetSessionDownloadsUrlResponse, GetSessionRecordingUrlResponse, GetSessionVideoRecordingUrlResponse, SessionDetail, SessionListParams, SessionListResponse, SessionRecording, UploadFileOptions, UploadFileResponse, SessionEventLogListParams, SessionEventLogListResponse, UpdateSessionProfileParams, UpdateSessionProxyParams, UpdateSessionScreenParams, UpdateSessionSolveCaptchasParams, UpdateSessionSolveCaptchasResponse, SessionGetParams } from "../types/session";
|
|
2
2
|
import { BaseService } from "./base";
|
|
3
|
+
import { WebMCPService } from "./webmcp";
|
|
3
4
|
/**
|
|
4
5
|
* Service for managing session event logs
|
|
5
6
|
*/
|
|
@@ -13,6 +14,7 @@ declare class SessionEventLogsService extends BaseService {
|
|
|
13
14
|
}
|
|
14
15
|
export declare class SessionsService extends BaseService {
|
|
15
16
|
readonly eventLogs: SessionEventLogsService;
|
|
17
|
+
readonly webmcp: WebMCPService;
|
|
16
18
|
constructor(apiKey: string, baseUrl: string, timeout: number);
|
|
17
19
|
/**
|
|
18
20
|
* Create a new browser session
|
|
@@ -31,6 +31,7 @@ const fs_1 = require("fs");
|
|
|
31
31
|
const path = __importStar(require("path"));
|
|
32
32
|
const form_data_1 = __importDefault(require("form-data"));
|
|
33
33
|
const base_1 = require("./base");
|
|
34
|
+
const webmcp_1 = require("./webmcp");
|
|
34
35
|
const client_1 = require("../client");
|
|
35
36
|
const CAPTCHA_EVALUATION_REQUEST_TIMEOUT_MS = 185000;
|
|
36
37
|
/**
|
|
@@ -61,6 +62,7 @@ class SessionsService extends base_1.BaseService {
|
|
|
61
62
|
constructor(apiKey, baseUrl, timeout) {
|
|
62
63
|
super(apiKey, baseUrl, timeout);
|
|
63
64
|
this.eventLogs = new SessionEventLogsService(apiKey, baseUrl, timeout);
|
|
65
|
+
this.webmcp = new webmcp_1.WebMCPService(apiKey, baseUrl, timeout);
|
|
64
66
|
}
|
|
65
67
|
/**
|
|
66
68
|
* Create a new browser session
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { BaseService } from "./base";
|
|
2
|
+
import { WebMCPInvocation, WebMCPInvokeParams, WebMCPInvokeResult, WebMCPResultParams, WebMCPStartParams, WebMCPToolsResponse } from "../types/webmcp";
|
|
3
|
+
/** Page tools for sessions created with enableWebMcp: true. */
|
|
4
|
+
export declare class WebMCPService extends BaseService {
|
|
5
|
+
private path;
|
|
6
|
+
/** Discover current tools across the session's tabs and frames. */
|
|
7
|
+
listTools(sessionId: string): Promise<WebMCPToolsResponse>;
|
|
8
|
+
/** Invoke once. Transport failures never cause an automatic retry. */
|
|
9
|
+
invoke(sessionId: string, params: WebMCPInvokeParams): Promise<WebMCPInvokeResult>;
|
|
10
|
+
/** Start once and return a handle. A lost response may mean the tool already ran. */
|
|
11
|
+
start(sessionId: string, params: WebMCPStartParams): Promise<WebMCPInvocation>;
|
|
12
|
+
/** Read or long-poll a handle. Pending responses do not cancel or restart the tool. */
|
|
13
|
+
getResult(sessionId: string, invocationId: string, params?: WebMCPResultParams): Promise<WebMCPInvocation>;
|
|
14
|
+
/** Request cancellation; completion can win the race. Read getResult for the outcome. */
|
|
15
|
+
cancel(sessionId: string, invocationId: string): Promise<WebMCPInvocation>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WebMCPService = void 0;
|
|
4
|
+
const base_1 = require("./base");
|
|
5
|
+
function seconds(value, min, max, name) {
|
|
6
|
+
if (!Number.isInteger(value) || value < min || value > max) {
|
|
7
|
+
throw new RangeError(`${name} must be an integer between ${min} and ${max}`);
|
|
8
|
+
}
|
|
9
|
+
return value;
|
|
10
|
+
}
|
|
11
|
+
function invocationBody(params) {
|
|
12
|
+
if (typeof params.toolRef !== "string" || !params.toolRef.trim()) {
|
|
13
|
+
throw new TypeError("toolRef must be a non-empty string from listTools");
|
|
14
|
+
}
|
|
15
|
+
if (params.input !== undefined &&
|
|
16
|
+
(params.input === null || typeof params.input !== "object" || Array.isArray(params.input))) {
|
|
17
|
+
throw new TypeError("input must be a JSON object");
|
|
18
|
+
}
|
|
19
|
+
return JSON.stringify(params);
|
|
20
|
+
}
|
|
21
|
+
/** Page tools for sessions created with enableWebMcp: true. */
|
|
22
|
+
class WebMCPService extends base_1.BaseService {
|
|
23
|
+
path(sessionId) {
|
|
24
|
+
return `/session/${encodeURIComponent(sessionId)}/webmcp`;
|
|
25
|
+
}
|
|
26
|
+
/** Discover current tools across the session's tabs and frames. */
|
|
27
|
+
async listTools(sessionId) {
|
|
28
|
+
return this.request(`${this.path(sessionId)}/tools`, {
|
|
29
|
+
timeout: Math.max(this.timeout, 40000),
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
/** Invoke once. Transport failures never cause an automatic retry. */
|
|
33
|
+
async invoke(sessionId, params) {
|
|
34
|
+
const timeout = seconds(params.timeoutSeconds ?? 60, 1, 120, "timeoutSeconds");
|
|
35
|
+
return this.request(`${this.path(sessionId)}/invoke`, {
|
|
36
|
+
method: "POST",
|
|
37
|
+
body: invocationBody(params),
|
|
38
|
+
timeout: Math.max(this.timeout, (timeout + 35) * 1000),
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
/** Start once and return a handle. A lost response may mean the tool already ran. */
|
|
42
|
+
async start(sessionId, params) {
|
|
43
|
+
seconds(params.timeoutSeconds ?? 300, 1, 3600, "timeoutSeconds");
|
|
44
|
+
return this.request(`${this.path(sessionId)}/invocations`, {
|
|
45
|
+
method: "POST",
|
|
46
|
+
body: invocationBody(params),
|
|
47
|
+
timeout: Math.max(this.timeout, 40000),
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/** Read or long-poll a handle. Pending responses do not cancel or restart the tool. */
|
|
51
|
+
async getResult(sessionId, invocationId, params = {}) {
|
|
52
|
+
const wait = seconds(params.waitSeconds ?? 0, 0, 30, "waitSeconds");
|
|
53
|
+
return this.request(`${this.path(sessionId)}/invocations/${encodeURIComponent(invocationId)}`, { timeout: Math.max(this.timeout, (wait + 20) * 1000) }, { waitSeconds: params.waitSeconds });
|
|
54
|
+
}
|
|
55
|
+
/** Request cancellation; completion can win the race. Read getResult for the outcome. */
|
|
56
|
+
async cancel(sessionId, invocationId) {
|
|
57
|
+
return this.request(`${this.path(sessionId)}/invocations/${encodeURIComponent(invocationId)}/cancel`, { method: "POST", timeout: Math.max(this.timeout, 20000) });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
exports.WebMCPService = WebMCPService;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { HyperbrowserConfig } from "./config";
|
|
2
|
+
export * from "./webmcp";
|
|
2
3
|
export { StartCrawlJobParams, StartCrawlJobResponse, CrawledPage, CrawlJobResponse, GetCrawlJobParams, CrawlJobStatusResponse, } from "./crawl";
|
|
3
4
|
export { StartScrapeJobParams, StartScrapeJobResponse, ScrapeJobData, ScrapeJobResponse, ScrapeOptions, ScrapeJobStatusResponse, BatchScrapeJobStatusResponse, StorageStateOptions, } from "./scrape";
|
|
4
5
|
export { StartExtractJobParams, StartExtractJobResponse, ExtractJobResponse, ExtractJobStatusResponse, ExtractJobMetadata, } from "./extract";
|
package/dist/types/index.js
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
2
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
17
|
exports.ComputerAction = void 0;
|
|
18
|
+
__exportStar(require("./webmcp"), exports);
|
|
4
19
|
var computer_action_1 = require("./computer-action");
|
|
5
20
|
Object.defineProperty(exports, "ComputerAction", { enumerable: true, get: function () { return computer_action_1.ComputerAction; } });
|
package/dist/types/session.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ export interface SessionProfile {
|
|
|
10
10
|
persistChanges?: boolean;
|
|
11
11
|
}
|
|
12
12
|
export interface SessionLaunchState {
|
|
13
|
+
enableWebMcp?: boolean;
|
|
13
14
|
useUltraStealth?: boolean;
|
|
14
15
|
useStealth?: boolean;
|
|
15
16
|
useProxy?: boolean;
|
|
@@ -128,6 +129,8 @@ export interface StartSessionFromSnapshotParams {
|
|
|
128
129
|
snapshotId: string;
|
|
129
130
|
}
|
|
130
131
|
export interface CreateSessionParams {
|
|
132
|
+
/** Enable page-provided WebMCP tools. Defaults to false on the server. */
|
|
133
|
+
enableWebMcp?: boolean;
|
|
131
134
|
useUltraStealth?: boolean;
|
|
132
135
|
useStealth?: boolean;
|
|
133
136
|
useProxy?: boolean;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/** Page-provided hints; these are not browser-enforced guarantees. */
|
|
2
|
+
export interface WebMCPAnnotations {
|
|
3
|
+
readOnly: boolean;
|
|
4
|
+
untrustedContent: boolean;
|
|
5
|
+
consequential: boolean;
|
|
6
|
+
autosubmit: boolean;
|
|
7
|
+
destructive?: boolean;
|
|
8
|
+
idempotent?: boolean;
|
|
9
|
+
openWorld?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface WebMCPFrame {
|
|
12
|
+
id: string;
|
|
13
|
+
url: string;
|
|
14
|
+
isMainFrame: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface WebMCPSource {
|
|
17
|
+
provider: "native" | "polyfill";
|
|
18
|
+
tabId: string;
|
|
19
|
+
pageUrl: string;
|
|
20
|
+
pageTitle: string;
|
|
21
|
+
frame: WebMCPFrame;
|
|
22
|
+
}
|
|
23
|
+
export interface WebMCPTool {
|
|
24
|
+
/** Opaque reference to this document. Discover tools again after navigation. */
|
|
25
|
+
toolRef: string;
|
|
26
|
+
name: string;
|
|
27
|
+
title?: string;
|
|
28
|
+
description: string;
|
|
29
|
+
inputSchema?: Record<string, unknown>;
|
|
30
|
+
outputSchema?: Record<string, unknown>;
|
|
31
|
+
annotations: WebMCPAnnotations;
|
|
32
|
+
declarative: boolean;
|
|
33
|
+
/** Native DOM node identifier, when available, in the source target/frame. */
|
|
34
|
+
backendNodeId?: number;
|
|
35
|
+
source: WebMCPSource;
|
|
36
|
+
}
|
|
37
|
+
export interface WebMCPToolsResponse {
|
|
38
|
+
tools: WebMCPTool[];
|
|
39
|
+
nativeSupported: boolean;
|
|
40
|
+
truncated: boolean;
|
|
41
|
+
}
|
|
42
|
+
export interface WebMCPInvokeParams {
|
|
43
|
+
toolRef: string;
|
|
44
|
+
/** Page-defined keys are passed through unchanged. Defaults to {}. */
|
|
45
|
+
input?: Record<string, unknown>;
|
|
46
|
+
/** Execution deadline in seconds: 1–120, default 60. */
|
|
47
|
+
timeoutSeconds?: number;
|
|
48
|
+
}
|
|
49
|
+
export interface WebMCPStartParams extends WebMCPInvokeParams {
|
|
50
|
+
/** Execution deadline including human submission: 1–3600 seconds, default 300. */
|
|
51
|
+
timeoutSeconds?: number;
|
|
52
|
+
}
|
|
53
|
+
export interface WebMCPResultParams {
|
|
54
|
+
/** Wait 0–30 seconds, default 0. A pending response does not cancel the tool. */
|
|
55
|
+
waitSeconds?: number;
|
|
56
|
+
}
|
|
57
|
+
export type WebMCPInvokeStatus = "completed" | "error" | "canceled" | "awaiting_submission";
|
|
58
|
+
export type WebMCPInvocationStatus = WebMCPInvokeStatus | "running" | "outcome_unknown";
|
|
59
|
+
export interface WebMCPInvokeResult {
|
|
60
|
+
invocationId?: string;
|
|
61
|
+
status: WebMCPInvokeStatus;
|
|
62
|
+
output?: unknown;
|
|
63
|
+
errorText?: string;
|
|
64
|
+
outputBytes: number;
|
|
65
|
+
outputTruncated?: boolean;
|
|
66
|
+
outputPreview?: string;
|
|
67
|
+
untrustedContent: boolean;
|
|
68
|
+
durationMs: number;
|
|
69
|
+
}
|
|
70
|
+
export interface WebMCPInvocationError {
|
|
71
|
+
code: string;
|
|
72
|
+
message: string;
|
|
73
|
+
}
|
|
74
|
+
/** Session-local record; results expire and do not survive receiver restarts. */
|
|
75
|
+
export interface WebMCPInvocation {
|
|
76
|
+
invocationId: string;
|
|
77
|
+
toolRef: string;
|
|
78
|
+
status: WebMCPInvocationStatus;
|
|
79
|
+
cancellationRequested: boolean;
|
|
80
|
+
createdAt: string;
|
|
81
|
+
expiresAt?: string;
|
|
82
|
+
result?: WebMCPInvokeResult;
|
|
83
|
+
error?: WebMCPInvocationError;
|
|
84
|
+
}
|