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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (296) hide show
  1. package/CHANGELOG.md +182 -0
  2. package/dist/bin.js +0 -0
  3. package/dist/cli/build/analytics/collect-analytics.js +1 -1
  4. package/dist/cli/build/analytics/collectors/get-sidebars-usage.d.ts +12 -0
  5. package/dist/cli/build/analytics/collectors/get-sidebars-usage.js +1 -0
  6. package/dist/cli/build/index.js +1 -1
  7. package/dist/cli/develop.js +1 -1
  8. package/dist/cli/eject/resolveEjectParams.js +1 -1
  9. package/dist/cli/generate/string-utils.js +1 -1
  10. package/dist/cli/stats/collectors/extension-sampling.js +1 -1
  11. package/dist/cli/translations/collect-config-translations.js +1 -1
  12. package/dist/client/App.js +1 -1
  13. package/dist/client/TestProvider.d.ts +3 -1
  14. package/dist/client/TestProvider.js +1 -1
  15. package/dist/client/app/Link.js +1 -1
  16. package/dist/client/app/ReviewComments/ReviewComments.js +2 -2
  17. package/dist/client/app/Sidebar/Sidebar.js +1 -1
  18. package/dist/client/app/Sidebar/useSidebarItems.js +1 -1
  19. package/dist/client/app/hooks/codeHighlight/treeview-transformer.js +1 -1
  20. package/dist/client/app/hooks/codeHighlight/useCodeHighlight.js +1 -1
  21. package/dist/client/app/hooks/index.d.ts +1 -0
  22. package/dist/client/app/hooks/index.js +1 -1
  23. package/dist/client/app/hooks/markdown/useMarkdownText.js +1 -1
  24. package/dist/client/app/hooks/useConsent.d.ts +11 -0
  25. package/dist/client/app/hooks/useConsent.js +1 -0
  26. package/dist/client/app/l10n/L10nContext.d.ts +10 -0
  27. package/dist/client/app/l10n/L10nContext.js +1 -0
  28. package/dist/client/app/l10n/hooks/useL10n.js +1 -1
  29. package/dist/client/app/l10n/hooks/useTranslate.js +1 -1
  30. package/dist/client/app/l10n/hooks/useTranslationKeys.d.ts +2 -0
  31. package/dist/client/app/l10n/hooks/useTranslationKeys.js +1 -1
  32. package/dist/client/app/l10n/ssrL10n.d.ts +4 -0
  33. package/dist/client/app/l10n/ssrL10n.js +1 -0
  34. package/dist/client/app/markdoc/custom-components/openapi/openapi-example.js +1 -1
  35. package/dist/client/app/markdoc/custom-components/openapi/openapi-response-sample.js +1 -1
  36. package/dist/client/app/markdoc/custom-components/openapi/replay-openapi.js +1 -1
  37. package/dist/client/app/markdoc/hooks/use-store.d.ts +2 -3
  38. package/dist/client/app/pages/DevLogin/DevLoginForm.js +1 -1
  39. package/dist/client/app/pages/Invite/Invite.js +1 -1
  40. package/dist/client/app/search/index.d.ts +1 -1
  41. package/dist/client/app/search/index.js +1 -1
  42. package/dist/client/app/search/useSearch.d.ts +3 -0
  43. package/dist/client/app/search/useSearch.js +1 -1
  44. package/dist/client/app/webmcp/index.d.ts +2 -0
  45. package/dist/client/app/webmcp/index.js +1 -0
  46. package/dist/client/app/webmcp/tools/api-tools.d.ts +8 -0
  47. package/dist/client/app/webmcp/tools/api-tools.js +1 -0
  48. package/dist/client/app/webmcp/tools/shared.d.ts +13 -0
  49. package/dist/client/app/webmcp/tools/shared.js +1 -0
  50. package/dist/client/app/webmcp/tools/site-tools.d.ts +5 -0
  51. package/dist/client/app/webmcp/tools/site-tools.js +3 -0
  52. package/dist/client/app/webmcp/types.d.ts +36 -0
  53. package/dist/client/app/webmcp/types.js +0 -0
  54. package/dist/client/app/webmcp/useWebMcpTools.d.ts +9 -0
  55. package/dist/client/app/webmcp/useWebMcpTools.js +1 -0
  56. package/dist/client/providers/page-data/hooks.d.ts +2 -0
  57. package/dist/client/providers/page-data/hooks.js +1 -1
  58. package/dist/client/providers/theme/ThemeDataProvider.js +1 -1
  59. package/dist/client/runtime/loader.js +1 -1
  60. package/dist/client/server-entry.d.ts +2 -1
  61. package/dist/client/server-entry.js +1 -1
  62. package/dist/client/templates/api-docs/helpers.js +1 -1
  63. package/dist/client/templates/api-docs/template.js +7 -3
  64. package/dist/client/utils/catalog/parse-filter-query.js +1 -1
  65. package/dist/client/{app/Sidebar/helpers → utils}/filter-out-versioned-items.d.ts +12 -2
  66. package/dist/client/utils/filter-out-versioned-items.js +1 -0
  67. package/dist/client/utils/navigation-tabs.d.ts +14 -0
  68. package/dist/client/utils/navigation-tabs.js +1 -0
  69. package/dist/compiled/svgo/svgo-node.js +39 -39
  70. package/dist/constants/common.d.ts +1 -0
  71. package/dist/constants/common.js +1 -1
  72. package/dist/constants/l10n/langs/ar.js +1 -1
  73. package/dist/constants/l10n/langs/de.js +1 -1
  74. package/dist/constants/l10n/langs/en.js +1 -1
  75. package/dist/constants/l10n/langs/es.js +1 -1
  76. package/dist/constants/l10n/langs/fr.js +1 -1
  77. package/dist/constants/l10n/langs/hi.js +1 -1
  78. package/dist/constants/l10n/langs/it.js +1 -1
  79. package/dist/constants/l10n/langs/ja.js +1 -1
  80. package/dist/constants/l10n/langs/ko.js +1 -1
  81. package/dist/constants/l10n/langs/pl.js +1 -1
  82. package/dist/constants/l10n/langs/pt-BR.js +1 -1
  83. package/dist/constants/l10n/langs/pt.js +1 -1
  84. package/dist/constants/l10n/langs/ru.js +1 -1
  85. package/dist/constants/l10n/langs/uk.js +1 -1
  86. package/dist/constants/l10n/langs/zh.js +1 -1
  87. package/dist/markdoc/nodes/table.d.ts +2 -0
  88. package/dist/markdoc/nodes/table.js +1 -1
  89. package/dist/server/config/env-config.d.ts +0 -6
  90. package/dist/server/config/env-schema.d.ts +0 -15
  91. package/dist/server/config/env-schemas/feature-flags.d.ts +0 -12
  92. package/dist/server/config/env-schemas/feature-flags.js +1 -1
  93. package/dist/server/constants/common.d.ts +3 -1
  94. package/dist/server/constants/common.js +1 -1
  95. package/dist/server/constants/entitlements.js +1 -1
  96. package/dist/server/constants/plugins/consent.d.ts +3 -0
  97. package/dist/server/constants/plugins/consent.js +1 -0
  98. package/dist/server/constants/plugins/search.js +1 -1
  99. package/dist/server/esbuild/esbuild-logger.js +3 -3
  100. package/dist/server/plugins/analytics/adobe/index.js +1 -1
  101. package/dist/server/plugins/analytics/amplitude/browser-hooks.js +1 -1
  102. package/dist/server/plugins/analytics/amplitude/index.js +1 -1
  103. package/dist/server/plugins/analytics/fullstory/index.js +1 -1
  104. package/dist/server/plugins/analytics/ga/index.js +1 -1
  105. package/dist/server/plugins/analytics/gtm/browser-hooks.js +1 -1
  106. package/dist/server/plugins/analytics/gtm/index.js +1 -1
  107. package/dist/server/plugins/analytics/heap/browser-hooks.js +1 -1
  108. package/dist/server/plugins/analytics/rudderstack/index.js +1 -1
  109. package/dist/server/plugins/analytics/segment/index.js +1 -1
  110. package/dist/server/plugins/api-docs/index.js +1 -1
  111. package/dist/server/plugins/api-docs/utils/apply-nav-item-to-root.d.ts +9 -0
  112. package/dist/server/plugins/api-docs/utils/apply-nav-item-to-root.js +1 -0
  113. package/dist/server/plugins/api-docs/utils/decorators.js +1 -1
  114. package/dist/server/plugins/catalog-entities/database/repositories/common/revision-repository.d.ts +1 -1
  115. package/dist/server/plugins/catalog-entities/database/repositories/common/revision-repository.js +1 -1
  116. package/dist/server/plugins/catalog-entities/database/repositories/common/version-repository.d.ts +5 -1
  117. package/dist/server/plugins/catalog-entities/database/repositories/common/version-repository.js +7 -1
  118. package/dist/server/plugins/catalog-entities/database/repositories/entities/entities-write-repository.js +1 -1
  119. package/dist/server/plugins/catalog-entities/utils/ajv-validator.js +1 -1
  120. package/dist/server/plugins/catalog-entities/utils/extract-parts-from-components-ref.js +1 -1
  121. package/dist/server/plugins/catalog-entities/utils/is-valid-tag-name.js +1 -1
  122. package/dist/server/plugins/catalog-entities/utils/openapi-component-content-extractor.js +1 -1
  123. package/dist/server/plugins/config-parser/format-custom-tags.d.ts +1 -0
  124. package/dist/server/plugins/config-parser/format-custom-tags.js +1 -1
  125. package/dist/server/plugins/config-parser/index.js +1 -1
  126. package/dist/server/plugins/config-parser/loaders/redocly-config-loader.js +1 -1
  127. package/dist/server/plugins/config-parser/loaders/versions-config-loader.js +1 -1
  128. package/dist/server/plugins/config-parser/safe-parse.js +1 -1
  129. package/dist/server/plugins/consent/build-consent-script.d.ts +6 -0
  130. package/dist/server/plugins/consent/build-consent-script.js +230 -0
  131. package/dist/server/plugins/consent/gate-ssr-components.d.ts +5 -0
  132. package/dist/server/plugins/consent/gate-ssr-components.js +1 -0
  133. package/dist/server/plugins/consent/index.d.ts +3 -0
  134. package/dist/server/plugins/consent/index.js +1 -0
  135. package/dist/server/plugins/consent/is-consent-enabled.d.ts +8 -0
  136. package/dist/server/plugins/consent/is-consent-enabled.js +1 -0
  137. package/dist/server/plugins/consent/zone-modes.d.ts +8 -0
  138. package/dist/server/plugins/consent/zone-modes.js +1 -0
  139. package/dist/server/plugins/default-theme/extract-team-names.js +1 -1
  140. package/dist/server/plugins/dev-onboarding/template/App.js +5 -5
  141. package/dist/server/plugins/dev-onboarding/template/components/ApiKeyOverview.js +3 -3
  142. package/dist/server/plugins/get-reserved-routes.d.ts +4 -2
  143. package/dist/server/plugins/get-reserved-routes.js +1 -1
  144. package/dist/server/plugins/l10n/index.js +1 -1
  145. package/dist/server/plugins/lifecycle.js +2 -2
  146. package/dist/server/plugins/markdown/markdoc/markdoc-options.d.ts +2 -0
  147. package/dist/server/plugins/markdown/search/get-ai-search-documents.js +9 -9
  148. package/dist/server/plugins/markdown/search/nodes/tag-node.d.ts +1 -1
  149. package/dist/server/plugins/markdown/search/nodes/tag-node.js +1 -1
  150. package/dist/server/plugins/markdown/search/to-markdown.js +1 -1
  151. package/dist/server/plugins/markdown/utils/sanitize-malformed-md-content.js +1 -1
  152. package/dist/server/plugins/mcp/audit/audit-log.js +1 -1
  153. package/dist/server/plugins/mcp/audit/secret-patterns.js +1 -1
  154. package/dist/server/plugins/mcp/auth/assistant-anonymous-token.d.ts +9 -0
  155. package/dist/server/plugins/mcp/auth/assistant-anonymous-token.js +1 -0
  156. package/dist/server/plugins/mcp/auth/auth-handlers.d.ts +5 -3
  157. package/dist/server/plugins/mcp/auth/auth-handlers.js +1 -1
  158. package/dist/server/plugins/mcp/codemode/build-tool-list.d.ts +6 -1
  159. package/dist/server/plugins/mcp/codemode/build-tool-list.js +2 -2
  160. package/dist/server/plugins/mcp/codemode/build-tool-type-declarations.js +4 -4
  161. package/dist/server/plugins/mcp/codemode/capabilities/fetch/index.js +3 -3
  162. package/dist/server/plugins/mcp/codemode/capabilities/types.d.ts +0 -1
  163. package/dist/server/plugins/mcp/codemode/capabilities/utils.d.ts +1 -2
  164. package/dist/server/plugins/mcp/codemode/capabilities/utils.js +4 -4
  165. package/dist/server/plugins/mcp/codemode/code-execution-audit.d.ts +3 -2
  166. package/dist/server/plugins/mcp/codemode/code-execution-audit.js +1 -1
  167. package/dist/server/plugins/mcp/codemode/code-execution-telemetry.d.ts +3 -4
  168. package/dist/server/plugins/mcp/codemode/code-execution-telemetry.js +1 -1
  169. package/dist/server/plugins/mcp/codemode/prompts.js +1 -1
  170. package/dist/server/plugins/mcp/codemode/tools/describe-tools.js +2 -2
  171. package/dist/server/plugins/mcp/codemode/tools/execute-schema.d.ts +0 -2
  172. package/dist/server/plugins/mcp/codemode/tools/execute-schema.js +1 -1
  173. package/dist/server/plugins/mcp/codemode/tools/execute.js +1 -1
  174. package/dist/server/plugins/mcp/codemode/tools/manage-credentials.js +2 -2
  175. package/dist/server/plugins/mcp/custom-tools/scan-custom-tools.js +1 -1
  176. package/dist/server/plugins/mcp/docs-mcp/tool-schemas.js +1 -1
  177. package/dist/server/plugins/mcp/docs-mcp/tools/core/create-anonymous-session.js +1 -1
  178. package/dist/server/plugins/mcp/docs-mcp/tools/core/whoami.js +1 -1
  179. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/constants.d.ts +2 -0
  180. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/constants.js +1 -1
  181. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/endpoint-suggestions.d.ts +6 -0
  182. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/endpoint-suggestions.js +1 -1
  183. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/get-endpoint-info.js +1 -1
  184. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/get-security-schemes.js +1 -1
  185. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/load-api-description.d.ts +2 -0
  186. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/load-api-description.js +1 -1
  187. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/utils.d.ts +6 -2
  188. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/utils.js +1 -1
  189. package/dist/server/plugins/mcp/docs-mcp/utils/resolve-refs.d.ts +20 -14
  190. package/dist/server/plugins/mcp/docs-mcp/utils/resolve-refs.js +1 -1
  191. package/dist/server/plugins/mcp/gateway-mcp/credential-validation.js +1 -1
  192. package/dist/server/plugins/mcp/gateway-mcp/elicitation.d.ts +16 -10
  193. package/dist/server/plugins/mcp/gateway-mcp/elicitation.js +5 -5
  194. package/dist/server/plugins/mcp/gateway-mcp/fetch/allowed-hosts.js +1 -1
  195. package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-bridge.js +1 -1
  196. package/dist/server/plugins/mcp/gateway-mcp/fetch/ssrf-guard.js +1 -1
  197. package/dist/server/plugins/mcp/gateway-mcp/fetch/url-placeholders.js +1 -1
  198. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/ip-key.js +1 -1
  199. package/dist/server/plugins/mcp/gateway-mcp/upstream-auth-scheme.d.ts +0 -6
  200. package/dist/server/plugins/mcp/gateway-mcp/upstream-auth-scheme.js +2 -2
  201. package/dist/server/plugins/mcp/handlers/docs-mcp-handler.js +1 -1
  202. package/dist/server/plugins/mcp/handlers/mcp-credentials-handler.js +1 -1
  203. package/dist/server/plugins/mcp/handlers/mcp-credentials-page.js +35 -35
  204. package/dist/server/plugins/mcp/index.js +1 -1
  205. package/dist/server/plugins/mcp/servers/docs-server.js +1 -1
  206. package/dist/server/plugins/mcp/servers/mcp-server.js +2 -4
  207. package/dist/server/plugins/mcp/types.d.ts +5 -11
  208. package/dist/server/plugins/mcp/utils/disabled-tools.d.ts +3 -0
  209. package/dist/server/plugins/mcp/utils/disabled-tools.js +1 -0
  210. package/dist/server/plugins/mcp/utils/json-schema-validator.d.ts +2 -2
  211. package/dist/server/plugins/mcp/utils/json-schema-validator.js +1 -1
  212. package/dist/server/plugins/mcp/utils/mcp-client.js +1 -1
  213. package/dist/server/plugins/mcp/utils/public-endpoint.d.ts +9 -0
  214. package/dist/server/plugins/mcp/utils/public-endpoint.js +1 -0
  215. package/dist/server/plugins/mcp/utils/telemetry-attributes.d.ts +2 -1
  216. package/dist/server/plugins/mcp/utils/telemetry-attributes.js +1 -1
  217. package/dist/server/plugins/mcp/utils/tool-registration.d.ts +2 -1
  218. package/dist/server/plugins/mcp/utils/tool-registration.js +1 -1
  219. package/dist/server/plugins/mcp/utils/xmcp-utils.d.ts +0 -7
  220. package/dist/server/plugins/mcp/utils/xmcp-utils.js +1 -1
  221. package/dist/server/plugins/mcp/workers/execute-mcp-tool.js +1 -1
  222. package/dist/server/plugins/mcp/workers/mcp-tool-telemetry.d.ts +5 -7
  223. package/dist/server/plugins/mcp/workers/mcp-tool-telemetry.js +1 -1
  224. package/dist/server/plugins/nav-utils.js +1 -1
  225. package/dist/server/plugins/scorecard-classic/index.js +1 -1
  226. package/dist/server/plugins/scorecard-classic/template/Grid/GridHeader.js +21 -8
  227. package/dist/server/plugins/scorecard-classic/template/ScorecardDashboard.js +3 -3
  228. package/dist/server/plugins/scorecard-classic/template/index.styles.d.ts +1 -0
  229. package/dist/server/plugins/scorecard-classic/template/index.styles.js +15 -5
  230. package/dist/server/plugins/scorecard-classic/template/useData.js +1 -1
  231. package/dist/server/plugins/scorecard-classic/template/views.js +1 -1
  232. package/dist/server/plugins/search/engines/flexsearch/index.js +2 -1
  233. package/dist/server/plugins/search/engines/flexsearch/search-index.d.ts +2 -2
  234. package/dist/server/plugins/search/engines/flexsearch/search-index.js +1 -1
  235. package/dist/server/plugins/search/llmstxt/index.js +1 -1
  236. package/dist/server/plugins/sidebars/index.js +7 -3
  237. package/dist/server/plugins/sidebars/tabs.d.ts +19 -0
  238. package/dist/server/plugins/sidebars/tabs.js +1 -0
  239. package/dist/server/plugins/sso/index.js +1 -1
  240. package/dist/server/ssr/render.js +1 -1
  241. package/dist/server/store.d.ts +2 -0
  242. package/dist/server/store.js +1 -1
  243. package/dist/server/tools/notifiers/helpers/privacy/mask-subject.js +1 -1
  244. package/dist/server/tools/notifiers/helpers/privacy/remove-pii.js +1 -1
  245. package/dist/server/types/plugins/search.d.ts +7 -5
  246. package/dist/server/utils/catalog-classic/get-catalog-shared-data-id.d.ts +3 -0
  247. package/dist/server/utils/catalog-classic/get-catalog-shared-data-id.js +1 -0
  248. package/dist/server/utils/envs/interpolate-env-variables.js +1 -1
  249. package/dist/server/utils/rbac-expand.js +1 -1
  250. package/dist/server/utils/rbac.js +1 -1
  251. package/dist/server/utils/redact-url.d.ts +6 -0
  252. package/dist/server/utils/redact-url.js +1 -0
  253. package/dist/server/utils/report-all-errors.js +1 -1
  254. package/dist/server/utils/sandbox-context.js +1 -1
  255. package/dist/server/utils/search/highlight-text-for-search.d.ts +1 -0
  256. package/dist/server/utils/search/highlight-text-for-search.js +1 -1
  257. package/dist/server/utils/search/text-match.d.ts +6 -0
  258. package/dist/server/utils/search/text-match.js +1 -0
  259. package/dist/server/utils/static-data.js +1 -1
  260. package/dist/server/utils/write-problems-report.d.ts +3 -0
  261. package/dist/server/utils/write-problems-report.js +1 -0
  262. package/dist/server/web-server/auth.d.ts +16 -2
  263. package/dist/server/web-server/auth.js +4 -4
  264. package/dist/server/web-server/jwt/jwt.js +1 -1
  265. package/dist/server/web-server/jwt/token-types.d.ts +11 -0
  266. package/dist/server/web-server/jwt/token-types.js +1 -0
  267. package/dist/server/web-server/jwt/types.d.ts +4 -4
  268. package/dist/server/web-server/jwt/types.js +1 -1
  269. package/dist/server/web-server/middleware/ensureSearchData.js +1 -1
  270. package/dist/server/web-server/middleware/responseHeadersMiddleware.js +1 -1
  271. package/dist/server/web-server/middleware/telemetry-middleware.js +1 -1
  272. package/dist/server/web-server/routes/ask-ai.js +1 -1
  273. package/dist/server/web-server/routes/auth.d.ts +1 -1
  274. package/dist/server/web-server/routes/auth.js +1 -1
  275. package/dist/server/web-server/routes/cors-proxy.js +2 -2
  276. package/dist/server/web-server/routes/dynamic-route.js +1 -1
  277. package/dist/server/web-server/routes/index.js +1 -1
  278. package/dist/server/web-server/routes/mcp-routes/mcp-oauth.js +1 -1
  279. package/dist/server/web-server/routes/mcp-routes/mcp-server-card.js +1 -1
  280. package/dist/server/web-server/routes/semantic-search.d.ts +1 -1
  281. package/dist/server/web-server/routes/semantic-search.js +1 -1
  282. package/dist/server/web-server/routes/static-content.js +1 -1
  283. package/dist/server/workers/worker-pool.js +1 -1
  284. package/dist/types/entitlements.d.ts +1 -0
  285. package/dist/utils/path/parse-path-versions.js +1 -1
  286. package/dist/utils/string/to-kebab-case.js +1 -1
  287. package/package.json +9 -9
  288. package/dist/client/app/Sidebar/helpers/filter-out-versioned-items.js +0 -1
  289. package/dist/server/plugins/mcp/auth/token-audience-telemetry.d.ts +0 -7
  290. package/dist/server/plugins/mcp/auth/token-audience-telemetry.js +0 -1
  291. package/dist/server/plugins/mcp/auth/token-audience.d.ts +0 -6
  292. package/dist/server/plugins/mcp/auth/token-audience.js +0 -1
  293. /package/dist/server/{plugins/mcp/gateway-mcp/fetch → web-server/utils}/ssrf-blocklist.d.ts +0 -0
  294. /package/dist/server/{plugins/mcp/gateway-mcp/fetch → web-server/utils}/ssrf-blocklist.js +0 -0
  295. /package/dist/server/{plugins/mcp/gateway-mcp/fetch → web-server/utils}/ssrf-safe-lookup.d.ts +0 -0
  296. /package/dist/server/{plugins/mcp/gateway-mcp/fetch → web-server/utils}/ssrf-safe-lookup.js +0 -0
