@redocly/revel 0.138.0-next.7 → 0.138.0

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 (275) hide show
  1. package/CHANGELOG.md +288 -0
  2. package/dist/api-schemas/mcp-fetch-count.d.ts +24 -0
  3. package/dist/api-schemas/mcp-fetch-count.js +1 -0
  4. package/dist/bin.js +0 -0
  5. package/dist/cli/build/analytics/collect-analytics.js +1 -1
  6. package/dist/cli/build/analytics/collectors/get-processed-config-stats-usage.js +1 -1
  7. package/dist/cli/build/index.js +1 -1
  8. package/dist/cli/develop.js +1 -1
  9. package/dist/cli/eject/ejectTheme.js +1 -1
  10. package/dist/cli/translations/collect-config-translations.js +1 -1
  11. package/dist/client/App.js +1 -1
  12. package/dist/client/app/ReviewComments/ReviewComments.js +2 -2
  13. package/dist/client/app/l10n/hooks/useTranslationKeys.js +1 -1
  14. package/dist/client/app/markdoc/custom-components/openapi/openapi-example.js +1 -1
  15. package/dist/client/app/markdoc/custom-components/openapi/openapi-response-sample.js +1 -1
  16. package/dist/client/app/markdoc/custom-components/openapi/replay-openapi.js +1 -1
  17. package/dist/client/app/markdoc/hooks/use-store.d.ts +2 -3
  18. package/dist/client/app/pages/Invite/Invite.js +1 -1
  19. package/dist/client/app/search/useSearch.js +1 -1
  20. package/dist/client/app/utils/loadAndNavigate.js +1 -1
  21. package/dist/client/polyfills.js +1 -1
  22. package/dist/client/runtime/loader.js +1 -1
  23. package/dist/client/utils/catalog/parse-filter-query.js +1 -1
  24. package/dist/compiled/svgo/svgo-node.js +39 -39
  25. package/dist/constants/api.d.ts +1 -0
  26. package/dist/constants/api.js +1 -1
  27. package/dist/constants/common.d.ts +6 -0
  28. package/dist/constants/common.js +1 -1
  29. package/dist/constants/l10n/langs/ar.js +1 -1
  30. package/dist/constants/l10n/langs/de.js +1 -1
  31. package/dist/constants/l10n/langs/en.js +1 -1
  32. package/dist/constants/l10n/langs/es.js +1 -1
  33. package/dist/constants/l10n/langs/fr.js +1 -1
  34. package/dist/constants/l10n/langs/hi.js +1 -1
  35. package/dist/constants/l10n/langs/it.js +1 -1
  36. package/dist/constants/l10n/langs/ja.js +1 -1
  37. package/dist/constants/l10n/langs/ko.js +1 -1
  38. package/dist/constants/l10n/langs/pl.js +1 -1
  39. package/dist/constants/l10n/langs/pt-BR.js +1 -1
  40. package/dist/constants/l10n/langs/pt.js +1 -1
  41. package/dist/constants/l10n/langs/ru.js +1 -1
  42. package/dist/constants/l10n/langs/uk.js +1 -1
  43. package/dist/constants/l10n/langs/zh.js +1 -1
  44. package/dist/markdoc/helpers/get-inner-text.js +2 -2
  45. package/dist/markdoc/helpers/guards/is-prompt-node.d.ts +13 -0
  46. package/dist/markdoc/helpers/guards/is-prompt-node.js +1 -0
  47. package/dist/server/config/env-config.d.ts +0 -4
  48. package/dist/server/config/env-schema.d.ts +0 -10
  49. package/dist/server/config/env-schemas/feature-flags.d.ts +0 -8
  50. package/dist/server/config/env-schemas/feature-flags.js +1 -1
  51. package/dist/server/constants/entitlements.js +1 -1
  52. package/dist/server/entitlements/entitlements-provider.js +1 -1
  53. package/dist/server/esbuild/esbuild.js +3 -3
  54. package/dist/server/esbuild/plugins/on-rebuild.js +1 -1
  55. package/dist/server/esbuild/plugins/styled-components-ssr.js +1 -1
  56. package/dist/server/esbuild/plugins/yaml-loader.js +1 -1
  57. package/dist/server/fs/content-fs.js +1 -1
  58. package/dist/server/fs/utils/is-l10n-root-file.d.ts +3 -0
  59. package/dist/server/fs/utils/is-l10n-root-file.js +1 -0
  60. package/dist/server/plugins/analytics/amplitude/index.js +1 -1
  61. package/dist/server/plugins/analytics/heap/browser-hooks.js +1 -1
  62. package/dist/server/plugins/api-docs/index.js +1 -1
  63. package/dist/server/plugins/api-docs/loader.js +3 -3
  64. package/dist/server/plugins/api-docs/spec-download.api.js +1 -1
  65. package/dist/server/plugins/api-docs/utils/apply-nav-item-to-root.js +1 -1
  66. package/dist/server/plugins/api-docs/utils/decorators.d.ts +11 -0
  67. package/dist/server/plugins/api-docs/utils/decorators.js +1 -1
  68. package/dist/server/plugins/arazzo-docs/arazzo-doc-loader.js +2 -2
  69. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/openapi-entities-extractor.js +1 -1
  70. package/dist/server/plugins/catalog-entities/utils/extract-parts-from-channels-message-ref.js +1 -1
  71. package/dist/server/plugins/config-parser/format-custom-tags.js +1 -1
  72. package/dist/server/plugins/config-parser/loaders/content-slugs-loader.js +1 -1
  73. package/dist/server/plugins/config-parser/loaders/versions-config-loader.js +1 -1
  74. package/dist/server/plugins/config-parser/resolve-mutual-exclusion.js +1 -1
  75. package/dist/server/plugins/config-parser/safe-parse.js +1 -1
  76. package/dist/server/plugins/default-theme/resolve-logo.js +1 -1
  77. package/dist/server/plugins/dev-onboarding/api/adapters/apigee/adapter.js +2 -2
  78. package/dist/server/plugins/dev-onboarding/api/adapters/gravitee/client.js +2 -2
  79. package/dist/server/plugins/dev-onboarding/api/combine.js +1 -1
  80. package/dist/server/plugins/dev-onboarding/template/components/ApiKeyOverview.js +3 -3
  81. package/dist/server/plugins/dev-onboarding/template/components/AppOverview.js +1 -1
  82. package/dist/server/plugins/dev-onboarding/template/components/useSortableData.js +1 -1
  83. package/dist/server/plugins/markdown/attribute-resolvers/code-walkthrough/file-chunk-parser.d.ts +1 -1
  84. package/dist/server/plugins/markdown/attribute-resolvers/index.js +1 -1
  85. package/dist/server/plugins/markdown/attribute-resolvers/resolve-link.js +1 -1
  86. package/dist/server/plugins/markdown/attribute-resolvers/resolve-svg-content.js +1 -1
  87. package/dist/server/plugins/markdown/attribute-resolvers/resolve-tag-raw-content.d.ts +4 -0
  88. package/dist/server/plugins/markdown/attribute-resolvers/resolve-tag-raw-content.js +2 -0
  89. package/dist/server/plugins/markdown/compiler.js +1 -1
  90. package/dist/server/plugins/markdown/create-source-lines-reader.d.ts +7 -0
  91. package/dist/server/plugins/markdown/create-source-lines-reader.js +1 -0
  92. package/dist/server/plugins/markdown/html/normalize-html-headings.d.ts +9 -0
  93. package/dist/server/plugins/markdown/html/normalize-html-headings.js +1 -0
  94. package/dist/server/plugins/markdown/markdoc/markdoc-options.js +1 -1
  95. package/dist/server/plugins/markdown/markdoc/plugins/utils.d.ts +1 -1
  96. package/dist/server/plugins/markdown/markdoc/plugins/utils.js +1 -1
  97. package/dist/server/plugins/markdown/markdown-static-data-loader.js +1 -1
  98. package/dist/server/plugins/markdown/search/get-ai-search-documents.js +2 -2
  99. package/dist/server/plugins/markdown/search/search-resolver.js +1 -1
  100. package/dist/server/plugins/markdown/search/to-markdown.js +13 -13
  101. package/dist/server/plugins/markdown/search/walk-sections.d.ts +3 -1
  102. package/dist/server/plugins/markdown/search/walk-sections.js +3 -3
  103. package/dist/server/plugins/markdown/utils/sanitize-malformed-md-content.js +2 -2
  104. package/dist/server/plugins/mcp/audit/audit-log.d.ts +1 -1
  105. package/dist/server/plugins/mcp/audit/audit-log.js +1 -1
  106. package/dist/server/plugins/mcp/audit/code-credentials.d.ts +9 -0
  107. package/dist/server/plugins/mcp/audit/code-credentials.js +2 -0
  108. package/dist/server/plugins/mcp/codemode/capabilities/fetch/index.js +5 -5
  109. package/dist/server/plugins/mcp/codemode/capabilities/types.d.ts +3 -1
  110. package/dist/server/plugins/mcp/codemode/capabilities/utils.d.ts +2 -1
  111. package/dist/server/plugins/mcp/codemode/capabilities/utils.js +3 -3
  112. package/dist/server/plugins/mcp/codemode/code-audit.d.ts +4 -3
  113. package/dist/server/plugins/mcp/codemode/code-execution-audit.js +1 -1
  114. package/dist/server/plugins/mcp/custom-tools/scan-custom-tools.js +1 -1
  115. package/dist/server/plugins/mcp/docs-mcp/tool-schemas.js +1 -1
  116. package/dist/server/plugins/mcp/docs-mcp/tools/core/utils.js +1 -1
  117. package/dist/server/plugins/mcp/docs-mcp/tools/core/whoami.js +1 -1
  118. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/list-apis.js +1 -1
  119. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/utils.d.ts +12 -3
  120. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/utils.js +1 -1
  121. package/dist/server/plugins/mcp/docs-mcp/utils/resolve-refs.d.ts +2 -2
  122. package/dist/server/plugins/mcp/docs-mcp/utils/resolve-refs.js +1 -1
  123. package/dist/server/plugins/mcp/gateway-mcp/allowed-http-methods.d.ts +11 -0
  124. package/dist/server/plugins/mcp/gateway-mcp/allowed-http-methods.js +1 -0
  125. package/dist/server/plugins/mcp/gateway-mcp/api-call-operations.d.ts +32 -0
  126. package/dist/server/plugins/mcp/gateway-mcp/api-call-operations.js +1 -0
  127. package/dist/server/plugins/mcp/gateway-mcp/callable-apis.d.ts +7 -4
  128. package/dist/server/plugins/mcp/gateway-mcp/callable-apis.js +1 -1
  129. package/dist/server/plugins/mcp/gateway-mcp/caller-api-calls.d.ts +9 -0
  130. package/dist/server/plugins/mcp/gateway-mcp/caller-api-calls.js +1 -0
  131. package/dist/server/plugins/mcp/gateway-mcp/credential-validation.js +1 -1
  132. package/dist/server/plugins/mcp/gateway-mcp/elicitation.d.ts +1 -0
  133. package/dist/server/plugins/mcp/gateway-mcp/elicitation.js +5 -5
  134. package/dist/server/plugins/mcp/gateway-mcp/eligibility.d.ts +8 -4
  135. package/dist/server/plugins/mcp/gateway-mcp/eligibility.js +1 -1
  136. package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-audit.d.ts +2 -1
  137. package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-audit.js +1 -1
  138. package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-bridge.d.ts +11 -1
  139. package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-bridge.js +1 -1
  140. package/dist/server/plugins/mcp/gateway-mcp/fetch/redact.d.ts +11 -0
  141. package/dist/server/plugins/mcp/gateway-mcp/fetch/redact.js +1 -1
  142. package/dist/server/plugins/mcp/gateway-mcp/fetch-capability.js +1 -1
  143. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/fetch-limiter/fetch-count-client.d.ts +4 -0
  144. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/fetch-limiter/fetch-count-client.js +1 -0
  145. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/fetch-limiter/fetch-count-secret.d.ts +4 -0
  146. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/fetch-limiter/fetch-count-secret.js +1 -0
  147. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/fetch-limiter/fetch-count.d.ts +11 -0
  148. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/fetch-limiter/fetch-count.js +1 -0
  149. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/fetch-limiter/fetch-counter-repository.d.ts +13 -0
  150. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/fetch-limiter/fetch-counter-repository.js +13 -0
  151. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/{limits.d.ts → fetch-limiter/fetch-limits.d.ts} +1 -1
  152. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/fetch-limiter/fetch-limits.js +1 -0
  153. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/{apply-edge-rate-limit.d.ts → request-limiter/apply-edge-rate-limit.d.ts} +1 -1
  154. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/request-limiter/apply-edge-rate-limit.js +1 -0
  155. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/{edge-limiter.d.ts → request-limiter/edge-limiter.d.ts} +3 -3
  156. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/request-limiter/edge-limiter.js +1 -0
  157. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/request-limiter/rate-limit-telemetry.js +1 -0
  158. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/request-limiter/request-limits.d.ts +6 -0
  159. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/request-limiter/request-limits.js +1 -0
  160. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/utils/ip-key.js +1 -0
  161. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/{window-counter.d.ts → utils/window-counter.d.ts} +1 -1
  162. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/utils/window-counter.js +1 -0
  163. package/dist/server/plugins/mcp/gateway-mcp/route-pattern.d.ts +18 -0
  164. package/dist/server/plugins/mcp/gateway-mcp/route-pattern.js +1 -0
  165. package/dist/server/plugins/mcp/gateway-mcp/secret-store.d.ts +9 -3
  166. package/dist/server/plugins/mcp/gateway-mcp/secret-store.js +1 -1
  167. package/dist/server/plugins/mcp/gateway-mcp/subject.js +1 -1
  168. package/dist/server/plugins/mcp/gateway-mcp/upstream-auth-scheme.d.ts +2 -0
  169. package/dist/server/plugins/mcp/gateway-mcp/upstream-auth-scheme.js +2 -2
  170. package/dist/server/plugins/mcp/gateway-mcp/upstream-auth.d.ts +0 -2
  171. package/dist/server/plugins/mcp/gateway-mcp/upstream-auth.js +1 -1
  172. package/dist/server/plugins/mcp/handlers/credentials-page/constants.d.ts +7 -0
  173. package/dist/server/plugins/mcp/handlers/credentials-page/constants.js +1 -0
  174. package/dist/server/plugins/mcp/handlers/credentials-page/form-contract.d.ts +5 -0
  175. package/dist/server/plugins/mcp/handlers/credentials-page/form-contract.js +1 -0
  176. package/dist/server/plugins/mcp/handlers/credentials-page/form-page.d.ts +14 -0
  177. package/dist/server/plugins/mcp/handlers/credentials-page/form-page.js +62 -0
  178. package/dist/server/plugins/mcp/handlers/credentials-page/layout.d.ts +17 -0
  179. package/dist/server/plugins/mcp/handlers/credentials-page/layout.js +11 -0
  180. package/dist/server/plugins/mcp/handlers/credentials-page/outcome-pages.d.ts +10 -0
  181. package/dist/server/plugins/mcp/handlers/credentials-page/outcome-pages.js +11 -0
  182. package/dist/server/plugins/mcp/handlers/credentials-page/site-branding.d.ts +10 -0
  183. package/dist/server/plugins/mcp/handlers/credentials-page/site-branding.js +1 -0
  184. package/dist/server/plugins/mcp/handlers/credentials-page/styles.d.ts +4 -0
  185. package/dist/server/plugins/mcp/handlers/credentials-page/styles.js +186 -0
  186. package/dist/server/plugins/mcp/handlers/credentials-page/types.d.ts +32 -0
  187. package/dist/server/plugins/mcp/handlers/credentials-page/types.js +0 -0
  188. package/dist/server/plugins/mcp/handlers/docs-mcp-handler.js +1 -1
  189. package/dist/server/plugins/mcp/handlers/handle-mcp-request.js +1 -1
  190. package/dist/server/plugins/mcp/handlers/mcp-credentials-handler.d.ts +0 -1
  191. package/dist/server/plugins/mcp/handlers/mcp-credentials-handler.js +1 -1
  192. package/dist/server/plugins/mcp/index.js +1 -1
  193. package/dist/server/plugins/mcp/servers/docs-server.js +1 -1
  194. package/dist/server/plugins/mcp/servers/mcp-server.js +2 -2
  195. package/dist/server/plugins/mcp/types.d.ts +16 -1
  196. package/dist/server/plugins/mcp/utils/mode.d.ts +4 -1
  197. package/dist/server/plugins/mcp/utils/mode.js +1 -1
  198. package/dist/server/plugins/mcp/utils/xmcp-utils.d.ts +3 -5
  199. package/dist/server/plugins/mcp/utils/xmcp-utils.js +1 -1
  200. package/dist/server/plugins/nav-utils.js +1 -1
  201. package/dist/server/plugins/scorecard-classic/loaders/scorecard.js +1 -1
  202. package/dist/server/plugins/scorecard-classic/template/components.js +1 -1
  203. package/dist/server/plugins/scorecard-classic/template/useData.js +1 -1
  204. package/dist/server/plugins/scorecard-classic/template/views.js +1 -1
  205. package/dist/server/plugins/search/engines/flexsearch/index.js +2 -2
  206. package/dist/server/plugins/sidebars/index.js +2 -2
  207. package/dist/server/plugins/sidebars/tabs.js +1 -1
  208. package/dist/server/plugins/sidebars/utils.js +1 -1
  209. package/dist/server/providers/database/client.d.ts +5 -0
  210. package/dist/server/providers/database/client.js +1 -1
  211. package/dist/server/providers/database/copy-migrations.js +1 -1
  212. package/dist/server/providers/database/database-connections-manager.js +1 -1
  213. package/dist/server/providers/database/has-project-database.d.ts +3 -0
  214. package/dist/server/providers/database/has-project-database.js +1 -0
  215. package/dist/server/store.d.ts +2 -0
  216. package/dist/server/store.js +1 -1
  217. package/dist/server/tools/notifiers/formatter.js +1 -1
  218. package/dist/server/tools/notifiers/helpers/privacy/mask-email.js +1 -1
  219. package/dist/server/tools/notifiers/logger.js +1 -1
  220. package/dist/server/types/plugins/markdown.d.ts +2 -0
  221. package/dist/server/types/web-server.d.ts +1 -0
  222. package/dist/server/utils/codeframes/codeframes.js +2 -2
  223. package/dist/server/utils/entitlements/read-entitlement-number.d.ts +3 -0
  224. package/dist/server/utils/entitlements/read-entitlement-number.js +1 -0
  225. package/dist/server/utils/fs.js +1 -1
  226. package/dist/server/utils/is-api-download-link.d.ts +1 -0
  227. package/dist/server/utils/is-api-download-link.js +1 -1
  228. package/dist/server/utils/rbac.js +1 -1
  229. package/dist/server/utils/redact-url.d.ts +3 -2
  230. package/dist/server/utils/redact-url.js +1 -1
  231. package/dist/server/utils/sandbox-context.d.ts +7 -4
  232. package/dist/server/utils/sandbox-context.js +1 -1
  233. package/dist/server/web-server/auth.d.ts +0 -1
  234. package/dist/server/web-server/auth.js +4 -4
  235. package/dist/server/web-server/dev-server.js +1 -1
  236. package/dist/server/web-server/http.d.ts +2 -1
  237. package/dist/server/web-server/http.js +2 -2
  238. package/dist/server/web-server/jwt/token-types.d.ts +1 -0
  239. package/dist/server/web-server/jwt/token-types.js +1 -1
  240. package/dist/server/web-server/middleware/catalogAuthMiddleware.js +1 -1
  241. package/dist/server/web-server/middleware/dynamic-middleware/hono-compose.js +1 -1
  242. package/dist/server/web-server/middleware/responseHeadersMiddleware.js +1 -1
  243. package/dist/server/web-server/routes/auth.d.ts +1 -1
  244. package/dist/server/web-server/routes/auth.js +1 -1
  245. package/dist/server/web-server/routes/catalog/helpers/create-entity-schema.d.ts +1756 -1756
  246. package/dist/server/web-server/routes/catalog/helpers/create-entity-update-schema.d.ts +295 -295
  247. package/dist/server/web-server/routes/cors-proxy.js +2 -2
  248. package/dist/server/web-server/routes/index.js +1 -1
  249. package/dist/server/web-server/routes/mcp-routes/mcp-consent-page.d.ts +24 -0
  250. package/dist/server/web-server/routes/mcp-routes/mcp-consent-page.js +35 -0
  251. package/dist/server/web-server/routes/mcp-routes/mcp-fetch-count.d.ts +8 -0
  252. package/dist/server/web-server/routes/mcp-routes/mcp-fetch-count.js +1 -0
  253. package/dist/server/web-server/routes/mcp-routes/mcp-oauth-store.d.ts +15 -0
  254. package/dist/server/web-server/routes/mcp-routes/mcp-oauth-store.js +1 -0
  255. package/dist/server/web-server/routes/mcp-routes/mcp-oauth.d.ts +3 -1
  256. package/dist/server/web-server/routes/mcp-routes/mcp-oauth.js +1 -1
  257. package/dist/server/web-server/routes/mcp-routes/mcp-routes.js +1 -1
  258. package/dist/server/web-server/routes/mcp-routes/mcp-server-card.js +1 -1
  259. package/dist/server/web-server/routes/resolve-route.js +1 -1
  260. package/dist/server/workers/worker-pool.js +1 -1
  261. package/dist/types/entitlements.d.ts +2 -0
  262. package/dist/utils/time/debounce.js +1 -1
  263. package/package.json +10 -11
  264. package/dist/client/app/utils/withLoadProgress.d.ts +0 -2
  265. package/dist/client/app/utils/withLoadProgress.js +0 -1
  266. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/apply-edge-rate-limit.js +0 -1
  267. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/edge-limiter.js +0 -1
  268. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/ip-key.js +0 -1
  269. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/limits.js +0 -1
  270. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/rate-limit-telemetry.js +0 -1
  271. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/window-counter.js +0 -1
  272. package/dist/server/plugins/mcp/handlers/mcp-credentials-page.d.ts +0 -12
  273. package/dist/server/plugins/mcp/handlers/mcp-credentials-page.js +0 -225
  274. /package/dist/server/plugins/mcp/gateway-mcp/rate-limit/{rate-limit-telemetry.d.ts → request-limiter/rate-limit-telemetry.d.ts} +0 -0
  275. /package/dist/server/plugins/mcp/gateway-mcp/rate-limit/{ip-key.d.ts → utils/ip-key.d.ts} +0 -0
