@redocly/realm 0.135.0 → 0.136.0-next.1
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.
- package/CHANGELOG.md +35 -0
- package/dist/cli/build/analytics/collect-analytics.js +1 -1
- package/dist/cli/build/analytics/collectors/get-skills-usage.d.ts +3 -0
- package/dist/cli/build/analytics/collectors/get-skills-usage.js +1 -0
- package/dist/client/templates/openapi-docs/helpers.js +1 -1
- package/dist/constants/common.d.ts +8 -0
- package/dist/constants/common.js +1 -1
- package/dist/server/api-routes/execute-api-route.js +1 -1
- package/dist/server/api-routes/helpers/enhance-context.d.ts +3 -1
- package/dist/server/api-routes/helpers/enhance-context.js +1 -1
- package/dist/server/api-routes/helpers/is-mock-server.d.ts +2 -0
- package/dist/server/api-routes/helpers/is-mock-server.js +1 -0
- package/dist/server/api-routes/mock-server/kv-state-store.d.ts +3 -0
- package/dist/server/api-routes/mock-server/kv-state-store.js +1 -0
- package/dist/server/api-routes/mock-server/mock-js-executor.d.ts +3 -0
- package/dist/server/api-routes/mock-server/mock-js-executor.js +13 -0
- package/dist/server/config/env-config.d.ts +4 -0
- package/dist/server/config/env-schema.d.ts +10 -0
- package/dist/server/config/env-schemas/catalog.d.ts +3 -0
- package/dist/server/config/env-schemas/catalog.js +1 -1
- package/dist/server/config/env-schemas/feature-flags.d.ts +4 -0
- package/dist/server/config/env-schemas/feature-flags.js +1 -1
- package/dist/server/constants/plugins/search.d.ts +1 -2
- package/dist/server/constants/plugins/search.js +1 -1
- package/dist/server/esbuild/plugins/on-rebuild.js +1 -1
- package/dist/server/fs/fs.js +1 -1
- package/dist/server/plugins/catalog-entities/database/catalog-entities-diff-publisher.d.ts +27 -0
- package/dist/server/plugins/catalog-entities/database/catalog-entities-diff-publisher.js +12 -0
- package/dist/server/plugins/catalog-entities/database/catalog-entities-publisher.js +1 -12
- package/dist/server/plugins/catalog-entities/database/catalog-entities-revisions-pruner.d.ts +20 -0
- package/dist/server/plugins/catalog-entities/database/catalog-entities-revisions-pruner.js +42 -0
- package/dist/server/plugins/catalog-entities/database/consts.d.ts +5 -0
- package/dist/server/plugins/catalog-entities/database/consts.js +1 -1
- package/dist/server/plugins/catalog-entities/database/repositories/entities/entities-write-repository.js +1 -1
- package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/arazzo-entities-extractor.js +1 -1
- package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/asyncapi-entities-extractor.js +1 -1
- package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/graphql-entities-extractor.js +2 -2
- package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/openapi-entities-extractor.js +1 -1
- package/dist/server/plugins/catalog-entities/plugin.js +1 -1
- package/dist/server/plugins/config-parser/loaders/redocly-config-loader.js +1 -1
- package/dist/server/plugins/lifecycle.js +2 -2
- package/dist/server/plugins/mcp/{docs-mcp/codemode → codemode}/build-tool-type-declarations.d.ts +1 -1
- package/dist/server/plugins/mcp/codemode/capabilities/fetch/index.d.ts +4 -0
- package/dist/server/plugins/mcp/codemode/capabilities/fetch/index.js +4 -0
- package/dist/server/plugins/mcp/codemode/capabilities/index.d.ts +3 -0
- package/dist/server/plugins/mcp/codemode/capabilities/index.js +1 -0
- package/dist/server/plugins/mcp/codemode/capabilities/registry.d.ts +4 -0
- package/dist/server/plugins/mcp/codemode/capabilities/registry.js +1 -0
- package/dist/server/plugins/mcp/codemode/capabilities/types.d.ts +13 -0
- package/dist/server/plugins/mcp/codemode/capabilities/utils.d.ts +13 -0
- package/dist/server/plugins/mcp/codemode/capabilities/utils.js +7 -0
- package/dist/server/plugins/mcp/codemode/constants.d.ts +8 -0
- package/dist/server/plugins/mcp/codemode/constants.js +1 -0
- package/dist/server/plugins/mcp/codemode/invoke-tool.d.ts +4 -0
- package/dist/server/plugins/mcp/codemode/invoke-tool.js +1 -0
- package/dist/server/plugins/mcp/codemode/prompts.d.ts +6 -0
- package/dist/server/plugins/mcp/codemode/prompts.js +4 -0
- package/dist/server/plugins/mcp/codemode/sandbox/create-sandbox-setup.d.ts +10 -0
- package/dist/server/plugins/mcp/codemode/sandbox/create-sandbox-setup.js +11 -0
- package/dist/server/plugins/mcp/codemode/sandbox/polyfills.d.ts +2 -0
- package/dist/server/plugins/mcp/codemode/sandbox/polyfills.js +99 -0
- package/dist/server/plugins/mcp/codemode/tools/describe-tools.d.ts +7 -0
- package/dist/server/plugins/mcp/codemode/tools/describe-tools.js +1 -0
- package/dist/server/plugins/mcp/codemode/tools/execute-schema.d.ts +5 -0
- package/dist/server/plugins/mcp/codemode/tools/execute-schema.js +1 -0
- package/dist/server/plugins/mcp/codemode/tools/execute.js +1 -0
- package/dist/server/plugins/mcp/codemode/types.d.ts +16 -0
- package/dist/server/plugins/mcp/codemode/types.js +0 -0
- package/dist/server/plugins/mcp/constants.d.ts +2 -0
- package/dist/server/plugins/mcp/constants.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/tool-schemas.d.ts +0 -4
- package/dist/server/plugins/mcp/docs-mcp/tool-schemas.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/tools/openapi/list-apis.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/utils.js +1 -1
- package/dist/server/plugins/mcp/gateway-mcp/eligibility.d.ts +30 -0
- package/dist/server/plugins/mcp/gateway-mcp/eligibility.js +1 -0
- package/dist/server/plugins/mcp/gateway-mcp/fetch/allowed-hosts.d.ts +13 -0
- package/dist/server/plugins/mcp/gateway-mcp/fetch/allowed-hosts.js +1 -0
- package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-bridge.d.ts +12 -0
- package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-bridge.js +1 -0
- package/dist/server/plugins/mcp/gateway-mcp/fetch/ssrf-guard.d.ts +9 -0
- package/dist/server/plugins/mcp/gateway-mcp/fetch/ssrf-guard.js +1 -0
- package/dist/server/plugins/mcp/gateway-mcp/fetch-capability.d.ts +6 -0
- package/dist/server/plugins/mcp/gateway-mcp/fetch-capability.js +1 -0
- package/dist/server/plugins/mcp/handlers/docs-mcp-handler.js +1 -1
- package/dist/server/plugins/mcp/handlers/errors.d.ts +3 -21
- package/dist/server/plugins/mcp/handlers/errors.js +1 -1
- package/dist/server/plugins/mcp/handlers/handle-mcp-request.js +1 -1
- package/dist/server/plugins/mcp/index.js +1 -1
- package/dist/server/plugins/mcp/servers/docs-server.d.ts +5 -10
- package/dist/server/plugins/mcp/servers/docs-server.js +1 -3
- package/dist/server/plugins/mcp/servers/mcp-server.d.ts +18 -0
- package/dist/server/plugins/mcp/servers/mcp-server.js +1 -0
- package/dist/server/plugins/mcp/types.d.ts +23 -8
- package/dist/server/plugins/mcp/utils/mode.d.ts +7 -0
- package/dist/server/plugins/mcp/utils/mode.js +1 -0
- package/dist/server/plugins/mcp/utils/xmcp-utils.d.ts +12 -60
- package/dist/server/plugins/mcp/utils/xmcp-utils.js +1 -1
- package/dist/server/plugins/mcp/utils.d.ts +8 -0
- package/dist/server/plugins/mcp/utils.js +1 -1
- package/dist/server/plugins/mcp/workers/execute-mcp-tool.js +1 -1
- package/dist/server/plugins/mcp/workers/mcp-tool-telemetry.d.ts +15 -3
- package/dist/server/plugins/mcp/workers/mcp-tool-telemetry.js +1 -1
- package/dist/server/plugins/openapi-docs/index.js +1 -1
- package/dist/server/plugins/search/engines/search-engine.d.ts +2 -1
- package/dist/server/plugins/search/index.js +1 -1
- package/dist/server/plugins/skills/discover-skills.d.ts +17 -0
- package/dist/server/plugins/skills/discover-skills.js +1 -0
- package/dist/server/plugins/skills/index.d.ts +3 -0
- package/dist/server/plugins/skills/index.js +1 -0
- package/dist/server/plugins/skills/utils/parse-skill.d.ts +18 -0
- package/dist/server/plugins/skills/utils/parse-skill.js +1 -0
- package/dist/server/plugins/sso/index.js +1 -1
- package/dist/server/sandbox/constants/host-functions.d.ts +3 -0
- package/dist/server/sandbox/constants/host-functions.js +1 -0
- package/dist/server/sandbox/constants/sandbox.d.ts +6 -0
- package/dist/server/sandbox/constants/sandbox.js +1 -0
- package/dist/server/sandbox/sandbox.d.ts +8 -0
- package/dist/server/sandbox/sandbox.js +3 -0
- package/dist/server/sandbox/types.d.ts +24 -0
- package/dist/server/sandbox/types.js +0 -0
- package/dist/server/sandbox/utils/eval-guest-code.d.ts +15 -0
- package/dist/server/sandbox/utils/eval-guest-code.js +1 -0
- package/dist/server/sandbox/utils/execution-budget.d.ts +11 -0
- package/dist/server/sandbox/utils/execution-budget.js +1 -0
- package/dist/server/sandbox/utils/setup-host-functions.d.ts +18 -0
- package/dist/server/sandbox/utils/setup-host-functions.js +5 -0
- package/dist/server/store.d.ts +4 -0
- package/dist/server/store.js +1 -1
- package/dist/server/types/plugins/common.d.ts +3 -0
- package/dist/server/types/plugins/search.d.ts +0 -1
- package/dist/server/types/plugins/skills.d.ts +16 -0
- package/dist/server/types/plugins/skills.js +0 -0
- package/dist/server/utils/cookie.d.ts +3 -0
- package/dist/server/utils/cookie.js +1 -1
- package/dist/server/utils/fetch-with-client.d.ts +10 -0
- package/dist/server/utils/fetch-with-client.js +1 -0
- package/dist/server/utils/skills/can-access-skill.d.ts +9 -0
- package/dist/server/utils/skills/can-access-skill.js +1 -0
- package/dist/server/utils/skills/get-accessible-skills.d.ts +5 -0
- package/dist/server/utils/skills/get-accessible-skills.js +1 -0
- package/dist/server/utils/skills/get-skill-url.d.ts +2 -0
- package/dist/server/utils/skills/get-skill-url.js +1 -0
- package/dist/server/web-server/auth.js +4 -4
- package/dist/server/web-server/middleware/apiKeyMiddleware.js +1 -1
- package/dist/server/web-server/middleware/catalogAuthMiddleware.js +1 -1
- package/dist/server/web-server/middleware/corsMiddleware.d.ts +1 -0
- package/dist/server/web-server/middleware/corsMiddleware.js +1 -1
- package/dist/server/web-server/middleware/ensureSearchData.js +1 -1
- package/dist/server/web-server/routes/ask-ai.js +1 -1
- package/dist/server/web-server/routes/auth.js +1 -1
- package/dist/server/web-server/routes/catalog/helpers/create-entity-schema.d.ts +305 -256
- package/dist/server/web-server/routes/catalog/helpers/create-entity-update-schema.d.ts +46 -39
- package/dist/server/web-server/routes/catalog/helpers/upsert-pages-stats.js +1 -1
- package/dist/server/web-server/routes/feedback.js +1 -1
- package/dist/server/web-server/routes/health.js +1 -1
- package/dist/server/web-server/routes/index.js +1 -1
- package/dist/server/web-server/routes/mcp-routes/a2a.d.ts +10 -0
- package/dist/server/web-server/routes/mcp-routes/a2a.js +1 -0
- package/dist/server/web-server/routes/mcp-routes/agent-card.d.ts +4 -0
- package/dist/server/web-server/routes/mcp-routes/agent-card.js +1 -0
- package/dist/server/web-server/routes/mcp-routes/constants.d.ts +14 -0
- package/dist/server/web-server/routes/mcp-routes/constants.js +1 -0
- package/dist/server/web-server/routes/mcp-routes/mcp-routes.d.ts +1 -1
- package/dist/server/web-server/routes/mcp-routes/mcp-routes.js +1 -1
- package/dist/server/web-server/routes/mcp-routes/mcp-server-card.d.ts +4 -0
- package/dist/server/web-server/routes/mcp-routes/mcp-server-card.js +1 -0
- package/dist/server/web-server/routes/mcp-routes/types.d.ts +34 -0
- package/dist/server/web-server/routes/mcp-routes/types.js +0 -0
- package/dist/server/web-server/routes/mcp-routes/utils/build-agent-card.d.ts +10 -0
- package/dist/server/web-server/routes/mcp-routes/utils/build-agent-card.js +1 -0
- package/dist/server/web-server/routes/page-data.js +1 -1
- package/dist/server/web-server/routes/semantic-search.js +1 -1
- package/dist/server/web-server/routes/skills/build-skills-index.d.ts +4 -0
- package/dist/server/web-server/routes/skills/build-skills-index.js +1 -0
- package/dist/server/web-server/routes/skills/constants.d.ts +4 -0
- package/dist/server/web-server/routes/skills/constants.js +1 -0
- package/dist/server/web-server/routes/skills/skill-markdown.d.ts +4 -0
- package/dist/server/web-server/routes/skills/skill-markdown.js +1 -0
- package/dist/server/web-server/routes/skills/skills-index.d.ts +4 -0
- package/dist/server/web-server/routes/skills/skills-index.js +1 -0
- package/dist/server/web-server/routes/skills/skills-routes.d.ts +4 -0
- package/dist/server/web-server/routes/skills/skills-routes.js +1 -0
- package/dist/server/web-server/routes/skills/types.d.ts +12 -0
- package/dist/server/web-server/routes/skills/types.js +0 -0
- package/dist/server/web-server/utils/resolve-public-base-url.d.ts +4 -0
- package/dist/server/web-server/utils/resolve-public-base-url.js +1 -0
- package/dist/server/web-server/utils.js +1 -1
- package/dist/server/workers/api-routes-worker-pool.js +1 -1
- package/dist/server/workers/mcp-tool-worker-pool.js +1 -1
- package/dist/server/workers/scorecards-worker-pool.js +1 -1
- package/dist/server/workers/worker-pool.d.ts +1 -0
- package/dist/server/workers/worker-pool.js +1 -1
- package/package.json +10 -10
- package/dist/server/plugins/mcp/docs-mcp/codemode/prompts.d.ts +0 -5
- package/dist/server/plugins/mcp/docs-mcp/codemode/prompts.js +0 -4
- package/dist/server/plugins/mcp/docs-mcp/codemode/sandbox.d.ts +0 -3
- package/dist/server/plugins/mcp/docs-mcp/codemode/sandbox.js +0 -7
- package/dist/server/plugins/mcp/docs-mcp/codemode/types.d.ts +0 -9
- package/dist/server/plugins/mcp/docs-mcp/tools/execute.js +0 -1
- package/dist/server/plugins/mcp/mode.d.ts +0 -9
- package/dist/server/plugins/mcp/mode.js +0 -1
- /package/dist/server/plugins/mcp/{docs-mcp/codemode → codemode}/build-tool-type-declarations.js +0 -0
- /package/dist/server/plugins/mcp/{docs-mcp/codemode → codemode/capabilities}/types.js +0 -0
- /package/dist/server/plugins/mcp/{docs-mcp → codemode}/tools/execute.d.ts +0 -0
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const SANDBOX_FETCH_SETUP = "\n const URLSearchParams = class URLSearchParams {\n constructor(init) {\n this._params = [];\n if (typeof init === 'string') {\n const str = init.startsWith('?') ? init.slice(1) : init;\n for (const pair of (str ? str.split('&') : [])) {\n const eq = pair.indexOf('=');\n const k = eq >= 0 ? pair.slice(0, eq) : pair;\n const v = eq >= 0 ? pair.slice(eq + 1) : '';\n if (k) this._params.push([decodeURIComponent(k), decodeURIComponent(v)]);\n }\n } else if (init != null && typeof init === 'object') {\n for (const [k, v] of Object.entries(init)) this._params.push([k, String(v)]);\n }\n }\n append(key, value) { this._params.push([String(key), String(value)]); }\n set(key, value) {\n const k = String(key), v = String(value);\n this._params = this._params.filter(([pk]) => pk !== k);\n this._params.push([k, v]);\n }\n get(key) { return (this._params.find(([k]) => k === String(key)) ?? [undefined, null])[1]; }\n getAll(key) { return this._params.filter(([k]) => k === String(key)).map(([, v]) => v); }\n has(key) { return this._params.some(([k]) => k === String(key)); }\n delete(key) { this._params = this._params.filter(([k]) => k !== String(key)); }\n entries() { return this._params.values(); }\n [Symbol.iterator]() { return this._params.values(); }\n toString() {\n return this._params\n .map(([k, v]) => encodeURIComponent(k) + '=' + encodeURIComponent(v))\n .join('&');\n }\n };\n globalThis.URLSearchParams = URLSearchParams;\n\n const FormData = class FormData {\n constructor() { this._fields = []; }\n append(key, value) { this._fields.push([String(key), String(value)]); }\n set(key, value) {\n const k = String(key), v = String(value);\n this._fields = this._fields.filter(([fk]) => fk !== k);\n this._fields.push([k, v]);\n }\n get(key) { return (this._fields.find(([k]) => k === String(key)) ?? [undefined, null])[1]; }\n has(key) { return this._fields.some(([k]) => k === String(key)); }\n delete(key) { this._fields = this._fields.filter(([k]) => k !== String(key)); }\n entries() { return this._fields.values(); }\n [Symbol.iterator]() { return this._fields.values(); }\n };\n globalThis.FormData = FormData;\n\n const hostFetch = globalThis.__fetchBridge.fetch;\n delete globalThis.__fetchBridge;\n globalThis.fetch = (url, init = {}) => {\n let body;\n let autoContentType;\n if (init.body instanceof URLSearchParams) {\n body = init.body.toString();\n autoContentType = 'application/x-www-form-urlencoded';\n } else if (init.body instanceof FormData) {\n const boundary = '----FormBoundary' + Math.random().toString(36).slice(2);\n body = init.body._fields\n .map(([k, v]) =>\n '--' + boundary + '\\r\\nContent-Disposition: form-data; name=\"' + k + '\"\\r\\n\\r\\n' + v,\n )\n .join('\\r\\n') + '\\r\\n--' + boundary + '--';\n autoContentType = 'multipart/form-data; boundary=' + boundary;\n } else if (init.body != null && typeof init.body !== 'string') {\n throw new TypeError('fetch body must be a string, URLSearchParams, or FormData');\n } else {\n body = init.body ?? undefined;\n }\n const callerHeaders = init.headers;\n const hasContentType = callerHeaders != null && Object.keys(callerHeaders).some(\n (k) => k.toLowerCase() === 'content-type',\n );\n const headers = autoContentType && !hasContentType\n ? Object.assign({ 'content-type': autoContentType }, callerHeaders)\n : callerHeaders;\n return hostFetch({ url: String(url), method: init.method, headers, body })\n .then((res) => {\n const resHeaders = res.headers || {};\n return {\n status: res.status,\n statusText: res.statusText,\n ok: res.ok,\n headers: {\n get: (name) => {\n const value = resHeaders[String(name).toLowerCase()];\n return value === undefined ? null : value;\n },\n },\n json: () => Promise.resolve(JSON.parse(res.bodyText)),\n text: () => Promise.resolve(res.bodyText),\n };\n });\n };\n";
|
|
2
|
+
//# sourceMappingURL=polyfills.d.ts.map
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import{FETCH_BRIDGE_FUNCTION_NAME as t,FETCH_BRIDGE_GLOBAL_NAME as e}from"../constants.js";const s=`
|
|
2
|
+
const URLSearchParams = class URLSearchParams {
|
|
3
|
+
constructor(init) {
|
|
4
|
+
this._params = [];
|
|
5
|
+
if (typeof init === 'string') {
|
|
6
|
+
const str = init.startsWith('?') ? init.slice(1) : init;
|
|
7
|
+
for (const pair of (str ? str.split('&') : [])) {
|
|
8
|
+
const eq = pair.indexOf('=');
|
|
9
|
+
const k = eq >= 0 ? pair.slice(0, eq) : pair;
|
|
10
|
+
const v = eq >= 0 ? pair.slice(eq + 1) : '';
|
|
11
|
+
if (k) this._params.push([decodeURIComponent(k), decodeURIComponent(v)]);
|
|
12
|
+
}
|
|
13
|
+
} else if (init != null && typeof init === 'object') {
|
|
14
|
+
for (const [k, v] of Object.entries(init)) this._params.push([k, String(v)]);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
append(key, value) { this._params.push([String(key), String(value)]); }
|
|
18
|
+
set(key, value) {
|
|
19
|
+
const k = String(key), v = String(value);
|
|
20
|
+
this._params = this._params.filter(([pk]) => pk !== k);
|
|
21
|
+
this._params.push([k, v]);
|
|
22
|
+
}
|
|
23
|
+
get(key) { return (this._params.find(([k]) => k === String(key)) ?? [undefined, null])[1]; }
|
|
24
|
+
getAll(key) { return this._params.filter(([k]) => k === String(key)).map(([, v]) => v); }
|
|
25
|
+
has(key) { return this._params.some(([k]) => k === String(key)); }
|
|
26
|
+
delete(key) { this._params = this._params.filter(([k]) => k !== String(key)); }
|
|
27
|
+
entries() { return this._params.values(); }
|
|
28
|
+
[Symbol.iterator]() { return this._params.values(); }
|
|
29
|
+
toString() {
|
|
30
|
+
return this._params
|
|
31
|
+
.map(([k, v]) => encodeURIComponent(k) + '=' + encodeURIComponent(v))
|
|
32
|
+
.join('&');
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
globalThis.URLSearchParams = URLSearchParams;
|
|
36
|
+
|
|
37
|
+
const FormData = class FormData {
|
|
38
|
+
constructor() { this._fields = []; }
|
|
39
|
+
append(key, value) { this._fields.push([String(key), String(value)]); }
|
|
40
|
+
set(key, value) {
|
|
41
|
+
const k = String(key), v = String(value);
|
|
42
|
+
this._fields = this._fields.filter(([fk]) => fk !== k);
|
|
43
|
+
this._fields.push([k, v]);
|
|
44
|
+
}
|
|
45
|
+
get(key) { return (this._fields.find(([k]) => k === String(key)) ?? [undefined, null])[1]; }
|
|
46
|
+
has(key) { return this._fields.some(([k]) => k === String(key)); }
|
|
47
|
+
delete(key) { this._fields = this._fields.filter(([k]) => k !== String(key)); }
|
|
48
|
+
entries() { return this._fields.values(); }
|
|
49
|
+
[Symbol.iterator]() { return this._fields.values(); }
|
|
50
|
+
};
|
|
51
|
+
globalThis.FormData = FormData;
|
|
52
|
+
`,r=`
|
|
53
|
+
const hostFetch = globalThis.${e}.${t};
|
|
54
|
+
delete globalThis.${e};
|
|
55
|
+
globalThis.fetch = (url, init = {}) => {
|
|
56
|
+
let body;
|
|
57
|
+
let autoContentType;
|
|
58
|
+
if (init.body instanceof URLSearchParams) {
|
|
59
|
+
body = init.body.toString();
|
|
60
|
+
autoContentType = 'application/x-www-form-urlencoded';
|
|
61
|
+
} else if (init.body instanceof FormData) {
|
|
62
|
+
const boundary = '----FormBoundary' + Math.random().toString(36).slice(2);
|
|
63
|
+
body = init.body._fields
|
|
64
|
+
.map(([k, v]) =>
|
|
65
|
+
'--' + boundary + '\\r\\nContent-Disposition: form-data; name="' + k + '"\\r\\n\\r\\n' + v,
|
|
66
|
+
)
|
|
67
|
+
.join('\\r\\n') + '\\r\\n--' + boundary + '--';
|
|
68
|
+
autoContentType = 'multipart/form-data; boundary=' + boundary;
|
|
69
|
+
} else if (init.body != null && typeof init.body !== 'string') {
|
|
70
|
+
throw new TypeError('fetch body must be a string, URLSearchParams, or FormData');
|
|
71
|
+
} else {
|
|
72
|
+
body = init.body ?? undefined;
|
|
73
|
+
}
|
|
74
|
+
const callerHeaders = init.headers;
|
|
75
|
+
const hasContentType = callerHeaders != null && Object.keys(callerHeaders).some(
|
|
76
|
+
(k) => k.toLowerCase() === 'content-type',
|
|
77
|
+
);
|
|
78
|
+
const headers = autoContentType && !hasContentType
|
|
79
|
+
? Object.assign({ 'content-type': autoContentType }, callerHeaders)
|
|
80
|
+
: callerHeaders;
|
|
81
|
+
return hostFetch({ url: String(url), method: init.method, headers, body })
|
|
82
|
+
.then((res) => {
|
|
83
|
+
const resHeaders = res.headers || {};
|
|
84
|
+
return {
|
|
85
|
+
status: res.status,
|
|
86
|
+
statusText: res.statusText,
|
|
87
|
+
ok: res.ok,
|
|
88
|
+
headers: {
|
|
89
|
+
get: (name) => {
|
|
90
|
+
const value = resHeaders[String(name).toLowerCase()];
|
|
91
|
+
return value === undefined ? null : value;
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
json: () => Promise.resolve(JSON.parse(res.bodyText)),
|
|
95
|
+
text: () => Promise.resolve(res.bodyText),
|
|
96
|
+
};
|
|
97
|
+
});
|
|
98
|
+
};
|
|
99
|
+
`,i=`${s}${r}`;export{i as SANDBOX_FETCH_SETUP};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ToolCallback } from '@redocly/mcp-typescript-sdk/server/mcp.js';
|
|
2
|
+
import type { McpToolSchema } from '../../../../types';
|
|
3
|
+
import type { McpToolContext } from '../../types.js';
|
|
4
|
+
import { type SandboxCapability } from '../capabilities/index.js';
|
|
5
|
+
export declare function describeToolsSchema(tools: McpToolSchema[], capabilities: SandboxCapability[]): Record<string, unknown>;
|
|
6
|
+
export declare function describeTools(tools: McpToolSchema[], isToolAvailable: (toolName: string) => Promise<boolean>, capabilities: SandboxCapability[], context: McpToolContext): ToolCallback<Record<string, unknown>>;
|
|
7
|
+
//# sourceMappingURL=describe-tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{renderDescribeToolsOutput as w}from"../capabilities/index.js";import{sanitizeToolName as o}from"../build-tool-type-declarations.js";function g(i,l){const n=[...new Set([...i.map(s=>o(s.name)),...l.map(s=>o(s.id))])];return{type:"object",required:[],additionalProperties:!1,properties:{tools:{type:"array",description:`Tool names to describe: ${n.join(", ")}. Omit to describe everything.`,items:{type:"string"},nullable:!0}}}}function v(i,l,n,s){const r=new Map(i.map(t=>[o(t.name),t])),c=new Map(n.map(t=>[o(t.id),t]));return async t=>{const a=[...new Set((t.tools??[]).map(o))],p=a.length===0,m=a.filter(e=>!r.has(e)&&!c.has(e));if(m.length>0){const e=[...r.keys(),...c.keys()];throw new Error(`Unknown tool(s): ${m.join(", ")}. Valid tools: ${e.join(", ")}.`)}const u=p?n:n.filter(e=>a.includes(o(e.id))),d=p?i:a.filter(e=>r.has(e)).map(e=>r.get(e)),y=await Promise.all(d.map(e=>l(e.name))),f=d.filter((e,b)=>y[b]);return{content:[{type:"text",text:w(f,u,s)}]}}}export{v as describeTools,g as describeToolsSchema};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ToolAnnotations } from '@redocly/mcp-typescript-sdk/types.js';
|
|
2
|
+
import type { McpToolSchema } from '../../../../types';
|
|
3
|
+
export declare const EXECUTE_BASE_ANNOTATIONS: ToolAnnotations;
|
|
4
|
+
export declare const EXECUTE_TOOL_SCHEMA: McpToolSchema;
|
|
5
|
+
//# sourceMappingURL=execute-schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{EXECUTE_TOOL_NAME as e}from"../constants.js";import{buildExecuteDescription as t}from"../prompts.js";const i={title:"Execute code",readOnlyHint:!0,openWorldHint:!1},n={name:e,description:t(!1),annotations:i,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}}}};export{i as EXECUTE_BASE_ANNOTATIONS,n as EXECUTE_TOOL_SCHEMA};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{mcpToolHandlers as s}from"../../../../../client/mcp-tool-handlers-entry.js";import{runInSandbox as c}from"../../../../sandbox/sandbox.js";import{isMcpToolAvailable as l}from"../../workers/execute-mcp-tool.js";import{buildExecuteHostFetch as m,isFetchCapable as f}from"../../gateway-mcp/fetch-capability.js";import{CODE_MODE_TOOL_NAMES as u,EXECUTE_TOOL_NAME as p}from"../constants.js";import{sanitizeToolName as d}from"../build-tool-type-declarations.js";import{invokeTool as b}from"../invoke-tool.js";import{createSandboxSetup as T}from"../sandbox/create-sandbox-setup.js";const E=async(e,t,i)=>{const o=await O(t,i),n=f(t)?m(t):void 0,{result:r,error:a}=await c(e.code,{setupContext:T(o,n)});return{content:[{type:"text",text:JSON.stringify({result:r,error:a})}],isError:a!==void 0}};async function O(e,t){const i={};for(const o of Object.keys(s))u.has(o)||!await l({toolName:o,context:e}).catch(()=>!1)||(i[d(o)]=r=>b(o,r,e,t));return i}var C={[p]:E};export{C as default};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type SandboxTool = (input: unknown) => Promise<unknown> | unknown;
|
|
2
|
+
export type SandboxFetchRequest = {
|
|
3
|
+
url: string;
|
|
4
|
+
method?: string;
|
|
5
|
+
headers?: Record<string, string>;
|
|
6
|
+
body?: string;
|
|
7
|
+
};
|
|
8
|
+
export type SandboxFetchResponse = {
|
|
9
|
+
status: number;
|
|
10
|
+
statusText: string;
|
|
11
|
+
ok: boolean;
|
|
12
|
+
headers: Record<string, string>;
|
|
13
|
+
bodyText: string;
|
|
14
|
+
};
|
|
15
|
+
export type SandboxFetch = (request: SandboxFetchRequest) => Promise<SandboxFetchResponse>;
|
|
16
|
+
//# sourceMappingURL=types.d.ts.map
|
|
File without changes
|
|
@@ -8,8 +8,10 @@ export declare const McpErrorCodes: {
|
|
|
8
8
|
readonly MethodNotFound: -32601;
|
|
9
9
|
readonly InvalidParams: -32602;
|
|
10
10
|
};
|
|
11
|
+
export declare const MCP_PROTOCOL_VERSION = "2025-06-18";
|
|
11
12
|
export declare const DEFAULT_CONNECTION_TIMEOUT_MS = 30000;
|
|
12
13
|
export declare const SSE_KEEPALIVE_INTERVAL_MS = 15000;
|
|
13
14
|
export declare const MAX_DOCUMENTS_PER_CATEGORY = 3;
|
|
14
15
|
export declare const MCP_NOT_ALLOWED_TEMPLATE_ID = "mcp-not-allowed";
|
|
16
|
+
export declare const DEFAULT_DOCS_MCP_SERVER_NAME = "Docs MCP server";
|
|
15
17
|
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const o={Docs:"docs"},r={InternalError:-32603,ServerError:-32e3,InvalidRequest:-32600,MethodNotFound:-32601,InvalidParams:-32602},e=3e4,t=15e3,
|
|
1
|
+
const o={Docs:"docs"},r={InternalError:-32603,ServerError:-32e3,InvalidRequest:-32600,MethodNotFound:-32601,InvalidParams:-32602},E="2025-06-18",e=3e4,t=15e3,_=3,s="mcp-not-allowed",c="Docs MCP server";export{e as DEFAULT_CONNECTION_TIMEOUT_MS,c as DEFAULT_DOCS_MCP_SERVER_NAME,_ as MAX_DOCUMENTS_PER_CATEGORY,s as MCP_NOT_ALLOWED_TEMPLATE_ID,E as MCP_PROTOCOL_VERSION,r as McpErrorCodes,o as McpServerType,t as SSE_KEEPALIVE_INTERVAL_MS};
|
|
@@ -1,8 +1,4 @@
|
|
|
1
1
|
import type { McpToolSchema } from '../../../types';
|
|
2
|
-
export declare const EXECUTE_TOOL_NAME = "execute";
|
|
3
|
-
export declare const EXECUTE_TOOL_SCHEMA: McpToolSchema;
|
|
4
|
-
export declare const DESCRIBE_TOOLS_TOOL_NAME = "describe-tools";
|
|
5
|
-
export declare const CODE_MODE_TOOL_NAMES: ReadonlySet<string>;
|
|
6
2
|
export declare function getDefaultToolSchemas(config: {
|
|
7
3
|
products?: string[];
|
|
8
4
|
locales?: string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{shouldHandleMcpAuth as d}from"../auth/auth-handlers.js";import{EXECUTE_DESCRIPTION as h}from"./codemode/prompts.js";import{GRAPHQL_TYPE_KINDS as o}from"./tools/graphql/types.js";const p=["GET","POST","PUT","DELETE","PATCH","OPTIONS","HEAD","TRACE"],t={type:"string",nullable:!0},n={limit:{type:"number"},total:{type:"number"},page:{type:"number"},totalPages:{type:"number"}},r={codemodeType:"OpenApiServer[]"},s={codemodeType:"OpenApiSecurityRequirement[]"},l={codemodeType:"Record<string, OpenApiSecurityScheme>"},y={codemodeType:"OpenApiDocument"},g={codemodeType:"OpenApiOperation & { path: string; method: string }"},c="execute",j={name:c,description:h,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 (shown to users in place of the raw call).",minLength:1}}}},f="describe-tools",I=new Set([c,f]),b={type:"object",additionalProperties:!1,required:[],properties:{filter:{type:"string",description:"API 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 APIs per page. Default is 300",minimum:1,default:300,nullable:!0}}},a={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"API name",minLength:1},version:{type:"string",description:"API version (required when multiple APIs share the same name but differ by version)",nullable:!0}}},S={type:"object",required:["name","path","method"],additionalProperties:!1,properties:{name:{type:"string",description:"API name",minLength:1},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:[...p,...p.map(e=>e.toLowerCase())],minLength:1},version:{type:"string",description:"API version (required when multiple APIs share the same name but differ by version)",nullable:!0}}},v={type:"object",required:[],additionalProperties:!1,properties:{}};function w(e){const i=[{name:"list-apis",description:"Lists available APIs with their context and purpose",schema:b,annotations:{title:"List APIs",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{items:{type:"array",items:{type:"object",properties:{name:{type:"string"},description:t,version:t,servers:r}}},...n}}},{name:"get-endpoints",description:"Get all endpoints for a specific API",schema:a,annotations:{title:"Get Endpoints",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{api:{type:"string"},version:{type:"string"},servers:r,endpoints:{type:"array",items:{type:"object",properties:{path:{type:"string"},method:{type:"string"},summary:t,description:t,security:s}}}}}},{name:"get-endpoint-info",description:"Get comprehensive information about specific endpoint including parameters, security, and examples",schema:S,annotations:{title:"Get Endpoint Info",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{api:{type:"string"},version:{type:"string"},servers:r,endpoint:g,globalSecurity:s,securitySchemes:l}}},{name:"get-security-schemes",description:"Get the security schemes for a specific API",schema:a,annotations:{title:"Get Security Schemes",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{name:t,version:t,securitySchemes:l,security:s}}},{name:"get-full-api-description",description:"Get the complete OpenAPI description",schema:a,annotations:{title:"Get Full API Description",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{api:{type:"string"},version:{type:"string"},definition:y}}},P(e.products,e.locales)];return d(e.requiresLogin,e.rbac)&&i.push({name:"whoami",description:"Get information about the currently authenticated user",schema:v,annotations:{title:"Who Am I",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.hasGraphqlApis&&i.push(...O()),i}const H={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}}},L={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",enum:[...o],nullable:!0},filter:{type:"string",description:'Optional: only members whose name contains this substring (e.g. "book")',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}}},T={type:"object",required:["name","type"],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},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}}},A={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"GraphQL schema name",minLength:1}}};function O(){return[{name:"list-graphql-apis",description:"Lists available GraphQL schemas with their context and purpose",schema:H,annotations:{title:"List GraphQL APIs",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{items:{type:"array",items:{type:"object",properties:{name:{type:"string"},description:t}}},...n}}},{name:"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` (member-name substring, 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.',schema:L,annotations:{title:"Get GraphQL Type List",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:o},name:{type:"string"},description:t,type:{type:"string"},args:{type:"string"}}}},...n}}},{name:"get-graphql-type",description:"Get the SDL for a single GraphQL type, operation (query/mutation/subscription field), or directive. Set includeReferencedTypes to also pull in every type it references transitively \u2014 the full 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:T,annotations:{title:"Get GraphQL Type",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"string"}},{name:"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:A,annotations:{title:"Get GraphQL Schema",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"string"}}]}function P(e,i){const u=e&&e.length>0,m=i&&i.length>0;return{name:"search",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},...u?{product:{type:"string",description:"Optional product name to filter search results by specific product.",enum:e,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:i,nullable:!0}}:{}}},annotations:{title:"Search Documentation",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!1,openWorldHint:!1},outputSchema:{type:"string"}}}export{I as CODE_MODE_TOOL_NAMES,f as DESCRIBE_TOOLS_TOOL_NAME,c as EXECUTE_TOOL_NAME,j as EXECUTE_TOOL_SCHEMA,w as getDefaultToolSchemas};
|
|
1
|
+
import{shouldHandleMcpAuth as m}from"../auth/auth-handlers.js";import{GRAPHQL_TYPE_KINDS as o}from"./tools/graphql/types.js";const p=["GET","POST","PUT","DELETE","PATCH","OPTIONS","HEAD","TRACE"],t={type:"string",nullable:!0},n={limit:{type:"number"},total:{type:"number"},page:{type:"number"},totalPages:{type:"number"}},r={codemodeType:"OpenApiServer[]"},s={codemodeType:"OpenApiSecurityRequirement[]"},l={codemodeType:"Record<string, OpenApiSecurityScheme>"},d={codemodeType:"OpenApiDocument"},h={codemodeType:"OpenApiOperation & { path: string; method: string }"},y={type:"object",additionalProperties:!1,required:[],properties:{filter:{type:"string",description:"API 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 APIs per page. Default is 300",minimum:1,default:300,nullable:!0}}},a={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"API name",minLength:1},version:{type:"string",description:"API version (required when multiple APIs share the same name but differ by version)",nullable:!0}}},g={type:"object",required:["name","path","method"],additionalProperties:!1,properties:{name:{type:"string",description:"API name",minLength:1},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:[...p,...p.map(e=>e.toLowerCase())],minLength:1},version:{type:"string",description:"API version (required when multiple APIs share the same name but differ by version)",nullable:!0}}},f={type:"object",required:[],additionalProperties:!1,properties:{}};function q(e){const i=[{name:"list-apis",description:"Lists available APIs with their context and purpose",schema:y,annotations:{title:"List APIs",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{items:{type:"array",items:{type:"object",properties:{name:{type:"string"},description:t,version:t,servers:r}}},...n}}},{name:"get-endpoints",description:"Get all endpoints for a specific API",schema:a,annotations:{title:"Get Endpoints",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{api:{type:"string"},version:{type:"string"},servers:r,endpoints:{type:"array",items:{type:"object",properties:{path:{type:"string"},method:{type:"string"},summary:t,description:t,security:s}}}}}},{name:"get-endpoint-info",description:"Get comprehensive information about specific endpoint including parameters, security, and examples",schema:g,annotations:{title:"Get Endpoint Info",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{api:{type:"string"},version:{type:"string"},servers:r,endpoint:h,globalSecurity:s,securitySchemes:l}}},{name:"get-security-schemes",description:"Get the security schemes for a specific API",schema:a,annotations:{title:"Get Security Schemes",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{name:t,version:t,securitySchemes:l,security:s}}},{name:"get-full-api-description",description:"Get the complete OpenAPI description",schema:a,annotations:{title:"Get Full API Description",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{api:{type:"string"},version:{type:"string"},definition:d}}},P(e.products,e.locales)];return m(e.requiresLogin,e.rbac)&&i.push({name:"whoami",description:"Get information about the currently authenticated user",schema:f,annotations:{title:"Who Am I",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.hasGraphqlApis&&i.push(...L()),i}const b={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}}},S={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",enum:[...o],nullable:!0},filter:{type:"string",description:'Optional: only members whose name contains this substring (e.g. "book")',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}}},H={type:"object",required:["name","type"],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},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}}},v={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"GraphQL schema name",minLength:1}}};function L(){return[{name:"list-graphql-apis",description:"Lists available GraphQL schemas with their context and purpose",schema:b,annotations:{title:"List GraphQL APIs",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{items:{type:"array",items:{type:"object",properties:{name:{type:"string"},description:t}}},...n}}},{name:"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` (member-name substring, 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.',schema:S,annotations:{title:"Get GraphQL Type List",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:o},name:{type:"string"},description:t,type:{type:"string"},args:{type:"string"}}}},...n}}},{name:"get-graphql-type",description:"Get the SDL for a single GraphQL type, operation (query/mutation/subscription field), or directive. Set includeReferencedTypes to also pull in every type it references transitively \u2014 the full 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:H,annotations:{title:"Get GraphQL Type",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"string"}},{name:"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:v,annotations:{title:"Get GraphQL Schema",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"string"}}]}function P(e,i){const c=e&&e.length>0,u=i&&i.length>0;return{name:"search",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},...c?{product:{type:"string",description:"Optional product name to filter search results by specific product.",enum:e,nullable:!0}}:{},...u?{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:i,nullable:!0}}:{}}},annotations:{title:"Search Documentation",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!1,openWorldHint:!1},outputSchema:{type:"string"}}}export{q as getDefaultToolSchemas};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{filterApiDescriptionsByName as f}from"../../utils.js";const
|
|
1
|
+
import{filterApiDescriptionsByName as f}from"../../utils.js";const g=async(l,a)=>{const{filter:i,page:n=1,limit:e=300}=l;let t=Object.values(a.apiDescriptionsMap);i&&(t=f(t,i));const s=(n-1)*e,o=s+e,c=Math.ceil(t.length/e),r=t.length;return t=t.slice(s,o),t.length===0?{content:[{type:"text",text:"No APIs available"}]}:{content:[{type:"text",text:JSON.stringify({items:t.map(({relativePath:h,fetchEligible:x,...p})=>p),limit:e,total:r,page:n,totalPages:c})}]}};var u={"list-apis":g};export{u as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
function
|
|
1
|
+
function v(t,o,n){if(!o)return;const s=o.toLowerCase(),r=Object.values(t).filter(({name:i})=>i.toLowerCase()===s);if(r.length===0)return;const e=n?r.filter(i=>i.version===n):r;if(e.length===0)return;if(e.length===1)return e[0];if(new Set(e.map(({version:i})=>i||"")).size>1){const i=e.map(({version:d})=>d||"(no version)").join(", ");throw new Error(`Multiple versions of "${o}" found: ${i}. Specify a version to disambiguate.`)}const c=e.map(({relativePath:i})=>i||"(unknown path)").join(", "),u=e[0].version?` at version "${e[0].version}"`:"";throw new Error(`Multiple APIs are titled "${o}"${u} (${c}). Give them a distinct info.title or info.version so they can be addressed individually.`)}function $(t,o){return Object.values(t).filter(({name:n})=>n.toLowerCase().includes(o.toLowerCase()))}function a(t,o){if(!o||!t?.startsWith("#/"))return;const n=t.slice(2).split("/");let s=o;for(const r of n)if(typeof s=="object"&&s!==null&&r in s)s=s[r];else return;return s}function l({schema:t,definition:o,visitedRefs:n=new Set,maxDepth:s=50,currentDepth:r=0}){if(!t)return;if(r>=s)return{type:"object",description:`Maximum resolution depth exceeded (${s})`};if("$ref"in t&&t.$ref){if(n.has(t.$ref))return{type:"object",description:`Circular reference detected: ${t.$ref}`,"x-circular-ref":t.$ref};const c=new Set(n);c.add(t.$ref);const u=a(t.$ref,o);return u?l({schema:u,definition:o,visitedRefs:c,maxDepth:s,currentDepth:r+1}):{type:"object",description:`Could not resolve reference: ${t.$ref}`,"x-unresolved-ref":t.$ref}}const e={...t};if(e.properties){const c={};for(const[u,i]of Object.entries(e.properties)){const d=l({schema:i,definition:o,visitedRefs:new Set(n),maxDepth:s,currentDepth:r+1});c[u]=d||i}e.properties=c}if(e.items&&typeof e.items=="object")if(Array.isArray(e.items))e.items=e.items.map(c=>l({schema:c,definition:o,visitedRefs:new Set(n),maxDepth:s,currentDepth:r+1})||c);else{const c=l({schema:e.items,definition:o,visitedRefs:new Set(n),maxDepth:s,currentDepth:r+1});c&&(e.items=c)}return["allOf","anyOf","oneOf"].forEach(c=>{const u=e[c];Array.isArray(u)&&(e[c]=u.reduce((i,d)=>{const p=l({schema:d,definition:o,visitedRefs:new Set(n),maxDepth:s,currentDepth:r+1});return p&&i.push(p),i},[]))}),e}function h({pathParams:t,opParams:o,definition:n}){return[...t,...o].reduce((s,r)=>{if(!r)return s;if("$ref"in r&&r.$ref){const e=a(r.$ref,n);return e&&s.push({...e,schema:"schema"in e&&e.schema?l({schema:e.schema,definition:n}):void 0}),s}return s.push({...r,schema:"schema"in r&&r.schema?l({schema:r.schema,definition:n}):void 0}),s},[])}function m(t,o){const n={...t};if(t.example!==void 0&&(n.example=t.example),!t.examples)return n;const s={};for(const[r,e]of Object.entries(t.examples))if("$ref"in e){const f=a(e.$ref,o);f&&(s[r]=f)}else s[r]=e;return n.examples=s,n}function w(t,o){if(!t)return;const n="$ref"in t&&t.$ref?a(t.$ref,o):t;if(!n)return;const s={...n};if("content"in n&&n.content){const r={};for(const[e,f]of Object.entries(n.content))r[e]={...m(f,o),schema:f.schema?l({schema:f.schema,definition:o}):void 0};s.content=r}return s}function b(t,o){return Object.entries(t).reduce((n,[s,r])=>{const e="$ref"in r&&r.$ref?a(r.$ref,o):r;if(!e)return n;const f={...e};if("content"in e&&e.content){const c={};for(const[u,i]of Object.entries(e.content))c[u]={...m(i,o),schema:i.schema?l({schema:i.schema,definition:o}):void 0};f.content=c}return n[s]=f,n},{})}export{$ as filterApiDescriptionsByName,v as findApiDescriptionByNameAndVersion,h as resolveParameters,a as resolveRef,w as resolveRequestBody,b as resolveResponses,l as resolveSchemaRefs};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { OpenAPIDefinition } from '@redocly/openapi-docs';
|
|
2
|
+
import type { OpenAPIMcp } from '@redocly/openapi-docs/lib/types/open-api.js';
|
|
3
|
+
import type { RbacConfig } from '@redocly/config';
|
|
4
|
+
type GatewayVisibility = {
|
|
5
|
+
hide?: boolean;
|
|
6
|
+
docs?: {
|
|
7
|
+
hide?: boolean;
|
|
8
|
+
ignore?: readonly string[];
|
|
9
|
+
};
|
|
10
|
+
gateway?: {
|
|
11
|
+
hide?: boolean;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
/** Whether the gateway fetch capability is on: the feature flag plus none of mcp/docs/gateway hidden. */
|
|
15
|
+
export declare function isGatewayCapabilityEnabled(mcp: GatewayVisibility | undefined): boolean;
|
|
16
|
+
/** Whether an API is eligible for the gateway (fetch-capable `execute` + `/mcp` advertisement). */
|
|
17
|
+
export declare function isGatewayEligible(info: OpenAPIDefinition['info'] | undefined, relativePath: string, rbacConfig: RbacConfig): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Whether an API docs page advertises the `/mcp` endpoint via an injected root-level x-mcp:
|
|
20
|
+
* the capability is on, the author has not provided their own x-mcp servers, and the API is
|
|
21
|
+
* both gateway-eligible and part of the Docs MCP catalog.
|
|
22
|
+
*/
|
|
23
|
+
export declare function shouldAdvertiseGatewayXMcp(definition: (OpenAPIDefinition & {
|
|
24
|
+
'x-mcp'?: {
|
|
25
|
+
servers?: unknown[];
|
|
26
|
+
};
|
|
27
|
+
}) | undefined, relativePath: string, rbacConfig: RbacConfig, mcpConfig: GatewayVisibility | undefined): boolean;
|
|
28
|
+
export declare function buildGatewayXMcp(url: string): OpenAPIMcp;
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=eligibility.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{join as r}from"node:path";import{PUBLIC_API_DEFINITIONS_FOLDER as s}from"../../../constants/common.js";import{DEFAULT_ANONYMOUS_VISITOR_TEAM as a}from"../../../../constants/common.js";import{canDownloadApiDefinition as n}from"../../../utils/rbac.js";import{MCP_PROTOCOL_VERSION as p}from"../constants.js";import{isApiIncludedInDocsMcp as l}from"../utils.js";import{isMcpGatewayEnabled as c}from"../utils/mode.js";import{isDefinitionHidden as f,hasGatewayConfig as m}from"../utils/xmcp-utils.js";function u(o){return c()&&!o?.hide&&!o?.docs?.hide&&!o?.gateway?.hide}function d(o,e,i){return f(o,"gateway")?!1:n(r(s,e),i,!1,{isAuthenticated:!1,teams:[a]})||m(o)}function D(o,e,i,t){return u(t)&&!o?.["x-mcp"]?.servers?.length&&d(o?.info,e,i)&&l(e,o,t)}function M(o){return{protocolVersion:p,capabilities:{tools:{}},servers:[{url:o}],tools:[],resources:[],prompts:[]}}export{M as buildGatewayXMcp,u as isGatewayCapabilityEnabled,d as isGatewayEligible,D as shouldAdvertiseGatewayXMcp};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { OpenAPIServer } from '@redocly/openapi-docs/lib/types/open-api.js';
|
|
2
|
+
/**
|
|
3
|
+
* Build case-insensitive host matchers from an API's server URL templates (plus any
|
|
4
|
+
* configured extra hosts). A server URL host may contain server-variable placeholders
|
|
5
|
+
* (e.g. a tenant `{subdomain}`); each placeholder expands to its `enum` values, or - when
|
|
6
|
+
* free-form - to one DNS label plus any fixed parent domain carried by the variable's
|
|
7
|
+
* `default`. So `{subdomain}.dealpos.com` matches `acme.dealpos.com`, and a whole-host
|
|
8
|
+
* `{subdomain}` defaulting to `acme.dealpos.net` matches `<tenant>.dealpos.net`, but neither
|
|
9
|
+
* matches `a.b.dealpos.com`, the bare parent domain, or an unrelated host.
|
|
10
|
+
*/
|
|
11
|
+
export declare function buildAllowedHostMatchers(servers?: readonly OpenAPIServer[], extraHosts?: readonly string[]): RegExp[];
|
|
12
|
+
export declare function isHostAllowed(host: string, matchers: readonly RegExp[]): boolean;
|
|
13
|
+
//# sourceMappingURL=allowed-hosts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const i=/\{([^}]+)\}/g;function m(n=[],e=[]){const t=[];for(const r of n){const o=u(r);o&&t.push(o)}for(const r of e){const o=h(r);o&&t.push(o)}return t}function p(n,e){return e.some(t=>t.test(n))}function u(n){const e=f(n.url);if(!e)return null;let t="",r=0;for(const o of e.matchAll(i)){const[c,l]=o;t+=s(e.slice(r,o.index)),t+=a(n.variables?.[l]),r=o.index+c.length}return t+=s(e.slice(r)),t.includes("\\.")?new RegExp(`^${t}$`,"i"):null}function a(n){const e=n?.enum?.filter(Boolean);if(e&&e.length>0)return`(?:${e.map(s).join("|")})`;const t=n?.default?.split(".").slice(1).join(".");return t?`[^.]+\\.${s(t)}`:"[^.]+"}function h(n){const e=n.trim().toLowerCase();return e?e.startsWith("*.")?new RegExp(`^[^.]+\\.${s(e.slice(2))}$`,"i"):new RegExp(`^${s(e)}$`,"i"):null}function f(n){if(!n)return null;const t=n.replace(/^[a-z][a-z0-9+.-]*:\/\//i,"").split(/[/?#]/,1)[0];return t&&(t.includes("@")?t.slice(t.lastIndexOf("@")+1):t).replace(/:(?:\d+|\{[^}]+\})$/,"")||null}function s(n){return n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}export{m as buildAllowedHostMatchers,p as isHostAllowed};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { SandboxFetch } from '../../codemode/types.js';
|
|
2
|
+
type FetchBridgeOptions = {
|
|
3
|
+
allowedHosts: readonly RegExp[];
|
|
4
|
+
authorization?: string;
|
|
5
|
+
fetchImpl?: typeof fetch;
|
|
6
|
+
timeoutMs?: number;
|
|
7
|
+
maxResponseBytes?: number;
|
|
8
|
+
};
|
|
9
|
+
/** Build the host-side `fetch` the gateway sandbox calls. */
|
|
10
|
+
export declare function buildFetchBridge({ allowedHosts, authorization, fetchImpl, timeoutMs, maxResponseBytes }: FetchBridgeOptions): SandboxFetch;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=fetch-bridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{assertUrlAllowed as f}from"./ssrf-guard.js";const b=3e4,w=1024*1024;function m({allowedHosts:t,authorization:e,fetchImpl:o=fetch,timeoutMs:n=b,maxResponseBytes:s=w}){return async r=>{const a=f(r.url,t),d=g(r.headers,e),c=new AbortController,u=setTimeout(()=>c.abort(),n);try{const i=await o(a,{method:r.method??"GET",headers:d,body:r.body,redirect:"manual",signal:c.signal}),h=await y(i,s);return{status:i.status,statusText:i.statusText,ok:i.ok,headers:T(i.headers),bodyText:h}}finally{clearTimeout(u)}}}async function y(t,e){const o=Number(t.headers.get("content-length"));if(Number.isFinite(o)&&o>e)throw l(e,o);if(!t.body)return"";const n=t.body.getReader(),s=new TextDecoder;let r=0,a="";try{for(;;){const{done:d,value:c}=await n.read();if(d)break;if(r+=c.byteLength,r>e)throw l(e,r);a+=s.decode(c,{stream:!0})}return a+s.decode()}finally{await n.cancel().catch(()=>{})}}function l(t,e){return new Error(`Response is too large (over ${t} bytes, got ${e}); request less data`)}function g(t,e){const o={};let n=!1;for(const[s,r]of Object.entries(t??{})){const a=s.toLowerCase();a==="host"||a==="content-length"||(a==="authorization"&&(n=!0),o[s]=r)}return e&&!n&&(o.Authorization=e),o}function T(t){const e={};return t.forEach((o,n)=>{e[n.toLowerCase()]=o}),e}export{m as buildFetchBridge};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validate an outbound request URL against an API's host allow-list before the gateway fetches it.
|
|
3
|
+
*
|
|
4
|
+
* Returns the parsed URL on success; throws with a clear message otherwise.
|
|
5
|
+
*/
|
|
6
|
+
export declare function assertUrlAllowed(rawUrl: string, matchers: readonly RegExp[]): URL;
|
|
7
|
+
/** True for loopback, private, link-local, unspecified, or otherwise internal addresses. */
|
|
8
|
+
export declare function isBlockedAddress(host: string): boolean;
|
|
9
|
+
//# sourceMappingURL=ssrf-guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{isHostAllowed as f}from"./allowed-hosts.js";function c(e,r){let t;try{t=new URL(e)}catch{throw new Error(`Invalid URL: ${e}`)}if(t.protocol!=="http:"&&t.protocol!=="https:")throw new Error(`Only http(s) URLs are allowed, got ${t.protocol}`);const n=o(t.hostname);if(u(n)||!f(n,r))throw new Error(`Host "${n}" is not allowed`);return t}function u(e){const r=o(e.toLowerCase());return r==="localhost"||r.endsWith(".localhost")?!0:i(r)?s(r):r.includes(":")?l(r):!1}function o(e){return e.replace(/^\[|\]$/g,"")}function i(e){return/^\d{1,3}(\.\d{1,3}){3}$/.test(e)}function s(e){const[r,t]=e.split(".").map(Number);return r===0||r===10||r===127||r===169&&t===254||r===172&&t>=16&&t<=31||r===192&&t===168||r===100&&t>=64&&t<=127}function l(e){if(e==="::1"||e==="::")return!0;const r=e.match(/::ffff:(\d{1,3}(?:\.\d{1,3}){3})$/);if(r)return s(r[1]);const t=parseInt(e.split(":")[0],16);return Number.isNaN(t)?!1:t>=65152&&t<=65215||t>=64512&&t<=65023}export{c as assertUrlAllowed,u as isBlockedAddress};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ApiDescriptionInfo, McpToolContext } from '../types.js';
|
|
2
|
+
import type { SandboxFetch } from '../codemode/types.js';
|
|
3
|
+
export declare function getCallableApis(context: McpToolContext): ApiDescriptionInfo[];
|
|
4
|
+
export declare function isFetchCapable(context: McpToolContext): boolean;
|
|
5
|
+
export declare function buildExecuteHostFetch(context: McpToolContext): SandboxFetch;
|
|
6
|
+
//# sourceMappingURL=fetch-capability.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{isGatewayCapabilityEnabled as a}from"./eligibility.js";import{buildAllowedHostMatchers as l}from"./fetch/allowed-hosts.js";import{buildFetchBridge as s}from"./fetch/fetch-bridge.js";function i(t){return Object.values(t.apiDescriptionsMap??{}).filter(e=>e.fetchEligible)}function u(t){const e=t.config?.mcp;return a(e)&&i(t).length>0}function f(t){const e=t.config?.mcp,o=i(t).flatMap(r=>r.servers??[]);return s({allowedHosts:l(o,e?.gateway?.allowedHosts),authorization:t.upstreamAuthorization})}export{f as buildExecuteHostFetch,i as getCallableApis,u as isFetchCapable};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{toFetchResponse as
|
|
1
|
+
import{toFetchResponse as E,toReqRes as k}from"fetch-to-node";import{logger as m}from"../../../tools/notifiers/logger.js";import{isObject as v}from"../../../../utils/guards/is-object.js";import{getAccessibleSkills as N}from"../../../utils/skills/get-accessible-skills.js";import{getSkillUrl as O}from"../../../utils/skills/get-skill-url.js";import{createDocsMcpServer as L}from"../servers/docs-server.js";import{filterApiDescriptionsByRbac as H,filterGraphqlDescriptionsByRbac as I}from"../utils.js";import{createMethodNotAllowedError as j,withErrorHandling as B}from"./errors.js";import{attachSseKeepalive as _}from"./sse-keepalive.js";import{constructInvalidTokenResponse as J,constructUnauthorizedResponse as P,handleMcpAuth as F,shouldHandleMcpAuth as G}from"../auth/auth-handlers.js";import{extractTokenFromAuthHeader as V}from"../utils/jwt.js";import{DEFAULT_DOCS_MCP_SERVER_NAME as $}from"../constants.js";const u="X-Redocly-AI-Metadata";function q(r){if(r)try{const e=JSON.parse(r);if(v(e))return e;m.warn(`Ignoring ${u} header: not a JSON object.`)}catch{m.warn(`Ignoring ${u} header: invalid JSON.`)}}const z=async(r,e,g)=>{const t=!!e?.config?.access?.requiresLogin,i=e?.config?.access?.rbac||{};let c;const f=r.headers.get("Authorization");if(G(t,i)){const{isAuthenticated:s,isTokenValid:p,currentUser:a,accessToken:d}=await F(r,e);if(!s)return P(new URL(r.url).origin);if(!p)return J();a&&(e.user=a),c=d}else f&&(c=V(f||"")??void 0);let n;return await B(async()=>{if(r.method==="GET")return new Response(JSON.stringify({error:"Method Not Allowed",message:`In order to use this MCP server, you need register it in your MCP Client (VS Code, Cursor, Claude Code, etc.) using that URL: ${r.url}`}),{status:405,headers:{"Content-Type":"application/json"}});if(r.method!=="POST")return j();const s=g,p=s?.props?.config?.apiDescriptionsMap||{},a=s?.props?.config?.graphqlDescriptions||[],d=s?.props?.config?.mcpDocsServerName||$,{config:{mcp:h={}}}=e,R=H(p,e.user,i,t),A=I(a,e.user,i,t),D=s?.props?.skillsBaseUrl||new URL(r.url).origin,M=N(s?.props?.skills||[],e.user,i,t).map(o=>({slug:o.slug,name:o.name,description:o.description,content:o.content,uri:O(D,o.slug)})),w=e.config.products?Object.values(e.config.products).map(o=>o?.name):[],y=h.docs?.name||d,S=q(r.headers.get(u)),T=s?.props?.tools||[];n=await L({name:y,tools:T,skills:M,context:{...e,accessToken:c,outdir:e.outdir||"",baseUrl:e.baseUrl||new URL(r.url).origin,apiDescriptionsMap:R,graphqlDescriptions:A,products:w,metadata:S}});const U=await r.json(),{req:C,res:l}=k(r),b=_(l);try{await n.transport.handleRequest(C,l,U)}catch(o){throw b.stop(),o}return E(l)},async()=>{n&&(await n.cleanup(),n=void 0)})};var ie=z;export{ie as default};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { McpErrorCodeTypes
|
|
1
|
+
import type { McpErrorCodeTypes } from '../types.js';
|
|
2
2
|
export type McpErrorData = {
|
|
3
3
|
readonly code: McpErrorCodeTypes;
|
|
4
4
|
readonly message: string;
|
|
@@ -10,29 +10,11 @@ export declare class McpError extends Error {
|
|
|
10
10
|
readonly data?: unknown;
|
|
11
11
|
readonly requestId?: string | number | null;
|
|
12
12
|
constructor(code: McpErrorCodeTypes, message: string, data?: unknown, requestId?: string | number | null);
|
|
13
|
-
/**
|
|
14
|
-
* Creates a JSON-RPC 2.0 compliant error response
|
|
15
|
-
*/
|
|
16
13
|
createErrorResponse(): Response;
|
|
17
14
|
}
|
|
18
|
-
/**
|
|
19
|
-
* Creates a method not allowed error response
|
|
20
|
-
*/
|
|
21
15
|
export declare function createMethodNotAllowedError(requestId?: string | number | null): Response;
|
|
22
|
-
|
|
23
|
-
* Creates an internal server error response with telemetry
|
|
24
|
-
*/
|
|
25
|
-
export declare function createInternalServerError(error: Error | string, serverType?: McpServerType, requestId?: string | number | null): Response;
|
|
26
|
-
/**
|
|
27
|
-
* Creates an invalid request error response
|
|
28
|
-
*/
|
|
16
|
+
export declare function createInternalServerError(error: Error | string, requestId?: string | number | null): Response;
|
|
29
17
|
export declare function createInvalidRequestError(message?: string, requestId?: string | number | null): Response;
|
|
30
|
-
/**
|
|
31
|
-
* Creates an invalid parameters error response
|
|
32
|
-
*/
|
|
33
18
|
export declare function createInvalidParamsError(message?: string, requestId?: string | number | null): Response;
|
|
34
|
-
|
|
35
|
-
* Safely handles errors in async functions with proper cleanup
|
|
36
|
-
*/
|
|
37
|
-
export declare function withErrorHandling<T>(operation: () => Promise<T>, serverType: McpServerType, cleanup?: () => Promise<void>): Promise<T | Response>;
|
|
19
|
+
export declare function withErrorHandling<T>(operation: () => Promise<T>, cleanup?: () => Promise<void>): Promise<T | Response>;
|
|
38
20
|
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{telemetry as
|
|
1
|
+
import{telemetry as d}from"../../../telemetry/index.js";import{McpErrorCodes as o,McpServerType as s}from"../constants.js";import{getMcpMode as i}from"../utils/mode.js";class n extends Error{code;data;requestId;constructor(e,t,a,c){super(t),this.name="McpError",this.code=e,this.data=a,this.requestId=c}createErrorResponse(){const e={jsonrpc:"2.0",error:{code:this.code,message:this.message,...this.data?{data:this.data}:{}},id:this.requestId??null},t=p(this.code);return new Response(JSON.stringify(e),{status:t,headers:{"Content-Type":"application/json"}})}}function p(r){switch(r){case o.InvalidRequest:case o.InvalidParams:return 400;case o.MethodNotFound:return 404;case o.ServerError:return 405;case o.InternalError:default:return 500}}function v(r){return new n(o.ServerError,"Method not allowed",void 0,r).createErrorResponse()}function u(r,e){const t=r instanceof Error?r.message:String(r),a=r instanceof Error?r.stack:void 0;return d.sendMcpErrorMessage([{id:s.Docs,object:"mcpServer",uri:`urn:redocly:realm:mcp:server:${s.Docs}`,server_type:s.Docs,message:t,stack:a||"",mode:i()}]),new n(o.InternalError,"Internal server error mcp",t,e).createErrorResponse()}function f(r="Invalid request",e){return new n(o.InvalidRequest,r,void 0,e).createErrorResponse()}function h(r="Invalid parameters",e){return new n(o.InvalidParams,r,void 0,e).createErrorResponse()}async function I(r,e){try{return await r()}catch(t){return d.sendMcpErrorMessage([{id:s.Docs,object:"mcpServer",uri:`urn:redocly:realm:mcp:server:${s.Docs}`,server_type:s.Docs,message:t?.message||"",stack:t?.stack||"",mode:i()}]),e&&e(),u(t)}}export{n as McpError,u as createInternalServerError,h as createInvalidParamsError,f as createInvalidRequestError,v as createMethodNotAllowedError,I as withErrorHandling};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{withPathPrefix as
|
|
1
|
+
import{withPathPrefix as f}from"@redocly/theme/core/utils";import{importApiRoutesHandler as g}from"../../../api-routes/import-api-routes-handlers.js";import{enhanceContext as h}from"../../../api-routes/helpers/enhance-context.js";import{telemetry as D}from"../../../telemetry/index.js";import{KvService as A}from"../../../persistence/kv/services/kv-service.js";import{envConfig as o}from"../../../config/env-config.js";import{acceptsHtml as T}from"../../../utils/ai-agent-detection.js";import{handleErrorPageRender as R}from"../../../web-server/utils.js";import{MCP_NOT_ALLOWED_TEMPLATE_ID as E}from"../constants.js";import{resolvePublicBaseUrl as w}from"../../../web-server/utils/resolve-public-base-url.js";async function C(i,t,e){const s=t.req.raw;if(s.method==="GET"&&T(s.headers.get("accept"))&&e.globalData.mcpData?.docs?.enabled)return R(t,e,{slug:i.slug},405,E);const r=t.get("auth"),n=await e.resolveRouteStaticData(i)||{},l=f(i.slug),{requestHandlers:c}=await g(e.serverOutDir),m=c[i.requestHandlerId],p=(await m()).default,u=async()=>await A.getInstance({baseDbDir:e.serverOutDir,sqldRemoteDatabaseUrl:o.SQLD_REMOTE_DATABASE_URL,sqldRemoteDatabaseAuthToken:o.SQLD_REMOTE_DATABASE_AUTH_TOKEN}),d=h({honoCtx:t,ctx:{user:{teams:r.teams,email:r.claims.email,claims:r.claims,idpAccessToken:r.idpAccessToken,idpId:r.claims.idpId,isAuthenticated:r.isAuthenticated},config:e.config,outdir:e.outdir,baseUrl:new URL(t.req.url).origin},telemetry:D,getKv:u}),a=await p(t.req.raw,d,{...n,props:{...n.props,routeSlug:l,outdir:e.outdir,skills:e.config.skills?.hide===!0?[]:e.getSkills(),skillsBaseUrl:w(e,t)}});return a instanceof Response?a:typeof a=="string"?new Response(a,{headers:{"Content-Type":"text/plain"}}):new Response(JSON.stringify(a),{headers:{"Content-Type":"application/json"}})}export{C as handleMcpRequest};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{fileURLToPath as
|
|
1
|
+
import{fileURLToPath as O}from"node:url";import{dirname as T,join as c}from"node:path";import{logger as g}from"../../tools/notifiers/logger.js";import{reporter as A}from"../../tools/notifiers/reporter.js";import{isDefined as R}from"../../../utils/guards/is-defined.js";import{buildGraphqlDescriptions as w,filterIgnoredApiDescriptions as u,getCleanedUpApiDescriptions as L,isMcpInRedirects as q}from"./utils.js";import{isMcpCodeModeEnabled as G}from"./utils/mode.js";import{getDefaultToolSchemas as N}from"./docs-mcp/tool-schemas.js";import{EXECUTE_TOOL_SCHEMA as j}from"./codemode/tools/execute-schema.js";import{isGatewayCapabilityEnabled as U,isGatewayEligible as H}from"./gateway-mcp/eligibility.js";import{telemetryTraceStep as I}from"../../../cli/telemetry/helpers/trace-step.js";import{DEFAULT_DOCS_MCP_SERVER_NAME as F,MCP_NOT_ALLOWED_TEMPLATE_ID as x}from"./constants.js";const h="mcp-docs-server-handler",V="/mcp",p=T(O(import.meta.url));async function B(){let r=!1;return{id:"mcp",async processContent(i,o){r||await I("build.plugin.mcp",async a=>{const s=await i.loadOpenApiDefinitions(o),l=await i.loadGraphqlDefinitions(o),n=await o.getConfig(),{mcp:t,redirects:D}=n;if(a?.setAttribute("config",JSON.stringify(t||{})),!(t?.hide||t?.docs?.hide)&&(q(D)&&await A.panicOnBuildContentError('The reserved route "/mcp" cannot be used in redirect configuration. Please remove any redirects involving "/mcp" from your redocly.yaml config.'),i.createTemplate(x,"@redocly/theme/layouts/McpNotAllowed"),!t?.docs?.hide)){g.info("Configuring MCP servers...");const C=c(p,"./handlers/docs-mcp-handler.js"),E=L(u(s,t?.docs?.ignore||[])),M=!!n?.access?.requiresLogin,d=n?.access?.rbac||{},v=U(t),m=new Map;for(const e of E){const b=e.definition.info?.title||"",S=e.definition.info?.version||"";m.set(e.relativePath,{name:b,description:e.definition.info?.description||"",version:S,servers:e.definition.servers||[],relativePath:e.relativePath,...v&&H(e.definition.info,e.relativePath,d)?{fetchEligible:!0}:{}})}const f=w(u(l,t?.docs?.ignore||[])),y=Object.values(n.products||{}).map(e=>e?.name).filter(R),P=n.l10n?.locales?.map(e=>e.code)??o.fs.localeFolders,_=N({products:y,locales:P,requiresLogin:M,rbac:d,hasGraphqlApis:f.length>0});i.addMcpTools(c(p,"./docs-mcp/tools/index.js"),_),G()&&i.addMcpTools(c(p,"./codemode/tools/execute.js"),[j]),await J({actions:i,handlerPath:C,apiDescriptionsMap:Object.fromEntries(m),graphqlDescriptions:f,mcpConfig:t}),r=!0}})},async afterRoutesCreated(i,o){const a=await o.getConfig(),{mcp:s}=a;i.setGlobalData({mcpData:{docs:{enabled:!s?.hide&&!s?.docs?.hide,name:s?.docs?.name}}})}}}var te=B;async function J({actions:r,handlerPath:i,apiDescriptionsMap:o,graphqlDescriptions:a,mcpConfig:s}){r.createRequestHandler(h,i),r.addApiRoute({slug:V,requestHandlerId:h,httpMethod:"all",getStaticData:async()=>({props:{config:{apiDescriptionsMap:o,graphqlDescriptions:a,mcpDocsServerName:s?.docs?.name||F},serverOutDir:r.serverOutDir,tools:r.getMcpTools().map(({importPath:l,...n})=>n)}})}),g.info("Registered Docs MCP Server endpoint at /mcp")}export{h as MCP_DOCS_SERVER_HANDLER_ID,te as default,B as mcpServerPlugin};
|
|
@@ -1,15 +1,10 @@
|
|
|
1
|
-
import { McpServer } from '@redocly/mcp-typescript-sdk/server/mcp.js';
|
|
2
|
-
import { StreamableHTTPServerTransport } from '@redocly/mcp-typescript-sdk/server/streamableHttp.js';
|
|
3
1
|
import type { McpToolSchema } from '../../../types';
|
|
4
|
-
import type { McpToolContext } from '../types.js';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
transport: StreamableHTTPServerTransport;
|
|
8
|
-
cleanup: () => Promise<void>;
|
|
9
|
-
};
|
|
10
|
-
export declare function createDocsMcpServer({ name, tools, context }: {
|
|
2
|
+
import type { McpToolContext, SkillMcpResource } from '../types.js';
|
|
3
|
+
import { type McpServerInstance } from './mcp-server.js';
|
|
4
|
+
export declare function createDocsMcpServer({ name, tools, context, skills }: {
|
|
11
5
|
name: string;
|
|
12
6
|
tools: McpToolSchema[];
|
|
13
7
|
context: McpToolContext;
|
|
14
|
-
|
|
8
|
+
skills?: SkillMcpResource[];
|
|
9
|
+
}): Promise<McpServerInstance>;
|
|
15
10
|
//# sourceMappingURL=docs-server.d.ts.map
|
|
@@ -1,3 +1 @@
|
|
|
1
|
-
import{
|
|
2
|
-
|
|
3
|
-
${h}`}]}}}function w(e){return{sessionId:e.sessionId,authInfo:e.authInfo,requestId:e.requestId,requestInfo:e.requestInfo,_meta:e._meta}}function L(e){return{user:e.user,config:e.config,outdir:e.outdir,baseUrl:e.baseUrl,params:e.params,query:e.query,cookies:e.cookies,apiDescriptionsMap:e.apiDescriptionsMap,graphqlDescriptions:e.graphqlDescriptions,products:e.products,accessToken:e.accessToken,metadata:e.metadata}}export{B as createDocsMcpServer};
|
|
1
|
+
import{logger as O}from"../../../tools/notifiers/logger.js";import{mcpToolWorkers as _,MCP_TOOL_IS_AVAILABLE_KEY as u}from"../../../workers/mcp-tool-worker-pool.js";import{EXECUTE_TOOL_SCHEMA as C}from"../codemode/tools/execute-schema.js";import{EXECUTE_TOOL_NAME as p,DESCRIBE_TOOLS_TOOL_NAME as M,CODE_MODE_TOOL_NAMES as b,FETCH_TOOL_NAME as S}from"../codemode/constants.js";import{buildCodeModeInstructions as A,buildExecuteDescription as h,DESCRIBE_TOOLS_DESCRIPTION as x}from"../codemode/prompts.js";import{composeExecuteAnnotations as L,getActiveCapabilities as D}from"../codemode/capabilities/index.js";import{describeToolsSchema as v,describeTools as y}from"../codemode/tools/describe-tools.js";import{isMcpCodeModeEnabled as g}from"../utils/mode.js";import{connectMcpServer as I,createMcpServer as k,createToolDispatch as w,extractSerializableContext as N}from"./mcp-server.js";async function K({name:E,tools:a,context:i,skills:d=[]}){const n=g(),r=n?D(i):[],s=r.some(e=>e.id===S),{server:o,transport:f}=k(E,n?A(s):void 0),c=N(i),m=w(c),l=async e=>{try{return await _.exec(u,[{toolName:e,context:c}],{timeout:1e4})}catch(t){return O.error(`Failed to check MCP tool availability for "${e}": ${t instanceof Error?t.message:String(t)}`),!1}};if(n){const e=a.filter(t=>!b.has(t.name));o.tool(p,h(s),C.schema,L(r),m(p)),o.tool(M,x,v(e,r),y(e,l,r,i))}else await Promise.all(a.map(async e=>{const t=e.annotations||{title:e.name},T=o.tool(e.name,e.description,e.schema,t,m(e.name));await l(e.name)||T.disable()}));for(const e of d)o.registerResource(e.slug,e.uri,{title:e.name,description:e.description,mimeType:"text/markdown"},async()=>({contents:[{uri:e.uri,mimeType:"text/markdown",text:e.content}]}));return I(o,f)}export{K as createDocsMcpServer};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { McpServer } from '@redocly/mcp-typescript-sdk/server/mcp.js';
|
|
2
|
+
import { StreamableHTTPServerTransport } from '@redocly/mcp-typescript-sdk/server/streamableHttp.js';
|
|
3
|
+
import type { ToolCallback } from '@redocly/mcp-typescript-sdk/server/mcp.js';
|
|
4
|
+
import type { McpToolContext } from '../types.js';
|
|
5
|
+
export type McpServerInstance = {
|
|
6
|
+
server: McpServer;
|
|
7
|
+
transport: StreamableHTTPServerTransport;
|
|
8
|
+
cleanup: () => Promise<void>;
|
|
9
|
+
};
|
|
10
|
+
export declare function createMcpServer(name: string, instructions?: string): {
|
|
11
|
+
server: McpServer;
|
|
12
|
+
transport: StreamableHTTPServerTransport;
|
|
13
|
+
};
|
|
14
|
+
export declare function connectMcpServer(server: McpServer, transport: StreamableHTTPServerTransport): Promise<McpServerInstance>;
|
|
15
|
+
/** Build the tool callback that ships a tool call to the worker pool. */
|
|
16
|
+
export declare function createToolDispatch(serializableContext: McpToolContext): (toolName: string) => ToolCallback<Record<string, unknown>>;
|
|
17
|
+
export declare function extractSerializableContext(context: McpToolContext): McpToolContext;
|
|
18
|
+
//# sourceMappingURL=mcp-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{McpServer as i}from"@redocly/mcp-typescript-sdk/server/mcp.js";import{StreamableHTTPServerTransport as t}from"@redocly/mcp-typescript-sdk/server/streamableHttp.js";import{logger as n}from"../../../tools/notifiers/logger.js";import{mcpToolWorkers as c,MCP_TOOL_WORKER_KEY as u}from"../../../workers/mcp-tool-worker-pool.js";const p=6e4;function T(e,r){const o=new i({name:e,version:new Date().toISOString().slice(0,10)},{capabilities:{logging:{}},...r?{instructions:r}:{}}),a=new t({sessionIdGenerator:void 0});return{server:o,transport:a}}async function g(e,r){return await e.connect(r),{server:e,transport:r,cleanup:async()=>{r.close()}}}function S(e){return r=>async(o,a)=>{n.info(`MCP tool called: ${r}`);const s={toolName:r,args:o,context:e,extra:l(a)};return await c.exec(u,[s],{timeout:p})}}function l(e){return{sessionId:e.sessionId,authInfo:e.authInfo,requestId:e.requestId,requestInfo:e.requestInfo,_meta:e._meta}}function q(e){return{user:e.user,config:e.config,outdir:e.outdir,baseUrl:e.baseUrl,params:e.params,query:e.query,cookies:e.cookies,apiDescriptionsMap:e.apiDescriptionsMap,graphqlDescriptions:e.graphqlDescriptions,products:e.products,accessToken:e.accessToken,metadata:e.metadata,upstreamAuthorization:e.upstreamAuthorization}}export{g as connectMcpServer,T as createMcpServer,S as createToolDispatch,q as extractSerializableContext};
|