toolcraft 0.0.343 → 0.0.345
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/tiny-http-mcp-server/dist/composition.json +1 -1
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/README.md +17 -3
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/loopback-authorization.d.ts +8 -0
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/loopback-authorization.js +44 -21
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/token-endpoint.d.ts +2 -0
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/token-endpoint.js +8 -0
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/index.d.ts +1 -1
- package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/index.js +1 -1
- package/node_modules/tiny-http-mcp-server/package.json +1 -1
- package/node_modules/tiny-mcp-client/README.md +4 -0
- package/node_modules/tiny-mcp-client/dist/index.d.ts +3 -1
- package/node_modules/tiny-mcp-client/dist/index.js +64 -25
- package/node_modules/tiny-stdio-mcp-server/dist/composition.json +1 -1
- 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.71",
|
|
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.345",
|
|
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.345",
|
|
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.71",
|
|
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.345",
|
|
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.345",
|
|
127
127
|
"license": "MIT"
|
|
128
128
|
},
|
|
129
129
|
{
|
|
@@ -24,10 +24,15 @@ const verifier = createJwksTokenVerifier({
|
|
|
24
24
|
|
|
25
25
|
## Public API
|
|
26
26
|
|
|
27
|
+
`OAuthError.is(value)` recognizes native token/challenge failures across separately
|
|
28
|
+
bundled package copies while preserving the SDK diagnostic fields. Error names
|
|
29
|
+
alone do not establish either native error type.
|
|
30
|
+
|
|
27
31
|
- `createDefaultOAuthClientProvider(options)`: default MCP OAuth client provider with dynamic or static client registration.
|
|
28
32
|
- `createOAuthClientProvider(options)`: lower-level provider constructor.
|
|
29
33
|
- `createAuthStoreSessionStore(options)`: persisted OAuth session store backed by `auth-store`.
|
|
30
34
|
- `createLoopbackAuthorizationSession(options)`: local callback server for browser authorization.
|
|
35
|
+
- `OAuthAuthorizationError`: a callback denial with its original `error`, `errorDescription` and message for host observers. Use `OAuthAuthorizationError.is(value)` to recognize errors across separately bundled package copies.
|
|
31
36
|
- `generateCodeVerifier()` and `generateCodeChallenge(...)`: PKCE helpers.
|
|
32
37
|
- `normalizeStoredOAuthClient(value)`: normalize a saved client identity, full registration and ownership marker.
|
|
33
38
|
- `normalizeOAuthScope(value)`: validate scope syntax and normalize its case-sensitive set.
|
|
@@ -86,14 +91,21 @@ later environment changes cannot move a transaction between file and Keychain.
|
|
|
86
91
|
Fixed redirects support `localhost`, `127.0.0.1`, and `::1` over HTTP. Their
|
|
87
92
|
exact spelling, port, path and query are preserved through registration,
|
|
88
93
|
authorization and code exchange. Credentials, fragments, port zero and reserved
|
|
89
|
-
OAuth callback query parameters are rejected before binding a listener.
|
|
94
|
+
OAuth callback query parameters, including `error_uri`, are rejected before binding a listener.
|
|
90
95
|
`createDefaultOAuthClientProvider` also checks the configured redirect before
|
|
91
96
|
creating the provider. Imported tokens that cannot be sent as HTTP header
|
|
92
97
|
values fail with diagnostics that omit their contents. Omit
|
|
93
98
|
`redirectUri` to allocate a random loopback port. Standalone callback sessions
|
|
94
|
-
accept the same `redirectUri`, `signal` and `timeoutMs` options.
|
|
99
|
+
accept the same `redirectUri`, `signal` and `timeoutMs` options. They capture configuration,
|
|
100
|
+
landing-page data and selected callbacks before invoking a host listener factory;
|
|
101
|
+
original signals and selected callback receivers/live method state remain active. Cancellation,
|
|
95
102
|
timeout and explicit close settle pending code waits and release listeners.
|
|
96
|
-
Always close a
|
|
103
|
+
Always close a standalone session in `finally`. Failed callback responses declare
|
|
104
|
+
plain UTF-8 text with content sniffing disabled; provider markup remains literal
|
|
105
|
+
text. Successful landing pages remain HTML with escaped custom title/body. Recognized
|
|
106
|
+
OAuth callback parameters must occur only once in HTTP callbacks or pasted URLs;
|
|
107
|
+
duplicates fail without reflecting values and code extraction returns null.
|
|
108
|
+
Unrecognized extension parameters remain ignored, including repeated fields.
|
|
97
109
|
|
|
98
110
|
Native provider calls capture request option handles before host work. Unauthorized
|
|
99
111
|
handling also owns complete discovery metadata, presented grant values, rejected
|
|
@@ -261,6 +273,8 @@ Before sending a refresh request, the provider persists a tokenless session with
|
|
|
261
273
|
A successful response replaces it with the rotated grant. A crash, cancellation,
|
|
262
274
|
network disconnect or incomplete response leaves the marker, so another process
|
|
263
275
|
cannot replay a possibly consumed refresh token or revive the initial import.
|
|
276
|
+
An explicit `refresh_token` must be a nonempty string; malformed fields also
|
|
277
|
+
retain the pending marker. Omitting it preserves the previous refresh token.
|
|
264
278
|
Such a session requires fresh authorization. Interactive unauthorized handling
|
|
265
279
|
can recover it; headless requests fail with an explicit unknown-outcome error.
|
|
266
280
|
Only complete OAuth error responses establish a rejected request and allow a
|
|
@@ -20,6 +20,14 @@ export interface LoopbackAuthorizationSession {
|
|
|
20
20
|
waitForCode(authorizationUrl: string): Promise<string>;
|
|
21
21
|
close(): void;
|
|
22
22
|
}
|
|
23
|
+
/** Authorization callback denial, retaining the provider diagnostic for host observers. */
|
|
24
|
+
export declare class OAuthAuthorizationError extends Error {
|
|
25
|
+
readonly error: string;
|
|
26
|
+
readonly errorDescription: string;
|
|
27
|
+
/** Recognize errors from separately bundled copies of this package. */
|
|
28
|
+
static is(value: unknown): value is OAuthAuthorizationError;
|
|
29
|
+
constructor(error: string, errorDescription: string);
|
|
30
|
+
}
|
|
23
31
|
export declare function createLoopbackAuthorizationSession(options?: LoopbackAuthorizationOptions): Promise<LoopbackAuthorizationSession>;
|
|
24
32
|
export declare function loopbackTarget(options: LoopbackAuthorizationOptions): {
|
|
25
33
|
port: number;
|
|
@@ -1,6 +1,28 @@
|
|
|
1
1
|
import http from "node:http";
|
|
2
2
|
import { parseAuthorizationState } from "./authorization-state.js";
|
|
3
|
+
const authorizationErrorBrand = Symbol.for("poe-platform.mcp-oauth.OAuthAuthorizationError");
|
|
4
|
+
const oauthCallbackParameters = ["code", "state", "iss", "error", "error_description", "error_uri"];
|
|
5
|
+
/** Authorization callback denial, retaining the provider diagnostic for host observers. */
|
|
6
|
+
export class OAuthAuthorizationError extends Error {
|
|
7
|
+
error;
|
|
8
|
+
errorDescription;
|
|
9
|
+
/** Recognize errors from separately bundled copies of this package. */
|
|
10
|
+
static is(value) {
|
|
11
|
+
return value instanceof Error && Object.getOwnPropertyDescriptor(value, authorizationErrorBrand)?.value === true;
|
|
12
|
+
}
|
|
13
|
+
constructor(error, errorDescription) {
|
|
14
|
+
super(`OAuth authorization failed: ${error} — ${errorDescription}`);
|
|
15
|
+
this.error = error;
|
|
16
|
+
this.errorDescription = errorDescription;
|
|
17
|
+
this.name = "OAuthAuthorizationError";
|
|
18
|
+
Object.defineProperty(this, authorizationErrorBrand, { value: true });
|
|
19
|
+
}
|
|
20
|
+
}
|
|
3
21
|
export async function createLoopbackAuthorizationSession(options = {}) {
|
|
22
|
+
const selected = { ...options };
|
|
23
|
+
options = { ...selected, createServer: selected.createServer?.bind(options),
|
|
24
|
+
openBrowser: selected.openBrowser?.bind(options), readLine: selected.readLine?.bind(options),
|
|
25
|
+
landingPage: selected.landingPage === undefined ? undefined : { ...selected.landingPage } };
|
|
4
26
|
options.signal?.throwIfAborted();
|
|
5
27
|
const timeoutMs = options.timeoutMs ?? 120_000;
|
|
6
28
|
if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > 2_147_483_647)
|
|
@@ -63,10 +85,9 @@ export function loopbackTarget(options) {
|
|
|
63
85
|
catch (cause) {
|
|
64
86
|
throw new Error("Invalid OAuth loopback redirect URI", { cause });
|
|
65
87
|
}
|
|
66
|
-
const forbiddenQuery = ["code", "state", "error", "error_description", "iss"];
|
|
67
88
|
if (url.protocol !== "http:" || !["localhost", "127.0.0.1", "[::1]"].includes(url.hostname)
|
|
68
89
|
|| url.username || url.password || url.hash || url.port === "0"
|
|
69
|
-
||
|
|
90
|
+
|| oauthCallbackParameters.some(name => url.searchParams.has(name))
|
|
70
91
|
|| [...options.redirectUri].some(char => char.codePointAt(0) <= 32)
|
|
71
92
|
|| (options.callbackPath !== undefined && options.callbackPath !== url.pathname))
|
|
72
93
|
throw new Error("Invalid OAuth loopback redirect URI");
|
|
@@ -137,21 +158,18 @@ function waitForAuthorizationCode(server, authorizationUrl, options, callbackPat
|
|
|
137
158
|
res.end("Not found");
|
|
138
159
|
return;
|
|
139
160
|
}
|
|
140
|
-
const callbackParameters = {
|
|
141
|
-
code: url.searchParams.get("code"), error: url.searchParams.get("error"),
|
|
142
|
-
errorDescription: url.searchParams.get("error_description"), state: url.searchParams.get("state"), iss: url.searchParams.get("iss")
|
|
143
|
-
};
|
|
144
161
|
try {
|
|
162
|
+
const callbackParameters = readAuthorizationCallbackParameters(url);
|
|
145
163
|
validateAuthorizationCallbackBinding(callbackParameters, expectedAuthorization);
|
|
146
164
|
if (callbackParameters.error !== null)
|
|
147
|
-
throw
|
|
165
|
+
throw new OAuthAuthorizationError(callbackParameters.error, callbackParameters.errorDescription ?? callbackParameters.error);
|
|
148
166
|
const code = validateAuthorizationCallbackParameters(callbackParameters, expectedAuthorization);
|
|
149
167
|
res.writeHead(200, { "Content-Type": "text/html" });
|
|
150
168
|
res.end(buildSuccessPage(options.landingPage));
|
|
151
169
|
settle(() => resolve(code));
|
|
152
170
|
}
|
|
153
171
|
catch (error) {
|
|
154
|
-
res.writeHead(400);
|
|
172
|
+
res.writeHead(400, { "Content-Type": "text/plain; charset=utf-8", "X-Content-Type-Options": "nosniff" });
|
|
155
173
|
res.end(error instanceof Error ? error.message : "Invalid OAuth callback");
|
|
156
174
|
settle(() => reject(error));
|
|
157
175
|
}
|
|
@@ -167,7 +185,7 @@ function waitForAuthorizationCode(server, authorizationUrl, options, callbackPat
|
|
|
167
185
|
throw new Error("OAuth callback missing authorization code");
|
|
168
186
|
validateAuthorizationCallbackBinding(callbackParameters, expectedAuthorization);
|
|
169
187
|
if (callbackParameters.error !== null)
|
|
170
|
-
throw
|
|
188
|
+
throw new OAuthAuthorizationError(callbackParameters.error, callbackParameters.errorDescription ?? callbackParameters.error);
|
|
171
189
|
const code = validateAuthorizationCallbackParameters(callbackParameters, expectedAuthorization);
|
|
172
190
|
settle(() => resolve(code));
|
|
173
191
|
}).catch(error => settle(() => reject(error)));
|
|
@@ -179,22 +197,21 @@ function waitForAuthorizationCode(server, authorizationUrl, options, callbackPat
|
|
|
179
197
|
});
|
|
180
198
|
}
|
|
181
199
|
export function extractCodeFromInput(input) {
|
|
182
|
-
|
|
200
|
+
try {
|
|
201
|
+
return extractCallbackParametersFromInput(input)?.code ?? null;
|
|
202
|
+
}
|
|
203
|
+
catch {
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
183
206
|
}
|
|
184
207
|
function extractCallbackParametersFromInput(input) {
|
|
185
208
|
const trimmed = input.replaceAll("\r", "").replaceAll("\n", "").trim();
|
|
186
209
|
if (trimmed.length === 0) {
|
|
187
210
|
return null;
|
|
188
211
|
}
|
|
212
|
+
let url;
|
|
189
213
|
try {
|
|
190
|
-
|
|
191
|
-
return {
|
|
192
|
-
code: url.searchParams.get("code"),
|
|
193
|
-
error: url.searchParams.get("error"),
|
|
194
|
-
errorDescription: url.searchParams.get("error_description"),
|
|
195
|
-
state: url.searchParams.get("state"),
|
|
196
|
-
iss: url.searchParams.get("iss")
|
|
197
|
-
};
|
|
214
|
+
url = new URL(trimmed);
|
|
198
215
|
}
|
|
199
216
|
catch {
|
|
200
217
|
return {
|
|
@@ -205,6 +222,15 @@ function extractCallbackParametersFromInput(input) {
|
|
|
205
222
|
iss: null
|
|
206
223
|
};
|
|
207
224
|
}
|
|
225
|
+
return readAuthorizationCallbackParameters(url);
|
|
226
|
+
}
|
|
227
|
+
function readAuthorizationCallbackParameters(url) {
|
|
228
|
+
for (const parameter of oauthCallbackParameters) {
|
|
229
|
+
if (url.searchParams.getAll(parameter).length > 1)
|
|
230
|
+
throw new Error(`OAuth callback parameter '${parameter}' must occur only once`);
|
|
231
|
+
}
|
|
232
|
+
return { code: url.searchParams.get("code"), error: url.searchParams.get("error"),
|
|
233
|
+
errorDescription: url.searchParams.get("error_description"), state: url.searchParams.get("state"), iss: url.searchParams.get("iss") };
|
|
208
234
|
}
|
|
209
235
|
function readExpectedAuthorizationCallback(authorizationUrl) {
|
|
210
236
|
const url = new URL(authorizationUrl);
|
|
@@ -244,9 +270,6 @@ function validateAuthorizationCallbackBinding(callback, expected) {
|
|
|
244
270
|
throw new Error("OAuth callback issuer mismatch");
|
|
245
271
|
}
|
|
246
272
|
}
|
|
247
|
-
function createAuthorizationError(error, description) {
|
|
248
|
-
return new Error(`OAuth authorization failed: ${error} — ${description}`);
|
|
249
|
-
}
|
|
250
273
|
function escapeHtml(text) {
|
|
251
274
|
return text
|
|
252
275
|
.replaceAll("&", "&")
|
package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/token-endpoint.d.ts
CHANGED
|
@@ -5,6 +5,8 @@ interface OAuthErrorShape {
|
|
|
5
5
|
error_uri?: string;
|
|
6
6
|
}
|
|
7
7
|
export declare class OAuthError extends Error {
|
|
8
|
+
/** Recognize errors from separately bundled copies of this package. */
|
|
9
|
+
static is(value: unknown): value is OAuthError;
|
|
8
10
|
readonly error: string;
|
|
9
11
|
readonly errorDescription: string | undefined;
|
|
10
12
|
readonly errorUri: string | undefined;
|
package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/token-endpoint.js
CHANGED
|
@@ -4,7 +4,12 @@ import { readBoundedResponseText } from "../http-response.js";
|
|
|
4
4
|
import { fetchMcpResponse } from "../http-fetch.js";
|
|
5
5
|
import { normalizeOAuthScope } from "./scope.js";
|
|
6
6
|
const MAX_JS_DATE_MS = 8_640_000_000_000_000;
|
|
7
|
+
const oauthErrorBrand = Symbol.for("poe-platform.mcp-oauth.OAuthError");
|
|
7
8
|
export class OAuthError extends Error {
|
|
9
|
+
/** Recognize errors from separately bundled copies of this package. */
|
|
10
|
+
static is(value) {
|
|
11
|
+
return value instanceof Error && Object.getOwnPropertyDescriptor(value, oauthErrorBrand)?.value === true;
|
|
12
|
+
}
|
|
8
13
|
error;
|
|
9
14
|
errorDescription;
|
|
10
15
|
errorUri;
|
|
@@ -20,6 +25,7 @@ export class OAuthError extends Error {
|
|
|
20
25
|
const uri = Object.hasOwn(shape, "error_uri") ? shape.error_uri : undefined;
|
|
21
26
|
super(description ?? (outcomeKnown ? shape.error : `OAuth HTTP response did not contain a valid error (HTTP ${status})`));
|
|
22
27
|
this.name = "OAuthError";
|
|
28
|
+
Object.defineProperty(this, oauthErrorBrand, { value: true });
|
|
23
29
|
this.error = shape.error;
|
|
24
30
|
this.errorDescription = description;
|
|
25
31
|
this.errorUri = uri;
|
|
@@ -132,6 +138,8 @@ async function requestTokens(input) {
|
|
|
132
138
|
}
|
|
133
139
|
}
|
|
134
140
|
const refreshToken = getOwnEntry(payload, "refresh_token");
|
|
141
|
+
if (refreshToken !== undefined && (typeof refreshToken !== "string" || refreshToken.trim().length === 0))
|
|
142
|
+
throw new Error("OAuth token response has invalid refresh_token");
|
|
135
143
|
const scope = getOwnEntry(payload, "scope");
|
|
136
144
|
const normalizedRefreshToken = typeof refreshToken === "string" && refreshToken.trim().length > 0
|
|
137
145
|
? refreshToken.trim()
|
|
@@ -7,7 +7,7 @@ export { createResourceBoundOAuthStores } from "./client/resource-bound-store.js
|
|
|
7
7
|
export type { ResourceBoundOAuthStores } from "./client/resource-bound-store.js";
|
|
8
8
|
export { parseOAuthClientRegistration, normalizeStoredOAuthClient } from "./client/client-registration.js";
|
|
9
9
|
export { createDefaultOAuthClientProvider, createOAuthClientProvider, } from "./client/default-oauth-client-provider.js";
|
|
10
|
-
export { buildSuccessPage, createLoopbackAuthorizationSession, extractCodeFromInput, } from "./client/loopback-authorization.js";
|
|
10
|
+
export { buildSuccessPage, createLoopbackAuthorizationSession, extractCodeFromInput, OAuthAuthorizationError, } from "./client/loopback-authorization.js";
|
|
11
11
|
export { generateCodeChallenge, generateCodeVerifier, } from "./client/pkce.js";
|
|
12
12
|
export { OAuthError, } from "./client/token-endpoint.js";
|
|
13
13
|
export { canonicalizeResourceIndicator, } from "./resource-indicator.js";
|
|
@@ -5,7 +5,7 @@ export { createAuthStoreSessionStore, } from "./client/auth-store-session-store.
|
|
|
5
5
|
export { createResourceBoundOAuthStores } from "./client/resource-bound-store.js";
|
|
6
6
|
export { parseOAuthClientRegistration, normalizeStoredOAuthClient } from "./client/client-registration.js";
|
|
7
7
|
export { createDefaultOAuthClientProvider, createOAuthClientProvider, } from "./client/default-oauth-client-provider.js";
|
|
8
|
-
export { buildSuccessPage, createLoopbackAuthorizationSession, extractCodeFromInput, } from "./client/loopback-authorization.js";
|
|
8
|
+
export { buildSuccessPage, createLoopbackAuthorizationSession, extractCodeFromInput, OAuthAuthorizationError, } from "./client/loopback-authorization.js";
|
|
9
9
|
export { generateCodeChallenge, generateCodeVerifier, } from "./client/pkce.js";
|
|
10
10
|
export { OAuthError, } from "./client/token-endpoint.js";
|
|
11
11
|
export { canonicalizeResourceIndicator, } from "./resource-indicator.js";
|
|
@@ -58,6 +58,10 @@ Legacy SSE mode opens a GET stream and posts messages to the endpoint announced
|
|
|
58
58
|
by the server. Announced endpoints must remain on the original origin without
|
|
59
59
|
embedded credentials or fragments; endpoint changes close the connection.
|
|
60
60
|
Both transports accept the same headers, OAuth provider and response limits.
|
|
61
|
+
Static HTTP headers are copied and validated when the transport is constructed,
|
|
62
|
+
before OAuth callbacks run. Invalid headers fail without reflecting their values.
|
|
63
|
+
Use `snapshotHttpTransportHeaders(headers)` to apply the same ownership and safe
|
|
64
|
+
validation when preparing a registry before constructing transports.
|
|
61
65
|
`maxResponseBytes` bounds a complete JSON body or each SSE event (default 16 MiB).
|
|
62
66
|
Receive streams may carry many bounded events and keepalive comments; the limit
|
|
63
67
|
does not cap their lifetime bytes. Use request deadlines and cancellation to
|
|
@@ -725,6 +725,8 @@ declare class StdioTransport implements McpTransport {
|
|
|
725
725
|
private appendStderrOutput;
|
|
726
726
|
dispose(reason?: Error): void;
|
|
727
727
|
}
|
|
728
|
+
/** Own and validate static HTTP headers without reflecting malformed values. */
|
|
729
|
+
declare function snapshotHttpTransportHeaders(headers?: RequestInit["headers"]): Headers;
|
|
728
730
|
declare class HttpTransport implements McpTransport {
|
|
729
731
|
readonly readable: Readable;
|
|
730
732
|
readonly writable: Writable;
|
|
@@ -872,5 +874,5 @@ declare class JsonRpcMessageLayer {
|
|
|
872
874
|
private handleCancellationNotification;
|
|
873
875
|
}
|
|
874
876
|
|
|
875
|
-
export { ERROR_INTERNAL, ERROR_INVALID_PARAMS, ERROR_INVALID_REQUEST, ERROR_METHOD_NOT_FOUND, ERROR_PARSE, HttpTransport, HttpTransportError, JsonRpcMessageLayer, MCP_PROTOCOL_VERSIONS, McpClient, McpError, OAuthMetadataDiscovery, StdioTransport, createInMemoryTransportPair, createSdkTestPair, createTestPair, discoverOAuthMetadata, fetchMcpResponse };
|
|
877
|
+
export { ERROR_INTERNAL, ERROR_INVALID_PARAMS, ERROR_INVALID_REQUEST, ERROR_METHOD_NOT_FOUND, ERROR_PARSE, HttpTransport, HttpTransportError, JsonRpcMessageLayer, MCP_PROTOCOL_VERSIONS, McpClient, McpError, OAuthMetadataDiscovery, StdioTransport, createInMemoryTransportPair, createSdkTestPair, createTestPair, discoverOAuthMetadata, fetchMcpResponse, snapshotHttpTransportHeaders };
|
|
876
878
|
export type { AudioContent, BlobResourceContents, CacheableResultMetadata, CallToolOptions, CallToolParams, CallToolResult, ClientCapabilities, CompleteArgument, CompleteParams, CompleteResult, Completion, ConnectResult, ContentItem, CreateMessageParams, CreateMessageResult, ElicitationParams, ElicitationResult, EmbeddedResource, GetPromptParams, GetPromptResult, HttpTransportFetch, HttpTransportOptions, ImageContent, InMemoryTransportPair, IncludeContext, InitializeParams, InitializeResult, JsonRpcErrorObject, JsonRpcErrorResponse, JsonRpcMessage, JsonRpcNotification, JsonRpcRequest, JsonRpcRequestOptions, JsonRpcResponse, JsonRpcSuccessResponse, LogLevel, LogMessage, McpClientConnection, McpClientOptions, McpProtocolVersion, McpRequestContext, McpSubscription, McpTransport, McpTransportClosedEvent, ModelHint, ModelPreferences, NotificationFilter, OAuthAuthorizationServerMetadata, OAuthClientProvider, OAuthClientProviderOptions, OAuthDiscoveryCache, OAuthDiscoveryResult, OAuthMetadataFetch, OAuthProtectedResourceMetadata, OAuthSessionStore, OAuthUnauthorizedChallenge, PaginatedParams, PaginatedResult, ProgressParams, ProgressToken, PromptMessage, PromptReference, ReadResourceParams, RequestId, ResourceContents, ResourceReference, ResultMetadata, Root, SamplingContent, SamplingMessage, SdkTestPair, ServerCapabilities, StdioSpawn, StdioTransportOptions, StoredOAuthSession, SubscriptionOptions, TextContent, TextResourceContents, Tool, ToolResultContent, ToolUseContent };
|
|
@@ -3516,7 +3516,32 @@ function getOwnEntry(record2, key2) {
|
|
|
3516
3516
|
}
|
|
3517
3517
|
|
|
3518
3518
|
// ../mcp-oauth/dist/client/loopback-authorization.js
|
|
3519
|
+
var authorizationErrorBrand = /* @__PURE__ */ Symbol.for("poe-platform.mcp-oauth.OAuthAuthorizationError");
|
|
3520
|
+
var oauthCallbackParameters = ["code", "state", "iss", "error", "error_description", "error_uri"];
|
|
3521
|
+
var OAuthAuthorizationError = class extends Error {
|
|
3522
|
+
error;
|
|
3523
|
+
errorDescription;
|
|
3524
|
+
/** Recognize errors from separately bundled copies of this package. */
|
|
3525
|
+
static is(value) {
|
|
3526
|
+
return value instanceof Error && Object.getOwnPropertyDescriptor(value, authorizationErrorBrand)?.value === true;
|
|
3527
|
+
}
|
|
3528
|
+
constructor(error, errorDescription) {
|
|
3529
|
+
super(`OAuth authorization failed: ${error} \u2014 ${errorDescription}`);
|
|
3530
|
+
this.error = error;
|
|
3531
|
+
this.errorDescription = errorDescription;
|
|
3532
|
+
this.name = "OAuthAuthorizationError";
|
|
3533
|
+
Object.defineProperty(this, authorizationErrorBrand, { value: true });
|
|
3534
|
+
}
|
|
3535
|
+
};
|
|
3519
3536
|
async function createLoopbackAuthorizationSession(options = {}) {
|
|
3537
|
+
const selected = { ...options };
|
|
3538
|
+
options = {
|
|
3539
|
+
...selected,
|
|
3540
|
+
createServer: selected.createServer?.bind(options),
|
|
3541
|
+
openBrowser: selected.openBrowser?.bind(options),
|
|
3542
|
+
readLine: selected.readLine?.bind(options),
|
|
3543
|
+
landingPage: selected.landingPage === void 0 ? void 0 : { ...selected.landingPage }
|
|
3544
|
+
};
|
|
3520
3545
|
options.signal?.throwIfAborted();
|
|
3521
3546
|
const timeoutMs = options.timeoutMs ?? 12e4;
|
|
3522
3547
|
if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > 2147483647)
|
|
@@ -3576,8 +3601,7 @@ function loopbackTarget(options) {
|
|
|
3576
3601
|
} catch (cause) {
|
|
3577
3602
|
throw new Error("Invalid OAuth loopback redirect URI", { cause });
|
|
3578
3603
|
}
|
|
3579
|
-
|
|
3580
|
-
if (url.protocol !== "http:" || !["localhost", "127.0.0.1", "[::1]"].includes(url.hostname) || url.username || url.password || url.hash || url.port === "0" || forbiddenQuery.some((name) => url.searchParams.has(name)) || [...options.redirectUri].some((char) => char.codePointAt(0) <= 32) || options.callbackPath !== void 0 && options.callbackPath !== url.pathname)
|
|
3604
|
+
if (url.protocol !== "http:" || !["localhost", "127.0.0.1", "[::1]"].includes(url.hostname) || url.username || url.password || url.hash || url.port === "0" || oauthCallbackParameters.some((name) => url.searchParams.has(name)) || [...options.redirectUri].some((char) => char.codePointAt(0) <= 32) || options.callbackPath !== void 0 && options.callbackPath !== url.pathname)
|
|
3581
3605
|
throw new Error("Invalid OAuth loopback redirect URI");
|
|
3582
3606
|
return { port: url.port ? Number(url.port) : 80, host: url.hostname === "[::1]" ? "::1" : url.hostname, callbackPath: url.pathname };
|
|
3583
3607
|
}
|
|
@@ -3653,23 +3677,17 @@ function waitForAuthorizationCode(server, authorizationUrl, options, callbackPat
|
|
|
3653
3677
|
res.end("Not found");
|
|
3654
3678
|
return;
|
|
3655
3679
|
}
|
|
3656
|
-
const callbackParameters = {
|
|
3657
|
-
code: url.searchParams.get("code"),
|
|
3658
|
-
error: url.searchParams.get("error"),
|
|
3659
|
-
errorDescription: url.searchParams.get("error_description"),
|
|
3660
|
-
state: url.searchParams.get("state"),
|
|
3661
|
-
iss: url.searchParams.get("iss")
|
|
3662
|
-
};
|
|
3663
3680
|
try {
|
|
3681
|
+
const callbackParameters = readAuthorizationCallbackParameters(url);
|
|
3664
3682
|
validateAuthorizationCallbackBinding(callbackParameters, expectedAuthorization);
|
|
3665
3683
|
if (callbackParameters.error !== null)
|
|
3666
|
-
throw
|
|
3684
|
+
throw new OAuthAuthorizationError(callbackParameters.error, callbackParameters.errorDescription ?? callbackParameters.error);
|
|
3667
3685
|
const code = validateAuthorizationCallbackParameters(callbackParameters, expectedAuthorization);
|
|
3668
3686
|
res.writeHead(200, { "Content-Type": "text/html" });
|
|
3669
3687
|
res.end(buildSuccessPage(options.landingPage));
|
|
3670
3688
|
settle(() => resolve(code));
|
|
3671
3689
|
} catch (error) {
|
|
3672
|
-
res.writeHead(400);
|
|
3690
|
+
res.writeHead(400, { "Content-Type": "text/plain; charset=utf-8", "X-Content-Type-Options": "nosniff" });
|
|
3673
3691
|
res.end(error instanceof Error ? error.message : "Invalid OAuth callback");
|
|
3674
3692
|
settle(() => reject(error));
|
|
3675
3693
|
}
|
|
@@ -3685,7 +3703,7 @@ function waitForAuthorizationCode(server, authorizationUrl, options, callbackPat
|
|
|
3685
3703
|
throw new Error("OAuth callback missing authorization code");
|
|
3686
3704
|
validateAuthorizationCallbackBinding(callbackParameters, expectedAuthorization);
|
|
3687
3705
|
if (callbackParameters.error !== null)
|
|
3688
|
-
throw
|
|
3706
|
+
throw new OAuthAuthorizationError(callbackParameters.error, callbackParameters.errorDescription ?? callbackParameters.error);
|
|
3689
3707
|
const code = validateAuthorizationCallbackParameters(callbackParameters, expectedAuthorization);
|
|
3690
3708
|
settle(() => resolve(code));
|
|
3691
3709
|
}).catch((error) => settle(() => reject(error)));
|
|
@@ -3700,15 +3718,9 @@ function extractCallbackParametersFromInput(input) {
|
|
|
3700
3718
|
if (trimmed.length === 0) {
|
|
3701
3719
|
return null;
|
|
3702
3720
|
}
|
|
3721
|
+
let url;
|
|
3703
3722
|
try {
|
|
3704
|
-
|
|
3705
|
-
return {
|
|
3706
|
-
code: url.searchParams.get("code"),
|
|
3707
|
-
error: url.searchParams.get("error"),
|
|
3708
|
-
errorDescription: url.searchParams.get("error_description"),
|
|
3709
|
-
state: url.searchParams.get("state"),
|
|
3710
|
-
iss: url.searchParams.get("iss")
|
|
3711
|
-
};
|
|
3723
|
+
url = new URL(trimmed);
|
|
3712
3724
|
} catch {
|
|
3713
3725
|
return {
|
|
3714
3726
|
code: trimmed,
|
|
@@ -3718,6 +3730,20 @@ function extractCallbackParametersFromInput(input) {
|
|
|
3718
3730
|
iss: null
|
|
3719
3731
|
};
|
|
3720
3732
|
}
|
|
3733
|
+
return readAuthorizationCallbackParameters(url);
|
|
3734
|
+
}
|
|
3735
|
+
function readAuthorizationCallbackParameters(url) {
|
|
3736
|
+
for (const parameter of oauthCallbackParameters) {
|
|
3737
|
+
if (url.searchParams.getAll(parameter).length > 1)
|
|
3738
|
+
throw new Error(`OAuth callback parameter '${parameter}' must occur only once`);
|
|
3739
|
+
}
|
|
3740
|
+
return {
|
|
3741
|
+
code: url.searchParams.get("code"),
|
|
3742
|
+
error: url.searchParams.get("error"),
|
|
3743
|
+
errorDescription: url.searchParams.get("error_description"),
|
|
3744
|
+
state: url.searchParams.get("state"),
|
|
3745
|
+
iss: url.searchParams.get("iss")
|
|
3746
|
+
};
|
|
3721
3747
|
}
|
|
3722
3748
|
function readExpectedAuthorizationCallback(authorizationUrl) {
|
|
3723
3749
|
const url = new URL(authorizationUrl);
|
|
@@ -3754,9 +3780,6 @@ function validateAuthorizationCallbackBinding(callback, expected) {
|
|
|
3754
3780
|
throw new Error("OAuth callback issuer mismatch");
|
|
3755
3781
|
}
|
|
3756
3782
|
}
|
|
3757
|
-
function createAuthorizationError(error, description) {
|
|
3758
|
-
return new Error(`OAuth authorization failed: ${error} \u2014 ${description}`);
|
|
3759
|
-
}
|
|
3760
3783
|
function escapeHtml(text) {
|
|
3761
3784
|
return text.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """);
|
|
3762
3785
|
}
|
|
@@ -5038,7 +5061,12 @@ async function readBoundedResponseText(response, maxBytes, readers, signal) {
|
|
|
5038
5061
|
|
|
5039
5062
|
// ../mcp-oauth/dist/client/token-endpoint.js
|
|
5040
5063
|
var MAX_JS_DATE_MS2 = 864e13;
|
|
5064
|
+
var oauthErrorBrand = /* @__PURE__ */ Symbol.for("poe-platform.mcp-oauth.OAuthError");
|
|
5041
5065
|
var OAuthError = class extends Error {
|
|
5066
|
+
/** Recognize errors from separately bundled copies of this package. */
|
|
5067
|
+
static is(value) {
|
|
5068
|
+
return value instanceof Error && Object.getOwnPropertyDescriptor(value, oauthErrorBrand)?.value === true;
|
|
5069
|
+
}
|
|
5042
5070
|
error;
|
|
5043
5071
|
errorDescription;
|
|
5044
5072
|
errorUri;
|
|
@@ -5054,6 +5082,7 @@ var OAuthError = class extends Error {
|
|
|
5054
5082
|
const uri = Object.hasOwn(shape, "error_uri") ? shape.error_uri : void 0;
|
|
5055
5083
|
super(description ?? (outcomeKnown ? shape.error : `OAuth HTTP response did not contain a valid error (HTTP ${status})`));
|
|
5056
5084
|
this.name = "OAuthError";
|
|
5085
|
+
Object.defineProperty(this, oauthErrorBrand, { value: true });
|
|
5057
5086
|
this.error = shape.error;
|
|
5058
5087
|
this.errorDescription = description;
|
|
5059
5088
|
this.errorUri = uri;
|
|
@@ -5155,6 +5184,8 @@ async function requestTokens(input) {
|
|
|
5155
5184
|
}
|
|
5156
5185
|
}
|
|
5157
5186
|
const refreshToken = getOwnEntry5(payload, "refresh_token");
|
|
5187
|
+
if (refreshToken !== void 0 && (typeof refreshToken !== "string" || refreshToken.trim().length === 0))
|
|
5188
|
+
throw new Error("OAuth token response has invalid refresh_token");
|
|
5158
5189
|
const scope = getOwnEntry5(payload, "scope");
|
|
5159
5190
|
const normalizedRefreshToken = typeof refreshToken === "string" && refreshToken.trim().length > 0 ? refreshToken.trim() : void 0;
|
|
5160
5191
|
const normalizedScope = normalizeOAuthScope(scope);
|
|
@@ -7640,6 +7671,13 @@ var StdioTransport = class _StdioTransport {
|
|
|
7640
7671
|
}
|
|
7641
7672
|
}
|
|
7642
7673
|
};
|
|
7674
|
+
function snapshotHttpTransportHeaders(headers) {
|
|
7675
|
+
try {
|
|
7676
|
+
return new Headers(headers);
|
|
7677
|
+
} catch {
|
|
7678
|
+
throw new Error("Invalid HTTP transport headers");
|
|
7679
|
+
}
|
|
7680
|
+
}
|
|
7643
7681
|
var HttpTransport = class {
|
|
7644
7682
|
readable;
|
|
7645
7683
|
writable;
|
|
@@ -7689,7 +7727,7 @@ var HttpTransport = class {
|
|
|
7689
7727
|
this.maxResponseBytes = maxResponseBytes;
|
|
7690
7728
|
this.url = url;
|
|
7691
7729
|
this.mode = mode;
|
|
7692
|
-
this.headers = headers;
|
|
7730
|
+
this.headers = snapshotHttpTransportHeaders(headers);
|
|
7693
7731
|
this.fetchImpl = fetchImpl;
|
|
7694
7732
|
this.onWarning = onWarning;
|
|
7695
7733
|
this.oauthProvider = oauth === void 0 ? void 0 : createOAuthClientProvider(oauth);
|
|
@@ -9249,7 +9287,8 @@ export {
|
|
|
9249
9287
|
createSdkTestPair,
|
|
9250
9288
|
createTestPair,
|
|
9251
9289
|
discoverOAuthMetadata,
|
|
9252
|
-
fetchMcpResponse
|
|
9290
|
+
fetchMcpResponse,
|
|
9291
|
+
snapshotHttpTransportHeaders
|
|
9253
9292
|
};
|
|
9254
9293
|
/*!
|
|
9255
9294
|
The MCP project is undergoing a licensing transition from the MIT License to the Apache License, Version 2.0 ("Apache-2.0"). All new code and specification contributions to the project are licensed under Apache-2.0. Documentation contributions (excluding specifications) are licensed under CC-BY-4.0.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "toolcraft",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.345",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -158,7 +158,7 @@
|
|
|
158
158
|
"yaml"
|
|
159
159
|
],
|
|
160
160
|
"optionalDependencies": {
|
|
161
|
-
"toolcraft-schema": "0.0.
|
|
161
|
+
"toolcraft-schema": "0.0.345",
|
|
162
162
|
"toolcraft-design": "*",
|
|
163
163
|
"@poe-code/frontmatter": "*",
|
|
164
164
|
"@poe-code/agent-mcp-config": "*",
|