@truefoundry/trueforge 0.1.2 → 0.1.3

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.
Files changed (163) hide show
  1. package/dist/_frontend/assets/{ConnectorSettings-XEO5ZQO5-BXis0tQK.js → ConnectorSettings-EYOQ72OS-DdSqeM08.js} +1 -1
  2. package/dist/_frontend/assets/ConnectorSettings-EYOQ72OS-DdSqeM08.js.br +0 -0
  3. package/dist/_frontend/assets/ConnectorSettings-EYOQ72OS-DdSqeM08.js.gz +0 -0
  4. package/dist/_frontend/assets/{DockLayout-F2KYSY4U-D8P84kCr.js → DockLayout-XIOJZ2YM-htVfvSLo.js} +1 -1
  5. package/dist/_frontend/assets/{DrawerLayout-FJ7XC2FU-ChH-Qykr.js → DrawerLayout-CNKNNVI7-CQ7wZgB6.js} +2 -2
  6. package/dist/_frontend/assets/DrawerLayout-CNKNNVI7-CQ7wZgB6.js.br +0 -0
  7. package/dist/_frontend/assets/DrawerLayout-CNKNNVI7-CQ7wZgB6.js.gz +0 -0
  8. package/dist/_frontend/assets/{ModelSettings-2QB7LE22-CDZku4g3.js → ModelSettings-WBDPLI6O-CYfqXYXo.js} +1 -1
  9. package/dist/_frontend/assets/ModelSettings-WBDPLI6O-CYfqXYXo.js.br +0 -0
  10. package/dist/_frontend/assets/ModelSettings-WBDPLI6O-CYfqXYXo.js.gz +0 -0
  11. package/dist/_frontend/assets/{SandboxSettings-QDDIPRBP-CImJLa0r.js → SandboxSettings-4GHBXULN-BPT3vPku.js} +1 -1
  12. package/dist/_frontend/assets/SandboxSettings-4GHBXULN-BPT3vPku.js.br +0 -0
  13. package/dist/_frontend/assets/SandboxSettings-4GHBXULN-BPT3vPku.js.gz +0 -0
  14. package/dist/_frontend/assets/{SettingsBuilder-4NF3Y7UZ-eXXDLQ6k.js → SettingsBuilder-TD42LCIU-COZb69Wb.js} +2 -2
  15. package/dist/_frontend/assets/SettingsBuilder-TD42LCIU-COZb69Wb.js.br +0 -0
  16. package/dist/_frontend/assets/SettingsBuilder-TD42LCIU-COZb69Wb.js.gz +0 -0
  17. package/dist/_frontend/assets/{ShellRouteSync-T4WLY57Q-CetHx5EA.js → ShellRouteSync-T4WLY57Q-BKbLAZEv.js} +1 -1
  18. package/dist/_frontend/assets/ShellRouteSync-T4WLY57Q-BKbLAZEv.js.br +0 -0
  19. package/dist/_frontend/assets/ShellRouteSync-T4WLY57Q-BKbLAZEv.js.gz +0 -0
  20. package/dist/_frontend/assets/{SidebarLayout-KX6RSJTP-B8G4CTTb.js → SidebarLayout-JGLTENB3-BiZz45he.js} +2 -2
  21. package/dist/_frontend/assets/SidebarLayout-JGLTENB3-BiZz45he.js.br +0 -0
  22. package/dist/_frontend/assets/SidebarLayout-JGLTENB3-BiZz45he.js.gz +0 -0
  23. package/dist/_frontend/assets/{SkillSettings-5EETEEDI-DbJE0Ms2.js → SkillSettings-UG6USX4N-DhQTOueg.js} +1 -1
  24. package/dist/_frontend/assets/SkillSettings-UG6USX4N-DhQTOueg.js.br +0 -0
  25. package/dist/_frontend/assets/SkillSettings-UG6USX4N-DhQTOueg.js.gz +0 -0
  26. package/dist/_frontend/assets/{TrueForgeUIWithRouter-IAQQTD5V-9G1rELmh.js → TrueForgeUIWithRouter-CTC5XRSY-BnWelV-R.js} +1 -1
  27. package/dist/_frontend/assets/{WidgetLayout-S6EK62TZ-BPf7T3wa.js → WidgetLayout-6P6OUUTG-B1G5uZ4_.js} +1 -1
  28. package/dist/_frontend/assets/WidgetLayout-6P6OUUTG-B1G5uZ4_.js.br +0 -0
  29. package/dist/_frontend/assets/WidgetLayout-6P6OUUTG-B1G5uZ4_.js.gz +0 -0
  30. package/dist/_frontend/assets/{chunk-X6U2Q7X5-DDlfUle1.js → chunk-27MKI3HF-CVw53aeu.js} +1 -1
  31. package/dist/_frontend/assets/chunk-27MKI3HF-CVw53aeu.js.br +0 -0
  32. package/dist/_frontend/assets/chunk-27MKI3HF-CVw53aeu.js.gz +0 -0
  33. package/dist/_frontend/assets/{chunk-62JRHF6Z-BUuLA42_.js → chunk-62JRHF6Z-yJ2twjOf.js} +1 -1
  34. package/dist/_frontend/assets/chunk-62JRHF6Z-yJ2twjOf.js.br +0 -0
  35. package/dist/_frontend/assets/chunk-62JRHF6Z-yJ2twjOf.js.gz +0 -0
  36. package/dist/_frontend/assets/{chunk-PTYEOSHT-C4gdhLwo.js → chunk-H75C5ETA-CX-fQN0e.js} +2 -2
  37. package/dist/_frontend/assets/chunk-H75C5ETA-CX-fQN0e.js.br +0 -0
  38. package/dist/_frontend/assets/chunk-H75C5ETA-CX-fQN0e.js.gz +0 -0
  39. package/dist/_frontend/assets/{cssMode-C1whwlDW.js → cssMode-CEpMXY8Z.js} +1 -1
  40. package/dist/_frontend/assets/cssMode-CEpMXY8Z.js.br +0 -0
  41. package/dist/_frontend/assets/cssMode-CEpMXY8Z.js.gz +0 -0
  42. package/dist/_frontend/assets/{freemarker2-CaMIS9bY.js → freemarker2-cQSgojlC.js} +1 -1
  43. package/dist/_frontend/assets/freemarker2-cQSgojlC.js.br +0 -0
  44. package/dist/_frontend/assets/freemarker2-cQSgojlC.js.gz +0 -0
  45. package/dist/_frontend/assets/{handlebars-Donx2d9H.js → handlebars-BQ-clQ7_.js} +1 -1
  46. package/dist/_frontend/assets/handlebars-BQ-clQ7_.js.br +0 -0
  47. package/dist/_frontend/assets/handlebars-BQ-clQ7_.js.gz +0 -0
  48. package/dist/_frontend/assets/{html-CtI8kZ6e.js → html-ChfWgJt-.js} +1 -1
  49. package/dist/_frontend/assets/html-ChfWgJt-.js.br +0 -0
  50. package/dist/_frontend/assets/html-ChfWgJt-.js.gz +0 -0
  51. package/dist/_frontend/assets/{htmlMode-B6ky8VkF.js → htmlMode-D1PmpoAx.js} +1 -1
  52. package/dist/_frontend/assets/htmlMode-D1PmpoAx.js.br +0 -0
  53. package/dist/_frontend/assets/htmlMode-D1PmpoAx.js.gz +0 -0
  54. package/dist/_frontend/assets/{index-DWr7ad72.js → index-BRS0kvLQ.js} +22 -22
  55. package/dist/_frontend/assets/index-BRS0kvLQ.js.br +0 -0
  56. package/dist/_frontend/assets/index-BRS0kvLQ.js.gz +0 -0
  57. package/dist/_frontend/assets/{index-DFmgzNuj.js → index-aEojVaVa.js} +3 -3
  58. package/dist/_frontend/assets/index-aEojVaVa.js.br +0 -0
  59. package/dist/_frontend/assets/index-aEojVaVa.js.gz +0 -0
  60. package/dist/_frontend/assets/{javascript-BDngdIws.js → javascript-DFHGvkjD.js} +1 -1
  61. package/dist/_frontend/assets/{jsonMode-B7OogXWW.js → jsonMode-DWo0prLv.js} +1 -1
  62. package/dist/_frontend/assets/jsonMode-DWo0prLv.js.br +0 -0
  63. package/dist/_frontend/assets/jsonMode-DWo0prLv.js.gz +0 -0
  64. package/dist/_frontend/assets/{liquid-D_8RkuUW.js → liquid-Bs2__P9v.js} +1 -1
  65. package/dist/_frontend/assets/liquid-Bs2__P9v.js.br +0 -0
  66. package/dist/_frontend/assets/liquid-Bs2__P9v.js.gz +0 -0
  67. package/dist/_frontend/assets/{lspLanguageFeatures-DJf8_W2N.js → lspLanguageFeatures-zZ0stYf4.js} +1 -1
  68. package/dist/_frontend/assets/lspLanguageFeatures-zZ0stYf4.js.br +0 -0
  69. package/dist/_frontend/assets/lspLanguageFeatures-zZ0stYf4.js.gz +0 -0
  70. package/dist/_frontend/assets/{mdx-HcpZSZ2w.js → mdx-C7c8MDI_.js} +1 -1
  71. package/dist/_frontend/assets/mdx-C7c8MDI_.js.br +0 -0
  72. package/dist/_frontend/assets/mdx-C7c8MDI_.js.gz +0 -0
  73. package/dist/_frontend/assets/{python-CPiT1vB4.js → python-CLO39XAV.js} +1 -1
  74. package/dist/_frontend/assets/python-CLO39XAV.js.br +0 -0
  75. package/dist/_frontend/assets/python-CLO39XAV.js.gz +0 -0
  76. package/dist/_frontend/assets/{razor-oizHS-vq.js → razor-efddsYhk.js} +1 -1
  77. package/dist/_frontend/assets/razor-efddsYhk.js.br +0 -0
  78. package/dist/_frontend/assets/razor-efddsYhk.js.gz +0 -0
  79. package/dist/_frontend/assets/{tsMode-n5kkpKJX.js → tsMode-xfchPgTX.js} +1 -1
  80. package/dist/_frontend/assets/tsMode-xfchPgTX.js.br +0 -0
  81. package/dist/_frontend/assets/tsMode-xfchPgTX.js.gz +0 -0
  82. package/dist/_frontend/assets/{typescript-BfXupYGq.js → typescript-BFzaCQP8.js} +1 -1
  83. package/dist/_frontend/assets/typescript-BFzaCQP8.js.br +0 -0
  84. package/dist/_frontend/assets/typescript-BFzaCQP8.js.gz +0 -0
  85. package/dist/_frontend/assets/{workers-DCX6qMOc.js → workers-DKwMBzKS.js} +1 -1
  86. package/dist/_frontend/assets/workers-DKwMBzKS.js.br +0 -0
  87. package/dist/_frontend/assets/workers-DKwMBzKS.js.gz +0 -0
  88. package/dist/_frontend/assets/{xml-MX-qfsGl.js → xml-Cx6gHwq3.js} +1 -1
  89. package/dist/_frontend/assets/xml-Cx6gHwq3.js.br +0 -0
  90. package/dist/_frontend/assets/xml-Cx6gHwq3.js.gz +0 -0
  91. package/dist/_frontend/assets/{yaml-DnKyyO9e.js → yaml-DyrfMWlf.js} +1 -1
  92. package/dist/_frontend/assets/yaml-DyrfMWlf.js.br +0 -0
  93. package/dist/_frontend/assets/yaml-DyrfMWlf.js.gz +0 -0
  94. package/dist/_frontend/index.html +1 -1
  95. package/dist/_frontend/index.html.br +0 -0
  96. package/dist/_frontend/index.html.gz +0 -0
  97. package/dist/main.js +49 -54
  98. package/dist/main.js.map +1 -1
  99. package/dist/postgres/migrations/20260818_000001_mcp_pending_auth_return_to.js +17 -0
  100. package/dist/postgres/migrations/20260818_000001_mcp_pending_auth_return_to.js.map +1 -0
  101. package/dist/sqlite/migrations/20260818_000001_mcp_pending_auth_return_to.js +19 -0
  102. package/dist/sqlite/migrations/20260818_000001_mcp_pending_auth_return_to.js.map +1 -0
  103. package/package.json +2 -2
  104. package/dist/_frontend/assets/ConnectorSettings-XEO5ZQO5-BXis0tQK.js.br +0 -0
  105. package/dist/_frontend/assets/ConnectorSettings-XEO5ZQO5-BXis0tQK.js.gz +0 -0
  106. package/dist/_frontend/assets/DrawerLayout-FJ7XC2FU-ChH-Qykr.js.br +0 -0
  107. package/dist/_frontend/assets/DrawerLayout-FJ7XC2FU-ChH-Qykr.js.gz +0 -0
  108. package/dist/_frontend/assets/ModelSettings-2QB7LE22-CDZku4g3.js.br +0 -0
  109. package/dist/_frontend/assets/ModelSettings-2QB7LE22-CDZku4g3.js.gz +0 -0
  110. package/dist/_frontend/assets/SandboxSettings-QDDIPRBP-CImJLa0r.js.br +0 -0
  111. package/dist/_frontend/assets/SandboxSettings-QDDIPRBP-CImJLa0r.js.gz +0 -0
  112. package/dist/_frontend/assets/SettingsBuilder-4NF3Y7UZ-eXXDLQ6k.js.br +0 -0
  113. package/dist/_frontend/assets/SettingsBuilder-4NF3Y7UZ-eXXDLQ6k.js.gz +0 -0
  114. package/dist/_frontend/assets/ShellRouteSync-T4WLY57Q-CetHx5EA.js.br +0 -0
  115. package/dist/_frontend/assets/ShellRouteSync-T4WLY57Q-CetHx5EA.js.gz +0 -0
  116. package/dist/_frontend/assets/SidebarLayout-KX6RSJTP-B8G4CTTb.js.br +0 -0
  117. package/dist/_frontend/assets/SidebarLayout-KX6RSJTP-B8G4CTTb.js.gz +0 -0
  118. package/dist/_frontend/assets/SkillSettings-5EETEEDI-DbJE0Ms2.js.br +0 -0
  119. package/dist/_frontend/assets/SkillSettings-5EETEEDI-DbJE0Ms2.js.gz +0 -0
  120. package/dist/_frontend/assets/WidgetLayout-S6EK62TZ-BPf7T3wa.js.br +0 -0
  121. package/dist/_frontend/assets/WidgetLayout-S6EK62TZ-BPf7T3wa.js.gz +0 -0
  122. package/dist/_frontend/assets/chunk-62JRHF6Z-BUuLA42_.js.br +0 -0
  123. package/dist/_frontend/assets/chunk-62JRHF6Z-BUuLA42_.js.gz +0 -0
  124. package/dist/_frontend/assets/chunk-PTYEOSHT-C4gdhLwo.js.br +0 -0
  125. package/dist/_frontend/assets/chunk-PTYEOSHT-C4gdhLwo.js.gz +0 -0
  126. package/dist/_frontend/assets/chunk-X6U2Q7X5-DDlfUle1.js.br +0 -0
  127. package/dist/_frontend/assets/chunk-X6U2Q7X5-DDlfUle1.js.gz +0 -0
  128. package/dist/_frontend/assets/cssMode-C1whwlDW.js.br +0 -0
  129. package/dist/_frontend/assets/cssMode-C1whwlDW.js.gz +0 -0
  130. package/dist/_frontend/assets/freemarker2-CaMIS9bY.js.br +0 -0
  131. package/dist/_frontend/assets/freemarker2-CaMIS9bY.js.gz +0 -0
  132. package/dist/_frontend/assets/handlebars-Donx2d9H.js.br +0 -0
  133. package/dist/_frontend/assets/handlebars-Donx2d9H.js.gz +0 -0
  134. package/dist/_frontend/assets/html-CtI8kZ6e.js.br +0 -0
  135. package/dist/_frontend/assets/html-CtI8kZ6e.js.gz +0 -0
  136. package/dist/_frontend/assets/htmlMode-B6ky8VkF.js.br +0 -0
  137. package/dist/_frontend/assets/htmlMode-B6ky8VkF.js.gz +0 -0
  138. package/dist/_frontend/assets/index-DFmgzNuj.js.br +0 -0
  139. package/dist/_frontend/assets/index-DFmgzNuj.js.gz +0 -0
  140. package/dist/_frontend/assets/index-DWr7ad72.js.br +0 -0
  141. package/dist/_frontend/assets/index-DWr7ad72.js.gz +0 -0
  142. package/dist/_frontend/assets/jsonMode-B7OogXWW.js.br +0 -0
  143. package/dist/_frontend/assets/jsonMode-B7OogXWW.js.gz +0 -0
  144. package/dist/_frontend/assets/liquid-D_8RkuUW.js.br +0 -0
  145. package/dist/_frontend/assets/liquid-D_8RkuUW.js.gz +0 -0
  146. package/dist/_frontend/assets/lspLanguageFeatures-DJf8_W2N.js.br +0 -0
  147. package/dist/_frontend/assets/lspLanguageFeatures-DJf8_W2N.js.gz +0 -0
  148. package/dist/_frontend/assets/mdx-HcpZSZ2w.js.br +0 -0
  149. package/dist/_frontend/assets/mdx-HcpZSZ2w.js.gz +0 -0
  150. package/dist/_frontend/assets/python-CPiT1vB4.js.br +0 -0
  151. package/dist/_frontend/assets/python-CPiT1vB4.js.gz +0 -0
  152. package/dist/_frontend/assets/razor-oizHS-vq.js.br +0 -0
  153. package/dist/_frontend/assets/razor-oizHS-vq.js.gz +0 -0
  154. package/dist/_frontend/assets/tsMode-n5kkpKJX.js.br +0 -0
  155. package/dist/_frontend/assets/tsMode-n5kkpKJX.js.gz +0 -0
  156. package/dist/_frontend/assets/typescript-BfXupYGq.js.br +0 -0
  157. package/dist/_frontend/assets/typescript-BfXupYGq.js.gz +0 -0
  158. package/dist/_frontend/assets/workers-DCX6qMOc.js.br +0 -0
  159. package/dist/_frontend/assets/workers-DCX6qMOc.js.gz +0 -0
  160. package/dist/_frontend/assets/xml-MX-qfsGl.js.br +0 -0
  161. package/dist/_frontend/assets/xml-MX-qfsGl.js.gz +0 -0
  162. package/dist/_frontend/assets/yaml-DnKyyO9e.js.br +0 -0
  163. package/dist/_frontend/assets/yaml-DnKyyO9e.js.gz +0 -0
