@browserstack/mcp-server 1.4.0-beta.3 → 1.5.0-beta.2
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/capability/loadtesting.capability-index.json +1764 -0
- package/capability/tm.capability-index.json +19793 -0
- package/dist/config.d.ts +1 -4
- package/dist/config.js +2 -23
- package/dist/index.js +2 -5
- package/dist/server-factory.js +5 -5
- package/dist/tools/accessibility.js +2 -5
- package/dist/tools/capability-registry/bind.d.ts +29 -0
- package/dist/tools/capability-registry/bind.js +134 -0
- package/dist/tools/capability-registry/config.d.ts +62 -0
- package/dist/tools/capability-registry/config.js +218 -0
- package/dist/tools/capability-registry/discovery.d.ts +44 -0
- package/dist/tools/capability-registry/discovery.js +99 -0
- package/dist/tools/capability-registry/egress.d.ts +44 -0
- package/dist/tools/capability-registry/egress.js +128 -0
- package/dist/tools/capability-registry/index-loader.d.ts +119 -0
- package/dist/tools/capability-registry/index-loader.js +314 -0
- package/dist/tools/capability-registry/register.d.ts +34 -0
- package/dist/tools/capability-registry/register.js +354 -0
- package/dist/tools/capability-registry/resolve.d.ts +38 -0
- package/dist/tools/capability-registry/resolve.js +45 -0
- package/dist/tools/capability-registry/search.d.ts +65 -0
- package/dist/tools/capability-registry/search.js +342 -0
- package/dist/tools/capability-registry/types.d.ts +208 -0
- package/dist/tools/capability-registry/types.js +33 -0
- package/dist/tools/get-failure-logs.js +1 -3
- package/dist/tools/rca-agent.js +2 -5
- package/dist/tools/selfheal.js +2 -5
- package/dist/tools/testmanagement.js +15 -37
- package/package.json +3 -2
- package/dist/tools/ask-browserstack/central-oauth.d.ts +0 -120
- package/dist/tools/ask-browserstack/central-oauth.js +0 -277
- package/dist/tools/ask-browserstack/config.d.ts +0 -102
- package/dist/tools/ask-browserstack/config.js +0 -140
- package/dist/tools/ask-browserstack/egress.d.ts +0 -34
- package/dist/tools/ask-browserstack/egress.js +0 -31
- package/dist/tools/ask-browserstack/register.d.ts +0 -61
- package/dist/tools/ask-browserstack/register.js +0 -416
- package/dist/tools/ask-browserstack/relay.d.ts +0 -201
- package/dist/tools/ask-browserstack/relay.js +0 -577
- package/dist/tools/ask-browserstack/stream.d.ts +0 -116
- package/dist/tools/ask-browserstack/stream.js +0 -236
- package/dist/tools/ask-browserstack/types.d.ts +0 -196
- package/dist/tools/ask-browserstack/types.js +0 -14
- package/dist/tools/tool-handoff.d.ts +0 -62
- package/dist/tools/tool-handoff.js +0 -75
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Where Atlas lives, and the timeout ladder.
|
|
3
|
-
*
|
|
4
|
-
* The host IS compiled in, matching every other tool here — `TM_BASE_URLS`, the
|
|
5
|
-
* instrumentation endpoint — so an install needs no configuration to work. One env var
|
|
6
|
-
* overrides it. See the warning on `DEFAULT_ATLAS_URL`: the compiled-in value is currently
|
|
7
|
-
* STAGING and is a deliberate placeholder.
|
|
8
|
-
*/
|
|
9
|
-
/**
|
|
10
|
-
* CONTRACT §4 — the timeout ladder, outermost first. EACH LAYER MUST EXCEED THE ONE INSIDE
|
|
11
|
-
* IT, or a layer dies before the layer it is waiting on can answer:
|
|
12
|
-
*
|
|
13
|
-
* MCP client -> tool call longest, client-side, not ours
|
|
14
|
-
* POST /agent HTTP request 330s <- here
|
|
15
|
-
* Atlas gate -> stream ask 300s Atlas's `permission_relay_timeout`
|
|
16
|
-
* elicitInput 270s <- here
|
|
17
|
-
*
|
|
18
|
-
* 300s is the browser path's existing PERMISSION_TIMEOUT, which also auto-rejects.
|
|
19
|
-
*/
|
|
20
|
-
export declare const AGENT_TIMEOUT_MS = 330000;
|
|
21
|
-
export declare const ELICITATION_TIMEOUT_MS = 270000;
|
|
22
|
-
/** Thrown for anything this tool refuses to attempt. Never carries a credential. */
|
|
23
|
-
export declare class AskError extends Error {
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Off by default is wrong for a shipped feature, but a kill switch is not.
|
|
27
|
-
*
|
|
28
|
-
* The only setting here still read from `process.env` per call, and deliberately: a kill
|
|
29
|
-
* switch that needs a process restart is slowest exactly when it is needed fastest. The
|
|
30
|
-
* other three are on the config singleton (rules/tool-design.md).
|
|
31
|
-
*/
|
|
32
|
-
export declare function isEnabled(): boolean;
|
|
33
|
-
/**
|
|
34
|
-
* May the relay be offered in the hosted (`REMOTE_MCP`) deployment?
|
|
35
|
-
*
|
|
36
|
-
* OFF BY DEFAULT, because it depends on something outside this package: the host has to
|
|
37
|
-
* keep one `McpServer` alive per session. Stateless hosts build a fresh server per POST,
|
|
38
|
-
* and an elicitation answer — which arrives as a SEPARATE POST — then reaches an instance
|
|
39
|
-
* that never asked anything, leaving the real one suspended until it times out. So this
|
|
40
|
-
* must stay opt-in per deployment rather than become a default that silently hangs.
|
|
41
|
-
*
|
|
42
|
-
* Turning it on does NOT force the relay on: `relayMode` still asks whether THIS client
|
|
43
|
-
* declared the `elicitation` capability, and a client that did not still gets a read-only
|
|
44
|
-
* run. This flag only removes the blanket refusal.
|
|
45
|
-
*/
|
|
46
|
-
export declare function allowRemoteRelay(): boolean;
|
|
47
|
-
/**
|
|
48
|
-
* ============================================================================
|
|
49
|
-
* PRODUCTION DEFAULTS
|
|
50
|
-
* ============================================================================
|
|
51
|
-
*
|
|
52
|
-
* These hosts are PRODUCTION. They replace the interim staging placeholders that this
|
|
53
|
-
* package shipped with while the relay was being built ("for now lets hardcode the
|
|
54
|
-
* base_url to staging only then we will point this to prod url later") — that step is
|
|
55
|
-
* now done.
|
|
56
|
-
*
|
|
57
|
-
* `https://workflows.browserstack.com` was verified, not guessed: its `/api/profiles`
|
|
58
|
-
* answers `401 {"detail":"authentication required"}`, byte-identical to staging Atlas.
|
|
59
|
-
* The production auth endpoint is `https://auth.browserstack.com/oauth2/v2/token`.
|
|
60
|
-
*
|
|
61
|
-
* WHY THIS MATTERS: this package publishes to npm as `@browserstack/mcp-server`, so an
|
|
62
|
-
* install with no environment variables set now talks to PRODUCTION. That is correct for
|
|
63
|
-
* a production deployment, but it removes the old safety property — a misconfigured or
|
|
64
|
-
* test deployment that forgets `ASK_BROWSERSTACK_ATLAS_URL` no longer fails safe onto
|
|
65
|
-
* staging, it reads and writes REAL customer data. Non-production deployments MUST set
|
|
66
|
-
* that variable explicitly. The resolved host is logged at info on first use, naming
|
|
67
|
-
* whether it came from the env var or from here, so a deployment pointing at the wrong
|
|
68
|
-
* Atlas is visible in a log line rather than inferred later from confusing data.
|
|
69
|
-
*
|
|
70
|
-
* Staging hosts, for anyone setting the override:
|
|
71
|
-
* ASK_BROWSERSTACK_ATLAS_URL = https://ai-platform-service.bsstag.com
|
|
72
|
-
* ASK_BROWSERSTACK_AUTH_TOKEN_URL = https://auth-preprod.bsstag.com/oauth2/v2/token
|
|
73
|
-
*
|
|
74
|
-
* The tests assert these literals precisely so that repointing has to be deliberate
|
|
75
|
-
* rather than something that slips through.
|
|
76
|
-
*
|
|
77
|
-
* grep: DEFAULT-PROD-HOSTS
|
|
78
|
-
*/
|
|
79
|
-
export declare const DEFAULT_ATLAS_URL = "https://workflows.browserstack.com";
|
|
80
|
-
export declare const DEFAULT_AUTH_TOKEN_URL = "https://auth.browserstack.com/oauth2/v2/token";
|
|
81
|
-
/** For tests, and for anything that legitimately re-resolves. */
|
|
82
|
-
export declare function resetHostAnnouncements(): void;
|
|
83
|
-
/**
|
|
84
|
-
* Resolve Atlas's base URL:
|
|
85
|
-
*
|
|
86
|
-
* 1. ASK_BROWSERSTACK_ATLAS_URL explicit override
|
|
87
|
-
* 2. the built-in staging default (see the warning above)
|
|
88
|
-
*
|
|
89
|
-
* Matching every other tool here, which ships its host in the code and treats the env var as
|
|
90
|
-
* an override — `TM_BASE_URLS`, the instrumentation endpoint. There is no environment map and
|
|
91
|
-
* no selector: one default, one override.
|
|
92
|
-
*/
|
|
93
|
-
export declare function atlasBaseUrl(): string;
|
|
94
|
-
/** Resolved per call, never captured at construction. */
|
|
95
|
-
export declare function agentUrl(): string;
|
|
96
|
-
/**
|
|
97
|
-
* Where a central-OAuth JWT is minted (CONTRACT v1.2 §I, as amended by task 7).
|
|
98
|
-
*
|
|
99
|
-
* The shared `delegation.token` path is gone from Atlas, so a user-attested central JWT is
|
|
100
|
-
* the only way in. Same two rungs as the host, and the same staging default.
|
|
101
|
-
*/
|
|
102
|
-
export declare function authTokenUrl(): string;
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
import appConfig from "../../config.js";
|
|
2
|
-
import logger from "../../logger.js";
|
|
3
|
-
/**
|
|
4
|
-
* Where Atlas lives, and the timeout ladder.
|
|
5
|
-
*
|
|
6
|
-
* The host IS compiled in, matching every other tool here — `TM_BASE_URLS`, the
|
|
7
|
-
* instrumentation endpoint — so an install needs no configuration to work. One env var
|
|
8
|
-
* overrides it. See the warning on `DEFAULT_ATLAS_URL`: the compiled-in value is currently
|
|
9
|
-
* STAGING and is a deliberate placeholder.
|
|
10
|
-
*/
|
|
11
|
-
/**
|
|
12
|
-
* CONTRACT §4 — the timeout ladder, outermost first. EACH LAYER MUST EXCEED THE ONE INSIDE
|
|
13
|
-
* IT, or a layer dies before the layer it is waiting on can answer:
|
|
14
|
-
*
|
|
15
|
-
* MCP client -> tool call longest, client-side, not ours
|
|
16
|
-
* POST /agent HTTP request 330s <- here
|
|
17
|
-
* Atlas gate -> stream ask 300s Atlas's `permission_relay_timeout`
|
|
18
|
-
* elicitInput 270s <- here
|
|
19
|
-
*
|
|
20
|
-
* 300s is the browser path's existing PERMISSION_TIMEOUT, which also auto-rejects.
|
|
21
|
-
*/
|
|
22
|
-
export const AGENT_TIMEOUT_MS = 330_000;
|
|
23
|
-
export const ELICITATION_TIMEOUT_MS = 270_000;
|
|
24
|
-
/** Thrown for anything this tool refuses to attempt. Never carries a credential. */
|
|
25
|
-
export class AskError extends Error {
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Off by default is wrong for a shipped feature, but a kill switch is not.
|
|
29
|
-
*
|
|
30
|
-
* The only setting here still read from `process.env` per call, and deliberately: a kill
|
|
31
|
-
* switch that needs a process restart is slowest exactly when it is needed fastest. The
|
|
32
|
-
* other three are on the config singleton (rules/tool-design.md).
|
|
33
|
-
*/
|
|
34
|
-
export function isEnabled() {
|
|
35
|
-
return (process.env.ASK_BROWSERSTACK_DISABLED || "").toLowerCase() !== "true";
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* May the relay be offered in the hosted (`REMOTE_MCP`) deployment?
|
|
39
|
-
*
|
|
40
|
-
* OFF BY DEFAULT, because it depends on something outside this package: the host has to
|
|
41
|
-
* keep one `McpServer` alive per session. Stateless hosts build a fresh server per POST,
|
|
42
|
-
* and an elicitation answer — which arrives as a SEPARATE POST — then reaches an instance
|
|
43
|
-
* that never asked anything, leaving the real one suspended until it times out. So this
|
|
44
|
-
* must stay opt-in per deployment rather than become a default that silently hangs.
|
|
45
|
-
*
|
|
46
|
-
* Turning it on does NOT force the relay on: `relayMode` still asks whether THIS client
|
|
47
|
-
* declared the `elicitation` capability, and a client that did not still gets a read-only
|
|
48
|
-
* run. This flag only removes the blanket refusal.
|
|
49
|
-
*/
|
|
50
|
-
export function allowRemoteRelay() {
|
|
51
|
-
return appConfig.ASK_BROWSERSTACK_ALLOW_REMOTE_RELAY;
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* ============================================================================
|
|
55
|
-
* PRODUCTION DEFAULTS
|
|
56
|
-
* ============================================================================
|
|
57
|
-
*
|
|
58
|
-
* These hosts are PRODUCTION. They replace the interim staging placeholders that this
|
|
59
|
-
* package shipped with while the relay was being built ("for now lets hardcode the
|
|
60
|
-
* base_url to staging only then we will point this to prod url later") — that step is
|
|
61
|
-
* now done.
|
|
62
|
-
*
|
|
63
|
-
* `https://workflows.browserstack.com` was verified, not guessed: its `/api/profiles`
|
|
64
|
-
* answers `401 {"detail":"authentication required"}`, byte-identical to staging Atlas.
|
|
65
|
-
* The production auth endpoint is `https://auth.browserstack.com/oauth2/v2/token`.
|
|
66
|
-
*
|
|
67
|
-
* WHY THIS MATTERS: this package publishes to npm as `@browserstack/mcp-server`, so an
|
|
68
|
-
* install with no environment variables set now talks to PRODUCTION. That is correct for
|
|
69
|
-
* a production deployment, but it removes the old safety property — a misconfigured or
|
|
70
|
-
* test deployment that forgets `ASK_BROWSERSTACK_ATLAS_URL` no longer fails safe onto
|
|
71
|
-
* staging, it reads and writes REAL customer data. Non-production deployments MUST set
|
|
72
|
-
* that variable explicitly. The resolved host is logged at info on first use, naming
|
|
73
|
-
* whether it came from the env var or from here, so a deployment pointing at the wrong
|
|
74
|
-
* Atlas is visible in a log line rather than inferred later from confusing data.
|
|
75
|
-
*
|
|
76
|
-
* Staging hosts, for anyone setting the override:
|
|
77
|
-
* ASK_BROWSERSTACK_ATLAS_URL = https://ai-platform-service.bsstag.com
|
|
78
|
-
* ASK_BROWSERSTACK_AUTH_TOKEN_URL = https://auth-preprod.bsstag.com/oauth2/v2/token
|
|
79
|
-
*
|
|
80
|
-
* The tests assert these literals precisely so that repointing has to be deliberate
|
|
81
|
-
* rather than something that slips through.
|
|
82
|
-
*
|
|
83
|
-
* grep: DEFAULT-PROD-HOSTS
|
|
84
|
-
*/
|
|
85
|
-
export const DEFAULT_ATLAS_URL = "https://workflows.browserstack.com";
|
|
86
|
-
export const DEFAULT_AUTH_TOKEN_URL = "https://auth.browserstack.com/oauth2/v2/token";
|
|
87
|
-
/** An operator's override may carry a trailing slash; the constants above do not. */
|
|
88
|
-
function trimUrl(value) {
|
|
89
|
-
return value.trim().replace(/\/+$/, "");
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Announced ONCE per distinct resolution, not per tool call.
|
|
93
|
-
*
|
|
94
|
-
* The point is that a deployment talking to the wrong Atlas shows up in the log; repeating it
|
|
95
|
-
* on every call would only make it easier to scroll past.
|
|
96
|
-
*/
|
|
97
|
-
const announced = new Set();
|
|
98
|
-
/** For tests, and for anything that legitimately re-resolves. */
|
|
99
|
-
export function resetHostAnnouncements() {
|
|
100
|
-
announced.clear();
|
|
101
|
-
}
|
|
102
|
-
function announce(what, url, source) {
|
|
103
|
-
const line = `${what}|${url}|${source}`;
|
|
104
|
-
if (announced.has(line))
|
|
105
|
-
return;
|
|
106
|
-
announced.add(line);
|
|
107
|
-
logger.info("askBrowserStackAI: %s is %s (source: %s)", what, url, source);
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Resolve Atlas's base URL:
|
|
111
|
-
*
|
|
112
|
-
* 1. ASK_BROWSERSTACK_ATLAS_URL explicit override
|
|
113
|
-
* 2. the built-in staging default (see the warning above)
|
|
114
|
-
*
|
|
115
|
-
* Matching every other tool here, which ships its host in the code and treats the env var as
|
|
116
|
-
* an override — `TM_BASE_URLS`, the instrumentation endpoint. There is no environment map and
|
|
117
|
-
* no selector: one default, one override.
|
|
118
|
-
*/
|
|
119
|
-
export function atlasBaseUrl() {
|
|
120
|
-
const explicit = appConfig.ASK_BROWSERSTACK_ATLAS_URL;
|
|
121
|
-
const url = explicit && explicit.trim() ? trimUrl(explicit) : DEFAULT_ATLAS_URL;
|
|
122
|
-
announce("Atlas", url, explicit && explicit.trim() ? "env" : "default");
|
|
123
|
-
return url;
|
|
124
|
-
}
|
|
125
|
-
/** Resolved per call, never captured at construction. */
|
|
126
|
-
export function agentUrl() {
|
|
127
|
-
return `${atlasBaseUrl()}/agent`;
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* Where a central-OAuth JWT is minted (CONTRACT v1.2 §I, as amended by task 7).
|
|
131
|
-
*
|
|
132
|
-
* The shared `delegation.token` path is gone from Atlas, so a user-attested central JWT is
|
|
133
|
-
* the only way in. Same two rungs as the host, and the same staging default.
|
|
134
|
-
*/
|
|
135
|
-
export function authTokenUrl() {
|
|
136
|
-
const explicit = appConfig.ASK_BROWSERSTACK_AUTH_TOKEN_URL;
|
|
137
|
-
const url = explicit && explicit.trim() ? trimUrl(explicit) : DEFAULT_AUTH_TOKEN_URL;
|
|
138
|
-
announce("auth token endpoint", url, explicit && explicit.trim() ? "env" : "default");
|
|
139
|
-
return url;
|
|
140
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The pieces of the outbound `POST /agent` that are not the transport itself.
|
|
3
|
-
*
|
|
4
|
-
* The transport moved to `stream.ts` when A2 was removed: `/agent` is read as an event
|
|
5
|
-
* stream now, so a one-request-one-response `AgentTransport` has nothing left to describe.
|
|
6
|
-
* What stays here is what both halves always shared — the header set, the credential pair,
|
|
7
|
-
* and the response shape `relay.ts` reads to tell a refusal from an unreachable service
|
|
8
|
-
* apart, which the stream's JSON-degrade path still produces.
|
|
9
|
-
*
|
|
10
|
-
* AUTH HERE IS NOT THE PRODUCT-API AUTH. `/agent` accepts exactly two credentials, both in
|
|
11
|
-
* `Authorization`: the shared delegation token or a BrowserStack central JWT. There is no
|
|
12
|
-
* `Api-Token` path on this route (CONTRACT v1.2 §I), so sending one would not merely be
|
|
13
|
-
* useless — it would push the user's `access_key` across a trust boundary to an endpoint
|
|
14
|
-
* that has no use for it, and into every request log on the way. The capability registry's
|
|
15
|
-
* `authHeaders` remains right for PRODUCT calls; it is simply not the header set for this
|
|
16
|
-
* one, and is deliberately not imported here.
|
|
17
|
-
*/
|
|
18
|
-
export interface Credentials {
|
|
19
|
-
username: string;
|
|
20
|
-
accessKey: string;
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* The complete header set for `POST /agent` (CONTRACT v1.2 §4). Three headers, no more.
|
|
24
|
-
*
|
|
25
|
-
* The token is a secret and appears nowhere else: not in a log line, not in a result, not in
|
|
26
|
-
* an error message.
|
|
27
|
-
*/
|
|
28
|
-
export declare function agentHeaders(token: string): Record<string, string>;
|
|
29
|
-
export interface AgentResponse {
|
|
30
|
-
status: number;
|
|
31
|
-
body: unknown;
|
|
32
|
-
/** Only when there was no response at all to speak for itself. */
|
|
33
|
-
error?: string;
|
|
34
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The pieces of the outbound `POST /agent` that are not the transport itself.
|
|
3
|
-
*
|
|
4
|
-
* The transport moved to `stream.ts` when A2 was removed: `/agent` is read as an event
|
|
5
|
-
* stream now, so a one-request-one-response `AgentTransport` has nothing left to describe.
|
|
6
|
-
* What stays here is what both halves always shared — the header set, the credential pair,
|
|
7
|
-
* and the response shape `relay.ts` reads to tell a refusal from an unreachable service
|
|
8
|
-
* apart, which the stream's JSON-degrade path still produces.
|
|
9
|
-
*
|
|
10
|
-
* AUTH HERE IS NOT THE PRODUCT-API AUTH. `/agent` accepts exactly two credentials, both in
|
|
11
|
-
* `Authorization`: the shared delegation token or a BrowserStack central JWT. There is no
|
|
12
|
-
* `Api-Token` path on this route (CONTRACT v1.2 §I), so sending one would not merely be
|
|
13
|
-
* useless — it would push the user's `access_key` across a trust boundary to an endpoint
|
|
14
|
-
* that has no use for it, and into every request log on the way. The capability registry's
|
|
15
|
-
* `authHeaders` remains right for PRODUCT calls; it is simply not the header set for this
|
|
16
|
-
* one, and is deliberately not imported here.
|
|
17
|
-
*/
|
|
18
|
-
/**
|
|
19
|
-
* The complete header set for `POST /agent` (CONTRACT v1.2 §4). Three headers, no more.
|
|
20
|
-
*
|
|
21
|
-
* The token is a secret and appears nowhere else: not in a log line, not in a result, not in
|
|
22
|
-
* an error message.
|
|
23
|
-
*/
|
|
24
|
-
export function agentHeaders(token) {
|
|
25
|
-
return {
|
|
26
|
-
Authorization: `Bearer ${token}`,
|
|
27
|
-
"Content-Type": "application/json",
|
|
28
|
-
// Attribution, so the downstream service can see the call came from an agent.
|
|
29
|
-
"request-source": "ai-chatbot",
|
|
30
|
-
};
|
|
31
|
-
}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `askBrowserStackAI` — one tool call in, one tool result out, with a human's approval
|
|
3
|
-
* relayed through the middle of it.
|
|
4
|
-
*
|
|
5
|
-
* The shape, and why:
|
|
6
|
-
*
|
|
7
|
-
* 1. NEGOTIATE FIRST. `relayMode()` is consulted BEFORE Atlas is called, so Atlas learns
|
|
8
|
-
* whether a human is reachable before it starts rather than discovering it at the gate.
|
|
9
|
-
* Anything other than "offered" means `permission_relay` is omitted entirely and Atlas
|
|
10
|
-
* runs read-only — today's exact behaviour, and the path opencode and goose stay on.
|
|
11
|
-
* That also covers the hosted `REMOTE_MCP` deployment, where the relay cannot work at
|
|
12
|
-
* all; see `relayMode` for why. Nothing here depends on `sampling`, which Claude Code
|
|
13
|
-
* does not declare.
|
|
14
|
-
* 2. LISTEN ON LOOPBACK. Transport is A2, so Atlas calls US back; because it initiates,
|
|
15
|
-
* the decision returns on the same connection to the same pod and PLAN.md's affinity
|
|
16
|
-
* problem never arises for this stdio deployment.
|
|
17
|
-
* 3. ELICIT, ONCE. Atlas's `description` is the message, nothing is requested in the form,
|
|
18
|
-
* and the ACTION is mapped by CONTRACT §7 with no second chances.
|
|
19
|
-
* 4. RETURN THE TRAIL. `approvals` and `applied_before_stop` are what let a caller tell
|
|
20
|
-
* "nothing happened" from "some steps applied, then stopped".
|
|
21
|
-
*
|
|
22
|
-
* FAIL CLOSED THROUGHOUT. A decline, a cancel, a timeout, a bad token, a body we cannot
|
|
23
|
-
* parse, a handler that throws — every one of them denies. An unattended run cannot approve
|
|
24
|
-
* itself because a headless client returns `cancel`, which is a deny.
|
|
25
|
-
*/
|
|
26
|
-
import { McpServer, RegisteredTool } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
27
|
-
import { BrowserStackConfig } from "../../lib/types.js";
|
|
28
|
-
import { Credentials } from "./egress.js";
|
|
29
|
-
import type { AgentStreamTransport, DecisionTransport } from "./stream.js";
|
|
30
|
-
import { RelayMode } from "./types.js";
|
|
31
|
-
export interface AskDeps {
|
|
32
|
-
/** Resolved per call: a deployment's host is configuration, not a constructor argument. */
|
|
33
|
-
agentUrl: () => string;
|
|
34
|
-
/**
|
|
35
|
-
* Sign in and return a bearer for `POST /agent`. Cached behind this, not minted per call.
|
|
36
|
-
*
|
|
37
|
-
* A function rather than a value because it is resolved per call for the same reason the
|
|
38
|
-
* host is, and because it can fail in ways a caller needs told apart.
|
|
39
|
-
*/
|
|
40
|
-
mintToken: () => Promise<string>;
|
|
41
|
-
/**
|
|
42
|
-
* Read per call, not captured: the remote server rebuilds config per session, so a
|
|
43
|
-
* captured credential would outlive the session it belongs to.
|
|
44
|
-
*
|
|
45
|
-
* These are now THE AUTH CREDENTIAL, not merely attribution: the access key is exchanged
|
|
46
|
-
* for a user-attested central JWT, which is what lets Atlas run the approved product call
|
|
47
|
-
* as the human rather than as a shared service account.
|
|
48
|
-
*/
|
|
49
|
-
credentialsFor: () => Credentials;
|
|
50
|
-
/**
|
|
51
|
-
* The two transport seams, injectable so a test can drive a whole approval round trip
|
|
52
|
-
* — ask, elicit, decide, result — without a socket.
|
|
53
|
-
*/
|
|
54
|
-
streamTransport?: AgentStreamTransport;
|
|
55
|
-
decisionTransport?: DecisionTransport;
|
|
56
|
-
}
|
|
57
|
-
export declare function relayMode(server: McpServer): RelayMode;
|
|
58
|
-
export declare function addAskBrowserStackAITool(server: McpServer, deps: AskDeps, config?: BrowserStackConfig): Record<string, RegisteredTool>;
|
|
59
|
-
/** The tool-adder the server factory calls. */
|
|
60
|
-
export declare function addAskBrowserStackAIToolFromConfig(server: McpServer, config: BrowserStackConfig): Record<string, RegisteredTool>;
|
|
61
|
-
export default addAskBrowserStackAIToolFromConfig;
|