@kya-os/create-mcpi-app 1.10.4 → 1.10.5

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.
@@ -141712,7 +141712,7 @@ async function handlePickupInternal(ctx, request, now2) {
141712
141712
  // ../mcp-i-cloudflare/package.json
141713
141713
  var package_default = {
141714
141714
  name: "@kya-os/mcp-i-cloudflare",
141715
- version: "1.12.2",
141715
+ version: "1.12.3",
141716
141716
  description: "Cloudflare Workers adapter for MCP-I framework",
141717
141717
  main: "dist/index.js",
141718
141718
  types: "dist/index.d.ts",
@@ -141741,9 +141741,9 @@ var package_default = {
141741
141741
  },
141742
141742
  dependencies: {
141743
141743
  "@kya-os/consent": "^0.1.41",
141744
- "@kya-os/contracts": "^1.9.1",
141744
+ "@kya-os/contracts": "^1.9.2",
141745
141745
  "@kya-os/mcp": "^1.10.1",
141746
- "@kya-os/mcp-i-core": "^1.8.2",
141746
+ "@kya-os/mcp-i-core": "^1.8.3",
141747
141747
  "@kya-os/mcp-i-runtime": "^1.0.0",
141748
141748
  "@kya-os/provider-registry": "^0.1.7",
141749
141749
  "@modelcontextprotocol/sdk": "^1.25.2",
@@ -147473,6 +147473,29 @@ function buildSuccessCheck(raw2) {
147473
147473
  }
147474
147474
  return { path, expectedValue };
147475
147475
  }
147476
+ function buildConsentOverrides(raw2) {
147477
+ if (!raw2)
147478
+ return void 0;
147479
+ const branding = readRecord(raw2, "branding", "branding");
147480
+ const formTitle = readString(raw2, "formTitle", "form_title");
147481
+ const formDescription = readString(raw2, "formDescription", "form_description");
147482
+ const identityFieldLabel = readString(raw2, "identityFieldLabel", "identity_field_label");
147483
+ const identityFieldType = readString(raw2, "identityFieldType", "identity_field_type");
147484
+ const passwordFieldLabel = readString(raw2, "passwordFieldLabel", "password_field_label");
147485
+ const submitButtonText = readString(raw2, "submitButtonText", "submit_button_text");
147486
+ if (!branding && !formTitle && !formDescription && !identityFieldLabel && !identityFieldType && !passwordFieldLabel && !submitButtonText) {
147487
+ return void 0;
147488
+ }
147489
+ return {
147490
+ ...branding ? { branding } : {},
147491
+ ...formTitle ? { formTitle } : {},
147492
+ ...formDescription ? { formDescription } : {},
147493
+ ...identityFieldLabel ? { identityFieldLabel } : {},
147494
+ ...identityFieldType ? { identityFieldType } : {},
147495
+ ...passwordFieldLabel ? { passwordFieldLabel } : {},
147496
+ ...submitButtonText ? { submitButtonText } : {}
147497
+ };
147498
+ }
147476
147499
  function buildCredentialConfig(entry) {
147477
147500
  const authEndpoint = readString(entry, "authEndpoint", "auth_endpoint");
147478
147501
  const requestBodyTemplate = readRecord(entry, "requestBodyTemplate", "request_body_template");
@@ -147494,6 +147517,7 @@ function buildCredentialConfig(entry) {
147494
147517
  const tokenUsage = readString(entry, "tokenUsage", "token_usage");
147495
147518
  const tokenHeader = readString(entry, "tokenHeader", "token_header");
147496
147519
  const cookieFormat = readString(entry, "cookieFormat", "cookie_format");
147520
+ const consentOverrides = buildConsentOverrides(readRecord(entry, "consentOverrides", "consent_overrides"));
147497
147521
  return {
147498
147522
  // The handler ignores `type`, but the contract's discriminant is "credential".
147499
147523
  type: "credential",
@@ -147505,7 +147529,8 @@ function buildCredentialConfig(entry) {
147505
147529
  ...headers ? { headers } : {},
147506
147530
  ...tokenUsage ? { tokenUsage } : {},
147507
147531
  ...tokenHeader ? { tokenHeader } : {},
147508
- ...cookieFormat ? { cookieFormat } : {}
147532
+ ...cookieFormat ? { cookieFormat } : {},
147533
+ ...consentOverrides ? { consentOverrides } : {}
147509
147534
  };
147510
147535
  }
147511
147536
  async function resolveAnchorCredentialProvider(env2, _scopes) {
@@ -147651,6 +147676,15 @@ function htmlResponse(html, status) {
147651
147676
  }
147652
147677
  });
147653
147678
  }
147679
+ function jsonResponse(body, status) {
147680
+ return new Response(JSON.stringify(body), {
147681
+ status,
147682
+ headers: {
147683
+ "Content-Type": "application/json",
147684
+ "Cache-Control": "no-store"
147685
+ }
147686
+ });
147687
+ }
147654
147688
  function page(title, bodyInner) {
147655
147689
  return `<!DOCTYPE html>
147656
147690
  <html lang="en">
@@ -147682,54 +147716,111 @@ function approvalFailedPage(message3, status = 410) {
147682
147716
  <p>${escapeHtml2(message3)}</p>
147683
147717
  </main>`), status);
147684
147718
  }