package/dist/main.js CHANGED
@@ -380,14 +380,14 @@ function toStoredOAuthPendingAuthorizationData(pending) {
380
380
  return {
381
381
  mcp_server_url: pending.mcpServerUrl,
382
382
  code_verifier: pending.codeVerifier,
383
- redirect_url: pending.redirectUrl
383
+ return_to: pending.returnTo
384
384
  };
385
385
  }
386
386
  function fromStoredOAuthPendingAuthorizationData(stored) {
387
387
  return {
388
388
  mcpServerUrl: stored.mcp_server_url,
389
389
  codeVerifier: stored.code_verifier,
390
- redirectUrl: stored.redirect_url
390
+ returnTo: stored.return_to
391
391
  };
392
392
  }
393
393
  var McpServerNameConflictError, PENDING_AUTHORIZATION_TTL_MS;
@@ -4511,19 +4511,6 @@ function isOAuthAccessTokenUsable(expiresAtIso, nowMs) {
4511
4511
  const expiresAtMs = Date.parse(expiresAtIso);
4512
4512
  return !Number.isNaN(expiresAtMs) && expiresAtMs > nowMs;
4513
4513
  }
4514
- function validateRedirectUris({ redirectUris }) {
4515
- for (const redirectUri of redirectUris) {
4516
- let parsed;
4517
- try {
4518
- parsed = new URL(redirectUri);
4519
- } catch (error) {
4520
- throw new McpConnectionError(`Invalid redirect URI: ${redirectUri}. Must be a valid URL.`, 400, { cause: error });
4521
- }
4522
- if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
4523
- throw new McpConnectionError(`Invalid redirect URI: ${redirectUri}. Must be a valid URL.`, 400);
4524
- }
4525
- }
4526
- }
4527
4514
 