@@ -1,5 +1,5 @@
1
- import{getCallableApis as n,isFetchCapable as o}from"../../../gateway-mcp/callable-apis.js";import{FETCH_TOOL_NAME as i}from"../../constants.js";const l=["```ts","/**"," * Call a documented API. Only the callable APIs' documented hosts are reachable."," * Responses cap at 1 MiB and redirects are not followed."," */","declare function fetch(url: string | URL, init?: {"," method?: string;"," /** `content-type` is set automatically for URLSearchParams/FormData unless you set one. */"," headers?: Record<string, string>;"," /** string \xB7 URLSearchParams (\u2192 application/x-www-form-urlencoded) \xB7 FormData (\u2192 multipart/form-data) */"," body?: string | URLSearchParams | FormData;"," /** Security scheme name (from the operation's `security` or `getSecuritySchemes`) whose credential to send. Omit to let the server choose. */"," securityScheme?: string;","}): Promise<{"," status: number;"," statusText: string;"," ok: boolean;"," headers: { get(name: string): string | null };"," json(): Promise<unknown>;"," text(): Promise<string>;","}>;","```"].join(`
2
- `),c=["listApis","getEndpoints","getEndpointInfo"],p=["Example - list the paid invoices of a billing API:","","```ts","const { items } = await tools.listApis({ filter: 'billing' });","const [api] = items;",`if (!api) return { error: 'no API matches "billing"' };`,"const { endpoints } = await tools.getEndpoints({ name: api.name });","const ep = endpoints.find((e) => e.method === 'GET' && e.path.includes('invoices'));","const info = await tools.getEndpointInfo({ name: api.name, path: ep.path, method: ep.method });","// Replace every `{placeholder}` first.","const url = new URL((info.servers?.[0]?.url ?? '') + ep.path);","// Every name below comes from `info.endpoint.parameters` - read them first, never guess them.","url.searchParams.set('filter', 'status:paid');","url.searchParams.set('sort', '-createdTime');","url.searchParams.set('limit', '100');","try {"," const res = await fetch(url, { method: ep.method });"," return res.ok ? await res.json() : { status: res.status, error: await res.text() };","} catch (error) {"," return { error: error instanceof Error ? error.message : String(error), endpointId: info };","}","```"].join(`
3
- `),d=["Example - call an endpoint you already read:","","```ts","// Call `getEndpointInfo` first for the server URL, the path, and the parameter names.","// Replace every `{placeholder}` first.","const url = new URL('https://api.example.com/invoices');","url.searchParams.set('filter', 'status:paid');","try {"," const res = await fetch(url, { method: 'GET' });"," return res.ok ? await res.json() : { status: res.status, error: await res.text() };","} catch (error) {"," return { error: error instanceof Error ? error.message : String(error) };","}","```"].join(`
4
- `);function h(r){return c.every(t=>r.includes(t))?p:d}function m(r){const t=new Map;for(const{name:e,version:a}of r){if(!e)continue;const s=t.get(e)??[];a&&s.push(a),t.set(e,s)}return[...t.entries()].map(([e,a])=>a.length>1?`${e} (${a.map(s=>`v${s}`).join(", ")})`:e).join(", ")}const g={id:i,purpose:"Call the documented APIs over HTTP",isActive:o,annotations:{readOnlyHint:!1,destructiveHint:!0,openWorldHint:!0},renderSection(r,t){const e=m(n(r));return["## `fetch` \u2014 call the documented APIs","",l,"","Always call `getEndpointInfo` before `fetch` for the exact URL, required parameters, and body shape. Put filtering, sorting, and paging in the query parameters, and keep sandbox JS for what the endpoint cannot express. Never guess.","","A `servers[].url` or an endpoint path can hold `{placeholders}`. Replace every one before you call `fetch`. Use the server variable `default`. Ask the user when the `default` only repeats the variable name, such as `{organizationId}`.","",`Callable APIs (their documented hosts are reachable via \`fetch\`): ${e}`,"",h(t)].join(`
5
- `)}};export{l as FETCH_DECLARATION,g as fetchCapability};
1
+ import{getCallableApis as o,isFetchCapable as s}from"../../../gateway-mcp/callable-apis.js";import{allowsOnlySafeHttpMethods as i,getAllowedHttpMethods as l}from"../../../gateway-mcp/allowed-http-methods.js";import{FETCH_TOOL_NAME as c}from"../../constants.js";const d=["```ts","/**"," * Call a documented operation of a callable API. Undocumented paths and methods are refused."," * Responses cap at 1 MiB and redirects are not followed."," */","declare function fetch(url: string | URL, init?: {"," method?: string;"," /** `content-type` is set automatically for URLSearchParams/FormData unless you set one. */"," headers?: Record<string, string>;"," /** string \xB7 URLSearchParams (\u2192 application/x-www-form-urlencoded) \xB7 FormData (\u2192 multipart/form-data) */"," body?: string | URLSearchParams | FormData;"," /** Security scheme name (from the operation's `security` or `getSecuritySchemes`) whose credential to send. Omit to let the server choose. */"," securityScheme?: string;","}): Promise<{"," status: number;"," statusText: string;"," ok: boolean;"," headers: { get(name: string): string | null };"," json(): Promise<unknown>;"," text(): Promise<string>;","}>;","```"].join(`
2
+ `),p=["listApis","getEndpoints","getEndpointInfo"],h=["Example - list the paid invoices of a billing API:","","```ts","const { items } = await tools.listApis({ filter: 'billing' });","const [api] = items;",`if (!api) return { error: 'no API matches "billing"' };`,"const { endpoints } = await tools.getEndpoints({ name: api.name });","const ep = endpoints.find((e) => e.method === 'GET' && e.path.includes('invoices'));","const info = await tools.getEndpointInfo({ name: api.name, path: ep.path, method: ep.method });","// Replace every `{placeholder}` first.","const url = new URL((info.servers?.[0]?.url ?? '') + ep.path);","// Every name below comes from `info.endpoint.parameters` - read them first, never guess them.","url.searchParams.set('filter', 'status:paid');","url.searchParams.set('sort', '-createdTime');","url.searchParams.set('limit', '100');","try {"," const res = await fetch(url, { method: ep.method });"," return res.ok ? await res.json() : { status: res.status, error: await res.text() };","} catch (error) {"," return { error: error instanceof Error ? error.message : String(error), endpointId: info };","}","```"].join(`
3
+ `),m=["Example - call an endpoint you already read:","","```ts","// Call `getEndpointInfo` first for the server URL, the path, and the parameter names.","// Replace every `{placeholder}` first.","const url = new URL('https://api.example.com/invoices');","url.searchParams.set('filter', 'status:paid');","try {"," const res = await fetch(url, { method: 'GET' });"," return res.ok ? await res.json() : { status: res.status, error: await res.text() };","} catch (error) {"," return { error: error instanceof Error ? error.message : String(error) };","}","```"].join(`
4
+ `);function u(e){return p.every(r=>e.includes(r))?h:m}function f(e){const r=new Map;for(const{name:t,version:a}of e){if(!t)continue;const n=r.get(t)??[];a&&n.push(a),r.set(t,n)}return[...r.entries()].map(([t,a])=>a.length>1?`${t} (${a.map(n=>`v${n}`).join(", ")})`:t).join(", ")}const w={id:c,purpose:"Call the documented APIs over HTTP",isActive:s,annotations:e=>i(e)?{readOnlyHint:!0,destructiveHint:!1,openWorldHint:!0}:{readOnlyHint:!1,destructiveHint:!0,openWorldHint:!0},renderSection(e,r){const t=f(o(e));return["## `fetch` \u2014 call the documented APIs","",d,"","Always call `getEndpointInfo` before `fetch` for the exact URL, required parameters, and body shape. Put filtering, sorting, and paging in the query parameters, and keep sandbox JS for what the endpoint cannot express. Never guess.","","A `servers[].url` or an endpoint path can hold `{placeholders}`. Replace every one before you call `fetch`. Use the server variable `default`. Ask the user when the `default` only repeats the variable name, such as `{organizationId}`.","",`\`fetch\` sends only the methods this project allows: ${l(e.config?.mcp).join(", ")}. Explain any other call to the user instead of making it.`,"",`Callable APIs (their documented hosts are reachable via \`fetch\`): ${t}`,"",u(r)].join(`
5
+ `)}};export{d as FETCH_DECLARATION,w as fetchCapability};
@@ -1,3 +1,4 @@
1
+ import type { RedoclyConfig } from '@redocly/config';
1
2
  import type { ToolAnnotations } from '@modelcontextprotocol/server';
