@eventcatalog/core 4.2.6 → 4.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/dist/analytics/analytics.cjs +1 -1
  2. package/dist/analytics/analytics.js +2 -2
  3. package/dist/analytics/log-build.cjs +1 -1
  4. package/dist/analytics/log-build.js +3 -3
  5. package/dist/{chunk-OBA7TFHM.js → chunk-32ZHIOUO.js} +3 -3
  6. package/dist/{chunk-XTSY2LTR.js → chunk-GZOFTODZ.js} +1 -1
  7. package/dist/{chunk-DEGSBGEF.js → chunk-RQCRNCF6.js} +1 -1
  8. package/dist/{chunk-OZNVNRI7.js → chunk-TE4QQSPT.js} +1 -1
  9. package/dist/{chunk-NZUMNTJK.js → chunk-ZLUUUTWP.js} +1 -1
  10. package/dist/constants.cjs +1 -1
  11. package/dist/constants.js +1 -1
  12. package/dist/docs/development/ask-your-architecture/03-mcp-server/getting-started.md +12 -1
  13. package/dist/eventcatalog.cjs +1 -1
  14. package/dist/eventcatalog.config.d.cts +5 -0
  15. package/dist/eventcatalog.config.d.ts +5 -0
  16. package/dist/eventcatalog.js +9 -9
  17. package/dist/generate.cjs +1 -1
  18. package/dist/generate.js +3 -3
  19. package/dist/utils/cli-logger.cjs +1 -1
  20. package/dist/utils/cli-logger.js +2 -2
  21. package/eventcatalog/src/components/CopyAsMarkdown.tsx +73 -5
  22. package/eventcatalog/src/components/McpConnectDialog.tsx +98 -0
  23. package/eventcatalog/src/components/McpIcon.tsx +14 -0
  24. package/eventcatalog/src/enterprise/feature.ts +1 -1
  25. package/eventcatalog/src/enterprise/mcp/mcp-scope.ts +159 -0
  26. package/eventcatalog/src/enterprise/mcp/mcp-scoped-tools.ts +197 -0
  27. package/eventcatalog/src/enterprise/mcp/mcp-server.ts +287 -176
  28. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +13 -0
  29. package/eventcatalog/src/types/mcp-modules.d.ts +1 -0
  30. package/package.json +1 -1
@@ -36,7 +36,7 @@ module.exports = __toCommonJS(analytics_exports);
36
36
  var import_os = __toESM(require("os"), 1);
37
37
 
38
38
  // package.json
39
- var version = "4.2.6";
39
+ var version = "4.3.0";
40
40
 
41
41
  // src/constants.ts
42
42
  var VERSION = version;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  raiseEvent
3
- } from "../chunk-NZUMNTJK.js";
4
- import "../chunk-XTSY2LTR.js";
3
+ } from "../chunk-ZLUUUTWP.js";
4
+ import "../chunk-GZOFTODZ.js";
5
5
  export {
6
6
  raiseEvent
7
7
  };
@@ -140,7 +140,7 @@ var verifyRequiredFieldsAreInCatalogConfigFile = async (projectDirectory) => {
140
140
  var import_os = __toESM(require("os"), 1);
141
141
 
142
142
  // package.json
143
- var version = "4.2.6";
143
+ var version = "4.3.0";
144
144
 
145
145
  // src/constants.ts
146
146
  var VERSION = version;
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  log_build_default
3
- } from "../chunk-OBA7TFHM.js";
3
+ } from "../chunk-32ZHIOUO.js";
4
+ import "../chunk-ZLUUUTWP.js";
4
5
  import "../chunk-K2XIENVT.js";
5
- import "../chunk-NZUMNTJK.js";
6
- import "../chunk-XTSY2LTR.js";
6
+ import "../chunk-GZOFTODZ.js";
7
7
  import "../chunk-6QENHZZP.js";