4528
4515
  // src/mcp/auth/mcpDcr.ts
4529
4516
  var MCP_OAUTH_HTTP_TIMEOUT_MS = 15e3;
@@ -4674,7 +4661,7 @@ async function buildMcpAuthorizationUrl(params) {
4674
4661
  userRef: params.userRef,
4675
4662
  mcpServerUrl: params.mcpServerUrl,
4676
4663
  codeVerifier: started.codeVerifier,
4677
- redirectUrl: params.redirectUrl ?? null
4664
+ returnTo: params.returnTo ?? null
4678
4665
  });
4679
4666
  return started.authorizationUrl;
4680
4667
  }
@@ -4717,7 +4704,7 @@ async function resolveMcpAuth(params) {
4717
4704
  userRef: params.userRef,
4718
4705
  mcpServerUrl: params.mcpServerUrl,
4719
4706
  mcpServerName: params.mcpServerName,
4720
- ...params.redirectUrl !== void 0 ? { redirectUrl: params.redirectUrl } : {}
4707
+ ...params.returnTo !== void 0 ? { returnTo: params.returnTo } : {}
4721
4708
  });
4722
4709
  return { authUrl };
4723
4710
  }
@@ -5104,9 +5091,7 @@ function buildTurnSandbox(input) {
5104
5091
  blockDestructiveToolsInCodeMode: true,
5105
5092
  mcpRequestTimeoutMs: config_default.MCP_REQUEST_TIMEOUT_MS,
5106
5093
  mcpConnectTimeoutMs: config_default.MCP_CONNECT_TIMEOUT_MS,
5107
- // Sandbox reads its tenant from TFY_TENANT_NAME for the ownership check
5108
- // against provider-created sandbox ids (`<tenant>.<uuid>`).
5109
- execExtraEnv: { TFY_TENANT_NAME: input.tenantName },
5094
+ tenantName: input.tenantName,
5110
5095
  ...skillMounter ? { skillMounter } : {},
5111
5096
  tracing: input.tracing,
5112
5097
  logger: input.logger
@@ -6044,6 +6029,18 @@ function buildAuthorizationRequestParams(config) {
6044
6029
  };
6045
6030
  }
