@apify/docs-theme 1.0.225 → 1.0.226

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apify/docs-theme",
3
- "version": "1.0.225",
3
+ "version": "1.0.226",
4
4
  "description": "",
5
5
  "main": "./src/index.js",
6
6
  "files": [
@@ -7,10 +7,13 @@ import {
7
7
  CheckIcon,
8
8
  ChevronDownIcon,
9
9
  CopyIcon,
10
+ CursorIcon,
10
11
  ExternalLinkIcon,
11
12
  LoaderIcon,
12
13
  MarkdownIcon,
14
+ McpIcon,
13
15
  PerplexityIcon,
16
+ VscodeIcon,
14
17
  } from '@apify/ui-icons';
15
18
  import { Menu, Text, theme } from '@apify/ui-library';
16
19
 
@@ -31,6 +34,29 @@ const DROPDOWN_OPTIONS = [
31
34
  Icon: MarkdownIcon,
32
35
  value: 'viewAsMarkdown',
33
36
  },
37
+ {
38
+ label: 'Copy MCP server',
39
+ description: 'Copy MCP Server URL to clipboard',
40
+ showExternalIcon: false,
41
+ Icon: McpIcon,
42
+ value: 'copyMcpServer',
43
+ },
44
+ {
45
+ label: 'Connect to Cursor',
46
+ description: 'Install MCP Server on Cursor',
47
+ showExternalIcon: true,
48
+ // TODO: Replace with CursorIcon - we don't have one yet
49
+ Icon: CursorIcon,
50
+ value: 'connectCursor',
51
+ },
52
+ {
53
+ label: 'Connect to VS Code',
54
+ description: 'Install MCP server on VS Code',
55
+ showExternalIcon: true,
56
+ // TODO: Replace with VS Code Icon - we don't have one yet
57
+ Icon: VscodeIcon,
58
+ value: 'connectVsCode',
59
+ },
34
60
  {
35
61
  label: 'Open in ChatGPT',
36
62
  description: 'Ask questions about this page',
@@ -54,6 +80,16 @@ const DROPDOWN_OPTIONS = [
54
80
  },
55
81
  ];
56
82
 
83
+ const MCP_SERVER_URL = 'https://mcp.apify.com/?tools=docs';
84
+
85
+ const MCP_CONFIG_JSON = `{
86
+ "mcpServers": {
87
+ "apify": {
88
+ "url": "${MCP_SERVER_URL}"
89
+ }
90
+ }
91
+ }`;
92
+
57
93
  const getPrompt = (currentUrl) => `Read from ${currentUrl} so I can ask questions about it.`;
58
94
  const getMarkdownUrl = (currentUrl) => {
59
95
  const url = new URL(currentUrl);
@@ -161,6 +197,87 @@ const onCopyAsMarkdownClick = async ({ setCopyingStatus }) => {
161
197
  }
162
198
  };
163
199
 
200
+ const onCopyMcpServerClick = async () => {
201
+ if (window.analytics) {
202
+ window.analytics.track('Clicked', {
203
+ app: 'docs',
204
+ button_text: 'Copy MCP server',
205
+ element: 'llm-buttons.copyMcpServer',
206
+ });
207
+ }
208
+
209
+ try {
210
+ await navigator.clipboard.writeText(MCP_CONFIG_JSON);
211
+ } catch (error) {
212
+ console.error('Failed to copy MCP configuration:', error);
213
+ }
214
+ };
215
+
216
+ const openApifyMcpConfigurator = (integration) => {
217
+ try {
218
+ window.open(`https://mcp.apify.com/?integration=${integration}`, '_blank');
219
+ } catch (error) {
220
+ console.error('Error opening fallback URL:', error);
221
+ }
222
+ };
223
+
224
+ const openMcpIntegration = async (integration) => {
225
+ // Try to open the app directly using URL scheme
226
+ let appUrl;
227
+ if (integration === 'cursor') {
228
+ // Cursor deeplink format:
229
+ // cursor://anysphere.cursor-deeplink/mcp/install?name=$NAME&config=$BASE64_JSON
230
+ const cursorConfig = {
231
+ url: MCP_SERVER_URL,
232
+ };
233
+ const encodedConfig = btoa(JSON.stringify(cursorConfig));
234
+ appUrl = `cursor://anysphere.cursor-deeplink/mcp/install?name=apify&config=${encodeURIComponent(encodedConfig)}`;
235
+ } else if (integration === 'vscode') {
236
+ // VS Code deeplink format: vscode:mcp/install?<url-encoded-json>
237
+ const mcpConfig = {
238
+ name: 'Apify',
239
+ type: 'http',
240
+ url: MCP_SERVER_URL,
241
+ };
242
+ const encodedConfig = encodeURIComponent(JSON.stringify(mcpConfig));
243
+ appUrl = `vscode:mcp/install?${encodedConfig}`;
244
+ }
245
+
246
+ if (appUrl) {
247
+ const openedWindow = window.open(appUrl, '_blank');
248
+
249
+ if (openedWindow) {
250
+ return;
251
+ }
252
+ }
253
+ // Fallback to web configurator if appUrl doesn't exist or window.open failed
254
+ openApifyMcpConfigurator(integration);
255
+ };
256
+
257
+ const onConnectCursorClick = () => {
258
+ if (window.analytics) {
259
+ window.analytics.track('Clicked', {
260
+ app: 'docs',
261
+ button_text: 'Connect to Cursor',
262
+ element: 'llm-buttons.connectCursor',
263
+ });
264
+ }
265
+
266
+ openMcpIntegration('cursor');
267
+ };
268
+
269
+ const onConnectVsCodeClick = () => {
270
+ if (window.analytics) {
271
+ window.analytics.track('Clicked', {
272
+ app: 'docs',
273
+ button_text: 'Connect to VS Code',
274
+ element: 'llm-buttons.connectVsCode',
275
+ });
276
+ }
277
+
278
+ openMcpIntegration('vscode');
279
+ };
280
+
164
281
  const onViewAsMarkdownClick = () => {
165
282
  if (window.analytics) {
166
283
  window.analytics.track('Clicked', {
@@ -257,6 +374,15 @@ export default function LLMButtons({ isApiReferencePage = false }) {
257
374
  case 'viewAsMarkdown':
258
375
  onViewAsMarkdownClick();
259
376
  break;
377
+ case 'copyMcpServer':
378
+ onCopyMcpServerClick();
379
+ break;
380
+ case 'connectCursor':
381
+ onConnectCursorClick();
382
+ break;
383
+ case 'connectVsCode':
384
+ onConnectVsCodeClick();
385
+ break;
260
386
  case 'openInChatGPT':
261
387
  onOpenInChatGPTClick();
262
388
  break;
@@ -277,9 +403,9 @@ export default function LLMButtons({ isApiReferencePage = false }) {
277
403
  [styles.llmMenuApiReferencePage]: isApiReferencePage,
278
404
  })}
279
405
  onMenuOpen={(isOpen) => chevronIconRef.current?.classList.toggle(
280
- styles.chevronIconOpen,
281
- isOpen,
282
- )
406
+ styles.chevronIconOpen,
407
+ isOpen,
408
+ )
283
409
  }
284
410
  components={{
285
411
  MenuBase: (props) => (