@redocly/realm 0.136.0-next.1 → 0.136.0-next.10

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 (495) hide show
  1. package/CHANGELOG.md +191 -0
  2. package/dist/bin.js +1 -1
  3. package/dist/cli/build/analytics/collect-analytics.js +1 -1
  4. package/dist/cli/build/index.js +1 -1
  5. package/dist/cli/eject/ejectComponent.d.ts +1 -1
  6. package/dist/cli/eject/ejectTheme.d.ts +1 -1
  7. package/dist/cli/eject/resolveEjectParams.js +1 -1
  8. package/dist/cli/eject/themeOperations.d.ts +2 -2
  9. package/dist/cli/stats/collectors/openapi/index.js +1 -1
  10. package/dist/cli/stats/index.js +1 -1
  11. package/dist/client/App.js +1 -1
  12. package/dist/client/ErrorBoundary.js +1 -1
  13. package/dist/client/TestProvider.d.ts +1 -1
  14. package/dist/client/TestProvider.js +1 -1
  15. package/dist/client/api-docs-builder-entry.d.ts +3 -0
  16. package/dist/client/api-docs-builder-entry.js +1 -0
  17. package/dist/client/app/ConditionalLink.d.ts +1 -1
  18. package/dist/client/app/Feedback/useSubmitFeedback.js +1 -1
  19. package/dist/client/app/Sidebar/Sidebar.js +3 -3
  20. package/dist/client/app/Sidebar/helpers/hide-empty-separators.d.ts +13 -0
  21. package/dist/client/app/Sidebar/helpers/hide-empty-separators.js +1 -0
  22. package/dist/client/app/Sidebar/useActions.js +1 -1
  23. package/dist/client/app/Sidebar/utils.js +1 -1
  24. package/dist/client/app/hooks/catalog/useCatalogFilter.d.ts +1 -1
  25. package/dist/client/app/hooks/catalog/useCatalogViewMode.js +1 -1
  26. package/dist/client/app/hooks/catalog/useFetchCatalogEntities.d.ts +1 -1
  27. package/dist/client/app/hooks/catalog/useFetchCatalogEntities.js +1 -1
  28. package/dist/client/app/hooks/catalog/useFetchCatalogEntitiesRelations.d.ts +2 -2
  29. package/dist/client/app/hooks/catalog/useFetchCatalogEntitiesRelations.js +1 -1
  30. package/dist/client/app/hooks/catalog/useFetchCatalogEntityRevisions.d.ts +1 -1
  31. package/dist/client/app/hooks/catalog/useSearchTracker.d.ts +2 -5
  32. package/dist/client/app/hooks/catalog/useSearchTracker.js +1 -1
  33. package/dist/client/app/hooks/codeHighlight/useCodeHighlight.d.ts +1 -6
  34. package/dist/client/app/hooks/codeHighlight/useCodeHighlight.js +1 -1
  35. package/dist/client/app/hooks/index.d.ts +1 -0
  36. package/dist/client/app/hooks/index.js +1 -1
  37. package/dist/client/app/hooks/useAutoScroll.js +1 -1
  38. package/dist/client/app/hooks/useUserClaims.js +1 -1
  39. package/dist/client/app/l10n/hooks/index.d.ts +1 -0
  40. package/dist/client/app/l10n/hooks/index.js +1 -1
  41. package/dist/client/app/l10n/hooks/useTranslate.js +1 -1
  42. package/dist/client/app/l10n/hooks/useTranslationKeys.d.ts +2 -0
  43. package/dist/client/app/l10n/hooks/useTranslationKeys.js +1 -0
  44. package/dist/client/app/l10n/initL10n.js +1 -1
  45. package/dist/client/app/markdoc/custom-components/openapi/json-schema.d.ts +1 -1
  46. package/dist/client/app/markdoc/custom-components/openapi/json-schema.js +1 -1
  47. package/dist/client/app/markdoc/custom-components/openapi/openapi-code-sample.d.ts +1 -5
  48. package/dist/client/app/markdoc/custom-components/openapi/openapi-code-sample.js +1 -1
  49. package/dist/client/app/markdoc/custom-components/openapi/openapi-example.js +1 -1
  50. package/dist/client/app/markdoc/custom-components/openapi/openapi-response-sample.js +1 -1
  51. package/dist/client/app/markdoc/custom-components/openapi/replay-openapi.d.ts +8 -24
  52. package/dist/client/app/markdoc/custom-components/openapi/replay-openapi.js +1 -1
  53. package/dist/client/app/markdoc/hooks/use-store.d.ts +8 -6
  54. package/dist/client/app/markdoc/utils/build-replay-operation-source-map.d.ts +20 -0
  55. package/dist/client/app/markdoc/utils/build-replay-operation-source-map.js +1 -0
  56. package/dist/client/app/markdoc/utils/find-api-item.d.ts +15 -0
  57. package/dist/client/app/markdoc/utils/find-api-item.js +1 -0
  58. package/dist/client/app/markdoc/utils/find-code-sample-panel.d.ts +11 -0
  59. package/dist/client/app/markdoc/utils/find-code-sample-panel.js +1 -0
  60. package/dist/client/app/markdoc/utils/find-openapi-response-samples.d.ts +15 -0
  61. package/dist/client/app/markdoc/utils/find-openapi-response-samples.js +1 -0
  62. package/dist/client/app/markdoc/utils/openapi-panel-entry.d.ts +18 -0
  63. package/dist/client/app/markdoc/utils/openapi-panel-entry.js +1 -0
  64. package/dist/client/app/pages/DevLogin/DevLoginForm.d.ts +1 -1
  65. package/dist/client/app/useGlobalData.d.ts +1 -1
  66. package/dist/client/app/usePreloadHistory.d.ts +2 -2
  67. package/dist/client/app/usePreloadHistory.js +1 -1
  68. package/dist/client/app/utils/loadAndNavigate.d.ts +1 -1
  69. package/dist/client/app/utils/loadAndNavigate.js +1 -1
  70. package/dist/client/app/utils/resolveRouteBySlug.js +1 -1
  71. package/dist/client/app/utils/same-resolved-route.d.ts +5 -0
  72. package/dist/client/app/utils/same-resolved-route.js +1 -0
  73. package/dist/client/browser-entry.js +2 -2
  74. package/dist/client/providers/page-data/hooks.d.ts +2 -2
  75. package/dist/client/providers/post-message/PostMessageProvider.js +1 -1
  76. package/dist/client/providers/post-message/use-post-message.d.ts +1 -1
  77. package/dist/client/providers/theme/ThemeDataProvider.js +1 -1
  78. package/dist/client/runtime/loader.js +1 -1
  79. package/dist/client/templates/api-docs/helpers.d.ts +10 -0
  80. package/dist/client/templates/api-docs/helpers.js +1 -0
  81. package/dist/client/templates/api-docs/template.d.ts +17 -0
  82. package/dist/client/templates/api-docs/template.js +14 -0
  83. package/dist/client/templates/openapi-docs/helpers.d.ts +1 -1
  84. package/dist/client/templates/openapi-docs/helpers.js +2 -2
  85. package/dist/client/types/sidebar.d.ts +0 -1
  86. package/dist/client/utils/utils.d.ts +0 -2
  87. package/dist/client/utils/utils.js +1 -1
  88. package/dist/constants/common.d.ts +14 -1
  89. package/dist/constants/common.js +1 -1
  90. package/dist/constants/l10n/langs/ar.js +1 -1
  91. package/dist/constants/l10n/langs/de.js +1 -1
  92. package/dist/constants/l10n/langs/en.js +1 -1
  93. package/dist/constants/l10n/langs/es.js +1 -1
  94. package/dist/constants/l10n/langs/fr.js +1 -1
  95. package/dist/constants/l10n/langs/hi.js +1 -1
  96. package/dist/constants/l10n/langs/it.js +1 -1
  97. package/dist/constants/l10n/langs/ja.js +1 -1
  98. package/dist/constants/l10n/langs/ko.js +1 -1
  99. package/dist/constants/l10n/langs/pl.js +1 -1
  100. package/dist/constants/l10n/langs/pt-BR.js +1 -1
  101. package/dist/constants/l10n/langs/pt.js +1 -1
  102. package/dist/constants/l10n/langs/ru.js +1 -1
  103. package/dist/constants/l10n/langs/uk.js +1 -1
  104. package/dist/constants/l10n/langs/zh.js +1 -1
  105. package/dist/markdoc/tags/index.d.ts +48 -2
  106. package/dist/server/api-routes/helpers/enhance-context.js +1 -1
  107. package/dist/server/api-routes/helpers/read-stream-with-size-limit.d.ts +1 -1
  108. package/dist/server/api-routes/run-api-routes-worker.d.ts +1 -1
  109. package/dist/server/api-routes/run-api-routes-worker.js +1 -1
  110. package/dist/server/config/env-config.d.ts +2 -4
  111. package/dist/server/config/env-schema.d.ts +5 -10
  112. package/dist/server/config/env-schemas/feature-flags.d.ts +4 -8
  113. package/dist/server/config/env-schemas/feature-flags.js +1 -1
  114. package/dist/server/constants/common.d.ts +2 -0
  115. package/dist/server/constants/common.js +1 -1
  116. package/dist/server/constants/entitlements.js +1 -1
  117. package/dist/server/constants/plugins/api-docs.d.ts +3 -0
  118. package/dist/server/constants/plugins/api-docs.js +1 -0
  119. package/dist/server/esbuild/esbuild-logger.js +3 -3
  120. package/dist/server/esbuild/esbuild.js +3 -3
  121. package/dist/server/esbuild/plugins/api-docs-module-replacer/empty-check.d.ts +9 -0
  122. package/dist/server/esbuild/plugins/api-docs-module-replacer/empty-check.js +1 -0
  123. package/dist/server/esbuild/plugins/api-docs-module-replacer/empty-overlay.d.ts +2 -0
  124. package/dist/server/esbuild/plugins/api-docs-module-replacer/empty-overlay.js +1 -0
  125. package/dist/server/esbuild/plugins/api-docs-module-replacer/index.d.ts +6 -0
  126. package/dist/server/esbuild/plugins/api-docs-module-replacer/index.js +1 -0
  127. package/dist/server/persistence/cache/mappers/create-cache-db-record.d.ts +1 -1
  128. package/dist/server/persistence/file-hashes/mappers/create-file-hash-db-record.d.ts +1 -1
  129. package/dist/server/persistence/kv/mappers/create-kv-db-record.d.ts +1 -1
  130. package/dist/server/plugins/api-docs/get-server-props.d.ts +4 -0
  131. package/dist/server/plugins/api-docs/get-server-props.js +1 -0
  132. package/dist/server/plugins/api-docs/get-template-path.d.ts +2 -0
  133. package/dist/server/plugins/api-docs/get-template-path.js +1 -0
  134. package/dist/server/plugins/api-docs/import-api-docs-builder.d.ts +8 -0
  135. package/dist/server/plugins/api-docs/import-api-docs-builder.js +1 -0
  136. package/dist/server/plugins/api-docs/index.d.ts +19 -0
  137. package/dist/server/plugins/api-docs/index.js +1 -0
  138. package/dist/server/plugins/api-docs/loader.d.ts +35 -0
  139. package/dist/server/plugins/api-docs/loader.js +3 -0
  140. package/dist/server/plugins/api-docs/options.d.ts +14 -0
  141. package/dist/server/plugins/api-docs/options.js +1 -0
  142. package/dist/server/plugins/api-docs/search/get-ai-search-documents.d.ts +20 -0
  143. package/dist/server/plugins/api-docs/search/get-ai-search-documents.js +105 -0
  144. package/dist/server/plugins/api-docs/search/search-facets.d.ts +10 -0
  145. package/dist/server/plugins/api-docs/search/search-facets.js +1 -0
  146. package/dist/server/plugins/api-docs/search/search-indexer.d.ts +9 -0
  147. package/dist/server/plugins/api-docs/search/search-indexer.js +1 -0
  148. package/dist/server/plugins/api-docs/search/search-resolver.d.ts +5 -0
  149. package/dist/server/plugins/api-docs/search/search-resolver.js +1 -0
  150. package/dist/server/plugins/api-docs/spec-download.api.d.ts +4 -0
  151. package/dist/server/plugins/api-docs/spec-download.api.js +1 -0
  152. package/dist/server/plugins/api-docs/store-definition-bundles.d.ts +3 -0
  153. package/dist/server/plugins/api-docs/store-definition-bundles.js +1 -0
  154. package/dist/server/plugins/api-docs/utils/build-item-positions.d.ts +17 -0
  155. package/dist/server/plugins/api-docs/utils/build-item-positions.js +1 -0
  156. package/dist/server/plugins/api-docs/utils/build-routes-mapping.d.ts +3 -0
  157. package/dist/server/plugins/api-docs/utils/build-routes-mapping.js +1 -0
  158. package/dist/server/plugins/api-docs/utils/collect-item-routes.d.ts +12 -0
  159. package/dist/server/plugins/api-docs/utils/collect-item-routes.js +1 -0
  160. package/dist/server/plugins/api-docs/utils/decorators.d.ts +26 -0
  161. package/dist/server/plugins/api-docs/utils/decorators.js +1 -0
  162. package/dist/server/plugins/api-docs/utils/format-bundle-error.d.ts +6 -0
  163. package/dist/server/plugins/api-docs/utils/format-bundle-error.js +5 -0
  164. package/dist/server/plugins/api-docs/utils/normalize-api-version.d.ts +2 -0
  165. package/dist/server/plugins/api-docs/utils/normalize-api-version.js +1 -0
  166. package/dist/server/plugins/api-docs/utils/normalize-feedback-options.d.ts +2 -0
  167. package/dist/server/plugins/api-docs/utils/normalize-feedback-options.js +1 -0
  168. package/dist/server/plugins/api-docs/utils/relative-path-to-base-slug.d.ts +20 -0
  169. package/dist/server/plugins/api-docs/utils/relative-path-to-base-slug.js +1 -0
  170. package/dist/server/plugins/api-docs/utils/replace-file-extension.d.ts +2 -0
  171. package/dist/server/plugins/api-docs/utils/replace-file-extension.js +1 -0
  172. package/dist/server/plugins/api-docs/utils/resolve-api-doc-title.d.ts +3 -0
  173. package/dist/server/plugins/api-docs/utils/resolve-api-doc-title.js +1 -0
  174. package/dist/server/plugins/api-docs/utils/resolve-config-rbac.d.ts +10 -0
  175. package/dist/server/plugins/api-docs/utils/resolve-config-rbac.js +1 -0
  176. package/dist/server/plugins/api-docs/utils/to-relative-slug.d.ts +2 -0
  177. package/dist/server/plugins/api-docs/utils/to-relative-slug.js +1 -0
  178. package/dist/server/plugins/api-functions/index.js +1 -1
  179. package/dist/server/plugins/arazzo-docs/index.js +1 -1
  180. package/dist/server/plugins/asyncapi-docs/index.js +1 -1
  181. package/dist/server/plugins/catalog-classic/index.js +1 -1
  182. package/dist/server/plugins/catalog-entities/database/catalog-entities-diff-publisher.d.ts +1 -1
  183. package/dist/server/plugins/catalog-entities/database/catalog-entities-revisions-pruner.d.ts +4 -2
  184. package/dist/server/plugins/catalog-entities/database/catalog-entities-revisions-pruner.js +23 -3
  185. package/dist/server/plugins/catalog-entities/database/catalog-entities-service.d.ts +5 -5
  186. package/dist/server/plugins/catalog-entities/database/mappers/create-entity-attributes-db-record.d.ts +1 -1
  187. package/dist/server/plugins/catalog-entities/database/mappers/create-entity-db-record.d.ts +1 -1
  188. package/dist/server/plugins/catalog-entities/database/mappers/create-entity-relation-db-record-from-file-schema.d.ts +1 -1
  189. package/dist/server/plugins/catalog-entities/database/remote-publish-lock-service.d.ts +3 -3
  190. package/dist/server/plugins/catalog-entities/database/repositories/bffEntities/bff-entities-read-repository.d.ts +2 -2
  191. package/dist/server/plugins/catalog-entities/database/repositories/catalog-entities-repository.js +1 -1
  192. package/dist/server/plugins/catalog-entities/database/repositories/common/filters-repository.d.ts +1 -1
  193. package/dist/server/plugins/catalog-entities/database/repositories/common/revision-repository.d.ts +1 -1
  194. package/dist/server/plugins/catalog-entities/database/repositories/entities/entities-read-repository.d.ts +1 -1
  195. package/dist/server/plugins/catalog-entities/database/repositories/entities/entities-write-repository.d.ts +2 -2
  196. package/dist/server/plugins/catalog-entities/database/repositories/entities/entities-write-repository.js +1 -1
  197. package/dist/server/plugins/catalog-entities/database/repositories/entityAttributes/entity-attributes-write-repository.d.ts +1 -1
  198. package/dist/server/plugins/catalog-entities/database/repositories/relations/relations-read-repository.d.ts +1 -1
  199. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/arazzo-entities-extractor.js +1 -1
  200. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/asyncapi-entities-extractor.d.ts +13 -5
  201. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/asyncapi-entities-extractor.js +1 -1
  202. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/base.d.ts +5 -2
  203. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/base.js +1 -1
  204. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/graphql-entities-extractor.d.ts +6 -5
  205. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/graphql-entities-extractor.js +2 -2
  206. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/openapi-entities-extractor.d.ts +12 -5
  207. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/openapi-entities-extractor.js +1 -1
  208. package/dist/server/plugins/catalog-entities/extensions/extractors/fs-entities-extractor.d.ts +1 -1
  209. package/dist/server/plugins/catalog-entities/plugin.js +1 -1
  210. package/dist/server/plugins/catalog-entities/template/index.js +1 -1
  211. package/dist/server/plugins/catalog-entities/types/openapi.d.ts +1 -1
  212. package/dist/server/plugins/catalog-entities/utils/get-not-accessible-catalog-resources.d.ts +1 -1
  213. package/dist/server/plugins/catalog-entities/utils/openapi-component-content-extractor.d.ts +4 -4
  214. package/dist/server/plugins/catalog-entities/utils/openapi-component-content-extractor.js +1 -1
  215. package/dist/server/plugins/catalog-entities/utils/openapi-schema-resolver.d.ts +4 -3
  216. package/dist/server/plugins/catalog-entities/utils/openapi-schema-resolver.js +1 -1
  217. package/dist/server/plugins/config-parser/index.js +1 -1
  218. package/dist/server/plugins/config-parser/loaders/utils/read-and-validate-config.js +1 -1
  219. package/dist/server/plugins/create-slugify.d.ts +17 -0
  220. package/dist/server/plugins/create-slugify.js +1 -0
  221. package/dist/server/plugins/default-theme/index.js +1 -1
  222. package/dist/server/plugins/dev-onboarding/index.d.ts +1 -1
  223. package/dist/server/plugins/dev-onboarding/index.js +1 -1
  224. package/dist/server/plugins/dev-onboarding/template/components/RevokeAPIKey.d.ts +1 -1
  225. package/dist/server/plugins/dev-onboarding/template/components/RollAPIKey.d.ts +1 -1
  226. package/dist/server/plugins/entitlements/index.js +1 -1
  227. package/dist/server/plugins/graphql-docs/index.js +1 -1
  228. package/dist/server/plugins/graphql-docs/search/ai/utils.d.ts +1 -1
  229. package/dist/server/plugins/helpers/parse-partials.d.ts +3 -0
  230. package/dist/server/plugins/helpers/parse-partials.js +1 -0
  231. package/dist/server/plugins/l10n/index.js +1 -1
  232. package/dist/server/plugins/lifecycle.js +2 -2
  233. package/dist/server/plugins/markdown/attribute-resolvers/helpers/load-openapi-bundle.d.ts +5 -3
  234. package/dist/server/plugins/markdown/attribute-resolvers/helpers/load-openapi-bundle.js +1 -1
  235. package/dist/server/plugins/markdown/attribute-resolvers/resolve-json-example-ref.js +1 -1
  236. package/dist/server/plugins/markdown/attribute-resolvers/resolve-open-api-ref.js +1 -1
  237. package/dist/server/plugins/markdown/attribute-resolvers/resolve-openapi-code-samples.js +1 -1
  238. package/dist/server/plugins/markdown/attribute-resolvers/resolve-openapi-response-samples.js +1 -1
  239. package/dist/server/plugins/markdown/index.js +1 -1
  240. package/dist/server/plugins/markdown/markdoc/markdoc-options.d.ts +9 -9
  241. package/dist/server/plugins/markdown/markdoc/plugins/utils.d.ts +5 -0
  242. package/dist/server/plugins/markdown/markdoc/plugins/utils.js +1 -1
  243. package/dist/server/plugins/markdown/runtime-transform.js +1 -1
  244. package/dist/server/plugins/markdown/search/create-render-tag-fn.d.ts +2 -1
  245. package/dist/server/plugins/markdown/search/create-render-tag-fn.js +1 -1
  246. package/dist/server/plugins/markdown/search/get-ai-search-documents.js +9 -9
  247. package/dist/server/plugins/markdown/search/walk-sections.js +1 -1
  248. package/dist/server/plugins/markdown/utils/resolve-markdown-template.d.ts +1 -1
  249. package/dist/server/plugins/mcp/auth/auth-handlers.d.ts +3 -0
  250. package/dist/server/plugins/mcp/auth/auth-handlers.js +1 -1
  251. package/dist/server/plugins/mcp/codemode/capabilities/types.d.ts +1 -1
  252. package/dist/server/plugins/mcp/codemode/capabilities/utils.d.ts +1 -1
  253. package/dist/server/plugins/mcp/codemode/code-audit.d.ts +12 -0
  254. package/dist/server/plugins/mcp/codemode/code-audit.js +1 -0
  255. package/dist/server/plugins/mcp/codemode/code-execution-telemetry.d.ts +11 -0
  256. package/dist/server/plugins/mcp/codemode/code-execution-telemetry.js +1 -0
  257. package/dist/server/plugins/mcp/codemode/constants.js +1 -1
  258. package/dist/server/plugins/mcp/codemode/prompts.js +1 -1
  259. package/dist/server/plugins/mcp/codemode/tools/describe-tools.d.ts +2 -3
  260. package/dist/server/plugins/mcp/codemode/tools/execute-schema.d.ts +1 -1
  261. package/dist/server/plugins/mcp/codemode/tools/execute-schema.js +1 -1
  262. package/dist/server/plugins/mcp/codemode/tools/execute.d.ts +1 -0
  263. package/dist/server/plugins/mcp/codemode/tools/execute.js +1 -1
  264. package/dist/server/plugins/mcp/constants.d.ts +2 -1
  265. package/dist/server/plugins/mcp/constants.js +1 -1
  266. package/dist/server/plugins/mcp/docs-mcp/tool-schemas.d.ts +1 -0
  267. package/dist/server/plugins/mcp/docs-mcp/tool-schemas.js +1 -1
  268. package/dist/server/plugins/mcp/docs-mcp/tools/core/create-anonymous-session.d.ts +11 -0
  269. package/dist/server/plugins/mcp/docs-mcp/tools/core/create-anonymous-session.js +1 -0
  270. package/dist/server/plugins/mcp/docs-mcp/tools/graphql/constants.d.ts +4 -0
  271. package/dist/server/plugins/mcp/docs-mcp/tools/graphql/constants.js +1 -0
  272. package/dist/server/plugins/mcp/docs-mcp/tools/graphql/get-graphql-type-list.js +1 -1
  273. package/dist/server/plugins/mcp/docs-mcp/tools/graphql/get-graphql-type.js +7 -4
  274. package/dist/server/plugins/mcp/docs-mcp/tools/graphql/types.d.ts +7 -1
  275. package/dist/server/plugins/mcp/docs-mcp/tools/graphql/types.js +0 -1
  276. package/dist/server/plugins/mcp/docs-mcp/tools/graphql/utils.d.ts +5 -1
  277. package/dist/server/plugins/mcp/docs-mcp/tools/graphql/utils.js +4 -2
  278. package/dist/server/plugins/mcp/docs-mcp/tools/index.d.ts +4 -0
  279. package/dist/server/plugins/mcp/docs-mcp/tools/index.js +1 -1
  280. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/constants.d.ts +2 -0
  281. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/constants.js +1 -0
  282. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/get-endpoint-info.js +1 -1
  283. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/get-endpoints.js +1 -1
  284. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/get-full-api-description.js +1 -1
  285. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/get-security-schemes.js +1 -1
  286. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/list-apis.js +1 -1
  287. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/load-api-description.d.ts +6 -2
  288. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/load-api-description.js +1 -1
  289. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/types.d.ts +2 -0
  290. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/utils.d.ts +2 -2
  291. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/utils.js +1 -1
  292. package/dist/server/plugins/mcp/docs-mcp/utils.d.ts +3 -3
  293. package/dist/server/plugins/mcp/docs-mcp/utils.js +1 -1
  294. package/dist/server/plugins/mcp/gateway-mcp/elicitation.d.ts +28 -0
  295. package/dist/server/plugins/mcp/gateway-mcp/elicitation.js +2 -0
  296. package/dist/server/plugins/mcp/gateway-mcp/eligibility.d.ts +5 -17
  297. package/dist/server/plugins/mcp/gateway-mcp/eligibility.js +1 -1
  298. package/dist/server/plugins/mcp/gateway-mcp/fetch/allowed-hosts.d.ts +9 -9
  299. package/dist/server/plugins/mcp/gateway-mcp/fetch/allowed-hosts.js +1 -1
  300. package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-bridge.d.ts +17 -1
  301. package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-bridge.js +1 -1
  302. package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-errors.d.ts +11 -0
  303. package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-errors.js +1 -0
  304. package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-telemetry.d.ts +14 -0
  305. package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-telemetry.js +1 -0
  306. package/dist/server/plugins/mcp/gateway-mcp/fetch/normalize-path.d.ts +6 -0
  307. package/dist/server/plugins/mcp/gateway-mcp/fetch/normalize-path.js +1 -0
  308. package/dist/server/plugins/mcp/gateway-mcp/fetch/redact.d.ts +4 -0
  309. package/dist/server/plugins/mcp/gateway-mcp/fetch/redact.js +1 -0
  310. package/dist/server/plugins/mcp/gateway-mcp/fetch/ssrf-blocklist.d.ts +22 -0
  311. package/dist/server/plugins/mcp/gateway-mcp/fetch/ssrf-blocklist.js +1 -0
  312. package/dist/server/plugins/mcp/gateway-mcp/fetch/ssrf-guard.d.ts +1 -1
  313. package/dist/server/plugins/mcp/gateway-mcp/fetch/ssrf-guard.js +1 -1
  314. package/dist/server/plugins/mcp/gateway-mcp/fetch/ssrf-safe-lookup.d.ts +13 -0
  315. package/dist/server/plugins/mcp/gateway-mcp/fetch/ssrf-safe-lookup.js +1 -0
  316. package/dist/server/plugins/mcp/gateway-mcp/fetch-capability.d.ts +8 -1
  317. package/dist/server/plugins/mcp/gateway-mcp/fetch-capability.js +1 -1
  318. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/apply-edge-rate-limit.d.ts +3 -0
  319. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/apply-edge-rate-limit.js +1 -0
  320. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/edge-limiter.d.ts +16 -0
  321. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/edge-limiter.js +1 -0
  322. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/ip-key.d.ts +2 -0
  323. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/ip-key.js +1 -0
  324. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/limits.d.ts +7 -0
  325. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/limits.js +1 -0
  326. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/rate-limit-telemetry.d.ts +8 -0
  327. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/rate-limit-telemetry.js +1 -0
  328. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/window-counter.d.ts +15 -0
  329. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/window-counter.js +1 -0
  330. package/dist/server/plugins/mcp/gateway-mcp/secret-store.d.ts +24 -0
  331. package/dist/server/plugins/mcp/gateway-mcp/secret-store.js +1 -0
  332. package/dist/server/plugins/mcp/gateway-mcp/subject.d.ts +20 -0
  333. package/dist/server/plugins/mcp/gateway-mcp/subject.js +1 -0
  334. package/dist/server/plugins/mcp/gateway-mcp/upstream-auth-scheme.d.ts +18 -0
  335. package/dist/server/plugins/mcp/gateway-mcp/upstream-auth-scheme.js +1 -0
  336. package/dist/server/plugins/mcp/gateway-mcp/upstream-auth.d.ts +10 -0
  337. package/dist/server/plugins/mcp/gateway-mcp/upstream-auth.js +1 -0
  338. package/dist/server/plugins/mcp/handlers/docs-mcp-handler.js +1 -1
  339. package/dist/server/plugins/mcp/handlers/errors.d.ts +3 -3
  340. package/dist/server/plugins/mcp/handlers/errors.js +1 -1
  341. package/dist/server/plugins/mcp/handlers/handle-mcp-request.js +1 -1
  342. package/dist/server/plugins/mcp/handlers/mcp-credentials-handler.d.ts +5 -0
  343. package/dist/server/plugins/mcp/handlers/mcp-credentials-handler.js +101 -0
  344. package/dist/server/plugins/mcp/index.d.ts +1 -0
  345. package/dist/server/plugins/mcp/index.js +1 -1
  346. package/dist/server/plugins/mcp/servers/docs-server.d.ts +3 -1
  347. package/dist/server/plugins/mcp/servers/docs-server.js +1 -1
  348. package/dist/server/plugins/mcp/servers/mcp-server.d.ts +15 -8
  349. package/dist/server/plugins/mcp/servers/mcp-server.js +1 -1
  350. package/dist/server/plugins/mcp/types.d.ts +16 -20
  351. package/dist/server/plugins/mcp/utils/json-schema-validator.d.ts +9 -0
  352. package/dist/server/plugins/mcp/utils/json-schema-validator.js +1 -0
  353. package/dist/server/plugins/mcp/utils/jwt.d.ts +0 -9
  354. package/dist/server/plugins/mcp/utils/jwt.js +1 -1
  355. package/dist/server/plugins/mcp/utils/mode.d.ts +12 -2
  356. package/dist/server/plugins/mcp/utils/mode.js +1 -1
  357. package/dist/server/plugins/mcp/utils/telemetry-attributes.d.ts +8 -0
  358. package/dist/server/plugins/mcp/utils/telemetry-attributes.js +1 -0
  359. package/dist/server/plugins/mcp/utils/xmcp-utils.d.ts +1 -1
  360. package/dist/server/plugins/mcp/utils.d.ts +17 -5
  361. package/dist/server/plugins/mcp/utils.js +1 -1
  362. package/dist/server/plugins/mcp/workers/execute-mcp-tool.js +1 -1
  363. package/dist/server/plugins/mcp/workers/mcp-tool-telemetry.d.ts +10 -2
  364. package/dist/server/plugins/mcp/workers/mcp-tool-telemetry.js +1 -1
  365. package/dist/server/plugins/openapi-docs/index.js +1 -1
  366. package/dist/server/plugins/openapi-docs/search/get-ai-search-documents.js +16 -16
  367. package/dist/server/plugins/openapi-docs/utils.js +1 -1
  368. package/dist/server/plugins/pages/index.js +1 -1
  369. package/dist/server/plugins/scorecard-classic/compute-scorecard.d.ts +1 -1
  370. package/dist/server/plugins/scorecard-classic/compute-scorecard.js +4 -4
  371. package/dist/server/plugins/scorecard-classic/index.d.ts +1 -1
  372. package/dist/server/plugins/scorecard-classic/index.js +1 -1
  373. package/dist/server/plugins/scorecard-classic/template/components.d.ts +1 -1
  374. package/dist/server/plugins/scorecard-classic/template/useData.d.ts +1 -1
  375. package/dist/server/plugins/scorecards/plugin.js +1 -1
  376. package/dist/server/plugins/search/ai-indexer/prepare-semantic-documents.d.ts +1 -1
  377. package/dist/server/plugins/search/ai-indexer/prepare-semantic-documents.js +2 -2
  378. package/dist/server/plugins/search/documents/search-documents.js +1 -1
  379. package/dist/server/plugins/search/engines/flexsearch/index.js +1 -1
  380. package/dist/server/plugins/search/engines/flexsearch/search-index.js +1 -1
  381. package/dist/server/plugins/search/engines/search-engine.d.ts +1 -1
  382. package/dist/server/plugins/search/engines/typesense/index.js +1 -1
  383. package/dist/server/plugins/search/index.js +1 -1
  384. package/dist/server/plugins/search/llmstxt/index.d.ts +1 -1
  385. package/dist/server/plugins/search/llmstxt/index.js +4 -4
  386. package/dist/server/plugins/sidebars/index.d.ts +1 -1
  387. package/dist/server/plugins/sidebars/index.js +1 -1
  388. package/dist/server/plugins/sitemap/index.js +1 -1
  389. package/dist/server/plugins/sso/index.js +1 -1
  390. package/dist/server/providers/database/database-path-generator.d.ts +2 -2
  391. package/dist/server/providers/database/utils/storage-limit-validator.d.ts +1 -1
  392. package/dist/server/sandbox/sandbox.js +2 -2
  393. package/dist/server/sandbox/types.d.ts +3 -2
  394. package/dist/server/sandbox/utils/execution-budget.d.ts +4 -3
  395. package/dist/server/sandbox/utils/execution-budget.js +1 -1
  396. package/dist/server/ssr/render.js +1 -1
  397. package/dist/server/ssr/server-side-props/get-default-static-props.d.ts +1 -1
  398. package/dist/server/ssr/server-side-props/get-server-props-from-user-handler.d.ts +1 -1
  399. package/dist/server/ssr/template.d.ts +1 -1
  400. package/dist/server/ssr/utils.d.ts +1 -0
  401. package/dist/server/ssr/utils.js +5 -5
  402. package/dist/server/store.d.ts +2 -6
  403. package/dist/server/store.js +1 -1
  404. package/dist/server/tools/notifiers/logger.js +1 -1
  405. package/dist/server/tools/notifiers/reporter.js +6 -6
  406. package/dist/server/types/plugins/common.d.ts +4 -6
  407. package/dist/server/types/plugins/markdown.d.ts +1 -3
  408. package/dist/server/types/plugins/search.d.ts +1 -0
  409. package/dist/server/utils/catalog-classic/get-route-slug-to-catalog-slug-map.test.js +1 -1
  410. package/dist/server/utils/crypto/constants.d.ts +5 -0
  411. package/dist/server/utils/crypto/constants.js +1 -0
  412. package/dist/server/utils/crypto/decrypt-aes-gcm.d.ts +6 -0
  413. package/dist/server/utils/crypto/decrypt-aes-gcm.js +1 -0
  414. package/dist/server/utils/crypto/decrypt-claim-value.d.ts +6 -0
  415. package/dist/server/utils/crypto/decrypt-claim-value.js +1 -0
  416. package/dist/server/utils/crypto/derive-key.d.ts +5 -0
  417. package/dist/server/utils/crypto/derive-key.js +1 -0
  418. package/dist/server/utils/crypto/encrypt-aes-gcm.d.ts +6 -0
  419. package/dist/server/utils/crypto/encrypt-aes-gcm.js +1 -0
  420. package/dist/server/utils/crypto/encrypt-claim-value.d.ts +6 -0
  421. package/dist/server/utils/crypto/encrypt-claim-value.js +1 -0
  422. package/dist/server/utils/l10n/get-build-translate-context.d.ts +7 -0
  423. package/dist/server/utils/l10n/get-build-translate-context.js +1 -0
  424. package/dist/server/utils/llmstxt/agent-feedback-llms-footer.js +1 -1
  425. package/dist/server/utils/rbac.d.ts +4 -0
  426. package/dist/server/utils/rbac.js +1 -1
  427. package/dist/server/utils/report-all-errors.js +1 -1
  428. package/dist/server/utils/sandbox-context.d.ts +18 -0
  429. package/dist/server/utils/sandbox-context.js +1 -0
  430. package/dist/server/utils/shared-data.js +1 -1
  431. package/dist/server/web-server/auth.d.ts +34 -4
  432. package/dist/server/web-server/auth.js +3 -3
  433. package/dist/server/web-server/handle-api-route-request.js +1 -1
  434. package/dist/server/web-server/middleware/catalogAuthMiddleware.d.ts +1 -1
  435. package/dist/server/web-server/middleware/telemetry-middleware.js +1 -1
  436. package/dist/server/web-server/routes/api-routes/api-routes.js +1 -1
  437. package/dist/server/web-server/routes/auth.js +1 -1
  438. package/dist/server/web-server/routes/catalog/bff-catalog-related-entities.js +1 -1
  439. package/dist/server/web-server/routes/catalog/bff-catalog-revisions.js +1 -1
  440. package/dist/server/web-server/routes/catalog/bff-catalog.js +1 -1
  441. package/dist/server/web-server/routes/catalog/catalog-relations.js +1 -1
  442. package/dist/server/web-server/routes/catalog/catalog.js +1 -1
  443. package/dist/server/web-server/routes/catalog/helpers/has-access-to-entity.d.ts +1 -1
  444. package/dist/server/web-server/routes/catalog/helpers/upsert-pages-stats.d.ts +1 -1
  445. package/dist/server/web-server/routes/dynamic-route.js +1 -1
  446. package/dist/server/web-server/routes/feedback.d.ts +1 -1
  447. package/dist/server/web-server/routes/helpers/process-redirects.d.ts +1 -1
  448. package/dist/server/web-server/routes/mcp-routes/a2a.js +1 -1
  449. package/dist/server/web-server/routes/mcp-routes/agent-card.js +1 -1
  450. package/dist/server/web-server/routes/mcp-routes/mcp-oauth.d.ts +10 -6
  451. package/dist/server/web-server/routes/mcp-routes/mcp-oauth.js +1 -1
  452. package/dist/server/web-server/routes/mcp-routes/mcp-routes.js +1 -1
  453. package/dist/server/web-server/routes/mcp-routes/mcp-server-card.js +1 -1
  454. package/dist/server/web-server/routes/mcp-routes/utils/build-agent-card.d.ts +1 -1
  455. package/dist/server/web-server/routes/page-data.js +1 -1
  456. package/dist/server/web-server/routes/resolve-route.js +1 -1
  457. package/dist/server/web-server/routes/search.js +1 -1
  458. package/dist/server/web-server/routes/skills/skill-markdown.js +1 -1
  459. package/dist/server/web-server/routes/skills/skills-index.js +1 -1
  460. package/dist/server/web-server/utils/prepare-list-response.d.ts +1 -1
  461. package/dist/server/workers/api-routes-worker-pool.js +1 -1
  462. package/dist/server/workers/mcp-tool-worker-pool.js +1 -1
  463. package/dist/server/workers/worker-pool.d.ts +1 -0
  464. package/dist/server/workers/worker-pool.js +1 -1
  465. package/dist/types/entitlements.d.ts +6 -1
  466. package/dist/types/markdoc.d.ts +2 -1
  467. package/dist/utils/l10n/build-i18n-config.d.ts +24 -0
  468. package/dist/utils/l10n/build-i18n-config.js +1 -0
  469. package/dist/utils/l10n/create-translate.d.ts +19 -0
  470. package/dist/utils/l10n/create-translate.js +1 -0
  471. package/dist/utils/url/get-shared-data-fetch-url.d.ts +17 -0
  472. package/dist/utils/url/get-shared-data-fetch-url.js +1 -0
  473. package/dist/utils/url/parse-preview-url.d.ts +22 -0
  474. package/dist/utils/url/parse-preview-url.js +1 -0
  475. package/package.json +15 -14
  476. package/dist/markdoc/helpers/get-operation/get-operation-info-by-id.d.ts +0 -4
  477. package/dist/markdoc/helpers/get-operation/get-operation-info-by-id.js +0 -1
  478. package/dist/markdoc/helpers/get-operation/get-operation-info-by-pointer.d.ts +0 -4
  479. package/dist/markdoc/helpers/get-operation/get-operation-info-by-pointer.js +0 -1
  480. package/dist/markdoc/helpers/get-operation/get-operation.d.ts +0 -14
  481. package/dist/markdoc/helpers/get-operation/get-operation.js +0 -1
  482. package/dist/markdoc/helpers/get-operation/index.d.ts +0 -4
  483. package/dist/markdoc/helpers/get-operation/index.js +0 -1
  484. package/dist/markdoc/helpers/get-operation/types/index.d.ts +0 -4
  485. package/dist/markdoc/helpers/get-operation/types/index.js +0 -0
  486. package/dist/markdoc/helpers/get-operation/types/operation-identifier.d.ts +0 -5
  487. package/dist/markdoc/helpers/get-operation/types/operation-identifier.js +0 -0
  488. package/dist/markdoc/helpers/get-operation/types/operation-info.d.ts +0 -6
  489. package/dist/markdoc/helpers/get-operation/types/operation-info.js +0 -0
  490. package/dist/markdoc/helpers/get-operation/types/operation-parameters.d.ts +0 -3
  491. package/dist/markdoc/helpers/get-operation/types/operation-parameters.js +0 -0
  492. package/dist/server/plugins/markdown/attribute-resolvers/helpers/get-media-content-samples.d.ts +0 -4
  493. package/dist/server/plugins/markdown/attribute-resolvers/helpers/get-media-content-samples.js +0 -1
  494. package/dist/server/plugins/mcp/handlers/sse-keepalive.d.ts +0 -15
  495. package/dist/server/plugins/mcp/handlers/sse-keepalive.js +0 -3