6046
6031
 
6032
+ // src/auth/safeReturnTo.ts
6033
+ var SAFE_RETURN_TO = /^\/(?!\/|api(?:\/|$)).*/;
6034
+ function isSafeReturnTo(value) {
6035
+ return SAFE_RETURN_TO.test(value);
6036
+ }
6037
+ function safeReturnTo(value) {
6038
+ if (value && isSafeReturnTo(value)) {
6039
+ return value;
6040
+ }
6041
+ return "/";
6042
+ }
6043
+
6047
6044
  // src/auth/oidc.ts
6048
6045
  var CALLBACK_PATH = "/api/v1/auth/callback";
6049
6046
  var OAUTH_STATE_MAX_AGE_SECONDS = 10 * 60;
@@ -6080,13 +6077,6 @@ function authCallbackUrl() {
6080
6077
  const publicBaseUrl = getPublicBaseUrl();
6081
6078
  return `${publicBaseUrl}${CALLBACK_PATH}`;
6082
6079
  }
6083
- var SAFE_RETURN_TO = /^\/(?!\/|api(?:\/|$)).*/;
6084
- function safeReturnTo(value) {
6085
- if (value && SAFE_RETURN_TO.test(value)) {
6086
- return value;
6087
- }
6088
- return "/";
6089
- }
6090
6080
  async function buildLoginAuthorization(params) {
6091
6081
  const oidcConfig = getOidcVerify()?.oidcConfig;
6092
6082
  if (!oidcConfig) {
@@ -6253,7 +6243,7 @@ var OAuthCallbackQuerySchema = z13.object({
6253
6243
  error_description: z13.string().optional().describe("Human-readable error detail from the identity provider when `error` is set.")
6254
6244
  });
6255
6245
  var OAuthCallbackSuccessSchema = z13.object({
6256
- success: z13.literal(true).describe("Present when the OAuth callback completed without a redirect_url.")
6246
+ success: z13.literal(true).describe("Present when the OAuth callback completed without a return_to.")
6257
6247
  });
6258
6248
  var MeResponseSchema = z13.object({
6259
6249
  type: z13.enum(["default", "oidc-connected"]).describe(
@@ -6838,7 +6828,7 @@ var mcpOAuthCallbackRoute = createRoute6({
6838
6828
  path: "/callback",
6839
6829
  tags: [MCP_OAUTH_TAG],
6840
6830
  summary: "OAuth callback for MCP authorization",
6841
- description: "Browser redirect target for MCP server OAuth. The authorization server redirects here with `code`/`state` (or `error`). Exchanges the code for tokens, then either returns JSON or redirects to the `redirect_url` supplied at authorize time. Not called by the SDK \u2014 browsers hit this URL directly.",
6831
+ description: "Browser redirect target for MCP server OAuth. The authorization server redirects here with `code`/`state` (or `error`). Exchanges the code for tokens, then either returns JSON or redirects to the `return_to` path supplied at authorize time. Not called by the SDK \u2014 browsers hit this URL directly.",
6842
6832
  // Browser-redirect target hit directly by the authorization server, never called by SDK.
6843
6833
  "x-fern-ignore": true,
6844
6834
  request: {
@@ -6847,10 +6837,10 @@ var mcpOAuthCallbackRoute = createRoute6({
6847
6837
  responses: {
6848
6838
  200: {
6849
6839
  content: { "application/json": { schema: OAuthCallbackSuccessSchema } },
6850
- description: "Token exchanged successfully and no `redirect_url` was given at authorize time."
6840
+ description: "Token exchanged successfully and no `return_to` was given at authorize time."
6851
6841
  },
6852
6842
  302: {
6853
- description: "Redirect to the `redirect_url` given at authorize time, with `isSuccess` (and `reason` when it failed) appended to its existing query params."
6843
+ description: "Redirect to the `return_to` path given at authorize time, with `isSuccess` (and `reason` when it failed) appended to its existing query params."
6854
6844
  },
6855
6845
  400: {
6856
6846
  content: { "application/json": { schema: RequestErrorResponseSchema } },
@@ -6864,25 +6854,28 @@ var mcpOAuthCallbackRoute = createRoute6({
6864
6854
  });
6865
6855
 
6866
6856
  // src/apis/mcpOAuth.ts
6867
- function callbackLandingUrl(params) {
6868
- const url = new URL(params.redirectUrl);
6857
+ function callbackLandingPath(params) {
6858
+ const url = new URL(params.returnTo, params.c.req.url);
6869
6859
  url.searchParams.set("isSuccess", String(params.isSuccess));
6870
6860
  if (params.reason) {
6871
6861
  url.searchParams.set("reason", params.reason);
6872
6862
  }
6873
- return url.href;
6863
+ return `${url.pathname}${url.search}`;
6874
6864
  }
6875
6865
  function callbackSuccess(params) {
6876
- const redirectUrl = params.pending.redirectUrl;
6877
- if (redirectUrl) {
6878
- return params.c.redirect(callbackLandingUrl({ redirectUrl, isSuccess: true }), 302);
6866
+ const returnTo = params.pending.returnTo;
6867
+ if (returnTo) {
6868
+ return params.c.redirect(callbackLandingPath({ c: params.c, returnTo, isSuccess: true }), 302);
6879
6869
  }
6880
6870
  return params.c.json({ success: true }, 200);
6881
6871
  }
6882
6872
  function callbackFailure(params) {
6883
- const redirectUrl = params.pending?.redirectUrl;
6884
- if (redirectUrl) {
6885
- return params.c.redirect(callbackLandingUrl({ redirectUrl, isSuccess: false, reason: params.message }), 302);
6873
+ const returnTo = params.pending?.returnTo;
6874
+ if (returnTo) {
6875
+ return params.c.redirect(
6876
+ callbackLandingPath({ c: params.c, returnTo, isSuccess: false, reason: params.message }),
6877
+ 302
6878
+ );
6886
6879
  }
6887
6880
  return params.c.json({ error: { message: params.message } }, params.jsonStatus ?? 400);
6888
6881
  }
@@ -6924,10 +6917,10 @@ function createMcpOAuthRouter(deps) {
6924
6917
  }
6925
6918
 
6926
6919
  // src/apis/mcpServers.ts
6927
- init_config();
6928
- init_mcpServerStore();
6929
6920
  import { OpenAPIHono as OpenAPIHono7 } from "@hono/zod-openapi";
6930
6921
  import { extractErrorLogFields as extractErrorLogFields5, isAuthRequired, McpConnectionError as McpConnectionError4, RemoteMCP } from "@truefoundry/trueforge-core/core";
6922
+ init_config();
6923
+ init_mcpServerStore();
6931
6924
 
6932
6925
  // src/routes/mcpServerRoutes.ts
6933
6926
  import { createRoute as createRoute7, z as z21 } from "@hono/zod-openapi";
@@ -7100,7 +7093,9 @@ var listMcpServerToolsRoute = createRoute7({
7100
7093
  }
7101
7094
  });
7102
7095
  var McpAuthorizeQuerySchema = z21.object({
7103
- redirect_url: z21.url().optional().describe("Optional FE landing URL the OAuth callback redirects to, with `isSuccess`/`reason` appended.")
7096
+ return_to: z21.string().optional().describe(
7097
+ "Optional path to return to after OAuth. Must be a same-origin relative path; the OAuth callback redirects here with `isSuccess`/`reason` appended."
7098
+ )
7104
7099
  });
7105
7100
  var authorizeMcpServerRoute = createRoute7({
7106
7101
  method: "get",
@@ -7109,7 +7104,7 @@ var authorizeMcpServerRoute = createRoute7({
7109
7104
  summary: "Start (or short-circuit) the auth flow for an MCP server",
7110
7105
  "x-fern-sdk-group-name": ["mcpServers"],
7111
7106
  "x-fern-sdk-method-name": "authorize",
7112
- description: "For servers without auth returns not_required, and for header credentials returns authenticated (no browser flow). For auth.type dcr, returns authenticated when a usable (or refreshable) token exists; otherwise runs DCR if needed and returns auth_required with an authorization URL. Optional redirect_url is where the OAuth callback then redirects the browser; without it the callback returns JSON.",
7107
+ description: "For servers without auth returns not_required, and for header credentials returns authenticated (no browser flow). For auth.type dcr, returns authenticated when a usable (or refreshable) token exists; otherwise runs DCR if needed and returns auth_required with an authorization URL. Optional return_to is where the OAuth callback then redirects the browser; without it the callback returns JSON.",
7113
7108
  request: {
7114
7109
  params: McpServerNameParamsSchema,
7115
7110
  query: McpAuthorizeQuerySchema
@@ -7121,7 +7116,7 @@ var authorizeMcpServerRoute = createRoute7({
7121
7116
  },
7122
7117
  400: {
7123
7118
  content: { "application/json": { schema: RequestErrorResponseSchema } },
7124
- description: "Invalid redirect_url."
7119
+ description: "Invalid return_to."
7125
7120
  },
7126
7121
  404: {
7127
7122
  content: { "application/json": { schema: RequestErrorResponseSchema } },
@@ -7141,13 +7136,13 @@ var authorizeMcpServerRoute = createRoute7({
7141
7136
  }
7142
7137
  }
7143
7138
  });
7144
- var deleteAuthorizeMcpServerRoute = createRoute7({
7139
+ var deleteAuthorizationMcpServerRoute = createRoute7({
7145
7140
  method: "delete",
7146
7141
  path: "/{name}/authorize",
7147
7142
  tags: [MCP_SERVERS_TAG],
7148
7143
  summary: "Disconnect OAuth for an MCP server",
7149
7144
  "x-fern-sdk-group-name": ["mcpServers"],
7150
- "x-fern-sdk-method-name": "delete_authorize",
7145
+ "x-fern-sdk-method-name": "delete_authorization",
7151
7146
  description: "For auth.type dcr, deletes the stored OAuth token and returns the server with auth_status auth_required, keeping the dynamically registered OAuth client so the next authorize can reuse it. No-op for header or no-auth servers (returns the server unchanged).",
7152
7147
  request: {
7153
7148
  params: McpServerNameParamsSchema
@@ -7460,7 +7455,7 @@ function createSettingsMcpServersRouter(deps) {
7460
7455
  function createMcpServersRouter(deps) {
7461
7456
  const authorizeHandler = async (c) => {
7462
7457
  const { name } = c.req.valid("param");
7463
- const { redirect_url: redirectUrl } = c.req.valid("query");
7458
+ const { return_to: returnTo } = c.req.valid("query");
7464
7459
  const userRef = deps.resolveUserContext(c).userRef;
7465
7460
  const record = await deps.mcpServerStore.getServer({ tenant_id: TENANT_ID, name });
7466
7461
  if (!record) {
@@ -7469,10 +7464,10 @@ function createMcpServersRouter(deps) {
7469
7464
  if (record.manifest.auth?.type !== "dcr") {
7470
7465
  return c.json(resolveMcpAuthStatus({ manifest: record.manifest }), 200);
7471
7466
  }
7467
+ if (returnTo && safeReturnTo(returnTo) !== returnTo) {
7468
+ return c.json({ error: { message: "Invalid return_to: must be a same-origin relative path" } }, 400);
7469
+ }
7472
7470
  try {
7473
- if (redirectUrl) {
7474
- validateRedirectUris({ redirectUris: [redirectUrl] });
7475
- }
7476
7471
  const result = await resolveMcpAuth({
7477
7472
  tokenStore: deps.tokenStore,
7478
7473
  mcpServerStore: deps.mcpServerStore,
@@ -7481,7 +7476,7 @@ function createMcpServersRouter(deps) {
7481
7476
  mcpServerUrl: record.manifest.url,
7482
7477
  mcpServerName: record.name,
7483
7478
  clientName: config_default.MCP_DCR_OAUTH_CLIENT_NAME,
7484
- ...redirectUrl !== void 0 ? { redirectUrl } : {}
7479
+ ...returnTo !== void 0 ? { returnTo } : {}
7485
7480
  });
7486
7481
  const authStatus = isMcpAuthRequired(result) ? { status: "auth_required", authorization_url: result.authUrl.href } : { status: "authenticated" };
7487
7482
  return c.json(authStatus, 200);
@@ -7503,7 +7498,7 @@ function createMcpServersRouter(deps) {
7503
7498
  return c.json({ error: { message: "Internal server error" } }, 500);
7504
7499
  }
7505
7500
  };
7506
- const deleteAuthorizeHandler = async (c) => {
7501
+ const deleteAuthorizationHandler = async (c) => {
7507
7502
  const { name } = c.req.valid("param");
7508
7503
  const userRef = deps.resolveUserContext(c).userRef;
7509
7504
  const record = await deps.mcpServerStore.getServer({ tenant_id: TENANT_ID, name });
@@ -7529,7 +7524,7 @@ function createMcpServersRouter(deps) {
7529
7524
  );
7530
7525
  });
7531
7526
  router.openapi(authorizeMcpServerRoute, authorizeHandler);
7532
- router.openapi(deleteAuthorizeMcpServerRoute, deleteAuthorizeHandler);
7527
+ router.openapi(deleteAuthorizationMcpServerRoute, deleteAuthorizationHandler);
7533
7528
  return router;
7534
7529
  }
7535
7530