@agent-native/core 0.198.3 → 0.198.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.
Files changed (94) hide show
  1. package/dist/a2a/types.d.ts +5 -0
  2. package/dist/agent/production-agent.js +26 -1
  3. package/dist/catalog.json +1 -0
  4. package/dist/client/chat/agentkit-agent-native.js +15 -15
  5. package/dist/client/chat/runtime.js +5 -3
  6. package/dist/client/feature-flags/types.d.ts +2 -0
  7. package/dist/client/i18n.d.ts +2 -0
  8. package/dist/client/i18n.js +2 -0
  9. package/dist/client/integrations/index.d.ts +1 -0
  10. package/dist/client/integrations/index.js +1 -0
  11. package/dist/client/labs/index.d.ts +1 -1
  12. package/dist/client/labs/use-lab.d.ts +5 -0
  13. package/dist/client/labs/use-lab.js +7 -3
  14. package/dist/client/resources/mcp-connection-resume.d.ts +5 -3
  15. package/dist/client/resources/mcp-connection-resume.js +150 -13
  16. package/dist/client/sse-event-processor.d.ts +6 -0
  17. package/dist/client/uploads/index.d.ts +1 -0
  18. package/dist/client/uploads/index.js +1 -0
  19. package/dist/client/uploads/private-icon.d.ts +10 -0
  20. package/dist/client/uploads/private-icon.js +52 -0
  21. package/dist/collab/routes.d.ts +2 -2
  22. package/dist/feature-flags/actions/get-feature-flags.js +20 -0
  23. package/dist/feature-flags/actions/list-feature-flags.d.ts +2 -0
  24. package/dist/feature-flags/actions/list-feature-flags.js +5 -0
  25. package/dist/feature-flags/actions/set-feature-flag.js +5 -0
  26. package/dist/file-upload/actions/upload-image.d.ts +3 -3
  27. package/dist/framework-tools.js +2 -0
  28. package/dist/icon-assets/index.d.ts +3 -0
  29. package/dist/icon-assets/index.js +3 -0
  30. package/dist/icon-assets/multipart.d.ts +9 -0
  31. package/dist/icon-assets/multipart.js +60 -0
  32. package/dist/icon-assets/schema.d.ts +194 -0
  33. package/dist/icon-assets/schema.js +16 -0
  34. package/dist/icon-assets/store.d.ts +38 -0
  35. package/dist/icon-assets/store.js +187 -0
  36. package/dist/icon-assets/svg.d.ts +2 -0
  37. package/dist/icon-assets/svg.js +146 -0
  38. package/dist/icon-assets/workspace-transport.d.ts +20 -0
  39. package/dist/icon-assets/workspace-transport.js +122 -0
  40. package/dist/identity/rekey.js +1 -0
  41. package/dist/jobs/actions/manage-recurring-job.d.ts +1 -1
  42. package/dist/labs/actions/get-lab-states.d.ts +2 -0
  43. package/dist/labs/actions/get-lab-states.js +14 -0
  44. package/dist/labs/actions/get-labs.js +2 -2
  45. package/dist/labs/actions/set-lab.js +4 -2
  46. package/dist/labs/index.d.ts +1 -1
  47. package/dist/labs/index.js +1 -1
  48. package/dist/labs/registry.d.ts +3 -0
  49. package/dist/labs/registry.js +14 -0
  50. package/dist/labs/server.d.ts +1 -1
  51. package/dist/labs/server.js +1 -1
  52. package/dist/labs/store.d.ts +13 -2
  53. package/dist/labs/store.js +124 -7
  54. package/dist/localization/default-messages.d.ts +2 -0
  55. package/dist/localization/default-messages.js +1 -1
  56. package/dist/localization/icon-picker-messages.d.ts +44 -0
  57. package/dist/localization/icon-picker-messages.js +22 -0
  58. package/dist/mcp-client/oauth-client.d.ts +1 -0
  59. package/dist/mcp-client/oauth-client.js +42 -4
  60. package/dist/mcp-client/oauth-routes.js +15 -2
  61. package/dist/notifications/routes.d.ts +1 -1
  62. package/dist/observability/routes.d.ts +9 -9
  63. package/dist/org/actions/list-workspace-icons.d.ts +7 -0
  64. package/dist/org/actions/list-workspace-icons.js +41 -0
  65. package/dist/org/handlers.d.ts +1 -1
  66. package/dist/org/handlers.js +28 -1
  67. package/dist/org/index.d.ts +1 -1
  68. package/dist/org/migrations.js +21 -0
  69. package/dist/org/plugin.js +42 -0
  70. package/dist/org/private-icon-handlers.d.ts +6 -0
  71. package/dist/org/private-icon-handlers.js +212 -0
  72. package/dist/progress/routes.d.ts +1 -1
  73. package/dist/provider-api/actions/custom-provider-registration.d.ts +8 -8
  74. package/dist/provider-api/actions/provider-api.d.ts +5 -5
  75. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  76. package/dist/provider-api/index.d.ts +1 -1
  77. package/dist/provider-api/index.js +26 -6
  78. package/dist/secrets/routes.d.ts +4 -4
  79. package/dist/server/action-discovery.js +5 -0
  80. package/dist/server/agent-chat-plugin.js +14 -0
  81. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  82. package/dist/server/agent-engine-default-model-route.d.ts +1 -1
  83. package/dist/server/agent-engine-ollama-models-route.d.ts +1 -1
  84. package/dist/server/core-routes-plugin.d.ts +1 -1
  85. package/dist/server/core-routes-plugin.js +18 -3
  86. package/dist/server/index.d.ts +1 -1
  87. package/dist/server/index.js +1 -1
  88. package/dist/server/workspace-provider-oauth.d.ts +1 -0
  89. package/dist/server/workspace-provider-oauth.js +4 -2
  90. package/dist/templates/chat/app/components/chat/ChatRouteContent.tsx +9 -16
  91. package/dist/triggers/actions/manage-automation.d.ts +5 -5
  92. package/dist/vite/action-types-plugin.js +4 -0
  93. package/package.json +7 -9
  94. package/src/templates/chat/app/components/chat/ChatRouteContent.tsx +9 -16