2
3
  import type { McpToolContext } from '../../types.js';
3
4
  /** A capability is a per-request-gated global the code-mode sandbox exposes beyond the schema-driven `tools.*` surface. */
@@ -6,7 +7,8 @@ export type SandboxCapability = {
6
7
  purpose: string;
7
8
  /** Whether this capability is live for THIS request (RBAC/config/flag-dependent). */
8
9
  isActive(context: McpToolContext): boolean;
9
- annotations: Partial<ToolAnnotations>;
10
+ /** The tool hints this capability adds to `execute` under the project's `mcp` config. */
11
+ annotations(mcp: RedoclyConfig['mcp'] | undefined): Partial<ToolAnnotations>;
10
12
  /**
11
13
  * The self-contained `describe-tools` section for this capability: heading, TS declaration,
12
14
  * guidance, and an example built only from `describedToolNames`.
@@ -1,9 +1,10 @@
1
+ import type { RedoclyConfig } from '@redocly/config';
1
2
  import type { ToolAnnotations } from '@modelcontextprotocol/server';
2
3
  import type { McpToolSchema } from '../../../../types';
3
4
  import type { McpToolContext } from '../../types.js';
4
5
  import type { SandboxCapability } from './types.js';
5
6
  export declare function getActiveCapabilities(context: McpToolContext): SandboxCapability[];
6
- export declare function composeExecuteAnnotations(tools: McpToolSchema[], capabilities: SandboxCapability[]): ToolAnnotations;
7
+ export declare function composeExecuteAnnotations(tools: McpToolSchema[], capabilities: SandboxCapability[], mcp: RedoclyConfig['mcp'] | undefined): ToolAnnotations;
7
8
  /**
8
9
  * The describe-tools output: the tool signatures, the always-present
9
10
  * `execute` args note, then one self-contained section per selected capability.
@@ -1,7 +1,7 @@
1
- import{buildToolTypeDeclarations as p,sanitizeToolName as c}from"../build-tool-type-declarations.js";import{buildExecuteExample as u,EXECUTE_ARGS_NOTE as l,USAGE_NOTES as m}from"../prompts.js";import{FETCH_TOOL_NAME as a}from"../constants.js";import{ALL_CAPABILITIES as d}from"./registry.js";function H(t){return d.filter(o=>o.isActive(t))}function h(t,o){const r=[...t,...o].map(({annotations:e})=>e??{}),i=r.filter(e=>e.readOnlyHint!==!0);return{readOnlyHint:i.length===0,destructiveHint:i.some(e=>e.destructiveHint!==!1),idempotentHint:i.every(e=>e.idempotentHint===!0),openWorldHint:r.some(e=>e.openWorldHint!==!1)}}function O(t,o,r){const i=t.map(n=>c(n.name)),e=[];if(t.length>0){const n=p(t),s=n.includes("OpenApi")?`
1
+ import{buildToolTypeDeclarations as p,sanitizeToolName as c}from"../build-tool-type-declarations.js";import{buildExecuteExample as a,EXECUTE_ARGS_NOTE as m,USAGE_NOTES as u}from"../prompts.js";import{FETCH_TOOL_NAME as l}from"../constants.js";import{ALL_CAPABILITIES as d}from"./registry.js";function H(n){return d.filter(o=>o.isActive(n))}function h(n,o,r){const i=[...n.map(({annotations:t})=>t??{}),...o.map(t=>t.annotations(r))],e=i.filter(t=>t.readOnlyHint!==!0);return{readOnlyHint:e.length===0,destructiveHint:e.some(t=>t.destructiveHint!==!1),idempotentHint:e.every(t=>t.idempotentHint===!0),openWorldHint:i.some(t=>t.openWorldHint!==!1)}}function O(n,o,r){const i=n.map(t=>c(t.name)),e=[];if(n.length>0){const t=p(n),s=t.includes("OpenApi")?`
2
2
 
3
- ${m}`:"";e.push(`## Sandbox tools
3
+ ${u}`:"";e.push(`## Sandbox tools
4
4
 
5
- ${n}${s}`)}e.push(l),t.length>0&&!o.some(n=>n.id===a)&&e.push(u(i));for(const n of o)e.push(n.renderSection(r,i));return e.join(`
5
+ ${t}${s}`)}e.push(m),n.length>0&&!o.some(t=>t.id===l)&&e.push(a(i));for(const t of o)e.push(t.renderSection(r,i));return e.join(`
6
6
 
7
7
  `)}export{h as composeExecuteAnnotations,H as getActiveCapabilities,O as renderDescribeToolsOutput};
@@ -4,9 +4,10 @@ export type CodeAudit = {
4
4
  flags: string;
5
5
  };
6
6
  /**
7
- * Fingerprint model-supplied code for the audit trail. The body itself is never reported — it can
8
- * contain data the model already pulled from a customer API — so callers get a hash plus flags for
9
- * patterns worth reviewing. The sandbox blocks all of the flagged targets; a flag is an attempt.
7
+ * Fingerprint model-supplied code. Telemetry never carries the body — it can contain data the model
8
+ * already pulled from a customer API — so it gets a hash plus flags for patterns worth reviewing; the
9
+ * redacted body goes only to the audit log. The sandbox blocks all of the flagged targets; a flag is
10
+ * an attempt.
10
11
  */
11
12
  export declare function auditCode(code: string): CodeAudit;
12
13
  //# sourceMappingURL=code-audit.d.ts.map
@@ -1 +1 @@
1
- import{auditInput as t,auditSha256 as g,logAuditRecord as h}from"../audit/audit-log.js";function f({audit:e,code:c,description:d,sessionHandle:o,toolNames:i,fetchBudget:u,fetchCapable:n,requestId:s,messageId:a}){h("Record code execution input",{code_sha256:e.sha256,code_length:e.length,request_id:s,message_id:a,flags:e.flags,subject_sha256:o?g(o):void 0,description:t(d),tools:[...i].sort().join(","),fetch_capable:n,fetch_budget:u,code:t(c)})}export{f as logCodeExecutionAudit};
1
+ import{auditInput as t,auditSha256 as a,logAuditRecord as f}from"../audit/audit-log.js";import{maskCodeCredentials as g}from"../audit/code-credentials.js";function p({audit:e,code:d,description:c,sessionHandle:o,toolNames:i,fetchBudget:n,fetchCapable:r,requestId:s,messageId:u}){f("Record code execution input",{code_sha256:e.sha256,code_length:e.length,request_id:s,message_id:u,flags:e.flags,subject_sha256:o?a(o):void 0,description:t(c),tools:[...i].sort().join(","),fetch_capable:r,fetch_budget:n,code:t(g(d))})}export{p as logCodeExecutionAudit};
@@ -1 +1 @@
1
- import{basename as d,join as p}from"node:path";import{envConfig as f}from"../../../config/env-config.js";import{logger as h}from"../../../tools/notifiers/logger.js";import{reporter as s}from"../../../tools/notifiers/reporter.js";import{CODE_MODE_TOOL_NAMES as O}from"../codemode/constants.js";import{ALL_DEFAULT_TOOL_NAMES as E}from"../docs-mcp/tool-schemas.js";import{extractToolDefinition as T}from"./extract-tool-definition.js";const M=/(^|\/)@mcp\/.*\.(ts|js)$/,_=/^[a-zA-Z0-9_-]{1,64}$/,C=new Set([...O,...E]);async function w(o,a,n){if(!f.REDOCLY_EXP_MCP_CUSTOM_TOOLS_ENABLED)return 0;N(o,n);const u=new Set(o.getMcpTools().map(r=>r.name)),l=new Map;for(const r of a.fs.scan(M)){if(r.isVirtual||r.relativePath.endsWith(".d.ts"))continue;const{relativePath:t}=r,e=d(t).replace(/\.(ts|js)$/,"");if(!_.test(e)){await s.panicOnBuildContentError(`Invalid MCP tool file "${t}": the tool name "${e}" is derived from the file name and may only contain letters, numbers, hyphens, and underscores (max 64 characters). Rename the file.`);continue}const c=l.get(e);if(c){await s.panicOnBuildContentError(`Duplicate MCP tool name "${e}": defined by both "${c}" and "${t}". Tool names are file names, so each file name must be unique across @mcp folders.`);continue}if(C.has(e)||u.has(e)){await s.panicOnBuildContentError(`Invalid MCP tool file "${t}": the tool name "${e}" is already used by a built-in MCP tool. Rename the file.`);continue}l.set(e,t);const m=p(o.contentDir,t),i=await T({toolName:e,absoluteSourcePath:m,contentDir:o.contentDir,serverOutDir:o.serverOutDir});if(!i.ok){await s.panicOnBuildContentError(`Invalid MCP tool file "${t}": ${i.errors.join(" ")}`);continue}!i.schema.outputSchema&&!n.warnedNoOutputSchemaTools.has(e)&&(n.warnedNoOutputSchemaTools.add(e),h.warn(`MCP tool "${e}" in %rp declares no \`outputSchema\`. Add one that describes the returned value.`,t)),o.addMcpTools(m,[i.schema]),n.registeredToolNames.push(e)}return n.registeredToolNames.length}function N(o,a){o.removeMcpTools(a.registeredToolNames),a.registeredToolNames=[]}export{N as resetCustomMcpTools,w as scanCustomMcpTools};
1
+ import{basename as d,join as p}from"node:path";import{logger as f}from"../../../tools/notifiers/logger.js";import{reporter as s}from"../../../tools/notifiers/reporter.js";import{CODE_MODE_TOOL_NAMES as h}from"../codemode/constants.js";import{ALL_DEFAULT_TOOL_NAMES as O}from"../docs-mcp/tool-schemas.js";import{extractToolDefinition as T}from"./extract-tool-definition.js";const E=/(^|\/)@mcp\/.*\.(ts|js)$/,M=/^[a-zA-Z0-9_-]{1,64}$/,C=new Set([...h,...O]);async function g(o,a,n){_(o,n);const u=new Set(o.getMcpTools().map(r=>r.name)),l=new Map;for(const r of a.fs.scan(E)){if(r.isVirtual||r.relativePath.endsWith(".d.ts"))continue;const{relativePath:t}=r,e=d(t).replace(/\.(ts|js)$/,"");if(!M.test(e)){await s.panicOnBuildContentError(`Invalid MCP tool file "${t}": the tool name "${e}" is derived from the file name and may only contain letters, numbers, hyphens, and underscores (max 64 characters). Rename the file.`);continue}const c=l.get(e);if(c){await s.panicOnBuildContentError(`Duplicate MCP tool name "${e}": defined by both "${c}" and "${t}". Tool names are file names, so each file name must be unique across @mcp folders.`);continue}if(C.has(e)||u.has(e)){await s.panicOnBuildContentError(`Invalid MCP tool file "${t}": the tool name "${e}" is already used by a built-in MCP tool. Rename the file.`);continue}l.set(e,t);const m=p(o.contentDir,t),i=await T({toolName:e,absoluteSourcePath:m,contentDir:o.contentDir,serverOutDir:o.serverOutDir});if(!i.ok){await s.panicOnBuildContentError(`Invalid MCP tool file "${t}": ${i.errors.join(" ")}`);continue}!i.schema.outputSchema&&!n.warnedNoOutputSchemaTools.has(e)&&(n.warnedNoOutputSchemaTools.add(e),f.warn(`MCP tool "${e}" in %rp declares no \`outputSchema\`. Add one that describes the returned value.`,t)),o.addMcpTools(m,[i.schema]),n.registeredToolNames.push(e)}return n.registeredToolNames.length}function _(o,a){o.removeMcpTools(a.registeredToolNames),a.registeredToolNames=[]}export{_ as resetCustomMcpTools,g as scanCustomMcpTools};
@@ -1 +1 @@
1
- import{SEMANTIC_SEARCH_API_URL as y}from"../../../constants/common.js";import{shouldHandleMcpAuth as f}from"../../../utils/rbac/should-handle-mcp-auth.js";import{CREATE_ANONYMOUS_SESSION_TOOL_NAME as g,SUBMIT_FEEDBACK_TOOL_NAME as b}from"../constants.js";import{GRAPHQL_TYPE_KINDS as l,GRAPHQL_LIST_SCOPES as v}from"./tools/graphql/constants.js";import{OPERATION_METHODS as c}from"./tools/openapi/constants.js";const i={type:"string",nullable:!0},s={limit:{type:"number"},total:{type:"number"},page:{type:"number"},totalPages:{type:"number"}},a={codemodeType:"OpenApiServer[]"},o={codemodeType:"OpenApiSecurityRequirement[]"},u={codemodeType:"Record<string, OpenApiSecurityScheme>"},P={codemodeType:"OpenApiDocument"},A={codemodeType:"OpenApiOperation & { path: string; method: string }"},S={codemodeType:"OpenApiComponents",description:"Components the endpoint references. A `$ref` in `endpoint` resolves against the root of the result."},n={filePath:{type:"string",description:"API definition file path"},otherMatches:{type:"array",description:"Other API definitions the lookup also matched. Present only when several matched; pass `filePath` to pick another one",items:{type:"object",required:["filePath"],properties:{version:{type:"string"},filePath:{type:"string"}}}}},r="When several definitions match the name, the highest version or the shortest file path is used and the rest are listed in `otherMatches`; tell the user which version or file the answer is based on.",H="A `$ref` in `endpoint` points into the `components` key at the root of the result: read `#/components/<section>/<name>` there.",L={type:"object",additionalProperties:!1,required:[],properties:{filter:{type:"string",description:"Matches part of an API name, or of a description when no name matches",minLength:1,nullable:!0},page:{type:"number",description:"Page number",minimum:1,default:1,nullable:!0},limit:{type:"number",description:"Number of APIs per page. Default is 300",minimum:1,default:300,nullable:!0}}},p={type:"object",required:[],additionalProperties:!1,properties:{name:{type:"string",description:"API name, or a unique part of it. Omit when `filePath` is given.",minLength:1,nullable:!0},apiName:{type:"string",description:"Alias of `name`",nullable:!0},api:{type:"string",description:"Alias of `name`",nullable:!0},version:{type:"string",description:"API version. When omitted and several versions exist, the highest one is used",nullable:!0},filePath:{type:"string",description:"API definition file path, as returned by `listApis`",nullable:!0}}},q={type:"object",required:["path","method"],additionalProperties:!1,properties:{name:{type:"string",description:"API name, or a unique part of it. Omit when `filePath` is given.",minLength:1,nullable:!0},apiName:{type:"string",description:"Alias of `name`",nullable:!0},api:{type:"string",description:"Alias of `name`",nullable:!0},path:{type:"string",description:"Endpoint path (e.g. /api/v1/users)",minLength:1},method:{type:"string",description:"HTTP method (GET, POST, PUT, DELETE, etc.)",enum:[...c.map(e=>e.toUpperCase()),...c],minLength:1},version:{type:"string",description:"API version. When omitted and several versions exist, the highest one is used",nullable:!0},filePath:{type:"string",description:"API definition file path, as returned by `listApis`",nullable:!0}}},O={type:"object",required:[],additionalProperties:!1,properties:{}},T={type:"object",required:[],additionalProperties:!1,properties:{}},G={type:"object",required:["path","summary"],additionalProperties:!1,properties:{path:{type:"string",description:"Path or URL of the documentation page the feedback is about (e.g. /guides/auth)",minLength:1,maxLength:1e3},summary:{type:"string",description:"One sentence that names what is wrong with the page",minLength:1,maxLength:500},details:{type:"string",description:"Expected versus actual behavior, missing steps, or the snippet that failed",maxLength:4e3,nullable:!0},targetFeature:{type:"string",description:"The API or feature the page documents",maxLength:500,nullable:!0}}};function I(e){const t=[{name:"list-apis",title:"List APIs",description:"Lists the APIs documented in this project",schema:L,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",required:["items","limit","total","page","totalPages"],properties:{items:{type:"array",items:{type:"object",required:["name","description","version","servers","filePath"],properties:{name:{type:"string"},description:{type:"string"},version:{type:"string"},servers:a,filePath:{type:"string",description:"API definition file path"},ambiguousTitle:{type:"boolean",description:"true = another API shares this title; a lookup picks the highest version, or the shortest file path at the same version, and lists the rest in `otherMatches`. Pass `filePath` to pick another one"},...e.hasCallableApis?{callable:{type:"boolean",description:"true = the documented hosts of this API are reachable via `fetch`; false = documentation only"}}:{}}}},...s}}},{name:"get-endpoints",title:"Get endpoints",description:`Get all endpoints for a specific API. ${r}`,schema:p,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",required:["api","version","filePath","servers","endpoints"],properties:{api:{type:"string"},version:{type:"string"},...n,servers:a,endpoints:{type:"array",items:{type:"object",required:["path","method"],properties:{path:{type:"string"},method:{type:"string"},summary:i,description:i,security:o}}}}}},{name:"get-endpoint-info",title:"Get endpoint info",description:`Get comprehensive information about specific endpoint including parameters, security, and examples. ${H} ${r}`,schema:q,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",required:["api","version","filePath","servers","endpoint","globalSecurity","securitySchemes"],properties:{api:{type:"string"},version:{type:"string"},...n,servers:a,endpoint:A,globalSecurity:o,securitySchemes:u,components:S}}},{name:"get-security-schemes",title:"Get security schemes",description:`Get the security schemes for a specific API. ${r}`,schema:p,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",required:["api","version","filePath","securitySchemes","security"],properties:{api:{type:"string"},version:{type:"string"},...n,securitySchemes:u,security:o}}},{name:"get-full-api-description",title:"Get full API description",description:`Get the complete OpenAPI description. ${r}`,schema:p,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",required:["api","version","filePath","definition"],properties:{api:{type:"string"},version:{type:"string"},...n,definition:P}}},...y?[d(e.products,e.locales)]:[]];return f(e.requiresLogin,e.rbac)&&t.push({name:"whoami",title:"Who am I",description:"Get information about the currently authenticated user",schema:O,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{email:{type:"string"},name:{type:"string"},subject:{type:"string"},clientId:{type:"string"},scope:{type:"string"},issuedAt:{type:"string"},expiresAt:{type:"string"}}}}),e.feedbackHidden||t.push({name:b,title:"Submit feedback",description:"Report a documentation page that is wrong or incomplete",schema:G,annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!1},outputSchema:{type:"object",required:["status","page","message"],properties:{status:{type:"string"},page:{type:"string"},message:{type:"string"}}}}),e.hasGraphqlApis&&t.push(...k()),e.elicitationEnabled&&e.hasCallableApis&&t.push({name:g,title:"Create anonymous session",description:"Create an anonymous session handle for storing upstream API credentials. Pass the returned sessionHandle to execute when an API needs credentials and the caller is not signed in. Treat it as a secret and reuse it across calls.",schema:T,annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!1},outputSchema:{type:"object",required:["sessionHandle"],properties:{sessionHandle:{type:"string"}}}}),t}const w={type:"object",required:[],additionalProperties:!1,properties:{filter:{type:"string",description:"GraphQL schema name (or part of it)",minLength:1,nullable:!0},page:{type:"number",description:"Page number",minimum:1,default:1,nullable:!0},limit:{type:"number",description:"Number of results per page. Default is 300",minimum:1,default:300,nullable:!0}}},j={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"GraphQL schema name",minLength:1},kind:{type:"string",description:'Optional: return only a single category of schema members. With scope "fields", restricts to the fields of that parent category ("objects", "interfaces", or "inputs" only).',enum:[...l,null],nullable:!0},scope:{type:"string",description:'Optional: what each list item is. "members" (default) lists top-level types and operations. "fields" flattens every field of every object/interface/input type into "ParentType.fieldName" entries with their descriptions \u2014 combine with `filter` to search nested fields anywhere in the schema.',enum:[...v,null],nullable:!0},filter:{type:"string",description:'Optional: only members whose name or description contains this substring, case-insensitive (e.g. "custom tags")',minLength:1,nullable:!0},referencesType:{type:"string",description:'Optional: only members that reference this type directly or transitively (via return, field, argument, union-member or input-field types). Finds cross-cutting members that never name it \u2014 e.g. referencesType "Book" surfaces a search query returning a union that includes Book.',minLength:1,nullable:!0},page:{type:"number",description:"Page number",minimum:1,default:1,nullable:!0},limit:{type:"number",description:"Number of results per page. Default is 300",minimum:1,default:300,nullable:!0}}},E={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"GraphQL schema name",minLength:1},type:{type:"string",description:"Name of the type, operation, or directive",minLength:1,nullable:!0},typeName:{type:"string",description:"Alias of `type`",nullable:!0},includeReferencedTypes:{type:"boolean",description:"Also include the SDL of every type referenced transitively. Gives the whole subgraph at once, but can be large for highly-connected types.",default:!1,nullable:!0}}},N={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"GraphQL schema name",minLength:1}}};function k(){return[{name:"list-graphql-apis",title:"List GraphQL APIs",description:"Lists available GraphQL schemas with their context and purpose",schema:w,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",required:["items","limit","total","page","totalPages"],properties:{items:{type:"array",items:{type:"object",required:["name"],properties:{name:{type:"string"},description:i}}},...s}}},{name:"get-graphql-type-list",title:"Get GraphQL type list",description:'List all operations and types in a GraphQL schema as a flat, paginated list. Each item is tagged with its kind (query, object, enum, \u2026) and carries a one-line description; operations also include their return type and argument signature \u2014 use it to decide which members to fetch in detail. Narrow the result with `kind` (one category), `filter` (case-insensitive substring of the member name or description, e.g. "book"), or `referencesType` (only members that use a given type, directly or transitively) to explore a domain cheaply instead of pulling the full schema. To search nested fields \u2014 not just type names \u2014 set scope "fields": it flattens every field of every object/interface/input type into "ParentType.fieldName" entries with their descriptions, so `filter` finds things like an input field whose docstring mentions your keyword.',schema:j,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",required:["name","items","limit","total","page","totalPages"],properties:{name:{type:"string"},items:{type:"array",items:{type:"object",required:["kind","name"],properties:{kind:{type:"string",enum:l},name:{type:"string"},description:i,type:{type:"string"},args:{type:"string"},directives:{type:"string"}}}},...s}}},{name:"get-graphql-type",title:"Get GraphQL type",description:'Get the SDL for a single GraphQL type, operation (query/mutation/subscription field), or directive. Without includeReferencedTypes, the SDL is followed by a one-level manifest of every directly referenced type\'s field names (e.g. "input ActionOperationInput { addTags, removeTags }"), so you can see what nested types contain before fetching them. Set includeReferencedTypes to instead pull in the full SDL of every type it references transitively \u2014 the whole structural subgraph in one call, ideal for complete exploration of an entity (e.g. Book and all the types it touches). That traversal only follows what the target depends on; to go the other direction and find the members that use a type, call get-graphql-type-list with `referencesType`.',schema:E,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"string"}},{name:"get-graphql-schema",title:"Get GraphQL schema",description:"Get the complete GraphQL schema as SDL \u2014 the whole type graph in one call. Returns everything, so it can be very large and token-expensive for big schemas; prefer get-graphql-type-list (filter/paginate) plus targeted get-graphql-type calls, and reach for this only for small schemas or when you truly need the full SDL.",schema:N,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"string"}}]}function d(e,t){const h=e&&e.length>0,m=t&&t.length>0;return{name:"search",title:"Search documentation",description:"Search across the documentation to fetch relevant content for a given query",schema:{type:"object",required:["query"],additionalProperties:!1,properties:{query:{type:"string",description:"Search query. Should be a single word or that phrase that is presented in a documentation.",minLength:1},...h?{product:{type:"string",description:"Optional product name to filter search results by specific product.",enum:[...e,null],nullable:!0}}:{},...m?{locale:{type:"string",description:"Optional locale code to filter search results by documentation language (e.g. 'en', 'ja'). Use the locale matching the language of the user's request. Defaults to the project's default locale.",enum:[...t,null],nullable:!0}}:{}}},annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!1,openWorldHint:!1},outputSchema:{type:"string"}}}const Q=new Set([...I({requiresLogin:!0,hasGraphqlApis:!0,elicitationEnabled:!0,hasCallableApis:!0}).map(e=>e.name),d().name]);export{Q as ALL_DEFAULT_TOOL_NAMES,I as getDefaultToolSchemas};
1
+ import{SEMANTIC_SEARCH_API_URL as y}from"../../../constants/common.js";import{shouldHandleMcpAuth as f}from"../../../utils/rbac/should-handle-mcp-auth.js";import{CREATE_ANONYMOUS_SESSION_TOOL_NAME as g,SUBMIT_FEEDBACK_TOOL_NAME as b}from"../constants.js";import{GRAPHQL_TYPE_KINDS as l,GRAPHQL_LIST_SCOPES as v}from"./tools/graphql/constants.js";import{OPERATION_METHODS as c}from"./tools/openapi/constants.js";const i={type:"string",nullable:!0},s={limit:{type:"number"},total:{type:"number"},page:{type:"number"},totalPages:{type:"number"}},a={codemodeType:"OpenApiServer[]"},o={codemodeType:"OpenApiSecurityRequirement[]"},u={codemodeType:"Record<string, OpenApiSecurityScheme>"},P={codemodeType:"OpenApiDocument"},A={codemodeType:"OpenApiOperation & { path: string; method: string }"},S={codemodeType:"OpenApiComponents",description:"Components the endpoint references. A `$ref` in `endpoint` resolves against the root of the result."},n={filePath:{type:"string",description:"API definition file path"},otherMatches:{type:"array",description:"Other API definitions the lookup also matched. Present only when several matched; pass `filePath` to pick another one",items:{type:"object",required:["filePath"],properties:{version:{type:"string"},filePath:{type:"string"}}}}},r="When several definitions match the name, the highest version or the shortest file path is used and the rest are listed in `otherMatches`; tell the user which version or file the answer is based on.",H="A `$ref` in `endpoint` points into the `components` key at the root of the result: read `#/components/<section>/<name>` there.",L={type:"object",additionalProperties:!1,required:[],properties:{filter:{type:"string",description:"Matches part of an API name, or of a description when no name matches",minLength:1,nullable:!0},page:{type:"number",description:"Page number",minimum:1,default:1,nullable:!0},limit:{type:"number",description:"Number of APIs per page. Default is 300",minimum:1,default:300,nullable:!0}}},p={type:"object",required:[],additionalProperties:!1,properties:{name:{type:"string",description:"API name, or a unique part of it. Omit when `filePath` is given.",minLength:1,nullable:!0},apiName:{type:"string",description:"Alias of `name`",nullable:!0},api:{type:"string",description:"Alias of `name`",nullable:!0},version:{type:"string",description:"API version. When omitted and several versions exist, the highest one is used",nullable:!0},filePath:{type:"string",description:"API definition file path, as returned by `listApis`",nullable:!0}}},q={type:"object",required:["path","method"],additionalProperties:!1,properties:{name:{type:"string",description:"API name, or a unique part of it. Omit when `filePath` is given.",minLength:1,nullable:!0},apiName:{type:"string",description:"Alias of `name`",nullable:!0},api:{type:"string",description:"Alias of `name`",nullable:!0},path:{type:"string",description:"Endpoint path (e.g. /api/v1/users)",minLength:1},method:{type:"string",description:"HTTP method (GET, POST, PUT, DELETE, etc.)",enum:[...c.map(e=>e.toUpperCase()),...c],minLength:1},version:{type:"string",description:"API version. When omitted and several versions exist, the highest one is used",nullable:!0},filePath:{type:"string",description:"API definition file path, as returned by `listApis`",nullable:!0}}},O={type:"object",required:[],additionalProperties:!1,properties:{}},T={type:"object",required:[],additionalProperties:!1,properties:{}},G={type:"object",required:["path","summary"],additionalProperties:!1,properties:{path:{type:"string",description:"Path or URL of the documentation page the feedback is about (e.g. /guides/auth)",minLength:1,maxLength:1e3},summary:{type:"string",description:"One sentence that names what is wrong with the page",minLength:1,maxLength:500},details:{type:"string",description:"Expected versus actual behavior, missing steps, or the snippet that failed",maxLength:4e3,nullable:!0},targetFeature:{type:"string",description:"The API or feature the page documents",maxLength:500,nullable:!0}}};function I(e){const t=[{name:"list-apis",title:"List APIs",description:"Lists the APIs documented in this project",schema:L,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",required:["items","limit","total","page","totalPages"],properties:{items:{type:"array",items:{type:"object",required:["name","description","version","servers","filePath"],properties:{name:{type:"string"},description:{type:"string"},version:{type:"string"},servers:a,filePath:{type:"string",description:"API definition file path"},ambiguousTitle:{type:"boolean",description:"true = another API shares this title; a lookup picks the highest version, or the shortest file path at the same version, and lists the rest in `otherMatches`. Pass `filePath` to pick another one"},...e.hasCallableApis?{callable:{type:"boolean",description:"true = the documented hosts of this API are reachable via `fetch`; false = documentation only"}}:{}}}},...s}}},{name:"get-endpoints",title:"Get endpoints",description:`Get all endpoints for a specific API. ${r}`,schema:p,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",required:["api","version","filePath","servers","endpoints"],properties:{api:{type:"string"},version:{type:"string"},...n,servers:a,endpoints:{type:"array",items:{type:"object",required:["path","method"],properties:{path:{type:"string"},method:{type:"string"},summary:i,description:i,security:o}}}}}},{name:"get-endpoint-info",title:"Get endpoint info",description:`Get comprehensive information about specific endpoint including parameters, security, and examples. ${H} ${r}`,schema:q,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",required:["api","version","filePath","servers","endpoint","globalSecurity","securitySchemes"],properties:{api:{type:"string"},version:{type:"string"},...n,servers:a,endpoint:A,globalSecurity:o,securitySchemes:u,components:S}}},{name:"get-security-schemes",title:"Get security schemes",description:`Get the security schemes for a specific API. ${r}`,schema:p,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",required:["api","version","filePath","securitySchemes","security"],properties:{api:{type:"string"},version:{type:"string"},...n,securitySchemes:u,security:o}}},{name:"get-full-api-description",title:"Get full API description",description:`Get the complete OpenAPI description. ${r}`,schema:p,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",required:["api","version","filePath","definition"],properties:{api:{type:"string"},version:{type:"string"},...n,definition:P}}},...y?[d(e.products,e.locales)]:[]];return f(e.requiresLogin,e.rbac)&&t.push({name:"whoami",title:"Who am I",description:"Get information about the currently authenticated user",schema:O,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",required:["authenticated"],properties:{authenticated:{type:"boolean"},email:{type:"string"},name:{type:"string"},subject:{type:"string"},clientId:{type:"string"},scope:{type:"string"},issuedAt:{type:"string"},expiresAt:{type:"string"}}}}),e.feedbackHidden||t.push({name:b,title:"Submit feedback",description:"Report a documentation page that is wrong or incomplete",schema:G,annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!1},outputSchema:{type:"object",required:["status","page","message"],properties:{status:{type:"string"},page:{type:"string"},message:{type:"string"}}}}),e.hasGraphqlApis&&t.push(...k()),e.elicitationEnabled&&e.hasCallableApis&&t.push({name:g,title:"Create anonymous session",description:"Create an anonymous session handle for storing upstream API credentials. Pass the returned sessionHandle to execute when an API needs credentials and the caller is not signed in. Treat it as a secret and reuse it across calls.",schema:T,annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!1},outputSchema:{type:"object",required:["sessionHandle"],properties:{sessionHandle:{type:"string"}}}}),t}const w={type:"object",required:[],additionalProperties:!1,properties:{filter:{type:"string",description:"GraphQL schema name (or part of it)",minLength:1,nullable:!0},page:{type:"number",description:"Page number",minimum:1,default:1,nullable:!0},limit:{type:"number",description:"Number of results per page. Default is 300",minimum:1,default:300,nullable:!0}}},j={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"GraphQL schema name",minLength:1},kind:{type:"string",description:'Optional: return only a single category of schema members. With scope "fields", restricts to the fields of that parent category ("objects", "interfaces", or "inputs" only).',enum:[...l,null],nullable:!0},scope:{type:"string",description:'Optional: what each list item is. "members" (default) lists top-level types and operations. "fields" flattens every field of every object/interface/input type into "ParentType.fieldName" entries with their descriptions \u2014 combine with `filter` to search nested fields anywhere in the schema.',enum:[...v,null],nullable:!0},filter:{type:"string",description:'Optional: only members whose name or description contains this substring, case-insensitive (e.g. "custom tags")',minLength:1,nullable:!0},referencesType:{type:"string",description:'Optional: only members that reference this type directly or transitively (via return, field, argument, union-member or input-field types). Finds cross-cutting members that never name it \u2014 e.g. referencesType "Book" surfaces a search query returning a union that includes Book.',minLength:1,nullable:!0},page:{type:"number",description:"Page number",minimum:1,default:1,nullable:!0},limit:{type:"number",description:"Number of results per page. Default is 300",minimum:1,default:300,nullable:!0}}},E={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"GraphQL schema name",minLength:1},type:{type:"string",description:"Name of the type, operation, or directive",minLength:1,nullable:!0},typeName:{type:"string",description:"Alias of `type`",nullable:!0},includeReferencedTypes:{type:"boolean",description:"Also include the SDL of every type referenced transitively. Gives the whole subgraph at once, but can be large for highly-connected types.",default:!1,nullable:!0}}},N={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"GraphQL schema name",minLength:1}}};function k(){return[{name:"list-graphql-apis",title:"List GraphQL APIs",description:"Lists available GraphQL schemas with their context and purpose",schema:w,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",required:["items","limit","total","page","totalPages"],properties:{items:{type:"array",items:{type:"object",required:["name"],properties:{name:{type:"string"},description:i}}},...s}}},{name:"get-graphql-type-list",title:"Get GraphQL type list",description:'List all operations and types in a GraphQL schema as a flat, paginated list. Each item is tagged with its kind (query, object, enum, \u2026) and carries a one-line description; operations also include their return type and argument signature \u2014 use it to decide which members to fetch in detail. Narrow the result with `kind` (one category), `filter` (case-insensitive substring of the member name or description, e.g. "book"), or `referencesType` (only members that use a given type, directly or transitively) to explore a domain cheaply instead of pulling the full schema. To search nested fields \u2014 not just type names \u2014 set scope "fields": it flattens every field of every object/interface/input type into "ParentType.fieldName" entries with their descriptions, so `filter` finds things like an input field whose docstring mentions your keyword.',schema:j,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",required:["name","items","limit","total","page","totalPages"],properties:{name:{type:"string"},items:{type:"array",items:{type:"object",required:["kind","name"],properties:{kind:{type:"string",enum:l},name:{type:"string"},description:i,type:{type:"string"},args:{type:"string"},directives:{type:"string"}}}},...s}}},{name:"get-graphql-type",title:"Get GraphQL type",description:'Get the SDL for a single GraphQL type, operation (query/mutation/subscription field), or directive. Without includeReferencedTypes, the SDL is followed by a one-level manifest of every directly referenced type\'s field names (e.g. "input ActionOperationInput { addTags, removeTags }"), so you can see what nested types contain before fetching them. Set includeReferencedTypes to instead pull in the full SDL of every type it references transitively \u2014 the whole structural subgraph in one call, ideal for complete exploration of an entity (e.g. Book and all the types it touches). That traversal only follows what the target depends on; to go the other direction and find the members that use a type, call get-graphql-type-list with `referencesType`.',schema:E,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"string"}},{name:"get-graphql-schema",title:"Get GraphQL schema",description:"Get the complete GraphQL schema as SDL \u2014 the whole type graph in one call. Returns everything, so it can be very large and token-expensive for big schemas; prefer get-graphql-type-list (filter/paginate) plus targeted get-graphql-type calls, and reach for this only for small schemas or when you truly need the full SDL.",schema:N,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"string"}}]}function d(e,t){const h=e&&e.length>0,m=t&&t.length>0;return{name:"search",title:"Search documentation",description:"Search across the documentation to fetch relevant content for a given query",schema:{type:"object",required:["query"],additionalProperties:!1,properties:{query:{type:"string",description:"Search query. Should be a single word or that phrase that is presented in a documentation.",minLength:1},...h?{product:{type:"string",description:"Optional product name to filter search results by specific product.",enum:[...e,null],nullable:!0}}:{},...m?{locale:{type:"string",description:"Optional locale code to filter search results by documentation language (e.g. 'en', 'ja'). Use the locale matching the language of the user's request. Defaults to the project's default locale.",enum:[...t,null],nullable:!0}}:{}}},annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!1,openWorldHint:!1},outputSchema:{type:"string"}}}const Q=new Set([...I({requiresLogin:!0,hasGraphqlApis:!0,elicitationEnabled:!0,hasCallableApis:!0}).map(e=>e.name),d().name]);export{Q as ALL_DEFAULT_TOOL_NAMES,I as getDefaultToolSchemas};
@@ -1,6 +1,6 @@
1
1
  import c from"node:fs";import f from"node:path";import{MAX_DOCUMENTS_PER_CATEGORY as $}from"../../../constants.js";function j(m,u){return Object.entries(m).map(([h,s])=>{if(!s||s.length===0)return"";const x=s.slice(0,$).map(d=>{const{document:t,highlight:o}=d,p=o?.title||(Array.isArray(t.title)?t.title[0]:t.title);let n=`Document: ${t.title}`;n+=`### [${p}](${t.url})
2
2
 
3
- `;let r;if(t.url)try{let e=t.url.startsWith("/")?t.url.slice(1):t.url;const i=e.indexOf("#");i!==-1&&(e=e.substring(0,i));const l=f.extname(e);l&&(e=e.slice(0,-l.length));let y=e+".md";const a=f.join(u,y);c.existsSync(a)&&(r=c.readFileSync(a,"utf8"))}catch{}return r||(r=o?.text||(Array.isArray(t.text)?t.text[0]:t.text)),n+=r,t.facets&&(n+=`
3
+ `;let r;if(t.url)try{let e=t.url.startsWith("/")?t.url.slice(1):t.url;const i=e.indexOf("#");i!==-1&&(e=e.substring(0,i));const l=f.extname(e);l&&(e=e.slice(0,-l.length));const y=e+".md",a=f.join(u,y);c.existsSync(a)&&(r=c.readFileSync(a,"utf8"))}catch{}return r||(r=o?.text||(Array.isArray(t.text)?t.text[0]:t.text)),n+=r,t.facets&&(n+=`
4
4
 
5
5
  **Categories:**
6
6
  `,Object.entries(t.facets).forEach(([e,i])=>{n+=`- ${e}: ${i}
@@ -1 +1 @@
1
- const s=async(i,e)=>e.user?.isAuthenticated?{content:[{type:"text",text:JSON.stringify({email:e.user.email,name:e.user.claims?.name,subject:e.user.claims?.sub,clientId:e.user.claims?.client_id,scope:e.user.claims?.scope,issuedAt:e.user.claims?.iat?new Date(Number(e.user.claims.iat)*1e3).toISOString():void 0,expiresAt:e.user.claims?.exp?new Date(Number(e.user.claims.exp)*1e3).toISOString():void 0})}],isError:!1}:{content:[{type:"text",text:JSON.stringify({error:"Not authenticated",message:"No valid authentication token found. Please authenticate first."})}],isError:!0};var r={whoami:s};export{r as default};
1
+ const s=async(i,e)=>e.user?.isAuthenticated?{content:[{type:"text",text:JSON.stringify({authenticated:!0,email:e.user.email,name:e.user.claims?.name,subject:e.user.claims?.sub,clientId:e.user.claims?.client_id,scope:e.user.claims?.scope,issuedAt:e.user.claims?.iat?new Date(Number(e.user.claims.iat)*1e3).toISOString():void 0,expiresAt:e.user.claims?.exp?new Date(Number(e.user.claims.exp)*1e3).toISOString():void 0})}]}:{content:[{type:"text",text:JSON.stringify({authenticated:!1})}]};var a={whoami:s};export{a as default};
@@ -1 +1 @@
1
- import{isFetchCapable as h}from"../../../gateway-mcp/callable-apis.js";import{filterApiDescriptionsByName as b}from"../../utils/api-name-matching.js";import{apiTitleKey as y,countApiTitles as T,orderSharedTitles as x}from"../../utils/api-titles.js";const A=async(r,i)=>{const{filter:s,page:l=1,limit:e=300}=r,c=h(i),a=x(Object.values(i.apiDescriptionsMap)),p=T(a);let t=a;s&&(t=b(t,s));const n=(l-1)*e,m=n+e,u=Math.ceil(t.length/e),f=t.length;return t=t.slice(n,m),{content:[{type:"text",text:JSON.stringify({items:t.map(({relativePath:d,fetchEligible:g,...o})=>({filePath:d,...o,...(p.get(y(o.name))??0)>1?{ambiguousTitle:!0}:{},...c?{callable:g===!0}:{}})),limit:e,total:f,page:l,totalPages:u})}]}};var M={"list-apis":A};export{M as default};
1
+ import{getCallableApis as b}from"../../../gateway-mcp/callable-apis.js";import{filterApiDescriptionsByName as d}from"../../utils/api-name-matching.js";import{apiTitleKey as y,countApiTitles as A,orderSharedTitles as T}from"../../utils/api-titles.js";const x=async(r,l)=>{const{filter:s,page:a=1,limit:e=300}=r,n=new Set(b(l).map(i=>i.relativePath)),m=n.size>0,o=T(Object.values(l.apiDescriptionsMap)),f=A(o);let t=o;s&&(t=d(t,s));const c=(a-1)*e,u=c+e,g=Math.ceil(t.length/e),h=t.length;return t=t.slice(c,u),{content:[{type:"text",text:JSON.stringify({items:t.map(({relativePath:i,fetchEligible:D,...p})=>({filePath:i,...p,...(f.get(y(p.name))??0)>1?{ambiguousTitle:!0}:{},...m?{callable:n.has(i)}:{}})),limit:e,total:h,page:a,totalPages:g})}]}};var I={"list-apis":x};export{I as default};
@@ -8,13 +8,22 @@ type EndpointInfo = Pick<OpenAPIOperation, 'summary' | 'description' | 'security
8
8
  path: string;
9
9
  };
10
10
  export declare function getEndpointsFromPaths(def: OpenAPIDefinition): EndpointInfo[];
11
- export declare function getApiDescriptionFromFs({ relativePath, outdir, user, rbac, requiresLogin, }: {
12
- relativePath: string;
13
- outdir: string;
11
+ type ApiDescriptionAccess = {
14
12
  user: ApiFunctionsUser;
15
13
  rbac?: RbacConfig;
16
14
  requiresLogin?: boolean;
15
+ };
16
+ export declare function getApiDescriptionFromFs({ relativePath, outdir, ...access }: ApiDescriptionAccess & {
17
+ relativePath: string;
18
+ outdir: string;
17
19
  }): Promise<OpenAPIDefinition | undefined>;
20
+ /** The bundled description with no RBAC filtering; never return it to a caller. */
21
+ export declare function readApiDescriptionFromFs(relativePath: string, outdir: string): Promise<OpenAPIDefinition | undefined>;
22
+ /**
23
+ * A filtered copy of `definition` holding only what the user can read, or undefined when the user
24
+ * can read none of it; the input is not mutated.
25
+ */
26
+ export declare function filterApiDescriptionByAccess(definition: OpenAPIDefinition, { user, rbac, requiresLogin }: ApiDescriptionAccess): OpenAPIDefinition | undefined;
18
27
  export declare function absolutePath(requestedPath: string): string;
19
28
  /** Models copy a path and lose its casing; the definition's own spelling still answers. */
20
29
  export declare function matchDocumentedPath(description: OpenAPIDefinition, requestedPath: string): string;
@@ -1 +1 @@
1
- import m from"node:path";import{existsSync as f}from"node:fs";import{readFile as u}from"node:fs/promises";import{replaceFileExtension as d}from"../../../../../plugins/api-docs/utils/replace-file-extension.js";import{PUBLIC_API_DEFINITIONS_FOLDER as h}from"../../../../../constants/common.js";import{filterDataByAccessDeep as l}from"../../../../../utils/rbac.js";import{isEndpointHidden as c}from"../../../utils/xmcp-utils.js";import{HTTP_METHODS as x}from"./constants.js";function y(t){return!t||c(t,"docs")?[]:Object.entries(t).filter(r=>{const[e,o]=r;return x.has(e.toLowerCase())&&typeof o=="object"&&o!==null&&!c(o,"docs")})}function P(t){const{paths:r={}}=t,e=[];for(const[o,i]of Object.entries(r))for(const[n,s]of y(i))e.push({path:o,method:n.toUpperCase(),summary:s.summary,description:s.description,security:s.security});return e}async function I({relativePath:t,outdir:r,user:e,rbac:o={},requiresLogin:i=!1}){const n=m.join(r||"",h,d(t,".json"));if(!f(n))return;const a=await u(n,"utf-8"),p=JSON.parse(a);return l(p,{isAuthenticated:e?.isAuthenticated,email:e?.email,teams:e?.teams},o,i)}function D(t){return t.startsWith("/")?t:`/${t}`}function S(t,r){const e=D(r);if(t.paths?.[e])return e;const o=e.toLowerCase();return Object.keys(t.paths??{}).find(n=>n.toLowerCase()===o)??e}export{D as absolutePath,I as getApiDescriptionFromFs,P as getEndpointsFromPaths,S as matchDocumentedPath,y as visibleOperations};
1
+ import a from"node:path";import{existsSync as p}from"node:fs";import{readFile as m}from"node:fs/promises";import{replaceFileExtension as f}from"../../../../../plugins/api-docs/utils/replace-file-extension.js";import{PUBLIC_API_DEFINITIONS_FOLDER as u}from"../../../../../constants/common.js";import{filterDataByAccessDeep as d}from"../../../../../utils/rbac.js";import{isEndpointHidden as c}from"../../../utils/xmcp-utils.js";import{HTTP_METHODS as h}from"./constants.js";function l(t){return!t||c(t,"docs")?[]:Object.entries(t).filter(o=>{const[e,r]=o;return h.has(e.toLowerCase())&&typeof r=="object"&&r!==null&&!c(r,"docs")})}function L(t){const{paths:o={}}=t,e=[];for(const[r,s]of Object.entries(o))for(const[n,i]of l(s))e.push({path:r,method:n.toUpperCase(),summary:i.summary,description:i.description,security:i.security});return e}async function P({relativePath:t,outdir:o,...e}){const r=await y(t,o);return r&&x(r,e)}async function y(t,o){const e=a.join(o||"",u,f(t,".json"));if(p(e))return JSON.parse(await m(e,"utf-8"))}function x(t,{user:o,rbac:e={},requiresLogin:r=!1}){return d(t,{isAuthenticated:o?.isAuthenticated,email:o?.email,teams:o?.teams},e,r)}function D(t){return t.startsWith("/")?t:`/${t}`}function I(t,o){const e=D(o);if(t.paths?.[e])return e;const r=e.toLowerCase();return Object.keys(t.paths??{}).find(n=>n.toLowerCase()===r)??e}export{D as absolutePath,x as filterApiDescriptionByAccess,P as getApiDescriptionFromFs,L as getEndpointsFromPaths,I as matchDocumentedPath,y as readApiDescriptionFromFs,l as visibleOperations};
@@ -1,5 +1,7 @@
1
1
  import type { OpenAPIParameter, Referenced, OpenAPIDefinition } from '@redocly/api-docs';
2
2
  import type { McpEndpoint } from '../../types.js';
3
+ import { resolveRef } from '@redocly/api-docs/lib/utils/inline-openapi-refs.js';
4
+ export { resolveRef };
3
5
  type JsonValue = string | number | boolean | null | JsonValue[] | {
4
6
  [key: string]: JsonValue;
5
7
  };
@@ -10,7 +12,6 @@ export type ResolvedOperation = {
10
12
  operation: JsonObject;
11
13
  components?: Record<string, JsonObject>;
12
14
  };
13
- export declare function resolveRef<T>(ref: string, def?: OpenAPIDefinition): T | undefined;
14
15
  type ResolveOperationParams = {
15
16
  operation: McpEndpoint;
16
17
  pathParams: Referenced<OpenAPIParameter>[];
@@ -22,5 +23,4 @@ export declare function resolveOperation({ operation, pathParams, definition, }:
22
23
  * `maxBytes` or the inliner cannot read the operation.
23
24
  */
24
25
  export declare function inlineOperation({ operation, pathParams, definition }: ResolveOperationParams, maxBytes: number): ResolvedOperation | undefined;
25
- export {};
26
26
  //# sourceMappingURL=resolve-refs.d.ts.map
@@ -1 +1 @@
1
- const S=/^#\/components\/([^/]+)\/([^/]+)(\/.*)?$/;function w(e){return e.replace(/~1/g,"/").replace(/~0/g,"~")}function d(e,s){if(!s||!e?.startsWith("#/"))return;const n=e.slice(2).split("/").map(w);let t=s;for(const r of n)if(typeof t=="object"&&t!==null&&r in t)t=t[r];else return;return t}function h(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function O(e,s){const n={},t=new Set,r=new Set,o=[e];for(;o.length>0;){const c=o.pop();if(!(c===null||typeof c!="object")){if(h(c)&&typeof c.$ref=="string"&&!t.has(c.$ref)){t.add(c.$ref);const[,i,f]=S.exec(c.$ref)??[],u=f&&w(f);if(i&&u&&!r.has(`${i}/${u}`)){const l=d(`#/components/${i}/${f}`,s);l!==void 0&&(r.add(`${i}/${u}`),(n[i]??={})[u]=l,o.push(l))}}for(const i of Object.values(c))o.push(i)}}return Object.keys(n).length>0?n:void 0}function R(e,s){const n=h(e)&&typeof e.$ref=="string"?d(e.$ref,s)??e:e,{name:t,in:r}=h(n)?n:{};return typeof t=="string"&&typeof r=="string"?`${r}:${t}`:JSON.stringify(e)}function g(e,s,n){const t=new Map;for(const r of[...e,...s])r&&t.set(R(r,n),r);return[...t.values()]}function C({operation:e,pathParams:s,definition:n}){const t={...e,parameters:g(s,e.parameters??[],n)};return{operation:t,components:O(t,n)}}class E extends Error{}function j(e,s){if(e.remainingBytes-=s,e.remainingBytes<0)throw new E}function $(e,s){return j(e,JSON.stringify(s).length),s}function m(e,s,n){const t=d(e,s);if(t===void 0)return;const r=n.bytesByRef.get(e)??JSON.stringify(t).length;return n.bytesByRef.set(e,r),j(n,r),t}function y(e,s,n){const t=$(n,Object.fromEntries(Object.entries(e).filter(([r,o])=>r!=="$ref"&&o!==void 0)));return{...s,...t}}function a({schema:e,definition:s,budget:n,visitedRefs:t=new Set,maxDepth:r=50,currentDepth:o=0}){if(!e)return;if(o>=r)return $(n,{type:"object",description:`Maximum resolution depth exceeded (${r})`});if("$ref"in e&&e.$ref){if(t.has(e.$ref))return $(n,{type:"object",description:`Circular reference detected: ${e.$ref}`,"x-circular-ref":e.$ref});const f=new Set(t);f.add(e.$ref);const u=m(e.$ref,s,n);if(!u)return $(n,{type:"object",description:`Could not resolve reference: ${e.$ref}`,"x-unresolved-ref":e.$ref});const l=a({schema:u,definition:s,budget:n,visitedRefs:f,maxDepth:r,currentDepth:o+1});return l&&y(e,l,n)}const c={...e};if(c.properties){const f={};for(const[u,l]of Object.entries(c.properties)){const p=a({schema:l,definition:s,budget:n,visitedRefs:new Set(t),maxDepth:r,currentDepth:o+1});f[u]=p||l}c.properties=f}if(c.items&&typeof c.items=="object")if(Array.isArray(c.items))c.items=c.items.map(f=>a({schema:f,definition:s,budget:n,visitedRefs:new Set(t),maxDepth:r,currentDepth:o+1})||f);else{const f=a({schema:c.items,definition:s,budget:n,visitedRefs:new Set(t),maxDepth:r,currentDepth:o+1});f&&(c.items=f)}return["allOf","anyOf","oneOf"].forEach(f=>{const u=c[f];Array.isArray(u)&&(c[f]=u.reduce((l,p)=>{const v=a({schema:p,definition:s,budget:n,visitedRefs:new Set(t),maxDepth:r,currentDepth:o+1});return v&&l.push(v),l},[]))}),c}function P({pathParams:e,opParams:s,definition:n,budget:t}){return[...e,...s].reduce((r,o)=>{if(!o)return r;if("$ref"in o&&o.$ref){const c=m(o.$ref,n,t);if(!c)return r;const i=y(o,c,t);return r.push({...i,schema:"schema"in i&&i.schema?a({schema:i.schema,definition:n,budget:t}):void 0}),r}return r.push({...o,schema:"schema"in o&&o.schema?a({schema:o.schema,definition:n,budget:t}):void 0}),r},[])}function x(e,s,n){const t={...e};if(e.example!==void 0&&(t.example=e.example),!e.examples)return t;const r={};for(const[o,c]of Object.entries(e.examples))if("$ref"in c){const i=m(c.$ref,s,n);i&&(r[o]=i)}else r[o]=c;return t.examples=r,t}function A(e,s,n){if(!e)return;const t="$ref"in e&&e.$ref?m(e.$ref,s,n):e;if(!t)return;const r=y(e,t,n),o={...r};if("content"in r&&r.content){const c={};for(const[i,f]of Object.entries(r.content))c[i]={...x(f,s,n),schema:f.schema?a({schema:f.schema,definition:s,budget:n}):void 0};o.content=c}return o}function B(e,s,n){if(e)return Object.entries(e).reduce((t,[r,o])=>{const c="$ref"in o&&o.$ref?m(o.$ref,s,n):o;if(!c)return t;const i=y(o,c,n),f={...i};if("content"in i&&i.content){const u={};for(const[l,p]of Object.entries(i.content))u[l]={...x(p,s,n),schema:p.schema?a({schema:p.schema,definition:s,budget:n}):void 0};f.content=u}return t[r]=f,t},{})}function N({operation:e,pathParams:s,definition:n},t){const r={remainingBytes:t,bytesByRef:new Map};try{const o={...e,parameters:P({pathParams:s,opParams:e.parameters||[],definition:n,budget:r}),requestBody:A(e.requestBody,n,r),responses:B(e.responses,n,r)};return{operation:o,components:O(o,n)}}catch{return}}export{N as inlineOperation,C as resolveOperation,d as resolveRef};
1
+ import{resolveParameters as y,resolveRef as p,resolveRequestBody as g,resolveResponses as m,unescapeJsonPointerToken as $}from"@redocly/api-docs/lib/utils/inline-openapi-refs.js";const h=/^#\/components\/([^/]+)\/([^/]+)(\/.*)?$/;function d(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function l(e,o){const n={},s=new Set,t=new Set,r=[e];for(;r.length>0;){const c=r.pop();if(!(c===null||typeof c!="object")){if(d(c)&&typeof c.$ref=="string"&&!s.has(c.$ref)){s.add(c.$ref);const[,f,i]=h.exec(c.$ref)??[],u=i&&$(i);if(f&&u&&!t.has(`${f}/${u}`)){const a=p(`#/components/${f}/${i}`,o);a!==void 0&&(t.add(`${f}/${u}`),(n[f]??={})[u]=a,r.push(a))}}for(const f of Object.values(c))r.push(f)}}return Object.keys(n).length>0?n:void 0}function b(e,o){const n=d(e)&&typeof e.$ref=="string"?p(e.$ref,o)??e:e,{name:s,in:t}=d(n)?n:{};return typeof s=="string"&&typeof t=="string"?`${t}:${s}`:JSON.stringify(e)}function O(e,o,n){const s=new Map;for(const t of[...e,...o])t&&s.set(b(t,n),t);return[...s.values()]}function x({operation:e,pathParams:o,definition:n}){const s={...e,parameters:O(o,e.parameters??[],n)};return{operation:s,components:l(s,n)}}class w extends Error{}function B(e){let o=e;const n=new Map;return(s,t)=>{let r=t===void 0?void 0:n.get(t);if(r===void 0&&(r=JSON.stringify(s).length,t!==void 0&&n.set(t,r)),o-=r,o<0)throw new w}}function R({operation:e,pathParams:o,definition:n},s){const t=B(s);try{const r={...e,parameters:y({pathParams:o,opParams:e.parameters||[],definition:n,charge:t}),requestBody:g(e.requestBody,n,t),responses:e.responses&&m(e.responses,n,t)};return{operation:r,components:l(r,n)}}catch{return}}export{R as inlineOperation,x as resolveOperation,p as resolveRef};
@@ -0,0 +1,11 @@
1
+ import type { RedoclyConfig } from '@redocly/config';
2
+ export type ApiCallsConfig = NonNullable<NonNullable<RedoclyConfig['mcp']>['apiCalls']>;
3
+ type ApiCallsHttpMethod = NonNullable<ApiCallsConfig['allowedHttpMethods']>[number];
4
+ /** The methods agents may send when `mcp.apiCalls.allowedHttpMethods` is not set. */
5
+ export declare const DEFAULT_ALLOWED_HTTP_METHODS: readonly ApiCallsHttpMethod[];
6
+ /** Upper-case HTTP methods agents may send; read-only unless `redocly.yaml` allows more. */
7
+ export declare function getAllowedHttpMethods(mcp: RedoclyConfig['mcp'] | undefined): string[];
8
+ /** Whether every allowed method is safe by HTTP semantics (`GET`, `HEAD`, `OPTIONS`). */
9
+ export declare function allowsOnlySafeHttpMethods(mcp: RedoclyConfig['mcp'] | undefined): boolean;
10
+ export {};
11
+ //# sourceMappingURL=allowed-http-methods.d.ts.map
@@ -0,0 +1 @@
1
+ const o=["GET","HEAD","OPTIONS"],r={GET:!0,HEAD:!0,OPTIONS:!0};function T(t){return(t?.apiCalls?.allowedHttpMethods??o).map(e=>e.toUpperCase())}function p(t){return T(t).every(e=>r[e])}export{o as DEFAULT_ALLOWED_HTTP_METHODS,p as allowsOnlySafeHttpMethods,T as getAllowedHttpMethods};
@@ -0,0 +1,32 @@
1
+ import type { OpenAPIDefinition, OpenAPIServer } from '@redocly/api-docs';
2
+ export type ApiCallOperation = {
3
+ pattern: RegExp;
4
+ /** Upper case. */
5
+ method: string;
6
+ /**
7
+ * False when `x-mcp.apiCalls.hide` or `x-mcp.docs.hide` on the path item or operation, or an
8
+ * `mcp.apiCalls.excludeOperations` entry, excludes it.
9
+ */
10
+ callable: boolean;
11
+ /**
12
+ * False when RBAC hides the operation from the caller. The bridge then answers as for an
13
+ * undocumented path, so the reply does not reveal that the operation exists.
14
+ */
15
+ visible: boolean;
16
+ /** Number of `{variable}` segments in the path; fewer is more specific. */
17
+ variables: number;
18
+ };
19
+ /** An `mcp.apiCalls.excludeOperations` entry of one API; no `method` excludes every method of `path`. */
20
+ export type ExcludedOperation = {
21
+ method?: string;
22
+ path: string;
23
+ };
24
+ /**
25
+ * Every operation of the unfiltered `description`, with the ones missing from `visibleDescription`,
26
+ * the caller's RBAC-filtered copy, marked not visible. A hidden or `excluded` operation stays in the
27
+ * list, so a less specific template cannot claim its requests.
28
+ */
29
+ export declare function apiCallOperationsOf(description: OpenAPIDefinition, visibleDescription: OpenAPIDefinition, servers: readonly OpenAPIServer[], excluded?: readonly ExcludedOperation[]): ApiCallOperation[];
30
+ /** The documented operations that an upper-case `method` on `pathname` matches. */
31
+ export declare function matchingApiCallOperations(operations: readonly ApiCallOperation[], pathname: string, method: string): ApiCallOperation[];
32
+ //# sourceMappingURL=api-call-operations.d.ts.map
@@ -0,0 +1 @@
1
+ import{OPERATION_METHODS as P}from"../docs-mcp/tools/openapi/constants.js";import{isEndpointHidden as u}from"../utils/xmcp-utils.js";import{basePathPrefix as T,operationHttpMethod as d,pathPattern as y,pathTemplateKey as C,pathVariableCount as H}from"./route-pattern.js";const M=new Set(P);function m(t){return u(t,"apiCalls")||u(t,"docs")}function w(t,n,i,a=[]){const b=T(i),c=new Set(a.map(({method:e,path:o})=>p(e&&d(e),o))),f=[];for(const[e,o]of Object.entries(t.paths??{})){if(!o||typeof o!="object")continue;const h=y(b,e);if(!h)continue;const O=m(o)||c.has(p(void 0,e)),x=n.paths?.[e],E=H(e);for(const[r,s]of Object.entries(o)){if(!M.has(r.toLowerCase())||!s||typeof s!="object")continue;const l=d(r);f.push({pattern:h,method:l,callable:!O&&!m(s)&&!c.has(p(l,e)),visible:!!x?.[r],variables:E})}}return f}function p(t,n){return`${t??"*"} ${C(n)}`}function I(t,n,i){return t.filter(a=>a.method===i&&a.pattern.test(n))}export{w as apiCallOperationsOf,I as matchingApiCallOperations};
@@ -1,10 +1,13 @@
1
1
  import type { ApiDescriptionInfo, McpToolContext } from '../types.js';
2
- export declare function getCallableApis(context: McpToolContext): ApiDescriptionInfo[];
2
+ import type { ExcludedOperation } from './api-call-operations.js';
3
3
  /**
4
- * Fetch capability at request/worker time is derived purely from the build-time stamps:
5
- * `fetchEligible` is stamped per API by the lifecycle plugin under `isGatewayCapabilityEnabled`
6
- * (entitlement + hide checks), and the map arriving here is already RBAC-filtered.
4
+ * The APIs an agent may call in this request: the build-stamped `fetchEligible` entries of the
5
+ * already RBAC-filtered map, minus what `mcp.apiCalls` removes. The config is read from the
6
+ * request context, so a `redocly.yaml` edit applies without restarting the dev server.
7
7
  * No EntitlementsProvider read — this code runs in graphs where the provider is uninitialized.
8
8
  */
9
+ export declare function getCallableApis(context: McpToolContext): ApiDescriptionInfo[];
10
+ /** The `mcp.apiCalls.excludeOperations` entries whose `file` glob matches the API at `relativePath`. */
11
+ export declare function getExcludedOperations(context: McpToolContext, relativePath: string): ExcludedOperation[];
9
12
  export declare function isFetchCapable(context: McpToolContext): boolean;
10
13
  //# sourceMappingURL=callable-apis.d.ts.map
@@ -1 +1 @@
1
- function i(e){return Object.values(e.apiDescriptionsMap??{}).filter(t=>t.fetchEligible)}function l(e){return i(e).length>0}export{i as getCallableApis,l as isFetchCapable};
1
+ import c from"picomatch";function r(e){const i=e.config?.mcp?.apiCalls;if(i?.hide)return[];const t=c(i?.excludeFiles??[]);return Object.values(e.apiDescriptionsMap??{}).filter(l=>l.fetchEligible&&!t(l.relativePath))}function n(e,i){return(e.config?.mcp?.apiCalls?.excludeOperations??[]).filter(({file:t})=>c.isMatch(i,t))}function p(e){return r(e).length>0}export{r as getCallableApis,n as getExcludedOperations,p as isFetchCapable};
@@ -0,0 +1,9 @@
1
+ import type { RedoclyConfig } from '@redocly/config';
2
+ /**
3
+ * `mcp` with `apiCalls` narrowed by the caller's `metadata.apiCalls` (`hide`, `allowedHttpMethods`),
4
+ * which the AI Assistant fills from `aiAssistant.mcp.apiCalls`. The caller can only take API calls
5
+ * or methods away: a value of another shape changes nothing, and a method list that keeps none of
6
+ * the project's methods turns API calls off.
7
+ */
8
+ export declare function narrowMcpConfigForCaller(mcp: RedoclyConfig['mcp'], metadata: Record<string, unknown> | undefined): RedoclyConfig['mcp'];
9
+ //# sourceMappingURL=caller-api-calls.d.ts.map
@@ -0,0 +1 @@
1
+ import{DEFAULT_ALLOWED_HTTP_METHODS as d}from"./allowed-http-methods.js";function h(e,a){const o=a?.apiCalls;if(!o||typeof o!="object")return e;const{hide:i,allowedHttpMethods:s}=o,t={...e?.apiCalls};if(i===!0&&(t.hide=!0),Array.isArray(s)){const n=new Set(s.map(r=>String(r).toUpperCase())),l=(e?.apiCalls?.allowedHttpMethods??d).filter(r=>n.has(r));l.length===0?t.hide=!0:t.allowedHttpMethods=l}return{...e,apiCalls:t}}export{h as narrowMcpConfigForCaller};
@@ -1 +1 @@
1
- const r=/[\r\n]/,o=255;function a(n){for(let e=0;e<n.length;e+=1){const t=n.charCodeAt(e);if(t===0||t>255)return!0}return!1}function s(n,e){if(!e)return"Enter a value before saving.";if(r.test(e))return"The value contains a line break. Paste it as a single line and save again.";if(a(e))return"The value contains a character that cannot be sent in an HTTP header, such as a curly quote or an invisible character. Copy the value again as plain text and save.";if(n.kind==="cookie")return i(n.name,e)}function i(n,e){if(e.includes(";")||e.toLowerCase().includes(`${n.toLowerCase()}=`))return`This looks like a whole cookie header. Paste only the value of the ${n} cookie, without the "${n}=" prefix and without any other name=value pairs.`}function c(n,e){if(!(!r.test(e)&&!a(e)))throw new Error(`The credential cannot be sent as the ${n} header value.`)}export{c as assertHeaderSafe,s as rejectCredential};
1
+ const r=/[\r\n]/,s=255,i=/^bearer$/i;function a(t){for(let e=0;e<t.length;e+=1){const n=t.charCodeAt(e);if(n===0||n>255)return!0}return!1}function c(t,e){if(!e)return"Enter a value before saving.";if(r.test(e))return"The value contains a line break. Paste it as a single line and save again.";if(a(e))return"The value contains a character that cannot be sent in an HTTP header, such as a curly quote or an invisible character. Copy the value again as plain text and save.";if(t.kind==="cookie")return o(t.name,e);if((t.kind==="bearer"||t.kind==="oauth2ClientCredentials")&&i.test(e))return"Paste the token that follows the word Bearer, not only the word."}function o(t,e){if(e.includes(";")||e.toLowerCase().includes(`${t.toLowerCase()}=`))return`This looks like a whole cookie header. Paste only the value of the ${t} cookie, without the "${t}=" prefix and without any other name=value pairs.`}function h(t,e){if(!(!r.test(e)&&!a(e)))throw new Error(`The credential cannot be sent as the ${t} header value.`)}export{h as assertHeaderSafe,c as rejectCredential};
@@ -8,6 +8,7 @@ export type CredentialTarget = {
8
8
  name: string;
9
9
  scheme: string;
10
10
  schemeLabel?: string;
11
+ acceptedSchemes?: string[];
11
12
  };
12
13
  /**
13
14
  * Why the prompt is being raised. `authFailure` is the automatic path behind an upstream 401;
@@ -1,5 +1,5 @@
1
- import{inputRequired as h,inputResponse as y}from"@modelcontextprotocol/server";import{withPathPrefix as I}from"@redocly/theme/core/utils";import{MCP_CREDENTIALS_ROUTE as A}from"../../../constants/mcp.js";import{MANAGE_API_CREDENTIALS_TOOL_NAME as u}from"../constants.js";import{secretStore as l,ELICITATION_TTL_MS as P}from"./secret-store.js";import{operationsForScheme as E,orderedSchemesOf as g}from"./upstream-auth-scheme.js";import{ANONYMOUS_SUBJECT_PREFIX as p}from"./subject.js";const m="credentials",d=new Map;function F(e,t){const r=d.get(e);if(r)return r;const n=t().finally(()=>{d.delete(e)});return d.set(e,n),n}function D(e){return!!e?.elicitation?.url}function H(e){return e.envelope!==void 0}function q(e){const t=y(e,m);if(t.kind==="elicit")return t.action==="accept"?"accepted":"declined"}function B(e,t){return[`The user accepted the prompt to add credentials for the "${e}" API.`,...t?["The credentials page:",t]:[],"",`Wait until the user says they saved the credentials, then retry the call that needed them. Do not call \`${u}\` again unless the user asks for a new link.`].join(`
2
- `)}async function Y(e,{kv:t,subject:r,baseUrl:n,apis:o}){if(typeof e!="string")return;const i=await l.peekElicitation(t,e);if(!(i?.subject!==r||!o.includes(i.api)))return{apiName:i.name,url:T(n,e)}}function W(e,t){return Object.keys(e).length>1?t:void 0}async function z(e){const{token:t,url:r}=await f(e);return h({inputRequests:{[m]:h.elicitUrl({message:C(e),url:r})},requestState:t})}async function G(e){const{url:t}=await f(e);return _(e,t,S(e.subject))}function J(e,t){const r=b(e);if(e.status===401&&!e.sentScheme){const[i,s]=e.callerHeader?[`Your code set the "${e.callerHeader}" header itself, so the stored credential was not sent.`,"Remove that header from the request and retry. Do not replace the stored credentials."]:["No stored credential was sent with this request, so this result says nothing about the stored credentials.","Do not replace them. Check whether this operation needs a different kind of credential or a different route."];return[`The "${e.name}" API returned ${r}. ${i}`,"",s].join(`
3
- `)}const n=e.status===401?`The "${e.name}" API rejected the stored ${t?`"${t}" `:""}credential (${r}).`:`The "${e.name}" API rejected the request with ${r}.`,o=t?`api: "${e.api}" and scheme: "${t}"`:`api: "${e.api}"`;return[n,"",`Do not retry the same call. Call \`${u}\` with ${o} to get a link the user has to open in a browser to replace or remove the stored credentials, then retry once they confirm they saved them.`].join(`
4
- `)}function b({status:e,detail:t}){return t?`HTTP ${e}: ${t}`:`HTTP ${e}`}async function f({kv:e,subject:t,baseUrl:r,target:n,auth:o,apiAuth:i,hasExistingSecret:s}){const a=i?await k(e,t,n.api,i):[],c=await l.createElicitation(e,{subject:t,api:n.api,name:n.name,scheme:n.scheme,...n.schemeLabel?{schemeLabel:n.schemeLabel}:{},auth:o,hasExistingSecret:s,...a.length>1?{schemes:a}:{}});return{token:c,url:T(r,c)}}async function k(e,t,r,n){const i=(await l.getSecretsForSubject(e,t))[r]??{};return g(n.schemes).map(s=>{const a=E(n,s),c=n.descriptions?.[s];return{name:s,...c?{label:c}:{},auth:n.schemes[s],hasExistingSecret:!!i[s],...a.length>0?{operations:a}:{}}})}function S(e){return e.startsWith(p)?e.slice(p.length):void 0}function C({target:e,hasExistingSecret:t,reason:r}){const n=`The link works for ${$()} minutes.`,o=x(e),i=r.kind==="authFailure"&&r.detail?` The API answered: ${r.detail}.`:"";return t?`Open this page in a browser to replace or remove the stored credentials for ${o}. They go straight to the API and never enter the chat. ${n}`:`${O(o)} needs credentials.${i} Open this page in a browser to paste them - they go straight to the API and never enter the chat. ${n}`}function x({name:e,schemeLabel:t}){return t?`the "${t}" scheme of the "${e}" API`:`the "${e}" API`}function O(e){return e.charAt(0).toUpperCase()+e.slice(1)}function $(){return Math.round(P/6e4)}function T(e,t){const r=I(A);if(!e)return`${r}?token=${t}`;try{const n=new URL(r,e);return n.searchParams.set("token",t),n.toString()}catch{return`${e}${r}?token=${t}`}}function _({target:e,reason:t,hasExistingSecret:r},n,o){const s=[`**Stop and show the user this link. They have to open it in a browser to ${r?`replace or remove the stored credentials for the "${e.name}" API`:`add credentials for the "${e.name}" API`} - nothing continues until they do.**`,"",n,"",`The link is valid ${$()} minutes and opens a form on this site. Credentials go straight to the API from there: never ask for them in the conversation and never pass them as a tool argument.`,"",t.kind==="authFailure"?`The upstream API "${e.name}" returned ${t.status}${t.detail?` (${t.detail})`:""} and needs credentials.`:r?`Credentials are already stored for the "${e.name}" API; the link lets the user replace or remove them.`:`The "${e.name}" API needs credentials.`,...e.schemeLabel?[`The operation authenticates with its "${e.schemeLabel}" security scheme.`]:[],o?`Once the user confirms they saved them, call this tool again with sessionHandle: "${o}" - the credentials are stored against that handle, applied server-side, and never appear in the conversation.`:"Once the user confirms they saved them, call this tool again - the credentials are applied server-side and never appear in the conversation."],a=t.kind==="authFailure"?t.otherApiNames??[]:[];if(a.length>0){const c=a.map(w=>`"${w}"`).join(", ");s.push("",`The remaining APIs (${c}) will prompt for credentials on subsequent calls.`)}return s.join(`
5
- `)}export{m as CREDENTIALS_INPUT_REQUEST_KEY,Y as acceptedCredentialsLink,B as buildCredentialsAcceptedHint,J as buildCredentialsToolHint,G as buildUpstreamCredentialFallback,z as buildUpstreamCredentialInputRequired,q as credentialElicitationAnswer,F as dedupeElicitation,H as isStatelessRequest,W as schemeLabelOf,D as supportsUrlElicitation};
1
+ import{inputRequired as d,inputResponse as I}from"@modelcontextprotocol/server";import{withPathPrefix as w}from"@redocly/theme/core/utils";import{MCP_CREDENTIALS_ROUTE as E}from"../../../constants/mcp.js";import{MANAGE_API_CREDENTIALS_TOOL_NAME as h}from"../constants.js";import{secretStore as l,ELICITATION_TTL_MINUTES as u}from"./secret-store.js";import{operationsForScheme as A,orderedSchemesOf as P}from"./upstream-auth-scheme.js";import{ANONYMOUS_SUBJECT_PREFIX as p}from"./subject.js";const m="credentials",c=new Map;function F(e,t){const n=c.get(e);if(n)return n;const i=t().finally(()=>{c.delete(e)});return c.set(e,i),i}function M(e){return!!e?.elicitation?.url}function D(e){return e.envelope!==void 0}function H(e){const t=I(e,m);if(t.kind==="elicit")return t.action==="accept"?"accepted":"declined"}function q(e,t){return[`The user accepted the prompt to add credentials for the "${e}" API.`,...t?["The credentials page:",t]:[],"",`Wait until the user says they saved the credentials, then retry the call that needed them. Do not call \`${h}\` again unless the user asks for a new link.`].join(`
2
+ `)}async function B(e,{kv:t,subject:n,baseUrl:i,apis:r}){if(typeof e!="string")return;const s=await l.peekElicitation(t,e);if(!(s?.subject!==n||!r.includes(s.api)))return{apiName:s.name,url:$(i,e)}}function W(e,t){return Object.keys(e).length>1?t:void 0}async function Y(e){const{token:t,url:n}=await f(e);return d({inputRequests:{[m]:d.elicitUrl({message:C(e),url:n})},requestState:t})}async function z(e){const{url:t}=await f(e);return x(e,t,S(e.subject))}function G(e,t){const n=b(e);if(e.status===401&&!e.sentScheme)return[`The "${e.name}" API returned ${n}. No stored credential was sent with this request, so this result says nothing about the stored credentials.`,"","Do not replace them. Check whether this operation needs a different kind of credential or a different route."].join(`
3
+ `);const i=e.status===401?`The "${e.name}" API rejected the stored ${t?`"${t}" `:""}credential (${n}).`:`The "${e.name}" API rejected the request with ${n}.`,r=t?`api: "${e.api}" and scheme: "${t}"`:`api: "${e.api}"`;return[i,"",`Do not retry the same call. Call \`${h}\` with ${r} to get a link the user has to open in a browser to replace or remove the stored credentials, then retry once they confirm they saved them.`].join(`
4
+ `)}function b({status:e,detail:t}){return t?`HTTP ${e}: ${t}`:`HTTP ${e}`}async function f({kv:e,subject:t,baseUrl:n,target:i,auth:r,apiAuth:s}){const a=s?k(s):[],o=await l.createElicitation(e,{subject:t,api:i.api,name:i.name,scheme:i.scheme,...i.schemeLabel?{schemeLabel:i.schemeLabel}:{},auth:r,...a.length>1?{schemes:a}:{},...a.length>1&&i.acceptedSchemes?{acceptedSchemes:i.acceptedSchemes}:{}});return{token:o,url:$(n,o)}}function k(e){return P(e.schemes).map(t=>{const n=A(e,t),i=e.descriptions?.[t];return{name:t,...i?{label:i}:{},auth:e.schemes[t],...n.length>0?{operations:n}:{}}})}function S(e){return e.startsWith(p)?e.slice(p.length):void 0}function C({target:e,hasExistingSecret:t,reason:n}){const i=`The link works for ${u} minutes.`,r=O(e),s=n.kind==="authFailure"&&n.detail?` The API answered: ${n.detail}.`:"";return t?`Open this page in a browser to replace or remove the stored credentials for ${r}. They stay out of the chat. ${i}`:`${g(r)} needs credentials.${s} Open this page in a browser to paste them - they stay out of the chat. ${i}`}function O({name:e,schemeLabel:t}){return t?`the "${t}" scheme of the "${e}" API`:`the "${e}" API`}function g(e){return e.charAt(0).toUpperCase()+e.slice(1)}function $(e,t){const n=w(E);if(!e)return`${n}?token=${t}`;try{const i=new URL(n,e);return i.searchParams.set("token",t),i.toString()}catch{return`${e}${n}?token=${t}`}}function x({target:e,reason:t,hasExistingSecret:n},i,r){const a=[`**Stop and show the user this link. They have to open it in a browser to ${n?`replace or remove the stored credentials for the "${e.name}" API`:`add credentials for the "${e.name}" API`} - nothing continues until they do.**`,"",i,"",`The link is valid ${u} minutes and opens a form on this site. The site stores the credentials and adds them to API calls: never ask for them in the conversation and never pass them as a tool argument.`,"",t.kind==="authFailure"?`The upstream API "${e.name}" returned ${t.status}${t.detail?` (${t.detail})`:""} and needs credentials.`:n?`Credentials are already stored for the "${e.name}" API; the link lets the user replace or remove them.`:`The "${e.name}" API needs credentials.`,...e.schemeLabel?[`The operation authenticates with its "${e.schemeLabel}" security scheme.`]:[],r?`Once the user confirms they saved them, retry the call that needed them with sessionHandle: "${r}" - the credentials are stored against that handle, applied server-side, and never appear in the conversation.`:"Once the user confirms they saved them, retry the call that needed them - the credentials are applied server-side and never appear in the conversation."],o=t.kind==="authFailure"?t.otherApiNames??[]:[];if(o.length>0){const T=o.map(y=>`"${y}"`).join(", ");a.push("",`The remaining APIs (${T}) will prompt for credentials on subsequent calls.`)}return a.join(`
5
+ `)}export{m as CREDENTIALS_INPUT_REQUEST_KEY,B as acceptedCredentialsLink,q as buildCredentialsAcceptedHint,G as buildCredentialsToolHint,z as buildUpstreamCredentialFallback,Y as buildUpstreamCredentialInputRequired,H as credentialElicitationAnswer,F as dedupeElicitation,D as isStatelessRequest,W as schemeLabelOf,M as supportsUrlElicitation};
@@ -1,9 +1,13 @@
1
1
  import type { OpenAPIDefinition, OpenAPIMcp } from '@redocly/api-docs';
2
- import type { RbacConfig, RedoclyConfig } from '@redocly/config';
2
+ import type { RedoclyConfig } from '@redocly/config';
3
3
  /** Whether the gateway fetch capability is on: the feature flag plus none of mcp/docs hidden. */
4
4
  export declare function isGatewayCapabilityEnabled(mcp?: RedoclyConfig['mcp']): boolean;
5
- /** Whether an API is eligible for the gateway (fetch-capable `execute` + `/mcp` advertisement). */
6
- export declare function isGatewayEligible(info: OpenAPIDefinition['info'] | undefined, relativePath: string, rbacConfig: RbacConfig): boolean;
5
+ /**
6
+ * Whether the API description allows agent calls: every documented API does unless its
7
+ * `info.x-mcp.apiCalls.hide` is set. Who may call it is decided per request by RBAC, and
8
+ * `mcp.apiCalls` config by `getCallableApis`.
9
+ */
10
+ export declare function isGatewayEligible(info: OpenAPIDefinition['info'] | undefined): boolean;
7
11
  /**
8
12
  * Whether an API docs page advertises the `/mcp` endpoint via an injected root-level x-mcp:
9
13
  * the capability is on, the author has not provided their own x-mcp servers, and the API is
@@ -13,6 +17,6 @@ export declare function shouldAdvertiseGatewayXMcp(definition: (OpenAPIDefinitio
13
17
  'x-mcp'?: {
14
18
  servers?: unknown[];
15
19
  };
16
- }) | undefined, relativePath: string, rbacConfig: RbacConfig, mcpConfig?: RedoclyConfig['mcp']): boolean;
20
+ }) | undefined, relativePath: string, mcpConfig?: RedoclyConfig['mcp']): boolean;
17
21
  export declare function buildGatewayXMcp(url: string): OpenAPIMcp;
18
22
  //# sourceMappingURL=eligibility.d.ts.map
@@ -1 +1 @@
1
- import{join as e}from"node:path";import{PUBLIC_API_DEFINITIONS_FOLDER as s}from"../../../constants/common.js";import{ANONYMOUS_AUTH_DETAILS as n}from"../../../constants/rbac.js";import{canDownloadApiDefinition as a}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,r,i){return m(o,"gateway")?!1:a(e(s,r),i,!1,n)||f(o)}function _(o,r,i,t){return u(t)&&!o?.["x-mcp"]?.servers?.length&&d(o?.info,r,i)&&c(r,o,t)}function G(o){return{protocolVersion:p,capabilities:{tools:{}},servers:[{url:o}],tools:[],resources:[],prompts:[]}}export{G as buildGatewayXMcp,u as isGatewayCapabilityEnabled,d as isGatewayEligible,_ as shouldAdvertiseGatewayXMcp};
1
+ import{MCP_PROTOCOL_VERSION as t}from"../constants.js";import{isApiIncludedInDocsMcp as i}from"../utils.js";import{isMcpGatewayEnabled as s}from"../utils/mode.js";import{isDefinitionHidden as a}from"../utils/xmcp-utils.js";function p(e){return s()&&!e?.hide&&!e?.docs?.hide}function n(e){return!a(e,"apiCalls")}function m(e,o,r){return p(r)&&!e?.["x-mcp"]?.servers?.length&&n(e?.info)&&i(o,e,r)}function f(e){return{protocolVersion:t,capabilities:{tools:{}},servers:[{url:e}],tools:[],resources:[],prompts:[]}}export{f as buildGatewayXMcp,p as isGatewayCapabilityEnabled,n as isGatewayEligible,m as shouldAdvertiseGatewayXMcp};
@@ -6,6 +6,7 @@ type GatewayFetchAuditRecord = {
6
6
  outcome: GatewayFetchOutcome;
7
7
  durationMs: number;
8
8
  injectedSecretValues: readonly string[];
9
+ credentialQueryParams?: readonly string[];
9
10
  path?: string;
10
11
  api?: string;
11
12
  status?: number;
@@ -20,6 +21,6 @@ type GatewayFetchAuditRecord = {
20
21
  * telemetry event verbatim so a Grafana row joins onto this line; `url_sha256` identifies the
21
22
  * request itself, since the telemetry event's `path` is deliberately normalized.
22
23
  */
23
- export declare function logGatewayFetchAudit({ rawUrl, method, host, outcome, durationMs, injectedSecretValues, path, api, status, injectedScheme, requestHeaders, requestBody, responseHeaders, responseBody, }: GatewayFetchAuditRecord): void;
24
+ export declare function logGatewayFetchAudit({ rawUrl, method, host, outcome, durationMs, injectedSecretValues, credentialQueryParams, path, api, status, injectedScheme, requestHeaders, requestBody, responseHeaders, responseBody, }: GatewayFetchAuditRecord): void;
24
25
  export {};
25
26
  //# sourceMappingURL=fetch-audit.d.ts.map
@@ -1 +1 @@
1
- import{auditHeaderNames as n,auditInput as g,auditOutputDigest as b,auditSha256 as l,auditUrl as y,logAuditRecord as A}from"../../audit/audit-log.js";function R({rawUrl:e,method:u,host:i,outcome:r,durationMs:o,injectedSecretValues:t,path:_,api:h,status:f,injectedScheme:m,requestHeaders:p,requestBody:d,responseHeaders:c,responseBody:s}){const a=s===void 0?void 0:b(s);A("Record gateway fetch",{url_sha256:l(e),host:i,method:u,path:_,api:h,outcome:r,status:f,injected_scheme:m,duration_ms:o,url:y(e,t),request_header_names:n(p),request_body:d===void 0?void 0:g(d,t),response_header_names:n(c),response_sha256:a?.sha256,response_bytes:a?.bytes})}export{R as logGatewayFetchAudit};
1
+ import{auditHeaderNames as n,auditInput as b,auditOutputDigest as l,auditSha256 as y,auditUrl as A,logAuditRecord as D}from"../../audit/audit-log.js";function q({rawUrl:e,method:u,host:i,outcome:r,durationMs:o,injectedSecretValues:t,credentialQueryParams:_,path:h,api:f,status:m,injectedScheme:p,requestHeaders:c,requestBody:d,responseHeaders:g,responseBody:s}){const a=s===void 0?void 0:l(s);D("Record gateway fetch",{url_sha256:y(e),host:i,method:u,path:h,api:f,outcome:r,status:m,injected_scheme:p,duration_ms:o,url:A(e,t,_),request_header_names:n(c),request_body:d===void 0?void 0:b(d,t),response_header_names:n(g),response_sha256:a?.sha256,response_bytes:a?.bytes})}export{q as logGatewayFetchAudit};
@@ -2,6 +2,7 @@ import { Agent, type Dispatcher } from 'undici';
2
2
  import type { SandboxFetch } from '../../codemode/types.js';
3
3
  import type { UpstreamAuthRequiredEvent } from '../upstream-auth.js';
4
4
  import type { StoredSecret } from '../secret-store.js';
5
+ import { type ApiCallOperation } from '../api-call-operations.js';
5
6
  export declare function getDefaultAgent(): Agent;
6
7
  export type FetchBridgeRoute = {
7
8
  pattern: RegExp;
@@ -16,7 +17,13 @@ export type FetchBridgeApi = {
16
17
  defaultScheme?: string;
17
18
  routes?: readonly FetchBridgeRoute[];
18
19
  credentialHeaders?: readonly string[];
20
+ credentialQueryParams?: readonly string[];
19
21
  schemePriority?: readonly string[];
22
+ /**
23
+ * The documented operations agents may reach on this API's hosts; see `apiCallOperationsOf`.
24
+ * Undefined puts no path restriction on the API.
25
+ */
26
+ operations?: readonly ApiCallOperation[];
20
27
  };
21
28
  type FetchBridgeOptions = {
22
29
  allowedHosts: readonly RegExp[];
@@ -28,10 +35,13 @@ type FetchBridgeOptions = {
28
35
  timeoutMs?: number;
29
36
  maxResponseBytes?: number;
30
37
  maxFetchesPerExec?: number;
38
+ beforeSend?: () => Promise<void>;
31
39
  clientIp?: string;
40
+ /** Upper-case methods that may reach the network (`mcp.apiCalls.allowedHttpMethods`); undefined allows all. */
41
+ allowedHttpMethods?: readonly string[];
32
42
  };
33
43
  /** Build the host-side `fetch` the gateway sandbox calls. */
34
- export declare function buildFetchBridge({ allowedHosts, apis, authorization, onAuthRequired, fetchImpl, dispatcher, timeoutMs, maxResponseBytes, maxFetchesPerExec, clientIp, }: FetchBridgeOptions): SandboxFetch;
44
+ export declare function buildFetchBridge({ allowedHosts, apis, authorization, onAuthRequired, fetchImpl, dispatcher, timeoutMs, maxResponseBytes, maxFetchesPerExec, beforeSend, clientIp, allowedHttpMethods, }: FetchBridgeOptions): SandboxFetch;
35
45
  export declare function readCappedBody(response: Response, maxBytes: number): Promise<string>;
36
46
  export {};
37
47
  //# sourceMappingURL=fetch-bridge.d.ts.map