147685
- function successPage() {
147686
- return htmlResponse(page("Authorization complete", `<main class="kya-consent-success">
147687
- <h1>Authorization complete</h1>
147688
- <p>You have authorized the request. You can close this window and return to the application.</p>
147689
- </main>`), 200);
147690
- }
147691
- function approveFormPage(sid, info, csrfToken) {
147692
- const scopeItems = info.requiredScopes.length > 0 ? info.requiredScopes.map((s5) => `<li class="kya-scope-item">${escapeHtml2(s5)}</li>`).join("") : `<li class="kya-scope-item">No specific permissions required.</li>`;
147693
- return page("Permission Request", `<main class="kya-consent">
147694
- <h1>Authorize delegation</h1>
147695
- <p class="kya-permissions-header">This request needs the following permissions:</p>
147696
- <ul class="kya-permissions-list">${scopeItems}</ul>
147697
- <form method="POST" action="/consent/approve?sid=${encodeURIComponent(sid)}">
147698
- <input type="hidden" name="sid" value="${escapeHtml2(sid)}">
147699
- <input type="hidden" name="csrf_token" value="${escapeHtml2(csrfToken)}">
147700
- <button type="submit" class="kya-consent-allow">Allow</button>
147701
- </form>
147702
- </main>`);
147703
- }
147704
- function credentialFieldNames(provider) {
147705
- const names = [];
147706
- for (const template of Object.values(provider.config.requestBodyTemplate)) {
147707
- const match2 = /\{\{(\w+)\}\}/.exec(template);
147708
- if (match2 && !names.includes(match2[1]))
147709
- names.push(match2[1]);
147710
- }
147711
- return names.length > 0 ? names : ["email", "password"];
147712
- }
147713
- function credentialFormPage(sid, info, provider, csrfToken) {
147714
- const scopeItems = info.requiredScopes.length > 0 ? info.requiredScopes.map((s5) => `<li class="kya-scope-item">${escapeHtml2(s5)}</li>`).join("") : `<li class="kya-scope-item">No specific permissions required.</li>`;
147715
- const fieldInputs = credentialFieldNames(provider).map((name16) => {
147716
- const isSecret = /pass|secret|token|pin/i.test(name16);
147717
- const label = name16.charAt(0).toUpperCase() + name16.slice(1);
147718
- return `<label class="kya-field-label" for="kya-field-${escapeHtml2(name16)}">${escapeHtml2(label)}</label>
147719
- <input class="kya-field-input" id="kya-field-${escapeHtml2(name16)}" name="${escapeHtml2(name16)}" type="${isSecret ? "password" : "text"}" autocomplete="${isSecret ? "current-password" : "username"}" required>`;
147720
- }).join("");
147721
- return page("Permission Request", `<main class="kya-consent">
147722
- <h1>Sign in to authorize</h1>
147723
- <p class="kya-provider-name">${escapeHtml2(provider.displayName)}</p>
147724
- <p class="kya-permissions-header">This request needs the following permissions:</p>
147725
- <ul class="kya-permissions-list">${scopeItems}</ul>
147726
- <form method="POST" action="/consent/approve?sid=${encodeURIComponent(sid)}">
147727
- <input type="hidden" name="sid" value="${escapeHtml2(sid)}">
147728
- <input type="hidden" name="csrf_token" value="${escapeHtml2(csrfToken)}">
147729
- ${fieldInputs}
147730
- <button type="submit" class="kya-consent-allow">Sign in &amp; allow</button>
147731
- </form>
147732
- </main>`);
147719
+ function notFoundJson() {
147720
+ return jsonResponse({
147721
+ error: "We could not find this authorization request. It may have already completed or been cancelled."
147722
+ }, 404);
147723
+ }
147724
+ function approvalFailedJson(message3, status = 410) {
147725
+ return jsonResponse({ error: message3 }, status);
147726
+ }
147727
+ function successJson(delegationId) {
147728
+ return jsonResponse({ success: true, delegation_id: delegationId }, 200);
147729
+ }
147730
+ function resolveAnchorCapabilities(consentConfig, scopes) {
147731
+ if (consentConfig.capabilities && consentConfig.capabilities.length > 0) {
147732
+ return consentConfig.capabilities;
147733
+ }
147734
+ if (scopes.length === 0)
147735
+ return void 0;
147736
+ const derived = resolveCapabilitiesForScopes(scopes);
147737
+ if (derived.length === 0)
147738
+ return void 0;
147739
+ return [{ id: "default", label: "Permissions", capabilities: derived }];
147740
+ }
147741
+ function renderAnchorConsentShell(params) {
147742
+ const { consentConfig, info, sid, csrfToken, serverUrl, projectId, credential } = params;
147743
+ const cpc = credential?.provider.config;
147744
+ const cpcOverrides = cpc?.consentOverrides;
147745
+ const shellConfig = {
147746
+ branding: consentConfig.branding,
147747
+ terms: consentConfig.terms,
147748
+ customFields: consentConfig.customFields,
147749
+ ui: consentConfig.ui,
147750
+ expirationDays: consentConfig.expirationDays,
147751
+ credentials: credential ? {
147752
+ usernameLabel: cpcOverrides?.identityFieldLabel || consentConfig.credentials?.usernameLabel || "Username",
147753
+ usernamePlaceholder: consentConfig.credentials?.usernamePlaceholder || "Enter your username",
147754
+ passwordLabel: cpcOverrides?.passwordFieldLabel || consentConfig.credentials?.passwordLabel || "Password",
147755
+ passwordPlaceholder: consentConfig.credentials?.passwordPlaceholder || "Enter your password",
147756
+ showRememberMe: consentConfig.credentials?.showRememberMe ?? true,
147757
+ showForgotPassword: consentConfig.credentials?.showForgotPassword ?? false,
147758
+ forgotPasswordUrl: consentConfig.credentials?.forgotPasswordUrl
147759
+ } : consentConfig.credentials
147760
+ };
147761
+ const shellOptions = {
147762
+ config: shellConfig,
147763
+ tool: "",
147764
+ scopes: info.requiredScopes,
147765
+ agentDid: info.agentDid || "",
147766
+ sessionId: sid,
147767
+ projectId,
147768
+ serverUrl,
147769
+ // Browser-tab title only (the in-page heading is `shellConfig.ui.title`,
147770
+ // shared across screens) — surface the provider's display name here for the
147771
+ // credential branch instead of dropping it entirely.
147772
+ pageTitle: credential ? `Sign in to ${credential.provider.displayName}` : "Permission Request",
147773
+ csrfToken,
147774
+ capabilities: resolveAnchorCapabilities(consentConfig, info.requiredScopes),
147775
+ agentMetadata: consentConfig.agentMetadata,
147776
+ consentTheme: consentConfig.theme,
147777
+ headlineVerb: consentConfig.headlineVerb,
147778
+ revocationPath: consentConfig.revocationPath,
147779
+ inactivityDays: consentConfig.inactivityDays,
147780
+ ...credential ? {
147781
+ authMode: "credentials",
147782
+ provider: credential.provider.providerId,
147783
+ authorizationType: "password"
147784
+ } : {}
147785
+ };
147786
+ return generateConsentShell(shellOptions);
147787
+ }
147788
+ function resolveServerUrl(env2, c) {
147789
+ const configured = env2.MCP_SERVER_URL;
147790
+ if (configured && configured !== "null" && configured.startsWith("http")) {
147791
+ return configured;
147792
+ }
147793
+ const raw2 = c.req?.raw;
147794
+ if (raw2) {
147795
+ try {
147796
+ return new URL(raw2.url).origin;
147797
+ } catch {
147798
+ }
147799
+ }
147800
+ return "";
147801
+ }
147802
+ async function resolveApproveSid(c) {
147803
+ const query = c.req.query("sid");
147804
+ if (isAnchorSid(query))
147805
+ return query;
147806
+ const raw2 = c.req?.raw;
147807
+ if (!raw2)
147808
+ return void 0;
147809
+ try {
147810
+ const contentType2 = raw2.headers.get("Content-Type") || "";
147811
+ const clone5 = raw2.clone();
147812
+ let candidate;
147813
+ if (contentType2.includes("application/json")) {
147814
+ const body = await clone5.json();
147815
+ candidate = body.sid ?? body.session_id;
147816
+ } else {
147817
+ const form = await clone5.formData();
147818
+ candidate = form.get("sid") ?? form.get("session_id");
147819
+ }
147820
+ return typeof candidate === "string" && isAnchorSid(candidate) ? candidate : void 0;
147821
+ } catch {
147822
+ return void 0;
147823
+ }
147733
147824
  }
147734
147825
  function base64UrlEncodeBytes(bytes) {
147735
147826
  return btoa(String.fromCharCode(...bytes)).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
@@ -147872,51 +147963,69 @@ async function handleAnchorConsentGet(c, sid, env2, _cfg) {
147872
147963
  }
147873
147964
  const info = await infoResponse.json();
147874
147965
  const csrfToken = await mintCsrfToken(env2, sid);
147966
+ const projectId = env2.AGENTSHIELD_PROJECT_ID || "";
147967
+ const consentConfig = await new ConsentConfigService(env2).getConsentConfig(projectId);
147968
+ const serverUrl = resolveServerUrl(env2, c);
147875
147969
  const resolution = await resolveAnchorCredentialProvider(env2, info.requiredScopes);
147876
147970
  if (resolution.status === "credential") {
147877
- return htmlResponse(credentialFormPage(sid, info, resolution.provider, csrfToken), 200);
147971
+ return htmlResponse(renderAnchorConsentShell({
147972
+ consentConfig,
147973
+ info,
147974
+ sid,
147975
+ csrfToken,
147976
+ serverUrl,
147977
+ projectId,
147978
+ credential: { provider: resolution.provider }
147979
+ }), 200);
147878
147980
  }
147879
- return htmlResponse(approveFormPage(sid, info, csrfToken), 200);
147981
+ return htmlResponse(renderAnchorConsentShell({
147982
+ consentConfig,
147983
+ info,
147984
+ sid,
147985
+ csrfToken,
147986
+ serverUrl,
147987
+ projectId
147988
+ }), 200);
147880
147989
  }
147881
147990
  async function handleAnchorConsentApprove(c, sid, env2, cfg) {
147882
147991
  const bodyFields = await readBodyFields(c);
147883
147992
  if (!isTestConsentMode(env2)) {
147884
147993
  const valid = await validateCsrfToken(env2, sid, bodyFields.csrf_token);
147885
147994
  if (!valid) {
147886
- return htmlResponse(page("Authorization failed", `<main class="kya-consent-failed"><h1>Authorization failed</h1><p>Invalid or missing security token. Please reload and try again.</p></main>`), 403);
147995
+ return jsonResponse({
147996
+ error: "Invalid or missing security token. Please reload and try again."
147997
+ }, 403);
147887
147998
  }
147888
147999
  }
147889
148000
  const infoResponse = await callAnchor2(env2, sid, INTERNAL_PICKUP_INFO, {
147890
148001
  sid
147891
148002
  });
147892
148003
  if (infoResponse.status === 404)
147893
- return notFoundPage();
148004
+ return notFoundJson();
147894
148005
  if (infoResponse.status === 410) {
147895
- return approvalFailedPage("This authorization request has expired. Nothing was authorized.");
148006
+ return approvalFailedJson("This authorization request has expired. Nothing was authorized.");
147896
148007
  }
147897
148008
  if (!infoResponse.ok) {
147898
- return approvalFailedPage("This authorization request could not be loaded. Please start over.", 502);
148009
+ return approvalFailedJson("This authorization request could not be loaded. Please start over.", 502);
147899
148010
  }
147900
148011
  const info = await infoResponse.json();
147901
148012
  const resolution = await resolveAnchorCredentialProvider(env2, info.requiredScopes);
147902
148013
  if (resolution.status === "unavailable") {
147903
- return approvalFailedPage("We could not verify the sign-in requirement for this request. Please try again.", 503);
148014
+ return approvalFailedJson("We could not verify the sign-in requirement for this request. Please try again.", 503);
147904
148015
  }
147905
148016
  const provider = resolution.status === "credential" ? resolution.provider : null;
147906
148017
  let authorizedUser = null;
147907
148018
  if (provider) {
147908
- const credentials = {};
147909
- for (const name16 of credentialFieldNames(provider)) {
147910
- if (bodyFields[name16] !== void 0)
147911
- credentials[name16] = bodyFields[name16];
147912
- }
148019
+ const { sid: _sid, csrf_token: _csrfToken, tool: _tool, scopes: _scopes, agent_did: _agentDid, session_id: _sessionId, project_id: _projectId, provider: _providerField, provider_type: _providerType, auth_mode: _authMode, termsAccepted: _termsAccepted, credential_provider_type: _credentialProviderType, credential_provider: _credentialProvider, oauth_provider_type: _oauthProviderType, user_did: _userDid, credential_user_email: _credentialUserEmail, credential_provider_user_id: _credentialProviderUserId, ...credentials } = bodyFields;
147913
148020
  const handler = createCredentialAuthHandler({
147914
148021
  fetch: (...args) => globalThis.fetch(...args),
147915
148022
  logger: (msg, data) => console.debug(`[kya-http] ${msg}`, data)
147916
148023
  });
147917
148024
  const authResult = await handler.authenticate(provider.config, credentials);
147918
148025
  if (!authResult.success) {
147919
- return htmlResponse(page("Sign-in failed", `<main class="kya-consent-failed"><h1>Sign-in failed</h1><p>${escapeHtml2(authResult.error || "Those credentials were not accepted. Please try again.")}</p></main>`), 401);
148026
+ return jsonResponse({
148027
+ error: authResult.error || "Those credentials were not accepted. Please try again."
148028
+ }, 401);
147920
148029
  }
147921
148030
  const identity = await resolveCredentialIdentity(env2, {
147922
148031
  projectId: env2.AGENTSHIELD_PROJECT_ID || "",
@@ -147926,7 +148035,7 @@ async function handleAnchorConsentApprove(c, sid, env2, cfg) {
147926
148035
  userDisplayName: authResult.userDisplayName
147927
148036
  });
147928
148037
  if (!identity.success || !identity.userDid) {
147929
- return approvalFailedPage("We signed you in but could not resolve your identity. Please start over.", 500);
148038
+ return approvalFailedJson("We signed you in but could not resolve your identity. Please start over.", 500);
147930
148039
  }
147931
148040
  authorizedUser = {
147932
148041
  userDid: identity.userDid,
@@ -147940,7 +148049,7 @@ async function handleAnchorConsentApprove(c, sid, env2, cfg) {
147940
148049
  ({ vcJwt, subjectDid } = await mintDelegationVcJwt(env2, sid, info, cfg.delegationExpiresInS));
147941
148050
  } catch (error87) {
147942
148051
  console.warn(`[kya-http] delegation mint failed (sid=${sid}):`, error87 instanceof Error ? error87.message : String(error87));
147943
- return approvalFailedPage("We could not complete the authorization. Please start over.", 500);
148052
+ return approvalFailedJson("We could not complete the authorization. Please start over.", 500);
147944
148053
  }
147945
148054
  const approveResponse = await callAnchor2(env2, sid, INTERNAL_PICKUP_APPROVE, {
147946
148055
  sid,
@@ -147948,12 +148057,12 @@ async function handleAnchorConsentApprove(c, sid, env2, cfg) {
147948
148057
  expiresInS: cfg.delegationExpiresInS
147949
148058
  });
147950
148059
  if (approveResponse.status === 410) {
147951
- return approvalFailedPage("This authorization request expired before it could be completed. Nothing was authorized.");
148060
+ return approvalFailedJson("This authorization request expired before it could be completed. Nothing was authorized.");
147952
148061
  }
147953
148062
  if (approveResponse.status === 404)
147954
- return notFoundPage();
148063
+ return notFoundJson();
147955
148064
  if (!approveResponse.ok) {
147956
- return approvalFailedPage("We could not complete the authorization. Please start over.", 502);
148065
+ return approvalFailedJson("We could not complete the authorization. Please start over.", 502);
147957
148066
  }
147958
148067
  if (authorizedUser && provider) {
147959
148068
  const report = notifyDelegation(env2, {
@@ -147970,7 +148079,7 @@ async function handleAnchorConsentApprove(c, sid, env2, cfg) {
147970
148079
  const execCtx = c.executionCtx;
147971
148080
  execCtx?.waitUntil?.(report);
147972
148081
  }
147973
- return successPage();
148082
+ return successJson(`urn:uuid:${sid}`);
147974
148083
  }
147975
148084
  async function readBodyFields(c) {
147976
148085
  const out = {};
@@ -148024,8 +148133,10 @@ function registerDelegationHttpRoutes(app, options, deps) {
148024
148133
  });
148025
148134
  app.post(`${CONSENT_ROUTE}/approve`, async (c, next) => {
148026
148135
  const { env: env2, cfg } = resolveRequest(c, options);
148027
- const sid = c.req.query("sid");
148028
- if (!cfg || !isAnchorSid(sid))
148136
+ if (!cfg)
148137
+ return next();
148138
+ const sid = await resolveApproveSid(c);
148139
+ if (!isAnchorSid(sid))
148029
148140
  return next();
148030
148141
  return handleAnchorConsentApprove(c, sid, env2, cfg);
148031
148142
  });
@@ -78,8 +78,8 @@ export async function getPackageVersions() {
78
78
  return {
79
79
  "@kya-os/mcp-i": "^1.7.13",
80
80
  "@kya-os/cli": "^1.5.9",
81
- "@kya-os/mcp-i-cloudflare": "^1.12.2",
82
- "@kya-os/contracts": "^1.9.1",
81
+ "@kya-os/mcp-i-cloudflare": "^1.12.3",
82
+ "@kya-os/contracts": "^1.9.2",
83
83
  };
84
84
  }
85
85
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kya-os/create-mcpi-app",
3
- "version": "1.10.4",
3
+ "version": "1.10.5",
4
4
  "description": "Scaffold a new MCP-I application",
5
5
  "type": "module",
6
6
  "main": "./dist/helpers/index.js",
@@ -55,11 +55,11 @@
55
55
  },
56
56
  "dependencies": {
57
57
  "@apidevtools/swagger-parser": "^10.1.1",
58
- "@kya-os/cli": "^1.6.2",
58
+ "@kya-os/cli": "^1.6.3",
59
59
  "@kya-os/cli-effects": "^1.0.19",
60
- "@kya-os/contracts": "^1.9.1",
60
+ "@kya-os/contracts": "^1.9.2",
61
61
  "@kya-os/mcp-i": "^1.7.13",
62
- "@kya-os/mcp-i-cloudflare": "^1.12.2",
62
+ "@kya-os/mcp-i-cloudflare": "^1.12.3",
63
63
  "base-x": "^5.0.0",
64
64
  "chalk": "^4.1.2",
65
65
  "commander": "^12.1.0",