@kya-os/create-mcpi-app 1.11.2 → 1.11.4

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.
@@ -1,5 +1,5 @@
1
1
 
2
- > @kya-os/create-mcpi-app@1.11.2 build /home/runner/work/xmcp-i/xmcp-i/packages/create-mcpi-app
2
+ > @kya-os/create-mcpi-app@1.11.4 build /home/runner/work/xmcp-i/xmcp-i/packages/create-mcpi-app
3
3
  > tsc && chmod +x dist/index.js && node --import tsx scripts/build-bundles.ts
4
4
 
5
5
  🔨 Building template bundles...
@@ -7,23 +7,23 @@
7
7
 
8
8
  📦 Building template: blank
9
9
  ✅ Source files written to /home/runner/work/xmcp-i/xmcp-i/packages/create-mcpi-app/dist/.tmp-bundles/blank
10
- ✅ Bundle built: 8169879 bytes, hash: sha256:a41e8aaff5b47...
10
+ ✅ Bundle built: 8172141 bytes, hash: sha256:964b549d9b27c...
11
11
 
12
12
  📦 Building template: hardware-world
13
13
  ✅ Source files written to /home/runner/work/xmcp-i/xmcp-i/packages/create-mcpi-app/dist/.tmp-bundles/hardware-world
14
- ✅ Bundle built: 8182298 bytes, hash: sha256:53b53d9d5fbec...
14
+ ✅ Bundle built: 8184560 bytes, hash: sha256:613ed3ca8a593...
15
15
 
16
16
  📦 Building template: ecommerce
17
17
  ✅ Source files written to /home/runner/work/xmcp-i/xmcp-i/packages/create-mcpi-app/dist/.tmp-bundles/ecommerce
18
- ✅ Bundle built: 8171573 bytes, hash: sha256:409344a00bc6b...
18
+ ✅ Bundle built: 8173835 bytes, hash: sha256:e1de25fb7a73e...
19
19
 
20
20
  📦 Building template: mix-station
21
21
  ✅ Source files written to /home/runner/work/xmcp-i/xmcp-i/packages/create-mcpi-app/dist/.tmp-bundles/mix-station
22
- ✅ Bundle built: 8184923 bytes, hash: sha256:1caa1051b3d6c...
22
+ ✅ Bundle built: 8187185 bytes, hash: sha256:b5acc100ef55c...
23
23
 
24
24
  ✅ All bundles built successfully!
25
25
  Output: /home/runner/work/xmcp-i/xmcp-i/packages/create-mcpi-app/dist/bundles
26
- Version: 1.11.2
27
- Framework: 1.14.2
26
+ Version: 1.11.4
27
+ Framework: 1.14.5
28
28
  Templates: blank, hardware-world, ecommerce, mix-station
29
29
  Manifest: /home/runner/work/xmcp-i/xmcp-i/packages/create-mcpi-app/dist/bundles/manifest.json
@@ -159215,9 +159215,11 @@ var import_config = __toESM(require_config2());
159215
159215
 
159216
159216
  // ../mcp-i-cloudflare/dist/delegation-http/remote-issuer.js
159217
159217
  var import_json_canonicalize7 = __toESM(require_index_umd());
159218
+ init_esm2();
159218
159219
  init_native_fetch();
159219
159220
  init_native_http();
159220
159221
  var encoder8 = new TextEncoder();
159222
+ var sourceIpSchema = external_exports2.string().max(45).ip();
159221
159223
  var fail = () => {
159222
159224
  throw new Error("Native issuer capability unavailable");
159223
159225
  };
