@redocly/theme 0.69.0-next.1 → 0.69.0-next.2

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.
@@ -44,11 +44,14 @@ const DropdownMenuItem_1 = require("../../components/Dropdown/DropdownMenuItem")
44
44
  const Button_1 = require("../../components/Button/Button");
45
45
  const CursorIcon_1 = require("../../icons/CursorIcon/CursorIcon");
46
46
  const VSCodeIcon_1 = require("../../icons/VSCodeIcon/VSCodeIcon");
47
+ const ClaudeIcon_1 = require("../../icons/ClaudeIcon/ClaudeIcon");
48
+ const CodexIcon_1 = require("../../icons/CodexIcon/CodexIcon");
47
49
  const CopyIcon_1 = require("../../icons/CopyIcon/CopyIcon");
48
50
  const CheckmarkFilledIcon_1 = require("../../icons/CheckmarkFilledIcon/CheckmarkFilledIcon");
49
51
  const ChevronDownIcon_1 = require("../../icons/ChevronDownIcon/ChevronDownIcon");
50
52
  const ChevronUpIcon_1 = require("../../icons/ChevronUpIcon/ChevronUpIcon");
51
53
  const hooks_1 = require("../../core/hooks");
54
+ const constants_1 = require("../../core/constants");
52
55
  const MENU_OPTIONS = [
53
56
  {
54
57
  key: 'cursor',
@@ -66,6 +69,22 @@ const MENU_OPTIONS = [
66
69
  descriptionTranslationKey: 'page.actions.connectMcp.vscodeDescription',
67
70
  descriptionDefault: 'Install MCP server on VS Code',
68
71
  },
72
+ {
73
+ key: 'claude-code',
74
+ icon: ClaudeIcon_1.ClaudeIcon,
75
+ titleTranslationKey: 'page.actions.connectMcp.claudeCode',
76
+ titleDefault: 'Connect to Claude Code',
77
+ descriptionTranslationKey: 'page.actions.connectMcp.claudeCodeDescription',
78
+ descriptionDefault: 'Copy the Claude Code CLI command',
79
+ },
80
+ {
81
+ key: 'codex',
82
+ icon: CodexIcon_1.CodexIcon,
83
+ titleTranslationKey: 'page.actions.connectMcp.codex',
84
+ titleDefault: 'Connect to Codex CLI',
85
+ descriptionTranslationKey: 'page.actions.connectMcp.codexDescription',
86
+ descriptionDefault: 'Copy the Codex CLI command',
87
+ },
69
88
  {
70
89
  key: 'copy',
71
90
  icon: CopyIcon_1.CopyIcon,
@@ -75,12 +94,14 @@ const MENU_OPTIONS = [
75
94
  descriptionDefault: 'Copy MCP JSON Configuration',
76
95
  },
77
96
  ];
78
- function ConnectMCPButton({ placement = 'bottom', alignment = 'end', options = ['cursor', 'vscode', 'copy'], }) {
97
+ // Copy actions keep the dropdown open so the copied checkmark is visible.
98
+ const COPY_OPTIONS = ['claude-code', 'codex', 'copy'];
99
+ function ConnectMCPButton({ placement = 'bottom', alignment = 'end', options = constants_1.DEFAULT_MCP_OPTIONS, }) {
79
100
  const { useTranslate } = (0, hooks_1.useThemeHooks)();
80
101
  const { translate } = useTranslate();
81
102
  const [isOpen, setIsOpen] = (0, react_1.useState)(false);
82
103
  const wrapperRef = (0, react_1.useRef)(null);
83
- const { isCopied, visibleOptions, handleAction } = (0, hooks_1.useConnectMCPButton)({ options });
104
+ const { copiedOption, visibleOptions, handleAction } = (0, hooks_1.useConnectMCPButton)({ options });
84
105
  (0, hooks_1.useOutsideClick)(wrapperRef, () => setIsOpen(false));
85
106
  const menuOptions = MENU_OPTIONS.filter((option) => visibleOptions.includes(option.key));
86
107
  const primaryOption = menuOptions[0];
@@ -88,12 +109,12 @@ function ConnectMCPButton({ placement = 'bottom', alignment = 'end', options = [
88
109
  if (!primaryOption)
89
110
  return null;
90
111
  const PrimaryIcon = primaryOption.icon;
91
- // When copy is the primary action there is no dropdown item to show the copied state, so the
92
- // primary button itself must reflect it.
93
- const showPrimaryCopied = primaryOption.key === 'copy' && isCopied;
112
+ const showPrimaryCopied = copiedOption === primaryOption.key;
94
113
  const handleMenuAction = (key) => {
95
114
  handleAction(key);
96
- setIsOpen(false);
115
+ if (!COPY_OPTIONS.includes(key)) {
116
+ setIsOpen(false);
117
+ }
97
118
  };
98
119
  return (react_1.default.createElement(ConnectMCPButtonWrapper, { ref: wrapperRef, "data-component-name": "Buttons/ConnectMCPButton" },
99
120
  react_1.default.createElement(SplitButtonGroup, null,
@@ -102,7 +123,7 @@ function ConnectMCPButton({ placement = 'bottom', alignment = 'end', options = [
102
123
  isOpen && dropdownOptions.length > 0 && (react_1.default.createElement(DropdownWrapper, { $placement: placement, $alignment: alignment },
103
124
  react_1.default.createElement(DropdownMenu_1.DropdownMenu, null, dropdownOptions.map((option) => {
104
125
  const Icon = option.icon;
105
- const showCheckmark = option.key === 'copy' && isCopied;
126
+ const showCheckmark = copiedOption === option.key;
106
127
  return (react_1.default.createElement(DropdownMenuItem_1.DropdownMenuItem, { key: option.key, onAction: () => handleMenuAction(option.key) },
107
128
  react_1.default.createElement(MenuItemContent, null,
108
129
  react_1.default.createElement(MenuItemIcon, null, showCheckmark ? (react_1.default.createElement(CheckmarkFilledIcon_1.CheckmarkFilledIcon, { color: "var(--color-success-base)" })) : (react_1.default.createElement(Icon, null))),
@@ -119,16 +140,24 @@ const SplitButtonGroup = styled_components_1.default.div `
119
140
  display: inline-flex;
120
141
  align-items: stretch;
121
142
  `;
143
+ /* Doubled selectors outrank the base button class in any style injection order,
144
+ and margin: 0 keeps themed button margins from splitting the group apart. */
122
145
  const PrimaryButton = (0, styled_components_1.default)(Button_1.Button) `
123
- --button-gap: var(--connect-mcp-button-gap);
124
- border-top-right-radius: 0;
125
- border-bottom-right-radius: 0;
146
+ && {
147
+ --button-gap: var(--connect-mcp-button-gap);
148
+ margin: 0;
149
+ border-top-right-radius: 0;
150
+ border-bottom-right-radius: 0;
151
+ }
126
152
  `;
127
153
  const ChevronButton = (0, styled_components_1.default)(Button_1.Button) `
128
- border-top-left-radius: 0;
129
- border-bottom-left-radius: 0;
130
- border-left: none;
131
- padding-inline: var(--connect-mcp-button-chevron-padding-inline);
154
+ && {
155
+ margin: 0;
156
+ border-top-left-radius: 0;
157
+ border-bottom-left-radius: 0;
158
+ border-left: none;
159
+ padding-inline: var(--connect-mcp-button-chevron-padding-inline);
160
+ }
132
161
  `;
133
162
  const DropdownWrapper = styled_components_1.default.div `
134
163
  position: absolute;
@@ -0,0 +1,7 @@
1
+ import type { JSX } from 'react';
2
+ export type McpConnectionTab = 'claude' | 'chatgpt' | 'json';
3
+ export type McpConnectionTabsProps = {
4
+ options?: McpConnectionTab[];
5
+ className?: string;
6
+ };
7
+ export declare function McpConnectionTabs({ options, className, }: McpConnectionTabsProps): JSX.Element | null;
@@ -0,0 +1,151 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.McpConnectionTabs = McpConnectionTabs;
40
+ const react_1 = __importStar(require("react"));
41
+ const styled_components_1 = __importDefault(require("styled-components"));
42
+ const hooks_1 = require("../../core/hooks");
43
+ const utils_1 = require("../../core/utils");
44
+ const CodeBlock_1 = require("../../components/CodeBlock/CodeBlock");
45
+ const ClaudeIcon_1 = require("../../icons/ClaudeIcon/ClaudeIcon");
46
+ const ChatGptIcon_1 = require("../../icons/ChatGptIcon/ChatGptIcon");
47
+ const Tabs_1 = require("../../markdoc/components/Tabs/Tabs");
48
+ const TabItemFragment_1 = require("../../markdoc/components/Tabs/TabItemFragment");
49
+ const NumberedList_1 = require("../../markdoc/components/NumberedList/NumberedList");
50
+ const NumberedItem_1 = require("../../markdoc/components/NumberedList/NumberedItem");
51
+ const DEFAULT_TAB_OPTIONS = ['claude', 'chatgpt', 'json'];
52
+ const TAB_LABELS = {
53
+ claude: {
54
+ translationKey: 'page.mcpNotAllowed.tabs.claude',
55
+ defaultLabel: 'Claude',
56
+ icon: ClaudeIcon_1.ClaudeIcon,
57
+ },
58
+ chatgpt: {
59
+ translationKey: 'page.mcpNotAllowed.tabs.chatgpt',
60
+ defaultLabel: 'ChatGPT',
61
+ icon: ChatGptIcon_1.ChatGptIcon,
62
+ },
63
+ json: { translationKey: 'page.mcpNotAllowed.tabs.json', defaultLabel: 'JSON' },
64
+ };
65
+ // The report control is docs feedback, not useful on the connection page.
66
+ const CODE_BLOCK_HEADER = { controls: { copy: {}, report: { hidden: true } } };
67
+ function McpConnectionTabs({ options = DEFAULT_TAB_OPTIONS, className, }) {
68
+ const { useTranslate } = (0, hooks_1.useThemeHooks)();
69
+ const { translate } = useTranslate();
70
+ const { serverName, serverUrl, isMcpDisabled } = (0, hooks_1.useMCPConfig)();
71
+ // The SSR markup of error pages is cached with the build-time origin, so the
72
+ // tabs remount after hydration to pick up the real browser origin.
73
+ const [hydrated, setHydrated] = (0, react_1.useState)(false);
74
+ (0, react_1.useEffect)(() => setHydrated(true), []);
75
+ if (isMcpDisabled) {
76
+ return null;
77
+ }
78
+ const connection = { serverName, url: serverUrl };
79
+ return (react_1.default.createElement(McpConnectionTabsWrapper, { key: hydrated ? 'client' : 'ssr', "data-component-name": "MCP/McpConnectionTabs", "data-testid": "mcp-connection-tabs", className: className },
80
+ react_1.default.createElement(Tabs_1.Tabs, { size: Tabs_1.TabsSize.SMALL }, options.map((option) => {
81
+ const { translationKey, defaultLabel, icon: TabIcon } = TAB_LABELS[option];
82
+ return (react_1.default.createElement(TabItemFragment_1.TabItemFragment, { key: option, label: translate(translationKey, defaultLabel), icon: TabIcon ? react_1.default.createElement(TabIcon, null) : undefined }, renderTabContent(option, connection, translate)));
83
+ }))));
84
+ }
85
+ function renderTabContent(option, connection, translate) {
86
+ const terminalHint = (react_1.default.createElement(TabHint, null, translate('page.mcpNotAllowed.snippets.terminal.hint', 'Run this command in your terminal:')));
87
+ const urlBlock = react_1.default.createElement(CodeBlock_1.CodeBlock, { lang: "text", source: connection.url, header: CODE_BLOCK_HEADER });
88
+ const assistantPromptClient = {
89
+ headline: translate('page.mcpNotAllowed.snippets.prompt.headline', 'Prompt'),
90
+ content: (react_1.default.createElement(react_1.default.Fragment, null,
91
+ react_1.default.createElement(TabHint, null, translate('page.mcpNotAllowed.snippets.prompt.hint', 'Or paste this prompt into the chat to have it add the server for you:')),
92
+ react_1.default.createElement(CodeBlock_1.CodeBlock, { lang: "text", source: (0, utils_1.generateMcpInstallPrompt)(connection), header: CODE_BLOCK_HEADER, wrapContents: true }))),
93
+ };
94
+ switch (option) {
95
+ case 'claude':
96
+ return renderClientList([
97
+ {
98
+ headline: translate('page.mcpNotAllowed.snippets.claudeCode.headline', 'Claude Code'),
99
+ content: (react_1.default.createElement(react_1.default.Fragment, null,
100
+ terminalHint,
101
+ react_1.default.createElement(CodeBlock_1.CodeBlock, { lang: "shell", source: (0, utils_1.generateClaudeCodeCommand)(connection), header: CODE_BLOCK_HEADER, wrapContents: true }))),
102
+ },
103
+ {
104
+ headline: translate('page.mcpNotAllowed.snippets.claudeDesktop.headline', 'Claude Desktop'),
105
+ content: (react_1.default.createElement(react_1.default.Fragment, null,
106
+ react_1.default.createElement(TabHint, null, translate('page.mcpNotAllowed.snippets.claudeDesktop.instruction', 'In Claude Desktop, open Settings → Developer → Edit Config, add this to the configuration file, and restart Claude Desktop:')),
107
+ react_1.default.createElement(CodeBlock_1.CodeBlock, { lang: "json", source: (0, utils_1.generateClaudeDesktopConfig)(connection), header: CODE_BLOCK_HEADER }))),
108
+ },
109
+ ]);
110
+ case 'chatgpt':
111
+ return renderClientList([
112
+ {
113
+ headline: translate('page.mcpNotAllowed.snippets.codexCli.headline', 'Codex CLI'),
114
+ content: (react_1.default.createElement(react_1.default.Fragment, null,
115
+ terminalHint,
116
+ react_1.default.createElement(CodeBlock_1.CodeBlock, { lang: "shell", source: (0, utils_1.generateCodexCommand)(connection), header: CODE_BLOCK_HEADER, wrapContents: true }))),
117
+ },
118
+ {
119
+ headline: translate('page.mcpNotAllowed.snippets.chatgptApp.headline', 'ChatGPT desktop app'),
120
+ content: (react_1.default.createElement(react_1.default.Fragment, null,
121
+ react_1.default.createElement(TabHint, null, translate('page.mcpNotAllowed.snippets.chatgptApp.instruction', 'In the ChatGPT desktop app, go to Settings → Plugins → MCPs and add a server with the "Streamable HTTP" type and this URL (restart the app afterwards):')),
122
+ urlBlock)),
123
+ },
124
+ assistantPromptClient,
125
+ ]);
126
+ case 'json':
127
+ return (react_1.default.createElement(react_1.default.Fragment, null,
128
+ react_1.default.createElement(TabHint, null, translate('page.mcpNotAllowed.snippets.json.hint', 'Add this server entry to your MCP client configuration file:')),
129
+ react_1.default.createElement(CodeBlock_1.CodeBlock, { lang: "json", source: JSON.stringify({ [connection.serverName]: { url: connection.url, description: 'MCP Server' } }, null, 2), header: CODE_BLOCK_HEADER })));
130
+ }
131
+ }
132
+ function renderClientList(clients) {
133
+ return (react_1.default.createElement(NumberedList_1.NumberedList, null, clients.map((client, index) => (react_1.default.createElement(NumberedItem_1.NumberedItem, { key: index, type: "dot", size: "small", headline: client.headline, index: index + 1, isLast: index === clients.length - 1 }, client.content)))));
134
+ }
135
+ const McpConnectionTabsWrapper = styled_components_1.default.div `
136
+ --md-numbered-list-margin: 0 0 var(--spacing-sm);
137
+
138
+ font-size: var(--page-mcp-405-snippets-font-size);
139
+ line-height: var(--page-mcp-405-snippets-line-height);
140
+ text-align: left;
141
+
142
+ /* The copy control floats over the code, so wrapped lines need room to clear it. */
143
+ pre[data-testid='source-code'] {
144
+ padding-right: var(--page-mcp-405-snippets-code-padding-right);
145
+ }
146
+ `;
147
+ const TabHint = styled_components_1.default.p `
148
+ margin: 0 0 var(--spacing-xs);
149
+ color: var(--page-mcp-405-snippets-hint-text-color);
150
+ `;
151
+ //# sourceMappingURL=McpConnectionTabs.js.map
@@ -1 +1,3 @@
1
+ import type { MCPOption } from '../types/mcp';
1
2
  export declare const DEFAULT_MCP_SERVER_NAME = "mcp-server";
3
+ export declare const DEFAULT_MCP_OPTIONS: MCPOption[];
@@ -1,5 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DEFAULT_MCP_SERVER_NAME = void 0;
3
+ exports.DEFAULT_MCP_OPTIONS = exports.DEFAULT_MCP_SERVER_NAME = void 0;
4
4
  exports.DEFAULT_MCP_SERVER_NAME = 'mcp-server';
5
+ exports.DEFAULT_MCP_OPTIONS = [
6
+ 'cursor',
7
+ 'vscode',
8
+ 'claude-code',
9
+ 'codex',
10
+ 'copy',
11
+ ];
5
12
  //# sourceMappingURL=mcp.js.map
@@ -45,10 +45,12 @@ function useActiveSectionId(location, hasOverviewPage = false, withNavbar = true
45
45
  return;
46
46
  }
47
47
  window.addEventListener('scroll', scrollListener, { capture: false });
48
- setTimeout(() => {
48
+ const initialRead = setTimeout(() => {
49
49
  scrollListener();
50
50
  }, 10);
51
51
  return () => {
52
+ clearTimeout(initialRead);
53
+ scrollListener.cancel();
52
54
  window.removeEventListener('scroll', scrollListener);
53
55
  };
54
56
  }, [location, heightOffset, scrollListener]);
@@ -3,7 +3,7 @@ export type McpButtonOptions = {
3
3
  options?: MCPOption[];
4
4
  };
5
5
  export type McpButtonSettings = {
6
- isCopied: boolean;
6
+ copiedOption: MCPOption | null;
7
7
  cursorUrl: string;
8
8
  vscodeUrl: string;
9
9
  triggerButtonText: string;
@@ -9,24 +9,27 @@ const lodash_debounce_1 = __importDefault(require("lodash.debounce"));
9
9
  const use_theme_hooks_1 = require("./use-theme-hooks");
10
10
  const use_mcp_config_1 = require("./use-mcp-config");
11
11
  const clipboard_service_1 = require("../utils/clipboard-service");
12
+ const mcp_1 = require("../constants/mcp");
13
+ const mcp_2 = require("../utils/mcp");
12
14
  const COPIED_RESET_TIMEOUT = 1000;
13
- function useConnectMCPButton({ options = ['cursor', 'vscode', 'copy'], } = {}) {
15
+ function useConnectMCPButton({ options = mcp_1.DEFAULT_MCP_OPTIONS, } = {}) {
14
16
  const { useTranslate } = (0, use_theme_hooks_1.useThemeHooks)();
15
17
  const { translate } = useTranslate();
16
18
  const { serverName, serverUrl, cursorUrl, vscodeUrl } = (0, use_mcp_config_1.useMCPConfig)();
17
- const [isCopied, setIsCopied] = (0, react_1.useState)(false);
19
+ const [copiedOption, setCopiedOption] = (0, react_1.useState)(null);
18
20
  // eslint-disable-next-line react-hooks/exhaustive-deps
19
- const resetCopied = (0, react_1.useCallback)((0, lodash_debounce_1.default)(() => setIsCopied(false), COPIED_RESET_TIMEOUT), []);
21
+ const resetCopied = (0, react_1.useCallback)((0, lodash_debounce_1.default)(() => setCopiedOption(null), COPIED_RESET_TIMEOUT), []);
20
22
  const handleAction = (0, react_1.useCallback)((action) => {
21
- if (action === 'copy') {
22
- const config = {
23
- [serverName]: {
24
- url: serverUrl,
25
- description: 'MCP Server',
26
- },
27
- };
28
- clipboard_service_1.ClipboardService.copyCustom(JSON.stringify(config, null, 2));
29
- setIsCopied(true);
23
+ const connection = { serverName, url: serverUrl };
24
+ const copyTextMap = {
25
+ copy: JSON.stringify({ [serverName]: { url: serverUrl, description: 'MCP Server' } }, null, 2),
26
+ 'claude-code': (0, mcp_2.generateClaudeCodeCommand)(connection),
27
+ codex: (0, mcp_2.generateCodexCommand)(connection),
28
+ };
29
+ const copyText = copyTextMap[action];
30
+ if (copyText !== undefined) {
31
+ clipboard_service_1.ClipboardService.copyCustom(copyText);
32
+ setCopiedOption(action);
30
33
  resetCopied();
31
34
  return;
32
35
  }
@@ -39,7 +42,7 @@ function useConnectMCPButton({ options = ['cursor', 'vscode', 'copy'], } = {}) {
39
42
  const triggerButtonText = (0, react_1.useMemo)(() => translate('page.actions.connectMcp', 'Connect MCP'), [translate]);
40
43
  const visibleOptions = (0, react_1.useMemo)(() => options.filter(Boolean), [options]);
41
44
  return {
42
- isCopied,
45
+ copiedOption,
43
46
  cursorUrl,
44
47
  vscodeUrl,
45
48
  triggerButtonText,
@@ -1037,8 +1037,8 @@ const pages = (0, styled_components_1.css) `
1037
1037
 
1038
1038
  --page-mcp-405-status-text-color: var(--text-color-helper);
1039
1039
  --page-mcp-405-status-font-size: var(--font-size-lg); // @presenter FontSize
1040
- --page-mcp-405-status-line-height: var(--line-height-lg); // @presenter LineHeight
1041
1040
  --page-mcp-405-status-font-weight: var(--font-weight-semibold); // @presenter FontWeight
1041
+ --page-mcp-405-status-line-height: var(--line-height-lg); // @presenter LineHeight
1042
1042
 
1043
1043
  --page-mcp-405-title-text-color: var(--text-color-primary);
1044
1044
  --page-mcp-405-title-font-size: 42px; // @presenter FontSize
@@ -1054,6 +1054,11 @@ const pages = (0, styled_components_1.css) `
1054
1054
  --page-mcp-405-description-font-size-mobile: var(--font-size-lg);
1055
1055
  --page-mcp-405-description-line-height-mobile: var(--line-height-lg);
1056
1056
 
1057
+ --page-mcp-405-snippets-font-size: var(--font-size-base); // @presenter FontSize
1058
+ --page-mcp-405-snippets-line-height: var(--line-height-base); // @presenter LineHeight
1059
+ --page-mcp-405-snippets-hint-text-color: var(--text-color-secondary);
1060
+ --page-mcp-405-snippets-code-padding-right: var(--spacing-xxl);
1061
+
1057
1062
  // @tokens End
1058
1063
 
1059
1064
  /**
@@ -180,6 +180,8 @@ export type BffCatalogList<T> = {
180
180
  export type BffCatalogEntityList = BffCatalogList<BffCatalogEntity>;
181
181
  export type BffCatalogRelatedEntityList = BffCatalogList<BffCatalogRelatedEntity>;
182
182
  export type Page = {
183
+ nextPage?: string | null;
184
+ previousPage?: string | null;
183
185
  endCursor: string | null;
184
186
  startCursor: string | null;
185
187
  hasNextPage: boolean;
@@ -1,5 +1,5 @@
1
1
  import type { TOptions } from 'i18next';
2
- export type TranslationKey = 'dev.newApp' | 'dev.newApp.text' | 'dev.sidebar.header' | 'dev.sidebar.footer.text' | 'dev.create.app.dialog.appName.placeholder' | 'dev.create.app.dialog.appName.error' | 'dev.create.app.dialog.selectAPIs' | 'dev.create.app.dialog.description' | 'dev.create.app.dialog.description.placeholder' | 'dev.create.app.dialog.create' | 'dev.create.app.dialog.cancel' | 'dev.main.tab.appKeys' | 'dev.main.tab.logs' | 'dev.app.description.title' | 'dev.edit.description.dialog.title' | 'dev.edit.description.dialog.save' | 'dev.edit.description.dialog.cancel' | 'dev.create.app.dialog.callbackUrls' | 'dev.create.app.dialog.callbackUrls.placeholder' | 'dev.create.app.dialog.callbackUrls.hint' | 'dev.app.callbackUrls.title' | 'dev.edit.callbackUrls.dialog.title' | 'dev.edit.callbackUrls.dialog.placeholder' | 'dev.edit.callbackUrls.dialog.hint' | 'dev.edit.callbackUrls.dialog.save' | 'dev.edit.callbackUrls.dialog.cancel' | 'dev.edit.apis.dialog.selectedAPIs' | 'dev.app.key.create' | 'dev.create.key.dialog.title' | 'dev.create.key.dialog.create' | 'dev.create.key.dialog.cancel' | 'dev.app.edit' | 'dev.app.delete' | 'dev.edit.app.dialog.title' | 'dev.edit.app.dialog.save' | 'dev.edit.app.dialog.cancel' | 'dev.delete.app.dialog.title' | 'dev.delete.app.dialog.confirmation' | 'dev.delete.app.dialog.delete' | 'dev.delete.app.dialog.cancel' | 'dev.app.key.roll' | 'dev.roll.key.dialog.title' | 'dev.roll.key.dialog.apiKey' | 'dev.roll.key.dialog.expires' | 'dev.roll.key.dialog.confirmation' | 'dev.roll.key.dialog.cancel' | 'dev.roll.key.dialog.roll' | 'dev.update.key.dialog.title' | 'dev.update.key.dialog.update' | 'dev.update.key.dialog.cancel' | 'dev.app.key.api.name' | 'dev.app.key.api.status' | 'dev.app.key.api.edit' | 'dev.edit.apis.dialog.title' | 'dev.edit.apis.dialog.apiKey' | 'dev.edit.apis.dialog.save' | 'dev.edit.apis.dialog.cancel' | 'dev.select.placeholder' | 'dev.app.overview.status.pending' | 'dev.app.overview.status.approved' | 'dev.app.overview.status.revoked' | 'dev.app.overview.status' | 'dev.app.overview.non-production' | 'dev.app.overview.production' | 'dev.app.overview.clientId' | 'dev.app.overview.apiKey' | 'dev.app.key.revoke' | 'dev.revoke.key.dialog.title' | 'dev.revoke.key.dialog.apiKey' | 'dev.revoke.key.dialog.expires' | 'dev.revoke.key.dialog.confirmation' | 'dev.revoke.key.dialog.revoke' | 'dev.revoke.key.dialog.cancel' | 'dev.app.overview.expires' | 'dev.app.overview.created' | 'dev.app.overview.visibilityToggle.hide' | 'dev.app.overview.visibilityToggle.show' | 'search.loading' | 'search.noResults.title' | 'search.keys.navigate' | 'search.keys.select' | 'search.keys.exit' | 'search.label' | 'search.cancel' | 'search.recent' | 'search.navbar.label' | 'search.suggested' | 'search.showMore' | 'search.error.title' | 'search.error.button' | 'search.filter.title' | 'search.filter.reset' | 'search.filter.field.reset' | 'search.ai.welcomeText' | 'search.ai.newConversation' | 'search.ai.backToSearch' | 'search.ai.back' | 'search.ai.assistant' | 'search.ai.placeholder' | 'search.ai.generatingResponse' | 'search.ai.followUpQuestion' | 'search.ai.suggestionsTitle' | 'search.ai.thinkingText' | 'search.ai.resourcesFound' | 'search.ai.resourcesFound.basedOn' | 'search.ai.resourcesFound.resources' | 'search.ai.feedback.title' | 'search.ai.feedback.detailsPlaceholder' | 'search.ai.feedback.thanks' | 'search.ai.toolCall.executed' | 'search.ai.toolCall.executing' | 'search.ai.toolCall.withArgs' | 'search.ai.button' | 'search.ai.label' | 'search.ai.disclaimer' | 'search.ai.error.description' | 'search.ai.error.description.forbidden' | 'search.ai.error.description.unauthorized' | 'search.ai.error.header' | 'search.ai.error.header.forbidden' | 'search.ai.error.header.unauthorized' | 'search.ai.feedback.more' | 'search.searchItem.deprecated' | 'search.groups.all' | 'search.filter.field.footer' | 'aiAssistant.trigger' | 'toc.header' | 'footer.copyrightText' | 'page.homeButton' | 'page.forbidden.title' | 'page.forbidden.description' | 'page.notFound.title' | 'page.notFound.description' | 'page.mcpNotAllowed.title' | 'page.mcpNotAllowed.description' | 'page.lastUpdated.timeago' | 'page.lastUpdated.on' | 'catalog.filters.placeholder' | 'catalog.filters.title' | 'catalog.filters.add' | 'catalog.filters.clearAll' | 'catalog.filters.select.addFilter' | 'catalog.filters.select.all' | 'catalog.filters.done' | 'catalog.catalogs.all.title' | 'catalog.catalogs.all.description' | 'catalog.catalogs.all.switcherLabel' | 'catalog.catalogs.service.title' | 'catalog.catalogs.service.description' | 'catalog.catalogs.service.switcherLabel' | 'catalog.catalogs.user.title' | 'catalog.catalogs.user.description' | 'catalog.catalogs.user.switcherLabel' | 'catalog.catalogs.team.title' | 'catalog.catalogs.team.description' | 'catalog.catalogs.team.switcherLabel' | 'catalog.catalogs.domain.title' | 'catalog.catalogs.domain.description' | 'catalog.catalogs.domain.switcherLabel' | 'catalog.catalogs.apiDescription.title' | 'catalog.catalogs.apiDescription.description' | 'catalog.catalogs.apiDescription.switcherLabel' | 'catalog.catalogs.dataSchema.title' | 'catalog.catalogs.dataSchema.description' | 'catalog.catalogs.dataSchema.switcherLabel' | 'catalog.catalogs.apiOperation.title' | 'catalog.catalogs.apiOperation.description' | 'catalog.catalogs.apiOperation.switcherLabel' | 'catalog.entity.metadata.title' | 'catalog.entity.schema.title' | 'catalog.entity.properties.apiDescription.title' | 'catalog.backToAllLabel' | 'catalog.notConnected' | 'catalog.tags.label' | 'catalog.sort' | 'catalog.catalogs.label' | 'catalog.owners.label' | 'catalog.repositories.label' | 'catalog.email.label' | 'catalog.format.label' | 'catalog.entityType.label' | 'catalog.domains.label' | 'catalog.contact.label' | 'catalog.methodAndPath.label' | 'catalog.links.label' | 'catalog.metadata.domains' | 'catalog.metadata.owners' | 'catalog.history.button.label' | 'catalog.history.sidebar.title' | 'catalog.history.sidebar.close' | 'catalog.history.version.label' | 'catalog.filters.close' | 'catalog.history.version.notSpecified' | 'catalog.history.version.default' | 'catalog.history.revisions.limitMessage' | 'catalog.history.revision.current' | 'catalog.history.revisions.showLess' | 'catalog.history.revisions.showMore' | 'sidebar.menu.backLabel' | 'sidebar.menu.backToLabel' | 'sidebar.actions.show' | 'sidebar.actions.hide' | 'sidebar.actions.changeToSingleColumn' | 'sidebar.actions.changeToTwoColumns' | 'sidebar.actions.singleColumn' | 'sidebar.actions.twoColumns' | 'versionPicker.label' | 'versionPicker.unversioned' | 'codeSnippet.copy.buttonText' | 'codeSnippet.copy.tooltipText' | 'codeSnippet.copy.toasterText' | 'markdown.editPage.text' | 'feedback.settings.comment.submitText' | 'feedback.settings.comment.label' | 'feedback.settings.comment.send' | 'feedback.settings.comment.cancel' | 'feedback.settings.comment.maxLength' | 'feedback.settings.comment.satisfiedLabel' | 'feedback.settings.comment.neutralLabel' | 'feedback.settings.comment.dissatisfiedLabel' | 'feedback.settings.submitText' | 'feedback.settings.label' | 'feedback.settings.reasons.label' | 'feedback.submit' | 'feedback.cancel' | 'feedback.settings.comment.likeLabel' | 'feedback.settings.comment.dislikeLabel' | 'feedback.sentiment.thumbUp' | 'feedback.sentiment.thumbDown' | 'feedback.settings.leftScaleLabel' | 'feedback.settings.rightScaleLabel' | 'feedback.settings.optionalEmail.placeholder' | 'feedback.settings.optionalEmail.label' | 'codeSnippet.report.buttonText' | 'codeSnippet.report.tooltipText' | 'codeSnippet.report.label' | 'codeSnippet.expand.tooltipText' | 'codeSnippet.collapse.tooltipText' | 'jsonViewer.showMore' | 'jsonViewer.showLess' | 'userMenu.login' | 'userMenu.logout' | 'userMenu.devOnboardingLabel' | 'mobileMenu.mainMenu' | 'mobileMenu.previous' | 'mobileMenu.products' | 'mobileMenu.version' | 'navbar.products' | 'page.nextButton' | 'page.previousButton' | 'page.actions.copyButtonText' | 'page.actions.copyTitle' | 'page.actions.copyDescription' | 'page.actions.viewAsMdTitle' | 'page.actions.viewAsMdButtonText' | 'page.actions.viewAsMdDescription' | 'page.actions.chatGptTitle' | 'page.actions.chatGptButtonText' | 'page.actions.chatGptDescription' | 'page.actions.claudeTitle' | 'page.actions.claudeButtonText' | 'page.actions.claudeDescription' | 'page.actions.cursorMcpButtonText' | 'page.actions.cursorMcpTitle' | 'page.actions.cursorMcpDescription' | 'page.actions.connectMcp' | 'page.actions.connectMcp.cursor' | 'page.actions.connectMcp.cursorDescription' | 'page.actions.connectMcp.vscode' | 'page.actions.connectMcp.vscodeDescription' | 'page.actions.connectMcp.copyConfig' | 'page.actions.connectMcp.copyConfigDescription' | 'openapi.download.description.title' | 'openapi.info.title' | 'openapi.info.contact.url' | 'openapi.info.contact.name' | 'openapi.info.license' | 'openapi.info.termsOfService' | 'openapi.info.metadata.title' | 'openapi.key' | 'openapi.value' | 'openapi.enum' | 'openapi.items' | 'openapi.default' | 'openapi.variable' | 'openapi.variables' | 'openapi.actions.show' | 'openapi.actions.hide' | 'openapi.actions.more' | 'openapi.languages.title' | 'openapi.languages.moreButton.tooltipText' | 'openapi.servers.title' | 'openapi.operations' | 'openapi.schemas' | 'openapi.webhooks' | 'openapi.description' | 'openapi.badges.deprecated' | 'openapi.badges.required' | 'openapi.badges.webhook' | 'openapi.request' | 'openapi.path' | 'openapi.query' | 'openapi.querystring' | 'openapi.cookie' | 'openapi.header' | 'openapi.body' | 'openapi.responses' | 'openapi.response' | 'openapi.callbacks' | 'openapi.callbackRequest' | 'openapi.callbackResponse' | 'openapi.payload' | 'openapi.discriminator' | 'openapi.contentType' | 'openapi.tryIt' | 'openapi.loading' | 'openapi.example' | 'openapi.examples' | 'openapi.additionalProperties' | 'openapi.patternProperties' | 'openapi.required' | 'openapi.recursive' | 'openapi.complex' | 'openapi.property' | 'openapi.properties' | 'openapi.details' | 'openapi.hideExample' | 'openapi.showExample' | 'openapi.expandAll' | 'openapi.collapseAll' | 'openapi.viewSecurityDetails' | 'openapi.noResponseExample' | 'openapi.discriminator.searchPlaceholder' | 'openapi.discriminator.searchNoResults' | 'openapi.discriminator.defaultMapping' | 'openapi.discriminator.defaultMappingTooltip' | 'openapi.noResponseContent' | 'openapi.noRequestPayload' | 'openapi.noRequestData' | 'openapi.hidePattern' | 'openapi.showPattern' | 'openapi.authorizationUrl' | 'openapi.tokenUrl' | 'openapi.refreshUrl' | 'openapi.showOptionalScopes' | 'openapi.hideOptionalScopes' | 'openapi.security' | 'openapi.httpAuthorizationScheme' | 'openapi.bearerFormat' | 'openapi.parameterName' | 'openapi.flowType' | 'openapi.connectUrl' | 'openapi.requiredScopes' | 'openapi.unsupportedLanguage' | 'openapi.failedToGenerateCodeSample' | 'openapi.schemaCatalogLink.title' | 'openapi.schemaCatalogLink.copyButtonTooltip' | 'openapi.schemaCatalogLink.copiedTooltip' | 'openapi.mcp.title' | 'openapi.mcp.endpoint' | 'openapi.mcp.tools' | 'openapi.mcp.protocolVersion' | 'openapi.mcp.capabilities' | 'openapi.mcp.experimentalCapabilities' | 'openapi.mcp.inputSchema' | 'openapi.mcp.inputExample' | 'openapi.mcp.outputSchema' | 'openapi.mcp.outputExample' | 'asyncapi.download.description.title' | 'asyncapi.info.title' | 'asyncapi.info.contact.url' | 'asyncapi.info.contact.name' | 'asyncapi.info.license' | 'asyncapi.info.termsOfService' | 'asyncapi.key' | 'asyncapi.value' | 'asyncapi.variables' | 'asyncapi.required' | 'asyncapi.requiredScopes' | 'asyncapi.viewSecurityDetails' | 'graphql.download.description.title' | 'graphql.info.title' | 'graphql.info.contact.url' | 'graphql.info.contact.name' | 'graphql.info.license' | 'graphql.info.termsOfService' | 'graphql.overview' | 'graphql.metadata' | 'graphql.key' | 'graphql.value' | 'graphql.queries' | 'graphql.mutations' | 'graphql.subscriptions' | 'graphql.directives' | 'graphql.objects' | 'graphql.interfaces' | 'graphql.unions' | 'graphql.enums' | 'graphql.inputs' | 'graphql.scalars' | 'graphql.actions.show' | 'graphql.actions.hide' | 'graphql.actions.more' | 'graphql.fields' | 'graphql.inputFields' | 'graphql.values' | 'graphql.arguments.label' | 'graphql.arguments.show' | 'graphql.arguments.hide' | 'graphql.arguments.here' | 'graphql.returnTypes.label' | 'graphql.returnTypes.show' | 'graphql.returnTypes.hide' | 'graphql.possibleTypes' | 'graphql.defaultValue' | 'graphql.deprecationReason' | 'graphql.requiredScopes' | 'graphql.viewSecurityDetails' | 'graphql.objectScopes' | 'graphql.fieldScopes' | 'graphql.implementedInterfaces' | 'graphql.implementedBy' | 'graphql.nonNull' | 'graphql.required' | 'asyncapi.badges.deprecated' | 'graphql.badges.deprecated' | 'asyncapi.actions.show' | 'asyncapi.actions.hide' | 'asyncapi.actions.more' | 'asyncapi.payload' | 'asyncapi.parameters' | 'asyncapi.messages' | 'asyncapi.contentType' | 'asyncapi.moreDetails' | 'asyncapi.property' | 'asyncapi.properties' | 'asyncapi.details' | 'asyncapi.reply' | 'asyncapi.servers.title' | 'graphql.variables' | 'graphql.querySample' | 'graphql.mutationSample' | 'graphql.subscriptionSample' | 'graphql.responseSample' | 'graphql.locations' | 'graphql.sample' | 'graphql.referenced' | 'graphql.content.fragment' | 'button.copy.tooltipText' | 'button.download.tooltipText' | 'button.externalLink.tooltipText' | 'button.email.tooltipText' | 'codeWalkthrough.download' | 'codeWalkthrough.preview' | 'time.justNow' | 'time.past.second' | 'time.past.seconds' | 'time.past.minute' | 'time.past.minutes' | 'time.past.hour' | 'time.past.hours' | 'time.past.day' | 'time.past.days' | 'time.past.week' | 'time.past.weeks' | 'time.past.month' | 'time.past.months' | 'time.past.year' | 'time.past.years' | 'page.internalServerError.title' | 'page.internalServerError.description' | 'page.skipToContent.label' | 'select.noResults' | 'loaders.loading' | 'filter.dateRange.from' | 'filter.dateRange.to' | 'diagram.openFullscreen' | 'diagram.zoomIn' | 'diagram.zoomOut' | 'diagram.reset' | 'diagram.close' | 'diagram.viewer';
2
+ export type TranslationKey = 'dev.newApp' | 'dev.newApp.text' | 'dev.sidebar.header' | 'dev.sidebar.footer.text' | 'dev.create.app.dialog.appName.placeholder' | 'dev.create.app.dialog.appName.error' | 'dev.create.app.dialog.selectAPIs' | 'dev.create.app.dialog.description' | 'dev.create.app.dialog.description.placeholder' | 'dev.create.app.dialog.create' | 'dev.create.app.dialog.cancel' | 'dev.main.tab.appKeys' | 'dev.main.tab.logs' | 'dev.app.description.title' | 'dev.edit.description.dialog.title' | 'dev.edit.description.dialog.save' | 'dev.edit.description.dialog.cancel' | 'dev.create.app.dialog.callbackUrls' | 'dev.create.app.dialog.callbackUrls.placeholder' | 'dev.create.app.dialog.callbackUrls.hint' | 'dev.app.callbackUrls.title' | 'dev.edit.callbackUrls.dialog.title' | 'dev.edit.callbackUrls.dialog.placeholder' | 'dev.edit.callbackUrls.dialog.hint' | 'dev.edit.callbackUrls.dialog.save' | 'dev.edit.callbackUrls.dialog.cancel' | 'dev.edit.apis.dialog.selectedAPIs' | 'dev.app.key.create' | 'dev.create.key.dialog.title' | 'dev.create.key.dialog.create' | 'dev.create.key.dialog.cancel' | 'dev.app.edit' | 'dev.app.delete' | 'dev.edit.app.dialog.title' | 'dev.edit.app.dialog.save' | 'dev.edit.app.dialog.cancel' | 'dev.delete.app.dialog.title' | 'dev.delete.app.dialog.confirmation' | 'dev.delete.app.dialog.delete' | 'dev.delete.app.dialog.cancel' | 'dev.app.key.roll' | 'dev.roll.key.dialog.title' | 'dev.roll.key.dialog.apiKey' | 'dev.roll.key.dialog.expires' | 'dev.roll.key.dialog.confirmation' | 'dev.roll.key.dialog.cancel' | 'dev.roll.key.dialog.roll' | 'dev.update.key.dialog.title' | 'dev.update.key.dialog.update' | 'dev.update.key.dialog.cancel' | 'dev.app.key.api.name' | 'dev.app.key.api.status' | 'dev.app.key.api.edit' | 'dev.edit.apis.dialog.title' | 'dev.edit.apis.dialog.apiKey' | 'dev.edit.apis.dialog.save' | 'dev.edit.apis.dialog.cancel' | 'dev.select.placeholder' | 'dev.app.overview.status.pending' | 'dev.app.overview.status.approved' | 'dev.app.overview.status.revoked' | 'dev.app.overview.status' | 'dev.app.overview.non-production' | 'dev.app.overview.production' | 'dev.app.overview.clientId' | 'dev.app.overview.apiKey' | 'dev.app.key.revoke' | 'dev.revoke.key.dialog.title' | 'dev.revoke.key.dialog.apiKey' | 'dev.revoke.key.dialog.expires' | 'dev.revoke.key.dialog.confirmation' | 'dev.revoke.key.dialog.revoke' | 'dev.revoke.key.dialog.cancel' | 'dev.app.overview.expires' | 'dev.app.overview.created' | 'dev.app.overview.visibilityToggle.hide' | 'dev.app.overview.visibilityToggle.show' | 'search.loading' | 'search.noResults.title' | 'search.keys.navigate' | 'search.keys.select' | 'search.keys.exit' | 'search.label' | 'search.cancel' | 'search.recent' | 'search.navbar.label' | 'search.suggested' | 'search.showMore' | 'search.error.title' | 'search.error.button' | 'search.filter.title' | 'search.filter.reset' | 'search.filter.field.reset' | 'search.ai.welcomeText' | 'search.ai.newConversation' | 'search.ai.backToSearch' | 'search.ai.back' | 'search.ai.assistant' | 'search.ai.placeholder' | 'search.ai.generatingResponse' | 'search.ai.followUpQuestion' | 'search.ai.suggestionsTitle' | 'search.ai.thinkingText' | 'search.ai.resourcesFound' | 'search.ai.resourcesFound.basedOn' | 'search.ai.resourcesFound.resources' | 'search.ai.feedback.title' | 'search.ai.feedback.detailsPlaceholder' | 'search.ai.feedback.thanks' | 'search.ai.toolCall.executed' | 'search.ai.toolCall.executing' | 'search.ai.toolCall.withArgs' | 'search.ai.button' | 'search.ai.label' | 'search.ai.disclaimer' | 'search.ai.error.description' | 'search.ai.error.description.forbidden' | 'search.ai.error.description.unauthorized' | 'search.ai.error.header' | 'search.ai.error.header.forbidden' | 'search.ai.error.header.unauthorized' | 'search.ai.feedback.more' | 'search.searchItem.deprecated' | 'search.groups.all' | 'search.filter.field.footer' | 'aiAssistant.trigger' | 'toc.header' | 'footer.copyrightText' | 'page.homeButton' | 'page.forbidden.title' | 'page.forbidden.description' | 'page.notFound.title' | 'page.notFound.description' | 'page.mcpNotAllowed.title' | 'page.mcpNotAllowed.description' | 'page.mcpNotAllowed.snippets.terminal.hint' | 'page.mcpNotAllowed.snippets.claudeCode.headline' | 'page.mcpNotAllowed.snippets.claudeDesktop.headline' | 'page.mcpNotAllowed.snippets.claudeDesktop.instruction' | 'page.mcpNotAllowed.snippets.chatgptApp.headline' | 'page.mcpNotAllowed.snippets.chatgptApp.instruction' | 'page.mcpNotAllowed.snippets.codexCli.headline' | 'page.mcpNotAllowed.snippets.prompt.headline' | 'page.mcpNotAllowed.snippets.prompt.hint' | 'page.mcpNotAllowed.snippets.json.hint' | 'page.mcpNotAllowed.tabs.claude' | 'page.mcpNotAllowed.tabs.chatgpt' | 'page.mcpNotAllowed.tabs.json' | 'page.lastUpdated.timeago' | 'page.lastUpdated.on' | 'catalog.filters.placeholder' | 'catalog.filters.title' | 'catalog.filters.add' | 'catalog.filters.clearAll' | 'catalog.filters.select.addFilter' | 'catalog.filters.select.all' | 'catalog.filters.done' | 'catalog.catalogs.all.title' | 'catalog.catalogs.all.description' | 'catalog.catalogs.all.switcherLabel' | 'catalog.catalogs.service.title' | 'catalog.catalogs.service.description' | 'catalog.catalogs.service.switcherLabel' | 'catalog.catalogs.user.title' | 'catalog.catalogs.user.description' | 'catalog.catalogs.user.switcherLabel' | 'catalog.catalogs.team.title' | 'catalog.catalogs.team.description' | 'catalog.catalogs.team.switcherLabel' | 'catalog.catalogs.domain.title' | 'catalog.catalogs.domain.description' | 'catalog.catalogs.domain.switcherLabel' | 'catalog.catalogs.apiDescription.title' | 'catalog.catalogs.apiDescription.description' | 'catalog.catalogs.apiDescription.switcherLabel' | 'catalog.catalogs.dataSchema.title' | 'catalog.catalogs.dataSchema.description' | 'catalog.catalogs.dataSchema.switcherLabel' | 'catalog.catalogs.apiOperation.title' | 'catalog.catalogs.apiOperation.description' | 'catalog.catalogs.apiOperation.switcherLabel' | 'catalog.entity.metadata.title' | 'catalog.entity.schema.title' | 'catalog.entity.properties.apiDescription.title' | 'catalog.backToAllLabel' | 'catalog.notConnected' | 'catalog.tags.label' | 'catalog.sort' | 'catalog.catalogs.label' | 'catalog.owners.label' | 'catalog.repositories.label' | 'catalog.email.label' | 'catalog.format.label' | 'catalog.entityType.label' | 'catalog.domains.label' | 'catalog.contact.label' | 'catalog.methodAndPath.label' | 'catalog.links.label' | 'catalog.metadata.domains' | 'catalog.metadata.owners' | 'catalog.history.button.label' | 'catalog.history.sidebar.title' | 'catalog.history.sidebar.close' | 'catalog.history.version.label' | 'catalog.filters.close' | 'catalog.history.version.notSpecified' | 'catalog.history.version.default' | 'catalog.history.revisions.limitMessage' | 'catalog.history.revision.current' | 'catalog.history.revisions.showLess' | 'catalog.history.revisions.showMore' | 'sidebar.menu.backLabel' | 'sidebar.menu.backToLabel' | 'sidebar.actions.show' | 'sidebar.actions.hide' | 'sidebar.actions.changeToSingleColumn' | 'sidebar.actions.changeToTwoColumns' | 'sidebar.actions.singleColumn' | 'sidebar.actions.twoColumns' | 'versionPicker.label' | 'versionPicker.unversioned' | 'codeSnippet.copy.buttonText' | 'codeSnippet.copy.tooltipText' | 'codeSnippet.copy.toasterText' | 'markdown.editPage.text' | 'feedback.settings.comment.submitText' | 'feedback.settings.comment.label' | 'feedback.settings.comment.send' | 'feedback.settings.comment.cancel' | 'feedback.settings.comment.maxLength' | 'feedback.settings.comment.satisfiedLabel' | 'feedback.settings.comment.neutralLabel' | 'feedback.settings.comment.dissatisfiedLabel' | 'feedback.settings.submitText' | 'feedback.settings.label' | 'feedback.settings.reasons.label' | 'feedback.submit' | 'feedback.cancel' | 'feedback.settings.comment.likeLabel' | 'feedback.settings.comment.dislikeLabel' | 'feedback.sentiment.thumbUp' | 'feedback.sentiment.thumbDown' | 'feedback.settings.leftScaleLabel' | 'feedback.settings.rightScaleLabel' | 'feedback.settings.optionalEmail.placeholder' | 'feedback.settings.optionalEmail.label' | 'codeSnippet.report.buttonText' | 'codeSnippet.report.tooltipText' | 'codeSnippet.report.label' | 'codeSnippet.expand.tooltipText' | 'codeSnippet.collapse.tooltipText' | 'jsonViewer.showMore' | 'jsonViewer.showLess' | 'userMenu.login' | 'userMenu.logout' | 'userMenu.devOnboardingLabel' | 'mobileMenu.mainMenu' | 'mobileMenu.previous' | 'mobileMenu.products' | 'mobileMenu.version' | 'navbar.products' | 'page.nextButton' | 'page.previousButton' | 'page.actions.copyButtonText' | 'page.actions.copyTitle' | 'page.actions.copyDescription' | 'page.actions.viewAsMdTitle' | 'page.actions.viewAsMdButtonText' | 'page.actions.viewAsMdDescription' | 'page.actions.chatGptTitle' | 'page.actions.chatGptButtonText' | 'page.actions.chatGptDescription' | 'page.actions.claudeTitle' | 'page.actions.claudeButtonText' | 'page.actions.claudeDescription' | 'page.actions.cursorMcpButtonText' | 'page.actions.cursorMcpTitle' | 'page.actions.cursorMcpDescription' | 'page.actions.connectMcp' | 'page.actions.connectMcp.cursor' | 'page.actions.connectMcp.cursorDescription' | 'page.actions.connectMcp.vscode' | 'page.actions.connectMcp.vscodeDescription' | 'page.actions.connectMcp.claudeCode' | 'page.actions.connectMcp.claudeCodeDescription' | 'page.actions.connectMcp.codex' | 'page.actions.connectMcp.codexDescription' | 'page.actions.connectMcp.copyConfig' | 'page.actions.connectMcp.copyConfigDescription' | 'openapi.download.description.title' | 'openapi.info.title' | 'openapi.info.contact.url' | 'openapi.info.contact.name' | 'openapi.info.license' | 'openapi.info.termsOfService' | 'openapi.info.metadata.title' | 'openapi.key' | 'openapi.value' | 'openapi.enum' | 'openapi.items' | 'openapi.default' | 'openapi.variable' | 'openapi.variables' | 'openapi.actions.show' | 'openapi.actions.hide' | 'openapi.actions.more' | 'openapi.languages.title' | 'openapi.languages.moreButton.tooltipText' | 'openapi.servers.title' | 'openapi.operations' | 'openapi.schemas' | 'openapi.webhooks' | 'openapi.description' | 'openapi.badges.deprecated' | 'openapi.badges.required' | 'openapi.badges.webhook' | 'openapi.request' | 'openapi.path' | 'openapi.query' | 'openapi.querystring' | 'openapi.cookie' | 'openapi.header' | 'openapi.body' | 'openapi.responses' | 'openapi.response' | 'openapi.callbacks' | 'openapi.callbackRequest' | 'openapi.callbackResponse' | 'openapi.payload' | 'openapi.discriminator' | 'openapi.contentType' | 'openapi.tryIt' | 'openapi.loading' | 'openapi.example' | 'openapi.examples' | 'openapi.additionalProperties' | 'openapi.patternProperties' | 'openapi.required' | 'openapi.recursive' | 'openapi.complex' | 'openapi.property' | 'openapi.properties' | 'openapi.details' | 'openapi.hideExample' | 'openapi.showExample' | 'openapi.expandAll' | 'openapi.collapseAll' | 'openapi.viewSecurityDetails' | 'openapi.noResponseExample' | 'openapi.discriminator.searchPlaceholder' | 'openapi.discriminator.searchNoResults' | 'openapi.discriminator.defaultMapping' | 'openapi.discriminator.defaultMappingTooltip' | 'openapi.noResponseContent' | 'openapi.noRequestPayload' | 'openapi.noRequestData' | 'openapi.hidePattern' | 'openapi.showPattern' | 'openapi.authorizationUrl' | 'openapi.tokenUrl' | 'openapi.refreshUrl' | 'openapi.showOptionalScopes' | 'openapi.hideOptionalScopes' | 'openapi.security' | 'openapi.httpAuthorizationScheme' | 'openapi.bearerFormat' | 'openapi.parameterName' | 'openapi.flowType' | 'openapi.connectUrl' | 'openapi.requiredScopes' | 'openapi.unsupportedLanguage' | 'openapi.failedToGenerateCodeSample' | 'openapi.schemaCatalogLink.title' | 'openapi.schemaCatalogLink.copyButtonTooltip' | 'openapi.schemaCatalogLink.copiedTooltip' | 'openapi.mcp.title' | 'openapi.mcp.endpoint' | 'openapi.mcp.tools' | 'openapi.mcp.protocolVersion' | 'openapi.mcp.capabilities' | 'openapi.mcp.experimentalCapabilities' | 'openapi.mcp.inputSchema' | 'openapi.mcp.inputExample' | 'openapi.mcp.outputSchema' | 'openapi.mcp.outputExample' | 'asyncapi.download.description.title' | 'asyncapi.info.title' | 'asyncapi.info.contact.url' | 'asyncapi.info.contact.name' | 'asyncapi.info.license' | 'asyncapi.info.termsOfService' | 'asyncapi.key' | 'asyncapi.value' | 'asyncapi.variables' | 'asyncapi.required' | 'asyncapi.requiredScopes' | 'asyncapi.viewSecurityDetails' | 'graphql.download.description.title' | 'graphql.info.title' | 'graphql.info.contact.url' | 'graphql.info.contact.name' | 'graphql.info.license' | 'graphql.info.termsOfService' | 'graphql.overview' | 'graphql.metadata' | 'graphql.key' | 'graphql.value' | 'graphql.queries' | 'graphql.mutations' | 'graphql.subscriptions' | 'graphql.directives' | 'graphql.objects' | 'graphql.interfaces' | 'graphql.unions' | 'graphql.enums' | 'graphql.inputs' | 'graphql.scalars' | 'graphql.actions.show' | 'graphql.actions.hide' | 'graphql.actions.more' | 'graphql.fields' | 'graphql.inputFields' | 'graphql.values' | 'graphql.arguments.label' | 'graphql.arguments.show' | 'graphql.arguments.hide' | 'graphql.arguments.here' | 'graphql.returnTypes.label' | 'graphql.returnTypes.show' | 'graphql.returnTypes.hide' | 'graphql.possibleTypes' | 'graphql.defaultValue' | 'graphql.deprecationReason' | 'graphql.requiredScopes' | 'graphql.viewSecurityDetails' | 'graphql.objectScopes' | 'graphql.fieldScopes' | 'graphql.implementedInterfaces' | 'graphql.implementedBy' | 'graphql.nonNull' | 'graphql.required' | 'asyncapi.badges.deprecated' | 'graphql.badges.deprecated' | 'asyncapi.actions.show' | 'asyncapi.actions.hide' | 'asyncapi.actions.more' | 'asyncapi.payload' | 'asyncapi.parameters' | 'asyncapi.messages' | 'asyncapi.contentType' | 'asyncapi.moreDetails' | 'asyncapi.property' | 'asyncapi.properties' | 'asyncapi.details' | 'asyncapi.reply' | 'asyncapi.servers.title' | 'graphql.variables' | 'graphql.querySample' | 'graphql.mutationSample' | 'graphql.subscriptionSample' | 'graphql.responseSample' | 'graphql.locations' | 'graphql.sample' | 'graphql.referenced' | 'graphql.content.fragment' | 'button.copy.tooltipText' | 'button.download.tooltipText' | 'button.externalLink.tooltipText' | 'button.email.tooltipText' | 'codeWalkthrough.download' | 'codeWalkthrough.preview' | 'time.justNow' | 'time.past.second' | 'time.past.seconds' | 'time.past.minute' | 'time.past.minutes' | 'time.past.hour' | 'time.past.hours' | 'time.past.day' | 'time.past.days' | 'time.past.week' | 'time.past.weeks' | 'time.past.month' | 'time.past.months' | 'time.past.year' | 'time.past.years' | 'page.internalServerError.title' | 'page.internalServerError.description' | 'page.skipToContent.label' | 'select.noResults' | 'loaders.loading' | 'filter.dateRange.from' | 'filter.dateRange.to' | 'diagram.openFullscreen' | 'diagram.zoomIn' | 'diagram.zoomOut' | 'diagram.reset' | 'diagram.close' | 'diagram.viewer';
3
3
  export type Locale = {
4
4
  code: string;
5
5
  name: string;
@@ -1,5 +1,5 @@
1
1
  export type MCPClientType = 'cursor' | 'vscode';
2
- export type MCPOption = 'cursor' | 'vscode' | 'copy';
2
+ export type MCPOption = 'cursor' | 'vscode' | 'claude-code' | 'codex' | 'copy';
3
3
  export type McpConnectionParams = {
4
4
  serverName: string;
5
5
  url: string;
@@ -1,2 +1,7 @@
1
1
  import type { MCPClientType, McpConnectionParams } from '../types';
2
2
  export declare function generateMCPDeepLink(clientType: MCPClientType, config: McpConnectionParams): string;
3
+ export declare function slugifyMcpServerName(name: string): string;
4
+ export declare function generateClaudeDesktopConfig(config: McpConnectionParams): string;
5
+ export declare function generateClaudeCodeCommand(config: McpConnectionParams): string;
6
+ export declare function generateCodexCommand(config: McpConnectionParams): string;
7
+ export declare function generateMcpInstallPrompt(config: McpConnectionParams): string;
@@ -1,6 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.generateMCPDeepLink = generateMCPDeepLink;
4
+ exports.slugifyMcpServerName = slugifyMcpServerName;
5
+ exports.generateClaudeDesktopConfig = generateClaudeDesktopConfig;
6
+ exports.generateClaudeCodeCommand = generateClaudeCodeCommand;
7
+ exports.generateCodexCommand = generateCodexCommand;
8
+ exports.generateMcpInstallPrompt = generateMcpInstallPrompt;
4
9
  function generateCursorMCPDeepLink(config) {
5
10
  const cursorConfig = {
6
11
  url: config.url,
@@ -28,4 +33,34 @@ function generateMCPDeepLink(clientType, config) {
28
33
  return generateCursorMCPDeepLink(config);
29
34
  }
30
35
  }
36
+ // Server names can contain spaces (e.g. "Docs MCP server") which break bare CLI
37
+ // arguments, so commands use a slugified form while JSON configs keep the raw name.
38
+ function slugifyMcpServerName(name) {
39
+ return name
40
+ .toLowerCase()
41
+ .replace(/[^a-z0-9_-]+/g, '-')
42
+ .replace(/^-+|-+$/g, '');
43
+ }
44
+ // Claude Desktop's config file only launches stdio commands, so remote servers
45
+ // connect through the mcp-remote bridge.
46
+ function generateClaudeDesktopConfig(config) {
47
+ return JSON.stringify({
48
+ mcpServers: {
49
+ [slugifyMcpServerName(config.serverName)]: {
50
+ command: 'npx',
51
+ args: ['-y', 'mcp-remote', config.url],
52
+ },
53
+ },
54
+ }, null, 2);
55
+ }
56
+ function generateClaudeCodeCommand(config) {
57
+ return `claude mcp add --transport http ${slugifyMcpServerName(config.serverName)} ${config.url}`;
58
+ }
59
+ function generateCodexCommand(config) {
60
+ return `codex mcp add ${slugifyMcpServerName(config.serverName)} --url ${config.url}`;
61
+ }
62
+ // Pasted into an AI assistant (Claude Code, Codex) so it installs the server itself.
63
+ function generateMcpInstallPrompt(config) {
64
+ return `Add the MCP server "${slugifyMcpServerName(config.serverName)}" with URL ${config.url} (streamable HTTP transport) to my MCP configuration, then verify it is connected.`;
65
+ }
31
66
  //# sourceMappingURL=mcp.js.map
@@ -0,0 +1,25 @@
1
+ import React from 'react';
2
+ import type { IconProps } from '../../icons/types';
3
+ declare const Icon: (props: IconProps) => React.JSX.Element;
4
+ export declare const CodexIcon: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("styled-components").FastOmit<{
5
+ color?: string;
6
+ size?: string;
7
+ className?: string;
8
+ 'data-component-name'?: string;
9
+ } & React.SVGProps<SVGSVGElement>, "data-component-name" | "size" | keyof React.SVGProps<SVGSVGElement>> & {
10
+ color?: string;
11
+ size?: string;
12
+ className?: string;
13
+ 'data-component-name'?: string;
14
+ } & React.SVGProps<SVGSVGElement>, "data-component-name"> & Partial<Pick<import("styled-components").FastOmit<{
15
+ color?: string;
16
+ size?: string;
17
+ className?: string;
18
+ 'data-component-name'?: string;
19
+ } & React.SVGProps<SVGSVGElement>, "data-component-name" | "size" | keyof React.SVGProps<SVGSVGElement>> & {
20
+ color?: string;
21
+ size?: string;
22
+ className?: string;
23
+ 'data-component-name'?: string;
24
+ } & React.SVGProps<SVGSVGElement>, "data-component-name">>> & string & Omit<typeof Icon, keyof React.Component<any, {}, any>>;
25
+ export {};
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.CodexIcon = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const styled_components_1 = __importDefault(require("styled-components"));
9
+ const utils_1 = require("../../core/utils");
10
+ const Icon = (props) => (react_1.default.createElement("svg", Object.assign({ viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, props),
11
+ react_1.default.createElement("path", { d: "M22.2819 9.8211a5.9847 5.9847 0 0 0-.5157-4.9108 6.0462 6.0462 0 0 0-6.5098-2.9A6.0651 6.0651 0 0 0 4.9807 4.1818a5.9847 5.9847 0 0 0-3.9977 2.9 6.0462 6.0462 0 0 0 .7427 7.0966 5.98 5.98 0 0 0 .511 4.9107 6.051 6.051 0 0 0 6.5146 2.9001A5.9847 5.9847 0 0 0 13.2599 24a6.0557 6.0557 0 0 0 5.7718-4.2058 5.9894 5.9894 0 0 0 3.9977-2.9001 6.0557 6.0557 0 0 0-.7475-7.073zm-9.022 12.6081a4.4755 4.4755 0 0 1-2.8764-1.0408l.1419-.0804 4.7783-2.7582a.7948.7948 0 0 0 .3927-.6813v-6.7369l2.02 1.1686a.071.071 0 0 1 .038.052v5.5826a4.504 4.504 0 0 1-4.4945 4.4944zm-9.6607-4.1254a4.4708 4.4708 0 0 1-.5346-3.0137l.142.0852 4.783 2.7582a.7712.7712 0 0 0 .7806 0l5.8428-3.3685v2.3324a.0804.0804 0 0 1-.0332.0615L9.74 19.9502a4.4992 4.4992 0 0 1-6.1408-1.6464zM2.3408 7.8956a4.485 4.485 0 0 1 2.3655-1.9728V11.6a.7664.7664 0 0 0 .3879.6765l5.8144 3.3543-2.0201 1.1685a.0757.0757 0 0 1-.071 0l-4.8303-2.7865A4.504 4.504 0 0 1 2.3408 7.8956zm16.5963 3.8558L13.1038 8.364 15.1192 7.2a.0757.0757 0 0 1 .071 0l4.8303 2.7913a4.4944 4.4944 0 0 1-.6765 8.1042v-5.6772a.79.79 0 0 0-.407-.667zm2.0107-3.0231l-.142-.0852-4.7735-2.7818a.7759.7759 0 0 0-.7854 0L9.409 9.2297V6.8974a.0662.0662 0 0 1 .0284-.0615l4.8303-2.7866a4.4992 4.4992 0 0 1 6.6802 4.66zM8.3065 12.863l-2.02-1.1638a.0804.0804 0 0 1-.038-.0567V6.0742a4.4992 4.4992 0 0 1 7.3757-3.4537l-.142.0805L8.704 5.459a.7948.7948 0 0 0-.3927.6813zm1.0976-2.3654l2.602-1.4998 2.6069 1.4998v2.9994l-2.5974 1.4997-2.6067-1.4997z" })));
12
+ exports.CodexIcon = (0, styled_components_1.default)(Icon).attrs({
13
+ 'data-component-name': 'icons/CodexIcon/CodexIcon',
14
+ }) `
15
+ path {
16
+ fill: ${({ color }) => (0, utils_1.getCssColorVariable)(color)};
17
+ }
18
+
19
+ height: ${({ size }) => size || '16px'};
20
+ width: ${({ size }) => size || '16px'};
21
+ `;
22
+ //# sourceMappingURL=CodexIcon.js.map