toolcraft 0.0.23 → 0.0.25
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 -2
- package/dist/cli.compile-check.js +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +50 -13
- package/dist/error-report.js +32 -3
- package/dist/human-in-loop/approval-tasks.d.ts +1 -0
- package/dist/human-in-loop/approval-tasks.js +7 -5
- package/dist/human-in-loop/approvals-commands.js +51 -8
- package/dist/human-in-loop/runner.js +24 -19
- package/dist/human-in-loop/state-machine.d.ts +3 -3
- package/dist/human-in-loop/state-machine.js +13 -5
- package/dist/index.d.ts +5 -0
- package/dist/index.js +6 -1
- package/dist/mcp-proxy.js +85 -19
- package/dist/mcp.compile-check.js +1 -0
- package/dist/mcp.d.ts +1 -0
- package/dist/mcp.js +50 -8
- package/dist/renderer.js +119 -13
- package/dist/sdk.compile-check.js +1 -0
- package/dist/sdk.d.ts +1 -0
- package/dist/sdk.js +56 -11
- package/node_modules/@poe-code/agent-defs/dist/registry.d.ts +1 -1
- package/node_modules/@poe-code/agent-defs/dist/registry.js +22 -11
- package/node_modules/@poe-code/agent-defs/package.json +1 -1
- package/node_modules/@poe-code/agent-human-in-loop/dist/providers/osascript-script.js +5 -1
- package/node_modules/@poe-code/agent-human-in-loop/dist/providers/osascript.js +1 -1
- package/node_modules/@poe-code/agent-human-in-loop/package.json +1 -1
- package/node_modules/@poe-code/agent-mcp-config/dist/apply.d.ts +1 -1
- package/node_modules/@poe-code/agent-mcp-config/dist/apply.js +41 -92
- package/node_modules/@poe-code/agent-mcp-config/dist/configs.js +4 -1
- package/node_modules/@poe-code/agent-mcp-config/dist/shapes.d.ts +14 -2
- package/node_modules/@poe-code/agent-mcp-config/dist/shapes.js +11 -4
- package/node_modules/@poe-code/agent-mcp-config/package.json +1 -1
- package/node_modules/@poe-code/config-mutations/dist/execution/apply-mutation.js +200 -22
- package/node_modules/@poe-code/config-mutations/dist/execution/path-utils.js +7 -1
- package/node_modules/@poe-code/config-mutations/dist/formats/index.js +1 -1
- package/node_modules/@poe-code/config-mutations/dist/formats/json.js +11 -7
- package/node_modules/@poe-code/config-mutations/dist/formats/object.d.ts +4 -0
- package/node_modules/@poe-code/config-mutations/dist/formats/object.js +27 -0
- package/node_modules/@poe-code/config-mutations/dist/formats/toml.js +12 -9
- package/node_modules/@poe-code/config-mutations/dist/formats/yaml.js +12 -9
- package/node_modules/@poe-code/config-mutations/dist/mutations/file-mutation.d.ts +11 -1
- package/node_modules/@poe-code/config-mutations/dist/mutations/file-mutation.js +10 -1
- package/node_modules/@poe-code/config-mutations/dist/testing/mock-fs.js +25 -1
- package/node_modules/@poe-code/config-mutations/dist/types.d.ts +12 -2
- package/node_modules/@poe-code/config-mutations/package.json +1 -1
- package/node_modules/@poe-code/design-system/dist/acp/components.js +3 -1
- package/node_modules/@poe-code/design-system/dist/components/browser.d.ts +1 -1
- package/node_modules/@poe-code/design-system/dist/components/browser.js +6 -1
- package/node_modules/@poe-code/design-system/dist/components/color.js +9 -8
- package/node_modules/@poe-code/design-system/dist/components/command-errors.js +3 -2
- package/node_modules/@poe-code/design-system/dist/components/detail-card.d.ts +22 -0
- package/node_modules/@poe-code/design-system/dist/components/detail-card.js +69 -0
- package/node_modules/@poe-code/design-system/dist/components/help-formatter.js +88 -11
- package/node_modules/@poe-code/design-system/dist/components/index.d.ts +1 -1
- package/node_modules/@poe-code/design-system/dist/components/index.js +1 -1
- package/node_modules/@poe-code/design-system/dist/components/table.d.ts +2 -0
- package/node_modules/@poe-code/design-system/dist/components/table.js +82 -5
- package/node_modules/@poe-code/design-system/dist/components/template.d.ts +4 -0
- package/node_modules/@poe-code/design-system/dist/components/template.js +198 -32
- package/node_modules/@poe-code/design-system/dist/components/text.js +29 -5
- package/node_modules/@poe-code/design-system/dist/dashboard/ansi.d.ts +2 -2
- package/node_modules/@poe-code/design-system/dist/dashboard/ansi.js +77 -32
- package/node_modules/@poe-code/design-system/dist/dashboard/buffer.js +28 -5
- package/node_modules/@poe-code/design-system/dist/dashboard/components/output-pane.js +45 -28
- package/node_modules/@poe-code/design-system/dist/dashboard/terminal-width.d.ts +4 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/terminal-width.js +71 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/types.d.ts +1 -0
- package/node_modules/@poe-code/design-system/dist/explorer/events.d.ts +6 -0
- package/node_modules/@poe-code/design-system/dist/explorer/reducer.js +32 -10
- package/node_modules/@poe-code/design-system/dist/explorer/render/detail.js +3 -0
- package/node_modules/@poe-code/design-system/dist/explorer/runtime.js +57 -6
- package/node_modules/@poe-code/design-system/dist/explorer/state.d.ts +1 -0
- package/node_modules/@poe-code/design-system/dist/explorer/state.js +12 -15
- package/node_modules/@poe-code/design-system/dist/index.d.ts +3 -1
- package/node_modules/@poe-code/design-system/dist/index.js +2 -1
- package/node_modules/@poe-code/design-system/dist/prompts/primitives/intro.js +2 -1
- package/node_modules/@poe-code/design-system/dist/prompts/primitives/log.js +8 -5
- package/node_modules/@poe-code/design-system/dist/prompts/primitives/note.js +1 -1
- package/node_modules/@poe-code/design-system/dist/static/menu.js +8 -2
- package/node_modules/@poe-code/design-system/dist/static/spinner.js +10 -4
- package/node_modules/@poe-code/design-system/dist/terminal-markdown/parser/frontmatter.js +9 -2
- package/node_modules/@poe-code/design-system/dist/terminal-markdown/renderer.js +19 -2
- package/node_modules/@poe-code/design-system/package.json +2 -1
- package/node_modules/@poe-code/process-runner/dist/docker/args.d.ts +1 -0
- package/node_modules/@poe-code/process-runner/dist/docker/args.js +11 -3
- package/node_modules/@poe-code/process-runner/dist/docker/docker-execution-env.js +377 -130
- package/node_modules/@poe-code/process-runner/dist/docker/docker-runner.js +78 -10
- package/node_modules/@poe-code/process-runner/dist/docker/env-file.d.ts +6 -0
- package/node_modules/@poe-code/process-runner/dist/docker/env-file.js +49 -0
- package/node_modules/@poe-code/process-runner/dist/host/host-execution-env.js +3 -2
- package/node_modules/@poe-code/process-runner/dist/host/host-runner.js +21 -5
- package/node_modules/@poe-code/process-runner/dist/index.d.ts +1 -0
- package/node_modules/@poe-code/process-runner/dist/index.js +1 -0
- package/node_modules/@poe-code/process-runner/dist/testing/mock-runner.js +30 -8
- package/node_modules/@poe-code/process-runner/dist/types.d.ts +6 -0
- package/node_modules/@poe-code/process-runner/dist/workspace-transfer.d.ts +61 -0
- package/node_modules/@poe-code/process-runner/dist/workspace-transfer.js +503 -0
- package/node_modules/@poe-code/process-runner/package.json +1 -1
- package/node_modules/@poe-code/task-list/README.md +0 -2
- package/node_modules/@poe-code/task-list/dist/backends/gh-issues-client.js +3 -0
- package/node_modules/@poe-code/task-list/dist/backends/gh-issues-sync.js +89 -59
- package/node_modules/@poe-code/task-list/dist/backends/gh-issues.d.ts +9 -3
- package/node_modules/@poe-code/task-list/dist/backends/gh-issues.js +460 -99
- package/node_modules/@poe-code/task-list/dist/backends/markdown-dir.js +156 -154
- package/node_modules/@poe-code/task-list/dist/backends/utils.d.ts +2 -0
- package/node_modules/@poe-code/task-list/dist/backends/utils.js +79 -0
- package/node_modules/@poe-code/task-list/dist/backends/yaml-file.js +120 -132
- package/node_modules/@poe-code/task-list/dist/index.d.ts +3 -1
- package/node_modules/@poe-code/task-list/dist/index.js +2 -0
- package/node_modules/@poe-code/task-list/dist/move.d.ts +2 -0
- package/node_modules/@poe-code/task-list/dist/move.js +215 -0
- package/node_modules/@poe-code/task-list/dist/open.js +3 -4
- package/node_modules/@poe-code/task-list/dist/state-machine.js +3 -1
- package/node_modules/@poe-code/task-list/dist/state.js +9 -0
- package/node_modules/@poe-code/task-list/dist/types.d.ts +48 -13
- package/node_modules/@poe-code/task-list/package.json +1 -2
- package/node_modules/auth-store/dist/create-secret-store.js +4 -1
- package/node_modules/auth-store/dist/encrypted-file-store.d.ts +8 -0
- package/node_modules/auth-store/dist/encrypted-file-store.js +104 -8
- package/node_modules/auth-store/dist/index.d.ts +1 -1
- package/node_modules/auth-store/dist/keychain-store.d.ts +4 -1
- package/node_modules/auth-store/dist/keychain-store.js +18 -16
- package/node_modules/auth-store/dist/provider-store.d.ts +5 -1
- package/node_modules/auth-store/dist/provider-store.js +55 -7
- package/node_modules/auth-store/dist/types.d.ts +3 -1
- package/node_modules/auth-store/package.json +2 -1
- package/node_modules/mcp-oauth/dist/client/default-oauth-client-provider.js +46 -15
- package/node_modules/mcp-oauth/dist/client/loopback-authorization.js +49 -12
- package/node_modules/mcp-oauth/dist/client/token-endpoint.js +6 -1
- package/node_modules/mcp-oauth/dist/server/jwks-token-verifier.js +1 -1
- package/node_modules/mcp-oauth/package.json +1 -0
- package/node_modules/tiny-mcp-client/.turbo/turbo-build.log +1 -1
- package/node_modules/tiny-mcp-client/dist/internal.d.ts +9 -4
- package/node_modules/tiny-mcp-client/dist/internal.js +244 -66
- package/node_modules/tiny-mcp-client/dist/oauth-discovery.d.ts +1 -1
- package/node_modules/tiny-mcp-client/dist/oauth-discovery.js +4 -7
- package/node_modules/tiny-mcp-client/package.json +2 -1
- package/node_modules/tiny-mcp-client/src/http-oauth.integration.test.ts +1 -1
- package/node_modules/tiny-mcp-client/src/http-oauth.test.ts +46 -0
- package/node_modules/tiny-mcp-client/src/internal.ts +287 -76
- package/node_modules/tiny-mcp-client/src/mcp-client-sdk.test.ts +32 -0
- package/node_modules/tiny-mcp-client/src/mcp-client-tiny-stdio-test-server-tools.test.ts +1 -1
- package/node_modules/tiny-mcp-client/src/oauth-discovery.ts +5 -10
- package/node_modules/tiny-mcp-client/src/transports.test.ts +588 -6
- package/package.json +10 -12
- package/node_modules/@poe-code/file-lock/README.md +0 -52
- package/node_modules/@poe-code/file-lock/dist/index.d.ts +0 -1
- package/node_modules/@poe-code/file-lock/dist/index.js +0 -1
- package/node_modules/@poe-code/file-lock/dist/lock.d.ts +0 -27
- package/node_modules/@poe-code/file-lock/dist/lock.js +0 -203
- package/node_modules/@poe-code/file-lock/package.json +0 -23
|
@@ -15,7 +15,6 @@ export function createDefaultOAuthClientProvider(options) {
|
|
|
15
15
|
const sessionStore = options.sessionStore ?? createAuthStoreSessionStore(options.authStore);
|
|
16
16
|
const clientStore = options.authStore === undefined ? null : createAuthStoreClientStore(options.authStore);
|
|
17
17
|
const now = options.now ?? Date.now;
|
|
18
|
-
const sessions = new Map();
|
|
19
18
|
const registeredClients = new Map();
|
|
20
19
|
const refreshPromises = new Map();
|
|
21
20
|
const authorizationPromises = new Map();
|
|
@@ -25,7 +24,10 @@ export function createDefaultOAuthClientProvider(options) {
|
|
|
25
24
|
const requestUrl = canonicalizeResourceIndicator(input.requestUrl);
|
|
26
25
|
const session = await ensureAuthorizedSession(requestUrl, undefined, input.fetch, false);
|
|
27
26
|
const accessToken = session?.tokens?.accessToken;
|
|
28
|
-
if (session === null
|
|
27
|
+
if (session === null
|
|
28
|
+
|| accessToken === undefined
|
|
29
|
+
|| session.tokens === undefined
|
|
30
|
+
|| isExpired(session.tokens, now)) {
|
|
29
31
|
return;
|
|
30
32
|
}
|
|
31
33
|
assertRequestMatchesResource(requestUrl, session.resource);
|
|
@@ -71,10 +73,11 @@ export function createDefaultOAuthClientProvider(options) {
|
|
|
71
73
|
return session;
|
|
72
74
|
}
|
|
73
75
|
}
|
|
74
|
-
if (!allowInteractive || sessionDiscovery === undefined) {
|
|
75
|
-
return session;
|
|
76
|
-
}
|
|
77
76
|
if (forceRefresh && session?.tokens !== undefined) {
|
|
77
|
+
session = clearSessionTokens(session);
|
|
78
|
+
await saveSession(canonicalResource, session);
|
|
79
|
+
}
|
|
80
|
+
if (!allowInteractive || sessionDiscovery === undefined) {
|
|
78
81
|
return session;
|
|
79
82
|
}
|
|
80
83
|
return authorizeSession(canonicalResource, session, sessionDiscovery, fetch);
|
|
@@ -125,7 +128,10 @@ export function createDefaultOAuthClientProvider(options) {
|
|
|
125
128
|
}
|
|
126
129
|
const updatedSession = {
|
|
127
130
|
...session,
|
|
128
|
-
tokens:
|
|
131
|
+
tokens: {
|
|
132
|
+
...refreshedTokens,
|
|
133
|
+
refreshToken: refreshedTokens.refreshToken ?? session.tokens.refreshToken,
|
|
134
|
+
},
|
|
129
135
|
discovery: toStoredDiscovery(discovery),
|
|
130
136
|
};
|
|
131
137
|
await saveSession(resource, updatedSession);
|
|
@@ -285,7 +291,7 @@ export function createDefaultOAuthClientProvider(options) {
|
|
|
285
291
|
});
|
|
286
292
|
const payload = await readOAuthJsonObjectResponse(response);
|
|
287
293
|
if (typeof payload.client_id !== "string" ||
|
|
288
|
-
payload.client_id.length === 0) {
|
|
294
|
+
payload.client_id.trim().length === 0) {
|
|
289
295
|
throw new Error("OAuth client registration response missing client_id");
|
|
290
296
|
}
|
|
291
297
|
const registeredClient = {
|
|
@@ -302,19 +308,12 @@ export function createDefaultOAuthClientProvider(options) {
|
|
|
302
308
|
};
|
|
303
309
|
}
|
|
304
310
|
async function loadSession(resource) {
|
|
305
|
-
|
|
306
|
-
return sessions.get(resource) ?? null;
|
|
307
|
-
}
|
|
308
|
-
const session = await sessionStore.load(resource);
|
|
309
|
-
sessions.set(resource, session);
|
|
310
|
-
return session;
|
|
311
|
+
return normalizeLoadedSession(await sessionStore.load(resource));
|
|
311
312
|
}
|
|
312
313
|
async function saveSession(resource, session) {
|
|
313
|
-
sessions.set(resource, session);
|
|
314
314
|
await sessionStore.save(resource, session);
|
|
315
315
|
}
|
|
316
316
|
async function clearSession(resource) {
|
|
317
|
-
sessions.delete(resource);
|
|
318
317
|
await sessionStore.clear(resource);
|
|
319
318
|
}
|
|
320
319
|
async function loadRegisteredClient(issuer) {
|
|
@@ -325,6 +324,10 @@ export function createDefaultOAuthClientProvider(options) {
|
|
|
325
324
|
return null;
|
|
326
325
|
}
|
|
327
326
|
const client = await clientStore.load(issuer);
|
|
327
|
+
if (client !== null && !isUsableClient(client)) {
|
|
328
|
+
await clientStore.clear(issuer);
|
|
329
|
+
return null;
|
|
330
|
+
}
|
|
328
331
|
registeredClients.set(issuer, client);
|
|
329
332
|
return client;
|
|
330
333
|
}
|
|
@@ -382,6 +385,34 @@ function clearSessionTokens(session) {
|
|
|
382
385
|
function hasCachedAccessToken(session) {
|
|
383
386
|
return session?.tokens?.accessToken !== undefined;
|
|
384
387
|
}
|
|
388
|
+
function normalizeLoadedSession(session) {
|
|
389
|
+
if (session === null) {
|
|
390
|
+
return null;
|
|
391
|
+
}
|
|
392
|
+
if (!isUsableClient(session.client)) {
|
|
393
|
+
return { ...session, client: { clientId: "" }, tokens: undefined };
|
|
394
|
+
}
|
|
395
|
+
return isUsableTokens(session.tokens)
|
|
396
|
+
? session
|
|
397
|
+
: { ...session, tokens: undefined };
|
|
398
|
+
}
|
|
399
|
+
function isUsableClient(client) {
|
|
400
|
+
return (typeof client.clientId === "string"
|
|
401
|
+
&& client.clientId.trim().length > 0
|
|
402
|
+
&& (client.clientSecret === undefined
|
|
403
|
+
|| (typeof client.clientSecret === "string" && client.clientSecret.trim().length > 0)));
|
|
404
|
+
}
|
|
405
|
+
function isUsableTokens(tokens) {
|
|
406
|
+
if (tokens === undefined) {
|
|
407
|
+
return true;
|
|
408
|
+
}
|
|
409
|
+
return (typeof tokens.accessToken === "string"
|
|
410
|
+
&& tokens.accessToken.trim().length > 0
|
|
411
|
+
&& tokens.tokenType === "Bearer"
|
|
412
|
+
&& (tokens.expiresAt === null || (typeof tokens.expiresAt === "number" && Number.isFinite(tokens.expiresAt)))
|
|
413
|
+
&& (tokens.refreshToken === undefined
|
|
414
|
+
|| (typeof tokens.refreshToken === "string" && tokens.refreshToken.trim().length > 0)));
|
|
415
|
+
}
|
|
385
416
|
function getClientMetadata(client) {
|
|
386
417
|
return client.metadata;
|
|
387
418
|
}
|
|
@@ -17,8 +17,14 @@ export async function createLoopbackAuthorizationSession(options = {}) {
|
|
|
17
17
|
};
|
|
18
18
|
}
|
|
19
19
|
async function startServer(server) {
|
|
20
|
-
return new Promise((resolve) => {
|
|
20
|
+
return new Promise((resolve, reject) => {
|
|
21
|
+
const handleError = (error) => {
|
|
22
|
+
server.off("error", handleError);
|
|
23
|
+
reject(error);
|
|
24
|
+
};
|
|
25
|
+
server.once("error", handleError);
|
|
21
26
|
server.listen(0, "127.0.0.1", () => {
|
|
27
|
+
server.off("error", handleError);
|
|
22
28
|
const address = server.address();
|
|
23
29
|
resolve(address.port);
|
|
24
30
|
});
|
|
@@ -41,20 +47,34 @@ function waitForAuthorizationCode(server, authorizationUrl, options, callbackPat
|
|
|
41
47
|
res.end("Not found");
|
|
42
48
|
return;
|
|
43
49
|
}
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
50
|
+
const callbackParameters = {
|
|
51
|
+
code: url.searchParams.get("code"),
|
|
52
|
+
error: url.searchParams.get("error"),
|
|
53
|
+
errorDescription: url.searchParams.get("error_description"),
|
|
54
|
+
state: url.searchParams.get("state"),
|
|
55
|
+
iss: url.searchParams.get("iss"),
|
|
56
|
+
};
|
|
57
|
+
try {
|
|
58
|
+
validateAuthorizationCallbackBinding(callbackParameters, expectedAuthorization);
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
res.writeHead(400);
|
|
62
|
+
res.end(error instanceof Error ? error.message : "Invalid OAuth callback");
|
|
63
|
+
if (callbackParameters.error === null) {
|
|
64
|
+
settle(() => reject(error instanceof Error ? error : new Error(String(error))));
|
|
65
|
+
}
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const authorizationError = callbackParameters.error;
|
|
69
|
+
if (authorizationError !== null) {
|
|
70
|
+
const description = callbackParameters.errorDescription ?? authorizationError;
|
|
47
71
|
res.writeHead(400);
|
|
48
72
|
res.end(`Authorization failed: ${description}`);
|
|
49
|
-
settle(() => reject(
|
|
73
|
+
settle(() => reject(createAuthorizationError(authorizationError, description)));
|
|
50
74
|
return;
|
|
51
75
|
}
|
|
52
76
|
try {
|
|
53
|
-
const code = validateAuthorizationCallbackParameters(
|
|
54
|
-
code: url.searchParams.get("code"),
|
|
55
|
-
state: url.searchParams.get("state"),
|
|
56
|
-
iss: url.searchParams.get("iss"),
|
|
57
|
-
}, expectedAuthorization);
|
|
77
|
+
const code = validateAuthorizationCallbackParameters(callbackParameters, expectedAuthorization);
|
|
58
78
|
res.writeHead(200, { "Content-Type": "text/html" });
|
|
59
79
|
res.end(buildSuccessPage(options.landingPage));
|
|
60
80
|
settle(() => resolve(code));
|
|
@@ -73,13 +93,20 @@ function waitForAuthorizationCode(server, authorizationUrl, options, callbackPat
|
|
|
73
93
|
return;
|
|
74
94
|
}
|
|
75
95
|
try {
|
|
96
|
+
validateAuthorizationCallbackBinding(callbackParameters, expectedAuthorization);
|
|
97
|
+
if (callbackParameters.error !== null) {
|
|
98
|
+
const description = callbackParameters.errorDescription ?? callbackParameters.error;
|
|
99
|
+
throw createAuthorizationError(callbackParameters.error, description);
|
|
100
|
+
}
|
|
76
101
|
const code = validateAuthorizationCallbackParameters(callbackParameters, expectedAuthorization);
|
|
77
102
|
settle(() => resolve(code));
|
|
78
103
|
}
|
|
79
104
|
catch (error) {
|
|
80
105
|
settle(() => reject(error instanceof Error ? error : new Error(String(error))));
|
|
81
106
|
}
|
|
82
|
-
}).catch(() =>
|
|
107
|
+
}).catch((error) => {
|
|
108
|
+
settle(() => reject(error instanceof Error ? error : new Error(String(error))));
|
|
109
|
+
});
|
|
83
110
|
}
|
|
84
111
|
if (options.openBrowser !== undefined) {
|
|
85
112
|
options.openBrowser(authorizationUrl).catch((error) => {
|
|
@@ -100,6 +127,8 @@ function extractCallbackParametersFromInput(input) {
|
|
|
100
127
|
const url = new URL(trimmed);
|
|
101
128
|
return {
|
|
102
129
|
code: url.searchParams.get("code"),
|
|
130
|
+
error: url.searchParams.get("error"),
|
|
131
|
+
errorDescription: url.searchParams.get("error_description"),
|
|
103
132
|
state: url.searchParams.get("state"),
|
|
104
133
|
iss: url.searchParams.get("iss"),
|
|
105
134
|
};
|
|
@@ -107,6 +136,8 @@ function extractCallbackParametersFromInput(input) {
|
|
|
107
136
|
catch {
|
|
108
137
|
return {
|
|
109
138
|
code: trimmed,
|
|
139
|
+
error: null,
|
|
140
|
+
errorDescription: null,
|
|
110
141
|
state: null,
|
|
111
142
|
iss: null,
|
|
112
143
|
};
|
|
@@ -123,9 +154,13 @@ function readExpectedAuthorizationCallback(authorizationUrl) {
|
|
|
123
154
|
};
|
|
124
155
|
}
|
|
125
156
|
function validateAuthorizationCallbackParameters(callback, expected) {
|
|
157
|
+
validateAuthorizationCallbackBinding(callback, expected);
|
|
126
158
|
if (callback.code === null || callback.code.length === 0) {
|
|
127
159
|
throw new Error("OAuth callback missing authorization code");
|
|
128
160
|
}
|
|
161
|
+
return callback.code;
|
|
162
|
+
}
|
|
163
|
+
function validateAuthorizationCallbackBinding(callback, expected) {
|
|
129
164
|
if (expected.state !== null) {
|
|
130
165
|
if (callback.state === null || callback.state.length === 0) {
|
|
131
166
|
throw new Error("OAuth callback missing state");
|
|
@@ -145,7 +180,9 @@ function validateAuthorizationCallbackParameters(callback, expected) {
|
|
|
145
180
|
&& callback.iss !== expected.issuer) {
|
|
146
181
|
throw new Error("OAuth callback issuer mismatch");
|
|
147
182
|
}
|
|
148
|
-
|
|
183
|
+
}
|
|
184
|
+
function createAuthorizationError(error, description) {
|
|
185
|
+
return new Error(`OAuth authorization failed: ${error} — ${description}`);
|
|
149
186
|
}
|
|
150
187
|
function escapeHtml(text) {
|
|
151
188
|
return text
|
|
@@ -75,13 +75,18 @@ async function requestTokens(input) {
|
|
|
75
75
|
body: body.toString(),
|
|
76
76
|
});
|
|
77
77
|
const payload = await readOAuthJsonObjectResponse(response);
|
|
78
|
-
if (typeof payload.access_token !== "string" || payload.access_token.length === 0) {
|
|
78
|
+
if (typeof payload.access_token !== "string" || payload.access_token.trim().length === 0) {
|
|
79
79
|
throw new Error("OAuth token response missing access_token");
|
|
80
80
|
}
|
|
81
81
|
const tokenType = normalizeBearerTokenType(payload.token_type);
|
|
82
82
|
if (tokenType === null) {
|
|
83
83
|
throw new Error("OAuth token response missing token_type=Bearer");
|
|
84
84
|
}
|
|
85
|
+
if (typeof payload.expires_in === "number"
|
|
86
|
+
&& Number.isFinite(payload.expires_in)
|
|
87
|
+
&& payload.expires_in < 0) {
|
|
88
|
+
throw new Error("OAuth token response has invalid expires_in");
|
|
89
|
+
}
|
|
85
90
|
return {
|
|
86
91
|
accessToken: payload.access_token,
|
|
87
92
|
refreshToken: typeof payload.refresh_token === "string" && payload.refresh_token.length > 0
|
|
@@ -242,7 +242,7 @@ export function createJwksTokenVerifier(options) {
|
|
|
242
242
|
const audience = normalizeVerifiedAudience(verified.payload.aud, expectedResource);
|
|
243
243
|
const accessToken = toVerifiedAccessToken(input.token, verified.payload, audience);
|
|
244
244
|
if (input.requiredScopes.length > 0
|
|
245
|
-
&& !
|
|
245
|
+
&& !input.requiredScopes.every((scope) => accessToken.scopes.includes(scope))) {
|
|
246
246
|
throw createTokenVerificationError({
|
|
247
247
|
error: "insufficient_scope",
|
|
248
248
|
errorDescription: "insufficient scope",
|
|
@@ -3,5 +3,5 @@ npm warn Unknown project config "package-manager-strict". This will stop working
|
|
|
3
3
|
npm warn Unknown project config "prefer-workspace-packages". This will stop working in the next major version of npm. See `npm help npmrc` for supported config options.
|
|
4
4
|
|
|
5
5
|
> tiny-mcp-client@0.1.0 build
|
|
6
|
-
> tsc
|
|
6
|
+
> node ../../scripts/guard-package-dist.mjs && tsc
|
|
7
7
|
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import type { ChildProcessWithoutNullStreams, SpawnOptions } from "node:child_process";
|
|
2
2
|
import type { Readable, Writable } from "node:stream";
|
|
3
3
|
import type { JSONRPCMessage as SdkJsonRpcMessage } from "@modelcontextprotocol/sdk/types.js";
|
|
4
|
-
import { type OAuthClientProviderOptions } from "
|
|
4
|
+
import { type OAuthClientProviderOptions } from "mcp-oauth";
|
|
5
5
|
import type { Server as TinyStdioMcpServer } from "tiny-stdio-mcp-server";
|
|
6
6
|
import type { OAuthDiscoveryCache } from "./oauth-discovery.js";
|
|
7
7
|
export { OAuthMetadataDiscovery, discoverOAuthMetadata, parseBearerWwwAuthenticateHeader, resolveAuthorizationServerMetadataUrl, resolveProtectedResourceMetadataUrl, } from "./oauth-discovery.js";
|
|
8
|
-
export { createAuthStoreSessionStore, createDefaultOAuthClientProvider, } from "
|
|
8
|
+
export { createAuthStoreSessionStore, createDefaultOAuthClientProvider, } from "mcp-oauth";
|
|
9
9
|
export type { OAuthDiscoveryCache, } from "./oauth-discovery.js";
|
|
10
10
|
export type { OAuthAuthorizationServerMetadata, OAuthDiscoveryResult, OAuthMetadataFetch, OAuthProtectedResourceMetadata, OAuthUnauthorizedChallenge } from "./oauth-discovery.js";
|
|
11
|
-
export type { DefaultOAuthClientProviderOptions, OAuthClientProvider, OAuthClientProviderOptions, OAuthSessionStore, StoredOAuthSession, } from "
|
|
11
|
+
export type { DefaultOAuthClientProviderOptions, OAuthClientProvider, OAuthClientProviderOptions, OAuthSessionStore, StoredOAuthSession, } from "mcp-oauth";
|
|
12
12
|
export type RequestId = number | string;
|
|
13
13
|
export interface Implementation {
|
|
14
14
|
name: string;
|
|
@@ -59,6 +59,7 @@ export interface InitializeResult {
|
|
|
59
59
|
}
|
|
60
60
|
export interface McpClientOptions {
|
|
61
61
|
clientInfo: Implementation;
|
|
62
|
+
requestTimeoutMs?: number;
|
|
62
63
|
capabilities?: ClientCapabilities;
|
|
63
64
|
onToolsChanged?: () => void | Promise<void>;
|
|
64
65
|
onResourcesChanged?: () => void | Promise<void>;
|
|
@@ -72,8 +73,11 @@ export interface McpClientOptions {
|
|
|
72
73
|
export declare class McpClient {
|
|
73
74
|
private currentState;
|
|
74
75
|
private currentServerCapabilities;
|
|
76
|
+
private currentClientCapabilities;
|
|
75
77
|
private currentServerInfo;
|
|
76
78
|
private currentInstructions;
|
|
79
|
+
private readonly subscribedResourceUris;
|
|
80
|
+
private readonly activeProgressTokens;
|
|
77
81
|
private readonly options;
|
|
78
82
|
private transport;
|
|
79
83
|
private messageLayer;
|
|
@@ -418,6 +422,7 @@ export declare class HttpTransport implements McpTransport {
|
|
|
418
422
|
private readonly openSseReaders;
|
|
419
423
|
constructor({ url, headers, fetch: fetchImpl, oauth, oauthDiscoveryCache, }: HttpTransportOptions);
|
|
420
424
|
dispose(reason?: Error): void;
|
|
425
|
+
private closeWithSessionTermination;
|
|
421
426
|
private abortInFlightFetches;
|
|
422
427
|
private cancelOpenSseReaders;
|
|
423
428
|
private fetchWithAbort;
|
|
@@ -428,7 +433,6 @@ export declare class HttpTransport implements McpTransport {
|
|
|
428
433
|
private authorizeRequestHeaders;
|
|
429
434
|
private captureSessionId;
|
|
430
435
|
private maybeOpenGetSseStream;
|
|
431
|
-
private terminateSession;
|
|
432
436
|
private sendSessionTerminationRequest;
|
|
433
437
|
private consumeGetSseStream;
|
|
434
438
|
private throwForPostHttpError;
|
|
@@ -511,6 +515,7 @@ export declare class SseParser {
|
|
|
511
515
|
export interface JsonRpcRequestOptions {
|
|
512
516
|
timeoutMs?: number;
|
|
513
517
|
onRequestId?: (requestId: RequestId) => void;
|
|
518
|
+
onTimeout?: (requestId: RequestId) => void;
|
|
514
519
|
}
|
|
515
520
|
interface JsonRpcRequestContext {
|
|
516
521
|
id: RequestId;
|