toolcraft 0.0.351 → 0.0.353

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 CHANGED
@@ -98,7 +98,7 @@
98
98
  },
99
99
  {
100
100
  "name": "tiny-http-mcp-server",
101
- "version": "0.1.82",
101
+ "version": "0.1.84",
102
102
  "license": "MIT"
103
103
  },
104
104
  {
@@ -113,7 +113,7 @@
113
113
  },
114
114
  {
115
115
  "name": "toolcraft",
116
- "version": "0.0.351",
116
+ "version": "0.0.353",
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.351",
126
+ "version": "0.0.353",
127
127
  "license": "MIT"
128
128
  },
129
129
  {
@@ -98,7 +98,7 @@
98
98
  },
99
99
  {
100
100
  "name": "tiny-http-mcp-server",
101
- "version": "0.1.82",
101
+ "version": "0.1.84",
102
102
  "license": "MIT"
103
103
  },
104
104
  {
@@ -113,7 +113,7 @@
113
113
  },
114
114
  {
115
115
  "name": "toolcraft",
116
- "version": "0.0.351",
116
+ "version": "0.0.353",
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.351",
126
+ "version": "0.0.353",
127
127
  "license": "MIT"
128
128
  },
129
129
  {
@@ -18,7 +18,7 @@
18
18
  },
19
19
  {
20
20
  "name": "tiny-http-mcp-server",
21
- "version": "0.1.82",
21
+ "version": "0.1.84",
22
22
  "license": "MIT"
23
23
  },