@@ -1,18 +1,7 @@
1
- import type { OpenAPIDefinition } from '@redocly/openapi-docs';
2
- import type { OpenAPIMcp } from '@redocly/openapi-docs/lib/types/open-api.js';
3
- import type { RbacConfig } from '@redocly/config';
4
- type GatewayVisibility = {
5
- hide?: boolean;
6
- docs?: {
7
- hide?: boolean;
8
- ignore?: readonly string[];
9
- };
10
- gateway?: {
11
- hide?: boolean;
12
- };
13
- };
14
- /** Whether the gateway fetch capability is on: the feature flag plus none of mcp/docs/gateway hidden. */
15
- export declare function isGatewayCapabilityEnabled(mcp: GatewayVisibility | undefined): boolean;
1
+ import type { OpenAPIDefinition, OpenAPIMcp } from '@redocly/api-docs';
2
+ import type { RbacConfig, RedoclyConfig } from '@redocly/config';
3
+ /** Whether the gateway fetch capability is on: the feature flag plus none of mcp/docs hidden. */
4
+ export declare function isGatewayCapabilityEnabled(mcp?: RedoclyConfig['mcp']): boolean;
16
5
  /** Whether an API is eligible for the gateway (fetch-capable `execute` + `/mcp` advertisement). */
17
6
  export declare function isGatewayEligible(info: OpenAPIDefinition['info'] | undefined, relativePath: string, rbacConfig: RbacConfig): boolean;