8
8
  export {
9
9
  log_build_default as default
@@ -1,10 +1,10 @@
1
+ import {
2
+ raiseEvent
3
+ } from "./chunk-ZLUUUTWP.js";
1
4
  import {
2
5
  countResources,
3
6
  serializeCounts
4
7
  } from "./chunk-K2XIENVT.js";
5
- import {
6
- raiseEvent
7
- } from "./chunk-NZUMNTJK.js";
8
8
  import {
9
9
  getEventCatalogConfigFile,
10
10
  verifyRequiredFieldsAreInCatalogConfigFile
@@ -1,5 +1,5 @@
1
1
  // package.json
2
- var version = "4.2.6";
2
+ var version = "4.3.0";
3
3
 
4
4
  // src/constants.ts
5
5
  var VERSION = version;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-XTSY2LTR.js";
3
+ } from "./chunk-GZOFTODZ.js";
4
4
 
5
5
  // src/utils/cli-logger.ts
6
6
  import pc from "picocolors";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  logger
3
- } from "./chunk-DEGSBGEF.js";
3
+ } from "./chunk-RQCRNCF6.js";
4
4
  import {
5
5
  cleanup,
6
6
  getEventCatalogConfigFile
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-XTSY2LTR.js";
3
+ } from "./chunk-GZOFTODZ.js";
4
4
 
5
5
  // src/analytics/analytics.js
6
6
  import os from "os";