24
24
  {
@@ -47,6 +47,7 @@ alone do not establish either native error type.
47
47
 
48
48
  - `client`
49
49
  - `mode: "dynamic"` with optional `metadata`
50
+ and optional existing `clientId`/`clientSecret`
50
51
  - `mode: "static"` with `clientId`, optional `clientSecret`, optional `metadata`
51
52
  - `allowInteractive: false` prevents interactive login while retaining cached tokens and silent refresh
52
53
  - `sessionLockTimeoutMs` limits acquisition waits for a session transaction lock (default 30,000 ms; integer from 1 to 2147483647)
@@ -123,6 +124,9 @@ A browser callback cannot redirect a later code exchange by changing caller
123
124
  metadata. Metadata loaded from a host session store is copied before clock or
124
125
  fetch callbacks, retaining the original refresh endpoint and persisted extensions. Explicit authentication owns metadata when lazy discovery returns;
125
126
  the selected discovery method retains its original receiver and live host state.
127
+ Browser and standalone loopback snapshots retain declared redirects, deadlines,
128
+ cancellation and selected host hooks regardless of property enumerability.
129
+ Browser callback hooks retain their original receiver and live host state.
126
130
 
127
131
  Provider request inputs accept an optional `signal`. It reaches callback waits,
128
132
  registration, token requests and bounded token-body reads. Cancellation retains
@@ -263,6 +267,10 @@ Static clients and dynamic initial-grant imports require cached grants to match
263
267
  the original normalized client ID and secret. A different client configuration
264
268
  fails before attaching or refreshing credentials and retains the stored record;
265
269
  select separate persistence or explicitly reset the session to change apps.
270
+ An explicitly supplied client ID is used for consent in either mode, including
271
+ when discovery advertises a registrar. Dynamic registration creates a client
272
+ only when no existing app identity is supplied; URL client IDs stay opaque and
273
+ do not trigger client-metadata fetching or registration fallback.
266
274
  Use `persistenceNamespace: "personal"` or `"work"` to keep separate native
267
275
  profiles for the same resource/issuer. `createAuthStoreSessionStore(options,
268
276
  namespace)` addresses the same profile when seeding or inspecting credentials.
@@ -6,7 +6,7 @@ import { isIP } from "node:net";
6
6
  import { fetchMcpResponse } from "../http-fetch.js";
7
7
  import { URL } from "node:url";
8
8
  import { createAuthStoreClientStore, createAuthStoreSessionStore, assertPersistenceNamespace } from "./auth-store-session-store.js";
9
- import { createLoopbackAuthorizationSession, loopbackTarget } from "./loopback-authorization.js";
9
+ import { createLoopbackAuthorizationSession, loopbackTarget, snapshotLoopbackAuthorizationOptions } from "./loopback-authorization.js";
10
10
  import { createAuthorizationState } from "./authorization-state.js";
11
11
  import { generateCodeChallenge, generateCodeVerifier } from "./pkce.js";
12
12
  import { exchangeAuthorizationCode, OAuthError, refreshAccessToken, isRetryableOAuthError, readOAuthJsonObjectResponse } from "./token-endpoint.js";
@@ -21,8 +21,7 @@ export function createOAuthClientProvider(options) {
21
21
  return createDefaultOAuthClientProvider(options);
22
22
  }
23
23
  export function createDefaultOAuthClientProvider(options) {
24
- const browser = { ...options.browser,
25
- ...(options.browser.landingPage === undefined ? {} : { landingPage: { ...options.browser.landingPage } }) };
24
+ const browser = snapshotLoopbackAuthorizationOptions(options.browser);
26
25
  const clientMode = options.client.mode;
27
26
  const interactiveEnabled = options.allowInteractive !== false;
28
27
  const sessionLockTimeoutMs = options.sessionLockTimeoutMs;
@@ -397,7 +396,7 @@ export function createDefaultOAuthClientProvider(options) {
397
396
  }
398
397
  async function resolveClient(existingSession, discovery, redirectUri, fetch, parentSignal) {
399
398
  parentSignal?.throwIfAborted();
400
- if (clientMode === "static" || configuredClient?.registration !== undefined) {
399
+ if (clientMode === "static" || configuredClient !== null) {
401
400
  if (configuredClient === null) {
402
401
  throw new Error("OAuth client_id must not be blank");
403
402
  }
@@ -411,13 +410,6 @@ export function createDefaultOAuthClientProvider(options) {
411
410
  };
412
411
  }
413
412
  const registrationEndpoint = getOwnString(discovery.authorizationServerMetadata, "registration_endpoint");
414
- if (registrationEndpoint === undefined && configuredClient !== null) {
415
- return {
416
- kind: "static",
417
- fromStoredRegistration: false,
418
- client: configuredClient
419
- };
420
- }
421
413
  let storedClient = await loadRegisteredClient(discovery.authorizationServer);
422
414
  const importedClient = existingSession?.client.registrationOwnership === "caller" ? existingSession.client :
423
415
  storedClient?.registrationOwnership === "caller" ? storedClient : undefined;
@@ -454,17 +446,12 @@ export function createDefaultOAuthClientProvider(options) {
454
446
  throw new Error("Authorization server metadata is missing registration_endpoint");
455
447
  }
456
448
  if (existingSession !== null && existingSession.client.clientId.length > 0 && !hasExpiredClientSecret(existingSession.client, now) && registrationMatchesRedirect(existingSession.client, redirectUri)) {
457
- const isConfiguredStaticFallback = configuredClient !== null &&
458
- existingSession.client.clientId === configuredClient.clientId &&
459
- existingSession.client.clientSecret === configuredClient.clientSecret;
460
- if (!isConfiguredStaticFallback) {
461
- await saveRegisteredClient(discovery.authorizationServer, existingSession.client);
462
- return {
463
- kind: "dynamic",
464
- fromStoredRegistration: true,
465
- client: existingSession.client
466
- };
467
- }
449
+ await saveRegisteredClient(discovery.authorizationServer, existingSession.client);
450
+ return {
451
+ kind: "dynamic",
452
+ fromStoredRegistration: true,
453
+ client: existingSession.client
454
+ };
468
455
  }
469
456
  const supported = getSupportedTokenAuthMethods(discovery.authorizationServerMetadata);
470
457
  const registrationMethod = requestedTokenMethod ?? (supported === undefined ? "none" :
@@ -20,6 +20,8 @@ export interface LoopbackAuthorizationSession {
20
20
  waitForCode(authorizationUrl: string): Promise<string>;
21
21
  close(): void;
22
22
  }
23
+ /** Capture declared configuration regardless of property enumerability. */
24
+ export declare function snapshotLoopbackAuthorizationOptions(options: LoopbackAuthorizationOptions): LoopbackAuthorizationOptions;
23
25
  /** Authorization callback denial, retaining the provider diagnostic for host observers. */
24
26
  export declare class OAuthAuthorizationError extends Error {
25
27
  readonly error: string;
@@ -2,6 +2,12 @@ import http from "node:http";
2
2
  import { parseAuthorizationState } from "./authorization-state.js";
3
3
  const authorizationErrorBrand = Symbol.for("poe-platform.mcp-oauth.OAuthAuthorizationError");
4
4
  const oauthCallbackParameters = ["code", "state", "iss", "error", "error_description", "error_uri"];
5
+ /** Capture declared configuration regardless of property enumerability. */
6
+ export function snapshotLoopbackAuthorizationOptions(options) {
7
+ return { ...options, openBrowser: options.openBrowser?.bind(options), readLine: options.readLine?.bind(options), createServer: options.createServer?.bind(options),
8
+ callbackPath: options.callbackPath, redirectUri: options.redirectUri, signal: options.signal, timeoutMs: options.timeoutMs,
9
+ landingPage: options.landingPage === undefined ? undefined : { ...options.landingPage } };
10
+ }
5
11
  /** Authorization callback denial, retaining the provider diagnostic for host observers. */
6
12
  export class OAuthAuthorizationError extends Error {
7
13
  error;
@@ -19,10 +25,7 @@ export class OAuthAuthorizationError extends Error {
19
25
  }
20
26
  }
21
27
  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 } };
28
+ options = snapshotLoopbackAuthorizationOptions(options);
26
29
  options.signal?.throwIfAborted();
27
30
  const timeoutMs = options.timeoutMs ?? 120_000;
28
31
  if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > 2_147_483_647)
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tiny-http-mcp-server",
3
- "version": "0.1.82",
3
+ "version": "0.1.84",
4
4
  "description": "Minimal MCP server over HTTP built on tiny-stdio-mcp-server",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -3518,6 +3518,19 @@ function getOwnEntry(record2, key2) {
3518
3518
  // ../mcp-oauth/dist/client/loopback-authorization.js
3519
3519
  var authorizationErrorBrand = /* @__PURE__ */ Symbol.for("poe-platform.mcp-oauth.OAuthAuthorizationError");
3520
3520
  var oauthCallbackParameters = ["code", "state", "iss", "error", "error_description", "error_uri"];
3521
+ function snapshotLoopbackAuthorizationOptions(options) {
3522
+ return {
3523
+ ...options,
3524
+ openBrowser: options.openBrowser?.bind(options),
3525
+ readLine: options.readLine?.bind(options),
3526
+ createServer: options.createServer?.bind(options),
3527
+ callbackPath: options.callbackPath,
3528
+ redirectUri: options.redirectUri,
3529
+ signal: options.signal,
3530
+ timeoutMs: options.timeoutMs,
3531
+ landingPage: options.landingPage === void 0 ? void 0 : { ...options.landingPage }
3532
+ };
3533
+ }
3521
3534
  var OAuthAuthorizationError = class extends Error {
3522
3535
  error;
3523
3536
  errorDescription;
@@ -3534,14 +3547,7 @@ var OAuthAuthorizationError = class extends Error {
3534
3547
  }
3535
3548
  };
3536
3549
  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
- };
3550
+ options = snapshotLoopbackAuthorizationOptions(options);
3545
3551
  options.signal?.throwIfAborted();
3546
3552
  const timeoutMs = options.timeoutMs ?? 12e4;
3547
3553
  if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > 2147483647)
@@ -5321,10 +5327,7 @@ function createOAuthClientProvider(options) {
5321
5327
  return createDefaultOAuthClientProvider(options);
5322
5328
  }
5323
5329
  function createDefaultOAuthClientProvider(options) {
5324
- const browser = {
5325
- ...options.browser,
5326
- ...options.browser.landingPage === void 0 ? {} : { landingPage: { ...options.browser.landingPage } }
5327
- };
5330
+ const browser = snapshotLoopbackAuthorizationOptions(options.browser);
5328
5331
  const clientMode = options.client.mode;
5329
5332
  const interactiveEnabled = options.allowInteractive !== false;
5330
5333
  const sessionLockTimeoutMs = options.sessionLockTimeoutMs;
@@ -5688,7 +5691,7 @@ function createDefaultOAuthClientProvider(options) {
5688
5691
  }
5689
5692
  async function resolveClient(existingSession, discovery, redirectUri, fetch2, parentSignal) {
5690
5693
  parentSignal?.throwIfAborted();
5691
- if (clientMode === "static" || configuredClient?.registration !== void 0) {
5694
+ if (clientMode === "static" || configuredClient !== null) {
5692
5695
  if (configuredClient === null) {
5693
5696
  throw new Error("OAuth client_id must not be blank");
5694
5697
  }
@@ -5702,13 +5705,6 @@ function createDefaultOAuthClientProvider(options) {
5702
5705
  };
5703
5706
  }
5704
5707
  const registrationEndpoint = getOwnString2(discovery.authorizationServerMetadata, "registration_endpoint");
5705
- if (registrationEndpoint === void 0 && configuredClient !== null) {
5706
- return {
5707
- kind: "static",
5708
- fromStoredRegistration: false,
5709
- client: configuredClient
5710
- };
5711
- }
5712
5708
  let storedClient = await loadRegisteredClient(discovery.authorizationServer);
5713
5709
  const importedClient = existingSession?.client.registrationOwnership === "caller" ? existingSession.client : storedClient?.registrationOwnership === "caller" ? storedClient : void 0;
5714
5710
  if (importedClient !== void 0) {
@@ -5744,15 +5740,12 @@ function createDefaultOAuthClientProvider(options) {
5744
5740
  throw new Error("Authorization server metadata is missing registration_endpoint");
5745
5741
  }
5746
5742
  if (existingSession !== null && existingSession.client.clientId.length > 0 && !hasExpiredClientSecret(existingSession.client, now) && registrationMatchesRedirect(existingSession.client, redirectUri)) {
5747
- const isConfiguredStaticFallback = configuredClient !== null && existingSession.client.clientId === configuredClient.clientId && existingSession.client.clientSecret === configuredClient.clientSecret;
5748
- if (!isConfiguredStaticFallback) {
5749
- await saveRegisteredClient(discovery.authorizationServer, existingSession.client);
5750
- return {
5751
- kind: "dynamic",
5752
- fromStoredRegistration: true,
5753
- client: existingSession.client
5754
- };
5755
- }
5743
+ await saveRegisteredClient(discovery.authorizationServer, existingSession.client);
5744
+ return {
5745
+ kind: "dynamic",
5746
+ fromStoredRegistration: true,
5747
+ client: existingSession.client
5748
+ };
5756
5749
  }
5757
5750
  const supported = getSupportedTokenAuthMethods(discovery.authorizationServerMetadata);
5758
5751
  const registrationMethod = requestedTokenMethod ?? (supported === void 0 ? "none" : ["none", "client_secret_basic", "client_secret_post"].find((method) => supported.includes(method)));
@@ -8,7 +8,7 @@
8
8
  },
9
9
  {
10
10
  "name": "toolcraft-schema",
11
- "version": "0.0.351",
11
+ "version": "0.0.353",
12
12
  "license": "MIT"
13
13
  }
14
14
  ]
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toolcraft-schema",
3
- "version": "0.0.351",
3
+ "version": "0.0.353",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toolcraft",
3
- "version": "0.0.351",
3
+ "version": "0.0.353",
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.351",
161
+ "toolcraft-schema": "0.0.353",
162
162
  "toolcraft-design": "*",
163
163
  "@poe-code/frontmatter": "*",
164
164
  "@poe-code/agent-mcp-config": "*",