18
7
  /**
@@ -24,7 +13,6 @@ export declare function shouldAdvertiseGatewayXMcp(definition: (OpenAPIDefinitio
24
13
  'x-mcp'?: {
25
14
  servers?: unknown[];
26
15
  };
27
- }) | undefined, relativePath: string, rbacConfig: RbacConfig, mcpConfig: GatewayVisibility | undefined): boolean;
16
+ }) | undefined, relativePath: string, rbacConfig: RbacConfig, mcpConfig?: RedoclyConfig['mcp']): boolean;
28
17
  export declare function buildGatewayXMcp(url: string): OpenAPIMcp;
29
- export {};
30
18
  //# sourceMappingURL=eligibility.d.ts.map
@@ -1 +1 @@
1
- import{join as r}from"node:path";import{PUBLIC_API_DEFINITIONS_FOLDER as s}from"../../../constants/common.js";import{DEFAULT_ANONYMOUS_VISITOR_TEAM as a}from"../../../../constants/common.js";import{canDownloadApiDefinition as n}from"../../../utils/rbac.js";import{MCP_PROTOCOL_VERSION as p}from"../constants.js";import{isApiIncludedInDocsMcp as l}from"../utils.js";import{isMcpGatewayEnabled as c}from"../utils/mode.js";import{isDefinitionHidden as f,hasGatewayConfig as m}from"../utils/xmcp-utils.js";function u(o){return c()&&!o?.hide&&!o?.docs?.hide&&!o?.gateway?.hide}function d(o,e,i){return f(o,"gateway")?!1:n(r(s,e),i,!1,{isAuthenticated:!1,teams:[a]})||m(o)}function D(o,e,i,t){return u(t)&&!o?.["x-mcp"]?.servers?.length&&d(o?.info,e,i)&&l(e,o,t)}function M(o){return{protocolVersion:p,capabilities:{tools:{}},servers:[{url:o}],tools:[],resources:[],prompts:[]}}export{M as buildGatewayXMcp,u as isGatewayCapabilityEnabled,d as isGatewayEligible,D as shouldAdvertiseGatewayXMcp};
1
+ import{join as e}from"node:path";import{PUBLIC_API_DEFINITIONS_FOLDER as s}from"../../../constants/common.js";import{DEFAULT_ANONYMOUS_VISITOR_TEAM as a}from"../../../../constants/common.js";import{canDownloadApiDefinition as n}from"../../../utils/rbac.js";import{MCP_PROTOCOL_VERSION as p}from"../constants.js";import{isApiIncludedInDocsMcp as c}from"../utils.js";import{isMcpGatewayEnabled as l}from"../utils/mode.js";import{isDefinitionHidden as m,hasGatewayConfig as f}from"../utils/xmcp-utils.js";function u(o){return l()&&!o?.hide&&!o?.docs?.hide}function d(o,i,r){return m(o,"gateway")?!1:n(e(s,i),r,!1,{isAuthenticated:!1,teams:[a]})||f(o)}function D(o,i,r,t){return u(t)&&!o?.["x-mcp"]?.servers?.length&&d(o?.info,i,r)&&c(i,o,t)}function M(o){return{protocolVersion:p,capabilities:{tools:{}},servers:[{url:o}],tools:[],resources:[],prompts:[]}}export{M as buildGatewayXMcp,u as isGatewayCapabilityEnabled,d as isGatewayEligible,D as shouldAdvertiseGatewayXMcp};
@@ -1,13 +1,13 @@
1
- import type { OpenAPIServer } from '@redocly/openapi-docs/lib/types/open-api.js';
1
+ import type { OpenAPIServer } from '@redocly/api-docs';
2
2
  /**
3
- * Build case-insensitive host matchers from an API's server URL templates (plus any
4
- * configured extra hosts). A server URL host may contain server-variable placeholders
5
- * (e.g. a tenant `{subdomain}`); each placeholder expands to its `enum` values, or - when
6
- * free-form - to one DNS label plus any fixed parent domain carried by the variable's
7
- * `default`. So `{subdomain}.dealpos.com` matches `acme.dealpos.com`, and a whole-host
8
- * `{subdomain}` defaulting to `acme.dealpos.net` matches `<tenant>.dealpos.net`, but neither
9
- * matches `a.b.dealpos.com`, the bare parent domain, or an unrelated host.
3
+ * Build case-insensitive host matchers from an API's server URL templates. A server URL host
4
+ * may contain server-variable placeholders (e.g. a tenant `{subdomain}`); each placeholder
5
+ * expands to its `enum` values, or - when free-form - to one DNS label plus any fixed parent
6
+ * domain carried by the variable's `default`. So `{subdomain}.dealpos.com` matches
7
+ * `acme.dealpos.com`, and a whole-host `{subdomain}` defaulting to `acme.dealpos.net` matches
8
+ * `<tenant>.dealpos.net`, but neither matches `a.b.dealpos.com`, the bare parent domain, or an
9
+ * unrelated host.
10
10
  */