@@ -25,7 +25,7 @@ __export(constants_exports, {
25
25
  module.exports = __toCommonJS(constants_exports);
26
26
 
27
27
  // package.json
28
- var version = "4.2.6";
28
+ var version = "4.3.0";
29
29
 
30
30
  // src/constants.ts
31
31
  var VERSION = version;
package/dist/constants.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-XTSY2LTR.js";
3
+ } from "./chunk-GZOFTODZ.js";
4
4
  export {
5
5
  VERSION
6
6
  };
@@ -31,6 +31,18 @@ For local development:
31
31
  http://localhost:3000/docs/mcp/
32
32
  ```
33
33
 
34
+ The MCP server is enabled by default when EventCatalog is running in server mode with a Scale license. To disable it, set
35
+ `mcp.enabled` to `false`:
36
+
37
+ ```js title="eventcatalog.config.js"
38
+ module.exports = {
39
+ output: 'server',
40
+ mcp: {
41
+ enabled: false,
42
+ },
43
+ };
44
+ ```
45
+
34
46
  ### Verify the server
35
47
 
36
48
  Visit the endpoint in your browser to verify. It returns available tools and resources:
@@ -285,4 +297,3 @@ See [instructions on the GitHub repository](https://github.com/event-catalog/mcp
285
297
 
286
298
 
287
299
 
288
-
@@ -144,7 +144,7 @@ var verifyRequiredFieldsAreInCatalogConfigFile = async (projectDirectory) => {
144
144
  var import_picocolors = __toESM(require("picocolors"), 1);
145
145
 
146
146
  // package.json
147
- var version = "4.2.6";
147
+ var version = "4.3.0";
148
148
 
149
149
  // src/constants.ts
150
150
  var VERSION = version;
@@ -170,6 +170,11 @@ type McpAuthConfig = {
170
170
  sharedSecretEnvVar?: string;
171
171
  };
172
172
  type McpConfig = {
173
+ /**
174
+ * Enables the built-in MCP server when EventCatalog is running in server mode with a Scale license.
175
+ * @default true
176
+ */
177
+ enabled?: boolean;
173
178
  auth?: McpAuthConfig;
174
179
  };
175
180
  type GA4Config = {
@@ -170,6 +170,11 @@ type McpAuthConfig = {
170
170
  sharedSecretEnvVar?: string;
171
171
  };
172
172
  type McpConfig = {
173
+ /**
174
+ * Enables the built-in MCP server when EventCatalog is running in server mode with a Scale license.
175
+ * @default true
176
+ */
177
+ enabled?: boolean;
173
178
  auth?: McpAuthConfig;
174
179
  };
175
180
  type GA4Config = {
@@ -1,11 +1,8 @@
1
1
  import {
2
2
  log_build_default
3
- } from "./chunk-OBA7TFHM.js";
3
+ } from "./chunk-32ZHIOUO.js";
4
+ import "./chunk-ZLUUUTWP.js";
4
5
  import "./chunk-K2XIENVT.js";
5
- import {
6
- runMigrations
7
- } from "./chunk-XUAF2H54.js";
8
- import "./chunk-CA4U2JP7.js";
9
6
  import {
10
7
  getProjectOutDir,
11
8
  isAuthEnabled,
@@ -14,10 +11,10 @@ import {
14
11
  } from "./chunk-B7HCX5HM.js";
15
12
  import {
16
13
  generate
17
- } from "./chunk-OZNVNRI7.js";
14
+ } from "./chunk-TE4QQSPT.js";
18
15
  import {
19
16
  logger
20
- } from "./chunk-DEGSBGEF.js";
17
+ } from "./chunk-RQCRNCF6.js";
21
18
  import {
22
19
  resolve_catalog_dependencies_default
23
20
  } from "./chunk-LHR4G2UO.js";
@@ -27,7 +24,10 @@ import {
27
24
  import {
28
25
  watch
29
26
  } from "./chunk-CAJUIMDJ.js";
30
- import "./chunk-NZUMNTJK.js";
27
+ import {
28
+ runMigrations
29
+ } from "./chunk-XUAF2H54.js";
30
+ import "./chunk-CA4U2JP7.js";
31
31
  import {
32
32
  createAstroDevLineFilter,
33
33
  createAstroLineFilter
@@ -38,7 +38,7 @@ import {
38
38
  import "./chunk-W5JQON7Z.js";
39
39
  import {
40
40
  VERSION
41
- } from "./chunk-XTSY2LTR.js";
41
+ } from "./chunk-GZOFTODZ.js";
42
42
  import {
43
43
  linkCoreNodeModules,
44
44
  resolveInstalledCoreNodeModules
package/dist/generate.cjs CHANGED
@@ -108,7 +108,7 @@ var getEventCatalogConfigFile = async (projectDirectory) => {
108
108
  var import_picocolors = __toESM(require("picocolors"), 1);
109
109
 
110
110
  // package.json
111
- var version = "4.2.6";
111
+ var version = "4.3.0";
112
112
 
113
113
  // src/constants.ts
114
114
  var VERSION = version;
package/dist/generate.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  generate
3
- } from "./chunk-OZNVNRI7.js";
4
- import "./chunk-DEGSBGEF.js";
5
- import "./chunk-XTSY2LTR.js";
3
+ } from "./chunk-TE4QQSPT.js";
4
+ import "./chunk-RQCRNCF6.js";
5
+ import "./chunk-GZOFTODZ.js";
6
6
  import "./chunk-6QENHZZP.js";
7
7
  export {
8
8
  generate
@@ -36,7 +36,7 @@ module.exports = __toCommonJS(cli_logger_exports);
36
36
  var import_picocolors = __toESM(require("picocolors"), 1);
37
37
 
38
38
  // package.json
39
- var version = "4.2.6";
39
+ var version = "4.3.0";
40
40
 
41
41
  // src/constants.ts
42
42
  var VERSION = version;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  logger
3
- } from "../chunk-DEGSBGEF.js";
4
- import "../chunk-XTSY2LTR.js";
3
+ } from "../chunk-RQCRNCF6.js";
4
+ import "../chunk-GZOFTODZ.js";
5
5
  export {
6
6
  logger
7
7
  };
@@ -1,8 +1,11 @@
1
1
  import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
2
2
  import { Copy, FileText, Sparkles, ChevronDownIcon, ExternalLink, PenSquareIcon, RssIcon } from 'lucide-react';
3
- import React, { useState, isValidElement } from 'react';
3
+ import React, { Suspense, isValidElement, lazy, useState } from 'react';
4
4
  import type { Schema } from '@utils/collections/schemas';
5
5
  import { buildUrl, toMarkdownUrl } from '@utils/url-builder';
6
+ import McpIcon from './McpIcon';
7
+
8
+ const McpConnectDialog = lazy(() => import('./McpConnectDialog'));
6
9
 
7
10
  // Type allows either a component type (like Lucide icon) or a pre-rendered element (like <img>)
8
11
  type IconInput = React.ElementType | React.ReactElement;
@@ -56,6 +59,9 @@ export function CopyPageMenu({
56
59
  preferChatAsDefault = false,
57
60
  chatButtonText = 'Ask',
58
61
  variant = 'menu',
62
+ mcpServerUrl,
63
+ resourceName,
64
+ mcpResourceType,
59
65
  }: {
60
66
  schemas: Schema[];
61
67
  chatQuery?: string;
@@ -66,6 +72,9 @@ export function CopyPageMenu({
66
72
  preferChatAsDefault?: boolean;
67
73
  chatButtonText?: string;
68
74
  variant?: 'menu' | 'toolbar';
75
+ mcpServerUrl?: string;
76
+ resourceName?: string;
77
+ mcpResourceType?: 'domain' | 'system';
69
78
  }) {
70
79
  // Define available actions
71
80
  const availableActions = {
@@ -75,6 +84,7 @@ export function CopyPageMenu({
75
84
  viewMarkdown: markdownDownloadEnabled,
76
85
  chat: chatEnabled,
77
86
  rssFeed: rssFeedEnabled,
87
+ mcpServer: Boolean(mcpServerUrl),
78
88
  };
79
89
 
80
90
  // Check if any actions are available
@@ -141,6 +151,13 @@ export function CopyPageMenu({
141
151
  icon: RssIcon,
142
152
  };
143
153
  }
154
+ if (availableActions.mcpServer) {
155
+ return {
156
+ type: 'mcpServer',
157
+ text: 'Connect to MCP server',
158
+ icon: McpIcon,
159
+ };
160
+ }
144
161
  return null;
145
162
  };
146
163
 
@@ -148,6 +165,18 @@ export function CopyPageMenu({
148
165
  const [open, setOpen] = useState(false);
149
166
  const [buttonText, setButtonText] = useState(defaultAction?.text || 'Action');
150
167
  const [copyButtonText, setCopyButtonText] = useState('Copy page as markdown');
168
+ const [mcpDialogOpen, setMcpDialogOpen] = useState(false);
169
+ const mcpDialog = mcpServerUrl && mcpDialogOpen && (
170
+ <Suspense fallback={null}>
171
+ <McpConnectDialog
172
+ open={mcpDialogOpen}
173
+ onOpenChange={setMcpDialogOpen}
174
+ serverUrl={mcpServerUrl}
175
+ resourceName={resourceName}
176
+ resourceType={mcpResourceType ?? 'domain'}
177
+ />
178
+ </Suspense>
179
+ );
151
180
 
152
181
  // Fetch the markdown from the url + .mdx
153
182
  const copyMarkdownToClipboard = async () => {
@@ -214,6 +243,9 @@ export function CopyPageMenu({
214
243
  // Dispatch custom event to open chat panel instead of navigating
215
244
  window.dispatchEvent(new CustomEvent('eventcatalog:open-chat'));
216
245
  break;
246
+ case 'mcpServer':
247
+ setMcpDialogOpen(true);
248
+ break;
217
249
  }
218
250
  };
219
251
 
@@ -224,6 +256,7 @@ export function CopyPageMenu({
224
256
  const actionButtonClass =
225
257
  'group inline-flex items-center gap-1.5 whitespace-nowrap text-xs font-medium text-[rgb(var(--ec-page-text-muted))] transition-colors duration-150 hover:text-[rgb(var(--ec-page-text))] focus:outline-hidden focus:ring-2 focus:ring-[rgb(var(--ec-accent))] focus:ring-offset-2 focus:ring-offset-[rgb(var(--ec-page-bg))] rounded-md';
226
258
  const actionIconClass = 'h-3.5 w-3.5 shrink-0 text-[rgb(var(--ec-icon-color))] group-hover:text-[rgb(var(--ec-page-text))]';
259
+ const mcpDescription = `Connect an MCP client to this ${mcpResourceType ?? 'resource'}`;
227
260
 
228
261
  const hasToolbarActions =
229
262
  availableActions.chat ||
@@ -231,12 +264,20 @@ export function CopyPageMenu({
231
264
  availableActions.viewMarkdown ||
232
265
  availableActions.copySchemas ||
233
266
  availableActions.rssFeed ||
267
+ availableActions.mcpServer ||
234
268
  availableActions.editPage;
235
269
 
236
270
  if (variant === 'toolbar') {
237
271
  if (!hasToolbarActions) return null;
238
272
 
239
- const moreActionsAvailable = availableActions.copySchemas || availableActions.rssFeed || availableActions.editPage;
273
+ const showMcpToolbarAction = availableActions.mcpServer;
274
+ const showCopyMarkdownToolbarAction = availableActions.copyMarkdown && !showMcpToolbarAction;
275
+ const hasSecondaryToolbarAction = showMcpToolbarAction || showCopyMarkdownToolbarAction;
276
+ const moreActionsAvailable =
277
+ availableActions.copySchemas ||
278
+ availableActions.rssFeed ||
279
+ availableActions.editPage ||
280
+ (showMcpToolbarAction && availableActions.copyMarkdown);
240
281
 
241
282
  return (
242
283
  <div className="not-prose flex flex-wrap items-center gap-x-3 gap-y-1.5 text-xs text-[rgb(var(--ec-page-text-muted))]">
@@ -251,18 +292,25 @@ export function CopyPageMenu({
251
292
  </button>
252
293
  )}
253
294
 
254
- {availableActions.chat && (availableActions.copyMarkdown || availableActions.viewMarkdown || moreActionsAvailable) && (
295
+ {availableActions.chat && (hasSecondaryToolbarAction || availableActions.viewMarkdown || moreActionsAvailable) && (
255
296
  <span className="h-4 w-px bg-[rgb(var(--ec-page-border))]" aria-hidden="true" />
256
297
  )}
257
298
 
258
- {availableActions.copyMarkdown && (
299
+ {showMcpToolbarAction && (
300
+ <button type="button" onClick={() => setMcpDialogOpen(true)} className={actionButtonClass}>
301
+ <McpIcon className={actionIconClass} />
302
+ Connect to MCP server
303
+ </button>
304
+ )}
305
+
306
+ {showCopyMarkdownToolbarAction && (
259
307
  <button type="button" onClick={copyMarkdownToClipboard} className={actionButtonClass}>
260
308
  <Copy className={actionIconClass} />
261
309
  {copyButtonText}
262
310
  </button>
263
311
  )}
264
312
 
265
- {availableActions.copyMarkdown && (availableActions.viewMarkdown || moreActionsAvailable) && (
313
+ {hasSecondaryToolbarAction && (availableActions.viewMarkdown || moreActionsAvailable) && (
266
314
  <span className="h-4 w-px bg-[rgb(var(--ec-page-border))]" aria-hidden="true" />
267
315
  )}
268
316
 
@@ -290,6 +338,15 @@ export function CopyPageMenu({
290
338
  sideOffset={10}
291
339
  align="start"
292
340
  >
341
+ {showMcpToolbarAction && availableActions.copyMarkdown && (
342
+ <DropdownMenu.Item
343
+ className="cursor-pointer rounded-2xl outline-hidden transition-colors duration-150 hover:bg-[rgb(var(--ec-dropdown-hover))] data-[highlighted]:bg-[rgb(var(--ec-dropdown-hover))]"
344
+ onSelect={() => copyMarkdownToClipboard()}
345
+ >
346
+ <MenuItemContent icon={Copy} title="Copy page as markdown" description="Copy page as Markdown for LLMs" />
347
+ </DropdownMenu.Item>
348
+ )}
349
+
293
350
  {availableActions.copySchemas &&
294
351
  schemas.map((schema) => {
295
352
  const title =
@@ -348,6 +405,7 @@ export function CopyPageMenu({
348
405
  </DropdownMenu.Content>
349
406
  </DropdownMenu.Root>
350
407
  )}
408
+ {mcpDialog}
351
409
  </div>
352
410
  );
353
411
  }
@@ -383,6 +441,15 @@ export function CopyPageMenu({
383
441
  sideOffset={10}
384
442
  align="end"
385
443
  >
444
+ {availableActions.mcpServer && (
445
+ <DropdownMenu.Item
446
+ className="cursor-pointer rounded-2xl outline-hidden transition-colors duration-150 hover:bg-[rgb(var(--ec-dropdown-hover))] data-[highlighted]:bg-[rgb(var(--ec-dropdown-hover))]"
447
+ onSelect={() => setMcpDialogOpen(true)}
448
+ >
449
+ <MenuItemContent icon={McpIcon} title="Connect to MCP server" description={mcpDescription} />
450
+ </DropdownMenu.Item>
451
+ )}
452
+
386
453
  {availableActions.chat && (
387
454
  <>
388
455
  <DropdownMenu.Item
@@ -477,6 +544,7 @@ export function CopyPageMenu({
477
544
  </>
478
545
  )}
479
546
  </DropdownMenu.Content>
547
+ {mcpDialog}
480
548
  </DropdownMenu.Root>
481
549
  );
482
550
  }
@@ -0,0 +1,98 @@
1
+ import * as Dialog from '@radix-ui/react-dialog';
2
+ import { Check, Copy, X } from 'lucide-react';
3
+ import { useEffect, useRef, useState } from 'react';
4
+ import McpIcon from './McpIcon';
5
+
6
+ type McpConnectDialogProps = {
7
+ open: boolean;
8
+ onOpenChange: (open: boolean) => void;
9
+ serverUrl: string;
10
+ resourceName?: string;
11
+ resourceType: 'domain' | 'system';
12
+ };
13
+
14
+ export default function McpConnectDialog({ open, onOpenChange, serverUrl, resourceName, resourceType }: McpConnectDialogProps) {
15
+ const [copied, setCopied] = useState(false);
16
+ const resetTimer = useRef<ReturnType<typeof setTimeout> | null>(null);
17
+ const absoluteServerUrl = new URL(serverUrl, window.location.origin).href;
18
+
19
+ useEffect(
20
+ () => () => {
21
+ if (resetTimer.current) clearTimeout(resetTimer.current);
22
+ },
23
+ []
24
+ );
25
+
26
+ const copyServerUrl = async () => {
27
+ try {
28
+ await navigator.clipboard.writeText(absoluteServerUrl);
29
+ setCopied(true);
30
+ if (resetTimer.current) clearTimeout(resetTimer.current);
31
+ resetTimer.current = setTimeout(() => setCopied(false), 2000);
32
+ } catch {
33
+ setCopied(false);
34
+ }
35
+ };
36
+
37
+ return (
38
+ <Dialog.Root open={open} onOpenChange={onOpenChange}>
39
+ <Dialog.Portal>
40
+ <Dialog.Overlay className="fixed inset-0 z-50 bg-black/50 data-[state=open]:animate-overlayShow" />
41
+ <Dialog.Content className="fixed left-1/2 top-1/2 z-[100] w-[calc(100vw-2rem)] max-w-lg -translate-x-1/2 -translate-y-1/2 rounded-lg border border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-card-bg,var(--ec-page-bg)))] p-6 shadow-xl focus:outline-hidden data-[state=open]:animate-contentShow">
42
+ <div className="flex items-start gap-3">
43
+ <div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-lg border border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-content-hover))]">
44
+ <McpIcon className="h-5 w-5" />
45
+ </div>
46
+ <div className="min-w-0 flex-1">
47
+ <Dialog.Title className="text-lg font-semibold text-[rgb(var(--ec-page-text))]">Connect to MCP server</Dialog.Title>
48
+ <Dialog.Description className="mt-1 text-sm leading-6 text-[rgb(var(--ec-page-text-muted))]">
49
+ Use this URL to connect an MCP client to this {resourceType}
50
+ {resourceName ? `: ${resourceName}` : ''}.
51
+ </Dialog.Description>
52
+ </div>
53
+ <Dialog.Close asChild>
54
+ <button
55
+ type="button"
56
+ aria-label="Close"
57
+ className="rounded-md p-2 text-[rgb(var(--ec-icon-color))] transition-colors hover:bg-[rgb(var(--ec-content-hover))] hover:text-[rgb(var(--ec-page-text))] focus:outline-hidden focus:ring-2 focus:ring-[rgb(var(--ec-accent))]"
58
+ >
59
+ <X className="h-4 w-4" aria-hidden="true" />
60
+ </button>
61
+ </Dialog.Close>
62
+ </div>
63
+
64
+ <div className="mt-6">
65
+ <label htmlFor="mcp-server-url" className="text-xs font-medium text-[rgb(var(--ec-page-text-muted))]">
66
+ MCP server URL
67
+ </label>
68
+ <div className="mt-2 flex items-center gap-2">
69
+ <input
70
+ id="mcp-server-url"
71
+ type="text"
72
+ readOnly
73
+ value={absoluteServerUrl}
74
+ onFocus={(event) => event.currentTarget.select()}
75
+ className="min-w-0 flex-1 rounded-md border border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-input-bg,var(--ec-page-bg)))] px-3 py-2.5 font-mono text-xs text-[rgb(var(--ec-page-text))] outline-hidden focus:border-[rgb(var(--ec-accent))] focus:ring-1 focus:ring-[rgb(var(--ec-accent))]"
76
+ />
77
+ <button
78
+ type="button"
79
+ onClick={copyServerUrl}
80
+ className="inline-flex h-10 items-center gap-2 rounded-md border border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-card-bg,var(--ec-page-bg)))] px-3 text-sm font-medium text-[rgb(var(--ec-page-text))] transition-colors hover:bg-[rgb(var(--ec-content-hover))] focus:outline-hidden focus:ring-2 focus:ring-[rgb(var(--ec-accent))]"
81
+ >
82
+ {copied ? (
83
+ <Check className="h-4 w-4 text-green-500" aria-hidden="true" />
84
+ ) : (
85
+ <Copy className="h-4 w-4" aria-hidden="true" />
86
+ )}
87
+ {copied ? 'Copied' : 'Copy'}
88
+ </button>
89
+ </div>
90
+ <p className="mt-3 text-xs leading-5 text-[rgb(var(--ec-page-text-muted))]">
91
+ Add this remote server URL to your MCP client. Authentication may be required if it is enabled for this catalog.
92
+ </p>
93
+ </div>
94
+ </Dialog.Content>
95
+ </Dialog.Portal>
96
+ </Dialog.Root>
97
+ );
98
+ }
@@ -0,0 +1,14 @@
1
+ import { buildUrl } from '@utils/url-builder';
2
+
3
+ export default function McpIcon({ className = 'h-4 w-4' }: { className?: string }) {
4
+ return (
5
+ <span className={`inline-flex shrink-0 ${className}`} aria-hidden="true">
6
+ <img src={buildUrl('/icons/protocols/mcp-light.svg', true)} alt="" className="h-full w-full object-contain dark:hidden" />
7
+ <img
8
+ src={buildUrl('/icons/protocols/mcp-dark.svg', true)}
9
+ alt=""
10
+ className="hidden h-full w-full object-contain dark:block"
11
+ />
12
+ </span>
13
+ );
14
+ }
@@ -67,7 +67,7 @@ export const isCustomStylesEnabled = () => {
67
67
  return isEventCatalogStarterEnabled() || isEventCatalogScaleEnabled();
68
68
  };
69
69
 
70
- export const isEventCatalogMCPEnabled = () => isEventCatalogScaleEnabled() && isSSR();
70
+ export const isEventCatalogMCPEnabled = () => isEventCatalogScaleEnabled() && isSSR() && (config?.mcp?.enabled ?? true);
71
71
 
72
72
  export const isEventCatalogMCPAuthEnabled = () => isEventCatalogMCPEnabled() && (config?.mcp?.auth?.enabled ?? false);
73
73