@@ -1,2 +1,2 @@
1
- function c(n){return n.replace(/\[([^\]]*<[^>]*>[^\]]*)\]\(([^)]+)\)/g,(r,t,s)=>`[${t.replace(/(`+)[^`]+\1|[<>]/g,e=>e==="<"?"&lt;":e===">"?"&gt;":e)}](${s})`).replace(/({%\s*(\w+)(?:\s+[^%]*)?%})(\s*)({%\s*\/\2\s*%})/g,(r,t,s,l,e)=>`${t}
1
+ function c(n){return n.replace(/\[(?<!\[[^\]()]*?\[)([^\]<]*<[^>]*>[^\]]*)\]\(([^)]+)\)/g,(r,t,s)=>`[${t.replace(/(`{1,16})[^`]+\1|[<>]/g,e=>e==="<"?"&lt;":e===">"?"&gt;":e)}](${s})`).replace(/({%\s*(\w+)(?:\s[^%]*)?%})(\s*)({%\s*\/\2\s*%})/g,(r,t,s,l,e)=>`${t}
2
2
  ${e}`)}export{c as sanitizeMalformedMdContent};
@@ -1 +1 @@
1
- import{createHash as a}from"node:crypto";import{logger as c}from"../../../tools/notifiers/logger.js";import{AUDIT_LOG_PREFIX as u}from"./constants.js";import{redactSecretsFromString as f}from"../gateway-mcp/fetch/redact.js";import{redactSecretShapes as p}from"./secret-patterns.js";import{AUDIT_LOG_PREFIX as I}from"./constants.js";const s=4096,d="redacted",m=new Set(["access_token","api-key","api_key","apikey","auth","code","id_token","key","password","refresh_token","secret","session","sig","signature","token","x-amz-credential","x-amz-security-token","x-amz-signature"]);function h(t){return a("sha256").update(t,"utf8").digest("hex")}function g(t){if(t.length<=s)return t;const e=t.slice(0,s),r=e.search(/\s\S*$/),n=r>0?e.slice(0,r):e;return`${n}\u2026[truncated: kept ${n.length} of ${t.length} chars]`}function i(t,e=[]){return p(f(g(t),e))}function S(t){return{sha256:h(t),bytes:Buffer.byteLength(t,"utf8")}}function $(t){return Object.keys(t??{}).map(e=>e.toLowerCase()).sort().join(",")}function E(t,e=[]){let r;try{r=new URL(t)}catch{return i(t,e)}for(const n of[...r.searchParams.keys()])m.has(n.toLowerCase())&&r.searchParams.set(n,d);return r.username="",r.password="",i(r.href,e)}function R(t,e){const r=Object.entries(e).filter(([,n])=>n!==void 0&&n!=="").map(([n,o])=>typeof o=="string"?`${n}=${JSON.stringify(o)}`:`${n}=${String(o)}`).join(" ");try{c.infoPreSanitized(`${u} ${t} ${r}`)}catch{}}export{s as AUDIT_FIELD_MAX_CHARS,I as AUDIT_LOG_PREFIX,$ as auditHeaderNames,i as auditInput,S as auditOutputDigest,h as auditSha256,E as auditUrl,R as logAuditRecord,g as truncateAuditField};
1
+ import{createHash as c}from"node:crypto";import{logger as s}from"../../../tools/notifiers/logger.js";import{redactUrl as f}from"../../../utils/redact-url.js";import{AUDIT_LOG_PREFIX as p}from"./constants.js";import{redactSecretsFromString as u}from"../gateway-mcp/fetch/redact.js";import{redactSecretShapes as a}from"./secret-patterns.js";import{AUDIT_LOG_PREFIX as L}from"./constants.js";const i=4096;function d(t){return c("sha256").update(t,"utf8").digest("hex")}function m(t){if(t.length<=i)return t;const r=t.slice(0,i),o=r.search(/\s\S*$/),e=o>0?r.slice(0,o):r;return`${e}\u2026[truncated: kept ${e.length} of ${t.length} chars]`}function h(t,r=[]){return a(u(m(t),r))}function _(t){return{sha256:d(t),bytes:Buffer.byteLength(t,"utf8")}}function l(t){return Object.keys(t??{}).map(r=>r.toLowerCase()).sort().join(",")}function O(t,r=[]){return h(f(t),r)}function y(t,r){const o=Object.entries(r).filter(([,e])=>e!==void 0&&e!=="").map(([e,n])=>typeof n=="string"?`${e}=${JSON.stringify(n)}`:`${e}=${String(n)}`).join(" ");try{s.infoPreSanitized(`${p} ${t} ${o}`)}catch{}}export{i as AUDIT_FIELD_MAX_CHARS,L as AUDIT_LOG_PREFIX,l as auditHeaderNames,h as auditInput,_ as auditOutputDigest,d as auditSha256,O as auditUrl,y as logAuditRecord,m as truncateAuditField};
@@ -1 +1 @@
1
- const n=[{name:"aws_access_key_id",re:/\bAKIA[0-9A-Z]{16}\b/g},{name:"aws_temp_key",re:/\bASIA[0-9A-Z]{16}\b/g},{name:"github_token",re:/\bgh[pousr]_[A-Za-z0-9_]{20,255}\b/g},{name:"github_fine_grained",re:/\bgithub_pat_[A-Za-z0-9_]{60,255}\b/g},{name:"jwt",re:/\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g},{name:"pem_private_key",re:/-----BEGIN (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/g},{name:"google_api_key",re:/\bAIza[0-9A-Za-z_-]{35}\b/g},{name:"slack_token",re:/\bxox[abprs]-[A-Za-z0-9-]{10,}\b/g},{name:"bearer_token",re:/(?<=[Aa]uthorization\s*[:=]\s*["']?[Bb]earer\s+)[A-Za-z0-9._\-+/=]{20,}/g},{name:"anthropic_key",re:/\bsk-ant-[A-Za-z0-9_-]{20,}\b/g},{name:"openai_key",re:/\bsk-(?:proj-|svcacct-)?[A-Za-z0-9_-]{20,}\b/g},{name:"stripe_key",re:/\b(?:sk|rk|pk)_(?:live|test)_[A-Za-z0-9]{20,}\b/g},{name:"sendgrid_key",re:/\bSG\.[A-Za-z0-9_-]{22}\.[A-Za-z0-9_-]{43}\b/g},{name:"basic_auth_url",re:/\b([a-z][a-z0-9+\-.]*:\/\/)[^\s/:@]+:[^\s/@]+@/gi}];function t(e){if(!e)return e;let a=e;for(const{name:r,re:_}of n)a=a.replace(_,(A,b)=>r==="basic_auth_url"?`${b??""}[REDACTED:${r}]@`:`[REDACTED:${r}]`);return a}export{t as redactSecretShapes};
1
+ const n=[{name:"aws_access_key_id",re:/\bAKIA[0-9A-Z]{16}\b/g},{name:"aws_temp_key",re:/\bASIA[0-9A-Z]{16}\b/g},{name:"github_token",re:/\bgh[pousr]_[A-Za-z0-9_]{20,255}\b/g},{name:"github_fine_grained",re:/\bgithub_pat_[A-Za-z0-9_]{60,255}\b/g},{name:"jwt",re:/\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g},{name:"pem_private_key",re:/-----BEGIN (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/g},{name:"google_api_key",re:/\bAIza[0-9A-Za-z_-]{35}\b/g},{name:"slack_token",re:/\bxox[abprs]-[A-Za-z0-9-]{10,}\b/g},{name:"bearer_token",re:/(?<=[Aa]uthorization\s*[:=]\s*["']?[Bb]earer\s{1,16})[A-Za-z0-9._\-+/=]{20,}/g},{name:"anthropic_key",re:/\bsk-ant-[A-Za-z0-9_-]{20,}\b/g},{name:"openai_key",re:/\bsk-(?:proj-|svcacct-)?[A-Za-z0-9_-]{20,}\b/g},{name:"stripe_key",re:/\b(?:sk|rk|pk)_(?:live|test)_[A-Za-z0-9]{20,}\b/g},{name:"sendgrid_key",re:/\bSG\.[A-Za-z0-9_-]{22}\.[A-Za-z0-9_-]{43}\b/g},{name:"basic_auth_url",re:/\b([a-z][a-z0-9+\-.]*:\/\/)[^\s/:@]+:[^\s/@]+@/gi}];function t(e){if(!e)return e;let a=e;for(const{name:r,re:_}of n)a=a.replace(_,(A,b)=>r==="basic_auth_url"?`${b??""}[REDACTED:${r}]@`:`[REDACTED:${r}]`);return a}export{t as redactSecretShapes};
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Mints the token the portal sends with an anonymous visitor's assistant question, so that the
3
+ * Reunite API reaches `/mcp` with anonymous scope instead of an OAuth challenge. Returns nothing
4
+ * when this portal cannot mint a token its own `/mcp` would accept.
5
+ */
6
+ export declare function createAssistantAnonymousToken(): Promise<string | undefined>;
7
+ /** Tells whether the bearer is an unexpired token this project minted for its own AI assistant. */
8
+ export declare function isAssistantAnonymousToken(token: string): Promise<boolean>;
9
+ //# sourceMappingURL=assistant-anonymous-token.d.ts.map
@@ -0,0 +1 @@
1
+ import{hkdfSync as S}from"node:crypto";import{FALLBACK_JWT_SECRET_KEY as c}from"../../../constants/common.js";import{envConfig as o}from"../../../config/env-config.js";import{AlgorithmTypes as i}from"../../../web-server/jwt/types.js";import*as r from"../../../web-server/jwt/jwt.js";import{InternalTokenTypes as a}from"../../../web-server/jwt/token-types.js";import{ensureArray as m}from"../../../../utils/array/ensure-array.js";const T=600,u="ai-assistant-anonymous";function f(){const n=o.JWT_SECRET_KEY;if(!(!n||n===c||!o.PROJECT_ID))return Buffer.from(S("sha256",n,u,u,32)).toString("hex")}async function N(){const n=f();if(!n)return;const t=Math.floor(Date.now()/1e3);return r.sign({type:a.AI_ASSISTANT_ANONYMOUS,anonymous:!0,aud:o.PROJECT_ID,iat:t,exp:t+T},n,i.HS256)}async function I(n){const t=f();if(!t)return!1;try{await r.verify(n,t,i.HS256)}catch{return!1}const{payload:e}=r.decode(n),s=o.PROJECT_ID;return e.type===a.AI_ASSISTANT_ANONYMOUS&&e.anonymous===!0&&!!s&&m(e.aud).includes(s)}export{N as createAssistantAnonymousToken,I as isAssistantAnonymousToken};
@@ -1,13 +1,15 @@
1
1
  import type { ApiFunctionsContext, ApiFunctionsUser } from '@redocly/config';
2
2
  import type { Store } from '../../../store.js';
3
3
  export declare function isMcpContentProtected(store: Store): boolean;
4
- export declare function handleMcpAuth(request: Request, context: ApiFunctionsContext): Promise<{
4
+ export type McpAuthResult = {
5
5
  isAuthenticated: boolean;
6
6
  isTokenValid?: boolean;
7
+ isFirstPartyAnonymous?: boolean;
7
8
  currentUser?: ApiFunctionsUser;
8
9
  accessToken?: string;
9
- }>;
10
+ };
11
+ export declare function handleMcpAuth(request: Request, context: ApiFunctionsContext): Promise<McpAuthResult>;
10
12
  export declare function constructUnauthorizedResponse(baseUrl: string, publicMcpUrl?: string): Response;
11
13
  export declare function constructForbiddenResponse(): Response;
12
- export declare function constructInvalidTokenResponse(baseUrl: string): Response;
14
+ export declare function constructInvalidTokenResponse(baseUrl: string, publicMcpUrl?: string): Response;
13
15
  //# sourceMappingURL=auth-handlers.d.ts.map
@@ -1 +1 @@
1
- import{extractTokenFromAuthHeader as d}from"../../../plugins/mcp/utils/jwt.js";import{SUPPORTED_MCP_SCOPES as p}from"../constants.js";import{getUserParamsFromCookies as h}from"../../../web-server/auth.js";import{ServerRoutes as c}from"../../../../constants/api.js";import{withPathPrefix as l}from"@redocly/theme/core/utils";import{shouldHandleMcpAuth as f}from"../../../utils/rbac/should-handle-mcp-auth.js";import{checkTokenAudience as m,isTokenAudienceEnforced as A,toAudienceList as T}from"./token-audience.js";import{reportMcpTokenAudienceMismatch as k}from"./token-audience-telemetry.js";function x(t){const e=t.getConfig().access;return f(!!e?.requiresLogin,e?.rbac||{})}async function E(t,e){const o=t.headers.get("Authorization");if(!o)return{isAuthenticated:!1};const i=d(o),r=e?.config?.ssoDirect||{},n=i?await h(r,{authorization:i}):{};if(!(i&&n&&n.isAuthenticated))return{isAuthenticated:!1,isTokenValid:!1};const s=n.aud;if(m(s)==="mismatch"){const a=A();if(k({audience:T(s).join(","),enforced:a}),a)return{isAuthenticated:!1,isTokenValid:!1}}return{isAuthenticated:!0,isTokenValid:!0,currentUser:{teams:n.teams||[],email:n.email||"",claims:n,isAuthenticated:!0,idpAccessToken:n.idpAccessToken||void 0,idpId:n.idpId||void 0},accessToken:i}}function u(t,e){const o=`${t}${c.MCP_OAUTH_PROTECTED_RESOURCE}${l("/mcp")}`,i=`${t}${c.MCP_OAUTH_AUTHORIZATION_SERVER}`,r=e?[`error="${e.code}"`,`error_description="${e.description}"`]:[];return r.push(`resource_metadata="${o}"`,`scope="${p.join(" ")}"`,`authorization_uri="${i}"`),`Bearer ${r.join(", ")}`}function S(t,e){const o=e?`Authentication required. A public endpoint that serves anonymous-accessible content is available at ${e}.`:"Authentication required";return new Response(JSON.stringify({error:"unauthorized",message:o}),{status:401,headers:{"Content-Type":"application/json","WWW-Authenticate":u(t),"Access-Control-Allow-Origin":"*"}})}function w(){return new Response(JSON.stringify({error:"forbidden",message:"You do not have access to this MCP server"}),{status:403,headers:{"Content-Type":"application/json","Access-Control-Allow-Origin":"*"}})}function y(t){return new Response(JSON.stringify({error:"invalid_token",message:"Invalid or expired token"}),{status:401,headers:{"Content-Type":"application/json","WWW-Authenticate":u(t,{code:"invalid_token",description:"Invalid or expired token"}),"Access-Control-Allow-Origin":"*"}})}export{w as constructForbiddenResponse,y as constructInvalidTokenResponse,S as constructUnauthorizedResponse,E as handleMcpAuth,x as isMcpContentProtected};
1
+ import{extractTokenFromAuthHeader as u}from"../../../plugins/mcp/utils/jwt.js";import{SUPPORTED_MCP_SCOPES as d}from"../constants.js";import{getUserParamsFromCookies as p}from"../../../web-server/auth.js";import{ServerRoutes as s}from"../../../../constants/api.js";import{withPathPrefix as l}from"@redocly/theme/core/utils";import{shouldHandleMcpAuth as h}from"../../../utils/rbac/should-handle-mcp-auth.js";import{isAssistantAnonymousToken as f}from"./assistant-anonymous-token.js";function R(t){const e=t.getConfig().access;return h(!!e?.requiresLogin,e?.rbac||{})}async function _(t,e){const n=t.headers.get("Authorization");if(!n)return{isAuthenticated:!1};const o=u(n);if(o&&await f(o))return{isAuthenticated:!1,isTokenValid:!0,isFirstPartyAnonymous:!0};const r=e?.config?.ssoDirect||{},i=o?await p(r,{authorization:o}):{};return o&&i&&i.isAuthenticated?{isAuthenticated:!0,isTokenValid:!0,currentUser:{teams:i.teams||[],email:i.email||"",claims:i,isAuthenticated:!0,idpAccessToken:i.idpAccessToken||void 0,idpId:i.idpId||void 0},accessToken:o}:{isAuthenticated:!1,isTokenValid:!1}}function a(t,e){const n=`${t}${s.MCP_OAUTH_PROTECTED_RESOURCE}${l("/mcp")}`,o=`${t}${s.MCP_OAUTH_AUTHORIZATION_SERVER}`,r=e?[`error="${e.code}"`,`error_description="${e.description}"`]:[];return r.push(`resource_metadata="${n}"`,`scope="${d.join(" ")}"`,`authorization_uri="${o}"`),`Bearer ${r.join(", ")}`}function c(t,e){return e?`${t}. A public endpoint that serves anonymous-accessible content is available at ${e}.`:t}function $(t,e){const n=c("Authentication required",e);return new Response(JSON.stringify({error:"unauthorized",message:n}),{status:401,headers:{"Content-Type":"application/json","WWW-Authenticate":a(t),"Access-Control-Allow-Origin":"*"}})}function y(){return new Response(JSON.stringify({error:"forbidden",message:"You do not have access to this MCP server"}),{status:403,headers:{"Content-Type":"application/json","Access-Control-Allow-Origin":"*"}})}function v(t,e){const n=c("Invalid or expired token",e);return new Response(JSON.stringify({error:"invalid_token",message:n}),{status:401,headers:{"Content-Type":"application/json","WWW-Authenticate":a(t,{code:"invalid_token",description:"Invalid or expired token"}),"Access-Control-Allow-Origin":"*"}})}export{y as constructForbiddenResponse,v as constructInvalidTokenResponse,$ as constructUnauthorizedResponse,_ as handleMcpAuth,R as isMcpContentProtected};
@@ -4,9 +4,14 @@ import type { SandboxCapability } from './capabilities/types.js';
4
4
  export type ToolListEntry = {
5
5
  name: string;
6
6
  purpose?: string;
7
+ /** A platform tool whose name explains it; its purpose gives way before a custom tool's. */
8
+ builtIn?: boolean;
7
9
  };
8
10
  /** Maps MCP tool schemas and active capabilities to tool-list entries (sandbox names). */
9
11
  export declare function toToolListEntries(tools: McpToolSchema[], capabilities: SandboxCapability[]): ToolListEntry[];
10
- /** Renders one `- name — purpose` line per entry within `maxChars`. */
12
+ /**
13
+ * Renders one `- name — purpose` line per entry within `maxChars`. Built-in purposes shorten
14
+ * and then drop before custom purposes shorten; names alone are the last resort.
15
+ */
11
16
  export declare function buildToolList(entries: ToolListEntry[], maxChars: number): string;
12
17
  //# sourceMappingURL=build-tool-list.d.ts.map
@@ -1,2 +1,2 @@
1
- import{sanitizeToolName as s}from"./build-tool-type-declarations.js";const l=60;function a(e,t){return[...e.map(n=>({name:s(n.name),purpose:n.description})),...t.map(n=>({name:s(n.id),purpose:n.purpose}))]}function $(e,t){if(e.length===0||t<=0)return"";const o=e.map(({name:r,purpose:f})=>{const i=(f??"").replace(/\s+/g," ").trim();if(!i)return`- ${r}`;const m=i.length>l?`${i.slice(0,l-1)}\u2026`:i;return`- ${r} \u2014 ${m}`}).join(`
2
- `);if(o.length<=t)return o;const u=e.map(r=>r.name),p=u.join(", ");return p.length<=t?p:h(u,t)}function h(e,t){const n=[];for(const o of e){if([...n,o].join(", ").length+c(e.length-n.length-1).length>t)break;n.push(o)}return n.length>0?`${n.join(", ")}${c(e.length-n.length)}`:""}function c(e){return e>0?` \u2026 (+${e} more)`:""}export{$ as buildToolList,a as toToolListEntries};
1
+ import{ALL_DEFAULT_TOOL_NAMES as p}from"../docs-mcp/tool-schemas.js";import{sanitizeToolName as c}from"./build-tool-type-declarations.js";const i=60,f=20,m=40;function L(n,e){return[...n.map(t=>({name:c(t.name),purpose:t.description,builtIn:p.has(t.name)})),...e.map(t=>({name:c(t.id),purpose:t.purpose,builtIn:!0}))]}function N(n,e){if(n.length===0||e<=0)return"";const t=n.map(o=>({...o,purpose:(o.purpose??"").replace(/\s+/g," ").trim()}));for(const o of a()){const s=h(t,o);if(s.length<=e)return s}const r=n.map(o=>o.name),u=r.join(", ");return u.length<=e?u:_(r,e)}function*a(){for(let n=i;n>=m;n--)yield{builtIn:n,custom:i};for(let n=i;n>=f;n--)yield{builtIn:0,custom:n}}function h(n,e){return n.map(({name:t,purpose:r,builtIn:u})=>{const o=u?e.builtIn:e.custom;return r&&o>0?`- ${t} \u2014 ${g(r,o)}`:`- ${t}`}).join(`
2
+ `)}function g(n,e){return n.length<=e?n:`${n.slice(0,e-1).replace(/[\uD800-\uDBFF]$/,"").trimEnd()}\u2026`}function _(n,e){const t=[];for(const r of n){if([...t,r].join(", ").length+l(n.length-t.length-1).length>e)break;t.push(r)}return t.length>0?`${t.join(", ")}${l(n.length-t.length)}`:""}function l(n){return n>0?` \u2026 (+${n} more)`:""}export{N as buildToolList,L as toToolListEntries};
@@ -1,8 +1,8 @@
1
- const f=/^[A-Za-z_$][\w$]*$/;function y(n){const e=n.split(/[^A-Za-z0-9]+/).filter(Boolean).map((o,i)=>i===0?o:o[0].toUpperCase()+o.slice(1)).join("");return f.test(e)?e:`_${e}`}function T(n){return["```ts","declare const tools: {",n.map(e=>{const o=e.schema,i=e.outputSchema?u(e.outputSchema):"unknown",s=o.required?.length?"input":"input?";return` /** ${l(e.description)} */
1
+ const l=/^[A-Za-z_$][\w$]*$/;function y(n){const e=n.split(/[^A-Za-z0-9]+/).filter(Boolean).map((o,i)=>i===0?o:o[0].toUpperCase()+o.slice(1)).join("");return l.test(e)?e:`_${e}`}function w(n){return["```ts","declare const tools: {",n.map(e=>{const o=e.schema,i=e.outputSchema?u(e.outputSchema):"unknown",s=o.required?.length?"input":"input?";return` /** ${f(e.description)} */
2
2
  ${y(e.name)}(${s}: ${u(o," ")}): Promise<${i}>;`}).join(`
3
3
  `),"};","```"].join(`
4
- `)}function l(n){return(n??"").replace(/\*\//g,"*\\/")}function u(n,r=""){if(!n||typeof n!="object")return"unknown";const e=n.nullable?" | null":"";if(typeof n.codemodeType=="string")return n.codemodeType+e;if(Array.isArray(n.enum))return n.enum.map(m).join(" | ")+e;switch(n.type){case"string":return"string"+e;case"number":case"integer":return"number"+e;case"boolean":return"boolean"+e;case"array":return`Array<${u(n.items,r)}>`+e;case"object":return b(n,r)+e;default:return"unknown"}}function m(n){return typeof n=="string"?`'${n.replace(/\\/g,"\\\\").replace(/'/g,"\\'")}'`:String(n)}function b(n,r){const e=n.properties??{},o=Object.keys(e),i=n.additionalProperties,s=i?i===!0?"unknown":u(i,r):void 0;if(o.length===0)return i===!1?"{}":`Record<string, ${s??"unknown"}>`;const $=new Set(n.required??[]),c=o.map(t=>{const p=e[t],d=$.has(t)?"":"?",g=f.test(t)?t:JSON.stringify(t);return{doc:p.description,field:`${g}${d}: ${u(p,r+" ")}`}});if(s&&c.push({field:`[key: string]: ${s}`}),!c.some(({doc:t})=>t))return`{ ${c.map(({field:t})=>t).join("; ")} }`;const a=r+" ";return`{
5
- ${c.map(({doc:t,field:p})=>`${t?`${a}/** ${l(t)} */
4
+ `)}function f(n){return(n??"").replace(/\*\//g,"*\\/")}function u(n,r=""){if(!n||typeof n!="object")return"unknown";const e=typeof n.codemodeType=="string"?[n.codemodeType]:Array.isArray(n.enum)&&n.enum.length>0?n.enum.map(b):[m(n,r)];return n.nullable&&e.push("null"),[...new Set(e)].join(" | ")}function m(n,r){switch(n.type){case"string":return"string";case"number":case"integer":return"number";case"boolean":return"boolean";case"array":return`Array<${u(n.items,r)}>`;case"object":return j(n,r);default:return"unknown"}}function b(n){return typeof n=="string"?`'${n.replace(/\\/g,"\\\\").replace(/'/g,"\\'")}'`:String(n)}function j(n,r){const e=n.properties??{},o=Object.keys(e),i=n.additionalProperties,s=i?i===!0?"unknown":u(i,r):void 0;if(o.length===0)return i===!1?"{}":`Record<string, ${s??"unknown"}>`;const $=new Set(n.required??[]),c=o.map(t=>{const p=e[t],d=$.has(t)?"":"?",g=l.test(t)?t:JSON.stringify(t);return{doc:p.description,field:`${g}${d}: ${u(p,r+" ")}`}});if(s&&c.push({field:`[key: string]: ${s}`}),!c.some(({doc:t})=>t))return`{ ${c.map(({field:t})=>t).join("; ")} }`;const a=r+" ";return`{
5
+ ${c.map(({doc:t,field:p})=>`${t?`${a}/** ${f(t)} */
6
6
  `:""}${a}${p};`).join(`
7
7
  `)}
8
- ${r}}`}export{T as buildToolTypeDeclarations,y as sanitizeToolName};
8
+ ${r}}`}export{w as buildToolTypeDeclarations,y as sanitizeToolName};
@@ -1,5 +1,5 @@
1
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"],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
- `),p=["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 m(r){return c.every(t=>r.includes(t))?h:p}function d(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=d(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}`.","","When an operation accepts more than one security scheme, pass `securityScheme` with the scheme name the user holds a credential for; without it the server picks one, and a mismatched credential fails upstream.","",`Callable APIs (their documented hosts are reachable via \`fetch\`): ${e}`,"",m(t)].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
5
  `)}};export{l as FETCH_DECLARATION,g as fetchCapability};
@@ -6,7 +6,6 @@ export type SandboxCapability = {
6
6
  purpose: string;
7
7
  /** Whether this capability is live for THIS request (RBAC/config/flag-dependent). */
8
8
  isActive(context: McpToolContext): boolean;
9
- /** How this capability changes `execute`'s MCP annotations when active. */
10
9
  annotations: Partial<ToolAnnotations>;
11
10
  /**
12
11
  * The self-contained `describe-tools` section for this capability: heading, TS declaration,
@@ -3,8 +3,7 @@ import type { McpToolSchema } from '../../../../types';
3
3
  import type { McpToolContext } from '../../types.js';
4
4
  import type { SandboxCapability } from './types.js';
5
5
  export declare function getActiveCapabilities(context: McpToolContext): SandboxCapability[];
6
- /** `execute`'s annotations = the read-only base with every active capability's delta merged over it. */
7
- export declare function composeExecuteAnnotations(active: SandboxCapability[]): ToolAnnotations;
6
+ export declare function composeExecuteAnnotations(tools: McpToolSchema[], capabilities: SandboxCapability[]): ToolAnnotations;
8
7
  /**
9
8
  * The describe-tools output: the tool signatures, the always-present
10
9
  * `execute` args note, then one self-contained section per selected capability.
@@ -1,7 +1,7 @@
1
- import{buildToolTypeDeclarations as c,sanitizeToolName as p}from"../build-tool-type-declarations.js";import{EXECUTE_BASE_ANNOTATIONS as u}from"../tools/execute-schema.js";import{buildExecuteExample as m,EXECUTE_ARGS_NOTE as a,USAGE_NOTES as E}from"../prompts.js";import{FETCH_TOOL_NAME as f}from"../constants.js";import{ALL_CAPABILITIES as A}from"./registry.js";function S(n){return A.filter(e=>e.isActive(n))}function _(n){return n.reduce((e,i)=>({...e,...i.annotations}),{...u})}function x(n,e,i){const r=n.map(o=>p(o.name)),t=[];if(n.length>0){const o=c(n),s=o.includes("OpenApi")?`
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")?`
2
2
 
3
- ${E}`:"";t.push(`## Sandbox tools
3
+ ${m}`:"";e.push(`## Sandbox tools
4
4
 
5
- ${o}${s}`)}t.push(a),n.length>0&&!e.some(o=>o.id===f)&&t.push(m(r));for(const o of e)t.push(o.renderSection(i,r));return t.join(`
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(`
6
6
 
7
- `)}export{_ as composeExecuteAnnotations,S as getActiveCapabilities,x as renderDescribeToolsOutput};
7
+ `)}export{h as composeExecuteAnnotations,H as getActiveCapabilities,O as renderDescribeToolsOutput};
@@ -1,5 +1,6 @@
1
1
  import type { CodeAudit } from './code-audit.js';
2
- type CodeExecutionAuditRecord = {
2
+ import type { McpCallAttribution } from '../types.js';
3
+ type CodeExecutionAuditRecord = Pick<McpCallAttribution, 'requestId' | 'messageId'> & {
3
4
  audit: CodeAudit;
4
5
  code: string;
5
6
  description: string;
@@ -12,6 +13,6 @@ type CodeExecutionAuditRecord = {
12
13
  * Full sandbox input for one code mode `execute`, keyed by the same `code_sha256` the
13
14
  * `mcpServer.codeExecuted` telemetry event carries, so a Grafana row resolves to this line.
14
15
  */
15
- export declare function logCodeExecutionAudit({ audit, code, description, sessionHandle, toolNames, fetchBudget, fetchCapable, }: CodeExecutionAuditRecord): void;
16
+ export declare function logCodeExecutionAudit({ audit, code, description, sessionHandle, toolNames, fetchBudget, fetchCapable, requestId, messageId, }: CodeExecutionAuditRecord): void;
16
17
  export {};
17
18
  //# sourceMappingURL=code-execution-audit.d.ts.map
@@ -1 +1 @@
1
- import{auditInput as t,auditSha256 as h,logAuditRecord as a}from"../audit/audit-log.js";function g({audit:e,code:c,description:d,sessionHandle:o,toolNames:i,fetchBudget:n,fetchCapable:u}){a("Record code execution input",{code_sha256:e.sha256,code_length:e.length,flags:e.flags,subject_sha256:o?h(o):void 0,description:t(d),tools:[...i].sort().join(","),fetch_capable:u,fetch_budget:n,code:t(c)})}export{g as logCodeExecutionAudit};
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,18 +1,17 @@
1
1
  import { telemetry } from '../../../telemetry/index.js';
2
2
  import type { CodeAudit } from './code-audit.js';
3
+ import type { McpCallAttribution } from '../types.js';
3
4
  type CodeExecutedData = Parameters<typeof telemetry.sendMcpCodeExecutedMessage>[0][number];
4
5
  export type McpCodeFailureReason = NonNullable<CodeExecutedData['failure_reason']>;
5
- type CodeExecutedEvent = {
6
+ type CodeExecutedEvent = McpCallAttribution & {
6
7
  audit: CodeAudit;
7
8
  fetchCount: number;
8
9
  outcome: CodeExecutedData['outcome'];
9
10
  durationMs: number;
10
11
  failureReason?: McpCodeFailureReason;
11
12
  failedTool?: string;
12
- client?: string;
13
- clientVersion?: string;
14
13
  };
15
14
  /** Audit record for one sandbox run. Carries the code fingerprint, never the code. */
16
- export declare function reportCodeExecuted({ audit, fetchCount, outcome, durationMs, failureReason, failedTool, client, clientVersion, }: CodeExecutedEvent): void;
15
+ export declare function reportCodeExecuted({ audit, fetchCount, outcome, durationMs, failureReason, failedTool, client, clientVersion, requestId, messageId, }: CodeExecutedEvent): void;
17
16
  export {};
18
17
  //# sourceMappingURL=code-execution-telemetry.d.ts.map
@@ -1 +1 @@
1
- import{telemetry as l}from"../../../telemetry/index.js";import{logger as n}from"../../../tools/notifiers/logger.js";import{McpServerType as m}from"../constants.js";import{serverAttributes as h}from"../utils/telemetry-attributes.js";function d({audit:e,fetchCount:t,outcome:c,durationMs:s,failureReason:o,failedTool:r,client:f,clientVersion:g}){try{l.sendMcpCodeExecutedMessage([{...h(m.Docs),code_sha256:e.sha256,code_length:e.length,fetch_count:t,outcome:c,flags:e.flags,duration_ms:s,failure_reason:o,failed_tool:r,client:f,client_version:g}])}catch{}n.info(`Gateway MCP code executed [${e.sha256.slice(0,12)}] outcome=${c} codeLength=${e.length} fetchCount=${t}`+(e.flags?` flags=${e.flags}`:"")+` durationMs=${s}`+(o?` failureReason=${o}`:"")+(r?` failedTool=${r}`:""))}export{d as reportCodeExecuted};
1
+ import{telemetry as m}from"../../../telemetry/index.js";import{logger as h}from"../../../tools/notifiers/logger.js";import{McpServerType as p}from"../constants.js";import{serverAttributes as a}from"../utils/telemetry-attributes.js";function x({audit:e,fetchCount:t,outcome:s,durationMs:c,failureReason:o,failedTool:r,client:g,clientVersion:f,requestId:l,messageId:n}){try{m.sendMcpCodeExecutedMessage([{...a(p.Docs),code_sha256:e.sha256,code_length:e.length,fetch_count:t,outcome:s,flags:e.flags,duration_ms:c,failure_reason:o,failed_tool:r,client:g,client_version:f,message_id:n}],{requestId:l})}catch{}h.info(`Gateway MCP code executed [${e.sha256.slice(0,12)}] outcome=${s} codeLength=${e.length} fetchCount=${t}`+(e.flags?` flags=${e.flags}`:"")+` durationMs=${c}`+(o?` failureReason=${o}`:"")+(r?` failedTool=${r}`:""))}export{x as reportCodeExecuted};
@@ -1,7 +1,7 @@
1
1
  import{buildToolList as i}from"./build-tool-list.js";const r=2048,d="Both `execute` arguments are required: `code` (the JavaScript to run; return a value to receive it) and `description` (a short human-readable summary of what the code does).",n="Available tools (exact signatures come from `describe-tools`):";function a(e,t){if(t.length===0)return e;const o=r-e.length-n.length-3,s=i(t,o);return s?[e,"",n,s].join(`
2
2
  `):e}function h(e,t=[]){const o=["Run JavaScript in a sandbox against the documentation tools on the global `tools` object.",e?"The extra globals are `tools`, `fetch`, `URL`, `URLSearchParams`, and `FormData` - there is no `console`, `setTimeout`, `require`, or Node.js API; all other I/O goes through `tools`.":"The only extra global is `tools` - there is no `fetch`, `console`, `setTimeout`, `require`, or Node.js API; all I/O goes through `tools`.","","Workflow - minimize round-trips; one `describe-tools` call plus one `execute` call covers most requests:","1. Analyze the request and decide which sandbox tools it needs.","2. Call `describe-tools` with those names to get their exact TypeScript signatures - inputs, result shapes, and a worked example. NEVER call `execute` with guessed method names, parameter names, enum values, or result field names: read fields off the declared return types, not from assumptions.","3. Batch everything into a SINGLE script: chain tool calls, pass one call's output into the next, process results in plain JavaScript, and `return` only what the request needs."].join(`
3
3
  `);return a(o,t)}const p=["Get the exact TypeScript signatures of the sandbox tools available to `execute`.","Analyze the user request first, then pass `tools` with only the tool names the request needs (every name is listed in this input schema / description); omit `tools` only when you cannot tell which tools apply.","Always call this before your first `execute` and never guess signatures. Request every tool the task may need in ONE call instead of calling this repeatedly."].join(`
4
- `);function m(e,t=[]){const o=["This server exposes documentation tools (API discovery, endpoint details, security schemes, full-text search) through `describe-tools` and `execute`:","- `describe-tools` returns the exact TypeScript signatures of the sandbox tools.","- `execute` runs JavaScript that calls those tools on the global `tools` object.","Workflow: analyze the request, call `describe-tools` once with only the tool names it needs, then batch everything into a single `execute` script. Minimize round-trips and never guess tool signatures.",...e?["The sandbox also has a global `fetch` that can call the documented APIs (allow-listed hosts only). Include `fetch` in your `describe-tools` call to get its contract and the list of callable APIs."]:[]].join(`
4
+ `);function m(e,t=[]){const o=["This server exposes documentation tools (API discovery, endpoint details, security schemes, full-text search) through `describe-tools` and `execute`:","- `describe-tools` returns the exact TypeScript signatures of the sandbox tools.","- `execute` runs JavaScript that calls those tools on the global `tools` object.","Workflow: analyze the request, call `describe-tools` once with `tools` set to only the names it needs, then batch everything into a single `execute` script. Minimize round-trips and never guess tool signatures.",...e?["The sandbox also has a global `fetch` that can call the documented APIs (allow-listed hosts only). Include `fetch` in your `describe-tools` call to get its contract and the list of callable APIs."]:[]].join(`
5
5
  `);return a(o,t)}const l=["listApis","getEndpoints"],c=["Example - list the write endpoints of an 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 writes = endpoints.filter((e) => e.method !== 'GET');","return { api: api.name, writes: writes.map((e) => `${e.method} ${e.path}`) };","```"].join(`
6
6
  `);function g(e){if(l.every(o=>e.includes(o)))return c;const[t]=e;return t?[`Example - call \`${t}\` and return what the request needs:`,"","```ts",`const result = await tools.${t}({ /* the input its signature above declares */ });`,"return result;","```"].join(`
7
7
  `):""}const b=["Types named `OpenApi\u2026` are the standard OpenAPI Specification objects.","Payload samples live on a media type object (`requestBody.content[mediaType]`, `responses[code].content[mediaType]`): `.example` holds a single value, `.examples[name].value` a named map, and some descriptions only set `.schema.example`. Read each before concluding a sample is absent."].join(`
@@ -1,3 +1,3 @@
1
- import{renderDescribeToolsOutput as O}from"../capabilities/index.js";import{McpServerType as M}from"../../constants.js";import{reportMcpToolCalled as _,reportMcpToolError as k}from"../../workers/mcp-tool-telemetry.js";import{DESCRIBE_TOOLS_TOOL_NAME as d}from"../constants.js";import{DESCRIBE_TOOLS_DESCRIPTION as D}from"../prompts.js";import{sanitizeToolName as n}from"../build-tool-type-declarations.js";import{UnknownToolError as v}from"./tool-errors.js";function x(i,c){const t=[...new Set([...i.map(s=>n(s.name)),...c.map(s=>n(s.id))])];return{name:d,title:"Describe tools",description:D,schema:{type:"object",required:[],additionalProperties:!1,properties:{tools:{type:"array",description:`Tool names to describe: ${t.join(", ")}. Omit to describe everything.`,items:t.length>0?{type:"string",enum:t}:{type:"string"},nullable:!0}}}}}function P(i,c,t,s){const l=new Map(i.map(r=>[n(r.name),r])),f=new Map(t.map(r=>[n(r.id),r]));return async r=>{const u=performance.now(),h=s.mcpMode??"code";try{const o=[...new Set((r.tools??[]).map(n))],a=o.length===0,T=o.filter(e=>!l.has(e)&&!f.has(e));if(T.length>0){const e=[...l.keys(),...f.keys()];throw new v(`Unknown tool(s): ${T.join(", ")}. Valid tools: ${e.join(", ")}.`)}const E=a?t:t.filter(e=>o.includes(n(e.id))),p=a?i:o.filter(e=>l.has(e)).map(e=>l.get(e)),y=await Promise.all(p.map(e=>c(e.name))),S=p.filter((e,m)=>y[m]),w=p.filter((e,m)=>!y[m]),g=[O(S,E,s)];w.length>0&&g.push(`Not available for this request: ${w.map(e=>n(e.name)).join(", ")}`);const b=g.join(`
1
+ import{renderDescribeToolsOutput as _}from"../capabilities/index.js";import{McpServerType as u}from"../../constants.js";import{logMcpToolCallAudit as E,reportMcpToolCalled as k,reportMcpToolError as C}from"../../workers/mcp-tool-telemetry.js";import{DESCRIBE_TOOLS_TOOL_NAME as l}from"../constants.js";import{DESCRIBE_TOOLS_DESCRIPTION as j}from"../prompts.js";import{sanitizeToolName as s}from"../build-tool-type-declarations.js";import{UnknownToolError as O}from"./tool-errors.js";import{callAttribution as N}from"../../utils/telemetry-attributes.js";function U(c,f){const r=[...new Set([...c.map(n=>s(n.name)),...f.map(n=>s(n.id))])];return{name:l,title:"Describe tools",description:j,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},schema:{type:"object",required:[],additionalProperties:!1,properties:{tools:{type:"array",description:`Tool names to describe: ${r.join(", ")}. Omit to describe everything.`,items:r.length>0?{type:"string",enum:r}:{type:"string"},nullable:!0}}}}}function x(c,f,r,n){const p=new Map(c.map(t=>[s(t.name),t])),w=new Map(r.map(t=>[s(t.id),t]));return async t=>{const b=performance.now(),m=n.mcpMode??"code",d=N(n);try{const o=[...new Set((t.tools??[]).map(s))],i=o.length===0,a=o.filter(e=>!p.has(e)&&!w.has(e));if(a.length>0){const e=[...p.keys(),...w.keys()];throw new O(`Unknown tool(s): ${a.join(", ")}. Valid tools: ${e.join(", ")}.`)}const S=i?r:r.filter(e=>o.includes(s(e.id))),T=i?c:o.filter(e=>p.has(e)).map(e=>p.get(e)),v=await Promise.all(T.map(e=>f(e.name))),D=T.filter((e,y)=>v[y]),M=T.filter((e,y)=>!v[y]),g=[_(D,S,n)];M.length>0&&g.push(`Not available for this request: ${M.map(e=>s(e.name)).join(", ")}`);const h=g.join(`
2
2
 
3
- `);return _({tool:d,mode:h,serverType:M.Docs,durationMs:Math.round(performance.now()-u),outputLength:b.length}),{content:[{type:"text",text:b}]}}catch(o){const a=o instanceof v;throw k({tool:d,mode:h,serverType:M.Docs,durationMs:Math.round(performance.now()-u),message:o instanceof Error?o.message:String(o),stack:!a&&o instanceof Error&&o.stack||"",errorClass:a?"tool_error":"server_error"}),o}}}export{P as describeTools,x as describeToolsSchema};
3
+ `);return E({tool:l,mode:m,serverType:u.Docs,args:t,result:h,...d}),k({tool:l,mode:m,serverType:u.Docs,durationMs:Math.round(performance.now()-b),outputLength:h.length,...d}),{content:[{type:"text",text:h}]}}catch(o){const i=o instanceof O,a=i?"tool_error":"server_error";throw E({tool:l,mode:m,serverType:u.Docs,args:t,errorClass:a,...d}),C({tool:l,mode:m,serverType:u.Docs,durationMs:Math.round(performance.now()-b),message:o instanceof Error?o.message:String(o),stack:!i&&o instanceof Error&&o.stack||"",errorClass:a,...d}),o}}}export{x as describeTools,U as describeToolsSchema};
@@ -1,5 +1,3 @@
1
- import type { ToolAnnotations } from '@modelcontextprotocol/server';
2
1
  import type { McpToolSchema } from '../../../../types';
3
- export declare const EXECUTE_BASE_ANNOTATIONS: ToolAnnotations;
4
2
  export declare const EXECUTE_TOOL_SCHEMA: McpToolSchema;
5
3
  //# sourceMappingURL=execute-schema.d.ts.map
@@ -1 +1 @@
1
- import{EXECUTE_TOOL_NAME as e}from"../constants.js";import{buildExecuteDescription as t}from"../prompts.js";const n={readOnlyHint:!0,openWorldHint:!1},r={name:e,title:"Execute code",description:t(!1),annotations:n,schema:{type:"object",required:["code","description"],additionalProperties:!1,properties:{code:{type:"string",description:"JavaScript to run in the sandbox. Return a value to receive it as the result.",minLength:1},description:{type:"string",description:"A short, human-readable summary of what this code does.",minLength:1},sessionHandle:{type:"string",description:"Handle returned by createAnonymousSession. Required when an API needs credentials. This parameter is only offered when createAnonymousSession is available, so pass it whenever you have called that tool.",minLength:1}}}};export{n as EXECUTE_BASE_ANNOTATIONS,r as EXECUTE_TOOL_SCHEMA};
1
+ import{EXECUTE_TOOL_NAME as e}from"../constants.js";import{buildExecuteDescription as t}from"../prompts.js";const r={name:e,title:"Execute code",description:t(!1),schema:{type:"object",required:["code","description"],additionalProperties:!1,properties:{code:{type:"string",description:"JavaScript to run in the sandbox. Return a value to receive it as the result.",minLength:1},description:{type:"string",description:"A short, human-readable summary of what this code does.",minLength:1},sessionHandle:{type:"string",description:"Handle returned by createAnonymousSession. Required when an API needs credentials. This parameter is only offered when createAnonymousSession is available, so pass it whenever you have called that tool.",minLength:1}}},outputSchema:{type:"object",properties:{result:{description:"The value the code returned, as JSON"},error:{type:"string",description:"Why the code failed. Set only on a failed call"}}}};export{r as EXECUTE_TOOL_SCHEMA};
@@ -1 +1 @@
1
- import{runInSandbox as C}from"../../../../sandbox/sandbox.js";import{SANDBOX_FAILURE as E}from"../../../../sandbox/constants/sandbox.js";import{returnLastExpression as y}from"../../../../sandbox/utils/return-last-expression.js";import{isMcpToolAvailable as g}from"../../workers/execute-mcp-tool.js";import{importMcpToolHandlers as A}from"../../workers/import-mcp-tool-handlers.js";import{isFetchCapable as M}from"../../gateway-mcp/callable-apis.js";import{buildExecuteHostFetch as S}from"../../gateway-mcp/fetch-capability.js";import{withAuthRequiredMeta as k}from"../../gateway-mcp/upstream-auth.js";import{CODE_MODE_TOOL_NAMES as v,EXECUTE_TOOL_NAME as x}from"../constants.js";import{sanitizeToolName as F}from"../build-tool-type-declarations.js";import{invokeTool as H}from"../invoke-tool.js";import{createSandboxSetup as R}from"../sandbox/create-sandbox-setup.js";import{createToolInputValidator as D}from"../sandbox/tool-input-validator.js";import{describeGuestError as j}from"../sandbox/unknown-tool-hint.js";import{auditCode as B}from"../code-audit.js";import{reportCodeExecuted as I}from"../code-execution-telemetry.js";import{logCodeExecutionAudit as L}from"../code-execution-audit.js";import{ToolResultError as N}from"./tool-errors.js";const P=async(e,t,n)=>{const i=new Map,s=await U(t,n,i),a=[],o=M(t)?await S(t,h=>a.push(h)):void 0;let f=0;const m=o?h=>(f+=1,o(h).catch(_=>{throw i.set(O(_),{reason:"runtime_error"}),_})):void 0,c=B(e.code);L({audit:c,code:e.code,description:e.description,sessionHandle:e.sessionHandle,toolNames:Object.keys(s),fetchBudget:t.gatewayFetchBudgetPerExec,fetchCapable:o!==void 0});const l=Date.now(),d=y(e.code),{result:u,error:r,failure:b,errorPosition:T}=await C(d,{setupContext:R(s,m),authoredCode:e.code}),w=r===void 0?void 0:j(d,r,T,Object.keys(s)),p=r!==void 0&&b===E.HostError?i.get(r):void 0;return I({audit:c,fetchCount:f,outcome:r===void 0?"ok":"error",durationMs:Date.now()-l,failureReason:V(b,p,w?.unknownTool),failedTool:p?.tool,client:t.client,clientVersion:t.clientVersion}),k({content:[{type:"text",text:JSON.stringify({result:u,error:w?.message})}],isError:r!==void 0,...p?.tool!==void 0?{errorClass:"tool_error"}:{}},a)};function V(e,t,n){return e===E.HostError?t?.reason??"runtime_error":e===E.RuntimeError?n===void 0?e:"unknown_tool":e}async function U(e,t,n){const i=Object.keys(await A()).filter(o=>!v.has(o)),s=await Promise.all(i.map(o=>g({toolName:o,context:e}).catch(()=>!1))),a={};return i.forEach((o,f)=>{if(!s[f])return;const m=F(o),c=e.sandboxToolSchemas?.[o],l=c?D(m,c):void 0;a[m]=d=>{const u=l?.(d);return u?(n.set(u,{tool:o,reason:"inner_tool_error"}),Promise.reject(new Error(u))):H(o,d,e,t).catch(r=>{throw n.set(O(r),{tool:o,reason:r instanceof N?"inner_tool_error":"server_error"}),r})}}),a}function O(e){return e instanceof Error?e.message:String(e)}var ae={[x]:P};export{ae as default};
1
+ import{runInSandbox as y}from"../../../../sandbox/sandbox.js";import{SANDBOX_FAILURE as b}from"../../../../sandbox/constants/sandbox.js";import{returnLastExpression as M}from"../../../../sandbox/utils/return-last-expression.js";import{isMcpToolAvailable as v}from"../../workers/execute-mcp-tool.js";import{reportMcpToolError as A}from"../../workers/mcp-tool-telemetry.js";import{McpServerType as S}from"../../constants.js";import{callAttribution as C}from"../../utils/telemetry-attributes.js";import{importMcpToolHandlers as I}from"../../workers/import-mcp-tool-handlers.js";import{isFetchCapable as k}from"../../gateway-mcp/callable-apis.js";import{buildExecuteHostFetch as F}from"../../gateway-mcp/fetch-capability.js";import{withAuthRequiredMeta as D}from"../../gateway-mcp/upstream-auth.js";import{CODE_MODE_TOOL_NAMES as H,EXECUTE_TOOL_NAME as R}from"../constants.js";import{sanitizeToolName as x}from"../build-tool-type-declarations.js";import{invokeTool as j}from"../invoke-tool.js";import{createSandboxSetup as B}from"../sandbox/create-sandbox-setup.js";import{createToolInputValidator as L}from"../sandbox/tool-input-validator.js";import{describeGuestError as P}from"../sandbox/unknown-tool-hint.js";import{auditCode as q}from"../code-audit.js";import{reportCodeExecuted as N}from"../code-execution-telemetry.js";import{logCodeExecutionAudit as U}from"../code-execution-audit.js";import{ToolResultError as X}from"./tool-errors.js";const z=async(o,r,n)=>{const s=new Map,a=await J(r,n,s),d=[],e=k(r)?await F(r,h=>d.push(h)):void 0;let m=0;const f=e?h=>(m+=1,e(h).catch(w=>{throw s.set(O(w),{reason:"runtime_error"}),w})):void 0,u=q(o.code);U({audit:u,code:o.code,description:o.description,sessionHandle:o.sessionHandle,toolNames:Object.keys(a),fetchBudget:r.gatewayFetchBudgetPerExec,fetchCapable:e!==void 0,requestId:r.requestId,messageId:r.messageId});const l=Date.now(),c=M(o.code),{result:i,error:t,failure:T,errorPosition:g}=await y(c,{setupContext:B(a,f),authoredCode:o.code}),p=t===void 0?void 0:P(c,t,g,Object.keys(a)),E=t!==void 0&&T===b.HostError?s.get(t):void 0;N({audit:u,fetchCount:m,outcome:t===void 0?"ok":"error",durationMs:Date.now()-l,failureReason:G(T,E,p?.unknownTool),failedTool:E?.tool,...C(r)});const _=p===void 0?{result:i}:{error:p.message};return D({content:[{type:"text",text:JSON.stringify(_)}],structuredContent:_,isError:t!==void 0,...E?.tool!==void 0?{errorClass:"tool_error"}:{}},d)};function G(o,r,n){return o===b.HostError?r?.reason??"runtime_error":o===b.RuntimeError?n===void 0?o:"unknown_tool":o}async function J(o,r,n){const s=Object.keys(await I()).filter(e=>!H.has(e)),a=await Promise.all(s.map(e=>v({toolName:e,context:o}).catch(()=>!1))),d={};return s.forEach((e,m)=>{if(!a[m])return;const f=x(e),u=o.sandboxToolSchemas?.[e],l=u?L(f,u):void 0;d[f]=c=>{const i=l?.(c);return i?(A({tool:e,message:i,mode:"code",serverType:S.Docs,durationMs:0,errorClass:"tool_error",...C(o)}),n.set(i,{tool:e,reason:"inner_tool_error"}),Promise.reject(new Error(i))):j(e,c,o,r).catch(t=>{throw n.set(O(t),{tool:e,reason:t instanceof X?"inner_tool_error":"server_error"}),t})}}),d}function O(o){return o instanceof Error?o.message:String(o)}var Eo={[R]:z};export{Eo as default};
@@ -1,2 +1,2 @@
1
- import{MANAGE_API_CREDENTIALS_TOOL_NAME as P}from"../../constants.js";import{buildUpstreamCredentialFallback as b,buildUpstreamCredentialInputRequired as I,dedupeElicitation as S,isCredentialElicitationDeclined as k,isStatelessRequest as E,schemeLabelOf as w,supportsUrlElicitation as C}from"../../gateway-mcp/elicitation.js";import{getCallableApis as u,isFetchCapable as j}from"../../gateway-mcp/callable-apis.js";import{secretStore as T}from"../../gateway-mcp/secret-store.js";import{MISSING_SESSION_HANDLE_MESSAGE as q,resolveSecretSubject as $}from"../../gateway-mcp/subject.js";import{upstreamAuthKey as R}from"../../gateway-mcp/upstream-auth.js";import{resolveUpstreamApiAuth as L}from"../../gateway-mcp/upstream-auth-scheme.js";import{apiTitleKey as N,countApiTitles as O}from"../../docs-mcp/utils/api-titles.js";function W(e){return!!e.elicitationEnabled&&j(e)}function z(e){const s=u(e),t=s.map(r=>r.relativePath),a=[...t,...U(s)];return{name:P,title:"Manage API credentials",description:["Get a secure link where the user sets, replaces, or removes the credentials this server sends to a documented API.","Call it when the user wants to change or clear an API key, or when a tool result tells you the stored credentials were rejected.","The link covers every credential the API accepts, so scheme is optional - pass it only when a tool result names the scheme that was rejected.","It returns a link for the user to open - never ask for the secret in the conversation and never pass it as an argument."].join(`
2
- `),annotations:{readOnlyHint:!1,openWorldHint:!1},schema:{type:"object",required:["api"],additionalProperties:!1,properties:{api:{type:"string",description:`The API to manage credentials for: its \`filePath\` or the \`name\` from \`listApis\`.${t.length>0?` The file paths are: ${t.join(", ")}.`:""}`,minLength:1,...a.length>0?{enum:a}:{}},scheme:{type:"string",description:"Name of the security scheme to manage the credential for, as named in the API description (a tool result that reports a rejected credential names it). Omit it to let the link cover every scheme the API accepts.",minLength:1},sessionHandle:{type:"string",description:"Handle returned by createAnonymousSession. Required while the caller is anonymous, so the credentials are stored against the same subject the API calls use.",minLength:1}}}}}function U(e){const s=O(e);return e.map(t=>t.name).filter(t=>s.get(N(t))===1)}function J(e,s){return async(t,a)=>{const r=$(e.user,typeof t.sessionHandle=="string"?t.sessionHandle:void 0);if(r.kind==="invalid")return h(r.message);if(r.kind==="anonymous")return h(q);const{subject:m}=r,p=typeof t.api=="string"?t.api:"",n=u(e).find(c=>c.relativePath===p||c.name===p);if(!n){const c=u(e).map(v=>v.relativePath).join(", ");return h(`Unknown api "${p}". Credentials can only be managed for the APIs this server can call: ${c||"none"}.`)}if(k(a.mcpReq.inputResponses))return{content:[{type:"text",text:`The user declined the credentials prompt for the "${n.name}" API, so this call minted no link.`}],isError:!1};const i=await L(e,n.relativePath),l=typeof t.scheme=="string"?t.scheme:void 0,y=Object.keys(i.schemes);if(l&&!i.schemes[l])return h(`Unknown scheme "${l}" for api "${n.relativePath}". The security schemes this server can store credentials for are: ${y.join(", ")}.`);const o=l??i.defaultScheme,d=w(i.schemes,o),f=await s.getKv(),A={subject:m,baseUrl:e.baseUrl??"",target:{api:n.relativePath,name:n.name,scheme:o,...d?{schemeLabel:d}:{}},auth:i.schemes[o],apiAuth:i,kv:f,hasExistingSecret:await T.hasSecret(f,m,n.relativePath,o),reason:{kind:"requested"}};if(E(a.mcpReq)&&C(s.getClientCapabilities()))return await I(A);const g=R({api:n.relativePath,scheme:o});return{content:[{type:"text",text:await S(`${m}:${g}`,()=>b(A))}],isError:!1}}}function h(e){return{content:[{type:"text",text:e}],isError:!0}}export{W as isManageApiCredentialsToolAvailable,J as manageApiCredentials,z as manageApiCredentialsSchema};
1
+ import{MANAGE_API_CREDENTIALS_TOOL_NAME as P}from"../../constants.js";import{acceptedCredentialsLink as k,buildCredentialsAcceptedHint as w,buildUpstreamCredentialFallback as S,buildUpstreamCredentialInputRequired as I,credentialElicitationAnswer as E,dedupeElicitation as C,isStatelessRequest as j,schemeLabelOf as q,supportsUrlElicitation as T}from"../../gateway-mcp/elicitation.js";import{getCallableApis as u,isFetchCapable as H}from"../../gateway-mcp/callable-apis.js";import{secretStore as R}from"../../gateway-mcp/secret-store.js";import{MISSING_SESSION_HANDLE_MESSAGE as U,resolveSecretSubject as $}from"../../gateway-mcp/subject.js";import{upstreamAuthKey as L}from"../../gateway-mcp/upstream-auth.js";import{resolveUpstreamApiAuth as N}from"../../gateway-mcp/upstream-auth-scheme.js";import{apiTitleKey as O,countApiTitles as _}from"../../docs-mcp/utils/api-titles.js";function Q(e){return!!e.elicitationEnabled&&H(e)}function V(e){const s=u(e),t=s.map(r=>r.relativePath),i=[...t,...M(s)];return{name:P,title:"Manage API credentials",description:["Get a secure link where the user sets, replaces, or removes the credentials this server sends to a documented API.","Call it when the user wants to change or clear an API key, or when a tool result tells you the stored credentials were rejected.","The link covers every credential the API accepts, so scheme is optional - pass it only when a tool result names the scheme that was rejected.","It returns a link for the user to open - never ask for the secret in the conversation and never pass it as an argument."].join(`
2
+ `),annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!1},schema:{type:"object",required:["api"],additionalProperties:!1,properties:{api:{type:"string",description:`The API to manage credentials for: its \`filePath\` or the \`name\` from \`listApis\`.${t.length>0?` The file paths are: ${t.join(", ")}.`:""}`,minLength:1,...i.length>0?{enum:i}:{}},scheme:{type:"string",description:"Name of the security scheme to manage the credential for, as named in the API description (a tool result that reports a rejected credential names it). Omit it to let the link cover every scheme the API accepts.",minLength:1},sessionHandle:{type:"string",description:"Handle returned by createAnonymousSession. Required while the caller is anonymous, so the credentials are stored against the same subject the API calls use.",minLength:1}}}}}function M(e){const s=_(e);return e.map(t=>t.name).filter(t=>s.get(O(t))===1)}function X(e,s){return async(t,i)=>{const r=$(e.user,typeof t.sessionHandle=="string"?t.sessionHandle:void 0);if(r.kind==="invalid")return m(r.message);if(r.kind==="anonymous")return m(U);const{subject:c}=r,p=typeof t.api=="string"?t.api:"",n=u(e).find(l=>l.relativePath===p||l.name===p);if(!n){const l=u(e).map(b=>b.relativePath).join(", ");return m(`Unknown api "${p}". Credentials can only be managed for the APIs this server can call: ${l||"none"}.`)}const d=E(i.mcpReq.inputResponses);if(d==="accepted"){const l=await k(i.mcpReq.requestState(),{kv:await s.getKv(),subject:c,baseUrl:e.baseUrl??"",apis:[n.relativePath]});return{content:[{type:"text",text:w(n.name,l?.url)}],isError:!1}}if(d==="declined")return{content:[{type:"text",text:`The user declined the credentials prompt for the "${n.name}" API, so this call minted no link.`}],isError:!1};const a=await N(e,n.relativePath),o=typeof t.scheme=="string"?t.scheme:void 0,y=Object.keys(a.schemes);if(o&&!a.schemes[o])return m(`Unknown scheme "${o}" for api "${n.relativePath}". The security schemes this server can store credentials for are: ${y.join(", ")}.`);const h=o??a.defaultScheme,f=o?q(a.schemes,o):void 0,A=await s.getKv(),v={subject:c,baseUrl:e.baseUrl??"",target:{api:n.relativePath,name:n.name,scheme:h,...f?{schemeLabel:f}:{}},auth:a.schemes[h],apiAuth:a,kv:A,hasExistingSecret:await R.hasSecret(A,c,n.relativePath,h),reason:{kind:"requested"}};if(j(i.mcpReq)&&T(s.getClientCapabilities()))return await I(v);const g=L({api:n.relativePath,scheme:h});return{content:[{type:"text",text:await C(`${c}:${g}`,()=>S(v))}],isError:!1}}}function m(e){return{content:[{type:"text",text:e}],isError:!0}}export{Q as isManageApiCredentialsToolAvailable,X as manageApiCredentials,V as manageApiCredentialsSchema};
@@ -1 +1 @@
1
- import{basename as f,join as d}from"node:path";import{envConfig as p}from"../../../config/env-config.js";import{reporter as i}from"../../../tools/notifiers/reporter.js";import{CODE_MODE_TOOL_NAMES as E}from"../codemode/constants.js";import{ALL_DEFAULT_TOOL_NAMES as O}from"../docs-mcp/tool-schemas.js";import{extractToolDefinition as h}from"./extract-tool-definition.js";const T=/(^|\/)@mcp\/.*\.(ts|js)$/,M=/^[a-zA-Z0-9_-]{1,64}$/,_=new Set([...E,...O]);async function S(o,r,a){if(!p.REDOCLY_EXP_MCP_CUSTOM_TOOLS_ENABLED)return 0;C(o,a);const u=new Set(o.getMcpTools().map(n=>n.name)),l=new Map;for(const n of r.fs.scan(T)){if(n.isVirtual||n.relativePath.endsWith(".d.ts"))continue;const{relativePath:t}=n,e=f(t).replace(/\.(ts|js)$/,"");if(!M.test(e)){await i.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 i.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(_.has(e)||u.has(e)){await i.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=d(o.contentDir,t),s=await h({toolName:e,absoluteSourcePath:m,contentDir:o.contentDir,serverOutDir:o.serverOutDir});if(!s.ok){await i.panicOnBuildContentError(`Invalid MCP tool file "${t}": ${s.errors.join(" ")}`);continue}o.addMcpTools(m,[s.schema]),a.registeredToolNames.push(e)}return a.registeredToolNames.length}function C(o,r){o.removeMcpTools(r.registeredToolNames),r.registeredToolNames=[]}export{C as resetCustomMcpTools,S 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 }"},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.",S={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}}},H={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}}},L={type:"object",required:[],additionalProperties:!1,properties:{}},q={type:"object",required:[],additionalProperties:!1,properties:{}},O={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 T(e){const t=[{name:"list-apis",title:"List APIs",description:"Lists the APIs documented in this project",schema:S,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{items:{type:"array",items:{type:"object",properties:{name:{type:"string"},description:i,version:i,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:["filePath"],properties:{api:{type:"string"},version:{type:"string"},...n,servers:a,endpoints:{type:"array",items:{type:"object",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. ${r}`,schema:H,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",required:["filePath"],properties:{api:{type:"string"},version:{type:"string"},...n,servers:a,endpoint:A,globalSecurity:o,securitySchemes:u}}},{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:["filePath"],properties:{name:i,version:i,...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:["filePath"],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:L,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:O,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(...E()),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:q,annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!1},outputSchema:{type:"object",required:["sessionHandle"],properties:{sessionHandle:{type:"string"}}}}),t}const G={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}}},w={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}}},I={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}}},j={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"GraphQL schema name",minLength:1}}};function E(){return[{name:"list-graphql-apis",title:"List GraphQL APIs",description:"Lists available GraphQL schemas with their context and purpose",schema:G,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{items:{type:"array",items:{type:"object",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:w,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{name:{type:"string"},items:{type:"array",items:{type:"object",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:I,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:j,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 x=new Set([...T({requiresLogin:!0,hasGraphqlApis:!0,elicitationEnabled:!0,hasCallableApis:!0}).map(e=>e.name),d().name]);export{x as ALL_DEFAULT_TOOL_NAMES,T 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 +1 @@
1
- import{CREATE_ANONYMOUS_SESSION_TOOL_NAME as o}from"../../../constants.js";import{isFetchCapable as i}from"../../../gateway-mcp/callable-apis.js";import{createSessionHandle as t}from"../../../gateway-mcp/subject.js";const r=async()=>({content:[{type:"text",text:JSON.stringify({sessionHandle:t()})}],isError:!1});function s(e){return!!e.elicitationEnabled&&e.mcpMode==="code"&&i(e)&&!e.user?.isAuthenticated}var c={[o]:{execute:r,isAvailable:s}};export{c as default,s as isAnonymousSessionToolAvailable};
1
+ import{CREATE_ANONYMOUS_SESSION_TOOL_NAME as t}from"../../../constants.js";import{isFetchCapable as o}from"../../../gateway-mcp/callable-apis.js";import{createSessionHandle as n}from"../../../gateway-mcp/subject.js";const i=async()=>{const e={sessionHandle:n()};return{content:[{type:"text",text:JSON.stringify(e)}],structuredContent:e}};function s(e){return!!e.elicitationEnabled&&e.mcpMode==="code"&&o(e)&&!e.user?.isAuthenticated}var u={[t]:{execute:i,isAvailable:s}};export{u as default,s as isAnonymousSessionToolAvailable};
@@ -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,3 +1,5 @@
1
1
  export declare const OPERATION_METHODS: readonly ['get', 'put', 'post', 'delete', 'options', 'head', 'patch', 'trace', 'query', 'x-query'];
2
2
  export declare const HTTP_METHODS: Set<string>;
3
+ export declare const MAX_ENDPOINT_INFO_BYTES: number;
4
+ export declare const MAX_INLINED_ENDPOINT_BYTES: number;
3
5
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +1 @@
1
- const e=["get","put","post","delete","options","head","patch","trace","query","x-query"],t=new Set(e);export{t as HTTP_METHODS,e as OPERATION_METHODS};
1
+ const t=["get","put","post","delete","options","head","patch","trace","query","x-query"],e=new Set(t),o=8*1024*1024,T=1024*1024;export{e as HTTP_METHODS,o as MAX_ENDPOINT_INFO_BYTES,T as MAX_INLINED_ENDPOINT_BYTES,t as OPERATION_METHODS};
@@ -4,6 +4,12 @@ import type { McpMode } from '../../../types.js';
4
4
  export declare function visibleMethodsAt(definition: OpenAPIDefinition, path: string): string[];
5
5
  /** Paths with at least one visible operation. */
6
6
  export declare function visiblePaths(definition: OpenAPIDefinition): string[];
7
+ /** The tools that recover a lookup miss. The sandbox calls the same tools by their JS names. */
8
+ export declare function recoveryToolNames(mcpMode?: McpMode): {
9
+ endpoints: string;
10
+ search: string;
11
+ listApis: string;
12
+ };
7
13
  /** Message for a path the definition does not document, or documents only behind `x-mcp`. */
8
14
  export declare function describePathMiss(definition: OpenAPIDefinition, apiTitle: string, path: string, mcpMode?: McpMode): string;
9
15
  /** Message for a visible path that does not document the requested method, or hides it. */
@@ -1 +1 @@
1
- import{isEndpointHidden as s}from"../../../utils/xmcp-utils.js";import{formatCandidates as i}from"../../utils/api-name-matching.js";import{HTTP_METHODS as p}from"./constants.js";import{isMcpEndpoint as a}from"./utils.js";function d(t,r){const e=t.paths?.[r];return!e||s(e,"docs")?[]:Object.entries(e).filter(([n,o])=>p.has(n.toLowerCase())&&a(o)&&!s(o,"docs")).map(([n])=>n.toUpperCase()).sort()}function f(t){return Object.keys(t.paths??{}).filter(r=>d(t,r).length>0).sort()}function $(t,r,e,n){const o=f(t);if(o.length===0)return"Endpoint not found";const h=n==="code"?"Call tools.getEndpoints for the full list, or tools.search with a keyword from the request.":"Call get-endpoints for the full list, or search with a keyword from the request.";return`No path "${e}" in "${r}". Documented paths: ${i(o)}. ${h}`}function b(t,r,e,n){const o=d(t,e);return o.length===0?"Endpoint not found":`"${e}" in "${r}" documents no ${n.toUpperCase()}. Available methods: ${i(o)}.`}export{b as describeMethodMiss,$ as describePathMiss,d as visibleMethodsAt,f as visiblePaths};
1
+ import{formatCandidates as r}from"../../utils/api-name-matching.js";import{visibleOperations as l}from"./utils.js";function i(t,e){return l(t.paths?.[e]).map(([o])=>o.toUpperCase()).sort()}function h(t){return Object.keys(t.paths??{}).filter(e=>i(t,e).length>0).sort()}function c(t){return t==="code"?{endpoints:"tools.getEndpoints",search:"tools.search",listApis:"tools.listApis"}:{endpoints:"get-endpoints",search:"search",listApis:"list-apis"}}function f(t,e,o,n){const s=h(t);if(s.length===0)return"Endpoint not found";const{endpoints:p,search:a}=c(n);return`No path "${o}" in "${e}". Documented paths: ${r(s)}. Call ${p} for the full list, or ${a} with a keyword from the request.`}function m(t,e,o,n){const s=i(t,o);return s.length===0?"Endpoint not found":`"${o}" in "${e}" documents no ${n.toUpperCase()}. Available methods: ${r(s)}.`}export{m as describeMethodMiss,f as describePathMiss,c as recoveryToolNames,i as visibleMethodsAt,h as visiblePaths};
@@ -1 +1 @@
1
- import{resolveParameters as v,resolveRequestBody as E,resolveResponses as M}from"../../utils/resolve-refs.js";import{isMcpEndpoint as P}from"./utils.js";import{describeMethodMiss as g,describePathMiss as b,visibleMethodsAt as q}from"./endpoint-suggestions.js";import{loadApiDescription as B}from"./load-api-description.js";import{checkEndpointAndDeleteXMcp as S}from"../../../utils/xmcp-utils.js";const k=async(c,d)=>{const{path:r,method:o}=c;if(!r||!o)return{content:[{type:"text",text:'Both "path" and "method" are required (e.g. path: "/tickets", method: "GET").'}],isError:!0};let h;try{h=await B(c,d)}catch(p){return{content:[{type:"text",text:p.message}],isError:!0}}const{description:t,filePath:l,otherMatches:n}=h,m=n?` Other definitions share this title: ${n.map(p=>`"${p.filePath}"`).join(", ")}. Pass "filePath" to check them.`:"",s=r.startsWith("/")?r:`/${r}`,{title:i=""}=t.info||{},a=t.paths?.[s],f=o.toLowerCase();if(!a||q(t,s).length===0)return{content:[{type:"text",text:b(t,i,s,d.mcpMode)+m}],isError:!0};const e=a[f];if(!P(e)||!S(e,"docs"))return{content:[{type:"text",text:g(t,i,s,o)+m}],isError:!0};const u=a?.parameters||[],y=e.parameters||[],x={...e,parameters:v({pathParams:u,opParams:y,definition:t}),requestBody:E(e.requestBody,t),responses:M(e.responses,t)};return{content:[{type:"text",text:JSON.stringify({api:i,version:t.info?.version||"",filePath:l,otherMatches:n,servers:t.servers||[],endpoint:{path:r,method:o.toUpperCase(),...x},globalSecurity:t.security||[],securitySchemes:t.components?.securitySchemes||{}},null,2)}]}};var D={"get-endpoint-info":k};export{D as default};
1
+ import{inlineOperation as N,resolveOperation as O}from"../../utils/resolve-refs.js";import{matchDocumentedPath as b,visibleOperations as I}from"./utils.js";import{MAX_ENDPOINT_INFO_BYTES as x,MAX_INLINED_ENDPOINT_BYTES as T}from"./constants.js";import{describeMethodMiss as _,describePathMiss as S}from"./endpoint-suggestions.js";import{loadApiDescription as $}from"./load-api-description.js";const D=async(c,n)=>{const{path:h,method:e}=c;if(!h||!e)return{content:[{type:"text",text:'Both "path" and "method" are required (e.g. path: "/tickets", method: "GET").'}],isError:!0};let m;try{m=await $(c,n)}catch(r){return{content:[{type:"text",text:r.message}],isError:!0}}const{description:t,filePath:E,otherMatches:i}=m,d=i?` Other definitions share this title: ${i.map(r=>`"${r.filePath}"`).join(", ")}. Pass "filePath" to check them.`:"",o=b(t,h),{title:s=""}=t.info||{},a=t.paths?.[o],l=I(a);if(!a||l.length===0)return{content:[{type:"text",text:S(t,s,o,n.mcpMode)+d}],isError:!0};const f=l.find(([r])=>r.toLowerCase()===e.toLowerCase())?.[1];if(!f)return{content:[{type:"text",text:_(t,s,o,e)+d}],isError:!0};const{"x-mcp":C,...P}=f,v=a?.parameters||[],u={operation:P,pathParams:v,definition:t},M=n.mcpMode==="code"?N(u,T):void 0,{operation:g,components:y}=M??O(u),p=JSON.stringify({api:s,version:t.info?.version||"",filePath:E,otherMatches:i,servers:t.servers||[],endpoint:{path:o,method:e.toUpperCase(),...g},globalSecurity:t.security||[],securitySchemes:t.components?.securitySchemes||{},...y?{components:y}:{}},null,2);return p.length>x?{content:[{type:"text",text:`${e.toUpperCase()} ${o} is ${p.length} bytes, over the ${x} byte limit.`}],isError:!0}:{content:[{type:"text",text:p}]}};var U={"get-endpoint-info":D};export{U as default};
@@ -1 +1 @@
1
- import{loadApiDescription as o}from"./load-api-description.js";const a=async(r,s)=>{let t;try{t=await o(r,s)}catch(n){return{content:[{type:"text",text:n.message}],isError:!0}}const{description:e,filePath:i,otherMatches:c}=t;return{content:[{type:"text",text:JSON.stringify({name:e.info?.title,version:e.info?.version,filePath:i,otherMatches:c,securitySchemes:e.components?.securitySchemes||{},security:e.security||[]},null,2)}]}};var y={"get-security-schemes":a};export{y as default};
1
+ import{loadApiDescription as n}from"./load-api-description.js";const a=async(r,i)=>{let t;try{t=await n(r,i)}catch(o){return{content:[{type:"text",text:o.message}],isError:!0}}const{description:e,filePath:s,otherMatches:c}=t;return{content:[{type:"text",text:JSON.stringify({api:e.info?.title||"",version:e.info?.version||"",filePath:s,otherMatches:c,securitySchemes:e.components?.securitySchemes||{},security:e.security||[]},null,2)}]}};var y={"get-security-schemes":a};export{y as default};
@@ -13,6 +13,8 @@ type ApiLookup = {
13
13
  name?: string;
14
14
  version?: string;
15
15
  filePath?: string;
16
+ path?: string;
17
+ method?: string;
16
18
  };
17
19
  export declare function loadApiDescription(args: ApiLookup & {
18
20
  apiName?: string;