11
- export declare function buildAllowedHostMatchers(servers?: readonly OpenAPIServer[], extraHosts?: readonly string[]): RegExp[];
11
+ export declare function buildAllowedHostMatchers(servers?: readonly OpenAPIServer[]): RegExp[];
12
12
  export declare function isHostAllowed(host: string, matchers: readonly RegExp[]): boolean;
13
13
  //# sourceMappingURL=allowed-hosts.d.ts.map
@@ -1 +1 @@
1
- const i=/\{([^}]+)\}/g;function m(n=[],e=[]){const t=[];for(const r of n){const o=u(r);o&&t.push(o)}for(const r of e){const o=h(r);o&&t.push(o)}return t}function p(n,e){return e.some(t=>t.test(n))}function u(n){const e=f(n.url);if(!e)return null;let t="",r=0;for(const o of e.matchAll(i)){const[c,l]=o;t+=s(e.slice(r,o.index)),t+=a(n.variables?.[l]),r=o.index+c.length}return t+=s(e.slice(r)),t.includes("\\.")?new RegExp(`^${t}$`,"i"):null}function a(n){const e=n?.enum?.filter(Boolean);if(e&&e.length>0)return`(?:${e.map(s).join("|")})`;const t=n?.default?.split(".").slice(1).join(".");return t?`[^.]+\\.${s(t)}`:"[^.]+"}function h(n){const e=n.trim().toLowerCase();return e?e.startsWith("*.")?new RegExp(`^[^.]+\\.${s(e.slice(2))}$`,"i"):new RegExp(`^${s(e)}$`,"i"):null}function f(n){if(!n)return null;const t=n.replace(/^[a-z][a-z0-9+.-]*:\/\//i,"").split(/[/?#]/,1)[0];return t&&(t.includes("@")?t.slice(t.lastIndexOf("@")+1):t).replace(/:(?:\d+|\{[^}]+\})$/,"")||null}function s(n){return n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}export{m as buildAllowedHostMatchers,p as isHostAllowed};
1
+ const h=/\{([^}]+)\}/g;function g(n=[]){const e=[];for(const t of n){const r=p(t);r&&e.push(r)}return e}function x(n,e){return e.some(t=>t.test(n))}function p(n){const e=m(n.url);if(!e)return null;let t="",r=0,o=!1;for(const l of e.matchAll(h)){const[i,f]=l,c=e.slice(r,l.index);c.includes(".")&&(o=!0),t+=s(c);const u=d(n.variables?.[f]);u.guaranteesDot&&(o=!0),t+=u.pattern,r=l.index+i.length}const a=e.slice(r);return a.includes(".")&&(o=!0),t+=s(a),o?new RegExp(`^${t}$`,"i"):null}function d(n){const e=n?.enum?.filter(Boolean);if(e&&e.length>0)return{pattern:`(?:${e.map(s).join("|")})`,guaranteesDot:e.every(r=>r.includes("."))};const t=n?.default?.split(".").slice(1).join(".");return t?{pattern:`[^.]+\\.${s(t)}`,guaranteesDot:!0}:{pattern:"[^.]+",guaranteesDot:!1}}function m(n){if(!n)return null;const t=n.replace(/^[a-z][a-z0-9+.-]*:\/\//i,"").split(/[/?#]/,1)[0];return t&&(t.includes("@")?t.slice(t.lastIndexOf("@")+1):t).replace(/:(?:\d+|\{[^}]+\})$/,"")||null}function s(n){return n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}export{g as buildAllowedHostMatchers,x as isHostAllowed};
@@ -1,12 +1,28 @@
1
+ import { Agent, type Dispatcher } from 'undici';
1
2
  import type { SandboxFetch } from '../../codemode/types.js';
3
+ import type { UpstreamAuthRequiredEvent } from '../upstream-auth.js';
4
+ import type { StoredSecret } from '../secret-store.js';
5
+ export declare function getDefaultAgent(): Agent;
6
+ export type FetchBridgeApi = {
7
+ slug: string;
8
+ name: string;
9
+ matchers: readonly RegExp[];
10
+ secret?: StoredSecret;
11
+ };
2
12
  type FetchBridgeOptions = {
3
13
  allowedHosts: readonly RegExp[];
14
+ apis?: readonly FetchBridgeApi[];
4
15
  authorization?: string;
16
+ onAuthRequired?: (event: UpstreamAuthRequiredEvent) => void;
5
17
  fetchImpl?: typeof fetch;
18
+ dispatcher?: Dispatcher;
6
19
  timeoutMs?: number;
7
20
  maxResponseBytes?: number;
21
+ maxFetchesPerExec?: number;
22
+ clientIp?: string;
8
23
  };
9
24
  /** Build the host-side `fetch` the gateway sandbox calls. */
10
- export declare function buildFetchBridge({ allowedHosts, authorization, fetchImpl, timeoutMs, maxResponseBytes }: FetchBridgeOptions): SandboxFetch;
25
+ export declare function buildFetchBridge({ allowedHosts, apis, authorization, onAuthRequired, fetchImpl, dispatcher, timeoutMs, maxResponseBytes, maxFetchesPerExec, clientIp, }: FetchBridgeOptions): SandboxFetch;
26
+ export declare function readCappedBody(response: Response, maxBytes: number): Promise<string>;
11
27
  export {};
12
28
  //# sourceMappingURL=fetch-bridge.d.ts.map
@@ -1 +1 @@
1
- import{assertUrlAllowed as f}from"./ssrf-guard.js";const b=3e4,w=1024*1024;function m({allowedHosts:t,authorization:e,fetchImpl:o=fetch,timeoutMs:n=b,maxResponseBytes:s=w}){return async r=>{const a=f(r.url,t),d=g(r.headers,e),c=new AbortController,u=setTimeout(()=>c.abort(),n);try{const i=await o(a,{method:r.method??"GET",headers:d,body:r.body,redirect:"manual",signal:c.signal}),h=await y(i,s);return{status:i.status,statusText:i.statusText,ok:i.ok,headers:T(i.headers),bodyText:h}}finally{clearTimeout(u)}}}async function y(t,e){const o=Number(t.headers.get("content-length"));if(Number.isFinite(o)&&o>e)throw l(e,o);if(!t.body)return"";const n=t.body.getReader(),s=new TextDecoder;let r=0,a="";try{for(;;){const{done:d,value:c}=await n.read();if(d)break;if(r+=c.byteLength,r>e)throw l(e,r);a+=s.decode(c,{stream:!0})}return a+s.decode()}finally{await n.cancel().catch(()=>{})}}function l(t,e){return new Error(`Response is too large (over ${t} bytes, got ${e}); request less data`)}function g(t,e){const o={};let n=!1;for(const[s,r]of Object.entries(t??{})){const a=s.toLowerCase();a==="host"||a==="content-length"||(a==="authorization"&&(n=!0),o[s]=r)}return e&&!n&&(o.Authorization=e),o}function T(t){const e={};return t.forEach((o,n)=>{e[n.toLowerCase()]=o}),e}export{m as buildFetchBridge};
1
+ import{Agent as P}from"undici";import{envConfig as W}from"../../../../config/env-config.js";import{logger as C}from"../../../../tools/notifiers/logger.js";import{assertUrlAllowed as H}from"./ssrf-guard.js";import{createSsrfSafeLookup as J}from"./ssrf-safe-lookup.js";import{SsrfBlockedError as U}from"./ssrf-blocklist.js";import{GatewayFetchBlockedError as $,GatewayFetchSystemError as K,GatewayFetchUserError as A}from"./fetch-errors.js";import{redactHeaders as x,redactSecretsFromString as V}from"./redact.js";import{normalizeFetchPath as X}from"./normalize-path.js";import{reportGatewayFetch as O}from"./fetch-telemetry.js";const G="x-forwarded-for",Y=3e4,z=1024*1024;let k;function I(){if(!k){const t=W.isDevelopMode;t&&C.warn("Gateway MCP SSRF guard: loopback upstreams are ALLOWED (develop mode only, never in runtime)."),k=new P({connect:{lookup:J({allowLoopback:t})}})}return k}function we({allowedHosts:t,apis:e=[],authorization:r,onAuthRequired:n,fetchImpl:s=fetch,dispatcher:u=I(),timeoutMs:c=Y,maxResponseBytes:h=z,maxFetchesPerExec:f,clientIp:m}){const v=[...t,...e.flatMap(o=>o.matchers)],N=[r,...e.map(o=>o.secret?.value)].filter(o=>!!o),D=e.map(o=>o.secret?.header).filter(o=>!!o);let F=0;return async o=>{const g=o.method??"GET",T=Date.now();let M,b,E,S={},R,L;try{if(f!==void 0){const l=Math.max(0,f);if(F+=1,F>l)throw new A(`Outbound fetch budget exceeded (max ${l} fetches per execute); split the work across calls`)}const i=H(o.url,v);M=i.hostname,b=X(i.pathname);const y=e.filter(l=>l.matchers.some(j=>j.test(i.hostname))),a=y.length===1?y[0]:void 0;E=a?.slug,S=ne(o.headers,a?.secret,r,m);const p=new AbortController;L=setTimeout(()=>p.abort(),c);const d=await s(i,{method:g,headers:S,body:o.body,redirect:"manual",signal:p.signal,dispatcher:u});R=d.status,d.status===401&&a&&n&&n({api:a.slug,name:a.name});const _=await oe(d,h);let w=ae(d.headers);if(ee(d.status)){w=x(w,D);const{location:l}=w;l&&!te(l,i,v)&&delete w.location}return O({host:i.hostname,method:g,outcome:"success",durationMs:Date.now()-T,path:b,api:E,status:d.status,bytes:Buffer.byteLength(_,"utf8")}),{status:d.status,statusText:d.statusText,ok:d.ok,headers:w,bodyText:_}}catch(i){const{outcome:y,userSafe:a}=Z(i),p=M??(a instanceof $?a.host:void 0)??q(o.url)??"invalid-url";throw O({host:p,method:g,outcome:y,durationMs:Date.now()-T,path:b,api:E,status:R}),a||(C.error(`Gateway MCP fetch failed [${g} ${p}]: ${V(re(i),N)} headers=${JSON.stringify(x(S,D))}`),new K("Upstream fetch failed due to an internal error"))}finally{L!==void 0&&clearTimeout(L)}}}function Q(t){let e=t;for(let r=0;r<5&&e instanceof Error;r++){if(e instanceof A||e instanceof U)return e;e=e.cause}}function Z(t){const e=Q(t);return{outcome:e instanceof $||e instanceof U?"blocked":e?"user_error":"system_error",userSafe:e}}function q(t){try{return new URL(t).hostname||void 0}catch{return}}function ee(t){return t>=300&&t<400}function te(t,e,r){try{return!!H(new URL(t,e).href,r)}catch{return!1}}function re(t){if(!(t instanceof Error))return String(t);const e=t.cause;return e instanceof Error?`${t.message}: ${e.message}`:t.message}async function oe(t,e){const r=Number(t.headers.get("content-length"));if(Number.isFinite(r)&&r>e)throw B(e,r);if(!t.body)return"";const n=t.body.getReader(),s=new TextDecoder;let u=0,c="";try{for(;;){const{done:h,value:f}=await n.read();if(h)break;if(u+=f.byteLength,u>e)throw B(e,u);c+=s.decode(f,{stream:!0})}return c+s.decode()}finally{await n.cancel().catch(()=>{})}}function B(t,e){return new A(`Response is too large (over ${t} bytes, got ${e}); request less data`)}function ne(t,e,r,n){const s={},u=new Set;for(const[h,f]of Object.entries(t??{})){const m=h.toLowerCase();m==="host"||m==="content-length"||m!==G&&(u.add(m),s[h]=f)}n&&(s[G]=n);const c=e??(r?{header:"Authorization",value:r}:void 0);return c&&!u.has(c.header.toLowerCase())&&(s[c.header]=c.value),s}function ae(t){const e={};return t.forEach((r,n)=>{e[n.toLowerCase()]=r}),e}export{we as buildFetchBridge,I as getDefaultAgent,oe as readCappedBody};
@@ -0,0 +1,11 @@
1
+ export declare class GatewayFetchUserError extends Error {
2
+ constructor(message: string);
3
+ }
4
+ export declare class GatewayFetchBlockedError extends GatewayFetchUserError {
5
+ readonly host?: string;
6
+ constructor(message: string, host?: string);
7
+ }
8
+ export declare class GatewayFetchSystemError extends Error {
9
+ constructor(message: string);
10
+ }
11
+ //# sourceMappingURL=fetch-errors.d.ts.map
@@ -0,0 +1 @@
1
+ class s extends Error{constructor(r){super(r),this.name="GatewayFetchUserError"}}class o extends s{host;constructor(r,t){super(r),this.name="GatewayFetchBlockedError",this.host=t}}class a extends Error{constructor(r){super(r),this.name="GatewayFetchSystemError"}}export{o as GatewayFetchBlockedError,a as GatewayFetchSystemError,s as GatewayFetchUserError};
@@ -0,0 +1,14 @@
1
+ export type GatewayFetchOutcome = 'success' | 'blocked' | 'user_error' | 'system_error';
2
+ type GatewayFetchEvent = {
3
+ host: string;
4
+ method: string;
5
+ outcome: GatewayFetchOutcome;
6
+ durationMs: number;
7
+ path?: string;
8
+ api?: string;
9
+ status?: number;
10
+ bytes?: number;
11
+ };
12
+ export declare function reportGatewayFetch({ host, method, outcome, durationMs, path, api, status, bytes, }: GatewayFetchEvent): void;
13
+ export {};
14
+ //# sourceMappingURL=fetch-telemetry.d.ts.map
@@ -0,0 +1 @@
1
+ import{telemetry as m}from"../../../../telemetry/index.js";import{logger as c}from"../../../../tools/notifiers/logger.js";import{McpServerType as u}from"../../constants.js";import{serverAttributes as $}from"../../utils/telemetry-attributes.js";function g({host:f,method:i,outcome:o,durationMs:t,path:e,api:r,status:n,bytes:d}){try{m.sendMcpGatewayFetchPerformedMessage([{...$(u.Docs),host:f,method:i,outcome:o,...e!==void 0&&{path:e},...r!==void 0&&{api:r},...n!==void 0&&{status:n},...d!==void 0&&{bytes:d},duration_ms:t}])}catch{}c.info(`Gateway MCP fetch [${i} ${f}] outcome=${o}`+(e!==void 0?` path=${e}`:"")+(r!==void 0?` api=${r}`:"")+(n!==void 0?` status=${n}`:"")+(d!==void 0?` bytes=${d}`:"")+` durationMs=${t}`)}export{g as reportGatewayFetch};
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Reduce a request path to something safe to report: no query string (it carries tokens), no
3
+ * identifiers (they explode cardinality and can be customer data), bounded length.
4
+ */
5
+ export declare function normalizeFetchPath(pathname: string): string;
6
+ //# sourceMappingURL=normalize-path.d.ts.map
@@ -0,0 +1 @@
1
+ const A=200,a=12,c=/^\d+$/,i=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,E=/^[0-9a-f]{16,}$/i,_=/^[a-z]{2,6}_[A-Za-z0-9]{8,}$/,f=/^(?=.*\d)[A-Za-z0-9._~-]{20,}$/;function r(t){return t&&(c.test(t)||i.test(t)||E.test(t)||_.test(t)||f.test(t)?"{id}":t)}function M(t){if(!t||t==="/")return"/";const o=t.split("/"),s=o.slice(0,13).map(r);o.length>13&&s.push("...");const n=s.join("/")||"/";return n.length>200?`${n.slice(0,200)}...`:n}export{M as normalizeFetchPath};
@@ -0,0 +1,4 @@
1
+ export declare const REDACTED = "\u00AB[redacted]\u00BB";
2
+ export declare function redactSecretsFromString(text: string, secretValues: readonly string[]): string;
3
+ export declare function redactHeaders(headers: Record<string, string>, extraSensitiveNames?: readonly string[]): Record<string, string>;
4
+ //# sourceMappingURL=redact.d.ts.map
@@ -0,0 +1 @@
1
+ const s="\xAB[redacted]\xBB",c=["authorization","proxy-authorization","cookie","set-cookie"];function a(r,n){let t=r;for(const e of n)e.trim()&&(t=t.split(e).join(s));return t}function u(r,n=[]){const t=new Set([...c,...n].map(o=>o.toLowerCase())),e={};for(const[o,i]of Object.entries(r))e[o]=t.has(o.toLowerCase())?s:i;return e}export{s as REDACTED,u as redactHeaders,a as redactSecretsFromString};
@@ -0,0 +1,22 @@
1
+ export declare class SsrfBlockedError extends Error {
2
+ code: string;
3
+ constructor(message: string);
4
+ }
5
+ /**
6
+ * If `ip` is an IPv4-mapped IPv6 address (`::ffff:0:0/96`), returns the
7
+ * embedded IPv4 in dotted form. Otherwise returns undefined.
8
+ *
9
+ * Examples:
10
+ * - `::ffff:1.2.3.4` -> `'1.2.3.4'`
11
+ * - `::ffff:a9fe:a9fe` -> `'169.254.169.254'`
12
+ * - `::1` -> `undefined`
13
+ */
14
+ export declare function extractMappedIpv4(ip: string): string | undefined;
15
+ /**
16
+ * True if `ip` (a literal IPv4/IPv6 string) is in a range unsafe to reach. Non-IP input is
17
+ * treated as blocked (fail closed). Handles IPv4-mapped IPv6 by checking the embedded IPv4.
18
+ */
19
+ export declare function isBlockedIp(ip: string): boolean;
20
+ /** True if `ip` (a literal IPv4/IPv6 string) is a loopback address. Non-IP input returns false. */
21
+ export declare function isLoopback(ip: string): boolean;
22
+ //# sourceMappingURL=ssrf-blocklist.d.ts.map
@@ -0,0 +1 @@
1
+ import{BlockList as c,isIP as o}from"node:net";class g extends Error{code="SSRF_BLOCKED";constructor(t){super(t),this.name="SsrfBlockedError"}}const m=[["0.0.0.0",8],["10.0.0.0",8],["100.64.0.0",10],["127.0.0.0",8],["169.254.0.0",16],["172.16.0.0",12],["192.0.0.0",24],["192.0.2.0",24],["192.168.0.0",16],["198.18.0.0",15],["198.51.100.0",24],["203.0.113.0",24],["224.0.0.0",4],["240.0.0.0",4],["255.255.255.255",32]],S=[["::",128],["::1",128],["64:ff9b::",96],["64:ff9b:1::",48],["100::",64],["2001::",32],["2001:db8::",32],["2002::",16],["fc00::",7],["fe80::",10],["fec0::",10],["ff00::",8]],d=(()=>{const r=new c;for(const[t,e]of m)r.addSubnet(t,e,"ipv4");for(const[t,e]of S)r.addSubnet(t,e,"ipv6");return r})(),p=(()=>{const r=new c;return r.addSubnet("127.0.0.0",8,"ipv4"),r.addAddress("::1","ipv6"),r})();function u(r){if(o(r)!==6)return;const t=v(r);if(!(t.length===8&&t[0]===0&&t[1]===0&&t[2]===0&&t[3]===0&&t[4]===0&&t[5]===65535))return;const n=t[6]??0,f=t[7]??0;return[n>>8&255,n&255,f>>8&255,f&255].join(".")}function v(r){const e=r.replace(/:(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/,(i,a,l,x,h)=>`:${((+a&255)<<8|+l&255).toString(16)}:${((+x&255)<<8|+h&255).toString(16)}`).split("::");if(e.length>2)return[];const n=e[0]?e[0].split(":"):[],f=e[1]?e[1].split(":"):[],s=e.length===2?8-n.length-f.length:0;return s<0?[]:[...n,...Array(s).fill("0"),...f].map(i=>Number.parseInt(i,16))}function B(r){const t=o(r);if(t===0||d.check(r,t===4?"ipv4":"ipv6"))return!0;if(t===6){const e=u(r);if(e&&d.check(e,"ipv4"))return!0}return!1}function _(r){const t=o(r);if(t===0)return!1;if(p.check(r,t===4?"ipv4":"ipv6"))return!0;if(t===6){const e=u(r);if(e&&p.check(e,"ipv4"))return!0}return!1}export{g as SsrfBlockedError,u as extractMappedIpv4,B as isBlockedIp,_ as isLoopback};
@@ -4,6 +4,6 @@
4
4
  * Returns the parsed URL on success; throws with a clear message otherwise.
5
5
  */
6
6
  export declare function assertUrlAllowed(rawUrl: string, matchers: readonly RegExp[]): URL;
7
- /** True for loopback, private, link-local, unspecified, or otherwise internal addresses. */
7
+ /** True for localhost or any literal IP in a blocked (private/reserved/loopback/link-local/…) range. */
8
8
  export declare function isBlockedAddress(host: string): boolean;
9
9
  //# sourceMappingURL=ssrf-guard.d.ts.map
@@ -1 +1 @@
1
- import{isHostAllowed as f}from"./allowed-hosts.js";function c(e,r){let t;try{t=new URL(e)}catch{throw new Error(`Invalid URL: ${e}`)}if(t.protocol!=="http:"&&t.protocol!=="https:")throw new Error(`Only http(s) URLs are allowed, got ${t.protocol}`);const n=o(t.hostname);if(u(n)||!f(n,r))throw new Error(`Host "${n}" is not allowed`);return t}function u(e){const r=o(e.toLowerCase());return r==="localhost"||r.endsWith(".localhost")?!0:i(r)?s(r):r.includes(":")?l(r):!1}function o(e){return e.replace(/^\[|\]$/g,"")}function i(e){return/^\d{1,3}(\.\d{1,3}){3}$/.test(e)}function s(e){const[r,t]=e.split(".").map(Number);return r===0||r===10||r===127||r===169&&t===254||r===172&&t>=16&&t<=31||r===192&&t===168||r===100&&t>=64&&t<=127}function l(e){if(e==="::1"||e==="::")return!0;const r=e.match(/::ffff:(\d{1,3}(?:\.\d{1,3}){3})$/);if(r)return s(r[1]);const t=parseInt(e.split(":")[0],16);return Number.isNaN(t)?!1:t>=65152&&t<=65215||t>=64512&&t<=65023}export{c as assertUrlAllowed,u as isBlockedAddress};
1
+ import{isIP as l}from"node:net";import{isHostAllowed as i}from"./allowed-hosts.js";import{isBlockedIp as a}from"./ssrf-blocklist.js";import{GatewayFetchBlockedError as c,GatewayFetchUserError as s}from"./fetch-errors.js";function m(o,r){let t;try{t=new URL(o)}catch{throw new s(`Invalid URL: ${o}`)}if(t.protocol!=="http:"&&t.protocol!=="https:")throw new s(`Only http(s) URLs are allowed, got ${t.protocol}`);if(t.username||t.password)throw new s("URLs must not contain embedded credentials");const e=n(t.hostname);if(d(e)||!i(e,r))throw new c(`Host "${e}" is not allowed`,e);return t}function d(o){const r=n(o.toLowerCase()).split("%")[0];return r==="localhost"||r.endsWith(".localhost")?!0:l(r)!==0?a(r):!1}function n(o){return o.replace(/^\[|\]$/g,"")}export{m as assertUrlAllowed,d as isBlockedAddress};
@@ -0,0 +1,13 @@
1
+ import { type LookupFunction } from 'node:net';
2
+ /**
3
+ * Returns a drop-in replacement for `dns.lookup` that errors with
4
+ * {@link SsrfBlockedError} if any resolved address is in the blocklist.
5
+ *
6
+ * Install on an http/https agent (`connect.lookup` for undici, or `lookup` for a node:https Agent)
7
+ * so that every socket connection — including those made while following redirects — is re-validated
8
+ * against the blocklist at connect time.
9
+ */
10
+ export declare function createSsrfSafeLookup({ allowLoopback, }?: {
11
+ allowLoopback?: boolean;
12
+ }): LookupFunction;
13
+ //# sourceMappingURL=ssrf-safe-lookup.d.ts.map
@@ -0,0 +1 @@
1
+ import{lookup as c}from"node:dns";import{isIP as k}from"node:net";import{isBlockedIp as v,isLoopback as w,SsrfBlockedError as n}from"./ssrf-blocklist.js";function L({allowLoopback:p=!1}={}){const f=o=>v(o)&&!(p&&w(o));return(o,m,r)=>{const s=m,l=t=>{if(s.all){r(null,t);return}const[e]=t;if(!e){r(new n(`Hostname "${o}" did not resolve`),"",0);return}r(null,e.address,e.family)},u=k(o);if(u!==0){if(f(o)){r(new n(`Hostname "${o}" is a blocked address`),"",0);return}l([{address:o,family:u}]);return}c(o,{...s,all:!0},(t,e)=>{if(t){r(t,"",0);return}const d=e.filter(({address:i})=>f(i));if(d.length>0){const i=d.map(({address:$})=>$).join(", ");r(new n(`Hostname "${o}" resolves to a blocked address: ${i}`),"",0);return}if(!e.length){r(new n(`Hostname "${o}" did not resolve`),"",0);return}l(e)})}}export{L as createSsrfSafeLookup};
@@ -1,6 +1,13 @@
1
1
  import type { ApiDescriptionInfo, McpToolContext } from '../types.js';
2
2
  import type { SandboxFetch } from '../codemode/types.js';
3
+ import type { UpstreamAuthRequiredEvent } from './upstream-auth.js';
3
4
  export declare function getCallableApis(context: McpToolContext): ApiDescriptionInfo[];
5
+ /**
6
+ * Fetch capability at request/worker time is derived purely from the build-time stamps:
7
+ * `fetchEligible` is stamped per API by the lifecycle plugin under `isGatewayCapabilityEnabled`
8
+ * (entitlement + hide checks), and the map arriving here is already RBAC-filtered.
9
+ * No EntitlementsProvider read — this code runs in graphs where the provider is uninitialized.
10
+ */
4
11
  export declare function isFetchCapable(context: McpToolContext): boolean;
5
- export declare function buildExecuteHostFetch(context: McpToolContext): SandboxFetch;
12
+ export declare function buildExecuteHostFetch(context: McpToolContext, onAuthRequired?: (event: UpstreamAuthRequiredEvent) => void): SandboxFetch;
6
13
  //# sourceMappingURL=fetch-capability.d.ts.map
@@ -1 +1 @@
1
- import{isGatewayCapabilityEnabled as a}from"./eligibility.js";import{buildAllowedHostMatchers as l}from"./fetch/allowed-hosts.js";import{buildFetchBridge as s}from"./fetch/fetch-bridge.js";function i(t){return Object.values(t.apiDescriptionsMap??{}).filter(e=>e.fetchEligible)}function u(t){const e=t.config?.mcp;return a(e)&&i(t).length>0}function f(t){const e=t.config?.mcp,o=i(t).flatMap(r=>r.servers??[]);return s({allowedHosts:l(o,e?.gateway?.allowedHosts),authorization:t.upstreamAuthorization})}export{f as buildExecuteHostFetch,i as getCallableApis,u as isFetchCapable};
1
+ import{buildAllowedHostMatchers as a}from"./fetch/allowed-hosts.js";import{buildFetchBridge as s}from"./fetch/fetch-bridge.js";function i(e){return Object.values(e.apiDescriptionsMap??{}).filter(r=>r.fetchEligible)}function u(e){return i(e).length>0}function n(e,r){const l=i(e).map(t=>({slug:t.relativePath,name:t.name,matchers:a(t.servers??[]),secret:e.upstreamSecrets?.[t.relativePath]}));return s({allowedHosts:a([]),apis:l,authorization:e.upstreamAuthorization,onAuthRequired:r,maxFetchesPerExec:e.gatewayFetchBudgetPerExec,clientIp:e.clientIp})}export{n as buildExecuteHostFetch,i as getCallableApis,u as isFetchCapable};
@@ -0,0 +1,3 @@
1
+ import type { Store } from '../../../../store.js';
2
+ export declare function applyEdgeRateLimit(request: Request, store: Store): Promise<Response | undefined>;
3
+ //# sourceMappingURL=apply-edge-rate-limit.d.ts.map
@@ -0,0 +1 @@
1
+ import{envConfig as o}from"../../../../config/env-config.js";import{KvRepository as s}from"../../../../persistence/kv/repositories/kv-repository.js";import{logger as m}from"../../../../tools/notifiers/logger.js";import{ipRateLimitKey as p}from"./ip-key.js";import{checkEdgeRateLimit as c}from"./edge-limiter.js";import{resolveGatewayFetchLimits as d}from"./limits.js";import{reportMcpRateLimited as f}from"./rate-limit-telemetry.js";async function S(n,a){const i=p(n);if(!i)return;let e,t;try{const r=await s.create({baseDbDir:a.serverOutDir,sqldRemoteDatabaseUrl:o.SQLD_REMOTE_DATABASE_URL,sqldRemoteDatabaseAuthToken:o.SQLD_REMOTE_DATABASE_AUTH_TOKEN});t=d(),e=await c({kv:r,ip:i,limits:t,now:Date.now()})}catch(r){m.warn(`gateway rate-limit init error, failing open: ${String(r)}`);return}if(!e.allowed)return f({scope:e.scope,retryAfterSeconds:e.retryAfterSeconds,limit:e.scope==="rate"?t.ratePerMin:t.quotaPerDay}),new Response(JSON.stringify({jsonrpc:"2.0",error:{code:-32029,message:`Rate limit exceeded (${e.scope}); retry after ${e.retryAfterSeconds}s`},id:null}),{status:429,headers:{"Content-Type":"application/json","Retry-After":String(e.retryAfterSeconds)}})}export{S as applyEdgeRateLimit};
@@ -0,0 +1,16 @@
1
+ import type { KvRepository } from '../../../../persistence/kv/repositories/kv-repository.js';
2
+ import type { GatewayFetchLimits } from './limits.js';
3
+ export type EdgeDecision = {
4
+ allowed: true;
5
+ } | {
6
+ allowed: false;
7
+ retryAfterSeconds: number;
8
+ scope: 'rate' | 'quota';
9
+ };
10
+ export declare function checkEdgeRateLimit(params: {
11
+ kv: KvRepository;
12
+ ip: string;
13
+ limits: GatewayFetchLimits;
14
+ now: number;
15
+ }): Promise<EdgeDecision>;
16
+ //# sourceMappingURL=edge-limiter.d.ts.map
@@ -0,0 +1 @@
1
+ import{checkAndIncrement as c}from"./window-counter.js";const s=60,d=86400;async function w(i){const{kv:e,ip:t,limits:o,now:r}=i;await e.sync();const n=await c({kv:e,ip:t,windowSeconds:s,limit:o.ratePerMin,now:r});if(!n.allowed)return{allowed:!1,retryAfterSeconds:n.retryAfterSeconds,scope:"rate"};const a=await c({kv:e,ip:t,windowSeconds:d,limit:o.quotaPerDay,now:r});return a.allowed?{allowed:!0}:{allowed:!1,retryAfterSeconds:a.retryAfterSeconds,scope:"quota"}}export{w as checkEdgeRateLimit};
@@ -0,0 +1,2 @@
1
+ export declare function ipRateLimitKey(req: Request): string | undefined;
2
+ //# sourceMappingURL=ip-key.d.ts.map
@@ -0,0 +1 @@
1
+ import{isIP as l}from"node:net";import{getFeedbackClientIp as a}from"../../../../web-server/utils/feedback-ip.js";import{extractMappedIpv4 as c}from"../fetch/ssrf-blocklist.js";function I(t){const n=a(t);if(n)return f(n)}function f(t){if(l(t)===6){const n=c(t);return n||`${u(t)}::/64`}return t}function u(t){const n=t.split("%")[0],[e,i=""]=n.split("::"),r=e?e.split(":"):[],o=i?i.split(":"):[],s=8-r.length-o.length;return[...r,...Array(Math.max(0,s)).fill("0"),...o].slice(0,4).map(p=>parseInt(p||"0",16).toString(16)).join(":")}export{I as ipRateLimitKey};
@@ -0,0 +1,7 @@
1
+ export type GatewayFetchLimits = {
2
+ ratePerMin: number;
3
+ quotaPerDay: number;
4
+ budgetPerExec: number;
5
+ };
6
+ export declare function resolveGatewayFetchLimits(): GatewayFetchLimits;
7
+ //# sourceMappingURL=limits.d.ts.map
@@ -0,0 +1 @@
1
+ import{EntitlementsProvider as u}from"../../../../entitlements/entitlements-provider.js";import{FEATURE as r,GATEWAY_FETCH_LIMIT_DEFAULTS as a}from"../../../../../constants/common.js";function n(e,i,o){const t=e.entitlements?.[i];return typeof t=="number"&&Number.isFinite(t)?t:o}function P(){const e=u.instance();return{ratePerMin:n(e,r.gatewayFetchRatePerMin,a.ratePerMin),quotaPerDay:n(e,r.gatewayFetchQuotaPerDay,a.quotaPerDay),budgetPerExec:n(e,r.gatewayFetchBudgetPerExec,a.budgetPerExec)}}export{P as resolveGatewayFetchLimits};
@@ -0,0 +1,8 @@
1
+ type RateLimitedEvent = {
2
+ scope: 'rate' | 'quota';
3
+ retryAfterSeconds: number;
4
+ limit: number;
5
+ };
6
+ export declare function reportMcpRateLimited({ scope, retryAfterSeconds, limit }: RateLimitedEvent): void;
7
+ export {};
8
+ //# sourceMappingURL=rate-limit-telemetry.d.ts.map
@@ -0,0 +1 @@
1
+ import{telemetry as o}from"../../../../telemetry/index.js";import{logger as i}from"../../../../tools/notifiers/logger.js";import{McpServerType as m}from"../../constants.js";import{serverAttributes as p}from"../../utils/telemetry-attributes.js";function d({scope:e,retryAfterSeconds:r,limit:t}){try{o.sendMcpRateLimitedMessage([{...p(m.Docs),scope:e,retry_after_seconds:r,limit:t}])}catch{}i.warn(`Gateway MCP rate limited [scope=${e}] retryAfterSeconds=${r} limit=${t}`)}export{d as reportMcpRateLimited};
@@ -0,0 +1,15 @@
1
+ import type { KvRepository } from '../../../../persistence/kv/repositories/kv-repository.js';
2
+ export type WindowCheck = {
3
+ allowed: false;
4
+ retryAfterSeconds: number;
5
+ } | {
6
+ allowed: true;
7
+ };
8
+ export declare function checkAndIncrement(params: {
9
+ kv: KvRepository;
10
+ ip: string;
11
+ windowSeconds: number;
12
+ limit: number;
13
+ now: number;
14
+ }): Promise<WindowCheck>;
15
+ //# sourceMappingURL=window-counter.d.ts.map
@@ -0,0 +1 @@
1
+ import{logger as g}from"../../../../tools/notifiers/logger.js";function u(e,t,o){return["mcp","gateway-fetch-rl",e,String(t),String(o)]}async function S(e){const{kv:t,ip:o,windowSeconds:n,limit:w,now:l}=e,r=Math.floor(l/1e3),c=Math.floor(r/n),i=u(o,n,c);try{const s=(await t.get(i))?.count??0;if(s>=w){const d=(c+1)*n-r;return{allowed:!1,retryAfterSeconds:Math.max(1,d)}}return await t.set(i,{count:s+1},{ttlInSeconds:n}),{allowed:!0}}catch(a){return g.warn(`gateway rate-limit store error, failing open: ${String(a)}`),{allowed:!0}}}export{S as checkAndIncrement};
@@ -0,0 +1,24 @@
1
+ import type { KvService } from '@redocly/config';
2
+ import type { UpstreamAuthScheme } from './upstream-auth-scheme.js';
3
+ export declare const ELICITATION_TTL_MS: number;
4
+ export type StoredSecret = {
5
+ header: string;
6
+ value: string;
7
+ };
8
+ export type ElicitationTarget = {
9
+ subject: string;
10
+ api: string;
11
+ name: string;
12
+ auth: UpstreamAuthScheme;
13
+ };
14
+ export declare class SecretStore {
15
+ #private;
16
+ setSecret(kv: KvService, subject: string, api: string, secret: StoredSecret): Promise<void>;
17
+ getSecretsForSubject(kv: KvService, subject: string): Promise<Record<string, StoredSecret>>;
18
+ deleteSubject(kv: KvService, subject: string): Promise<void>;
19
+ createElicitation(kv: KvService, target: ElicitationTarget): Promise<string>;
20
+ peekElicitation(kv: KvService, token: string): Promise<ElicitationTarget | undefined>;
21
+ consumeElicitation(kv: KvService, token: string): Promise<ElicitationTarget | undefined>;
22
+ }
23
+ export declare const secretStore: SecretStore;
24
+ //# sourceMappingURL=secret-store.d.ts.map
@@ -0,0 +1 @@
1
+ import{createCipheriv as o,createDecipheriv as f,createHash as u,hkdfSync as a,randomBytes as h,randomUUID as m}from"node:crypto";import{JWT_SECRET_KEY as c}from"../../../constants/common.js";import{secretTtlSeconds as l}from"./subject.js";const p=900*1e3,d="mcp-upstream-secrets",y="mcp-elicitation",S="mcp-elicitation";class g{async setSecret(t,e,r,n){const i={api:r,...this.#c(this.#a(e),n,r)};await t.set(this.#n(e,r),i,{ttlInSeconds:l(e)})}async getSecretsForSubject(t,e){const r=this.#a(e),{items:n}=await t.list({prefix:this.#i(e)}),i={};for(const s of n)if(s.value)try{i[s.value.api]=this.#r(r,s.value,s.value.api)}catch{continue}return i}async deleteSubject(t,e){const{items:r}=await t.list({prefix:this.#i(e)}),n=r.flatMap(i=>i.value?[this.#n(e,i.value.api)]:[]);n.length!==0&&await t.transaction(async i=>{for(const s of n)await i.delete(s)})}async createElicitation(t,e){const r=m();return await t.set(this.#t(r),this.#c(this.#e(),e),{ttlInSeconds:p/1e3}),r}async peekElicitation(t,e){const r=await t.get(this.#t(e));if(r)try{return this.#r(this.#e(),r)}catch{return}}async consumeElicitation(t,e){const r=this.#t(e),n=await t.transaction(async i=>{const s=await i.get(r);return s&&await i.delete(r),s});if(n)try{return this.#r(this.#e(),n)}catch{return}}#i(t){return["mcp","secret",this.#s(t)]}#n(t,e){return["mcp","secret",this.#s(t),e]}#t(t){return["mcp","elicitation",t]}#s(t){return u("sha256").update(t).digest("hex")}#a(t){return Buffer.from(a("sha256",c,t,d,32))}#e(){return Buffer.from(a("sha256",c,S,y,32))}#c(t,e,r){const n=h(12),i=o("aes-256-gcm",t,n);r&&i.setAAD(Buffer.from(r,"utf8"));const s=Buffer.concat([i.update(JSON.stringify(e),"utf8"),i.final()]);return{iv:n.toString("base64"),tag:i.getAuthTag().toString("base64"),data:s.toString("base64")}}#r(t,e,r){const n=f("aes-256-gcm",t,Buffer.from(e.iv,"base64"));r&&n.setAAD(Buffer.from(r,"utf8")),n.setAuthTag(Buffer.from(e.tag,"base64"));const i=Buffer.concat([n.update(Buffer.from(e.data,"base64")),n.final()]).toString("utf8");return JSON.parse(i)}}const E=new g;export{p as ELICITATION_TTL_MS,g as SecretStore,E as secretStore};
@@ -0,0 +1,20 @@
1
+ import type { ApiFunctionsUser } from '@redocly/config';
2
+ export declare const ANONYMOUS_SUBJECT_PREFIX = "anon:";
3
+ export declare const USER_SUBJECT_PREFIX = "user:";
4
+ export declare const MISSING_SESSION_HANDLE_MESSAGE = "This API requires credentials and the caller is anonymous; call createAnonymousSession first, then retry with sessionHandle";
5
+ export declare const MALFORMED_SESSION_HANDLE_MESSAGE = "The sessionHandle is not a valid handle; call createAnonymousSession to obtain one";
6
+ export type SubjectResolution = {
7
+ kind: 'resolved';
8
+ subject: string;
9
+ } | {
10
+ kind: 'anonymous';
11
+ } | {
12
+ kind: 'invalid';
13
+ message: string;
14
+ };
15
+ export declare function createSessionHandle(): string;
16
+ export declare function isValidSessionHandle(value: string): boolean;
17
+ export declare function userSubject(user: ApiFunctionsUser | undefined): string | undefined;
18
+ export declare function resolveSecretSubject(user: ApiFunctionsUser | undefined, sessionHandle: string | undefined): SubjectResolution;
19
+ export declare function secretTtlSeconds(subject: string): number;
20
+ //# sourceMappingURL=subject.d.ts.map
@@ -0,0 +1 @@
1
+ import{randomBytes as r}from"node:crypto";const i=32,S=/^[A-Za-z0-9_-]{43}$/,c=1440*60,u=720*60*60,s="anon:",d="user:",f="This API requires credentials and the caller is anonymous; call createAnonymousSession first, then retry with sessionHandle",a="The sessionHandle is not a valid handle; call createAnonymousSession to obtain one";function N(){return r(i).toString("base64url")}function E(e){return S.test(e)}function l(e){if(!e?.isAuthenticated)return;const n=e.claims,o=(typeof n?.sub=="string"&&n.sub?n.sub:void 0)??(e.email||void 0);if(o)return`${d}${e.idpId??"local"}:${o}`}function A(e,n){const t=l(e);return t?{kind:"resolved",subject:t}:n===void 0?{kind:"anonymous"}:E(n)?{kind:"resolved",subject:`${s}${n}`}:{kind:"invalid",message:a}}function T(e){return e.startsWith(s)?c:u}export{s as ANONYMOUS_SUBJECT_PREFIX,a as MALFORMED_SESSION_HANDLE_MESSAGE,f as MISSING_SESSION_HANDLE_MESSAGE,d as USER_SUBJECT_PREFIX,N as createSessionHandle,E as isValidSessionHandle,A as resolveSecretSubject,T as secretTtlSeconds,l as userSubject};
@@ -0,0 +1,18 @@
1
+ import type { McpToolContext } from '../types.js';
2
+ import { getApiDescriptionFromFs } from '../docs-mcp/tools/openapi/utils.js';
3
+ export type UpstreamAuthScheme = {
4
+ kind: 'raw';
5
+ } | {
6
+ kind: 'bearer';
7
+ } | {
8
+ kind: 'apiKey';
9
+ header: string;
10
+ } | {
11
+ kind: 'oauth2ClientCredentials';
12
+ tokenUrl: string;
13
+ scopes: string[];
14
+ };
15
+ type SecuritySchemeLoader = typeof getApiDescriptionFromFs;
16
+ export declare function resolveUpstreamAuthScheme(context: McpToolContext, apiRelativePath: string, loadDescription?: SecuritySchemeLoader): Promise<UpstreamAuthScheme>;
17
+ export {};
18
+ //# sourceMappingURL=upstream-auth-scheme.d.ts.map
@@ -0,0 +1 @@
1
+ import{getApiDescriptionFromFs as o}from"../docs-mcp/tools/openapi/utils.js";const c={kind:"raw"};async function u(i,r,n=o){const s=Object.values(i.apiDescriptionsMap??{}).find(t=>t.relativePath===r);if(!s)return c;try{const t=await n({relativePath:s.relativePath,outdir:i.outdir||"",user:i.user,rbac:i.config?.access?.rbac||{},requiresLogin:!!i.config?.access?.requiresLogin});return a(t)}catch{return c}}function a(i){const r=Object.values(i?.components?.securitySchemes??{}).filter(l),n=r.find(e=>e.type==="oauth2"&&e.flows?.clientCredentials);if(n?.flows.clientCredentials){const e=n.flows.clientCredentials;return{kind:"oauth2ClientCredentials",tokenUrl:e.tokenUrl,scopes:Object.keys(e.scopes??{})}}if(r.find(e=>e.type==="http"&&e.scheme==="bearer"||e.type==="oauth2"))return{kind:"bearer"};const t=r.find(e=>e.type==="apiKey"&&e.in==="header");return t?{kind:"apiKey",header:t.name||"X-Api-Key"}:c}function l(i){return typeof i=="object"&&i!==null&&"type"in i}export{u as resolveUpstreamAuthScheme};
@@ -0,0 +1,10 @@
1
+ import type { CallToolResult } from '@modelcontextprotocol/server';
2
+ export declare const UPSTREAM_AUTH_REQUIRED_META = "com.redocly/upstream-auth-required";
3
+ export type UpstreamAuthRequiredEvent = {
4
+ api: string;
5
+ name: string;
6
+ };
7
+ export declare function withAuthRequiredMeta(result: CallToolResult, events: UpstreamAuthRequiredEvent[]): CallToolResult;
8
+ export declare function readAuthRequiredMeta(result: CallToolResult): UpstreamAuthRequiredEvent[];
9
+ export declare function stripAuthRequiredMeta(result: CallToolResult): CallToolResult;
10
+ //# sourceMappingURL=upstream-auth.d.ts.map
@@ -0,0 +1 @@
1
+ const n="com.redocly/upstream-auth-required";function i(e,a){const t=[...new Map(a.map(r=>[r.api,r])).values()];return t.length===0?e:{...e,_meta:{...e._meta,[n]:t}}}function o(e){const a=e._meta?.[n];return Array.isArray(a)?a.filter(t=>typeof t?.api=="string"&&typeof t?.name=="string"):[]}function p(e){if(!e._meta||!(n in e._meta))return e;const{[n]:a,...t}=e._meta,r={...e};return Object.keys(t).length>0?r._meta=t:delete r._meta,r}export{n as UPSTREAM_AUTH_REQUIRED_META,o as readAuthRequiredMeta,p as stripAuthRequiredMeta,i as withAuthRequiredMeta};
@@ -1 +1 @@
1
- import{toFetchResponse as E,toReqRes as k}from"fetch-to-node";import{logger as m}from"../../../tools/notifiers/logger.js";import{isObject as v}from"../../../../utils/guards/is-object.js";import{getAccessibleSkills as N}from"../../../utils/skills/get-accessible-skills.js";import{getSkillUrl as O}from"../../../utils/skills/get-skill-url.js";import{createDocsMcpServer as L}from"../servers/docs-server.js";import{filterApiDescriptionsByRbac as H,filterGraphqlDescriptionsByRbac as I}from"../utils.js";import{createMethodNotAllowedError as j,withErrorHandling as B}from"./errors.js";import{attachSseKeepalive as _}from"./sse-keepalive.js";import{constructInvalidTokenResponse as J,constructUnauthorizedResponse as P,handleMcpAuth as F,shouldHandleMcpAuth as G}from"../auth/auth-handlers.js";import{extractTokenFromAuthHeader as V}from"../utils/jwt.js";import{DEFAULT_DOCS_MCP_SERVER_NAME as $}from"../constants.js";const u="X-Redocly-AI-Metadata";function q(r){if(r)try{const e=JSON.parse(r);if(v(e))return e;m.warn(`Ignoring ${u} header: not a JSON object.`)}catch{m.warn(`Ignoring ${u} header: invalid JSON.`)}}const z=async(r,e,g)=>{const t=!!e?.config?.access?.requiresLogin,i=e?.config?.access?.rbac||{};let c;const f=r.headers.get("Authorization");if(G(t,i)){const{isAuthenticated:s,isTokenValid:p,currentUser:a,accessToken:d}=await F(r,e);if(!s)return P(new URL(r.url).origin);if(!p)return J();a&&(e.user=a),c=d}else f&&(c=V(f||"")??void 0);let n;return await B(async()=>{if(r.method==="GET")return new Response(JSON.stringify({error:"Method Not Allowed",message:`In order to use this MCP server, you need register it in your MCP Client (VS Code, Cursor, Claude Code, etc.) using that URL: ${r.url}`}),{status:405,headers:{"Content-Type":"application/json"}});if(r.method!=="POST")return j();const s=g,p=s?.props?.config?.apiDescriptionsMap||{},a=s?.props?.config?.graphqlDescriptions||[],d=s?.props?.config?.mcpDocsServerName||$,{config:{mcp:h={}}}=e,R=H(p,e.user,i,t),A=I(a,e.user,i,t),D=s?.props?.skillsBaseUrl||new URL(r.url).origin,M=N(s?.props?.skills||[],e.user,i,t).map(o=>({slug:o.slug,name:o.name,description:o.description,content:o.content,uri:O(D,o.slug)})),w=e.config.products?Object.values(e.config.products).map(o=>o?.name):[],y=h.docs?.name||d,S=q(r.headers.get(u)),T=s?.props?.tools||[];n=await L({name:y,tools:T,skills:M,context:{...e,accessToken:c,outdir:e.outdir||"",baseUrl:e.baseUrl||new URL(r.url).origin,apiDescriptionsMap:R,graphqlDescriptions:A,products:w,metadata:S}});const U=await r.json(),{req:C,res:l}=k(r),b=_(l);try{await n.transport.handleRequest(C,l,U)}catch(o){throw b.stop(),o}return E(l)},async()=>{n&&(await n.cleanup(),n=void 0)})};var ie=z;export{ie as default};
1
+ import{logger as g}from"../../../tools/notifiers/logger.js";import{getFeedbackClientIp as O}from"../../../web-server/utils/feedback-ip.js";import{GATEWAY_FETCH_LIMIT_DEFAULTS as v}from"../../../../constants/common.js";import{isObject as F}from"../../../../utils/guards/is-object.js";import{getAccessibleSkills as N}from"../../../utils/skills/get-accessible-skills.js";import{getSkillUrl as _}from"../../../utils/skills/get-skill-url.js";import{createDocsMcpServer as L}from"../servers/docs-server.js";import{filterApiDescriptionsByRbac as k,filterGraphqlDescriptionsByRbac as B}from"../utils.js";import{createMethodNotAllowedError as P,withErrorHandling as H}from"./errors.js";import{constructForbiddenResponse as j,constructInvalidTokenResponse as V,constructUnauthorizedResponse as G,handleMcpAuth as J,shouldHandleMcpAuth as $}from"../auth/auth-handlers.js";import{extractTokenFromAuthHeader as z}from"../utils/jwt.js";import{DEFAULT_DOCS_MCP_SERVER_NAME as K}from"../constants.js";import{canAccessFeature as Y}from"../../../utils/rbac.js";import{DEFAULT_ANONYMOUS_VISITOR_TEAM as W,RbacFeatures as X}from"../../../../constants/common.js";const u="X-Redocly-AI-Metadata";function Q(r){if(r)try{const e=JSON.parse(r);if(F(e))return e;g.warn(`Ignoring ${u} header: not a JSON object.`)}catch{g.warn(`Ignoring ${u} header: invalid JSON.`)}}const Z=async(r,e,s)=>{const i=!!e?.config?.access?.requiresLogin,t=e?.config?.access?.rbac||{},f=s?.props?.config?.mcpMode??"tools",h=s?.props?.config?.gatewayFetchBudgetPerExec??v.budgetPerExec;let p;const m=r.headers.get("Authorization");if($(i,t)){const{isAuthenticated:d,isTokenValid:o,currentUser:c,accessToken:l}=await J(r,e);if(!d)return G(new URL(r.url).origin);if(!o)return V();c&&(e.user=c),p=l}else m&&(p=z(m||"")??void 0);const A={isAuthenticated:!!e.user?.isAuthenticated,teams:e.user?.teams||[W],claims:e.user?.claims??{}};if(!Y(X.MCP,A,t,i))return j();let a;return await H(async()=>{const d=s?.props?.config?.elicitationEnabled??!1;if(r.method==="GET")return new Response(JSON.stringify({error:"Method Not Allowed",message:`In order to use this MCP server, you need to register it in your MCP Client (VS Code, Cursor, Claude Code, etc.) using this URL: ${r.url}`}),{status:405,headers:{"Content-Type":"application/json"}});if(r.method!=="POST")return P();const o=s,c=o?.props?.config?.apiDescriptionsMap||{},l=o?.props?.config?.graphqlDescriptions||[],M=o?.props?.config?.mcpDocsServerName||K,{config:{mcp:E={}}}=e,T=k(c,e.user,t,i),D=B(l,e.user,t,i),R=e.config.products?Object.values(e.config.products).map(n=>n?.name):[],w=E.docs?.name||M,S=Q(r.headers.get(u)),b=o?.props?.tools||[],y=o?.props?.skillsBaseUrl||new URL(r.url).origin,U=N(o?.props?.skills||[],e.user,t,i).map(n=>({slug:n.slug,name:n.name,description:n.description,content:n.content,uri:_(y,n.slug)})),C=await r.json(),I={name:w,tools:b,skills:U,context:{...e,accessToken:p,outdir:e.outdir||"",baseUrl:e.baseUrl||new URL(r.url).origin,apiDescriptionsMap:T,graphqlDescriptions:D,products:R,metadata:S,mcpMode:f,elicitationEnabled:d,gatewayFetchBudgetPerExec:h,clientIp:O(r)}};return a=await L({...I,getKv:e.getKv}),await q(r,a,C)},async()=>{a&&(await a.cleanup(),a=void 0)},f)};async function q(r,e,s){return e.transport.handleRequest(r,s!==void 0?{parsedBody:s}:void 0)}var me=Z;export{me as default};
@@ -1,4 +1,4 @@
1
- import type { McpErrorCodeTypes } from '../types.js';
1
+ import type { McpErrorCodeTypes, McpMode } from '../types.js';
2
2
  export type McpErrorData = {
3
3
  readonly code: McpErrorCodeTypes;
4
4
  readonly message: string;
@@ -13,8 +13,8 @@ export declare class McpError extends Error {
13
13
  createErrorResponse(): Response;
14
14
  }
15
15
  export declare function createMethodNotAllowedError(requestId?: string | number | null): Response;
16
- export declare function createInternalServerError(error: Error | string, requestId?: string | number | null): Response;
16
+ export declare function createInternalServerError(error: Error | string, requestId?: string | number | null, mode?: McpMode): Response;
17
17
  export declare function createInvalidRequestError(message?: string, requestId?: string | number | null): Response;
18
18
  export declare function createInvalidParamsError(message?: string, requestId?: string | number | null): Response;
19
- export declare function withErrorHandling<T>(operation: () => Promise<T>, cleanup?: () => Promise<void>): Promise<T | Response>;
19
+ export declare function withErrorHandling<T>(operation: () => Promise<T>, cleanup?: () => Promise<void>, mode?: McpMode): Promise<T | Response>;
20
20
  //# sourceMappingURL=errors.d.ts.map
@@ -1 +1 @@
1
- import{telemetry as d}from"../../../telemetry/index.js";import{McpErrorCodes as o,McpServerType as s}from"../constants.js";import{getMcpMode as i}from"../utils/mode.js";class n extends Error{code;data;requestId;constructor(e,t,a,c){super(t),this.name="McpError",this.code=e,this.data=a,this.requestId=c}createErrorResponse(){const e={jsonrpc:"2.0",error:{code:this.code,message:this.message,...this.data?{data:this.data}:{}},id:this.requestId??null},t=p(this.code);return new Response(JSON.stringify(e),{status:t,headers:{"Content-Type":"application/json"}})}}function p(r){switch(r){case o.InvalidRequest:case o.InvalidParams:return 400;case o.MethodNotFound:return 404;case o.ServerError:return 405;case o.InternalError:default:return 500}}function v(r){return new n(o.ServerError,"Method not allowed",void 0,r).createErrorResponse()}function u(r,e){const t=r instanceof Error?r.message:String(r),a=r instanceof Error?r.stack:void 0;return d.sendMcpErrorMessage([{id:s.Docs,object:"mcpServer",uri:`urn:redocly:realm:mcp:server:${s.Docs}`,server_type:s.Docs,message:t,stack:a||"",mode:i()}]),new n(o.InternalError,"Internal server error mcp",t,e).createErrorResponse()}function f(r="Invalid request",e){return new n(o.InvalidRequest,r,void 0,e).createErrorResponse()}function h(r="Invalid parameters",e){return new n(o.InvalidParams,r,void 0,e).createErrorResponse()}async function I(r,e){try{return await r()}catch(t){return d.sendMcpErrorMessage([{id:s.Docs,object:"mcpServer",uri:`urn:redocly:realm:mcp:server:${s.Docs}`,server_type:s.Docs,message:t?.message||"",stack:t?.stack||"",mode:i()}]),e&&e(),u(t)}}export{n as McpError,u as createInternalServerError,h as createInvalidParamsError,f as createInvalidRequestError,v as createMethodNotAllowedError,I as withErrorHandling};
1
+ import{telemetry as c}from"../../../telemetry/index.js";import{McpErrorCodes as s,McpServerType as d}from"../constants.js";import{serverAttributes as i}from"../utils/telemetry-attributes.js";class n extends Error{code;data;requestId;constructor(e,t,o,a){super(t),this.name="McpError",this.code=e,this.data=o,this.requestId=a}createErrorResponse(){const e={jsonrpc:"2.0",error:{code:this.code,message:this.message,...this.data?{data:this.data}:{}},id:this.requestId??null},t=u(this.code);return new Response(JSON.stringify(e),{status:t,headers:{"Content-Type":"application/json"}})}}function u(r){switch(r){case s.InvalidRequest:case s.InvalidParams:return 400;case s.MethodNotFound:return 404;case s.ServerError:return 405;case s.InternalError:default:return 500}}function h(r){return new n(s.ServerError,"Method not allowed",void 0,r).createErrorResponse()}function p(r,e,t="tools"){const o=r instanceof Error?r.message:String(r),a=r instanceof Error?r.stack:void 0;return c.sendMcpErrorMessage([{...i(d.Docs),message:o,stack:a||"",error_class:"server_error",mode:t}]),new n(s.InternalError,"Internal server error mcp",o,e).createErrorResponse()}function v(r="Invalid request",e){return new n(s.InvalidRequest,r,void 0,e).createErrorResponse()}function I(r="Invalid parameters",e){return new n(s.InvalidParams,r,void 0,e).createErrorResponse()}async function g(r,e,t="tools"){try{return await r()}catch(o){return c.sendMcpErrorMessage([{...i(d.Docs),message:o?.message||"",stack:o?.stack||"",error_class:"server_error",mode:t}]),e&&e(),p(o,void 0,t)}}export{n as McpError,p as createInternalServerError,I as createInvalidParamsError,v as createInvalidRequestError,h as createMethodNotAllowedError,g as withErrorHandling};
@@ -1 +1 @@
1
- import{withPathPrefix as f}from"@redocly/theme/core/utils";import{importApiRoutesHandler as g}from"../../../api-routes/import-api-routes-handlers.js";import{enhanceContext as h}from"../../../api-routes/helpers/enhance-context.js";import{telemetry as D}from"../../../telemetry/index.js";import{KvService as A}from"../../../persistence/kv/services/kv-service.js";import{envConfig as o}from"../../../config/env-config.js";import{acceptsHtml as T}from"../../../utils/ai-agent-detection.js";import{handleErrorPageRender as R}from"../../../web-server/utils.js";import{MCP_NOT_ALLOWED_TEMPLATE_ID as E}from"../constants.js";import{resolvePublicBaseUrl as w}from"../../../web-server/utils/resolve-public-base-url.js";async function C(i,t,e){const s=t.req.raw;if(s.method==="GET"&&T(s.headers.get("accept"))&&e.globalData.mcpData?.docs?.enabled)return R(t,e,{slug:i.slug},405,E);const r=t.get("auth"),n=await e.resolveRouteStaticData(i)||{},l=f(i.slug),{requestHandlers:c}=await g(e.serverOutDir),m=c[i.requestHandlerId],p=(await m()).default,u=async()=>await A.getInstance({baseDbDir:e.serverOutDir,sqldRemoteDatabaseUrl:o.SQLD_REMOTE_DATABASE_URL,sqldRemoteDatabaseAuthToken:o.SQLD_REMOTE_DATABASE_AUTH_TOKEN}),d=h({honoCtx:t,ctx:{user:{teams:r.teams,email:r.claims.email,claims:r.claims,idpAccessToken:r.idpAccessToken,idpId:r.claims.idpId,isAuthenticated:r.isAuthenticated},config:e.config,outdir:e.outdir,baseUrl:new URL(t.req.url).origin},telemetry:D,getKv:u}),a=await p(t.req.raw,d,{...n,props:{...n.props,routeSlug:l,outdir:e.outdir,skills:e.config.skills?.hide===!0?[]:e.getSkills(),skillsBaseUrl:w(e,t)}});return a instanceof Response?a:typeof a=="string"?new Response(a,{headers:{"Content-Type":"text/plain"}}):new Response(JSON.stringify(a),{headers:{"Content-Type":"application/json"}})}export{C as handleMcpRequest};
1
+ import{withPathPrefix as g}from"@redocly/theme/core/utils";import{importApiRoutesHandler as D}from"../../../api-routes/import-api-routes-handlers.js";import{enhanceContext as h}from"../../../api-routes/helpers/enhance-context.js";import{telemetry as R}from"../../../telemetry/index.js";import{KvService as A}from"../../../persistence/kv/services/kv-service.js";import{envConfig as l}from"../../../config/env-config.js";import{acceptsHtml as E}from"../../../utils/ai-agent-detection.js";import{handleErrorPageRender as T}from"../../../web-server/utils.js";import{MCP_NOT_ALLOWED_TEMPLATE_ID as _}from"../constants.js";import{MCP_DOCS_SERVER_HANDLER_ID as w}from"../index.js";import{resolvePublicBaseUrl as S}from"../../../web-server/utils/resolve-public-base-url.js";import{applyEdgeRateLimit as q}from"../gateway-mcp/rate-limit/apply-edge-rate-limit.js";async function B(a,t,e){const n=t.req.raw;if(a.requestHandlerId===w&&n.method==="GET"&&E(n.headers.get("accept"))&&e.globalData.mcpData?.docs?.enabled)return T(t,e,{slug:a.slug},405,_);const r=t.get("auth"),s=await q(n,e);if(s)return s;const o=await e.resolveRouteStaticData(a)||{},m=g(a.slug),{requestHandlers:c}=await D(e.serverOutDir),p=c[a.requestHandlerId],d=(await p()).default,u=async()=>await A.getInstance({baseDbDir:e.serverOutDir,sqldRemoteDatabaseUrl:l.SQLD_REMOTE_DATABASE_URL,sqldRemoteDatabaseAuthToken:l.SQLD_REMOTE_DATABASE_AUTH_TOKEN}),f=h({honoCtx:t,ctx:{user:{teams:r.teams,email:r.claims.email,claims:r.claims,idpAccessToken:r.idpAccessToken,idpId:r.claims.idpId,isAuthenticated:r.isAuthenticated},config:e.config,outdir:e.outdir,baseUrl:new URL(t.req.url).origin},telemetry:R,getKv:u}),i=await d(t.req.raw,f,{...o,props:{...o.props,routeSlug:m,outdir:e.outdir,skills:e.config.skills?.hide===!0?[]:e.getSkills(),skillsBaseUrl:S(e,t)}});return i instanceof Response?i:typeof i=="string"?new Response(i,{headers:{"Content-Type":"text/plain"}}):new Response(JSON.stringify(i),{headers:{"Content-Type":"application/json"}})}export{B as handleMcpRequest};
@@ -0,0 +1,5 @@
1
+ import type { ApiRoutesHandler } from '@redocly/config';
2
+ export declare function setCredentialsFetchImpl(impl: typeof fetch): void;
3
+ declare const mcpCredentialsHandler: ApiRoutesHandler;
4
+ export default mcpCredentialsHandler;
5
+ //# sourceMappingURL=mcp-credentials-handler.d.ts.map