@@ -4,7 +4,9 @@ export declare const ICON_PICKER_MESSAGES: {
4
4
  allCategories: string;
5
5
  loadError: string;
6
6
  saveError: string;
7
+ uploadFailed: string;
7
8
  uploadTooLarge: string;
9
+ uploadUnsupportedType: string;
8
10
  retry: string;
9
11
  uploadHint: string;
10
12
  colorNames: {
@@ -83,7 +85,9 @@ export declare const ICON_PICKER_MESSAGES: {
83
85
  allCategories: string;
84
86
  loadError: string;
85
87
  saveError: string;
88
+ uploadFailed: string;
86
89
  uploadTooLarge: string;
90
+ uploadUnsupportedType: string;
87
91
  retry: string;
88
92
  uploadHint: string;
89
93
  colorNames: {
@@ -162,7 +166,9 @@ export declare const ICON_PICKER_MESSAGES: {
162
166
  allCategories: string;
163
167
  loadError: string;
164
168
  saveError: string;
169
+ uploadFailed: string;
165
170
  uploadTooLarge: string;
171
+ uploadUnsupportedType: string;
166
172
  retry: string;
167
173
  uploadHint: string;
168
174
  colorNames: {
@@ -241,7 +247,9 @@ export declare const ICON_PICKER_MESSAGES: {
241
247
  allCategories: string;
242
248
  loadError: string;
243
249
  saveError: string;
250
+ uploadFailed: string;
244
251
  uploadTooLarge: string;
252
+ uploadUnsupportedType: string;
245
253
  retry: string;
246
254
  uploadHint: string;
247
255
  colorNames: {
@@ -320,7 +328,9 @@ export declare const ICON_PICKER_MESSAGES: {
320
328
  allCategories: string;
321
329
  loadError: string;
322
330
  saveError: string;
331
+ uploadFailed: string;
323
332
  uploadTooLarge: string;
333
+ uploadUnsupportedType: string;
324
334
  retry: string;
325
335
  uploadHint: string;
326
336
  colorNames: {
@@ -399,7 +409,9 @@ export declare const ICON_PICKER_MESSAGES: {
399
409
  allCategories: string;
400
410
  loadError: string;
401
411
  saveError: string;
412
+ uploadFailed: string;
402
413
  uploadTooLarge: string;
414
+ uploadUnsupportedType: string;
403
415
  retry: string;
404
416
  uploadHint: string;
405
417
  colorNames: {
@@ -478,7 +490,9 @@ export declare const ICON_PICKER_MESSAGES: {
478
490
  allCategories: string;
479
491
  loadError: string;
480
492
  saveError: string;
493
+ uploadFailed: string;
481
494
  uploadTooLarge: string;
495
+ uploadUnsupportedType: string;
482
496
  retry: string;
483
497
  uploadHint: string;
484
498
  colorNames: {
@@ -557,7 +571,9 @@ export declare const ICON_PICKER_MESSAGES: {
557
571
  allCategories: string;
558
572
  loadError: string;
559
573
  saveError: string;
574
+ uploadFailed: string;
560
575
  uploadTooLarge: string;
576
+ uploadUnsupportedType: string;
561
577
  retry: string;
562
578
  uploadHint: string;
563
579
  colorNames: {
@@ -636,7 +652,9 @@ export declare const ICON_PICKER_MESSAGES: {
636
652
  allCategories: string;
637
653
  loadError: string;
638
654
  saveError: string;
655
+ uploadFailed: string;
639
656
  uploadTooLarge: string;
657
+ uploadUnsupportedType: string;
640
658
  retry: string;
641
659
  uploadHint: string;
642
660
  colorNames: {
@@ -715,7 +733,9 @@ export declare const ICON_PICKER_MESSAGES: {
715
733
  allCategories: string;
716
734
  loadError: string;
717
735
  saveError: string;
736
+ uploadFailed: string;
718
737
  uploadTooLarge: string;
738
+ uploadUnsupportedType: string;
719
739
  retry: string;
720
740
  uploadHint: string;
721
741
  colorNames: {
@@ -794,7 +814,9 @@ export declare const ICON_PICKER_MESSAGES: {
794
814
  allCategories: string;
795
815
  loadError: string;
796
816
  saveError: string;
817
+ uploadFailed: string;
797
818
  uploadTooLarge: string;
819
+ uploadUnsupportedType: string;
798
820
  retry: string;
799
821
  uploadHint: string;
800
822
  colorNames: {
@@ -874,7 +896,9 @@ export declare function iconPickerMessagesForLocale(locale: LocaleCode): {
874
896
  allCategories: string;
875
897
  loadError: string;
876
898
  saveError: string;
899
+ uploadFailed: string;
877
900
  uploadTooLarge: string;
901
+ uploadUnsupportedType: string;
878
902
  retry: string;
879
903
  uploadHint: string;
880
904
  colorNames: {
@@ -952,7 +976,9 @@ export declare function iconPickerMessagesForLocale(locale: LocaleCode): {
952
976
  allCategories: string;
953
977
  loadError: string;
954
978
  saveError: string;
979
+ uploadFailed: string;
955
980
  uploadTooLarge: string;
981
+ uploadUnsupportedType: string;
956
982
  retry: string;
957
983
  uploadHint: string;
958
984
  colorNames: {
@@ -1030,7 +1056,9 @@ export declare function iconPickerMessagesForLocale(locale: LocaleCode): {
1030
1056
  allCategories: string;
1031
1057
  loadError: string;
1032
1058
  saveError: string;
1059
+ uploadFailed: string;
1033
1060
  uploadTooLarge: string;
1061
+ uploadUnsupportedType: string;
1034
1062
  retry: string;
1035
1063
  uploadHint: string;
1036
1064
  colorNames: {
@@ -1108,7 +1136,9 @@ export declare function iconPickerMessagesForLocale(locale: LocaleCode): {
1108
1136
  allCategories: string;
1109
1137
  loadError: string;
1110
1138
  saveError: string;
1139
+ uploadFailed: string;
1111
1140
  uploadTooLarge: string;
1141
+ uploadUnsupportedType: string;
1112
1142
  retry: string;
1113
1143
  uploadHint: string;
1114
1144
  colorNames: {
@@ -1186,7 +1216,9 @@ export declare function iconPickerMessagesForLocale(locale: LocaleCode): {
1186
1216
  allCategories: string;
1187
1217
  loadError: string;
1188
1218
  saveError: string;
1219
+ uploadFailed: string;
1189
1220
  uploadTooLarge: string;
1221
+ uploadUnsupportedType: string;
1190
1222
  retry: string;
1191
1223
  uploadHint: string;
1192
1224
  colorNames: {
@@ -1264,7 +1296,9 @@ export declare function iconPickerMessagesForLocale(locale: LocaleCode): {
1264
1296
  allCategories: string;
1265
1297
  loadError: string;
1266
1298
  saveError: string;
1299
+ uploadFailed: string;
1267
1300
  uploadTooLarge: string;
1301
+ uploadUnsupportedType: string;
1268
1302
  retry: string;
1269
1303
  uploadHint: string;
1270
1304
  colorNames: {
@@ -1342,7 +1376,9 @@ export declare function iconPickerMessagesForLocale(locale: LocaleCode): {
1342
1376
  allCategories: string;
1343
1377
  loadError: string;
1344
1378
  saveError: string;
1379
+ uploadFailed: string;
1345
1380
  uploadTooLarge: string;
1381
+ uploadUnsupportedType: string;
1346
1382
  retry: string;
1347
1383
  uploadHint: string;
1348
1384
  colorNames: {
@@ -1420,7 +1456,9 @@ export declare function iconPickerMessagesForLocale(locale: LocaleCode): {
1420
1456
  allCategories: string;
1421
1457
  loadError: string;
1422
1458
  saveError: string;
1459
+ uploadFailed: string;
1423
1460
  uploadTooLarge: string;
1461
+ uploadUnsupportedType: string;
1424
1462
  retry: string;
1425
1463
  uploadHint: string;
1426
1464
  colorNames: {
@@ -1498,7 +1536,9 @@ export declare function iconPickerMessagesForLocale(locale: LocaleCode): {
1498
1536
  allCategories: string;
1499
1537
  loadError: string;
1500
1538
  saveError: string;
1539
+ uploadFailed: string;
1501
1540
  uploadTooLarge: string;
1541
+ uploadUnsupportedType: string;
1502
1542
  retry: string;
1503
1543
  uploadHint: string;
1504
1544
  colorNames: {
@@ -1576,7 +1616,9 @@ export declare function iconPickerMessagesForLocale(locale: LocaleCode): {
1576
1616
  allCategories: string;
1577
1617
  loadError: string;
1578
1618
  saveError: string;
1619
+ uploadFailed: string;
1579
1620
  uploadTooLarge: string;
1621
+ uploadUnsupportedType: string;
1580
1622
  retry: string;
1581
1623
  uploadHint: string;
1582
1624
  colorNames: {
@@ -1654,7 +1696,9 @@ export declare function iconPickerMessagesForLocale(locale: LocaleCode): {
1654
1696
  allCategories: string;
1655
1697
  loadError: string;
1656
1698
  saveError: string;
1699
+ uploadFailed: string;
1657
1700
  uploadTooLarge: string;
1701
+ uploadUnsupportedType: string;
1658
1702
  retry: string;
1659
1703
  uploadHint: string;
1660
1704
  colorNames: {
@@ -4,7 +4,9 @@ export const ICON_PICKER_MESSAGES = {
4
4
  allCategories: "All categories",
5
5
  loadError: "Could not load icons.",
6
6
  saveError: "Could not save icon.",
7
+ uploadFailed: "Could not upload icon image. Try again.",
7
8
  uploadTooLarge: "Icon image must be 5 MiB or smaller.",
9
+ uploadUnsupportedType: "Only PNG, JPEG, WebP, or SVG images can be uploaded.",
8
10
  retry: "Try again",
9
11
  uploadHint: "PNG, JPG, WebP, SVG",
10
12
  colorNames: {
@@ -83,7 +85,9 @@ export const ICON_PICKER_MESSAGES = {
83
85
  allCategories: "Todas las categorías",
84
86
  loadError: "No se pudieron cargar los iconos.",
85
87
  saveError: "No se pudo guardar el icono.",
88
+ uploadFailed: "No se pudo subir la imagen del icono. Inténtalo de nuevo.",
86
89
  uploadTooLarge: "La imagen del icono debe ser de 5 MiB o menos.",
90
+ uploadUnsupportedType: "Solo se pueden subir imágenes PNG, JPEG, WebP o SVG.",
87
91
  retry: "Reintentar",
88
92
  uploadHint: "PNG, JPG, WebP, SVG",
89
93
  colorNames: {
@@ -162,7 +166,9 @@ export const ICON_PICKER_MESSAGES = {
162
166
  allCategories: "Toutes les catégories",
163
167
  loadError: "Impossible de charger les icônes.",
164
168
  saveError: "Impossible d’enregistrer l’icône.",
169
+ uploadFailed: "Impossible d’importer l’image de l’icône. Réessayez.",
165
170
  uploadTooLarge: "L’image de l’icône ne doit pas dépasser 5 MiB.",
171
+ uploadUnsupportedType: "Seules les images PNG, JPEG, WebP ou SVG peuvent être importées.",
166
172
  retry: "Réessayer",
167
173
  uploadHint: "PNG, JPG, WebP, SVG",
168
174
  colorNames: {
@@ -241,7 +247,9 @@ export const ICON_PICKER_MESSAGES = {
241
247
  allCategories: "Alle Kategorien",
242
248
  loadError: "Symbole konnten nicht geladen werden.",
243
249
  saveError: "Symbol konnte nicht gespeichert werden.",
250
+ uploadFailed: "Das Icon-Bild konnte nicht hochgeladen werden. Versuche es erneut.",
244
251
  uploadTooLarge: "Das Icon-Bild darf höchstens 5 MiB groß sein.",
252
+ uploadUnsupportedType: "Nur PNG-, JPEG-, WebP- oder SVG-Bilder können hochgeladen werden.",
245
253
  retry: "Erneut versuchen",
246
254
  uploadHint: "PNG, JPG, WebP, SVG",
247
255
  colorNames: {
@@ -320,7 +328,9 @@ export const ICON_PICKER_MESSAGES = {
320
328
  allCategories: "Todas as categorias",
321
329
  loadError: "Não foi possível carregar os ícones.",
322
330
  saveError: "Não foi possível salvar o ícone.",
331
+ uploadFailed: "Não foi possível enviar a imagem do ícone. Tente novamente.",
323
332
  uploadTooLarge: "A imagem do ícone deve ter no máximo 5 MiB.",
333
+ uploadUnsupportedType: "Só é possível enviar imagens PNG, JPEG, WebP ou SVG.",
324
334
  retry: "Tentar novamente",
325
335
  uploadHint: "PNG, JPG, WebP, SVG",
326
336
  colorNames: {
@@ -399,7 +409,9 @@ export const ICON_PICKER_MESSAGES = {
399
409
  allCategories: "所有分类",
400
410
  loadError: "无法加载图标。",
401
411
  saveError: "无法保存图标。",
412
+ uploadFailed: "无法上传图标图片,请重试。",
402
413
  uploadTooLarge: "图标图片不能超过 5 MiB。",
414
+ uploadUnsupportedType: "只能上传 PNG、JPEG、WebP 或 SVG 图片。",
403
415
  retry: "重试",
404
416
  uploadHint: "PNG、JPG、WebP、SVG",
405
417
  colorNames: {
@@ -478,7 +490,9 @@ export const ICON_PICKER_MESSAGES = {
478
490
  allCategories: "所有分類",
479
491
  loadError: "無法載入圖示。",
480
492
  saveError: "無法儲存圖示。",
493
+ uploadFailed: "無法上傳圖示圖片,請再試一次。",
481
494
  uploadTooLarge: "圖示圖片不可超過 5 MiB。",
495
+ uploadUnsupportedType: "只能上傳 PNG、JPEG、WebP 或 SVG 圖片。",
482
496
  retry: "重試",
483
497
  uploadHint: "PNG、JPG、WebP、SVG",
484
498
  colorNames: {
@@ -557,7 +571,9 @@ export const ICON_PICKER_MESSAGES = {
557
571
  allCategories: "すべてのカテゴリー",
558
572
  loadError: "アイコンを読み込めませんでした。",
559
573
  saveError: "アイコンを保存できませんでした。",
574
+ uploadFailed: "アイコン画像をアップロードできませんでした。再試行してください。",
560
575
  uploadTooLarge: "アイコン画像は 5 MiB 以下にしてください。",
576
+ uploadUnsupportedType: "PNG、JPEG、WebP、SVG 形式の画像のみアップロードできます。",
561
577
  retry: "再試行",
562
578
  uploadHint: "PNG、JPG、WebP、SVG",
563
579
  colorNames: {
@@ -636,7 +652,9 @@ export const ICON_PICKER_MESSAGES = {
636
652
  allCategories: "모든 카테고리",
637
653
  loadError: "아이콘을 불러오지 못했습니다.",
638
654
  saveError: "아이콘을 저장하지 못했습니다.",
655
+ uploadFailed: "아이콘 이미지를 업로드하지 못했습니다. 다시 시도하세요.",
639
656
  uploadTooLarge: "아이콘 이미지는 5 MiB 이하여야 합니다.",
657
+ uploadUnsupportedType: "PNG, JPEG, WebP 또는 SVG 이미지만 업로드할 수 있습니다.",
640
658
  retry: "다시 시도",
641
659
  uploadHint: "PNG, JPG, WebP, SVG",
642
660
  colorNames: {
@@ -715,7 +733,9 @@ export const ICON_PICKER_MESSAGES = {
715
733
  allCategories: "सभी श्रेणियाँ",
716
734
  loadError: "आइकन लोड नहीं हो सके।",
717
735
  saveError: "आइकन सहेजा नहीं जा सका।",
736
+ uploadFailed: "आइकन चित्र अपलोड नहीं हो सका। फिर से प्रयास करें।",
718
737
  uploadTooLarge: "आइकन छवि 5 MiB या उससे छोटी होनी चाहिए।",
738
+ uploadUnsupportedType: "केवल PNG, JPEG, WebP या SVG चित्र अपलोड किए जा सकते हैं।",
719
739
  retry: "फिर से प्रयास करें",
720
740
  uploadHint: "PNG, JPG, WebP, SVG",
721
741
  colorNames: {
@@ -794,7 +814,9 @@ export const ICON_PICKER_MESSAGES = {
794
814
  allCategories: "جميع الفئات",
795
815
  loadError: "تعذر تحميل الأيقونات.",
796
816
  saveError: "تعذر حفظ الأيقونة.",
817
+ uploadFailed: "تعذر تحميل صورة الأيقونة. حاول مرة أخرى.",
797
818
  uploadTooLarge: "يجب ألا يتجاوز حجم صورة الأيقونة 5 MiB.",
819
+ uploadUnsupportedType: "يمكن تحميل صور PNG أو JPEG أو WebP أو SVG فقط.",
798
820
  retry: "إعادة المحاولة",
799
821
  uploadHint: "PNG, JPG, WebP, SVG",
800
822
  colorNames: {
@@ -23,6 +23,7 @@ export interface McpOAuthProviderOptions {
23
23
  serverUrl: string;
24
24
  redirectUrl: string;
25
25
  state: string;
26
+ tokenEndpointAuthMethod?: OAuthClientMetadata["token_endpoint_auth_method"];
26
27
  clientInformation?: StoredOAuthClientInformation;
27
28
  codeVerifier?: string;
28
29
  discoveryState?: McpOAuthDiscoveryState;
@@ -1,5 +1,5 @@
1
1
  import crypto from "node:crypto";
2
- import { auth, refreshAuthorization, validateAuthorizationResponseIssuer, } from "@modelcontextprotocol/client";
2
+ import { auth, discoverOAuthServerInfo, refreshAuthorization, validateAuthorizationResponseIssuer, } from "@modelcontextprotocol/client";
3
3
  import { getAppConfig } from "../app-config/index.js";
4
4
  import { ssrfSafeFetch } from "../extensions/url-safety.js";
5
5
  import { readOAuthCredentialState, resolveOAuthCredentialAccess, markOAuthReconnectRequired, revokeOAuthCredential, saveOAuthCredential, } from "../oauth-tokens/lifecycle.js";
@@ -375,6 +375,18 @@ function validateDiscoveryUrls(state) {
375
375
  }
376
376
  }
377
377
  }
378
+ function dynamicClientAuthMethod(metadata) {
379
+ const methods = metadata?.token_endpoint_auth_methods_supported;
380
+ if (!Array.isArray(methods))
381
+ return "client_secret_basic";
382
+ if (methods.includes("none"))
383
+ return "none";
384
+ for (const method of ["client_secret_basic", "client_secret_post"]) {
385
+ if (methods.includes(method))
386
+ return method;
387
+ }
388
+ throw new Error("MCP OAuth server does not support a client authentication method this connector can register with.");
389
+ }
378
390
  function issuerForDiscovery(discovery) {
379
391
  const issuer = discovery?.authorizationServerMetadata?.issuer;
380
392
  return typeof issuer === "string" && issuer ? issuer : undefined;
@@ -458,7 +470,7 @@ export class McpOAuthClientProvider {
458
470
  this.metadata = {
459
471
  ...brandedOAuthClientMetadata(),
460
472
  redirect_uris: [options.redirectUrl],
461
- token_endpoint_auth_method: "none",
473
+ token_endpoint_auth_method: options.tokenEndpointAuthMethod ?? "none",
462
474
  grant_types: ["authorization_code", "refresh_token"],
463
475
  response_types: ["code"],
464
476
  application_type: applicationTypeForRedirect(options.redirectUrl),
@@ -609,11 +621,37 @@ export async function startMcpOAuthAuthorization(options) {
609
621
  if (googleScopes) {
610
622
  return startGoogleMcpOAuthAuthorization({ ...options, serverUrl: serverUrl.toString() }, googleScopes);
611
623
  }
612
- if (!options.clientInformation && options.discoveryState) {
613
- assertRegisterableClient(options.discoveryState, undefined);
624
+ const resourceMetadataUrl = options.resourceMetadataUrl
625
+ ? checkedRemoteUrl(options.resourceMetadataUrl, "resource metadata").href
626
+ : undefined;
627
+ const discoveredState = !options.clientInformation && !options.discoveryState
628
+ ? await discoverOAuthServerInfo(serverUrl, {
629
+ fetchFn: guardedOAuthFetch(),
630
+ ...(resourceMetadataUrl
631
+ ? { resourceMetadataUrl: new URL(resourceMetadataUrl) }
632
+ : {}),
633
+ })
634
+ : undefined;
635
+ const discoveryState = options.discoveryState ??
636
+ (discoveredState
637
+ ? {
638
+ ...discoveredState,
639
+ ...(resourceMetadataUrl ? { resourceMetadataUrl } : {}),
640
+ }
641
+ : undefined);
642
+ if (discoveryState)
643
+ validateDiscoveryUrls(discoveryState);
644
+ if (!options.clientInformation && discoveryState) {
645
+ assertRegisterableClient(discoveryState, undefined);
614
646
  }
615
647
  const provider = new McpOAuthClientProvider({
616
648
  ...options,
649
+ ...(discoveryState ? { discoveryState } : {}),
650
+ ...(!options.clientInformation
651
+ ? {
652
+ tokenEndpointAuthMethod: dynamicClientAuthMethod(discoveryState?.authorizationServerMetadata),
653
+ }
654
+ : {}),
617
655
  ...(options.clientInformation
618
656
  ? {}
619
657
  : { onDiscoveryState: assertRegisterableClient }),
@@ -38,6 +38,7 @@ const MCP_WORKSPACE_STATE_PROVIDER = "mcp";
38
38
  const MANAGED_MCP_OAUTH_CLIENTS = [
39
39
  {
40
40
  serverOrigins: ["https://mcp.hubspot.com"],
41
+ requireClientCredentials: true,
41
42
  credentialPairs: [
42
43
  ["HUBSPOT_MCP_CLIENT_ID", "HUBSPOT_MCP_CLIENT_SECRET"],
43
44
  ["HUBSPOT_INTEGRATION_CLIENT_ID", "HUBSPOT_INTEGRATION_CLIENT_SECRET"],
@@ -55,12 +56,19 @@ const MANAGED_MCP_OAUTH_CLIENTS = [
55
56
  "https://chatmcp.googleapis.com",
56
57
  "https://people.googleapis.com",
57
58
  ],
59
+ requireClientCredentials: true,
58
60
  credentialPairs: [["GOOGLE_CLIENT_ID", "GOOGLE_CLIENT_SECRET"]],
59
61
  },
60
62
  {
61
63
  serverOrigins: ["https://workspacemcp.googleapis.com"],
64
+ requireClientCredentials: true,
62
65
  credentialPairs: [["GOOGLE_CLIENT_ID", "GOOGLE_CLIENT_SECRET"]],
63
66
  },
67
+ {
68
+ serverOrigins: ["https://mcp.gong.io"],
69
+ allowOrganizationScope: true,
70
+ credentialPairs: [["GONG_MCP_CLIENT_ID", "GONG_MCP_CLIENT_SECRET"]],
71
+ },
64
72
  ];
65
73
  export function resolveMcpOAuthReturnPath(connected, flow) {
66
74
  if (!connected)
@@ -216,7 +224,8 @@ async function handleMcpOAuthStart(event) {
216
224
  try {
217
225
  const started = await runWithRequestContext(requestContext, async () => {
218
226
  const clientInformation = await resolveManagedMcpOAuthClient(urlCheck.url);
219
- if (isManagedMcpOAuthServer(urlCheck.url) && !clientInformation) {
227
+ if (managedMcpOAuthClientFor(urlCheck.url)?.requireClientCredentials &&
228
+ !clientInformation) {
220
229
  return null;
221
230
  }
222
231
  const storedCredentials = reconnectServer?.oauthSecretKey && reconnectScopeId
@@ -347,7 +356,11 @@ export function wantsHtmlResponse(event) {
347
356
  return (getRequestHeader(event, "accept") ?? "").includes("text/html");
348
357
  }
349
358
  function isManagedMcpOAuthServer(serverUrl) {
350
- return MANAGED_MCP_OAUTH_CLIENTS.some((client) => client.serverOrigins.includes(serverUrl.origin));
359
+ const client = managedMcpOAuthClientFor(serverUrl);
360
+ return Boolean(client && !client.allowOrganizationScope);
361
+ }
362
+ function managedMcpOAuthClientFor(serverUrl) {
363
+ return MANAGED_MCP_OAUTH_CLIENTS.find((client) => client.serverOrigins.includes(serverUrl.origin));
351
364
  }
352
365
  export function resolveMcpOAuthScope(serverUrl, requestedScope, options) {
353
366
  if (isBuilderPublishMcpServer(serverUrl)) {
@@ -16,6 +16,6 @@ export declare function createNotificationsHandler(): import("h3").EventHandlerW
16
16
  } | {
17
17
  count?: undefined;
18
18
  updated?: undefined;
19
- ok: boolean;
20
19
  error?: undefined;
20
+ ok: boolean;
21
21
  }>>;
@@ -27,38 +27,38 @@ export declare function createObservabilityHandler(): import("h3").EventHandlerW
27
27
  thumbsUpRate: number;
28
28
  avgEvalScore: number;
29
29
  } | {
30
+ id?: undefined;
31
+ ok?: undefined;
30
32
  error: string;
31
33
  message: string;
32
34
  summary?: undefined;
33
35
  spans?: undefined;
36
+ } | {
34
37
  id?: undefined;
38
+ error?: undefined;
35
39
  ok?: undefined;
36
- } | {
37
40
  message?: undefined;
38
41
  summary: import("./types.js").TraceSummary;
39
42
  spans: import("./types.js").TraceSpan[];
40
- id?: undefined;
43
+ } | {
41
44
  error?: undefined;
42
45
  ok?: undefined;
43
- } | {
44
46
  message?: undefined;
45
47
  summary?: undefined;
46
48
  spans?: undefined;
47
49
  id: string;
48
- error?: undefined;
49
- ok?: undefined;
50
50
  } | {
51
+ id?: undefined;
52
+ ok?: undefined;
51
53
  message?: undefined;
52
54
  summary?: undefined;
53
55
  spans?: undefined;
54
- id?: undefined;
55
56
  error: any;
56
- ok?: undefined;
57
57
  } | {
58
+ id?: undefined;
59
+ error?: undefined;
58
60
  message?: undefined;
59
61
  summary?: undefined;
60
62
  spans?: undefined;
61
- id?: undefined;
62
- error?: undefined;
63
63
  ok: boolean;
64
64
  }>>;
@@ -0,0 +1,7 @@
1
+ declare const _default: import("../../action.js").ActionDefinition<Record<string, never>, {
2
+ assets: {
3
+ id: string;
4
+ alt: string;
5
+ }[];
6
+ }>;
7
+ export default _default;
@@ -0,0 +1,41 @@
1
+ import { z } from "zod";
2
+ import { defineAction } from "../../action.js";
3
+ import { getDbExec } from "../../db/client.js";
4
+ import { listIconAssets } from "../../icon-assets/index.js";
5
+ import { listFederatedWorkspaceIconsForOwner } from "../../icon-assets/workspace-transport.js";
6
+ import { requireOrgMember } from "../actions.js";
7
+ export default defineAction({
8
+ description: "List private workspace icons uploaded by the current organization administrator.",
9
+ http: { method: "GET" },
10
+ readOnly: true,
11
+ schema: z.object({}),
12
+ run: async (_args, ctx) => {
13
+ const caller = await requireOrgMember(ctx, true);
14
+ const result = await getDbExec().execute({
15
+ sql: `SELECT identity_authority, identity_id, allowed_domain FROM organizations WHERE id = ? LIMIT 1`,
16
+ args: [caller.orgId],
17
+ });
18
+ const row = result.rows[0];
19
+ if (!row)
20
+ throw new Error("Organization not found.");
21
+ const authority = {
22
+ identityAuthority: typeof row.identity_authority === "string"
23
+ ? row.identity_authority
24
+ : null,
25
+ identityId: typeof row.identity_id === "string" ? row.identity_id : null,
26
+ allowedDomain: typeof row.allowed_domain === "string" ? row.allowed_domain : null,
27
+ };
28
+ if (Boolean(authority.identityAuthority) !== Boolean(authority.identityId)) {
29
+ throw new Error("Workspace identity mapping is incomplete.");
30
+ }
31
+ const assets = authority.identityAuthority
32
+ ? await listFederatedWorkspaceIconsForOwner(authority, caller.email)
33
+ : await listIconAssets({ ownerEmail: caller.email, orgId: caller.orgId });
34
+ return {
35
+ assets: assets.map((asset) => ({
36
+ id: asset.id,
37
+ alt: asset.filename?.replace(/\.[^./\\]+$/, "") || undefined,
38
+ })),
39
+ };
40
+ },
41
+ });
@@ -72,9 +72,9 @@ export declare const setWorkspaceAppDefaultVisibilityHandler: import("h3").Event
72
72
  }>>;
73
73
  export declare const createOrgHandler: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
74
74
  success: boolean;
75
- id?: undefined;
76
75
  name?: undefined;
77
76
  role?: undefined;
77
+ id?: undefined;
78
78
  } | {
79
79
  success?: undefined;
80
80
  id: string;
@@ -28,6 +28,7 @@ import { CORE_INVITE_EMAIL_ID } from "../email-catalog/system-emails.js";
28
28
  import { renderTransactionalEmail } from "../email-catalog/templates.js";
29
29
  import { ssrfSafeFetch } from "../extensions/url-safety.js";
30
30
  import { evaluateFeatureFlagStrict } from "../feature-flags/store.js";
31
+ import { verifyFederatedWorkspaceIconOwner } from "../icon-assets/workspace-transport.js";
31
32
  import { offboardMember } from "../identity/offboard.js";
32
33
  import { getAppProductionUrl } from "../server/app-url.js";
33
34
  import { isTrustedSelfHostedRuntime, resolveVercelDeploymentProtectionHeaders, } from "../server/credential-provider.js";
@@ -46,6 +47,7 @@ import { CROSS_APP_ORG_FEDERATION_FLAG } from "./feature-flags.js";
46
47
  import { FederatedIconConflictError, addFederatedOrganizationMember, updateFederatedOrganizationMemberRole, revokeFederatedOrganizationMember, syncOrganizationToIdentityHub, } from "./federation.js";
47
48
  import { isFreeEmailProvider } from "./free-email-providers.js";
48
49
  import { canManageOrgA2ASecret, canManageOrgDomain } from "./permissions.js";
50
+ import { assertOwnedLocalWorkspaceIcon, requirePrivateWorkspaceIconId, } from "./private-icon-handlers.js";
49
51
  import { invalidateMemberOrgCaches } from "./request-org-cache.js";
50
52
  import { isBootstrapAdmin } from "./signup-admission.js";
51
53
  import { registerBackgroundWork, trackInviteAccepted, } from "./track-invite-accepted.js";
@@ -1119,7 +1121,7 @@ export const setOrgVisualIdentityHandler = defineEventHandler(async (event) => {
1119
1121
  }
1120
1122
  const e = await exec();
1121
1123
  const currentResult = await e.execute({
1122
- sql: `SELECT name, icon_revision, identity_authority, identity_id
1124
+ sql: `SELECT name, icon_revision, identity_authority, identity_id, allowed_domain
1123
1125
  FROM organizations WHERE id = ? LIMIT 1`,
1124
1126
  args: [ctx.orgId],
1125
1127
  });
@@ -1130,6 +1132,31 @@ export const setOrgVisualIdentityHandler = defineEventHandler(async (event) => {
1130
1132
  const iconRevision = Number(current.icon_revision ?? 0) + 1;
1131
1133
  const isFederated = Boolean(String(current.identity_authority ?? "").trim() ||
1132
1134
  String(current.identity_id ?? "").trim());
1135
+ if (icon?.kind === "image") {
1136
+ if (icon.authority !== "private-icon") {
1137
+ throw createError({
1138
+ statusCode: 400,
1139
+ message: "Workspace images must use private icon storage",
1140
+ });
1141
+ }
1142
+ requirePrivateWorkspaceIconId(icon.assetId);
1143
+ if (isFederated) {
1144
+ const owned = await verifyFederatedWorkspaceIconOwner(event, {
1145
+ identityAuthority: String(current.identity_authority ?? "") || null,
1146
+ identityId: String(current.identity_id ?? "") || null,
1147
+ allowedDomain: String(current.allowed_domain ?? "") || null,
1148
+ }, ctx.email, icon.assetId);
1149
+ if (!owned) {
1150
+ throw createError({
1151
+ statusCode: 403,
1152
+ message: "Workspace icon asset is not owned by this organization administrator",
1153
+ });
1154
+ }
1155
+ }
1156
+ else {
1157
+ await assertOwnedLocalWorkspaceIcon(icon.assetId, ctx.email, ctx.orgId);
1158
+ }
1159
+ }
1133
1160
  const updated = await e.execute({
1134
1161
  sql: `UPDATE organizations
1135
1162
  SET icon_json = ?, icon_revision = ?
@@ -179,8 +179,8 @@ export declare const getMyOrgHandler: import("h3").EventHandlerWithFetch<import(
179
179
  export declare const createOrgHandler: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
180
180
  name?: undefined;
181
181
  success: boolean;
182
- id?: undefined;
183
182
  role?: undefined;
183
+ id?: undefined;
184
184
  } | {
185
185
  success?: undefined;
186
186
  id: string;
@@ -263,4 +263,25 @@ export const ORG_MIGRATIONS = [
263
263
  ALTER TABLE organizations ADD COLUMN IF NOT EXISTS icon_revision BIGINT NOT NULL DEFAULT 0;
264
264
  `,
265
265
  },
266
+ {
267
+ version: 1034,
268
+ name: "private-icon-assets",
269
+ sql: `
270
+ CREATE TABLE IF NOT EXISTS private_icon_assets (
271
+ id TEXT PRIMARY KEY,
272
+ owner_email TEXT NOT NULL,
273
+ org_id TEXT,
274
+ mime_type TEXT NOT NULL,
275
+ filename TEXT,
276
+ alt TEXT,
277
+ size BIGINT NOT NULL,
278
+ sha256 TEXT NOT NULL,
279
+ blob_handle_json TEXT NOT NULL,
280
+ created_at BIGINT NOT NULL,
281
+ updated_at BIGINT NOT NULL
282
+ );
283
+ CREATE INDEX IF NOT EXISTS private_icon_assets_owner_org_created_idx
284
+ ON private_icon_assets (owner_email, org_id, created_at);
285
+ `,
286
+ },
266
287
  ];