agents 0.30.1 → 0.32.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 +2 -1
- package/dist/{agent-routing-CDbpVjYq.d.ts → agent-routing-vVMA7m8Y.d.ts} +69 -608
- package/dist/agent-routing.d.ts +1 -1
- package/dist/agent-tool-types.d.ts +1 -1
- package/dist/{agent-tools-C8DH8Yii.d.ts → agent-tools-gGXXkf1z.d.ts} +2 -2
- package/dist/agent-tools.d.ts +1 -1
- package/dist/agent-tools.js +0 -1
- package/dist/agent-tools.js.map +1 -1
- package/dist/{ai-iXw0uOGj.d.ts → ai-CDn3Abax.d.ts} +30 -4
- package/dist/{ai-sdk-DRPh2rRa.js → ai-sdk-Kon40i0q.js} +2 -36
- package/dist/ai-sdk-Kon40i0q.js.map +1 -0
- package/dist/browser/ai.d.ts +1 -1
- package/dist/browser/ai.js +16 -3
- package/dist/browser/ai.js.map +1 -1
- package/dist/browser/index.d.ts +64 -16
- package/dist/browser/index.js +4 -4
- package/dist/browser/tools/ai-sdk.d.ts +7 -5
- package/dist/browser/tools/ai-sdk.js +4 -4
- package/dist/browser/tools/ai-sdk.js.map +1 -1
- package/dist/browser/tools/pi.d.ts +9 -15
- package/dist/browser/tools/pi.js +6 -14
- package/dist/browser/tools/pi.js.map +1 -1
- package/dist/browser/tools/tanstack-ai.d.ts +48 -25
- package/dist/browser/tools/tanstack-ai.js +8 -4
- package/dist/browser/tools/tanstack-ai.js.map +1 -1
- package/dist/{browser-DccPw_wW.js → browser-1eUbPvC2.js} +413 -14
- package/dist/browser-1eUbPvC2.js.map +1 -0
- package/dist/{browser-DlXhSAdf.d.ts → browser-D9RNpJuT.d.ts} +254 -20
- package/dist/browser-tool-BhjCcNVE.d.ts +71 -0
- package/dist/browser-tool-DRan7Lk6.js +497 -0
- package/dist/browser-tool-DRan7Lk6.js.map +1 -0
- package/dist/capability-id-B3J8Nok_.js +13 -0
- package/dist/capability-id-B3J8Nok_.js.map +1 -0
- package/dist/catalog-BpOejOsE.js +239 -0
- package/dist/catalog-BpOejOsE.js.map +1 -0
- package/dist/catalog-BpiVV1OF.d.ts +173 -0
- package/dist/chat/index.d.ts +2 -2
- package/dist/chat-sdk/index.d.ts +3 -3
- package/dist/chat-sdk/index.js +1 -1
- package/dist/client-4OlMIJx-.js.map +1 -1
- package/dist/{client-BnYbNT3z.js → client-DMWujQJ1.js} +68 -244
- package/dist/client-DMWujQJ1.js.map +1 -0
- package/dist/{client-C27CtRZr.d.ts → client-eSfgYvd3.d.ts} +9 -7
- package/dist/client.d.ts +1 -1
- package/dist/{cloudflare-Dzvc7V2N.js → cloudflare-CUUm_9q9.js} +26 -4
- package/dist/cloudflare-CUUm_9q9.js.map +1 -0
- package/dist/{connector-DAXBOIIi.js → connector-CM-uuxKM.js} +96 -8
- package/dist/connector-CM-uuxKM.js.map +1 -0
- package/dist/{connector-20DJ6p4k.d.ts → connector-DZ71EjE-.d.ts} +109 -9
- package/dist/{do-oauth-client-provider-DfsUcpc3.d.ts → do-oauth-client-provider-DtNqv7oj.d.ts} +26 -2
- package/dist/{index-YSKgfgg9.d.ts → emitter-BJZtCVjQ.d.ts} +6 -140
- package/dist/emitter-DPOVcCln.js +15 -0
- package/dist/emitter-DPOVcCln.js.map +1 -0
- package/dist/experimental/channels/web/index.js +1 -1
- package/dist/experimental/webmcp.js +1 -1
- package/dist/{handler-stateless-Bly_nSH3.js → handler-stateless-B5hU3dxK.js} +35 -2
- package/dist/handler-stateless-B5hU3dxK.js.map +1 -0
- package/dist/{handler-stateless-DxYpJ_XF.d.ts → handler-stateless-C90kD5_R.d.ts} +3 -47
- package/dist/harness/container/index.d.ts +15 -15
- package/dist/harness/container/index.js +0 -1
- package/dist/harness/container/index.js.map +1 -1
- package/dist/harness/container/runtime/index.js +2 -2
- package/dist/harness/opencode/index.js +0 -1
- package/dist/harness/opencode/index.js.map +1 -1
- package/dist/harness/pi/index.d.ts +15 -7
- package/dist/harness/pi/index.js +74 -151
- package/dist/harness/pi/index.js.map +1 -1
- package/dist/harness/think/index.d.ts +2 -1
- package/dist/{images-xaDv2Fqe.js → images-CfuRCjwq.js} +1 -5
- package/dist/images-CfuRCjwq.js.map +1 -0
- package/dist/{index-DCxk3OSJ.d.ts → index-8k4qsX1T.d.ts} +2 -28
- package/dist/index.d.ts +15 -16
- package/dist/index.js +3 -3
- package/dist/internal-hosts-Kfp5A392.d.ts +230 -0
- package/dist/internal-kmw70xwR.js.map +1 -1
- package/dist/invoker-BC1SZ3q1.js +26 -0
- package/dist/invoker-BC1SZ3q1.js.map +1 -0
- package/dist/invoker-DoLFPJZV.d.ts +21 -0
- package/dist/markdown-BZ-VLtA1.js +86 -0
- package/dist/markdown-BZ-VLtA1.js.map +1 -0
- package/dist/mcp/client/do-oauth-client-provider.d.ts +4 -2
- package/dist/mcp/client/do-oauth-client-provider.js +15 -1
- package/dist/mcp/client/do-oauth-client-provider.js.map +1 -1
- package/dist/mcp/client/index.d.ts +15 -1
- package/dist/mcp/client/index.js +2 -2
- package/dist/mcp/client/x402.d.ts +7 -5
- package/dist/mcp/client/x402.js +34 -1
- package/dist/mcp/client/x402.js.map +1 -1
- package/dist/mcp/index.d.ts +561 -27
- package/dist/mcp/index.js +180 -3
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/server/index.d.ts +1 -1
- package/dist/mcp/server/index.js +1 -1
- package/dist/models/ai-sdk/index.d.ts +2 -2
- package/dist/models/ai-sdk/index.js +1 -1
- package/dist/models/opencode/index.d.ts +2 -2
- package/dist/models/opencode/index.js +1 -1
- package/dist/models/pi-ai/index.d.ts +3 -28
- package/dist/models/pi-ai/index.js +160 -18
- package/dist/models/pi-ai/index.js.map +1 -1
- package/dist/observability/ai/index.js +1 -2
- package/dist/observability/ai/index.js.map +1 -1
- package/dist/observability/index.d.ts +170 -9
- package/dist/observability/index.js +386 -11
- package/dist/observability/index.js.map +1 -1
- package/dist/protocol-BEgrJYC5.d.ts +29 -29
- package/dist/react.d.ts +2 -2
- package/dist/resource-B59OV2a2.js +325 -0
- package/dist/resource-B59OV2a2.js.map +1 -0
- package/dist/routing/index.d.ts +1 -1
- package/dist/script-CFDLTk5b.d.ts +91 -0
- package/dist/script-workspace-BpdAYq1R.d.ts +41 -0
- package/dist/serializable.d.ts +1 -1
- package/dist/{session-store-yvwq1f9x.js → session-7CDgVE0z.js} +455 -33
- package/dist/session-7CDgVE0z.js.map +1 -0
- package/dist/{session-store-_IK6dV-w.d.ts → session-store-B7Ca-u1t.d.ts} +8 -1
- package/dist/settings-Dk2il2Hf.js.map +1 -1
- package/dist/skill-DRBcIBjC.d.ts +221 -0
- package/dist/skills/index.d.ts +275 -36
- package/dist/skills/index.js +265 -1534
- package/dist/skills/index.js.map +1 -1
- package/dist/skills/runner.d.ts +37 -0
- package/dist/skills/runner.js +912 -0
- package/dist/skills/runner.js.map +1 -0
- package/dist/skills/tools/ai-sdk.d.ts +36 -0
- package/dist/skills/tools/ai-sdk.js +94 -0
- package/dist/skills/tools/ai-sdk.js.map +1 -0
- package/dist/source-9RQzlEhM.d.ts +112 -0
- package/dist/{src-DfLzdwlK.js → src-DoGNJ4Ud.js} +21 -6
- package/dist/src-DoGNJ4Ud.js.map +1 -0
- package/dist/sub-routing.d.ts +12 -12
- package/dist/tool-CTp72Jb_.d.ts +10 -10
- package/dist/tool-CxKsvxjm.js.map +1 -1
- package/dist/tool-DkT_DJBm.js.map +1 -1
- package/dist/tool-DoVberpN.d.ts +22 -22
- package/dist/tool-helpers-BI7ifO2S.js +255 -0
- package/dist/tool-helpers-BI7ifO2S.js.map +1 -0
- package/dist/{transport-CPh7YGiw.d.ts → transport-5moD2pW5.d.ts} +1 -43
- package/dist/types-D2naO3rA.d.ts +49 -0
- package/dist/vite.d.ts +2 -2
- package/dist/vite.js +10 -258
- package/dist/vite.js.map +1 -1
- package/dist/voice/index.d.ts +1 -1
- package/dist/websockets/index.js +1 -1
- package/dist/{websockets-CyoeosdO.js → websockets-C6SJtWCJ.js} +1 -2
- package/dist/{websockets-CyoeosdO.js.map → websockets-C6SJtWCJ.js.map} +1 -1
- package/dist/workflow-types.d.ts +1 -1
- package/dist/workflows.d.ts +1 -1
- package/dist/workflows.js +0 -1
- package/dist/workflows.js.map +1 -1
- package/docs/browse-the-web.md +247 -413
- package/docs/harnesses/pi.md +36 -30
- package/docs/index.md +4 -4
- package/docs/mcp-client.md +25 -1
- package/docs/mcp-servers.md +26 -7
- package/docs/models-pi-ai.md +9 -11
- package/docs/models.md +1 -8
- package/docs/observability.md +5 -3
- package/docs/securing-mcp-servers.md +113 -302
- package/package.json +31 -17
- package/dist/ai-sdk-DRPh2rRa.js.map +0 -1
- package/dist/browser-DccPw_wW.js.map +0 -1
- package/dist/browser-tool-B1mhifin.js +0 -616
- package/dist/browser-tool-B1mhifin.js.map +0 -1
- package/dist/browser-tool-Cxjk5sgG.d.ts +0 -92
- package/dist/client-BnYbNT3z.js.map +0 -1
- package/dist/cloudflare-Dzvc7V2N.js.map +0 -1
- package/dist/connector-DAXBOIIi.js.map +0 -1
- package/dist/handler-stateless-Bly_nSH3.js.map +0 -1
- package/dist/images-xaDv2Fqe.js.map +0 -1
- package/dist/index-iv9FTXX9.d.ts +0 -311
- package/dist/invoker-CG0_p_Wq.d.ts +0 -20
- package/dist/invoker-CHMnoxIA.js +0 -57
- package/dist/invoker-CHMnoxIA.js.map +0 -1
- package/dist/session-store-yvwq1f9x.js.map +0 -1
- package/dist/skills/compile.d.ts +0 -40
- package/dist/skills/compile.js +0 -65
- package/dist/skills/compile.js.map +0 -1
- package/dist/src-DfLzdwlK.js.map +0 -1
- package/dist/tool-helpers-O5BDVEAY.js +0 -58
- package/dist/tool-helpers-O5BDVEAY.js.map +0 -1
- package/skills-module.d.ts +0 -22
package/dist/index.js
CHANGED
|
@@ -5,11 +5,11 @@ import { t as __DO_NOT_USE_WILL_BREAK__agentContext } from "./current-agent-DhoD
|
|
|
5
5
|
import { callable, unstable_callable } from "./callable-decorator.js";
|
|
6
6
|
import { MessageType } from "./types.js";
|
|
7
7
|
import { createHeaderBasedEmailResolver } from "./email.js";
|
|
8
|
-
import {
|
|
8
|
+
import { r as withInvocationScope } from "./cloudflare-CUUm_9q9.js";
|
|
9
9
|
import { SUB_PREFIX, buildAgentPath, buildAgentUrl, getSubAgentByName, parseSubAgentPath, routeSubAgentRequest } from "./sub-routing.js";
|
|
10
|
-
import { a as routeAgentEmail, i as getCurrentAgent, n as DEFAULT_AGENT_STATIC_OPTIONS, r as StreamingResponse, t as Agent } from "./src-
|
|
10
|
+
import { a as routeAgentEmail, i as getCurrentAgent, n as DEFAULT_AGENT_STATIC_OPTIONS, r as StreamingResponse, t as Agent } from "./src-DoGNJ4Ud.js";
|
|
11
11
|
import { isDurableObjectCodeUpdateReset, isDurableObjectMemoryLimitReset, isDurableObjectStorageReset, isPlatformTransientError } from "./retries.js";
|
|
12
12
|
import { SqlError } from "./sql-error.js";
|
|
13
|
-
import { i as normalizeServerId, n as MCP_SERVER_ID_MAX_LENGTH } from "./client-
|
|
13
|
+
import { i as normalizeServerId, n as MCP_SERVER_ID_MAX_LENGTH } from "./client-DMWujQJ1.js";
|
|
14
14
|
import { DurableObjectOAuthClientProvider } from "./mcp/client/do-oauth-client-provider.js";
|
|
15
15
|
export { AGENT_TOOL_MILESTONE_PART, AGENT_TOOL_PROGRESS_PART, Agent, DEFAULT_AGENT_STATIC_OPTIONS, DurableObjectOAuthClientProvider, MCP_SERVER_ID_MAX_LENGTH, MessageType, SUB_PREFIX, SqlError, StreamingResponse, __DO_NOT_USE_WILL_BREAK__agentContext, withInvocationScope as __DO_NOT_USE_WILL_BREAK__withInvocationScope, buildAgentPath, buildAgentUrl, callable, camelCaseToKebabCase, createHeaderBasedEmailResolver, getAgentByName, getCurrentAgent, getSubAgentByName, isDurableObjectCodeUpdateReset, isDurableObjectMemoryLimitReset, isDurableObjectStorageReset, isPlatformTransientError, normalizeServerId, parseSubAgentPath, routeAgentEmail, routeAgentRequest, routeSubAgentRequest, unstable_callable };
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { WorkerEntrypoint } from "cloudflare:workers";
|
|
2
|
+
|
|
3
|
+
//#region src/browser/internal-hosts.d.ts
|
|
4
|
+
/** The most hostnames one browser can have. A Browser Run limit. */
|
|
5
|
+
declare const MAX_INTERNAL_HOSTS = 8;
|
|
6
|
+
/** A Standard Schema: something that validates a value. */
|
|
7
|
+
interface StandardSchemaV1<Input = unknown, Output = Input> {
|
|
8
|
+
readonly "~standard": {
|
|
9
|
+
readonly version: 1;
|
|
10
|
+
readonly vendor: string;
|
|
11
|
+
readonly validate: (
|
|
12
|
+
value: unknown
|
|
13
|
+
) => StandardSchemaResult<Output> | Promise<StandardSchemaResult<Output>>;
|
|
14
|
+
readonly types?:
|
|
15
|
+
| {
|
|
16
|
+
readonly input: Input;
|
|
17
|
+
readonly output: Output;
|
|
18
|
+
}
|
|
19
|
+
| undefined;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
type StandardSchemaResult<Output> =
|
|
23
|
+
| {
|
|
24
|
+
readonly value: Output;
|
|
25
|
+
readonly issues?: undefined;
|
|
26
|
+
}
|
|
27
|
+
| {
|
|
28
|
+
readonly issues: ReadonlyArray<{
|
|
29
|
+
readonly message: string;
|
|
30
|
+
readonly path?: ReadonlyArray<
|
|
31
|
+
| PropertyKey
|
|
32
|
+
| {
|
|
33
|
+
readonly key: PropertyKey;
|
|
34
|
+
}
|
|
35
|
+
>;
|
|
36
|
+
}>;
|
|
37
|
+
};
|
|
38
|
+
/** A Standard JSON Schema: something that can describe itself as JSON Schema. */
|
|
39
|
+
interface StandardJSONSchemaV1 {
|
|
40
|
+
readonly "~standard": {
|
|
41
|
+
readonly jsonSchema: {
|
|
42
|
+
readonly input: (options: {
|
|
43
|
+
readonly target: string;
|
|
44
|
+
}) => Record<string, unknown>;
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/** A typed schema: validates (Standard Schema) and describes itself (Standard JSON Schema). */
|
|
49
|
+
type TypedTargetSchema = StandardSchemaV1 & StandardJSONSchemaV1;
|
|
50
|
+
/** A plain JSON Schema object, such as TypeBox output or a hand-written one. */
|
|
51
|
+
type JsonSchemaObject = {
|
|
52
|
+
readonly [key: string]: unknown;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* What the model passes to `browser.assignHost()` for a host. A typed schema (zod
|
|
56
|
+
* 4.2+, ArkType, Valibot) types `fetch`'s `target`; a plain JSON Schema
|
|
57
|
+
* leaves it `unknown`.
|
|
58
|
+
*/
|
|
59
|
+
type TargetSchema = TypedTargetSchema | JsonSchemaObject;
|
|
60
|
+
/** The value a schema validates to: typed for a Standard Schema, else `unknown`. */
|
|
61
|
+
type TargetOf<S> =
|
|
62
|
+
S extends StandardSchemaV1<unknown, infer Output> ? Output : unknown;
|
|
63
|
+
/** A host served by code in your agent. */
|
|
64
|
+
interface InternalHost<S = unknown> {
|
|
65
|
+
/** Shown to the model next to the hostname. */
|
|
66
|
+
description?: string;
|
|
67
|
+
/**
|
|
68
|
+
* What the model passes to `browser.assignHost()` to point this host somewhere,
|
|
69
|
+
* as a schema. Omit it for a host that always serves the same thing.
|
|
70
|
+
*
|
|
71
|
+
* The model picks this value, so if part of it becomes a path, URL or
|
|
72
|
+
* command in `fetch`, limit it in the schema (an enum, a pattern, a range)
|
|
73
|
+
* rather than trusting it.
|
|
74
|
+
*/
|
|
75
|
+
target?: S & TargetSchema;
|
|
76
|
+
/**
|
|
77
|
+
* Serves every browser request to this hostname. Runs in your agent, with
|
|
78
|
+
* the target the model last assigned (validated by `target`), or
|
|
79
|
+
* `undefined` when the host has no `target` schema.
|
|
80
|
+
*
|
|
81
|
+
* Any http page open in the browser can send requests here, not only
|
|
82
|
+
* pages on this host: a page on another internal hostname, or an http
|
|
83
|
+
* site the guardrails allow, can POST to `http://preview.internal`. Chrome
|
|
84
|
+
* doesn't send `Sec-Fetch-*` headers to http hosts, so if a request has
|
|
85
|
+
* side effects, check that its `Origin` is this host.
|
|
86
|
+
*
|
|
87
|
+
* If it throws, the browser gets a 502 and the error is logged, not shown
|
|
88
|
+
* to the page.
|
|
89
|
+
*/
|
|
90
|
+
fetch: (request: Request, target: TargetOf<S>) => Promise<Response>;
|
|
91
|
+
worker?: never;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* A host served by a deployed Worker directly, without going through your
|
|
95
|
+
* agent: a service binding, or an entrypoint of your own Worker. Not a
|
|
96
|
+
* Dynamic Worker or Durable Object stub — Browser Run can't hold those.
|
|
97
|
+
*/
|
|
98
|
+
interface InternalWorkerHost {
|
|
99
|
+
/** Shown to the model next to the hostname. */
|
|
100
|
+
description?: string;
|
|
101
|
+
/**
|
|
102
|
+
* The Worker that serves this hostname: a service binding, or an
|
|
103
|
+
* entrypoint of your own Worker. Requests go straight to it, without
|
|
104
|
+
* waking your agent.
|
|
105
|
+
*
|
|
106
|
+
* An entrypoint passed as is (`this.ctx.exports.DocsSite`) is called with
|
|
107
|
+
* empty props; to give it props, call it yourself
|
|
108
|
+
* (`this.ctx.exports.DocsSite({ props })`). A Durable Object stub doesn't
|
|
109
|
+
* type-check: Browser Run accepts one, then resets every request.
|
|
110
|
+
*/
|
|
111
|
+
worker: Fetcher & {
|
|
112
|
+
id?: never;
|
|
113
|
+
};
|
|
114
|
+
target?: never;
|
|
115
|
+
fetch?: never;
|
|
116
|
+
}
|
|
117
|
+
/** The entrypoint loopback for {@link InternalHostRouter}: `this.ctx.exports.InternalHostRouter`. */
|
|
118
|
+
type InternalHostRouterLoopback = (init: {
|
|
119
|
+
props: InternalHostRouterProps;
|
|
120
|
+
}) => Fetcher;
|
|
121
|
+
/**
|
|
122
|
+
* `browserRun()`'s `internalHosts`: hostnames only this browser can open.
|
|
123
|
+
*
|
|
124
|
+
* Fixed when a browser starts. Adding or removing a hostname replaces the
|
|
125
|
+
* browser (the model sees `restarted`); changing a host's `fetch`,
|
|
126
|
+
* `description` or `target` doesn't. Nor does pointing a `worker` host at
|
|
127
|
+
* a different Worker: the running browser keeps the old one until it is
|
|
128
|
+
* replaced, so call `browser.close()` after such a change.
|
|
129
|
+
*/
|
|
130
|
+
interface InternalHostsOptions<S = Record<string, unknown>> {
|
|
131
|
+
/**
|
|
132
|
+
* Your Worker's {@link InternalHostRouter} export, as
|
|
133
|
+
* `this.ctx.exports.InternalHostRouter`. Needed for `fetch` hosts.
|
|
134
|
+
*/
|
|
135
|
+
router?: InternalHostRouterLoopback;
|
|
136
|
+
/**
|
|
137
|
+
* At most {@link MAX_INTERNAL_HOSTS} hostnames: bare and lowercase, no
|
|
138
|
+
* scheme, port, or path, ending in a suffix that can't be a real site:
|
|
139
|
+
* `.internal`, `.test`, `.example` or `.invalid`, like `preview.internal`.
|
|
140
|
+
*/
|
|
141
|
+
hosts: { [K in keyof S]: InternalHost<S[K]> | InternalWorkerHost };
|
|
142
|
+
}
|
|
143
|
+
/** One host, as the host API and the model see it. */
|
|
144
|
+
interface InternalHostInfo {
|
|
145
|
+
/** The hostname, such as `preview.internal`. */
|
|
146
|
+
host: string;
|
|
147
|
+
/** Where the browser opens it: `http://<host>/`. */
|
|
148
|
+
url: string;
|
|
149
|
+
description?: string;
|
|
150
|
+
/** Whether the model can point it somewhere with `browser.assignHost()`. */
|
|
151
|
+
assignable: boolean;
|
|
152
|
+
/** The JSON Schema `browser.assignHost()` checks the target against. */
|
|
153
|
+
targetSchema?: Record<string, unknown>;
|
|
154
|
+
/** The target last assigned, as assigned (before the schema transforms it). */
|
|
155
|
+
target?: unknown;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* What {@link InternalHostRouter} is given for one hostname: which agent and
|
|
159
|
+
* browser own it. Browser Run keeps these for the whole session, across
|
|
160
|
+
* redeploys, so they hold names only, never secrets or config.
|
|
161
|
+
*/
|
|
162
|
+
type InternalHostRouterProps = {
|
|
163
|
+
readonly v: 1 /** The agent's class name, as exported from the Worker. */;
|
|
164
|
+
readonly className: string /** The agent's name. */;
|
|
165
|
+
readonly name: string /** The name of the `Browser` that owns the host. */;
|
|
166
|
+
readonly browser: string /** The hostname this route serves. */;
|
|
167
|
+
readonly host: string;
|
|
168
|
+
};
|
|
169
|
+
/**
|
|
170
|
+
* One browser request to an internal hostname, as {@link InternalHostRouter}
|
|
171
|
+
* hands it to the agent's `fetchInternalHost()`.
|
|
172
|
+
*
|
|
173
|
+
* `Agent` has `fetchInternalHost()` built in. A plain Durable Object adds it
|
|
174
|
+
* and passes the message to its `Browser`:
|
|
175
|
+
*
|
|
176
|
+
* ```ts
|
|
177
|
+
* fetchInternalHost(message: InternalHostMessage) {
|
|
178
|
+
* return this.browser.fetchInternalHost(message);
|
|
179
|
+
* }
|
|
180
|
+
* ```
|
|
181
|
+
*/
|
|
182
|
+
type InternalHostMessage = {
|
|
183
|
+
/** The name of the `Browser` that owns the host. */ readonly browser: string /** The hostname, such as `preview.internal`. */;
|
|
184
|
+
readonly host: string /** The browser's request. */;
|
|
185
|
+
readonly request: Request;
|
|
186
|
+
};
|
|
187
|
+
/**
|
|
188
|
+
* Carries a browser's requests for an internal hostname to the agent that
|
|
189
|
+
* owns it. Export it from your Worker's main module, so
|
|
190
|
+
* `this.ctx.exports.InternalHostRouter` exists:
|
|
191
|
+
*
|
|
192
|
+
* ```ts
|
|
193
|
+
* export { InternalHostRouter } from "agents/browser";
|
|
194
|
+
* ```
|
|
195
|
+
*
|
|
196
|
+
* It trusts its props: Browser Run sets them from your routes, but another
|
|
197
|
+
* Worker in your account with a service binding to this entrypoint could
|
|
198
|
+
* set its own and reach any agent's hosts. That Worker could already call
|
|
199
|
+
* your agents directly, so this grants nothing new.
|
|
200
|
+
*
|
|
201
|
+
* It holds no logic of its own: it calls the agent's `fetchInternalHost()`
|
|
202
|
+
* with an {@link InternalHostMessage}, and the agent's `Browser` runs the
|
|
203
|
+
* host's `fetch`. `Agent` has `fetchInternalHost()` built in; a plain
|
|
204
|
+
* Durable Object adds it (see {@link InternalHostMessage}).
|
|
205
|
+
*
|
|
206
|
+
* @experimental The API may change before it stabilizes.
|
|
207
|
+
*/
|
|
208
|
+
declare class InternalHostRouter extends WorkerEntrypoint<
|
|
209
|
+
unknown,
|
|
210
|
+
InternalHostRouterProps
|
|
211
|
+
> {
|
|
212
|
+
fetch(request: Request): Promise<Response>;
|
|
213
|
+
}
|
|
214
|
+
//#endregion
|
|
215
|
+
export {
|
|
216
|
+
InternalHostRouterLoopback as a,
|
|
217
|
+
InternalWorkerHost as c,
|
|
218
|
+
TargetOf as d,
|
|
219
|
+
TargetSchema as f,
|
|
220
|
+
InternalHostRouter as i,
|
|
221
|
+
JsonSchemaObject as l,
|
|
222
|
+
InternalHostInfo as n,
|
|
223
|
+
InternalHostRouterProps as o,
|
|
224
|
+
TypedTargetSchema as p,
|
|
225
|
+
InternalHostMessage as r,
|
|
226
|
+
InternalHostsOptions as s,
|
|
227
|
+
InternalHost as t,
|
|
228
|
+
MAX_INTERNAL_HOSTS as u
|
|
229
|
+
};
|
|
230
|
+
//# sourceMappingURL=internal-hosts-Kfp5A392.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal-kmw70xwR.js","names":[],"sources":["../src/experimental/channels/internal.ts"],"sourcesContent":["import type {
|
|
1
|
+
{"version":3,"file":"internal-kmw70xwR.js","names":[],"sources":["../src/experimental/channels/internal.ts"],"sourcesContent":["import type { DeliveryResult, ParticipantResult } from \"./channel\";\nimport type { ChannelIngressResult } from \"./ingress\";\nimport type { Participant } from \"./protocol\";\n\nconst textEncoder = new TextEncoder();\n\nexport function encodeUtf8(value: string): Uint8Array<ArrayBuffer> {\n return textEncoder.encode(value);\n}\n\nexport function utf8ByteLength(value: string): number {\n return encodeUtf8(value).byteLength;\n}\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nexport function emptyIngressResponse<TRaw>(\n status = 200\n): ChannelIngressResult<TRaw> {\n return { events: [], response: new Response(null, { status }) };\n}\n\nexport function unsupported(\n code: string,\n message: string\n): Extract<DeliveryResult, { status: \"failed\" }> {\n return {\n status: \"failed\",\n retryable: false,\n error: { code, message }\n };\n}\n\n/** The agent object of a participant's own, namespaced so app routes cannot collide. */\nexport function participantRoute(participant: Participant): string {\n return `participant:${participant.id}`;\n}\n\n/** Check what an application's `participant` callback returned. */\nexport function toParticipant(\n result: ParticipantResult,\n source: string\n): Participant | null {\n if (result === null) return null;\n if (typeof result === \"string\") {\n if (result.length > 0) return { id: result };\n } else if (\n isRecord(result) &&\n typeof result.id === \"string\" &&\n result.id.length > 0 &&\n (result.name === undefined || typeof result.name === \"string\")\n ) {\n return result.name === undefined\n ? { id: result.id }\n : { id: result.id, name: result.name };\n }\n throw new Error(\n `${source} participant must return a non-empty id, a participant, or null`\n );\n}\n"],"mappings":";AAIA,MAAM,cAAc,IAAI,YAAY;AAEpC,SAAgB,WAAW,OAAwC;CACjE,OAAO,YAAY,OAAO,KAAK;AACjC;AAEA,SAAgB,eAAe,OAAuB;CACpD,OAAO,WAAW,KAAK,CAAC,CAAC;AAC3B;AAEA,SAAgB,SAAS,OAAkD;CACzE,OAAO,UAAU,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAgB,qBACd,SAAS,KACmB;CAC5B,OAAO;EAAE,QAAQ,CAAC;EAAG,UAAU,IAAI,SAAS,MAAM,EAAE,OAAO,CAAC;CAAE;AAChE;AAEA,SAAgB,YACd,MACA,SAC+C;CAC/C,OAAO;EACL,QAAQ;EACR,WAAW;EACX,OAAO;GAAE;GAAM;EAAQ;CACzB;AACF;;AAGA,SAAgB,iBAAiB,aAAkC;CACjE,OAAO,eAAe,YAAY;AACpC;;AAGA,SAAgB,cACd,QACA,QACoB;CACpB,IAAI,WAAW,MAAM,OAAO;CAC5B,IAAI,OAAO,WAAW;MAChB,OAAO,SAAS,GAAG,OAAO,EAAE,IAAI,OAAO;CAAA,OACtC,IACL,SAAS,MAAM,KACf,OAAO,OAAO,OAAO,YACrB,OAAO,GAAG,SAAS,MAClB,OAAO,SAAS,KAAA,KAAa,OAAO,OAAO,SAAS,WAErD,OAAO,OAAO,SAAS,KAAA,IACnB,EAAE,IAAI,OAAO,GAAG,IAChB;EAAE,IAAI,OAAO;EAAI,MAAM,OAAO;CAAK;CAEzC,MAAM,IAAI,MACR,GAAG,OAAO,gEACZ;AACF"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
//#region src/mcp/client/invoker.ts
|
|
2
|
+
function isLegacyResultSchema(value) {
|
|
3
|
+
return typeof value?.parse === "function";
|
|
4
|
+
}
|
|
5
|
+
function normalizeCallToolArguments(schemaOrOptions, options) {
|
|
6
|
+
return isLegacyResultSchema(schemaOrOptions) ? {
|
|
7
|
+
schema: schemaOrOptions,
|
|
8
|
+
options
|
|
9
|
+
} : { options: schemaOrOptions ?? options };
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Invoke SDK v2 while preserving the deprecated v1 result-schema overload.
|
|
13
|
+
* The v2 request funnel still owns decoding and automatic MRTR.
|
|
14
|
+
*/
|
|
15
|
+
function callV2Tool(client, params, schemaOrOptions, options) {
|
|
16
|
+
const normalized = normalizeCallToolArguments(schemaOrOptions, options);
|
|
17
|
+
if (normalized.schema) return client.request({
|
|
18
|
+
method: "tools/call",
|
|
19
|
+
params
|
|
20
|
+
}, normalized.schema, normalized.options);
|
|
21
|
+
return client.callTool(params, normalized.options);
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
export { normalizeCallToolArguments as n, callV2Tool as t };
|
|
25
|
+
|
|
26
|
+
//# sourceMappingURL=invoker-BC1SZ3q1.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invoker-BC1SZ3q1.js","names":[],"sources":["../src/mcp/client/invoker.ts"],"sourcesContent":["import type {\n CallToolRequest,\n CallToolRequestOptions,\n CallToolResult,\n Client\n} from \"@modelcontextprotocol/client\";\n\n/**\n * A v1 result schema such as `CallToolResultSchema` or\n * `CompatibilityCallToolResultSchema` from `@modelcontextprotocol/sdk`.\n *\n * Typed structurally so the MCP client (reachable from the root `agents`\n * entry) does not depend on `@modelcontextprotocol/sdk`, which is an optional\n * peer.\n */\nexport type LegacyCallToolResultSchema = {\n parse(data: unknown): unknown;\n};\n\nexport type CallToolSchemaOrOptions =\n | LegacyCallToolResultSchema\n | CallToolRequestOptions;\n\nfunction isLegacyResultSchema(\n value: CallToolSchemaOrOptions | undefined\n): value is LegacyCallToolResultSchema {\n return (\n typeof (value as { parse?: unknown } | undefined)?.parse === \"function\"\n );\n}\n\nexport function normalizeCallToolArguments(\n schemaOrOptions?: CallToolSchemaOrOptions,\n options?: CallToolRequestOptions\n): {\n schema?: LegacyCallToolResultSchema;\n options?: CallToolRequestOptions;\n} {\n return isLegacyResultSchema(schemaOrOptions)\n ? { schema: schemaOrOptions, options }\n : { options: schemaOrOptions ?? options };\n}\n\n/**\n * Invoke SDK v2 while preserving the deprecated v1 result-schema overload.\n * The v2 request funnel still owns decoding and automatic MRTR.\n */\nexport function callV2Tool(\n client: Client,\n params: CallToolRequest[\"params\"],\n schemaOrOptions?: CallToolSchemaOrOptions,\n options?: CallToolRequestOptions\n): Promise<CallToolResult> {\n const normalized = normalizeCallToolArguments(schemaOrOptions, options);\n if (normalized.schema) {\n return client.request(\n { method: \"tools/call\", params },\n normalized.schema as never,\n normalized.options\n ) as Promise<CallToolResult>;\n }\n return client.callTool(params, normalized.options);\n}\n"],"mappings":";AAuBA,SAAS,qBACP,OACqC;CACrC,OACE,OAAQ,OAA2C,UAAU;AAEjE;AAEA,SAAgB,2BACd,iBACA,SAIA;CACA,OAAO,qBAAqB,eAAe,IACvC;EAAE,QAAQ;EAAiB;CAAQ,IACnC,EAAE,SAAS,mBAAmB,QAAQ;AAC5C;;;;;AAMA,SAAgB,WACd,QACA,QACA,iBACA,SACyB;CACzB,MAAM,aAAa,2BAA2B,iBAAiB,OAAO;CACtE,IAAI,WAAW,QACb,OAAO,OAAO,QACZ;EAAE,QAAQ;EAAc;CAAO,GAC/B,WAAW,QACX,WAAW,OACb;CAEF,OAAO,OAAO,SAAS,QAAQ,WAAW,OAAO;AACnD"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CallToolRequest,
|
|
3
|
+
CallToolRequestOptions,
|
|
4
|
+
Client
|
|
5
|
+
} from "@modelcontextprotocol/client";
|
|
6
|
+
|
|
7
|
+
//#region src/mcp/client/invoker.d.ts
|
|
8
|
+
/**
|
|
9
|
+
* A v1 result schema such as `CallToolResultSchema` or
|
|
10
|
+
* `CompatibilityCallToolResultSchema` from `@modelcontextprotocol/sdk`.
|
|
11
|
+
*
|
|
12
|
+
* Typed structurally so the MCP client (reachable from the root `agents`
|
|
13
|
+
* entry) does not depend on `@modelcontextprotocol/sdk`, which is an optional
|
|
14
|
+
* peer.
|
|
15
|
+
*/
|
|
16
|
+
type LegacyCallToolResultSchema = {
|
|
17
|
+
parse(data: unknown): unknown;
|
|
18
|
+
};
|
|
19
|
+
//#endregion
|
|
20
|
+
export { LegacyCallToolResultSchema as t };
|
|
21
|
+
//# sourceMappingURL=invoker-DoLFPJZV.d.ts.map
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { d as err, f as ok, l as parseSkillFrontmatter, s as SkillParseError } from "./resource-B59OV2a2.js";
|
|
2
|
+
import { parse, stringify } from "yaml";
|
|
3
|
+
//#region src/skills/markdown.ts
|
|
4
|
+
/**
|
|
5
|
+
* `SKILL.md` text: YAML frontmatter between `---` lines, then Markdown.
|
|
6
|
+
* Kept apart from `./skill` because it loads the YAML parser.
|
|
7
|
+
*
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
const FRONTMATTER = /^\uFEFF?---[ \t]*\r?\n(?:([\s\S]*?)\r?\n)?---[ \t]*(?:\r?\n([\s\S]*))?$/;
|
|
11
|
+
/**
|
|
12
|
+
* Parse a `SKILL.md` file.
|
|
13
|
+
*
|
|
14
|
+
* Follows the spec's guide for agents: a skill that breaks a rule still
|
|
15
|
+
* parses, with each broken rule in `warnings`. Frontmatter that only fails
|
|
16
|
+
* because of unquoted values containing `: ` (for example
|
|
17
|
+
* `description: Use when: the user asks`), which many clients accept, is
|
|
18
|
+
* read again with those values quoted. The parse fails only when the skill
|
|
19
|
+
* cannot be used: no frontmatter, YAML that still does not parse, no
|
|
20
|
+
* description, or an unsafe name.
|
|
21
|
+
*
|
|
22
|
+
* To check a skill before storing it, require `warnings` to be empty.
|
|
23
|
+
*
|
|
24
|
+
* @param markdown - The full file: YAML frontmatter, then Markdown.
|
|
25
|
+
* @param options - `directory` to check the name against.
|
|
26
|
+
* @returns The parsed skill and warnings, or a `SkillParseError`.
|
|
27
|
+
*/
|
|
28
|
+
function parseSkill(markdown, options = {}) {
|
|
29
|
+
const match = FRONTMATTER.exec(markdown);
|
|
30
|
+
if (!match) return err(new SkillParseError("missing-frontmatter", "SKILL.md must start with YAML frontmatter between --- lines."));
|
|
31
|
+
const yaml = match[1] ?? "";
|
|
32
|
+
const body = match[2] ?? "";
|
|
33
|
+
const parsed = parseFrontmatterYaml(yaml);
|
|
34
|
+
if (parsed.ok) return parseSkillFrontmatter(parsed.value ?? {}, body, options);
|
|
35
|
+
const repaired = parseFrontmatterYaml(quoteColonValues(yaml));
|
|
36
|
+
if (!repaired.ok) return parsed;
|
|
37
|
+
const result = parseSkillFrontmatter(repaired.value ?? {}, body, options);
|
|
38
|
+
return result.ok ? {
|
|
39
|
+
...result,
|
|
40
|
+
warnings: [new SkillParseError("invalid-yaml", "SKILL.md frontmatter is not valid YAML; it was read after quoting values that contain `: `.", { cause: parsed.error.cause }), ...result.warnings]
|
|
41
|
+
} : result;
|
|
42
|
+
}
|
|
43
|
+
function parseFrontmatterYaml(yaml) {
|
|
44
|
+
try {
|
|
45
|
+
return ok(parse(yaml));
|
|
46
|
+
} catch (cause) {
|
|
47
|
+
return err(new SkillParseError("invalid-yaml", `SKILL.md frontmatter is not valid YAML: ${cause instanceof Error ? cause.message : String(cause)}`, { cause }));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Quote top-level `key: value` lines whose value contains `: `, the most
|
|
52
|
+
* common way hand-written frontmatter breaks YAML. Values that are already
|
|
53
|
+
* quoted, block scalars, or flow collections are left alone.
|
|
54
|
+
*/
|
|
55
|
+
function quoteColonValues(yaml) {
|
|
56
|
+
return yaml.split(/\r?\n/).map((line) => {
|
|
57
|
+
const match = /^([A-Za-z0-9_-]+):[ \t]+(.+)$/.exec(line);
|
|
58
|
+
if (!match) return line;
|
|
59
|
+
const [, key, value] = match;
|
|
60
|
+
if (value === void 0 || !value.includes(": ")) return line;
|
|
61
|
+
if (/^["'|>[{&*!]/.test(value)) return line;
|
|
62
|
+
return `${key}: ${JSON.stringify(value.trim())}`;
|
|
63
|
+
}).join("\n");
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Render a skill back to `SKILL.md` text.
|
|
67
|
+
*
|
|
68
|
+
* @param skill - The parsed skill.
|
|
69
|
+
* @returns Frontmatter and body that {@link parseSkill} reads back to an
|
|
70
|
+
* equal skill.
|
|
71
|
+
*/
|
|
72
|
+
function formatSkill(skill) {
|
|
73
|
+
return `---\n${stringify({
|
|
74
|
+
name: skill.name,
|
|
75
|
+
description: skill.description,
|
|
76
|
+
...skill.license === void 0 ? {} : { license: skill.license },
|
|
77
|
+
...skill.compatibility === void 0 ? {} : { compatibility: skill.compatibility },
|
|
78
|
+
...Object.keys(skill.metadata).length === 0 ? {} : { metadata: skill.metadata },
|
|
79
|
+
...skill.allowedTools.length === 0 ? {} : { "allowed-tools": skill.allowedTools.join(" ") },
|
|
80
|
+
...skill.extraFields
|
|
81
|
+
}).trimEnd()}\n---\n${skill.body}`;
|
|
82
|
+
}
|
|
83
|
+
//#endregion
|
|
84
|
+
export { parseSkill as n, formatSkill as t };
|
|
85
|
+
|
|
86
|
+
//# sourceMappingURL=markdown-BZ-VLtA1.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown-BZ-VLtA1.js","names":["parseYaml","stringifyYaml"],"sources":["../src/skills/markdown.ts"],"sourcesContent":["import { parse as parseYaml, stringify as stringifyYaml } from \"yaml\";\nimport { err, ok, type SkillResult } from \"./result\";\nimport {\n parseSkillFrontmatter,\n SkillParseError,\n type ParseSkillOptions,\n type Skill,\n type SkillParseResult\n} from \"./skill\";\n\n/**\n * `SKILL.md` text: YAML frontmatter between `---` lines, then Markdown.\n * Kept apart from `./skill` because it loads the YAML parser.\n *\n * @module\n */\n\nconst FRONTMATTER =\n /^\\uFEFF?---[ \\t]*\\r?\\n(?:([\\s\\S]*?)\\r?\\n)?---[ \\t]*(?:\\r?\\n([\\s\\S]*))?$/;\n\n/**\n * Parse a `SKILL.md` file.\n *\n * Follows the spec's guide for agents: a skill that breaks a rule still\n * parses, with each broken rule in `warnings`. Frontmatter that only fails\n * because of unquoted values containing `: ` (for example\n * `description: Use when: the user asks`), which many clients accept, is\n * read again with those values quoted. The parse fails only when the skill\n * cannot be used: no frontmatter, YAML that still does not parse, no\n * description, or an unsafe name.\n *\n * To check a skill before storing it, require `warnings` to be empty.\n *\n * @param markdown - The full file: YAML frontmatter, then Markdown.\n * @param options - `directory` to check the name against.\n * @returns The parsed skill and warnings, or a `SkillParseError`.\n */\nexport function parseSkill(\n markdown: string,\n options: ParseSkillOptions = {}\n): SkillParseResult {\n const match = FRONTMATTER.exec(markdown);\n if (!match) {\n return err(\n new SkillParseError(\n \"missing-frontmatter\",\n \"SKILL.md must start with YAML frontmatter between --- lines.\"\n )\n );\n }\n\n const yaml = match[1] ?? \"\";\n const body = match[2] ?? \"\";\n const parsed = parseFrontmatterYaml(yaml);\n if (parsed.ok) {\n return parseSkillFrontmatter(parsed.value ?? {}, body, options);\n }\n const repaired = parseFrontmatterYaml(quoteColonValues(yaml));\n if (!repaired.ok) return parsed;\n const result = parseSkillFrontmatter(repaired.value ?? {}, body, options);\n return result.ok\n ? {\n ...result,\n warnings: [\n new SkillParseError(\n \"invalid-yaml\",\n \"SKILL.md frontmatter is not valid YAML; it was read after quoting values that contain `: `.\",\n { cause: parsed.error.cause }\n ),\n ...result.warnings\n ]\n }\n : result;\n}\n\nfunction parseFrontmatterYaml(\n yaml: string\n): SkillResult<unknown, SkillParseError> {\n try {\n return ok(parseYaml(yaml));\n } catch (cause) {\n return err(\n new SkillParseError(\n \"invalid-yaml\",\n `SKILL.md frontmatter is not valid YAML: ${cause instanceof Error ? cause.message : String(cause)}`,\n { cause }\n )\n );\n }\n}\n\n/**\n * Quote top-level `key: value` lines whose value contains `: `, the most\n * common way hand-written frontmatter breaks YAML. Values that are already\n * quoted, block scalars, or flow collections are left alone.\n */\nfunction quoteColonValues(yaml: string): string {\n return yaml\n .split(/\\r?\\n/)\n .map((line) => {\n const match = /^([A-Za-z0-9_-]+):[ \\t]+(.+)$/.exec(line);\n if (!match) return line;\n const [, key, value] = match;\n if (value === undefined || !value.includes(\": \")) return line;\n if (/^[\"'|>[{&*!]/.test(value)) return line;\n return `${key}: ${JSON.stringify(value.trim())}`;\n })\n .join(\"\\n\");\n}\n\n/**\n * Render a skill back to `SKILL.md` text.\n *\n * @param skill - The parsed skill.\n * @returns Frontmatter and body that {@link parseSkill} reads back to an\n * equal skill.\n */\nexport function formatSkill(skill: Skill): string {\n const frontmatter: Record<string, unknown> = {\n name: skill.name,\n description: skill.description,\n ...(skill.license === undefined ? {} : { license: skill.license }),\n ...(skill.compatibility === undefined\n ? {}\n : { compatibility: skill.compatibility }),\n ...(Object.keys(skill.metadata).length === 0\n ? {}\n : { metadata: skill.metadata }),\n ...(skill.allowedTools.length === 0\n ? {}\n : { \"allowed-tools\": skill.allowedTools.join(\" \") }),\n ...skill.extraFields\n };\n return `---\\n${stringifyYaml(frontmatter).trimEnd()}\\n---\\n${skill.body}`;\n}\n"],"mappings":";;;;;;;;;AAiBA,MAAM,cACJ;;;;;;;;;;;;;;;;;;AAmBF,SAAgB,WACd,UACA,UAA6B,CAAC,GACZ;CAClB,MAAM,QAAQ,YAAY,KAAK,QAAQ;CACvC,IAAI,CAAC,OACH,OAAO,IACL,IAAI,gBACF,uBACA,8DACF,CACF;CAGF,MAAM,OAAO,MAAM,MAAM;CACzB,MAAM,OAAO,MAAM,MAAM;CACzB,MAAM,SAAS,qBAAqB,IAAI;CACxC,IAAI,OAAO,IACT,OAAO,sBAAsB,OAAO,SAAS,CAAC,GAAG,MAAM,OAAO;CAEhE,MAAM,WAAW,qBAAqB,iBAAiB,IAAI,CAAC;CAC5D,IAAI,CAAC,SAAS,IAAI,OAAO;CACzB,MAAM,SAAS,sBAAsB,SAAS,SAAS,CAAC,GAAG,MAAM,OAAO;CACxE,OAAO,OAAO,KACV;EACE,GAAG;EACH,UAAU,CACR,IAAI,gBACF,gBACA,+FACA,EAAE,OAAO,OAAO,MAAM,MAAM,CAC9B,GACA,GAAG,OAAO,QACZ;CACF,IACA;AACN;AAEA,SAAS,qBACP,MACuC;CACvC,IAAI;EACF,OAAO,GAAGA,MAAU,IAAI,CAAC;CAC3B,SAAS,OAAO;EACd,OAAO,IACL,IAAI,gBACF,gBACA,2CAA2C,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,KAChG,EAAE,MAAM,CACV,CACF;CACF;AACF;;;;;;AAOA,SAAS,iBAAiB,MAAsB;CAC9C,OAAO,KACJ,MAAM,OAAO,CAAC,CACd,KAAK,SAAS;EACb,MAAM,QAAQ,gCAAgC,KAAK,IAAI;EACvD,IAAI,CAAC,OAAO,OAAO;EACnB,MAAM,GAAG,KAAK,SAAS;EACvB,IAAI,UAAU,KAAA,KAAa,CAAC,MAAM,SAAS,IAAI,GAAG,OAAO;EACzD,IAAI,eAAe,KAAK,KAAK,GAAG,OAAO;EACvC,OAAO,GAAG,IAAI,IAAI,KAAK,UAAU,MAAM,KAAK,CAAC;CAC/C,CAAC,CAAC,CACD,KAAK,IAAI;AACd;;;;;;;;AASA,SAAgB,YAAY,OAAsB;CAgBhD,OAAO,QAAQC,UAAc;EAd3B,MAAM,MAAM;EACZ,aAAa,MAAM;EACnB,GAAI,MAAM,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,SAAS,MAAM,QAAQ;EAChE,GAAI,MAAM,kBAAkB,KAAA,IACxB,CAAC,IACD,EAAE,eAAe,MAAM,cAAc;EACzC,GAAI,OAAO,KAAK,MAAM,QAAQ,CAAC,CAAC,WAAW,IACvC,CAAC,IACD,EAAE,UAAU,MAAM,SAAS;EAC/B,GAAI,MAAM,aAAa,WAAW,IAC9B,CAAC,IACD,EAAE,iBAAiB,MAAM,aAAa,KAAK,GAAG,EAAE;EACpD,GAAG,MAAM;CAE4B,CAAC,CAAC,CAAC,QAAQ,EAAE,SAAS,MAAM;AACrE"}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
|
+
i as DurableObjectOAuthClientProviderOptions,
|
|
2
3
|
n as AgentsOAuthProvider,
|
|
3
4
|
r as DurableObjectOAuthClientProvider,
|
|
4
5
|
t as AgentMcpOAuthProvider
|
|
5
|
-
} from "../../do-oauth-client-provider-
|
|
6
|
+
} from "../../do-oauth-client-provider-DtNqv7oj.js";
|
|
6
7
|
export {
|
|
7
8
|
AgentMcpOAuthProvider,
|
|
8
9
|
AgentsOAuthProvider,
|
|
9
|
-
DurableObjectOAuthClientProvider
|
|
10
|
+
DurableObjectOAuthClientProvider,
|
|
11
|
+
DurableObjectOAuthClientProviderOptions
|
|
10
12
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
2
|
import { nanoid } from "nanoid";
|
|
3
|
+
import { validateClientMetadataUrl } from "@modelcontextprotocol/client";
|
|
3
4
|
//#region src/mcp/client/do-oauth-client-provider.ts
|
|
4
5
|
const STATE_EXPIRATION_MS = 600 * 1e3;
|
|
5
6
|
const codeVerifierStateStorage = new AsyncLocalStorage();
|
|
@@ -26,11 +27,24 @@ function isExpired(createdAt) {
|
|
|
26
27
|
return Date.now() - createdAt > STATE_EXPIRATION_MS;
|
|
27
28
|
}
|
|
28
29
|
var DurableObjectOAuthClientProvider = class {
|
|
29
|
-
constructor(storage, clientName, baseRedirectUrl) {
|
|
30
|
+
constructor(storage, clientName, baseRedirectUrl, options = {}) {
|
|
30
31
|
this.storage = storage;
|
|
31
32
|
this.clientName = clientName;
|
|
32
33
|
this.baseRedirectUrl = baseRedirectUrl;
|
|
33
34
|
if (!storage) throw new Error("DurableObjectOAuthClientProvider requires a valid DurableObjectStorage instance");
|
|
35
|
+
validateClientMetadataUrl(options.clientMetadataUrl);
|
|
36
|
+
this.clientMetadataUrl = options.clientMetadataUrl || void 0;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* The Client ID Metadata Document to serve at `clientMetadataUrl`.
|
|
40
|
+
* Throws when the provider has no `clientMetadataUrl`.
|
|
41
|
+
*/
|
|
42
|
+
get clientMetadataDocument() {
|
|
43
|
+
if (!this.clientMetadataUrl) throw new Error("clientMetadataDocument requires a clientMetadataUrl option");
|
|
44
|
+
return {
|
|
45
|
+
client_id: this.clientMetadataUrl,
|
|
46
|
+
...this.clientMetadata
|
|
47
|
+
};
|
|
34
48
|
}
|
|
35
49
|
get clientMetadata() {
|
|
36
50
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"do-oauth-client-provider.js","names":[],"sources":["../../../src/mcp/client/do-oauth-client-provider.ts"],"sourcesContent":["import type {\n OAuthClientInformationContext,\n OAuthClientMetadata,\n OAuthClientProvider,\n OAuthDiscoveryState,\n StoredOAuthClientInformation,\n StoredOAuthTokens\n} from \"@modelcontextprotocol/client\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { nanoid } from \"nanoid\";\n\nconst STATE_EXPIRATION_MS = 10 * 60 * 1000; // 10 minutes\n\nconst codeVerifierStateStorage = new AsyncLocalStorage<{\n state: string;\n servedKey?: string;\n}>();\n\ninterface StoredState {\n nonce: string;\n serverId: string;\n createdAt: number;\n}\n\ninterface StoredCodeVerifier {\n verifier: string;\n createdAt: number;\n}\n\n// A slight extension to the standard OAuthClientProvider interface because `redirectToAuthorization` doesn't give us the interface we need\n// This allows us to track authentication for a specific server and associated dynamic client registration\nexport interface AgentMcpOAuthProvider extends OAuthClientProvider {\n authUrl: string | undefined;\n clientId: string | undefined;\n serverId: string | undefined;\n checkState(\n state: string\n ): Promise<{ valid: boolean; serverId?: string; error?: string }>;\n consumeState(state: string): Promise<void>;\n runWithCodeVerifierState?<T>(\n state: string,\n callback: () => Promise<T>\n ): Promise<T>;\n deleteCodeVerifier(): Promise<void>;\n}\n\nfunction parseOAuthState(\n state: string\n): { nonce: string; serverId: string } | undefined {\n const parts = state.split(\".\");\n if (parts.length !== 2) {\n return undefined;\n }\n\n const [nonce, serverId] = parts;\n if (!nonce || !serverId) {\n return undefined;\n }\n\n return { nonce, serverId };\n}\n\nfunction base64UrlEncode(bytes: Uint8Array): string {\n let binary = \"\";\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n return btoa(binary)\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/, \"\");\n}\n\nasync function createCodeChallenge(verifier: string): Promise<string> {\n const digest = await crypto.subtle.digest(\n \"SHA-256\",\n new TextEncoder().encode(verifier)\n );\n return base64UrlEncode(new Uint8Array(digest));\n}\n\nfunction isExpired(createdAt: number): boolean {\n return Date.now() - createdAt > STATE_EXPIRATION_MS;\n}\n\n/**\n * @deprecated Use {@link AgentMcpOAuthProvider} instead.\n */\nexport type AgentsOAuthProvider = AgentMcpOAuthProvider;\n\nexport class DurableObjectOAuthClientProvider implements AgentMcpOAuthProvider {\n private _authUrl_: string | undefined;\n private _serverId_: string | undefined;\n private _clientId_: string | undefined;\n\n constructor(\n public storage: DurableObjectStorage,\n public clientName: string,\n public baseRedirectUrl: string\n ) {\n if (!storage) {\n throw new Error(\n \"DurableObjectOAuthClientProvider requires a valid DurableObjectStorage instance\"\n );\n }\n }\n\n get clientMetadata(): OAuthClientMetadata {\n return {\n client_name: this.clientName,\n client_uri: this.clientUri,\n grant_types: [\"authorization_code\", \"refresh_token\"],\n redirect_uris: [this.redirectUrl],\n response_types: [\"code\"],\n token_endpoint_auth_method: \"none\"\n };\n }\n\n get clientUri() {\n return new URL(this.redirectUrl).origin;\n }\n\n get redirectUrl() {\n return this.baseRedirectUrl;\n }\n\n get clientId() {\n if (!this._clientId_) {\n throw new Error(\"Trying to access clientId before it was set\");\n }\n return this._clientId_;\n }\n\n set clientId(clientId_: string) {\n this._clientId_ = clientId_;\n }\n\n get serverId() {\n if (!this._serverId_) {\n throw new Error(\"Trying to access serverId before it was set\");\n }\n return this._serverId_;\n }\n\n set serverId(serverId_: string) {\n this._serverId_ = serverId_;\n }\n\n keyPrefix(clientId: string) {\n return `/${this.clientName}/${this.serverId}/${clientId}`;\n }\n\n clientInfoKey(clientId: string) {\n return `${this.keyPrefix(clientId)}/client_info/`;\n }\n\n discoveryStateKey() {\n return `/${this.clientName}/${this.serverId}/oauth_discovery`;\n }\n\n async saveDiscoveryState(state: OAuthDiscoveryState): Promise<void> {\n await this.storage.put(this.discoveryStateKey(), state);\n }\n\n async discoveryState(): Promise<OAuthDiscoveryState | undefined> {\n return (\n (await this.storage.get<OAuthDiscoveryState>(this.discoveryStateKey())) ??\n undefined\n );\n }\n\n async clientInformation(\n _context?: OAuthClientInformationContext\n ): Promise<StoredOAuthClientInformation | undefined> {\n if (!this._clientId_) return undefined;\n return (\n (await this.storage.get<StoredOAuthClientInformation>(\n this.clientInfoKey(this.clientId)\n )) ?? undefined\n );\n }\n\n async saveClientInformation(\n clientInformation: StoredOAuthClientInformation,\n _context?: OAuthClientInformationContext\n ): Promise<void> {\n this.clientId = clientInformation.client_id;\n // Round-trip the SDK's issuer stamp verbatim. The SDK treats a credential\n // stamped for another issuer as absent, so one durable slot per MCP server\n // is both sufficient and safer than maintaining our own issuer index.\n await this.storage.put(\n this.clientInfoKey(clientInformation.client_id),\n clientInformation\n );\n }\n\n tokenKey(clientId: string) {\n return `${this.keyPrefix(clientId)}/token`;\n }\n\n async tokens(\n _context?: OAuthClientInformationContext\n ): Promise<StoredOAuthTokens | undefined> {\n if (!this._clientId_) return undefined;\n return (\n (await this.storage.get<StoredOAuthTokens>(\n this.tokenKey(this.clientId)\n )) ?? undefined\n );\n }\n\n async saveTokens(\n tokens: StoredOAuthTokens,\n _context?: OAuthClientInformationContext\n ): Promise<void> {\n // Keep the SDK-owned issuer stamp intact for SEP-2352 validation. Discovery\n // is needed across the browser redirect, but once token issuance succeeds\n // it must not pin later re-authorization to this AS: a subsequent 401 must\n // re-read PRM so an authorization-server migration can be observed.\n await this.storage.put(this.tokenKey(this.clientId), tokens);\n await this.storage.delete(this.discoveryStateKey());\n }\n\n get authUrl() {\n return this._authUrl_;\n }\n\n stateKey(nonce: string) {\n return `/${this.clientName}/${this.serverId}/state/${nonce}`;\n }\n\n async state(): Promise<string> {\n const nonce = nanoid();\n const state = `${nonce}.${this.serverId}`;\n const storedState: StoredState = {\n nonce,\n serverId: this.serverId,\n createdAt: Date.now()\n };\n await this.storage.put(this.stateKey(nonce), storedState);\n return state;\n }\n\n async checkState(\n state: string\n ): Promise<{ valid: boolean; serverId?: string; error?: string }> {\n const parsed = parseOAuthState(state);\n if (!parsed) {\n return { valid: false, error: \"Invalid state format\" };\n }\n\n const { nonce, serverId } = parsed;\n const key = this.stateKey(nonce);\n const storedState = await this.storage.get<StoredState>(key);\n\n if (!storedState) {\n return { valid: false, error: \"State not found or already used\" };\n }\n\n if (storedState.serverId !== serverId) {\n await this.storage.delete(key);\n return { valid: false, error: \"State serverId mismatch\" };\n }\n\n if (isExpired(storedState.createdAt)) {\n const deleteKeys = [key];\n if (this._clientId_) {\n deleteKeys.push(this.stateCodeVerifierKey(this.clientId, nonce));\n }\n await this.storage.delete(deleteKeys);\n return { valid: false, error: \"State expired\" };\n }\n\n return { valid: true, serverId };\n }\n\n async consumeState(state: string): Promise<void> {\n const parsed = parseOAuthState(state);\n if (!parsed) {\n // This should never happen since checkState validates format first.\n // Log for debugging but don't throw - state consumption is best-effort.\n console.warn(`[OAuth] consumeState called with invalid state format`);\n return;\n }\n await this.storage.delete(this.stateKey(parsed.nonce));\n }\n\n async redirectToAuthorization(authUrl: URL): Promise<void> {\n this._authUrl_ = authUrl.toString();\n\n const clientId = this._clientId_;\n const serverId = this._serverId_;\n if (!clientId || !serverId) {\n return;\n }\n\n const state = authUrl.searchParams.get(\"state\");\n const codeChallenge = authUrl.searchParams.get(\"code_challenge\");\n if (!state || !codeChallenge) {\n return;\n }\n\n const parsed = parseOAuthState(state);\n if (!parsed || parsed.serverId !== serverId) {\n return;\n }\n\n const challengeKey = this.challengeCodeVerifierKey(clientId, codeChallenge);\n const pendingVerifier =\n await this.storage.get<StoredCodeVerifier>(challengeKey);\n if (!pendingVerifier) {\n return;\n }\n\n if (isExpired(pendingVerifier.createdAt)) {\n await this.storage.delete(challengeKey);\n return;\n }\n\n await this.storage.put(\n this.stateCodeVerifierKey(clientId, parsed.nonce),\n pendingVerifier\n );\n await this.storage.delete(challengeKey);\n }\n\n async invalidateCredentials(\n scope: \"all\" | \"client\" | \"tokens\" | \"verifier\" | \"discovery\"\n ): Promise<void> {\n const deleteKeys: string[] = [];\n\n if (scope === \"all\" || scope === \"discovery\") {\n deleteKeys.push(this.discoveryStateKey());\n }\n\n if (this._clientId_) {\n const clientId = this.clientId;\n if (scope === \"all\" || scope === \"client\") {\n deleteKeys.push(this.clientInfoKey(clientId));\n }\n if (scope === \"all\" || scope === \"tokens\") {\n deleteKeys.push(this.tokenKey(clientId));\n }\n if (scope === \"all\" || scope === \"verifier\") {\n deleteKeys.push(\n ...(await this.codeVerifierKeys(clientId, {\n includeChallengeKeys: true\n }))\n );\n }\n }\n\n if (deleteKeys.length > 0) {\n await this.storage.delete([...new Set(deleteKeys)]);\n }\n }\n\n /**\n * Delete every key this provider stores for its server: tokens and client\n * info for any client ID, verifiers, pending states and discovery state.\n * Used when the server is removed. Other servers' keys are untouched.\n */\n async clearServerStorage(): Promise<void> {\n const keys = [\n ...(\n await this.storage.list({\n prefix: `/${this.clientName}/${this.serverId}/`\n })\n ).keys()\n ];\n // DO storage caps a multi-key delete at 128 keys.\n for (let i = 0; i < keys.length; i += 128) {\n await this.storage.delete(keys.slice(i, i + 128));\n }\n }\n\n codeVerifierKey(clientId: string) {\n return `${this.keyPrefix(clientId)}/code_verifier`;\n }\n\n stateCodeVerifierPrefix(clientId: string) {\n return `${this.keyPrefix(clientId)}/code_verifier/`;\n }\n\n stateCodeVerifierKey(clientId: string, nonce: string) {\n return `${this.stateCodeVerifierPrefix(clientId)}${nonce}`;\n }\n\n challengeCodeVerifierPrefix(clientId: string) {\n return `${this.keyPrefix(clientId)}/code_verifier_challenge/`;\n }\n\n challengeCodeVerifierKey(clientId: string, codeChallenge: string) {\n return `${this.challengeCodeVerifierPrefix(clientId)}${codeChallenge}`;\n }\n\n async codeVerifierKeys(\n clientId: string,\n options: { includeChallengeKeys?: boolean } = {}\n ): Promise<string[]> {\n const legacyKey = this.codeVerifierKey(clientId);\n const keys: string[] = [];\n\n if (await this.storage.get(legacyKey)) {\n keys.push(legacyKey);\n }\n\n const stateKeys = await this.storage.list({\n prefix: this.stateCodeVerifierPrefix(clientId)\n });\n keys.push(...stateKeys.keys());\n\n if (options.includeChallengeKeys) {\n const challengeKeys = await this.storage.list({\n prefix: this.challengeCodeVerifierPrefix(clientId)\n });\n keys.push(...challengeKeys.keys());\n }\n\n return keys;\n }\n\n async saveCodeVerifier(verifier: string): Promise<void> {\n await this.deleteExpiredChallengeCodeVerifiers(this.clientId);\n\n const codeChallenge = await createCodeChallenge(verifier);\n const storedVerifier: StoredCodeVerifier = {\n verifier,\n createdAt: Date.now()\n };\n\n await this.storage.put(\n this.challengeCodeVerifierKey(this.clientId, codeChallenge),\n storedVerifier\n );\n }\n\n private async deleteExpiredChallengeCodeVerifiers(\n clientId: string\n ): Promise<void> {\n const challengeVerifiers = await this.storage.list<StoredCodeVerifier>({\n prefix: this.challengeCodeVerifierPrefix(clientId)\n });\n const expiredKeys = [...challengeVerifiers.entries()]\n .filter(([, storedVerifier]) => isExpired(storedVerifier.createdAt))\n .map(([key]) => key);\n if (expiredKeys.length > 0) {\n await this.storage.delete(expiredKeys);\n }\n }\n\n async codeVerifier(): Promise<string> {\n const context = codeVerifierStateStorage.getStore();\n if (context) {\n const stateVerifier = await this.codeVerifierForState(context.state);\n if (stateVerifier) {\n context.servedKey = stateVerifier.key;\n return stateVerifier.verifier;\n }\n }\n\n const legacyVerifier = await this.storage.get<string>(\n this.codeVerifierKey(this.clientId)\n );\n if (legacyVerifier) {\n if (context) {\n context.servedKey = this.codeVerifierKey(this.clientId);\n }\n return legacyVerifier;\n }\n\n if (context) {\n throw new Error(\"No code verifier found for OAuth state\");\n }\n\n const pendingVerifiers = await this.storage.list<StoredCodeVerifier>({\n prefix: this.stateCodeVerifierPrefix(this.clientId)\n });\n const unexpiredPendingVerifiers = [...pendingVerifiers.entries()].filter(\n ([, storedVerifier]) => !isExpired(storedVerifier.createdAt)\n );\n const expiredKeys = [...pendingVerifiers.entries()]\n .filter(([, storedVerifier]) => isExpired(storedVerifier.createdAt))\n .map(([key]) => key);\n if (expiredKeys.length > 0) {\n await this.storage.delete(expiredKeys);\n }\n\n if (unexpiredPendingVerifiers.length === 1) {\n const [[, storedVerifier]] = unexpiredPendingVerifiers;\n return storedVerifier.verifier;\n }\n\n if (unexpiredPendingVerifiers.length > 1) {\n throw new Error(\n \"Multiple OAuth code verifiers are pending; complete authorization with the callback state\"\n );\n }\n\n throw new Error(\"No code verifier found\");\n }\n\n private async codeVerifierForState(\n state: string\n ): Promise<{ key: string; verifier: string } | undefined> {\n const parsed = parseOAuthState(state);\n if (!parsed) {\n throw new Error(\"Invalid state format\");\n }\n\n const key = this.stateCodeVerifierKey(this.clientId, parsed.nonce);\n const storedVerifier = await this.storage.get<StoredCodeVerifier>(key);\n if (!storedVerifier) {\n return undefined;\n }\n\n if (isExpired(storedVerifier.createdAt)) {\n await this.storage.delete(key);\n throw new Error(\"Code verifier expired\");\n }\n\n return { key, verifier: storedVerifier.verifier };\n }\n\n async runWithCodeVerifierState<T>(\n state: string,\n callback: () => Promise<T>\n ): Promise<T> {\n return codeVerifierStateStorage.run({ state }, callback);\n }\n\n async deleteCodeVerifier(): Promise<void> {\n const context = codeVerifierStateStorage.getStore();\n if (context?.servedKey) {\n await this.storage.delete(context.servedKey);\n return;\n }\n\n if (context) {\n const parsed = parseOAuthState(context.state);\n if (parsed) {\n await this.storage.delete(\n this.stateCodeVerifierKey(this.clientId, parsed.nonce)\n );\n return;\n }\n }\n\n const keys = await this.codeVerifierKeys(this.clientId);\n if (keys.length > 0) {\n await this.storage.delete(keys);\n }\n }\n}\n"],"mappings":";;;AAWA,MAAM,sBAAsB,MAAU;AAEtC,MAAM,2BAA2B,IAAI,kBAGlC;AA8BH,SAAS,gBACP,OACiD;CACjD,MAAM,QAAQ,MAAM,MAAM,GAAG;CAC7B,IAAI,MAAM,WAAW,GACnB;CAGF,MAAM,CAAC,OAAO,YAAY;CAC1B,IAAI,CAAC,SAAS,CAAC,UACb;CAGF,OAAO;EAAE;EAAO;CAAS;AAC3B;AAEA,SAAS,gBAAgB,OAA2B;CAClD,IAAI,SAAS;CACb,KAAK,MAAM,QAAQ,OACjB,UAAU,OAAO,aAAa,IAAI;CAEpC,OAAO,KAAK,MAAM,CAAC,CAChB,QAAQ,OAAO,GAAG,CAAC,CACnB,QAAQ,OAAO,GAAG,CAAC,CACnB,QAAQ,OAAO,EAAE;AACtB;AAEA,eAAe,oBAAoB,UAAmC;CACpE,MAAM,SAAS,MAAM,OAAO,OAAO,OACjC,WACA,IAAI,YAAY,CAAC,CAAC,OAAO,QAAQ,CACnC;CACA,OAAO,gBAAgB,IAAI,WAAW,MAAM,CAAC;AAC/C;AAEA,SAAS,UAAU,WAA4B;CAC7C,OAAO,KAAK,IAAI,IAAI,YAAY;AAClC;AAOA,IAAa,mCAAb,MAA+E;CAK7E,YACE,SACA,YACA,iBACA;EAHO,KAAA,UAAA;EACA,KAAA,aAAA;EACA,KAAA,kBAAA;EAEP,IAAI,CAAC,SACH,MAAM,IAAI,MACR,iFACF;CAEJ;CAEA,IAAI,iBAAsC;EACxC,OAAO;GACL,aAAa,KAAK;GAClB,YAAY,KAAK;GACjB,aAAa,CAAC,sBAAsB,eAAe;GACnD,eAAe,CAAC,KAAK,WAAW;GAChC,gBAAgB,CAAC,MAAM;GACvB,4BAA4B;EAC9B;CACF;CAEA,IAAI,YAAY;EACd,OAAO,IAAI,IAAI,KAAK,WAAW,CAAC,CAAC;CACnC;CAEA,IAAI,cAAc;EAChB,OAAO,KAAK;CACd;CAEA,IAAI,WAAW;EACb,IAAI,CAAC,KAAK,YACR,MAAM,IAAI,MAAM,6CAA6C;EAE/D,OAAO,KAAK;CACd;CAEA,IAAI,SAAS,WAAmB;EAC9B,KAAK,aAAa;CACpB;CAEA,IAAI,WAAW;EACb,IAAI,CAAC,KAAK,YACR,MAAM,IAAI,MAAM,6CAA6C;EAE/D,OAAO,KAAK;CACd;CAEA,IAAI,SAAS,WAAmB;EAC9B,KAAK,aAAa;CACpB;CAEA,UAAU,UAAkB;EAC1B,OAAO,IAAI,KAAK,WAAW,GAAG,KAAK,SAAS,GAAG;CACjD;CAEA,cAAc,UAAkB;EAC9B,OAAO,GAAG,KAAK,UAAU,QAAQ,EAAE;CACrC;CAEA,oBAAoB;EAClB,OAAO,IAAI,KAAK,WAAW,GAAG,KAAK,SAAS;CAC9C;CAEA,MAAM,mBAAmB,OAA2C;EAClE,MAAM,KAAK,QAAQ,IAAI,KAAK,kBAAkB,GAAG,KAAK;CACxD;CAEA,MAAM,iBAA2D;EAC/D,OACG,MAAM,KAAK,QAAQ,IAAyB,KAAK,kBAAkB,CAAC,KACrE,KAAA;CAEJ;CAEA,MAAM,kBACJ,UACmD;EACnD,IAAI,CAAC,KAAK,YAAY,OAAO,KAAA;EAC7B,OACG,MAAM,KAAK,QAAQ,IAClB,KAAK,cAAc,KAAK,QAAQ,CAClC,KAAM,KAAA;CAEV;CAEA,MAAM,sBACJ,mBACA,UACe;EACf,KAAK,WAAW,kBAAkB;EAIlC,MAAM,KAAK,QAAQ,IACjB,KAAK,cAAc,kBAAkB,SAAS,GAC9C,iBACF;CACF;CAEA,SAAS,UAAkB;EACzB,OAAO,GAAG,KAAK,UAAU,QAAQ,EAAE;CACrC;CAEA,MAAM,OACJ,UACwC;EACxC,IAAI,CAAC,KAAK,YAAY,OAAO,KAAA;EAC7B,OACG,MAAM,KAAK,QAAQ,IAClB,KAAK,SAAS,KAAK,QAAQ,CAC7B,KAAM,KAAA;CAEV;CAEA,MAAM,WACJ,QACA,UACe;EAKf,MAAM,KAAK,QAAQ,IAAI,KAAK,SAAS,KAAK,QAAQ,GAAG,MAAM;EAC3D,MAAM,KAAK,QAAQ,OAAO,KAAK,kBAAkB,CAAC;CACpD;CAEA,IAAI,UAAU;EACZ,OAAO,KAAK;CACd;CAEA,SAAS,OAAe;EACtB,OAAO,IAAI,KAAK,WAAW,GAAG,KAAK,SAAS,SAAS;CACvD;CAEA,MAAM,QAAyB;EAC7B,MAAM,QAAQ,OAAO;EACrB,MAAM,QAAQ,GAAG,MAAM,GAAG,KAAK;EAC/B,MAAM,cAA2B;GAC/B;GACA,UAAU,KAAK;GACf,WAAW,KAAK,IAAI;EACtB;EACA,MAAM,KAAK,QAAQ,IAAI,KAAK,SAAS,KAAK,GAAG,WAAW;EACxD,OAAO;CACT;CAEA,MAAM,WACJ,OACgE;EAChE,MAAM,SAAS,gBAAgB,KAAK;EACpC,IAAI,CAAC,QACH,OAAO;GAAE,OAAO;GAAO,OAAO;EAAuB;EAGvD,MAAM,EAAE,OAAO,aAAa;EAC5B,MAAM,MAAM,KAAK,SAAS,KAAK;EAC/B,MAAM,cAAc,MAAM,KAAK,QAAQ,IAAiB,GAAG;EAE3D,IAAI,CAAC,aACH,OAAO;GAAE,OAAO;GAAO,OAAO;EAAkC;EAGlE,IAAI,YAAY,aAAa,UAAU;GACrC,MAAM,KAAK,QAAQ,OAAO,GAAG;GAC7B,OAAO;IAAE,OAAO;IAAO,OAAO;GAA0B;EAC1D;EAEA,IAAI,UAAU,YAAY,SAAS,GAAG;GACpC,MAAM,aAAa,CAAC,GAAG;GACvB,IAAI,KAAK,YACP,WAAW,KAAK,KAAK,qBAAqB,KAAK,UAAU,KAAK,CAAC;GAEjE,MAAM,KAAK,QAAQ,OAAO,UAAU;GACpC,OAAO;IAAE,OAAO;IAAO,OAAO;GAAgB;EAChD;EAEA,OAAO;GAAE,OAAO;GAAM;EAAS;CACjC;CAEA,MAAM,aAAa,OAA8B;EAC/C,MAAM,SAAS,gBAAgB,KAAK;EACpC,IAAI,CAAC,QAAQ;GAGX,QAAQ,KAAK,uDAAuD;GACpE;EACF;EACA,MAAM,KAAK,QAAQ,OAAO,KAAK,SAAS,OAAO,KAAK,CAAC;CACvD;CAEA,MAAM,wBAAwB,SAA6B;EACzD,KAAK,YAAY,QAAQ,SAAS;EAElC,MAAM,WAAW,KAAK;EACtB,MAAM,WAAW,KAAK;EACtB,IAAI,CAAC,YAAY,CAAC,UAChB;EAGF,MAAM,QAAQ,QAAQ,aAAa,IAAI,OAAO;EAC9C,MAAM,gBAAgB,QAAQ,aAAa,IAAI,gBAAgB;EAC/D,IAAI,CAAC,SAAS,CAAC,eACb;EAGF,MAAM,SAAS,gBAAgB,KAAK;EACpC,IAAI,CAAC,UAAU,OAAO,aAAa,UACjC;EAGF,MAAM,eAAe,KAAK,yBAAyB,UAAU,aAAa;EAC1E,MAAM,kBACJ,MAAM,KAAK,QAAQ,IAAwB,YAAY;EACzD,IAAI,CAAC,iBACH;EAGF,IAAI,UAAU,gBAAgB,SAAS,GAAG;GACxC,MAAM,KAAK,QAAQ,OAAO,YAAY;GACtC;EACF;EAEA,MAAM,KAAK,QAAQ,IACjB,KAAK,qBAAqB,UAAU,OAAO,KAAK,GAChD,eACF;EACA,MAAM,KAAK,QAAQ,OAAO,YAAY;CACxC;CAEA,MAAM,sBACJ,OACe;EACf,MAAM,aAAuB,CAAC;EAE9B,IAAI,UAAU,SAAS,UAAU,aAC/B,WAAW,KAAK,KAAK,kBAAkB,CAAC;EAG1C,IAAI,KAAK,YAAY;GACnB,MAAM,WAAW,KAAK;GACtB,IAAI,UAAU,SAAS,UAAU,UAC/B,WAAW,KAAK,KAAK,cAAc,QAAQ,CAAC;GAE9C,IAAI,UAAU,SAAS,UAAU,UAC/B,WAAW,KAAK,KAAK,SAAS,QAAQ,CAAC;GAEzC,IAAI,UAAU,SAAS,UAAU,YAC/B,WAAW,KACT,GAAI,MAAM,KAAK,iBAAiB,UAAU,EACxC,sBAAsB,KACxB,CAAC,CACH;EAEJ;EAEA,IAAI,WAAW,SAAS,GACtB,MAAM,KAAK,QAAQ,OAAO,CAAC,GAAG,IAAI,IAAI,UAAU,CAAC,CAAC;CAEtD;;;;;;CAOA,MAAM,qBAAoC;EACxC,MAAM,OAAO,CACX,IACE,MAAM,KAAK,QAAQ,KAAK,EACtB,QAAQ,IAAI,KAAK,WAAW,GAAG,KAAK,SAAS,GAC/C,CAAC,EAAA,CACD,KAAK,CACT;EAEA,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK,KACpC,MAAM,KAAK,QAAQ,OAAO,KAAK,MAAM,GAAG,IAAI,GAAG,CAAC;CAEpD;CAEA,gBAAgB,UAAkB;EAChC,OAAO,GAAG,KAAK,UAAU,QAAQ,EAAE;CACrC;CAEA,wBAAwB,UAAkB;EACxC,OAAO,GAAG,KAAK,UAAU,QAAQ,EAAE;CACrC;CAEA,qBAAqB,UAAkB,OAAe;EACpD,OAAO,GAAG,KAAK,wBAAwB,QAAQ,IAAI;CACrD;CAEA,4BAA4B,UAAkB;EAC5C,OAAO,GAAG,KAAK,UAAU,QAAQ,EAAE;CACrC;CAEA,yBAAyB,UAAkB,eAAuB;EAChE,OAAO,GAAG,KAAK,4BAA4B,QAAQ,IAAI;CACzD;CAEA,MAAM,iBACJ,UACA,UAA8C,CAAC,GAC5B;EACnB,MAAM,YAAY,KAAK,gBAAgB,QAAQ;EAC/C,MAAM,OAAiB,CAAC;EAExB,IAAI,MAAM,KAAK,QAAQ,IAAI,SAAS,GAClC,KAAK,KAAK,SAAS;EAGrB,MAAM,YAAY,MAAM,KAAK,QAAQ,KAAK,EACxC,QAAQ,KAAK,wBAAwB,QAAQ,EAC/C,CAAC;EACD,KAAK,KAAK,GAAG,UAAU,KAAK,CAAC;EAE7B,IAAI,QAAQ,sBAAsB;GAChC,MAAM,gBAAgB,MAAM,KAAK,QAAQ,KAAK,EAC5C,QAAQ,KAAK,4BAA4B,QAAQ,EACnD,CAAC;GACD,KAAK,KAAK,GAAG,cAAc,KAAK,CAAC;EACnC;EAEA,OAAO;CACT;CAEA,MAAM,iBAAiB,UAAiC;EACtD,MAAM,KAAK,oCAAoC,KAAK,QAAQ;EAE5D,MAAM,gBAAgB,MAAM,oBAAoB,QAAQ;EACxD,MAAM,iBAAqC;GACzC;GACA,WAAW,KAAK,IAAI;EACtB;EAEA,MAAM,KAAK,QAAQ,IACjB,KAAK,yBAAyB,KAAK,UAAU,aAAa,GAC1D,cACF;CACF;CAEA,MAAc,oCACZ,UACe;EAIf,MAAM,cAAc,CAAC,IAAG,MAHS,KAAK,QAAQ,KAAyB,EACrE,QAAQ,KAAK,4BAA4B,QAAQ,EACnD,CAAC,EAAA,CAC0C,QAAQ,CAAC,CAAC,CAClD,QAAQ,GAAG,oBAAoB,UAAU,eAAe,SAAS,CAAC,CAAC,CACnE,KAAK,CAAC,SAAS,GAAG;EACrB,IAAI,YAAY,SAAS,GACvB,MAAM,KAAK,QAAQ,OAAO,WAAW;CAEzC;CAEA,MAAM,eAAgC;EACpC,MAAM,UAAU,yBAAyB,SAAS;EAClD,IAAI,SAAS;GACX,MAAM,gBAAgB,MAAM,KAAK,qBAAqB,QAAQ,KAAK;GACnE,IAAI,eAAe;IACjB,QAAQ,YAAY,cAAc;IAClC,OAAO,cAAc;GACvB;EACF;EAEA,MAAM,iBAAiB,MAAM,KAAK,QAAQ,IACxC,KAAK,gBAAgB,KAAK,QAAQ,CACpC;EACA,IAAI,gBAAgB;GAClB,IAAI,SACF,QAAQ,YAAY,KAAK,gBAAgB,KAAK,QAAQ;GAExD,OAAO;EACT;EAEA,IAAI,SACF,MAAM,IAAI,MAAM,wCAAwC;EAG1D,MAAM,mBAAmB,MAAM,KAAK,QAAQ,KAAyB,EACnE,QAAQ,KAAK,wBAAwB,KAAK,QAAQ,EACpD,CAAC;EACD,MAAM,4BAA4B,CAAC,GAAG,iBAAiB,QAAQ,CAAC,CAAC,CAAC,QAC/D,GAAG,oBAAoB,CAAC,UAAU,eAAe,SAAS,CAC7D;EACA,MAAM,cAAc,CAAC,GAAG,iBAAiB,QAAQ,CAAC,CAAC,CAChD,QAAQ,GAAG,oBAAoB,UAAU,eAAe,SAAS,CAAC,CAAC,CACnE,KAAK,CAAC,SAAS,GAAG;EACrB,IAAI,YAAY,SAAS,GACvB,MAAM,KAAK,QAAQ,OAAO,WAAW;EAGvC,IAAI,0BAA0B,WAAW,GAAG;GAC1C,MAAM,CAAC,GAAG,mBAAmB;GAC7B,OAAO,eAAe;EACxB;EAEA,IAAI,0BAA0B,SAAS,GACrC,MAAM,IAAI,MACR,2FACF;EAGF,MAAM,IAAI,MAAM,wBAAwB;CAC1C;CAEA,MAAc,qBACZ,OACwD;EACxD,MAAM,SAAS,gBAAgB,KAAK;EACpC,IAAI,CAAC,QACH,MAAM,IAAI,MAAM,sBAAsB;EAGxC,MAAM,MAAM,KAAK,qBAAqB,KAAK,UAAU,OAAO,KAAK;EACjE,MAAM,iBAAiB,MAAM,KAAK,QAAQ,IAAwB,GAAG;EACrE,IAAI,CAAC,gBACH;EAGF,IAAI,UAAU,eAAe,SAAS,GAAG;GACvC,MAAM,KAAK,QAAQ,OAAO,GAAG;GAC7B,MAAM,IAAI,MAAM,uBAAuB;EACzC;EAEA,OAAO;GAAE;GAAK,UAAU,eAAe;EAAS;CAClD;CAEA,MAAM,yBACJ,OACA,UACY;EACZ,OAAO,yBAAyB,IAAI,EAAE,MAAM,GAAG,QAAQ;CACzD;CAEA,MAAM,qBAAoC;EACxC,MAAM,UAAU,yBAAyB,SAAS;EAClD,IAAI,SAAS,WAAW;GACtB,MAAM,KAAK,QAAQ,OAAO,QAAQ,SAAS;GAC3C;EACF;EAEA,IAAI,SAAS;GACX,MAAM,SAAS,gBAAgB,QAAQ,KAAK;GAC5C,IAAI,QAAQ;IACV,MAAM,KAAK,QAAQ,OACjB,KAAK,qBAAqB,KAAK,UAAU,OAAO,KAAK,CACvD;IACA;GACF;EACF;EAEA,MAAM,OAAO,MAAM,KAAK,iBAAiB,KAAK,QAAQ;EACtD,IAAI,KAAK,SAAS,GAChB,MAAM,KAAK,QAAQ,OAAO,IAAI;CAElC;AACF"}
|
|
1
|
+
{"version":3,"file":"do-oauth-client-provider.js","names":[],"sources":["../../../src/mcp/client/do-oauth-client-provider.ts"],"sourcesContent":["import type {\n OAuthClientInformationContext,\n OAuthClientMetadata,\n OAuthClientProvider,\n OAuthDiscoveryState,\n StoredOAuthClientInformation,\n StoredOAuthTokens\n} from \"@modelcontextprotocol/client\";\nimport { validateClientMetadataUrl } from \"@modelcontextprotocol/client\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { nanoid } from \"nanoid\";\n\nconst STATE_EXPIRATION_MS = 10 * 60 * 1000; // 10 minutes\n\nconst codeVerifierStateStorage = new AsyncLocalStorage<{\n state: string;\n servedKey?: string;\n}>();\n\ninterface StoredState {\n nonce: string;\n serverId: string;\n createdAt: number;\n}\n\ninterface StoredCodeVerifier {\n verifier: string;\n createdAt: number;\n}\n\n// A slight extension to the standard OAuthClientProvider interface because `redirectToAuthorization` doesn't give us the interface we need\n// This allows us to track authentication for a specific server and associated dynamic client registration\nexport interface AgentMcpOAuthProvider extends OAuthClientProvider {\n authUrl: string | undefined;\n clientId: string | undefined;\n serverId: string | undefined;\n checkState(\n state: string\n ): Promise<{ valid: boolean; serverId?: string; error?: string }>;\n consumeState(state: string): Promise<void>;\n runWithCodeVerifierState?<T>(\n state: string,\n callback: () => Promise<T>\n ): Promise<T>;\n deleteCodeVerifier(): Promise<void>;\n}\n\nfunction parseOAuthState(\n state: string\n): { nonce: string; serverId: string } | undefined {\n const parts = state.split(\".\");\n if (parts.length !== 2) {\n return undefined;\n }\n\n const [nonce, serverId] = parts;\n if (!nonce || !serverId) {\n return undefined;\n }\n\n return { nonce, serverId };\n}\n\nfunction base64UrlEncode(bytes: Uint8Array): string {\n let binary = \"\";\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n return btoa(binary)\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/, \"\");\n}\n\nasync function createCodeChallenge(verifier: string): Promise<string> {\n const digest = await crypto.subtle.digest(\n \"SHA-256\",\n new TextEncoder().encode(verifier)\n );\n return base64UrlEncode(new Uint8Array(digest));\n}\n\nfunction isExpired(createdAt: number): boolean {\n return Date.now() - createdAt > STATE_EXPIRATION_MS;\n}\n\n/**\n * @deprecated Use {@link AgentMcpOAuthProvider} instead.\n */\nexport type AgentsOAuthProvider = AgentMcpOAuthProvider;\n\nexport interface DurableObjectOAuthClientProviderOptions {\n /**\n * HTTPS URL of this client's OAuth Client ID Metadata Document.\n *\n * When an authorization server advertises\n * `client_id_metadata_document_supported`, the client uses this URL as its\n * `client_id` instead of dynamic client registration. Other servers still\n * use dynamic client registration. Serve\n * {@link DurableObjectOAuthClientProvider.clientMetadataDocument} at this\n * URL, and use a stable `callbackPath` so the document's `redirect_uris`\n * match every authorization request.\n */\n clientMetadataUrl?: string;\n}\n\nexport class DurableObjectOAuthClientProvider implements AgentMcpOAuthProvider {\n private _authUrl_: string | undefined;\n private _serverId_: string | undefined;\n private _clientId_: string | undefined;\n readonly clientMetadataUrl: string | undefined;\n\n constructor(\n public storage: DurableObjectStorage,\n public clientName: string,\n public baseRedirectUrl: string,\n options: DurableObjectOAuthClientProviderOptions = {}\n ) {\n if (!storage) {\n throw new Error(\n \"DurableObjectOAuthClientProvider requires a valid DurableObjectStorage instance\"\n );\n }\n validateClientMetadataUrl(options.clientMetadataUrl);\n this.clientMetadataUrl = options.clientMetadataUrl || undefined;\n }\n\n /**\n * The Client ID Metadata Document to serve at `clientMetadataUrl`.\n * Throws when the provider has no `clientMetadataUrl`.\n */\n get clientMetadataDocument(): OAuthClientMetadata & { client_id: string } {\n if (!this.clientMetadataUrl) {\n throw new Error(\n \"clientMetadataDocument requires a clientMetadataUrl option\"\n );\n }\n return { client_id: this.clientMetadataUrl, ...this.clientMetadata };\n }\n\n get clientMetadata(): OAuthClientMetadata {\n return {\n client_name: this.clientName,\n client_uri: this.clientUri,\n grant_types: [\"authorization_code\", \"refresh_token\"],\n redirect_uris: [this.redirectUrl],\n response_types: [\"code\"],\n token_endpoint_auth_method: \"none\"\n };\n }\n\n get clientUri() {\n return new URL(this.redirectUrl).origin;\n }\n\n get redirectUrl() {\n return this.baseRedirectUrl;\n }\n\n get clientId() {\n if (!this._clientId_) {\n throw new Error(\"Trying to access clientId before it was set\");\n }\n return this._clientId_;\n }\n\n set clientId(clientId_: string) {\n this._clientId_ = clientId_;\n }\n\n get serverId() {\n if (!this._serverId_) {\n throw new Error(\"Trying to access serverId before it was set\");\n }\n return this._serverId_;\n }\n\n set serverId(serverId_: string) {\n this._serverId_ = serverId_;\n }\n\n keyPrefix(clientId: string) {\n return `/${this.clientName}/${this.serverId}/${clientId}`;\n }\n\n clientInfoKey(clientId: string) {\n return `${this.keyPrefix(clientId)}/client_info/`;\n }\n\n discoveryStateKey() {\n return `/${this.clientName}/${this.serverId}/oauth_discovery`;\n }\n\n async saveDiscoveryState(state: OAuthDiscoveryState): Promise<void> {\n await this.storage.put(this.discoveryStateKey(), state);\n }\n\n async discoveryState(): Promise<OAuthDiscoveryState | undefined> {\n return (\n (await this.storage.get<OAuthDiscoveryState>(this.discoveryStateKey())) ??\n undefined\n );\n }\n\n async clientInformation(\n _context?: OAuthClientInformationContext\n ): Promise<StoredOAuthClientInformation | undefined> {\n if (!this._clientId_) return undefined;\n return (\n (await this.storage.get<StoredOAuthClientInformation>(\n this.clientInfoKey(this.clientId)\n )) ?? undefined\n );\n }\n\n async saveClientInformation(\n clientInformation: StoredOAuthClientInformation,\n _context?: OAuthClientInformationContext\n ): Promise<void> {\n this.clientId = clientInformation.client_id;\n // Round-trip the SDK's issuer stamp verbatim. The SDK treats a credential\n // stamped for another issuer as absent, so one durable slot per MCP server\n // is both sufficient and safer than maintaining our own issuer index.\n await this.storage.put(\n this.clientInfoKey(clientInformation.client_id),\n clientInformation\n );\n }\n\n tokenKey(clientId: string) {\n return `${this.keyPrefix(clientId)}/token`;\n }\n\n async tokens(\n _context?: OAuthClientInformationContext\n ): Promise<StoredOAuthTokens | undefined> {\n if (!this._clientId_) return undefined;\n return (\n (await this.storage.get<StoredOAuthTokens>(\n this.tokenKey(this.clientId)\n )) ?? undefined\n );\n }\n\n async saveTokens(\n tokens: StoredOAuthTokens,\n _context?: OAuthClientInformationContext\n ): Promise<void> {\n // Keep the SDK-owned issuer stamp intact for SEP-2352 validation. Discovery\n // is needed across the browser redirect, but once token issuance succeeds\n // it must not pin later re-authorization to this AS: a subsequent 401 must\n // re-read PRM so an authorization-server migration can be observed.\n await this.storage.put(this.tokenKey(this.clientId), tokens);\n await this.storage.delete(this.discoveryStateKey());\n }\n\n get authUrl() {\n return this._authUrl_;\n }\n\n stateKey(nonce: string) {\n return `/${this.clientName}/${this.serverId}/state/${nonce}`;\n }\n\n async state(): Promise<string> {\n const nonce = nanoid();\n const state = `${nonce}.${this.serverId}`;\n const storedState: StoredState = {\n nonce,\n serverId: this.serverId,\n createdAt: Date.now()\n };\n await this.storage.put(this.stateKey(nonce), storedState);\n return state;\n }\n\n async checkState(\n state: string\n ): Promise<{ valid: boolean; serverId?: string; error?: string }> {\n const parsed = parseOAuthState(state);\n if (!parsed) {\n return { valid: false, error: \"Invalid state format\" };\n }\n\n const { nonce, serverId } = parsed;\n const key = this.stateKey(nonce);\n const storedState = await this.storage.get<StoredState>(key);\n\n if (!storedState) {\n return { valid: false, error: \"State not found or already used\" };\n }\n\n if (storedState.serverId !== serverId) {\n await this.storage.delete(key);\n return { valid: false, error: \"State serverId mismatch\" };\n }\n\n if (isExpired(storedState.createdAt)) {\n const deleteKeys = [key];\n if (this._clientId_) {\n deleteKeys.push(this.stateCodeVerifierKey(this.clientId, nonce));\n }\n await this.storage.delete(deleteKeys);\n return { valid: false, error: \"State expired\" };\n }\n\n return { valid: true, serverId };\n }\n\n async consumeState(state: string): Promise<void> {\n const parsed = parseOAuthState(state);\n if (!parsed) {\n // This should never happen since checkState validates format first.\n // Log for debugging but don't throw - state consumption is best-effort.\n console.warn(`[OAuth] consumeState called with invalid state format`);\n return;\n }\n await this.storage.delete(this.stateKey(parsed.nonce));\n }\n\n async redirectToAuthorization(authUrl: URL): Promise<void> {\n this._authUrl_ = authUrl.toString();\n\n const clientId = this._clientId_;\n const serverId = this._serverId_;\n if (!clientId || !serverId) {\n return;\n }\n\n const state = authUrl.searchParams.get(\"state\");\n const codeChallenge = authUrl.searchParams.get(\"code_challenge\");\n if (!state || !codeChallenge) {\n return;\n }\n\n const parsed = parseOAuthState(state);\n if (!parsed || parsed.serverId !== serverId) {\n return;\n }\n\n const challengeKey = this.challengeCodeVerifierKey(clientId, codeChallenge);\n const pendingVerifier =\n await this.storage.get<StoredCodeVerifier>(challengeKey);\n if (!pendingVerifier) {\n return;\n }\n\n if (isExpired(pendingVerifier.createdAt)) {\n await this.storage.delete(challengeKey);\n return;\n }\n\n await this.storage.put(\n this.stateCodeVerifierKey(clientId, parsed.nonce),\n pendingVerifier\n );\n await this.storage.delete(challengeKey);\n }\n\n async invalidateCredentials(\n scope: \"all\" | \"client\" | \"tokens\" | \"verifier\" | \"discovery\"\n ): Promise<void> {\n const deleteKeys: string[] = [];\n\n if (scope === \"all\" || scope === \"discovery\") {\n deleteKeys.push(this.discoveryStateKey());\n }\n\n if (this._clientId_) {\n const clientId = this.clientId;\n if (scope === \"all\" || scope === \"client\") {\n deleteKeys.push(this.clientInfoKey(clientId));\n }\n if (scope === \"all\" || scope === \"tokens\") {\n deleteKeys.push(this.tokenKey(clientId));\n }\n if (scope === \"all\" || scope === \"verifier\") {\n deleteKeys.push(\n ...(await this.codeVerifierKeys(clientId, {\n includeChallengeKeys: true\n }))\n );\n }\n }\n\n if (deleteKeys.length > 0) {\n await this.storage.delete([...new Set(deleteKeys)]);\n }\n }\n\n /**\n * Delete every key this provider stores for its server: tokens and client\n * info for any client ID, verifiers, pending states and discovery state.\n * Used when the server is removed. Other servers' keys are untouched.\n */\n async clearServerStorage(): Promise<void> {\n const keys = [\n ...(\n await this.storage.list({\n prefix: `/${this.clientName}/${this.serverId}/`\n })\n ).keys()\n ];\n // DO storage caps a multi-key delete at 128 keys.\n for (let i = 0; i < keys.length; i += 128) {\n await this.storage.delete(keys.slice(i, i + 128));\n }\n }\n\n codeVerifierKey(clientId: string) {\n return `${this.keyPrefix(clientId)}/code_verifier`;\n }\n\n stateCodeVerifierPrefix(clientId: string) {\n return `${this.keyPrefix(clientId)}/code_verifier/`;\n }\n\n stateCodeVerifierKey(clientId: string, nonce: string) {\n return `${this.stateCodeVerifierPrefix(clientId)}${nonce}`;\n }\n\n challengeCodeVerifierPrefix(clientId: string) {\n return `${this.keyPrefix(clientId)}/code_verifier_challenge/`;\n }\n\n challengeCodeVerifierKey(clientId: string, codeChallenge: string) {\n return `${this.challengeCodeVerifierPrefix(clientId)}${codeChallenge}`;\n }\n\n async codeVerifierKeys(\n clientId: string,\n options: { includeChallengeKeys?: boolean } = {}\n ): Promise<string[]> {\n const legacyKey = this.codeVerifierKey(clientId);\n const keys: string[] = [];\n\n if (await this.storage.get(legacyKey)) {\n keys.push(legacyKey);\n }\n\n const stateKeys = await this.storage.list({\n prefix: this.stateCodeVerifierPrefix(clientId)\n });\n keys.push(...stateKeys.keys());\n\n if (options.includeChallengeKeys) {\n const challengeKeys = await this.storage.list({\n prefix: this.challengeCodeVerifierPrefix(clientId)\n });\n keys.push(...challengeKeys.keys());\n }\n\n return keys;\n }\n\n async saveCodeVerifier(verifier: string): Promise<void> {\n await this.deleteExpiredChallengeCodeVerifiers(this.clientId);\n\n const codeChallenge = await createCodeChallenge(verifier);\n const storedVerifier: StoredCodeVerifier = {\n verifier,\n createdAt: Date.now()\n };\n\n await this.storage.put(\n this.challengeCodeVerifierKey(this.clientId, codeChallenge),\n storedVerifier\n );\n }\n\n private async deleteExpiredChallengeCodeVerifiers(\n clientId: string\n ): Promise<void> {\n const challengeVerifiers = await this.storage.list<StoredCodeVerifier>({\n prefix: this.challengeCodeVerifierPrefix(clientId)\n });\n const expiredKeys = [...challengeVerifiers.entries()]\n .filter(([, storedVerifier]) => isExpired(storedVerifier.createdAt))\n .map(([key]) => key);\n if (expiredKeys.length > 0) {\n await this.storage.delete(expiredKeys);\n }\n }\n\n async codeVerifier(): Promise<string> {\n const context = codeVerifierStateStorage.getStore();\n if (context) {\n const stateVerifier = await this.codeVerifierForState(context.state);\n if (stateVerifier) {\n context.servedKey = stateVerifier.key;\n return stateVerifier.verifier;\n }\n }\n\n const legacyVerifier = await this.storage.get<string>(\n this.codeVerifierKey(this.clientId)\n );\n if (legacyVerifier) {\n if (context) {\n context.servedKey = this.codeVerifierKey(this.clientId);\n }\n return legacyVerifier;\n }\n\n if (context) {\n throw new Error(\"No code verifier found for OAuth state\");\n }\n\n const pendingVerifiers = await this.storage.list<StoredCodeVerifier>({\n prefix: this.stateCodeVerifierPrefix(this.clientId)\n });\n const unexpiredPendingVerifiers = [...pendingVerifiers.entries()].filter(\n ([, storedVerifier]) => !isExpired(storedVerifier.createdAt)\n );\n const expiredKeys = [...pendingVerifiers.entries()]\n .filter(([, storedVerifier]) => isExpired(storedVerifier.createdAt))\n .map(([key]) => key);\n if (expiredKeys.length > 0) {\n await this.storage.delete(expiredKeys);\n }\n\n if (unexpiredPendingVerifiers.length === 1) {\n const [[, storedVerifier]] = unexpiredPendingVerifiers;\n return storedVerifier.verifier;\n }\n\n if (unexpiredPendingVerifiers.length > 1) {\n throw new Error(\n \"Multiple OAuth code verifiers are pending; complete authorization with the callback state\"\n );\n }\n\n throw new Error(\"No code verifier found\");\n }\n\n private async codeVerifierForState(\n state: string\n ): Promise<{ key: string; verifier: string } | undefined> {\n const parsed = parseOAuthState(state);\n if (!parsed) {\n throw new Error(\"Invalid state format\");\n }\n\n const key = this.stateCodeVerifierKey(this.clientId, parsed.nonce);\n const storedVerifier = await this.storage.get<StoredCodeVerifier>(key);\n if (!storedVerifier) {\n return undefined;\n }\n\n if (isExpired(storedVerifier.createdAt)) {\n await this.storage.delete(key);\n throw new Error(\"Code verifier expired\");\n }\n\n return { key, verifier: storedVerifier.verifier };\n }\n\n async runWithCodeVerifierState<T>(\n state: string,\n callback: () => Promise<T>\n ): Promise<T> {\n return codeVerifierStateStorage.run({ state }, callback);\n }\n\n async deleteCodeVerifier(): Promise<void> {\n const context = codeVerifierStateStorage.getStore();\n if (context?.servedKey) {\n await this.storage.delete(context.servedKey);\n return;\n }\n\n if (context) {\n const parsed = parseOAuthState(context.state);\n if (parsed) {\n await this.storage.delete(\n this.stateCodeVerifierKey(this.clientId, parsed.nonce)\n );\n return;\n }\n }\n\n const keys = await this.codeVerifierKeys(this.clientId);\n if (keys.length > 0) {\n await this.storage.delete(keys);\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
$t as RPCClientTransportOptions,
|
|
2
3
|
At as ElicitRequest,
|
|
3
4
|
Bt as MCPConnectionResult,
|
|
4
5
|
Ft as MCPClientElicitationHandlers,
|
|
@@ -11,14 +12,20 @@ import {
|
|
|
11
12
|
Mt as MCPAITool,
|
|
12
13
|
Nt as MCPAIToolSet,
|
|
13
14
|
Pt as MCPClientElicitationHandler,
|
|
15
|
+
Qt as RPCClientTransport,
|
|
14
16
|
Rt as MCPClientOAuthCallbackConfig,
|
|
15
17
|
Ut as MCPServerFilter,
|
|
16
18
|
Vt as MCPDiscoverResult,
|
|
17
19
|
Wt as MCPServerOptions,
|
|
20
|
+
Xt as MCPElicitationHandlers,
|
|
21
|
+
Yt as MCPElicitationHandler,
|
|
22
|
+
Zt as McpRpcAgent,
|
|
23
|
+
en as RPC_DO_PREFIX,
|
|
18
24
|
jt as ElicitResult,
|
|
19
25
|
qt as getNamespacedData,
|
|
20
26
|
zt as MCPClientOAuthResult
|
|
21
|
-
} from "../../agent-routing-
|
|
27
|
+
} from "../../agent-routing-vVMA7m8Y.js";
|
|
28
|
+
import { i as McpClientOptions } from "../../types-D2naO3rA.js";
|
|
22
29
|
export {
|
|
23
30
|
type ElicitRequest,
|
|
24
31
|
type ElicitResult,
|
|
@@ -32,10 +39,17 @@ export {
|
|
|
32
39
|
MCPClientOAuthResult,
|
|
33
40
|
MCPConnectionResult,
|
|
34
41
|
MCPDiscoverResult,
|
|
42
|
+
type MCPElicitationHandler,
|
|
43
|
+
type MCPElicitationHandlers,
|
|
35
44
|
MCPOAuthCallbackResult,
|
|
36
45
|
MCPServerFilter,
|
|
37
46
|
MCPServerOptions,
|
|
38
47
|
MCP_SERVER_ID_MAX_LENGTH,
|
|
48
|
+
type McpClientOptions,
|
|
49
|
+
type McpRpcAgent,
|
|
50
|
+
RPCClientTransport,
|
|
51
|
+
type RPCClientTransportOptions,
|
|
52
|
+
RPC_DO_PREFIX,
|
|
39
53
|
RegisterServerOptions,
|
|
40
54
|
getNamespacedData,
|
|
41
55
|
normalizeServerId
|
package/dist/mcp/client/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as normalizeServerId, n as MCP_SERVER_ID_MAX_LENGTH, r as getNamespacedData, t as MCPClientManager } from "../../client-
|
|
2
|
-
export { MCPClientManager, MCP_SERVER_ID_MAX_LENGTH, getNamespacedData, normalizeServerId };
|
|
1
|
+
import { c as RPCClientTransport, i as normalizeServerId, l as RPC_DO_PREFIX, n as MCP_SERVER_ID_MAX_LENGTH, r as getNamespacedData, t as MCPClientManager } from "../../client-DMWujQJ1.js";
|
|
2
|
+
export { MCPClientManager, MCP_SERVER_ID_MAX_LENGTH, RPCClientTransport, RPC_DO_PREFIX, getNamespacedData, normalizeServerId };
|