toolcraft 0.0.745 → 0.0.747
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/composition.json +3 -3
- package/dist/composition.json +3 -3
- package/node_modules/auth-store/dist/transaction-lock.js +2 -2
- package/node_modules/tiny-http-mcp-server/dist/composition.json +1 -1
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/README.md +1 -1
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/client-registration.js +1 -1
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/loopback-authorization.d.ts +2 -9
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/loopback-authorization.js +8 -48
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/redirect-target.d.ts +10 -0
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/redirect-target.js +42 -0
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/resource-bound-store.js +2 -2
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/session-transaction.js +4 -3
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/index.browser.d.ts +6 -0
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/index.browser.js +8 -0
- package/node_modules/tiny-http-mcp-server/package.json +1 -1
- package/node_modules/tiny-mcp-client/dist/index.browser.js +75 -11
- package/node_modules/tiny-mcp-client/dist/index.js +431 -424
- package/node_modules/tiny-stdio-mcp-server/dist/base64.js +6 -1
- package/node_modules/tiny-stdio-mcp-server/dist/composition.json +1 -1
- package/node_modules/tiny-stdio-mcp-server/dist/headers.js +7 -6
- package/node_modules/toolcraft-schema/package.json +1 -1
- package/package.json +2 -2
package/composition.json
CHANGED
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
},
|
|
99
99
|
{
|
|
100
100
|
"name": "tiny-http-mcp-server",
|
|
101
|
-
"version": "0.1.
|
|
101
|
+
"version": "0.1.115",
|
|
102
102
|
"license": "MIT"
|
|
103
103
|
},
|
|
104
104
|
{
|
|
@@ -113,7 +113,7 @@
|
|
|
113
113
|
},
|
|
114
114
|
{
|
|
115
115
|
"name": "toolcraft",
|
|
116
|
-
"version": "0.0.
|
|
116
|
+
"version": "0.0.747",
|
|
117
117
|
"license": "MIT"
|
|
118
118
|
},
|
|
119
119
|
{
|
|
@@ -123,7 +123,7 @@
|
|
|
123
123
|
},
|
|
124
124
|
{
|
|
125
125
|
"name": "toolcraft-schema",
|
|
126
|
-
"version": "0.0.
|
|
126
|
+
"version": "0.0.747",
|
|
127
127
|
"license": "MIT"
|
|
128
128
|
},
|
|
129
129
|
{
|
package/dist/composition.json
CHANGED
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
},
|
|
99
99
|
{
|
|
100
100
|
"name": "tiny-http-mcp-server",
|
|
101
|
-
"version": "0.1.
|
|
101
|
+
"version": "0.1.115",
|
|
102
102
|
"license": "MIT"
|
|
103
103
|
},
|
|
104
104
|
{
|
|
@@ -113,7 +113,7 @@
|
|
|
113
113
|
},
|
|
114
114
|
{
|
|
115
115
|
"name": "toolcraft",
|
|
116
|
-
"version": "0.0.
|
|
116
|
+
"version": "0.0.747",
|
|
117
117
|
"license": "MIT"
|
|
118
118
|
},
|
|
119
119
|
{
|
|
@@ -123,7 +123,7 @@
|
|
|
123
123
|
},
|
|
124
124
|
{
|
|
125
125
|
"name": "toolcraft-schema",
|
|
126
|
-
"version": "0.0.
|
|
126
|
+
"version": "0.0.747",
|
|
127
127
|
"license": "MIT"
|
|
128
128
|
},
|
|
129
129
|
{
|
|
@@ -4,8 +4,8 @@ import { hasOwnErrorCode } from "./error-codes.js";
|
|
|
4
4
|
/** Filesystem bakery lock: unique claims allow dead-owner cleanup without deleting a replacement owner's lock. */
|
|
5
5
|
export async function withSecretStoreFileLock(fs, lockDirectory, operation, options = {}) {
|
|
6
6
|
options = { ...options, signal: options.signal, timeoutMs: options.timeoutMs };
|
|
7
|
-
const timeoutMs = options.timeoutMs ??
|
|
8
|
-
if (!Number.isFinite(timeoutMs) || timeoutMs < 0 || timeoutMs > 2_147_483_647)
|
|
7
|
+
const timeoutMs = options.timeoutMs ?? Infinity;
|
|
8
|
+
if (timeoutMs !== Infinity && (!Number.isFinite(timeoutMs) || timeoutMs < 0 || timeoutMs > 2_147_483_647))
|
|
9
9
|
throw new Error("Invalid secret-store transaction lock timeout");
|
|
10
10
|
options.signal?.throwIfAborted();
|
|
11
11
|
const deadline = performance.now() + timeoutMs;
|
|
@@ -47,7 +47,7 @@ alone do not establish either native error type.
|
|
|
47
47
|
in both Node and Worker exports, and through `@poe-platform/safe-bash/mcp`.
|
|
48
48
|
They use Web Crypto and host storage, with no filesystem, listener, browser opener
|
|
49
49
|
or pending callback promise. Supply a statically registered client and trusted
|
|
50
|
-
discovery. See [the public MCP example](../safe-bash-mcp/README.md#resumable-https-oauth)
|
|
50
|
+
discovery. See [the public MCP example](../safe-bash-command-mcp/README.md#resumable-https-oauth)
|
|
51
51
|
for callback routing and the required atomic storage contract.
|
|
52
52
|
|
|
53
53
|
## Configuration
|
package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/client-registration.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { copyBoundedOAuthJson } from "./bounded-json.js";
|
|
2
|
-
import { loopbackTarget, validateHostedOAuthRedirect } from "./
|
|
2
|
+
import { loopbackTarget, validateHostedOAuthRedirect } from "./redirect-target.js";
|
|
3
3
|
import { normalizeOAuthScope } from "./scope.js";
|
|
4
4
|
import { normalizeOAuthTokenEndpointAuthMethod } from "./token-auth-method.js";
|
|
5
5
|
/** Validate and copy a JSON DCR response without quoting credential input. */
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import http from "node:http";
|
|
2
2
|
export { OAuthAuthorizationError } from "./authorization-error.js";
|
|
3
|
+
export { loopbackTarget, validateAuthorizationRedirect, validateHostedOAuthRedirect } from "./redirect-target.js";
|
|
3
4
|
export interface OAuthLandingPage {
|
|
4
5
|
title: string;
|
|
5
6
|
body: string;
|
|
@@ -19,7 +20,7 @@ export interface LoopbackAuthorizationOptions {
|
|
|
19
20
|
/** Exact registered HTTP loopback redirect, including its fixed port and query. */
|
|
20
21
|
redirectUri?: string;
|
|
21
22
|
signal?: AbortSignal;
|
|
22
|
-
/** Bounds listener setup and authorization; defaults to
|
|
23
|
+
/** Bounds listener setup and authorization; defaults to unlimited. */
|
|
23
24
|
timeoutMs?: number;
|
|
24
25
|
}
|
|
25
26
|
export interface LoopbackAuthorizationSession {
|
|
@@ -31,13 +32,5 @@ export interface LoopbackAuthorizationSession {
|
|
|
31
32
|
export declare function snapshotLoopbackAuthorizationOptions(options: LoopbackAuthorizationOptions): LoopbackAuthorizationOptions;
|
|
32
33
|
/** Authorization callback denial, retaining the provider diagnostic for host observers. */
|
|
33
34
|
export declare function createLoopbackAuthorizationSession(options?: LoopbackAuthorizationOptions): Promise<LoopbackAuthorizationSession>;
|
|
34
|
-
export declare function loopbackTarget(options: LoopbackAuthorizationOptions): {
|
|
35
|
-
port: number;
|
|
36
|
-
host: string;
|
|
37
|
-
callbackPath: string;
|
|
38
|
-
};
|
|
39
|
-
/** Hosted redirects are explicit HTTPS URLs; local redirects retain loopback policy. */
|
|
40
|
-
export declare function validateAuthorizationRedirect(options: LoopbackAuthorizationOptions): void;
|
|
41
|
-
export declare function validateHostedOAuthRedirect(redirectUri: string, callbackPath?: string): void;
|
|
42
35
|
export declare function extractCodeFromInput(input: string): string | null;
|
|
43
36
|
export declare function buildSuccessPage(landingPage?: OAuthLandingPage): string;
|
|
@@ -2,7 +2,8 @@ import http from "node:http";
|
|
|
2
2
|
import { parseAuthorizationState } from "./authorization-state.js";
|
|
3
3
|
import { OAuthAuthorizationError } from "./authorization-error.js";
|
|
4
4
|
export { OAuthAuthorizationError } from "./authorization-error.js";
|
|
5
|
-
|
|
5
|
+
import { oauthCallbackParameters, loopbackTarget, validateAuthorizationRedirect } from "./redirect-target.js";
|
|
6
|
+
export { loopbackTarget, validateAuthorizationRedirect, validateHostedOAuthRedirect } from "./redirect-target.js";
|
|
6
7
|
/** Capture declared configuration regardless of property enumerability. */
|
|
7
8
|
export function snapshotLoopbackAuthorizationOptions(options) {
|
|
8
9
|
return { ...options, openBrowser: options.openBrowser?.bind(options), readLine: options.readLine?.bind(options), waitForCallback: options.waitForCallback?.bind(options), createServer: options.createServer?.bind(options),
|
|
@@ -13,8 +14,8 @@ export function snapshotLoopbackAuthorizationOptions(options) {
|
|
|
13
14
|
export async function createLoopbackAuthorizationSession(options = {}) {
|
|
14
15
|
options = snapshotLoopbackAuthorizationOptions(options);
|
|
15
16
|
options.signal?.throwIfAborted();
|
|
16
|
-
const timeoutMs = options.timeoutMs ??
|
|
17
|
-
if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > 2_147_483_647)
|
|
17
|
+
const timeoutMs = options.timeoutMs ?? Infinity;
|
|
18
|
+
if (timeoutMs !== Infinity && (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > 2_147_483_647))
|
|
18
19
|
throw new Error("OAuth authorization timeoutMs must be a positive supported timer interval");
|
|
19
20
|
if (options.waitForCallback !== undefined)
|
|
20
21
|
return createHostedAuthorizationSession(options, timeoutMs);
|
|
@@ -33,8 +34,8 @@ export async function createLoopbackAuthorizationSession(options = {}) {
|
|
|
33
34
|
server.closeAllConnections?.();
|
|
34
35
|
server.close();
|
|
35
36
|
};
|
|
36
|
-
const timer = setTimeout(() => controller.abort(new Error("OAuth authorization timed out")), timeoutMs);
|
|
37
|
-
timer
|
|
37
|
+
const timer = timeoutMs === Infinity ? undefined : setTimeout(() => controller.abort(new Error("OAuth authorization timed out")), timeoutMs);
|
|
38
|
+
timer?.unref?.();
|
|
38
39
|
controller.signal.addEventListener("abort", teardown, { once: true });
|
|
39
40
|
options.signal?.addEventListener("abort", callerAbort, { once: true });
|
|
40
41
|
if (options.signal?.aborted)
|
|
@@ -67,54 +68,13 @@ export async function createLoopbackAuthorizationSession(options = {}) {
|
|
|
67
68
|
}
|
|
68
69
|
};
|
|
69
70
|
}
|
|
70
|
-
export function loopbackTarget(options) {
|
|
71
|
-
if (options.redirectUri !== undefined) {
|
|
72
|
-
let url;
|
|
73
|
-
try {
|
|
74
|
-
url = new URL(options.redirectUri);
|
|
75
|
-
}
|
|
76
|
-
catch (cause) {
|
|
77
|
-
throw new Error("Invalid OAuth loopback redirect URI", { cause });
|
|
78
|
-
}
|
|
79
|
-
if (url.protocol !== "http:" || !["localhost", "127.0.0.1", "[::1]"].includes(url.hostname)
|
|
80
|
-
|| url.username || url.password || url.href.includes("#") || url.port === "0"
|
|
81
|
-
|| oauthCallbackParameters.some(name => url.searchParams.has(name))
|
|
82
|
-
|| [...options.redirectUri].some(char => char.codePointAt(0) <= 32)
|
|
83
|
-
|| (options.callbackPath !== undefined && options.callbackPath !== url.pathname))
|
|
84
|
-
throw new Error("Invalid OAuth loopback redirect URI");
|
|
85
|
-
return { port: url.port ? Number(url.port) : 80, host: url.hostname === "[::1]" ? "::1" : url.hostname, callbackPath: url.pathname };
|
|
86
|
-
}
|
|
87
|
-
const callbackPath = options.callbackPath ?? "/callback";
|
|
88
|
-
const parsed = new URL(callbackPath, "http://127.0.0.1");
|
|
89
|
-
if (!callbackPath.startsWith("/") || parsed.origin !== "http://127.0.0.1" || parsed.pathname !== callbackPath || parsed.search || parsed.hash)
|
|
90
|
-
throw new Error("Invalid OAuth loopback callback path");
|
|
91
|
-
return { port: 0, host: "127.0.0.1", callbackPath };
|
|
92
|
-
}
|
|
93
|
-
/** Hosted redirects are explicit HTTPS URLs; local redirects retain loopback policy. */
|
|
94
|
-
export function validateAuthorizationRedirect(options) {
|
|
95
|
-
if (options.waitForCallback === undefined) {
|
|
96
|
-
loopbackTarget(options);
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
if (typeof options.waitForCallback !== "function" || options.redirectUri === undefined)
|
|
100
|
-
throw new Error("Hosted OAuth callbacks require redirectUri and waitForCallback");
|
|
101
|
-
validateHostedOAuthRedirect(options.redirectUri, options.callbackPath);
|
|
102
|
-
}
|
|
103
|
-
export function validateHostedOAuthRedirect(redirectUri, callbackPath) {
|
|
104
|
-
const url = new URL(redirectUri);
|
|
105
|
-
if (url.protocol !== "https:" || url.username || url.password || url.href.includes("#") || url.port === "0"
|
|
106
|
-
|| oauthCallbackParameters.some(name => url.searchParams.has(name))
|
|
107
|
-
|| [...redirectUri].some(char => char.codePointAt(0) <= 32)
|
|
108
|
-
|| (callbackPath !== undefined && callbackPath !== url.pathname))
|
|
109
|
-
throw new Error("Invalid hosted OAuth redirect URI");
|
|
110
|
-
}
|
|
111
71
|
function createHostedAuthorizationSession(options, timeoutMs) {
|
|
112
72
|
validateAuthorizationRedirect(options);
|
|
113
73
|
const redirectUri = options.redirectUri, controller = new AbortController();
|
|
114
74
|
let used = false;
|
|
115
75
|
const aborted = () => controller.abort(options.signal?.reason);
|
|
116
|
-
const timer = setTimeout(() => controller.abort(new Error("OAuth authorization timed out")), timeoutMs);
|
|
117
|
-
timer
|
|
76
|
+
const timer = timeoutMs === Infinity ? undefined : setTimeout(() => controller.abort(new Error("OAuth authorization timed out")), timeoutMs);
|
|
77
|
+
timer?.unref?.();
|
|
118
78
|
const cleanup = () => { clearTimeout(timer); options.signal?.removeEventListener("abort", aborted); };
|
|
119
79
|
controller.signal.addEventListener("abort", cleanup, { once: true });
|
|
120
80
|
options.signal?.addEventListener("abort", aborted, { once: true });
|
package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/redirect-target.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { LoopbackAuthorizationOptions } from "./loopback-authorization.js";
|
|
2
|
+
export declare const oauthCallbackParameters: string[];
|
|
3
|
+
export declare function loopbackTarget(options: LoopbackAuthorizationOptions): {
|
|
4
|
+
port: number;
|
|
5
|
+
host: string;
|
|
6
|
+
callbackPath: string;
|
|
7
|
+
};
|
|
8
|
+
/** Hosted redirects are explicit HTTPS URLs; local redirects retain loopback policy. */
|
|
9
|
+
export declare function validateAuthorizationRedirect(options: LoopbackAuthorizationOptions): void;
|
|
10
|
+
export declare function validateHostedOAuthRedirect(redirectUri: string, callbackPath?: string): void;
|
package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/redirect-target.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export const oauthCallbackParameters = ["code", "state", "iss", "error", "error_description", "error_uri"];
|
|
2
|
+
export function loopbackTarget(options) {
|
|
3
|
+
if (options.redirectUri !== undefined) {
|
|
4
|
+
let url;
|
|
5
|
+
try {
|
|
6
|
+
url = new URL(options.redirectUri);
|
|
7
|
+
}
|
|
8
|
+
catch (cause) {
|
|
9
|
+
throw new Error("Invalid OAuth loopback redirect URI", { cause });
|
|
10
|
+
}
|
|
11
|
+
if (url.protocol !== "http:" || !["localhost", "127.0.0.1", "[::1]"].includes(url.hostname)
|
|
12
|
+
|| url.username || url.password || url.href.includes("#") || url.port === "0"
|
|
13
|
+
|| oauthCallbackParameters.some(name => url.searchParams.has(name))
|
|
14
|
+
|| [...options.redirectUri].some(char => char.codePointAt(0) <= 32)
|
|
15
|
+
|| (options.callbackPath !== undefined && options.callbackPath !== url.pathname))
|
|
16
|
+
throw new Error("Invalid OAuth loopback redirect URI");
|
|
17
|
+
return { port: url.port ? Number(url.port) : 80, host: url.hostname === "[::1]" ? "::1" : url.hostname, callbackPath: url.pathname };
|
|
18
|
+
}
|
|
19
|
+
const callbackPath = options.callbackPath ?? "/callback";
|
|
20
|
+
const parsed = new URL(callbackPath, "http://127.0.0.1");
|
|
21
|
+
if (!callbackPath.startsWith("/") || parsed.origin !== "http://127.0.0.1" || parsed.pathname !== callbackPath || parsed.search || parsed.hash)
|
|
22
|
+
throw new Error("Invalid OAuth loopback callback path");
|
|
23
|
+
return { port: 0, host: "127.0.0.1", callbackPath };
|
|
24
|
+
}
|
|
25
|
+
/** Hosted redirects are explicit HTTPS URLs; local redirects retain loopback policy. */
|
|
26
|
+
export function validateAuthorizationRedirect(options) {
|
|
27
|
+
if (options.waitForCallback === undefined) {
|
|
28
|
+
loopbackTarget(options);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (typeof options.waitForCallback !== "function" || options.redirectUri === undefined)
|
|
32
|
+
throw new Error("Hosted OAuth callbacks require redirectUri and waitForCallback");
|
|
33
|
+
validateHostedOAuthRedirect(options.redirectUri, options.callbackPath);
|
|
34
|
+
}
|
|
35
|
+
export function validateHostedOAuthRedirect(redirectUri, callbackPath) {
|
|
36
|
+
const url = new URL(redirectUri);
|
|
37
|
+
if (url.protocol !== "https:" || url.username || url.password || url.href.includes("#") || url.port === "0"
|
|
38
|
+
|| oauthCallbackParameters.some(name => url.searchParams.has(name))
|
|
39
|
+
|| [...redirectUri].some(char => char.codePointAt(0) <= 32)
|
|
40
|
+
|| (callbackPath !== undefined && callbackPath !== url.pathname))
|
|
41
|
+
throw new Error("Invalid hosted OAuth redirect URI");
|
|
42
|
+
}
|
package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/resource-bound-store.js
CHANGED
|
@@ -54,8 +54,8 @@ export function createResourceBoundOAuthStores(options, namespace, identity) {
|
|
|
54
54
|
async function replace(record, options) {
|
|
55
55
|
options = { ...options, signal: options.signal, timeoutMs: options.timeoutMs };
|
|
56
56
|
options.signal?.throwIfAborted();
|
|
57
|
-
const timeoutMs = options.timeoutMs ??
|
|
58
|
-
if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > 2_147_483_647)
|
|
57
|
+
const timeoutMs = options.timeoutMs ?? Infinity;
|
|
58
|
+
if (timeoutMs !== Infinity && (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > 2_147_483_647))
|
|
59
59
|
throw new Error("OAuth replacement timeoutMs must be a positive supported timer interval");
|
|
60
60
|
if (store.withLock === undefined)
|
|
61
61
|
throw new Error("OAuth resource identity backend must support transaction locks");
|
package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/session-transaction.js
CHANGED
|
@@ -2,8 +2,8 @@ import { waitForOAuthOperation } from "./cancellable-operation.js";
|
|
|
2
2
|
const queues = new WeakMap();
|
|
3
3
|
/** Serialize the complete read/redeem/write operation, with independent cancellation for waiters. */
|
|
4
4
|
export async function withOAuthSessionTransaction(store, resource, operation, options = {}) {
|
|
5
|
-
const timeoutMs = options.timeoutMs ??
|
|
6
|
-
if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > 2_147_483_647)
|
|
5
|
+
const timeoutMs = options.timeoutMs ?? Infinity;
|
|
6
|
+
if (timeoutMs !== Infinity && (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > 2_147_483_647))
|
|
7
7
|
throw new Error("sessionLockTimeoutMs must be an integer from 1 to 2147483647 milliseconds");
|
|
8
8
|
options.signal?.throwIfAborted();
|
|
9
9
|
const started = performance.now();
|
|
@@ -21,7 +21,8 @@ export async function withOAuthSessionTransaction(store, resource, operation, op
|
|
|
21
21
|
const waiting = new Promise((resolve, reject) => { rejectWait = reject; previous.then(resolve, reject); });
|
|
22
22
|
const abort = () => rejectWait(options.signal?.reason);
|
|
23
23
|
try {
|
|
24
|
-
|
|
24
|
+
if (timeoutMs !== Infinity)
|
|
25
|
+
timer = setTimeout(() => rejectWait(new Error("Timed out waiting for OAuth session transaction lock")), timeoutMs);
|
|
25
26
|
options.signal?.addEventListener("abort", abort, { once: true });
|
|
26
27
|
if (options.signal?.aborted)
|
|
27
28
|
abort();
|
|
@@ -12,3 +12,9 @@ export declare function createDefaultOAuthClientProvider(): never;
|
|
|
12
12
|
export declare function createAuthStoreSessionStore(): never;
|
|
13
13
|
export { beginRemoteMcpAuthorization, completeRemoteMcpAuthorization } from "./client/resumable.js";
|
|
14
14
|
export type { RemoteMcpAuthorizationTransaction, RemoteMcpAuthorizationStore, BeginRemoteMcpAuthorizationOptions, CompleteRemoteMcpAuthorizationOptions } from "./client/resumable.js";
|
|
15
|
+
export { normalizeOAuthScope } from "./client/scope.js";
|
|
16
|
+
export { waitForOAuthOperation } from "./client/cancellable-operation.js";
|
|
17
|
+
export { parseOAuthTokenGrant } from "./client/token-grant.js";
|
|
18
|
+
export { parseOAuthClientRegistration, normalizeStoredOAuthClient } from "./client/client-registration.js";
|
|
19
|
+
/** Native persistence needs a desktop host; portable callers provide atomic hooks. */
|
|
20
|
+
export declare function createResourceBoundOAuthStores(): never;
|
|
@@ -17,3 +17,11 @@ export function createAuthStoreSessionStore() {
|
|
|
17
17
|
throw new Error("Desktop OAuth persistence is unavailable in Worker MCP");
|
|
18
18
|
}
|
|
19
19
|
export { beginRemoteMcpAuthorization, completeRemoteMcpAuthorization } from "./client/resumable.js";
|
|
20
|
+
export { normalizeOAuthScope } from "./client/scope.js";
|
|
21
|
+
export { waitForOAuthOperation } from "./client/cancellable-operation.js";
|
|
22
|
+
export { parseOAuthTokenGrant } from "./client/token-grant.js";
|
|
23
|
+
export { parseOAuthClientRegistration, normalizeStoredOAuthClient } from "./client/client-registration.js";
|
|
24
|
+
/** Native persistence needs a desktop host; portable callers provide atomic hooks. */
|
|
25
|
+
export function createResourceBoundOAuthStores() {
|
|
26
|
+
throw new Error("Desktop OAuth persistence is unavailable in Worker MCP; provide host-owned import/reset hooks");
|
|
27
|
+
}
|
|
@@ -57,8 +57,63 @@ function assertHttpJsonBudget(text) {
|
|
|
57
57
|
if (stack.length !== 0) throw new SyntaxError("Unterminated MCP HTTP JSON container");
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
// src/
|
|
61
|
-
|
|
60
|
+
// src/stream.browser.ts
|
|
61
|
+
var PassThrough = class {
|
|
62
|
+
destroyed = false;
|
|
63
|
+
writableEnded = false;
|
|
64
|
+
chunks = [];
|
|
65
|
+
wake;
|
|
66
|
+
failure;
|
|
67
|
+
listeners = /* @__PURE__ */ new Map();
|
|
68
|
+
once(event, listener) {
|
|
69
|
+
const listeners = this.listeners.get(event) ?? /* @__PURE__ */ new Set();
|
|
70
|
+
listeners.add(listener);
|
|
71
|
+
this.listeners.set(event, listeners);
|
|
72
|
+
return this;
|
|
73
|
+
}
|
|
74
|
+
write(value) {
|
|
75
|
+
if (this.destroyed || this.writableEnded) throw this.failure ?? new Error("HTTP message channel is closed");
|
|
76
|
+
this.chunks.push(typeof value === "string" ? new TextEncoder().encode(value) : value.slice());
|
|
77
|
+
this.wake?.();
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
end() {
|
|
81
|
+
this.writableEnded = true;
|
|
82
|
+
this.wake?.();
|
|
83
|
+
return this;
|
|
84
|
+
}
|
|
85
|
+
destroy(error) {
|
|
86
|
+
if (this.destroyed) return this;
|
|
87
|
+
this.destroyed = true;
|
|
88
|
+
this.failure = error;
|
|
89
|
+
this.chunks.length = 0;
|
|
90
|
+
this.wake?.();
|
|
91
|
+
const errors = this.listeners.get("error"), close = this.listeners.get("close");
|
|
92
|
+
this.listeners.clear();
|
|
93
|
+
if (error !== void 0) for (const listener of errors ?? []) listener(error);
|
|
94
|
+
for (const listener of close ?? []) listener();
|
|
95
|
+
return this;
|
|
96
|
+
}
|
|
97
|
+
async *[Symbol.asyncIterator]() {
|
|
98
|
+
try {
|
|
99
|
+
for (; ; ) {
|
|
100
|
+
if (this.failure !== void 0) throw this.failure;
|
|
101
|
+
const chunk = this.chunks.shift();
|
|
102
|
+
if (chunk !== void 0) {
|
|
103
|
+
yield chunk;
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
if (this.writableEnded || this.destroyed) return;
|
|
107
|
+
await new Promise((resolve) => {
|
|
108
|
+
this.wake = resolve;
|
|
109
|
+
});
|
|
110
|
+
this.wake = void 0;
|
|
111
|
+
}
|
|
112
|
+
} finally {
|
|
113
|
+
this.destroy();
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
};
|
|
62
117
|
|
|
63
118
|
// src/http-message-validation.ts
|
|
64
119
|
var subscriptionMethods = /* @__PURE__ */ new Set([
|
|
@@ -1255,7 +1310,11 @@ var JSON_RPC_ERROR_CODES = Object.freeze({
|
|
|
1255
1310
|
function isBase64(value) {
|
|
1256
1311
|
if (value.length % 4 !== 0)
|
|
1257
1312
|
return false;
|
|
1258
|
-
|
|
1313
|
+
try {
|
|
1314
|
+
return btoa(atob(value)) === value;
|
|
1315
|
+
} catch {
|
|
1316
|
+
return false;
|
|
1317
|
+
}
|
|
1259
1318
|
}
|
|
1260
1319
|
|
|
1261
1320
|
// ../tiny-stdio-mcp-server/dist/uri.js
|
|
@@ -3549,15 +3608,15 @@ function createOAuthClientProvider(options) {
|
|
|
3549
3608
|
|
|
3550
3609
|
// ../tiny-stdio-mcp-server/dist/headers.js
|
|
3551
3610
|
function encodeHeaderValue(value) {
|
|
3552
|
-
const bytes =
|
|
3553
|
-
if (
|
|
3611
|
+
const bytes = new TextEncoder().encode(value);
|
|
3612
|
+
if (new TextDecoder("utf-8", { ignoreBOM: true }).decode(bytes) !== value)
|
|
3554
3613
|
throw new Error("MCP header value must contain valid Unicode");
|
|
3555
3614
|
const sentinel = value.startsWith("=?base64?") && value.endsWith("?=");
|
|
3556
3615
|
const unsafe = value.trim() !== value || [...value].some((character) => {
|
|
3557
3616
|
const code = character.charCodeAt(0);
|
|
3558
3617
|
return code !== 9 && (code < 32 || code > 126);
|
|
3559
3618
|
});
|
|
3560
|
-
return sentinel || unsafe ? `=?base64?${bytes.
|
|
3619
|
+
return sentinel || unsafe ? `=?base64?${btoa(Array.from(bytes, (byte) => String.fromCharCode(byte)).join(""))}?=` : value;
|
|
3561
3620
|
}
|
|
3562
3621
|
var schemaMaps = /* @__PURE__ */ new Set([
|
|
3563
3622
|
"properties",
|
|
@@ -3993,6 +4052,10 @@ var OAuthMetadataDiscovery = class {
|
|
|
3993
4052
|
);
|
|
3994
4053
|
}
|
|
3995
4054
|
};
|
|
4055
|
+
async function discoverOAuthMetadata(resourceUrl, options = {}) {
|
|
4056
|
+
const discovery = new OAuthMetadataDiscovery(options);
|
|
4057
|
+
return discovery.discover(resourceUrl, options);
|
|
4058
|
+
}
|
|
3996
4059
|
function skipOptionalWhitespace(value, start) {
|
|
3997
4060
|
let index = start;
|
|
3998
4061
|
while (index < value.length && (value[index] === " " || value[index] === " ")) {
|
|
@@ -5187,7 +5250,7 @@ var HttpTransport = class {
|
|
|
5187
5250
|
if (this.legacyProtocolVersion !== void 0) headers.set("MCP-Protocol-Version", this.legacyProtocolVersion);
|
|
5188
5251
|
if (this.lastEventId !== void 0) {
|
|
5189
5252
|
if (this.lastEventId === "") headers.delete("Last-Event-ID");
|
|
5190
|
-
else headers.set("Last-Event-ID",
|
|
5253
|
+
else headers.set("Last-Event-ID", Array.from(new TextEncoder().encode(this.lastEventId), (byte) => String.fromCharCode(byte)).join(""));
|
|
5191
5254
|
}
|
|
5192
5255
|
return this.authorizeRequestHeaders(headers, signal);
|
|
5193
5256
|
}
|
|
@@ -5616,7 +5679,7 @@ async function* readLines(stream, maxLineBytes = 16 * 1024 * 1024) {
|
|
|
5616
5679
|
let bytes = 0;
|
|
5617
5680
|
const decoder = new TextDecoder("utf-8", { fatal: true });
|
|
5618
5681
|
const append = (part) => {
|
|
5619
|
-
bytes +=
|
|
5682
|
+
bytes += new TextEncoder().encode(part).byteLength;
|
|
5620
5683
|
if (bytes > maxLineBytes) throw new Error(`Stdio input line byte limit exceeded (${maxLineBytes} bytes)`);
|
|
5621
5684
|
if (part.length > 0) parts.push(part);
|
|
5622
5685
|
};
|
|
@@ -5677,7 +5740,7 @@ var SseParser = class {
|
|
|
5677
5740
|
else if (index === this.buffer.length - 1) this.skipLf = true;
|
|
5678
5741
|
}
|
|
5679
5742
|
start = index + 1;
|
|
5680
|
-
if (
|
|
5743
|
+
if (new TextEncoder().encode(line).byteLength > this.maxEventBytes)
|
|
5681
5744
|
throw new Error(`SSE event exceeds ${this.maxEventBytes} bytes`);
|
|
5682
5745
|
this.consumeLine(line, messages);
|
|
5683
5746
|
this.assertEventSize("");
|
|
@@ -5709,7 +5772,7 @@ var SseParser = class {
|
|
|
5709
5772
|
return;
|
|
5710
5773
|
}
|
|
5711
5774
|
if (field === "data") {
|
|
5712
|
-
this.dataBytes +=
|
|
5775
|
+
this.dataBytes += new TextEncoder().encode(value).byteLength + (this.dataLines.length > 0 ? 1 : 0);
|
|
5713
5776
|
this.dataLines.push(value);
|
|
5714
5777
|
return;
|
|
5715
5778
|
}
|
|
@@ -5748,7 +5811,7 @@ var SseParser = class {
|
|
|
5748
5811
|
this.dataBytes = 0;
|
|
5749
5812
|
}
|
|
5750
5813
|
assertEventSize(partialLine) {
|
|
5751
|
-
if (this.dataBytes +
|
|
5814
|
+
if (this.dataBytes + new TextEncoder().encode(this.eventType ?? "").byteLength + new TextEncoder().encode(this.eventId).byteLength + new TextEncoder().encode(partialLine).byteLength > this.maxEventBytes)
|
|
5752
5815
|
throw new Error(`SSE event exceeds ${this.maxEventBytes} bytes`);
|
|
5753
5816
|
}
|
|
5754
5817
|
};
|
|
@@ -6466,6 +6529,7 @@ export {
|
|
|
6466
6529
|
McpError,
|
|
6467
6530
|
OAuthMetadataDiscovery,
|
|
6468
6531
|
OAuthMetadataError,
|
|
6532
|
+
discoverOAuthMetadata,
|
|
6469
6533
|
snapshotHttpTransportHeaders
|
|
6470
6534
|
};
|
|
6471
6535
|
/*!
|