@@ -159249,12 +159251,22 @@ function resolveManagedNativeIssuer(env2) {
159249
159251
  return null;
159250
159252
  try {
159251
159253
  const binding = JSON.parse(env2.MCPI_NATIVE_HTTP_ISSUER_CONFIG);
159252
- if (!binding || Object.keys(binding).length !== 6 || binding.version !== 1 || !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(binding.projectId) || !/^did:web:[^/?#]+:orgs:[a-z0-9][a-z0-9-]*$/.test(binding.issuerDid) || bytes(binding.issuerPublicKey).length !== 32 || !isOrigin(binding.authorizationOrigin) || !isOrigin(binding.controlPlaneOrigin) || !env2.MCPI_NATIVE_HTTP_ISSUER_API_KEY || env2.MCPI_NATIVE_HTTP_ISSUER_API_KEY !== env2.AGENTSHIELD_API_KEY || env2.CHECKPOINT_API_KEY !== void 0 && env2.CHECKPOINT_API_KEY !== env2.MCPI_NATIVE_HTTP_ISSUER_API_KEY)
159254
+ if (!binding || env2.MCPI_NATIVE_HTTP_INGRESS !== void 0 && env2.MCPI_NATIVE_HTTP_INGRESS !== "cloudflare-dispatch" || Object.keys(binding).length !== 6 || binding.version !== 1 || !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(binding.projectId) || !/^did:web:[^/?#]+:orgs:[a-z0-9][a-z0-9-]*$/.test(binding.issuerDid) || bytes(binding.issuerPublicKey).length !== 32 || !isOrigin(binding.authorizationOrigin) || !isOrigin(binding.controlPlaneOrigin) || !env2.MCPI_NATIVE_HTTP_ISSUER_API_KEY || env2.MCPI_NATIVE_HTTP_ISSUER_API_KEY !== env2.AGENTSHIELD_API_KEY || env2.CHECKPOINT_API_KEY !== void 0 && env2.CHECKPOINT_API_KEY !== env2.MCPI_NATIVE_HTTP_ISSUER_API_KEY)
159253
159255
  return null;
159254
159256
  return {
159255
159257
  authorizationOrigin: binding.authorizationOrigin,
159256
159258
  issuerDid: binding.issuerDid,
159257
159259
  projectId: binding.projectId,
159260
+ // Isolated WfP workers cannot access request.cf. This deployment-owned
159261
+ // opt-in is valid only behind a Cloudflare dispatch ingress that passes
159262
+ // Cloudflare's CF-Connecting-IP unchanged. Never infer trust from a header
159263
+ // supplied by the caller, or fall back to X-Forwarded-For / X-Real-IP.
159264
+ ...env2.MCPI_NATIVE_HTTP_INGRESS === "cloudflare-dispatch" ? {
159265
+ resolveSourceIp: (request) => {
159266
+ const ip = request.headers.get("CF-Connecting-IP");
159267
+ return sourceIpSchema.safeParse(ip).success ? ip : null;
159268
+ }
159269
+ } : {},
159258
159270
  remoteIssuer: createRemoteIssuer(binding, env2.MCPI_NATIVE_HTTP_ISSUER_API_KEY)
159259
159271
  };
159260
159272
  } catch {
@@ -159561,6 +159573,7 @@ function mapPrefixedEnv(env2, prefix) {
159561
159573
  MCP_IDENTITY_PUBLIC_KEY: typeof env2.MCP_IDENTITY_PUBLIC_KEY === "string" ? env2.MCP_IDENTITY_PUBLIC_KEY : void 0,
159562
159574
  MCP_IDENTITY_AGENT_DID: typeof env2.MCP_IDENTITY_AGENT_DID === "string" ? env2.MCP_IDENTITY_AGENT_DID : void 0,
159563
159575
  MCPI_NATIVE_HTTP_ISSUER_CONFIG: typeof env2.MCPI_NATIVE_HTTP_ISSUER_CONFIG === "string" ? env2.MCPI_NATIVE_HTTP_ISSUER_CONFIG : void 0,
159576
+ MCPI_NATIVE_HTTP_INGRESS: typeof env2.MCPI_NATIVE_HTTP_INGRESS === "string" ? env2.MCPI_NATIVE_HTTP_INGRESS : void 0,
159564
159577
  MCPI_NATIVE_HTTP_ISSUER_API_KEY: typeof env2.MCPI_NATIVE_HTTP_ISSUER_API_KEY === "string" ? env2.MCPI_NATIVE_HTTP_ISSUER_API_KEY : void 0,
159565
159578
  AGENTSHIELD_API_URL: typeof env2.AGENTSHIELD_API_URL === "string" ? env2.AGENTSHIELD_API_URL : void 0,
159566
159579
  AGENTSHIELD_API_KEY: typeof env2.AGENTSHIELD_API_KEY === "string" ? env2.AGENTSHIELD_API_KEY : void 0,
@@ -159633,7 +159646,12 @@ function anchorSnapshot(rec) {
159633
159646
  nativePolicyRevision: rec.nativePolicyRevision
159634
159647
  };
159635
159648
  }
159636
- var pendingBody = () => ({ status: "pending" });
159649
+ var pendingBody = (rec, now2) => ({
159650
+ status: "pending",
159651
+ // This is the remaining authorization-session lifetime, not the future VC's
159652
+ // lifetime. Preserve the frozen legacy response and the original DO deadline.
159653
+ ...rec.nativeHttp ? { expires_in: Math.max(0, Math.floor((rec.expiresAt - now2) / 1e3)) } : {}
159654
+ });
159637
159655
  var pinnedErr = () => ({ error: KYAOS_ERRORS.pickupPinned });
159638
159656
  var invalidSessionErr = () => ({ error: KYAOS_ERRORS.invalidSession });
159639
159657
  var pickupExpiredErr = () => ({ error: KYAOS_ERRORS.pickupExpired });
@@ -159737,7 +159755,7 @@ function reducePoll(rec, holder, now2) {
159737
159755
  }
159738
159756
  return {
159739
159757
  record: { ...working, lastPollAt: now2 },
159740
- response: { status: 202, body: pendingBody() }
159758
+ response: { status: 202, body: pendingBody(working, now2) }
159741
159759
  };
159742
159760
  }
159743
159761
  function reduceApprove(rec, input2, now2) {
@@ -159887,7 +159905,7 @@ async function handlePickupInternal(ctx, request, now2) {
159887
159905
  // ../mcp-i-cloudflare/package.json
159888
159906
  var package_default = {
159889
159907
  name: "@kya-os/mcp-i-cloudflare",
159890
- version: "1.14.2",
159908
+ version: "1.14.5",
159891
159909
  description: "Cloudflare Workers adapter for MCP-I framework",
159892
159910
  main: "dist/index.js",
159893
159911
  types: "dist/index.d.ts",
@@ -166377,6 +166395,22 @@ function approvalFailedPage(message3, status = 410) {
166377
166395
  <p>${escapeHtml2(message3)}</p>
166378
166396
  </main>`), status);
166379
166397
  }
166398
+ var REQUEST_NOT_PREPARED = {
166399
+ title: "Your agent has not prepared this request yet",
166400
+ body: "Before you can approve, your agent must establish the secure key that will receive your permission. No access has been granted.",
166401
+ nextStep: "Return to your chat and ask your agent to finish preparing this authorization request before sharing the approval link.",
166402
+ unsupported: "If the agent's tools cannot sign requests, this flow cannot be completed in that tool. Do not send your password or browser cookies to the agent."
166403
+ };
166404
+ function requestNotPreparedPage(sid) {
166405
+ return htmlResponse(page(REQUEST_NOT_PREPARED.title, `<main class="kya-consent-not-prepared">
166406
+ <h1>${escapeHtml2(REQUEST_NOT_PREPARED.title)}</h1>
166407
+ <p>${escapeHtml2(REQUEST_NOT_PREPARED.body)}</p>
166408
+ <h2>What to do next</h2>
166409
+ <p>${escapeHtml2(REQUEST_NOT_PREPARED.nextStep)}</p>
166410
+ <p>${escapeHtml2(REQUEST_NOT_PREPARED.unsupported)}</p>
166411
+ <p>Once your agent confirms it is ready, <a href="?sid=${encodeURIComponent(sid)}">Reload this page</a>. If the request has expired, ask your agent to start a new request.</p>
166412
+ </main>`), 409);
166413
+ }
166380
166414
  function notFoundJson() {
166381
166415
  return jsonResponse({
166382
166416
  error: "We could not find this authorization request. It may have already completed or been cancelled."
@@ -166718,7 +166752,7 @@ async function handleAnchorConsentGet(c, sid, env2, cfg) {
166718
166752
  }
166719
166753
  const info = await infoResponse.json();
166720
166754
  if (info.nativeHttp && (!info.holderKeyId || info.status === "pending")) {
166721
- return approvalFailedPage("The agent must establish its pickup key before you approve.", 409);
166755
+ return requestNotPreparedPage(sid);
166722
166756
  }
166723
166757
  if (info.nativeHttp && (!cfg.native || info.nativeIssuerDid !== cfg.native.issuerDid))
166724
166758
  return nativeUnavailable();
@@ -166796,7 +166830,7 @@ async function handleAnchorConsentApprove(c, sid, env2, cfg) {
166796
166830
  }
166797
166831
  const info = await infoResponse.json();
166798
166832
  if (info.nativeHttp && (!info.holderKeyId || info.status === "pending")) {
166799
- return approvalFailedJson("The agent must establish its pickup key before you approve.", 409);
166833
+ return approvalFailedJson(`${REQUEST_NOT_PREPARED.title}. ${REQUEST_NOT_PREPARED.body} ${REQUEST_NOT_PREPARED.nextStep} ${REQUEST_NOT_PREPARED.unsupported}`, 409);
166800
166834
  }
166801
166835
  if (info.nativeHttp && (!cfg.native || info.nativeIssuerDid !== cfg.native.issuerDid))
166802
166836
  return nativeUnavailable();
@@ -159215,9 +159215,11 @@ var import_config = __toESM(require_config2());
159215
159215
 
159216
159216
  // ../mcp-i-cloudflare/dist/delegation-http/remote-issuer.js
159217
159217
  var import_json_canonicalize7 = __toESM(require_index_umd());
159218
+ init_esm2();
159218
159219
  init_native_fetch();
159219
159220
  init_native_http();
159220
159221
  var encoder8 = new TextEncoder();
159222
+ var sourceIpSchema = external_exports2.string().max(45).ip();
159221
159223
  var fail = () => {
159222
159224
  throw new Error("Native issuer capability unavailable");
159223
159225
  };
@@ -159249,12 +159251,22 @@ function resolveManagedNativeIssuer(env2) {
159249
159251
  return null;
159250
159252
  try {
159251
159253
  const binding = JSON.parse(env2.MCPI_NATIVE_HTTP_ISSUER_CONFIG);
159252
- if (!binding || Object.keys(binding).length !== 6 || binding.version !== 1 || !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(binding.projectId) || !/^did:web:[^/?#]+:orgs:[a-z0-9][a-z0-9-]*$/.test(binding.issuerDid) || bytes(binding.issuerPublicKey).length !== 32 || !isOrigin(binding.authorizationOrigin) || !isOrigin(binding.controlPlaneOrigin) || !env2.MCPI_NATIVE_HTTP_ISSUER_API_KEY || env2.MCPI_NATIVE_HTTP_ISSUER_API_KEY !== env2.AGENTSHIELD_API_KEY || env2.CHECKPOINT_API_KEY !== void 0 && env2.CHECKPOINT_API_KEY !== env2.MCPI_NATIVE_HTTP_ISSUER_API_KEY)
159254
+ if (!binding || env2.MCPI_NATIVE_HTTP_INGRESS !== void 0 && env2.MCPI_NATIVE_HTTP_INGRESS !== "cloudflare-dispatch" || Object.keys(binding).length !== 6 || binding.version !== 1 || !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(binding.projectId) || !/^did:web:[^/?#]+:orgs:[a-z0-9][a-z0-9-]*$/.test(binding.issuerDid) || bytes(binding.issuerPublicKey).length !== 32 || !isOrigin(binding.authorizationOrigin) || !isOrigin(binding.controlPlaneOrigin) || !env2.MCPI_NATIVE_HTTP_ISSUER_API_KEY || env2.MCPI_NATIVE_HTTP_ISSUER_API_KEY !== env2.AGENTSHIELD_API_KEY || env2.CHECKPOINT_API_KEY !== void 0 && env2.CHECKPOINT_API_KEY !== env2.MCPI_NATIVE_HTTP_ISSUER_API_KEY)
159253
159255
  return null;
159254
159256
  return {
159255
159257
  authorizationOrigin: binding.authorizationOrigin,
159256
159258
  issuerDid: binding.issuerDid,
159257
159259
  projectId: binding.projectId,
159260
+ // Isolated WfP workers cannot access request.cf. This deployment-owned
159261
+ // opt-in is valid only behind a Cloudflare dispatch ingress that passes
159262
+ // Cloudflare's CF-Connecting-IP unchanged. Never infer trust from a header
159263
+ // supplied by the caller, or fall back to X-Forwarded-For / X-Real-IP.
159264
+ ...env2.MCPI_NATIVE_HTTP_INGRESS === "cloudflare-dispatch" ? {
159265
+ resolveSourceIp: (request) => {
159266
+ const ip = request.headers.get("CF-Connecting-IP");
159267
+ return sourceIpSchema.safeParse(ip).success ? ip : null;
159268
+ }
159269
+ } : {},
159258
159270
  remoteIssuer: createRemoteIssuer(binding, env2.MCPI_NATIVE_HTTP_ISSUER_API_KEY)
159259
159271
  };
159260
159272
  } catch {
@@ -159561,6 +159573,7 @@ function mapPrefixedEnv(env2, prefix) {
159561
159573
  MCP_IDENTITY_PUBLIC_KEY: typeof env2.MCP_IDENTITY_PUBLIC_KEY === "string" ? env2.MCP_IDENTITY_PUBLIC_KEY : void 0,
159562
159574
  MCP_IDENTITY_AGENT_DID: typeof env2.MCP_IDENTITY_AGENT_DID === "string" ? env2.MCP_IDENTITY_AGENT_DID : void 0,
159563
159575
  MCPI_NATIVE_HTTP_ISSUER_CONFIG: typeof env2.MCPI_NATIVE_HTTP_ISSUER_CONFIG === "string" ? env2.MCPI_NATIVE_HTTP_ISSUER_CONFIG : void 0,
159576
+ MCPI_NATIVE_HTTP_INGRESS: typeof env2.MCPI_NATIVE_HTTP_INGRESS === "string" ? env2.MCPI_NATIVE_HTTP_INGRESS : void 0,
159564
159577
  MCPI_NATIVE_HTTP_ISSUER_API_KEY: typeof env2.MCPI_NATIVE_HTTP_ISSUER_API_KEY === "string" ? env2.MCPI_NATIVE_HTTP_ISSUER_API_KEY : void 0,
159565
159578
  AGENTSHIELD_API_URL: typeof env2.AGENTSHIELD_API_URL === "string" ? env2.AGENTSHIELD_API_URL : void 0,
159566
159579
  AGENTSHIELD_API_KEY: typeof env2.AGENTSHIELD_API_KEY === "string" ? env2.AGENTSHIELD_API_KEY : void 0,
@@ -159633,7 +159646,12 @@ function anchorSnapshot(rec) {
159633
159646
  nativePolicyRevision: rec.nativePolicyRevision
159634
159647
  };
159635
159648
  }
159636
- var pendingBody = () => ({ status: "pending" });
159649
+ var pendingBody = (rec, now2) => ({
159650
+ status: "pending",
159651
+ // This is the remaining authorization-session lifetime, not the future VC's
159652
+ // lifetime. Preserve the frozen legacy response and the original DO deadline.
159653
+ ...rec.nativeHttp ? { expires_in: Math.max(0, Math.floor((rec.expiresAt - now2) / 1e3)) } : {}
159654
+ });
159637
159655
  var pinnedErr = () => ({ error: KYAOS_ERRORS.pickupPinned });
159638
159656
  var invalidSessionErr = () => ({ error: KYAOS_ERRORS.invalidSession });
159639
159657
  var pickupExpiredErr = () => ({ error: KYAOS_ERRORS.pickupExpired });
@@ -159737,7 +159755,7 @@ function reducePoll(rec, holder, now2) {
159737
159755
  }
159738
159756
  return {
159739
159757
  record: { ...working, lastPollAt: now2 },
159740
- response: { status: 202, body: pendingBody() }
159758
+ response: { status: 202, body: pendingBody(working, now2) }
159741
159759
  };
159742
159760
  }
159743
159761
  function reduceApprove(rec, input2, now2) {
@@ -159887,7 +159905,7 @@ async function handlePickupInternal(ctx, request, now2) {
159887
159905
  // ../mcp-i-cloudflare/package.json
159888
159906
  var package_default = {
159889
159907
  name: "@kya-os/mcp-i-cloudflare",
159890
- version: "1.14.2",
159908
+ version: "1.14.5",
159891
159909
  description: "Cloudflare Workers adapter for MCP-I framework",
159892
159910
  main: "dist/index.js",
159893
159911
  types: "dist/index.d.ts",
@@ -166377,6 +166395,22 @@ function approvalFailedPage(message3, status = 410) {
166377
166395
  <p>${escapeHtml2(message3)}</p>
166378
166396
  </main>`), status);
166379
166397
  }
166398
+ var REQUEST_NOT_PREPARED = {
166399
+ title: "Your agent has not prepared this request yet",
166400
+ body: "Before you can approve, your agent must establish the secure key that will receive your permission. No access has been granted.",
166401
+ nextStep: "Return to your chat and ask your agent to finish preparing this authorization request before sharing the approval link.",
166402
+ unsupported: "If the agent's tools cannot sign requests, this flow cannot be completed in that tool. Do not send your password or browser cookies to the agent."
166403
+ };
166404
+ function requestNotPreparedPage(sid) {
166405
+ return htmlResponse(page(REQUEST_NOT_PREPARED.title, `<main class="kya-consent-not-prepared">
166406
+ <h1>${escapeHtml2(REQUEST_NOT_PREPARED.title)}</h1>
166407
+ <p>${escapeHtml2(REQUEST_NOT_PREPARED.body)}</p>
166408
+ <h2>What to do next</h2>
166409
+ <p>${escapeHtml2(REQUEST_NOT_PREPARED.nextStep)}</p>
166410
+ <p>${escapeHtml2(REQUEST_NOT_PREPARED.unsupported)}</p>
166411
+ <p>Once your agent confirms it is ready, <a href="?sid=${encodeURIComponent(sid)}">Reload this page</a>. If the request has expired, ask your agent to start a new request.</p>
166412
+ </main>`), 409);
166413
+ }
166380
166414
  function notFoundJson() {
166381
166415
  return jsonResponse({
166382
166416
  error: "We could not find this authorization request. It may have already completed or been cancelled."
@@ -166718,7 +166752,7 @@ async function handleAnchorConsentGet(c, sid, env2, cfg) {
166718
166752
  }
166719
166753
  const info = await infoResponse.json();
166720
166754
  if (info.nativeHttp && (!info.holderKeyId || info.status === "pending")) {
166721
- return approvalFailedPage("The agent must establish its pickup key before you approve.", 409);
166755
+ return requestNotPreparedPage(sid);
166722
166756
  }
166723
166757
  if (info.nativeHttp && (!cfg.native || info.nativeIssuerDid !== cfg.native.issuerDid))
166724
166758
  return nativeUnavailable();
@@ -166796,7 +166830,7 @@ async function handleAnchorConsentApprove(c, sid, env2, cfg) {
166796
166830
  }
166797
166831
  const info = await infoResponse.json();
166798
166832
  if (info.nativeHttp && (!info.holderKeyId || info.status === "pending")) {
166799
- return approvalFailedJson("The agent must establish its pickup key before you approve.", 409);
166833
+ return approvalFailedJson(`${REQUEST_NOT_PREPARED.title}. ${REQUEST_NOT_PREPARED.body} ${REQUEST_NOT_PREPARED.nextStep} ${REQUEST_NOT_PREPARED.unsupported}`, 409);
166800
166834
  }
166801
166835
  if (info.nativeHttp && (!cfg.native || info.nativeIssuerDid !== cfg.native.issuerDid))
166802
166836
  return nativeUnavailable();
@@ -159215,9 +159215,11 @@ var import_config = __toESM(require_config2());
159215
159215
 
159216
159216
  // ../mcp-i-cloudflare/dist/delegation-http/remote-issuer.js
159217
159217
  var import_json_canonicalize7 = __toESM(require_index_umd());
159218
+ init_esm2();
159218
159219
  init_native_fetch();
159219
159220
  init_native_http();
159220
159221
  var encoder8 = new TextEncoder();
159222
+ var sourceIpSchema = external_exports2.string().max(45).ip();
159221
159223
  var fail = () => {
159222
159224
  throw new Error("Native issuer capability unavailable");
159223
159225
  };
@@ -159249,12 +159251,22 @@ function resolveManagedNativeIssuer(env2) {
159249
159251
  return null;
159250
159252
  try {
159251
159253
  const binding = JSON.parse(env2.MCPI_NATIVE_HTTP_ISSUER_CONFIG);
159252
- if (!binding || Object.keys(binding).length !== 6 || binding.version !== 1 || !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(binding.projectId) || !/^did:web:[^/?#]+:orgs:[a-z0-9][a-z0-9-]*$/.test(binding.issuerDid) || bytes(binding.issuerPublicKey).length !== 32 || !isOrigin(binding.authorizationOrigin) || !isOrigin(binding.controlPlaneOrigin) || !env2.MCPI_NATIVE_HTTP_ISSUER_API_KEY || env2.MCPI_NATIVE_HTTP_ISSUER_API_KEY !== env2.AGENTSHIELD_API_KEY || env2.CHECKPOINT_API_KEY !== void 0 && env2.CHECKPOINT_API_KEY !== env2.MCPI_NATIVE_HTTP_ISSUER_API_KEY)
159254
+ if (!binding || env2.MCPI_NATIVE_HTTP_INGRESS !== void 0 && env2.MCPI_NATIVE_HTTP_INGRESS !== "cloudflare-dispatch" || Object.keys(binding).length !== 6 || binding.version !== 1 || !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(binding.projectId) || !/^did:web:[^/?#]+:orgs:[a-z0-9][a-z0-9-]*$/.test(binding.issuerDid) || bytes(binding.issuerPublicKey).length !== 32 || !isOrigin(binding.authorizationOrigin) || !isOrigin(binding.controlPlaneOrigin) || !env2.MCPI_NATIVE_HTTP_ISSUER_API_KEY || env2.MCPI_NATIVE_HTTP_ISSUER_API_KEY !== env2.AGENTSHIELD_API_KEY || env2.CHECKPOINT_API_KEY !== void 0 && env2.CHECKPOINT_API_KEY !== env2.MCPI_NATIVE_HTTP_ISSUER_API_KEY)
159253
159255
  return null;
159254
159256
  return {
159255
159257
  authorizationOrigin: binding.authorizationOrigin,
159256
159258
  issuerDid: binding.issuerDid,
159257
159259
  projectId: binding.projectId,
159260
+ // Isolated WfP workers cannot access request.cf. This deployment-owned
159261
+ // opt-in is valid only behind a Cloudflare dispatch ingress that passes
159262
+ // Cloudflare's CF-Connecting-IP unchanged. Never infer trust from a header
159263
+ // supplied by the caller, or fall back to X-Forwarded-For / X-Real-IP.
159264
+ ...env2.MCPI_NATIVE_HTTP_INGRESS === "cloudflare-dispatch" ? {
159265
+ resolveSourceIp: (request) => {
159266
+ const ip = request.headers.get("CF-Connecting-IP");
159267
+ return sourceIpSchema.safeParse(ip).success ? ip : null;
159268
+ }
159269
+ } : {},
159258
159270
  remoteIssuer: createRemoteIssuer(binding, env2.MCPI_NATIVE_HTTP_ISSUER_API_KEY)
159259
159271
  };
159260
159272
  } catch {
@@ -159561,6 +159573,7 @@ function mapPrefixedEnv(env2, prefix) {
159561
159573
  MCP_IDENTITY_PUBLIC_KEY: typeof env2.MCP_IDENTITY_PUBLIC_KEY === "string" ? env2.MCP_IDENTITY_PUBLIC_KEY : void 0,
159562
159574
  MCP_IDENTITY_AGENT_DID: typeof env2.MCP_IDENTITY_AGENT_DID === "string" ? env2.MCP_IDENTITY_AGENT_DID : void 0,
159563
159575
  MCPI_NATIVE_HTTP_ISSUER_CONFIG: typeof env2.MCPI_NATIVE_HTTP_ISSUER_CONFIG === "string" ? env2.MCPI_NATIVE_HTTP_ISSUER_CONFIG : void 0,
159576
+ MCPI_NATIVE_HTTP_INGRESS: typeof env2.MCPI_NATIVE_HTTP_INGRESS === "string" ? env2.MCPI_NATIVE_HTTP_INGRESS : void 0,
159564
159577
  MCPI_NATIVE_HTTP_ISSUER_API_KEY: typeof env2.MCPI_NATIVE_HTTP_ISSUER_API_KEY === "string" ? env2.MCPI_NATIVE_HTTP_ISSUER_API_KEY : void 0,
159565
159578
  AGENTSHIELD_API_URL: typeof env2.AGENTSHIELD_API_URL === "string" ? env2.AGENTSHIELD_API_URL : void 0,
159566
159579
  AGENTSHIELD_API_KEY: typeof env2.AGENTSHIELD_API_KEY === "string" ? env2.AGENTSHIELD_API_KEY : void 0,
@@ -159633,7 +159646,12 @@ function anchorSnapshot(rec) {
159633
159646
  nativePolicyRevision: rec.nativePolicyRevision
159634
159647
  };
159635
159648
  }
159636
- var pendingBody = () => ({ status: "pending" });
159649
+ var pendingBody = (rec, now2) => ({
159650
+ status: "pending",
159651
+ // This is the remaining authorization-session lifetime, not the future VC's
159652
+ // lifetime. Preserve the frozen legacy response and the original DO deadline.
159653
+ ...rec.nativeHttp ? { expires_in: Math.max(0, Math.floor((rec.expiresAt - now2) / 1e3)) } : {}
159654
+ });
159637
159655
  var pinnedErr = () => ({ error: KYAOS_ERRORS.pickupPinned });
159638
159656
  var invalidSessionErr = () => ({ error: KYAOS_ERRORS.invalidSession });
159639
159657
  var pickupExpiredErr = () => ({ error: KYAOS_ERRORS.pickupExpired });
@@ -159737,7 +159755,7 @@ function reducePoll(rec, holder, now2) {
159737
159755
  }
159738
159756
  return {
159739
159757
  record: { ...working, lastPollAt: now2 },
159740
- response: { status: 202, body: pendingBody() }
159758
+ response: { status: 202, body: pendingBody(working, now2) }
159741
159759
  };
159742
159760
  }
159743
159761
  function reduceApprove(rec, input2, now2) {
@@ -159887,7 +159905,7 @@ async function handlePickupInternal(ctx, request, now2) {
159887
159905
  // ../mcp-i-cloudflare/package.json
159888
159906
  var package_default = {
159889
159907
  name: "@kya-os/mcp-i-cloudflare",
159890
- version: "1.14.2",
159908
+ version: "1.14.5",
159891
159909
  description: "Cloudflare Workers adapter for MCP-I framework",
159892
159910
  main: "dist/index.js",
159893
159911
  types: "dist/index.d.ts",
@@ -166377,6 +166395,22 @@ function approvalFailedPage(message3, status = 410) {
166377
166395
  <p>${escapeHtml2(message3)}</p>
166378
166396
  </main>`), status);
166379
166397
  }
166398
+ var REQUEST_NOT_PREPARED = {
166399
+ title: "Your agent has not prepared this request yet",
166400
+ body: "Before you can approve, your agent must establish the secure key that will receive your permission. No access has been granted.",
166401
+ nextStep: "Return to your chat and ask your agent to finish preparing this authorization request before sharing the approval link.",
166402
+ unsupported: "If the agent's tools cannot sign requests, this flow cannot be completed in that tool. Do not send your password or browser cookies to the agent."
166403
+ };
166404
+ function requestNotPreparedPage(sid) {
166405
+ return htmlResponse(page(REQUEST_NOT_PREPARED.title, `<main class="kya-consent-not-prepared">
166406
+ <h1>${escapeHtml2(REQUEST_NOT_PREPARED.title)}</h1>
166407
+ <p>${escapeHtml2(REQUEST_NOT_PREPARED.body)}</p>
166408
+ <h2>What to do next</h2>
166409
+ <p>${escapeHtml2(REQUEST_NOT_PREPARED.nextStep)}</p>
166410
+ <p>${escapeHtml2(REQUEST_NOT_PREPARED.unsupported)}</p>
166411
+ <p>Once your agent confirms it is ready, <a href="?sid=${encodeURIComponent(sid)}">Reload this page</a>. If the request has expired, ask your agent to start a new request.</p>
166412
+ </main>`), 409);
166413
+ }
166380
166414
  function notFoundJson() {
166381
166415
  return jsonResponse({
166382
166416
  error: "We could not find this authorization request. It may have already completed or been cancelled."
@@ -166718,7 +166752,7 @@ async function handleAnchorConsentGet(c, sid, env2, cfg) {
166718
166752
  }
166719
166753
  const info = await infoResponse.json();
166720
166754
  if (info.nativeHttp && (!info.holderKeyId || info.status === "pending")) {
166721
- return approvalFailedPage("The agent must establish its pickup key before you approve.", 409);
166755
+ return requestNotPreparedPage(sid);
166722
166756
  }
166723
166757
  if (info.nativeHttp && (!cfg.native || info.nativeIssuerDid !== cfg.native.issuerDid))
166724
166758
  return nativeUnavailable();
@@ -166796,7 +166830,7 @@ async function handleAnchorConsentApprove(c, sid, env2, cfg) {
166796
166830
  }
166797
166831
  const info = await infoResponse.json();
166798
166832
  if (info.nativeHttp && (!info.holderKeyId || info.status === "pending")) {
166799
- return approvalFailedJson("The agent must establish its pickup key before you approve.", 409);
166833
+ return approvalFailedJson(`${REQUEST_NOT_PREPARED.title}. ${REQUEST_NOT_PREPARED.body} ${REQUEST_NOT_PREPARED.nextStep} ${REQUEST_NOT_PREPARED.unsupported}`, 409);
166800
166834
  }
166801
166835
  if (info.nativeHttp && (!cfg.native || info.nativeIssuerDid !== cfg.native.issuerDid))
166802
166836
  return nativeUnavailable();
@@ -1,29 +1,29 @@
1
1
  {
2
- "version": "1.11.2",
3
- "frameworkVersion": "1.14.2",
2
+ "version": "1.11.4",
3
+ "frameworkVersion": "1.14.5",
4
4
  "doClassName": "MCPIAgent",
5
5
  "auditDoClassName": "AuditProducer",
6
- "buildDate": "2026-09-15T20:52:10.037Z",
6
+ "buildDate": "2026-09-17T17:15:27.894Z",
7
7
  "templates": {
8
8
  "blank": {
9
9
  "file": "blank.js",
10
- "size": 8169879,
11
- "hash": "sha256:a41e8aaff5b47df24cd40fda14f1b82250145fc770e13d691690bd62719462bb"
10
+ "size": 8172141,
11
+ "hash": "sha256:964b549d9b27cc744b75232f5315c8a2a88edd4e34da4e8d6cede681be910191"
12
12
  },
13
13
  "hardware-world": {
14
14
  "file": "hardware-world.js",
15
- "size": 8182298,
16
- "hash": "sha256:53b53d9d5fbec2def7855d5075f31ce6a3b3bae476cd2bb6c2b778a114741c68"
15
+ "size": 8184560,
16
+ "hash": "sha256:613ed3ca8a5936fa063137a257fd95183b8db7fbb28f557909fd1976c5187e1b"
17
17
  },
18
18
  "ecommerce": {
19
19
  "file": "ecommerce.js",
20
- "size": 8171573,
21
- "hash": "sha256:409344a00bc6b6637442ded50c562eb45f312e7e109a65dcc22cad318e3a1ec8"
20
+ "size": 8173835,
21
+ "hash": "sha256:e1de25fb7a73eb3d73b0d9d1c6dff89d82605b263cfe01d5ccc245238a354b28"
22
22
  },
23
23
  "mix-station": {
24
24
  "file": "mix-station.js",
25
- "size": 8184923,
26
- "hash": "sha256:1caa1051b3d6cd9959ef99f60af821c28cb420d6359fe535ec33824824f0efde"
25
+ "size": 8187185,
26
+ "hash": "sha256:b5acc100ef55c725c25eff966d5739203cb112ecded3c9430c6d1acf366136b6"
27
27
  }
28
28
  }
29
29
  }
@@ -159215,9 +159215,11 @@ var import_config = __toESM(require_config2());
159215
159215
 
159216
159216
  // ../mcp-i-cloudflare/dist/delegation-http/remote-issuer.js
159217
159217
  var import_json_canonicalize7 = __toESM(require_index_umd());
159218
+ init_esm2();
159218
159219
  init_native_fetch();
159219
159220
  init_native_http();
159220
159221
  var encoder8 = new TextEncoder();
159222
+ var sourceIpSchema = external_exports2.string().max(45).ip();
159221
159223
  var fail = () => {
159222
159224
  throw new Error("Native issuer capability unavailable");
159223
159225
  };
@@ -159249,12 +159251,22 @@ function resolveManagedNativeIssuer(env2) {
159249
159251
  return null;
159250
159252
  try {
159251
159253
  const binding = JSON.parse(env2.MCPI_NATIVE_HTTP_ISSUER_CONFIG);
159252
- if (!binding || Object.keys(binding).length !== 6 || binding.version !== 1 || !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(binding.projectId) || !/^did:web:[^/?#]+:orgs:[a-z0-9][a-z0-9-]*$/.test(binding.issuerDid) || bytes(binding.issuerPublicKey).length !== 32 || !isOrigin(binding.authorizationOrigin) || !isOrigin(binding.controlPlaneOrigin) || !env2.MCPI_NATIVE_HTTP_ISSUER_API_KEY || env2.MCPI_NATIVE_HTTP_ISSUER_API_KEY !== env2.AGENTSHIELD_API_KEY || env2.CHECKPOINT_API_KEY !== void 0 && env2.CHECKPOINT_API_KEY !== env2.MCPI_NATIVE_HTTP_ISSUER_API_KEY)
159254
+ if (!binding || env2.MCPI_NATIVE_HTTP_INGRESS !== void 0 && env2.MCPI_NATIVE_HTTP_INGRESS !== "cloudflare-dispatch" || Object.keys(binding).length !== 6 || binding.version !== 1 || !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(binding.projectId) || !/^did:web:[^/?#]+:orgs:[a-z0-9][a-z0-9-]*$/.test(binding.issuerDid) || bytes(binding.issuerPublicKey).length !== 32 || !isOrigin(binding.authorizationOrigin) || !isOrigin(binding.controlPlaneOrigin) || !env2.MCPI_NATIVE_HTTP_ISSUER_API_KEY || env2.MCPI_NATIVE_HTTP_ISSUER_API_KEY !== env2.AGENTSHIELD_API_KEY || env2.CHECKPOINT_API_KEY !== void 0 && env2.CHECKPOINT_API_KEY !== env2.MCPI_NATIVE_HTTP_ISSUER_API_KEY)
159253
159255
  return null;
159254
159256
  return {
159255
159257
  authorizationOrigin: binding.authorizationOrigin,
159256
159258
  issuerDid: binding.issuerDid,
159257
159259
  projectId: binding.projectId,
159260
+ // Isolated WfP workers cannot access request.cf. This deployment-owned
159261
+ // opt-in is valid only behind a Cloudflare dispatch ingress that passes
159262
+ // Cloudflare's CF-Connecting-IP unchanged. Never infer trust from a header
159263
+ // supplied by the caller, or fall back to X-Forwarded-For / X-Real-IP.
159264
+ ...env2.MCPI_NATIVE_HTTP_INGRESS === "cloudflare-dispatch" ? {
159265
+ resolveSourceIp: (request) => {
159266
+ const ip = request.headers.get("CF-Connecting-IP");
159267
+ return sourceIpSchema.safeParse(ip).success ? ip : null;
159268
+ }
159269
+ } : {},
159258
159270
  remoteIssuer: createRemoteIssuer(binding, env2.MCPI_NATIVE_HTTP_ISSUER_API_KEY)
159259
159271
  };
159260
159272
  } catch {
@@ -159561,6 +159573,7 @@ function mapPrefixedEnv(env2, prefix) {
159561
159573
  MCP_IDENTITY_PUBLIC_KEY: typeof env2.MCP_IDENTITY_PUBLIC_KEY === "string" ? env2.MCP_IDENTITY_PUBLIC_KEY : void 0,
159562
159574
  MCP_IDENTITY_AGENT_DID: typeof env2.MCP_IDENTITY_AGENT_DID === "string" ? env2.MCP_IDENTITY_AGENT_DID : void 0,
159563
159575
  MCPI_NATIVE_HTTP_ISSUER_CONFIG: typeof env2.MCPI_NATIVE_HTTP_ISSUER_CONFIG === "string" ? env2.MCPI_NATIVE_HTTP_ISSUER_CONFIG : void 0,
159576
+ MCPI_NATIVE_HTTP_INGRESS: typeof env2.MCPI_NATIVE_HTTP_INGRESS === "string" ? env2.MCPI_NATIVE_HTTP_INGRESS : void 0,
159564
159577
  MCPI_NATIVE_HTTP_ISSUER_API_KEY: typeof env2.MCPI_NATIVE_HTTP_ISSUER_API_KEY === "string" ? env2.MCPI_NATIVE_HTTP_ISSUER_API_KEY : void 0,
159565
159578
  AGENTSHIELD_API_URL: typeof env2.AGENTSHIELD_API_URL === "string" ? env2.AGENTSHIELD_API_URL : void 0,
159566
159579
  AGENTSHIELD_API_KEY: typeof env2.AGENTSHIELD_API_KEY === "string" ? env2.AGENTSHIELD_API_KEY : void 0,
@@ -159633,7 +159646,12 @@ function anchorSnapshot(rec) {
159633
159646
  nativePolicyRevision: rec.nativePolicyRevision
159634
159647
  };
159635
159648
  }
159636
- var pendingBody = () => ({ status: "pending" });
159649
+ var pendingBody = (rec, now2) => ({
159650
+ status: "pending",
159651
+ // This is the remaining authorization-session lifetime, not the future VC's
159652
+ // lifetime. Preserve the frozen legacy response and the original DO deadline.
159653
+ ...rec.nativeHttp ? { expires_in: Math.max(0, Math.floor((rec.expiresAt - now2) / 1e3)) } : {}
159654
+ });
159637
159655
  var pinnedErr = () => ({ error: KYAOS_ERRORS.pickupPinned });
159638
159656
  var invalidSessionErr = () => ({ error: KYAOS_ERRORS.invalidSession });
159639
159657
  var pickupExpiredErr = () => ({ error: KYAOS_ERRORS.pickupExpired });
@@ -159737,7 +159755,7 @@ function reducePoll(rec, holder, now2) {
159737
159755
  }
159738
159756
  return {
159739
159757
  record: { ...working, lastPollAt: now2 },
159740
- response: { status: 202, body: pendingBody() }
159758
+ response: { status: 202, body: pendingBody(working, now2) }
159741
159759
  };
159742
159760
  }
159743
159761
  function reduceApprove(rec, input2, now2) {
@@ -159887,7 +159905,7 @@ async function handlePickupInternal(ctx, request, now2) {
159887
159905
  // ../mcp-i-cloudflare/package.json
159888
159906
  var package_default = {
159889
159907
  name: "@kya-os/mcp-i-cloudflare",
159890
- version: "1.14.2",
159908
+ version: "1.14.5",
159891
159909
  description: "Cloudflare Workers adapter for MCP-I framework",
159892
159910
  main: "dist/index.js",
159893
159911
  types: "dist/index.d.ts",
@@ -166377,6 +166395,22 @@ function approvalFailedPage(message3, status = 410) {
166377
166395
  <p>${escapeHtml2(message3)}</p>
166378
166396
  </main>`), status);
166379
166397
  }
166398
+ var REQUEST_NOT_PREPARED = {
166399
+ title: "Your agent has not prepared this request yet",
166400
+ body: "Before you can approve, your agent must establish the secure key that will receive your permission. No access has been granted.",
166401
+ nextStep: "Return to your chat and ask your agent to finish preparing this authorization request before sharing the approval link.",
166402
+ unsupported: "If the agent's tools cannot sign requests, this flow cannot be completed in that tool. Do not send your password or browser cookies to the agent."
166403
+ };
166404
+ function requestNotPreparedPage(sid) {
166405
+ return htmlResponse(page(REQUEST_NOT_PREPARED.title, `<main class="kya-consent-not-prepared">
166406
+ <h1>${escapeHtml2(REQUEST_NOT_PREPARED.title)}</h1>
166407
+ <p>${escapeHtml2(REQUEST_NOT_PREPARED.body)}</p>
166408
+ <h2>What to do next</h2>
166409
+ <p>${escapeHtml2(REQUEST_NOT_PREPARED.nextStep)}</p>
166410
+ <p>${escapeHtml2(REQUEST_NOT_PREPARED.unsupported)}</p>
166411
+ <p>Once your agent confirms it is ready, <a href="?sid=${encodeURIComponent(sid)}">Reload this page</a>. If the request has expired, ask your agent to start a new request.</p>
166412
+ </main>`), 409);
166413
+ }
166380
166414
  function notFoundJson() {
166381
166415
  return jsonResponse({
166382
166416
  error: "We could not find this authorization request. It may have already completed or been cancelled."
@@ -166718,7 +166752,7 @@ async function handleAnchorConsentGet(c, sid, env2, cfg) {
166718
166752
  }
166719
166753
  const info = await infoResponse.json();
166720
166754
  if (info.nativeHttp && (!info.holderKeyId || info.status === "pending")) {
166721
- return approvalFailedPage("The agent must establish its pickup key before you approve.", 409);
166755
+ return requestNotPreparedPage(sid);
166722
166756
  }
166723
166757
  if (info.nativeHttp && (!cfg.native || info.nativeIssuerDid !== cfg.native.issuerDid))
166724
166758
  return nativeUnavailable();
@@ -166796,7 +166830,7 @@ async function handleAnchorConsentApprove(c, sid, env2, cfg) {
166796
166830
  }
166797
166831
  const info = await infoResponse.json();
166798
166832
  if (info.nativeHttp && (!info.holderKeyId || info.status === "pending")) {
166799
- return approvalFailedJson("The agent must establish its pickup key before you approve.", 409);
166833
+ return approvalFailedJson(`${REQUEST_NOT_PREPARED.title}. ${REQUEST_NOT_PREPARED.body} ${REQUEST_NOT_PREPARED.nextStep} ${REQUEST_NOT_PREPARED.unsupported}`, 409);
166800
166834
  }
166801
166835
  if (info.nativeHttp && (!cfg.native || info.nativeIssuerDid !== cfg.native.issuerDid))
166802
166836
  return nativeUnavailable();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kya-os/create-mcpi-app",
3
- "version": "1.11.2",
3
+ "version": "1.11.4",
4
4
  "description": "Scaffold a new MCP-I application",
5
5
  "type": "module",
6
6
  "main": "./dist/helpers/index.js",
@@ -51,7 +51,7 @@
51
51
  "@kya-os/cli-effects": "^1.0.19",
52
52
  "@kya-os/contracts": "^1.12.1",
53
53
  "@kya-os/mcp-i": "^1.12.2",
54
- "@kya-os/mcp-i-cloudflare": "^1.14.2",
54
+ "@kya-os/mcp-i-cloudflare": "^1.14.5",
55
55
  "base-x": "^5.0.0",
56
56
  "chalk": "^4.1.2",
57
57
  "commander": "^12.1.0",