@eventcatalog/core 4.12.2 → 5.0.0-beta.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.
- package/LICENSE +226 -95
- package/NOTICE +30 -0
- package/README.md +3 -2
- package/dist/analytics/analytics.cjs +1 -1
- package/dist/analytics/analytics.js +2 -2
- package/dist/analytics/log-build.cjs +43 -16
- package/dist/analytics/log-build.d.cts +6 -5
- package/dist/analytics/log-build.d.ts +6 -5
- package/dist/analytics/log-build.js +4 -3
- package/dist/{chunk-U4YJSTGV.js → chunk-AYNZXUB5.js} +2 -10
- package/dist/{chunk-IVVM67LN.js → chunk-CR6AK5LR.js} +1 -1
- package/dist/{chunk-GTIC4R74.js → chunk-LR7AGRHN.js} +13 -16
- package/dist/chunk-TQLRG35T.js +203 -0
- package/dist/{chunk-WK4J6FP3.js → chunk-TWN43V4T.js} +1 -1
- package/dist/{chunk-ZW3MYAWF.js → chunk-WAIADKQE.js} +1 -1
- package/dist/{chunk-RPVA2SZY.js → chunk-ZHKEARLJ.js} +1 -1
- package/dist/constants.cjs +1 -1
- package/dist/constants.js +1 -1
- package/dist/eventcatalog.cjs +407 -291
- package/dist/eventcatalog.config.d.cts +2 -3
- package/dist/eventcatalog.config.d.ts +2 -3
- package/dist/eventcatalog.js +30 -93
- package/dist/federation/content-cache.d.cts +0 -5
- package/dist/federation/content-cache.d.ts +0 -5
- package/dist/federation/diagnostics.d.cts +0 -5
- package/dist/federation/diagnostics.d.ts +0 -5
- package/dist/federation/federate.cjs +0 -9
- package/dist/federation/federate.d.cts +0 -5
- package/dist/federation/federate.d.ts +0 -5
- package/dist/federation/federate.js +2 -3
- package/dist/federation/filesystem-source-provider.d.cts +0 -5
- package/dist/federation/filesystem-source-provider.d.ts +0 -5
- package/dist/federation/github-source-provider.d.cts +0 -5
- package/dist/federation/github-source-provider.d.ts +0 -5
- package/dist/federation/output-transaction.d.cts +0 -4
- package/dist/federation/output-transaction.d.ts +0 -4
- package/dist/federation/public-assets.d.cts +0 -5
- package/dist/federation/public-assets.d.ts +0 -5
- package/dist/federation/source-provider.d.cts +0 -5
- package/dist/federation/source-provider.d.ts +0 -5
- package/dist/federation/types.d.cts +0 -5
- package/dist/federation/types.d.ts +0 -5
- package/dist/generate.cjs +1 -1
- package/dist/generate.js +3 -3
- package/dist/license-C1y-56bb.d.cts +23 -0
- package/dist/license-C1y-56bb.d.ts +23 -0
- package/dist/runtime-dependencies/@eventcatalog__visualiser__layout.mjs +3 -0
- package/dist/runtime-dependencies/@modelcontextprotocol__ext-apps.mjs +3 -0
- package/dist/runtime-dependencies/@modelcontextprotocol__ext-apps__react.mjs +3 -0
- package/dist/runtime-dependencies/@modelcontextprotocol__ext-apps__server.mjs +3 -0
- package/dist/runtime-dependencies/@modelcontextprotocol__sdk__types.js.mjs +3 -0
- package/dist/runtime-dependencies/manifest.json +12 -1
- package/dist/runtime-dependencies/react-syntax-highlighter__dist__esm__languages__prism__graphql.mjs +3 -0
- package/dist/runtime-dependencies/react-syntax-highlighter__dist__esm__languages__prism__json.mjs +3 -0
- package/dist/runtime-dependencies/react-syntax-highlighter__dist__esm__languages__prism__markup.mjs +3 -0
- package/dist/runtime-dependencies/react-syntax-highlighter__dist__esm__languages__prism__protobuf.mjs +3 -0
- package/dist/runtime-dependencies/react-syntax-highlighter__dist__esm__languages__prism__yaml.mjs +3 -0
- package/dist/runtime-dependencies/react-syntax-highlighter__dist__esm__styles__prism__one-dark.mjs +3 -0
- package/dist/runtime-dependencies/react-syntax-highlighter__dist__esm__styles__prism__one-light.mjs +3 -0
- package/dist/utils/cli-logger.cjs +1 -1
- package/dist/utils/cli-logger.js +2 -2
- package/dist/utils/license-status.cjs +240 -0
- package/dist/utils/license-status.d.cts +28 -0
- package/dist/utils/license-status.d.ts +28 -0
- package/dist/utils/license-status.js +12 -0
- package/eventcatalog/astro.config.mjs +1 -1
- package/eventcatalog/integrations/eventcatalog-runtime.mjs +1 -1
- package/eventcatalog/src/components/ChatPanel/ChatPanel.tsx +29 -19
- package/eventcatalog/src/components/ChatPanel/OfflineReply.tsx +74 -0
- package/eventcatalog/src/components/FieldsExplorer/FieldFilters.tsx +24 -28
- package/eventcatalog/src/components/FieldsExplorer/FieldNodeGraph.tsx +16 -11
- package/eventcatalog/src/components/FieldsExplorer/FieldsExplorer.tsx +4 -218
- package/eventcatalog/src/components/FieldsExplorer/FieldsTable.tsx +27 -36
- package/eventcatalog/src/components/Header.astro +43 -58
- package/eventcatalog/src/components/Lists/PillListFlat.styles.css +17 -17
- package/eventcatalog/src/components/MDX/EntityMap/EntityMap.astro +1 -1
- package/eventcatalog/src/components/MDX/Flow/Flow.astro +4 -0
- package/eventcatalog/src/components/MDX/NodeGraph/AstroNodeGraph.tsx +14 -0
- package/eventcatalog/src/components/MDX/NodeGraph/NodeGraph.astro +49 -18
- package/eventcatalog/src/components/MDX/RemoteFile.astro +2 -24
- package/eventcatalog/src/components/SchemaExplorer/ApiAccessSection.tsx +59 -93
- package/eventcatalog/src/components/SchemaExplorer/ApiContentViewer.tsx +1 -32
- package/eventcatalog/src/components/SchemaExplorer/DiffViewer.tsx +20 -67
- package/eventcatalog/src/components/SchemaExplorer/SchemaContentViewer.tsx +2 -11
- package/eventcatalog/src/components/SchemaExplorer/SchemaDetailsPanel.tsx +11 -60
- package/eventcatalog/src/components/SchemaExplorer/SchemaExplorer.tsx +1 -3
- package/eventcatalog/src/components/SchemaExplorer/SchemaPageViewer.tsx +0 -3
- package/eventcatalog/src/components/SchemaExplorer/VersionHistoryModal.tsx +2 -9
- package/eventcatalog/src/components/SchemaExplorer/parse-schema.ts +46 -0
- package/eventcatalog/src/components/SchemaExplorer/utils.ts +11 -0
- package/eventcatalog/src/components/Settings/AssistantSettingsForm.tsx +2 -9
- package/eventcatalog/src/components/Settings/LicenseSettings.tsx +288 -0
- package/eventcatalog/src/components/Settings/LlmAccessSettingsForm.tsx +3 -19
- package/eventcatalog/src/components/Settings/McpSettingsForm.tsx +85 -30
- package/eventcatalog/src/components/Settings/SettingsShared.tsx +7 -75
- package/eventcatalog/src/components/SideNav/CustomDocsNav.astro +2 -2
- package/eventcatalog/src/components/TrialBadge.astro +82 -0
- package/eventcatalog/src/content.config.ts +9 -90
- package/eventcatalog/src/{enterprise → features}/ai/chat-api.ts +22 -34
- package/eventcatalog/src/{enterprise → features}/analytics/adapters/ga4.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/analytics/adapters/gtm.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/analytics/adapters/posthog.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/analytics/components/AnalyticsHead.astro +2 -4
- package/eventcatalog/src/{enterprise → features}/analytics/components/AnalyticsTracker.astro +2 -4
- package/eventcatalog/src/{enterprise → features}/analytics/tracker.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/api/catalog.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/auth/[...auth].ts +0 -5
- package/eventcatalog/src/{enterprise → features}/auth/middleware/middleware-auth.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/auth/middleware/middleware.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/collections/custom-pages.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/collections/index.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/collections/resource-docs.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/custom-documentation/collection.ts +0 -5
- package/eventcatalog/src/features/custom-documentation/components/CustomDocsNav/CustomDocsNav.astro +9 -0
- package/eventcatalog/src/{enterprise → features}/custom-documentation/components/CustomDocsNav/CustomDocsNavWrapper.tsx +0 -5
- package/eventcatalog/src/{enterprise → features}/custom-documentation/components/CustomDocsNav/components/NestedItem.tsx +1 -6
- package/eventcatalog/src/{enterprise → features}/custom-documentation/components/CustomDocsNav/components/NoResultsFound.tsx +0 -5
- package/eventcatalog/src/{enterprise → features}/custom-documentation/components/CustomDocsNav/index.tsx +1 -6
- package/eventcatalog/src/{enterprise → features}/custom-documentation/components/CustomDocsNav/types.ts +0 -5
- package/eventcatalog/src/{enterprise/custom-documentation/pages/docs/custom/index.astro → features/custom-documentation/components/CustomDocumentationPage.astro} +5 -5
- package/eventcatalog/src/{enterprise → features}/custom-documentation/utils/badge-styles.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/custom-documentation/utils/custom-docs.ts +1 -6
- package/eventcatalog/src/{enterprise → features}/custom-documentation/utils/docs-search.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/custom-pages/routes.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/directory/user-team-directory.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/fields/field-extractor.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/fields/field-indexer.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/fields/fields-db.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/fields/pages/api/fields.ts +1 -6
- package/eventcatalog/src/{enterprise → features}/fields/pages/fields.astro +1 -2
- package/eventcatalog/src/{enterprise → features}/integrations/eventcatalog-features.ts +17 -75
- package/eventcatalog/src/features/mcp/apps/architecture-diagram/links.ts +59 -0
- package/eventcatalog/src/features/mcp/apps/architecture-diagram/node-chat.tsx +299 -0
- package/eventcatalog/src/features/mcp/apps/architecture-diagram/shared.ts +14 -0
- package/eventcatalog/src/features/mcp/apps/architecture-diagram/view.tsx +454 -0
- package/eventcatalog/src/features/mcp/apps/generated/viewer.html +432 -0
- package/eventcatalog/src/features/mcp/apps/mermaid-stub.ts +10 -0
- package/eventcatalog/src/features/mcp/apps/schema-viewer/schema-code.tsx +65 -0
- package/eventcatalog/src/features/mcp/apps/schema-viewer/shared.ts +23 -0
- package/eventcatalog/src/features/mcp/apps/schema-viewer/view.tsx +170 -0
- package/eventcatalog/src/features/mcp/apps/shared/app-view.tsx +98 -0
- package/eventcatalog/src/features/mcp/apps/shared/resource-types.ts +15 -0
- package/eventcatalog/src/features/mcp/apps/viewer/shared.ts +24 -0
- package/eventcatalog/src/features/mcp/apps/viewer/styles.css +25 -0
- package/eventcatalog/src/features/mcp/apps/viewer/view.tsx +59 -0
- package/eventcatalog/src/features/mcp/mcp-app-icons.ts +63 -0
- package/eventcatalog/src/features/mcp/mcp-apps.ts +160 -0
- package/eventcatalog/src/{enterprise → features}/mcp/mcp-auth.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/mcp/mcp-scope.ts +7 -7
- package/eventcatalog/src/{enterprise → features}/mcp/mcp-scoped-tools.ts +47 -40
- package/eventcatalog/src/{enterprise → features}/mcp/mcp-server.ts +347 -34
- package/eventcatalog/src/{enterprise → features}/mcp/oauth-protected-resource.ts +0 -5
- package/eventcatalog/src/features/mcp/schema-viewer.ts +24 -0
- package/eventcatalog/src/{enterprise → features}/tools/catalog-tools.ts +133 -102
- package/eventcatalog/src/features/tools/index.ts +5 -0
- package/eventcatalog/src/{enterprise → features}/visualizer-layout/reset.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/visualizer-layout/save.ts +0 -5
- package/eventcatalog/src/layouts/BaseLayout.astro +2 -2
- package/eventcatalog/src/layouts/Footer.astro +31 -39
- package/eventcatalog/src/layouts/SettingsLayout.astro +6 -6
- package/eventcatalog/src/layouts/VerticalSideBarLayout.astro +7 -37
- package/eventcatalog/src/{enterprise → pages}/api/schemas/[collection]/[id]/[version]/index.ts +0 -22
- package/eventcatalog/src/{enterprise → pages}/api/schemas/services/[id]/[version]/[specification]/index.ts +0 -19
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/[docVersion]/_index.data.ts +2 -6
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/[docVersion]/index.astro +1 -5
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/_index.data.ts +2 -6
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/index.astro +1 -5
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId].md.ts +2 -6
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId].mdx.ts +2 -6
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +9 -5
- package/eventcatalog/src/pages/docs/custom/[...path]/index.astro +12 -0
- package/eventcatalog/src/{enterprise/custom-documentation/pages/docs/custom/root-index.astro → pages/docs/custom/index.astro} +1 -23
- package/eventcatalog/src/pages/docs/llm/llms-full.txt.ts +4 -9
- package/eventcatalog/src/pages/docs/llm/llms.txt.ts +4 -4
- package/eventcatalog/src/pages/docs/llm/schemas.txt.ts +0 -11
- package/eventcatalog/src/pages/docs/services/[id]/[docType]/[docId]/index.astro +2 -2
- package/eventcatalog/src/pages/index.astro +2 -2
- package/eventcatalog/src/pages/schemas/[type]/[id]/[version]/index.astro +0 -3
- package/eventcatalog/src/pages/schemas/explorer/index.astro +1 -4
- package/eventcatalog/src/pages/settings/assistant.astro +2 -4
- package/eventcatalog/src/pages/settings/license.astro +18 -0
- package/eventcatalog/src/pages/settings/llm-access.astro +1 -4
- package/eventcatalog/src/pages/settings/mcp.astro +33 -4
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/_index.data.ts +1 -2
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/data/index.astro +2 -45
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/entity-map/index.astro +1 -1
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version].mermaid.ts +7 -109
- package/eventcatalog/src/pages/visualiser/_mermaid-route.ts +78 -0
- package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/_index.data.ts +44 -0
- package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/entity-map/index.astro +1 -1
- package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/index.astro +56 -0
- package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/systems-context/index.astro +3 -40
- package/eventcatalog/src/pages/visualiser/domains/[id]/[version].mermaid.ts +20 -0
- package/eventcatalog/src/pages/visualiser/systems/[id]/[version]/_index.data.ts +29 -0
- package/eventcatalog/src/pages/visualiser/systems/[id]/[version]/context/index.astro +3 -38
- package/eventcatalog/src/pages/visualiser/systems/[id]/[version]/index.astro +56 -0
- package/eventcatalog/src/pages/visualiser/systems/[id]/[version].mermaid.ts +20 -0
- package/eventcatalog/src/stores/sidebar-store/builders/agent.ts +1 -1
- package/eventcatalog/src/stores/sidebar-store/builders/container.ts +1 -1
- package/eventcatalog/src/stores/sidebar-store/builders/data-product.ts +1 -1
- package/eventcatalog/src/stores/sidebar-store/builders/domain.ts +7 -32
- package/eventcatalog/src/stores/sidebar-store/builders/entity.ts +1 -1
- package/eventcatalog/src/stores/sidebar-store/builders/message.ts +1 -1
- package/eventcatalog/src/stores/sidebar-store/builders/service.ts +2 -8
- package/eventcatalog/src/stores/sidebar-store/builders/system.ts +2 -12
- package/eventcatalog/src/stores/sidebar-store/custom-sidebar.ts +0 -10
- package/eventcatalog/src/stores/sidebar-store/state.ts +4 -6
- package/eventcatalog/src/styles/theme.css +22 -18
- package/eventcatalog/src/styles/themes/forest.css +8 -8
- package/eventcatalog/src/styles/themes/ocean.css +8 -8
- package/eventcatalog/src/styles/themes/sapphire.css +8 -8
- package/eventcatalog/src/styles/themes/sunset.css +8 -8
- package/eventcatalog/src/utils/clipboard.ts +4 -4
- package/eventcatalog/src/utils/collections/flow-step-schema.ts +117 -0
- package/eventcatalog/src/utils/collections/pointer-schema.ts +7 -0
- package/eventcatalog/src/utils/collections/resource-docs.ts +677 -14
- package/eventcatalog/src/utils/collections/schema-loader.ts +0 -5
- package/eventcatalog/src/utils/feature.ts +14 -23
- package/eventcatalog/src/utils/license.ts +114 -0
- package/eventcatalog/src/utils/node-graphs/architecture-diagram-types.ts +32 -0
- package/eventcatalog/src/utils/node-graphs/architecture-diagram.ts +84 -0
- package/eventcatalog/src/utils/node-graphs/catalog-force-graph.ts +1 -0
- package/eventcatalog/src/utils/node-graphs/channel-node-graph.ts +4 -25
- package/eventcatalog/src/utils/node-graphs/container-node-graph.ts +12 -39
- package/eventcatalog/src/utils/node-graphs/data-products-node-graph.ts +11 -27
- package/eventcatalog/src/utils/node-graphs/domain-levels-node-graph.ts +679 -0
- package/eventcatalog/src/utils/node-graphs/domains-node-graph.ts +3 -20
- package/eventcatalog/src/utils/node-graphs/export-mermaid.ts +62 -4
- package/eventcatalog/src/utils/node-graphs/field-node-graph.ts +8 -23
- package/eventcatalog/src/utils/node-graphs/flow-lanes.ts +119 -0
- package/eventcatalog/src/utils/node-graphs/flows-node-graph.ts +153 -45
- package/eventcatalog/src/utils/node-graphs/layout-node-graph.ts +28 -0
- package/eventcatalog/src/utils/node-graphs/layout-persistence.ts +3 -3
- package/eventcatalog/src/utils/node-graphs/message-node-graph.ts +16 -34
- package/eventcatalog/src/utils/node-graphs/services-node-graph.ts +11 -25
- package/eventcatalog/src/utils/node-graphs/system-context-node-graph.ts +18 -54
- package/eventcatalog/src/utils/node-graphs/system-levels-node-graph.ts +59 -0
- package/eventcatalog/src/utils/node-graphs/systems-node-graph.ts +20 -80
- package/eventcatalog/src/utils/node-graphs/utils/utils.ts +1 -78
- package/eventcatalog/src/utils/trial.ts +36 -0
- package/eventcatalog/tsconfig.json +1 -1
- package/package.json +11 -11
- package/dist/chunk-FV56YFM4.js +0 -7
- package/dist/federation/entitlement.cjs +0 -31
- package/dist/federation/entitlement.d.cts +0 -12
- package/dist/federation/entitlement.d.ts +0 -12
- package/dist/federation/entitlement.js +0 -6
- package/dist/runtime-dependencies/dagre.mjs +0 -3
- package/eventcatalog/src/components/Settings/BillingSettingsForm.tsx +0 -265
- package/eventcatalog/src/enterprise/LICENSE +0 -57
- package/eventcatalog/src/enterprise/README.md +0 -5
- package/eventcatalog/src/enterprise/collections/resource-docs-utils.ts +0 -691
- package/eventcatalog/src/enterprise/custom-documentation/components/CustomDocsNav/CustomDocsNav.astro +0 -9
- package/eventcatalog/src/enterprise/custom-documentation/pages/docs/custom/[...path]/index.astro +0 -18
- package/eventcatalog/src/enterprise/custom-documentation/pages/docs/custom/feature.astro +0 -171
- package/eventcatalog/src/enterprise/feature.ts +0 -75
- package/eventcatalog/src/enterprise/tools/index.ts +0 -10
- package/eventcatalog/src/hooks/eventcatalog-visualizer.ts +0 -126
- package/eventcatalog/src/pages/settings/billing.astro +0 -17
- package/eventcatalog/src/pages/visualiser/domain-integrations/index.astro +0 -26
- package/eventcatalog/src/types/mcp-modules.d.ts +0 -67
- package/eventcatalog/src/utils/node-graphs/domains-canvas.ts +0 -261
- package/eventcatalog/src/utils/node-graphs/export-node-graph.ts +0 -91
- /package/eventcatalog/src/{enterprise → features}/auth/error.astro +0 -0
- /package/eventcatalog/src/{enterprise → features}/auth/login.astro +0 -0
- /package/eventcatalog/src/{enterprise → features}/auth/unauthorized.astro +0 -0
- /package/eventcatalog/src/{enterprise/custom-documentation/pages → pages}/docs/custom/[...path]/_index.data.ts +0 -0
- /package/eventcatalog/src/{enterprise/custom-documentation/pages → pages}/docs/custom/[...path].mdx.ts +0 -0
|
@@ -1,20 +1,42 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Licensed under the EventCatalog Commercial License.
|
|
3
|
-
* See /packages/core/eventcatalog/src/enterprise/LICENSE
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
1
|
import type { APIRoute } from 'astro';
|
|
7
2
|
import { Hono, type Context } from 'hono';
|
|
8
3
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
9
4
|
import { WebStandardStreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js';
|
|
10
5
|
import { z } from 'zod';
|
|
11
6
|
import { join } from 'node:path';
|
|
12
|
-
import
|
|
13
|
-
import * as catalogTools from '@enterprise/tools/catalog-tools';
|
|
7
|
+
import * as catalogTools from '@features/tools/catalog-tools';
|
|
14
8
|
import { getCollection } from 'astro:content';
|
|
15
9
|
import { createMcpAuthErrorResponse, validateMcpRequest } from './mcp-auth';
|
|
16
10
|
import { createScopedCatalogTools } from './mcp-scoped-tools';
|
|
17
11
|
import { McpScopeNotFoundError, resolveMcpScope, type McpScope, type McpScopeKind } from './mcp-scope';
|
|
12
|
+
import { getArchitectureDiagramView } from '@utils/node-graphs/architecture-diagram';
|
|
13
|
+
import type {
|
|
14
|
+
ArchitectureDiagramCollection,
|
|
15
|
+
ArchitectureDiagramView,
|
|
16
|
+
Graph,
|
|
17
|
+
} from '@utils/node-graphs/architecture-diagram-types';
|
|
18
|
+
import { inlineNodeIcons } from './mcp-app-icons';
|
|
19
|
+
import type { ArchitectureDiagramPayload } from './apps/architecture-diagram/shared';
|
|
20
|
+
import type { SchemaViewerPayload } from './apps/schema-viewer/shared';
|
|
21
|
+
import { RESOURCE_VIEWS, VIEWER_META_KEY, VIEWER_RESOURCE_URI, VIEWER_VIEW_TOOL, type ViewerPayload } from './apps/viewer/shared';
|
|
22
|
+
import { toSchemaViewerSchemas } from './schema-viewer';
|
|
23
|
+
import { getMcpAppViewLoader, mcpAppNote, registerMcpApp } from './mcp-apps';
|
|
24
|
+
import { buildUrl } from '@utils/url-builder';
|
|
25
|
+
|
|
26
|
+
const loadViewerView = getMcpAppViewLoader('viewer');
|
|
27
|
+
|
|
28
|
+
const SHOW_RESOURCE_DESCRIPTION = [
|
|
29
|
+
"Show the user a resource in EventCatalog's interactive viewer. Pick what to show with view:",
|
|
30
|
+
'"architecture" shows an architecture diagram of a domain, system, service, agent, event, command, query, flow, data store or data product: what it connects to, what it publishes and consumes, and the systems and domains around it. Use it whenever the user wants to see or understand how something works or fits together, e.g. "show me how the Order Service works", "how does the Ordering domain fit together", "what does Payments talk to", or asks for a diagram, map or visual of something. Prefer it over drawing your own diagram. For domains and systems, pass detail "overview" for just the domains, systems and their relationships, or "full" (default) to include services, messages and channels.',
|
|
31
|
+
'"schema" shows the schema of a message (event, command or query) or other resource: its properties, types, descriptions and which ones are required. Use it whenever the user wants to see or understand a schema or payload, e.g. "show me the schema for OrderCreated", "what fields does PlaceOrder have", "what does the OrderShipped payload look like".',
|
|
32
|
+
'Clients that support MCP Apps show one viewer and switch it to each thing you show, so call this again to show the user something else. The result also contains what is shown (the diagram as Mermaid in mermaidCode, or the schema code) so you can understand it.',
|
|
33
|
+
'When the client shows the viewer, do not redraw the diagram or print the whole schema again in your reply: explain it and point out what matters. Otherwise, show the user the mermaidCode or the relevant parts of the schema code.',
|
|
34
|
+
].join(' ');
|
|
35
|
+
|
|
36
|
+
type McpServerOptions = {
|
|
37
|
+
/** Where this EventCatalog is served, for links from MCP App views back to it */
|
|
38
|
+
catalogUrl: string;
|
|
39
|
+
};
|
|
18
40
|
|
|
19
41
|
const catalogDirectory = process.env.PROJECT_DIR || process.cwd();
|
|
20
42
|
|
|
@@ -50,7 +72,7 @@ let extendedToolNames: string[] = [];
|
|
|
50
72
|
try {
|
|
51
73
|
const providerConfiguration = await import(/* @vite-ignore */ join(catalogDirectory, 'eventcatalog.chat.js'));
|
|
52
74
|
|
|
53
|
-
if (
|
|
75
|
+
if (providerConfiguration.tools) {
|
|
54
76
|
extendedTools = providerConfiguration.tools;
|
|
55
77
|
extendedToolNames = Object.keys(extendedTools);
|
|
56
78
|
}
|
|
@@ -58,12 +80,49 @@ try {
|
|
|
58
80
|
// No chat configuration or tools defined - this is fine
|
|
59
81
|
}
|
|
60
82
|
|
|
83
|
+
const MCP_SERVER_VERSION = '1.3.0';
|
|
84
|
+
|
|
85
|
+
// Every built-in tool only reads the catalog, so clients can safely auto-approve them
|
|
86
|
+
const readOnlyAnnotations = {
|
|
87
|
+
readOnlyHint: true,
|
|
88
|
+
destructiveHint: false,
|
|
89
|
+
idempotentHint: true,
|
|
90
|
+
openWorldHint: false,
|
|
91
|
+
} as const;
|
|
92
|
+
|
|
93
|
+
const optionalVersion = (resource: string) =>
|
|
94
|
+
z.string().optional().describe(`The version of the ${resource}. Omit it (or pass "latest") to use the latest version.`);
|
|
95
|
+
|
|
96
|
+
function getServerInstructions(scope?: McpScope) {
|
|
97
|
+
return [
|
|
98
|
+
'EventCatalog documents an event-driven architecture: domains, systems, services, agents, the messages they exchange (events, commands, queries), channels, flows, entities, data products, schemas, owners (teams and users) and custom documentation.',
|
|
99
|
+
...(scope
|
|
100
|
+
? [
|
|
101
|
+
`This server is scoped to the ${scope.name} ${scope.ref.kind} (version ${scope.ref.version}). Only resources inside this ${scope.ref.kind} are available.`,
|
|
102
|
+
]
|
|
103
|
+
: []),
|
|
104
|
+
'Resources are identified by an id and a version. Versions are optional on every tool: omit the version to use the latest version.',
|
|
105
|
+
'To find something, call getResources with a collection and a search term, then fetch the details with getResource. Use getSchemaForResource when you need a schema or OpenAPI/AsyncAPI specification for yourself, not to show it to the user.',
|
|
106
|
+
'When the user wants to see or understand how something works or fits together (e.g. "show me how the Order Service works"), call showResource with view "architecture": it shows them an interactive diagram. Do not draw your own diagram of the architecture.',
|
|
107
|
+
'When the user wants to see a schema, payload or the fields of a message (e.g. "show me the schema for OrderCreated"), call showResource with view "schema", not getSchemaForResource: it shows them an interactive schema viewer. Do not print the schema yourself.',
|
|
108
|
+
'For relationships use getMessagesProducedOrConsumedByResource, getProducersOfMessage and getConsumersOfMessage. Before changing a message, call analyzeChangeImpact to find the affected services, agents and owning teams.',
|
|
109
|
+
...(scope
|
|
110
|
+
? []
|
|
111
|
+
: [
|
|
112
|
+
'Use findResourcesByOwner, getTeam and getUser to find who owns something and how to contact them. Guides, runbooks and architecture notes live in custom documentation: use searchCustomDocs, then getCustomDoc.',
|
|
113
|
+
]),
|
|
114
|
+
].join('\n');
|
|
115
|
+
}
|
|
116
|
+
|
|
61
117
|
// Create MCP Server with tools that access Astro collections
|
|
62
|
-
function createMcpServer(scope
|
|
63
|
-
const server = new McpServer(
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
118
|
+
function createMcpServer(scope: McpScope | undefined, { catalogUrl }: McpServerOptions) {
|
|
119
|
+
const server = new McpServer(
|
|
120
|
+
{
|
|
121
|
+
name: scope ? `EventCatalog MCP Server — ${scope.name} ${scope.ref.kind}` : 'EventCatalog MCP Server',
|
|
122
|
+
version: MCP_SERVER_VERSION,
|
|
123
|
+
},
|
|
124
|
+
{ instructions: getServerInstructions(scope) }
|
|
125
|
+
);
|
|
67
126
|
|
|
68
127
|
const tools = scope ? createScopedCatalogTools(scope) : catalogTools;
|
|
69
128
|
|
|
@@ -71,12 +130,14 @@ function createMcpServer(scope?: McpScope) {
|
|
|
71
130
|
server.registerTool(
|
|
72
131
|
'getResources',
|
|
73
132
|
{
|
|
133
|
+
title: 'List catalog resources',
|
|
74
134
|
description: catalogTools.toolDescriptions.getResources,
|
|
75
135
|
inputSchema: z.object({
|
|
76
136
|
collection: catalogTools.collectionSchema.describe('The collection to get the resources from'),
|
|
77
137
|
cursor: z.string().optional().describe('Pagination cursor from previous response'),
|
|
78
138
|
search: z.string().optional().describe('Search term to filter resources by name, id, or summary (case-insensitive)'),
|
|
79
139
|
}),
|
|
140
|
+
annotations: readOnlyAnnotations,
|
|
80
141
|
},
|
|
81
142
|
createToolHandler(tools.getResources, 'Failed to get resources')
|
|
82
143
|
);
|
|
@@ -84,12 +145,14 @@ function createMcpServer(scope?: McpScope) {
|
|
|
84
145
|
server.registerTool(
|
|
85
146
|
'getResource',
|
|
86
147
|
{
|
|
148
|
+
title: 'Get a catalog resource',
|
|
87
149
|
description: catalogTools.toolDescriptions.getResource,
|
|
88
150
|
inputSchema: z.object({
|
|
89
151
|
collection: catalogTools.collectionSchema.describe('The collection to get the resource from'),
|
|
90
152
|
id: z.string().describe('The id of the resource to get'),
|
|
91
|
-
version:
|
|
153
|
+
version: optionalVersion('resource'),
|
|
92
154
|
}),
|
|
155
|
+
annotations: readOnlyAnnotations,
|
|
93
156
|
},
|
|
94
157
|
createToolHandler(tools.getResource, 'Failed to get resource')
|
|
95
158
|
);
|
|
@@ -97,14 +160,16 @@ function createMcpServer(scope?: McpScope) {
|
|
|
97
160
|
server.registerTool(
|
|
98
161
|
'getMessagesProducedOrConsumedByResource',
|
|
99
162
|
{
|
|
163
|
+
title: 'Get messages a resource sends and receives',
|
|
100
164
|
description: catalogTools.toolDescriptions.getMessagesProducedOrConsumedByResource,
|
|
101
165
|
inputSchema: z.object({
|
|
102
166
|
resourceId: z.string().describe('The id of the resource to get the messages produced or consumed for'),
|
|
103
|
-
resourceVersion:
|
|
167
|
+
resourceVersion: optionalVersion('resource'),
|
|
104
168
|
resourceCollection: catalogTools.resourceCollectionSchema
|
|
105
169
|
.describe('The collection of the resource to get the messages produced or consumed for')
|
|
106
170
|
.default('services'),
|
|
107
171
|
}),
|
|
172
|
+
annotations: readOnlyAnnotations,
|
|
108
173
|
},
|
|
109
174
|
createToolHandler(tools.getMessagesProducedOrConsumedByResource, 'Failed to get messages')
|
|
110
175
|
);
|
|
@@ -112,14 +177,16 @@ function createMcpServer(scope?: McpScope) {
|
|
|
112
177
|
server.registerTool(
|
|
113
178
|
'getSchemaForResource',
|
|
114
179
|
{
|
|
115
|
-
|
|
180
|
+
title: 'Get schemas and specifications',
|
|
181
|
+
description: `${catalogTools.toolDescriptions.getSchemaForResource}. To show the user a schema, use showResource with view "schema" instead: it shows them an interactive schema viewer.`,
|
|
116
182
|
inputSchema: z.object({
|
|
117
183
|
resourceId: z.string().describe('The id of the resource to get the schema for'),
|
|
118
|
-
resourceVersion:
|
|
184
|
+
resourceVersion: optionalVersion('resource'),
|
|
119
185
|
resourceCollection: catalogTools.resourceCollectionSchema
|
|
120
186
|
.describe('The collection of the resource to get the schema for')
|
|
121
187
|
.default('services'),
|
|
122
188
|
}),
|
|
189
|
+
annotations: readOnlyAnnotations,
|
|
123
190
|
},
|
|
124
191
|
createToolHandler(tools.getSchemaForResource, 'Failed to get schema')
|
|
125
192
|
);
|
|
@@ -127,10 +194,12 @@ function createMcpServer(scope?: McpScope) {
|
|
|
127
194
|
server.registerTool(
|
|
128
195
|
'findResourcesByOwner',
|
|
129
196
|
{
|
|
197
|
+
title: 'Find resources by owner',
|
|
130
198
|
description: catalogTools.toolDescriptions.findResourcesByOwner,
|
|
131
199
|
inputSchema: z.object({
|
|
132
200
|
ownerId: z.string().describe('The id of the owner (team or user) to find resources for'),
|
|
133
201
|
}),
|
|
202
|
+
annotations: readOnlyAnnotations,
|
|
134
203
|
},
|
|
135
204
|
createToolHandler(tools.findResourcesByOwner, 'Failed to find resources')
|
|
136
205
|
);
|
|
@@ -138,14 +207,16 @@ function createMcpServer(scope?: McpScope) {
|
|
|
138
207
|
server.registerTool(
|
|
139
208
|
'getProducersOfMessage',
|
|
140
209
|
{
|
|
210
|
+
title: 'Find producers of a message',
|
|
141
211
|
description: catalogTools.toolDescriptions.getProducersOfMessage,
|
|
142
212
|
inputSchema: z.object({
|
|
143
213
|
messageId: z.string().describe('The id of the message to find producers for'),
|
|
144
|
-
messageVersion:
|
|
214
|
+
messageVersion: optionalVersion('message'),
|
|
145
215
|
messageCollection: catalogTools.messageCollectionSchema
|
|
146
216
|
.describe('The collection type of the message (events, commands, or queries)')
|
|
147
217
|
.default('events'),
|
|
148
218
|
}),
|
|
219
|
+
annotations: readOnlyAnnotations,
|
|
149
220
|
},
|
|
150
221
|
createToolHandler(tools.getProducersOfMessage, 'Failed to get producers')
|
|
151
222
|
);
|
|
@@ -153,14 +224,16 @@ function createMcpServer(scope?: McpScope) {
|
|
|
153
224
|
server.registerTool(
|
|
154
225
|
'getConsumersOfMessage',
|
|
155
226
|
{
|
|
227
|
+
title: 'Find consumers of a message',
|
|
156
228
|
description: catalogTools.toolDescriptions.getConsumersOfMessage,
|
|
157
229
|
inputSchema: z.object({
|
|
158
230
|
messageId: z.string().describe('The id of the message to find consumers for'),
|
|
159
|
-
messageVersion:
|
|
231
|
+
messageVersion: optionalVersion('message'),
|
|
160
232
|
messageCollection: catalogTools.messageCollectionSchema
|
|
161
233
|
.describe('The collection type of the message (events, commands, or queries)')
|
|
162
234
|
.default('events'),
|
|
163
235
|
}),
|
|
236
|
+
annotations: readOnlyAnnotations,
|
|
164
237
|
},
|
|
165
238
|
createToolHandler(tools.getConsumersOfMessage, 'Failed to get consumers')
|
|
166
239
|
);
|
|
@@ -169,10 +242,12 @@ function createMcpServer(scope?: McpScope) {
|
|
|
169
242
|
server.registerTool(
|
|
170
243
|
'getC4Diagram',
|
|
171
244
|
{
|
|
245
|
+
title: 'Get C4 (LikeC4) diagrams',
|
|
172
246
|
description: catalogTools.toolDescriptions.getC4Diagram,
|
|
173
247
|
inputSchema: z.object({
|
|
174
248
|
viewId: z.string().describe('The id of the LikeC4 view to return source files for').optional(),
|
|
175
249
|
}),
|
|
250
|
+
annotations: readOnlyAnnotations,
|
|
176
251
|
},
|
|
177
252
|
createToolHandler(catalogTools.getC4Diagram, 'Failed to get c4 diagram')
|
|
178
253
|
);
|
|
@@ -181,14 +256,16 @@ function createMcpServer(scope?: McpScope) {
|
|
|
181
256
|
server.registerTool(
|
|
182
257
|
'analyzeChangeImpact',
|
|
183
258
|
{
|
|
259
|
+
title: 'Analyze the impact of changing a message',
|
|
184
260
|
description: catalogTools.toolDescriptions.analyzeChangeImpact,
|
|
185
261
|
inputSchema: z.object({
|
|
186
262
|
messageId: z.string().describe('The id of the message to analyze impact for'),
|
|
187
|
-
messageVersion:
|
|
263
|
+
messageVersion: optionalVersion('message'),
|
|
188
264
|
messageCollection: catalogTools.messageCollectionSchema
|
|
189
265
|
.describe('The collection type of the message (events, commands, or queries)')
|
|
190
266
|
.default('events'),
|
|
191
267
|
}),
|
|
268
|
+
annotations: readOnlyAnnotations,
|
|
192
269
|
},
|
|
193
270
|
createToolHandler(tools.analyzeChangeImpact, 'Failed to analyze impact')
|
|
194
271
|
);
|
|
@@ -196,11 +273,13 @@ function createMcpServer(scope?: McpScope) {
|
|
|
196
273
|
server.registerTool(
|
|
197
274
|
'explainBusinessFlow',
|
|
198
275
|
{
|
|
276
|
+
title: 'Explain a business flow',
|
|
199
277
|
description: catalogTools.toolDescriptions.explainBusinessFlow,
|
|
200
278
|
inputSchema: z.object({
|
|
201
279
|
flowId: z.string().describe('The id of the flow to explain'),
|
|
202
|
-
flowVersion:
|
|
280
|
+
flowVersion: optionalVersion('flow'),
|
|
203
281
|
}),
|
|
282
|
+
annotations: readOnlyAnnotations,
|
|
204
283
|
},
|
|
205
284
|
createToolHandler(tools.explainBusinessFlow, 'Failed to explain flow')
|
|
206
285
|
);
|
|
@@ -209,10 +288,12 @@ function createMcpServer(scope?: McpScope) {
|
|
|
209
288
|
server.registerTool(
|
|
210
289
|
'getTeams',
|
|
211
290
|
{
|
|
291
|
+
title: 'List teams',
|
|
212
292
|
description: catalogTools.toolDescriptions.getTeams,
|
|
213
293
|
inputSchema: z.object({
|
|
214
294
|
cursor: z.string().optional().describe('Pagination cursor from previous response'),
|
|
215
295
|
}),
|
|
296
|
+
annotations: readOnlyAnnotations,
|
|
216
297
|
},
|
|
217
298
|
createToolHandler(catalogTools.getTeams, 'Failed to get teams')
|
|
218
299
|
);
|
|
@@ -220,10 +301,12 @@ function createMcpServer(scope?: McpScope) {
|
|
|
220
301
|
server.registerTool(
|
|
221
302
|
'getTeam',
|
|
222
303
|
{
|
|
304
|
+
title: 'Get a team',
|
|
223
305
|
description: catalogTools.toolDescriptions.getTeam,
|
|
224
306
|
inputSchema: z.object({
|
|
225
307
|
id: z.string().describe('The id of the team to get'),
|
|
226
308
|
}),
|
|
309
|
+
annotations: readOnlyAnnotations,
|
|
227
310
|
},
|
|
228
311
|
createToolHandler(catalogTools.getTeam, 'Failed to get team')
|
|
229
312
|
);
|
|
@@ -231,10 +314,12 @@ function createMcpServer(scope?: McpScope) {
|
|
|
231
314
|
server.registerTool(
|
|
232
315
|
'getUsers',
|
|
233
316
|
{
|
|
317
|
+
title: 'List users',
|
|
234
318
|
description: catalogTools.toolDescriptions.getUsers,
|
|
235
319
|
inputSchema: z.object({
|
|
236
320
|
cursor: z.string().optional().describe('Pagination cursor from previous response'),
|
|
237
321
|
}),
|
|
322
|
+
annotations: readOnlyAnnotations,
|
|
238
323
|
},
|
|
239
324
|
createToolHandler(catalogTools.getUsers, 'Failed to get users')
|
|
240
325
|
);
|
|
@@ -242,18 +327,195 @@ function createMcpServer(scope?: McpScope) {
|
|
|
242
327
|
server.registerTool(
|
|
243
328
|
'getUser',
|
|
244
329
|
{
|
|
330
|
+
title: 'Get a user',
|
|
245
331
|
description: catalogTools.toolDescriptions.getUser,
|
|
246
332
|
inputSchema: z.object({
|
|
247
333
|
id: z.string().describe('The id of the user to get'),
|
|
248
334
|
}),
|
|
335
|
+
annotations: readOnlyAnnotations,
|
|
249
336
|
},
|
|
250
337
|
createToolHandler(catalogTools.getUser, 'Failed to get user')
|
|
251
338
|
);
|
|
252
339
|
}
|
|
253
340
|
|
|
341
|
+
// Icons served by EventCatalog don't load in the host's sandbox, so they are embedded in the diagram
|
|
342
|
+
const withInlineIcons = async ({ overview, hiddenMessages, ...graph }: ArchitectureDiagramView) => {
|
|
343
|
+
const publicDirectory = join(catalogDirectory, 'public');
|
|
344
|
+
const inline = async (level: Graph) => ({ ...level, nodes: await inlineNodeIcons(level.nodes, publicDirectory) });
|
|
345
|
+
return {
|
|
346
|
+
...(await inline(graph)),
|
|
347
|
+
...(overview && { overview: await inline(overview) }),
|
|
348
|
+
...(hiddenMessages && { hiddenMessages: await inline(hiddenMessages) }),
|
|
349
|
+
};
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
const getResourceName = async (diagram: { resourceCollection: string; resourceId: string; resourceVersion: string }) => {
|
|
353
|
+
const resource = await catalogTools.getResource({
|
|
354
|
+
collection: diagram.resourceCollection,
|
|
355
|
+
id: diagram.resourceId,
|
|
356
|
+
version: diagram.resourceVersion,
|
|
357
|
+
});
|
|
358
|
+
return ('data' in resource && resource.data.name) || diagram.resourceId;
|
|
359
|
+
};
|
|
360
|
+
|
|
361
|
+
// The diagram with its levels for the MCP App view, as the resource's Diagram page shows it
|
|
362
|
+
const getArchitectureDiagramPayload = async (diagram: {
|
|
363
|
+
resourceCollection: ArchitectureDiagramCollection;
|
|
364
|
+
resourceId: string;
|
|
365
|
+
resourceVersion: string;
|
|
366
|
+
visualiserUrl: string;
|
|
367
|
+
}): Promise<ArchitectureDiagramPayload> => ({
|
|
368
|
+
resource: {
|
|
369
|
+
collection: diagram.resourceCollection,
|
|
370
|
+
id: diagram.resourceId,
|
|
371
|
+
version: diagram.resourceVersion,
|
|
372
|
+
name: await getResourceName(diagram),
|
|
373
|
+
},
|
|
374
|
+
catalogUrl,
|
|
375
|
+
visualiserPath: diagram.visualiserUrl,
|
|
376
|
+
view: await withInlineIcons(
|
|
377
|
+
await getArchitectureDiagramView({
|
|
378
|
+
collection: diagram.resourceCollection,
|
|
379
|
+
id: diagram.resourceId,
|
|
380
|
+
version: diagram.resourceVersion,
|
|
381
|
+
})
|
|
382
|
+
),
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
// The resource's schemas, parsed for the view's JSON Schema, Avro and Protobuf viewers
|
|
386
|
+
const getSchemaViewerPayload = async (params: {
|
|
387
|
+
resourceId: string;
|
|
388
|
+
resourceVersion?: string;
|
|
389
|
+
resourceCollection: string;
|
|
390
|
+
}): Promise<SchemaViewerPayload | { error: string }> => {
|
|
391
|
+
const resource = await tools.getResource({
|
|
392
|
+
collection: params.resourceCollection,
|
|
393
|
+
id: params.resourceId,
|
|
394
|
+
version: params.resourceVersion,
|
|
395
|
+
});
|
|
396
|
+
if (resource.error !== undefined) return { error: resource.error };
|
|
397
|
+
|
|
398
|
+
const schemas = await tools.getSchemaForResource({ ...params, resourceVersion: resource.version });
|
|
399
|
+
if ('error' in schemas) return schemas;
|
|
400
|
+
|
|
401
|
+
return {
|
|
402
|
+
resource: {
|
|
403
|
+
collection: params.resourceCollection,
|
|
404
|
+
id: resource.id,
|
|
405
|
+
version: resource.version,
|
|
406
|
+
name: resource.data.name || resource.id,
|
|
407
|
+
},
|
|
408
|
+
catalogUrl,
|
|
409
|
+
docsPath: buildUrl(`/docs/${params.resourceCollection}/${resource.id}/${resource.version}`),
|
|
410
|
+
schemas: Array.isArray(schemas) ? toSchemaViewerSchemas(schemas) : [],
|
|
411
|
+
};
|
|
412
|
+
};
|
|
413
|
+
|
|
414
|
+
// Every collection that has an architecture diagram or a schema
|
|
415
|
+
const viewCollectionSchema = z.enum([
|
|
416
|
+
...new Set([...catalogTools.resourceCollectionSchema.options, ...catalogTools.visualiserCollectionSchema.options]),
|
|
417
|
+
] as [string, ...string[]]);
|
|
418
|
+
|
|
419
|
+
const resourceViewInput = {
|
|
420
|
+
view: z
|
|
421
|
+
.enum(RESOURCE_VIEWS)
|
|
422
|
+
.describe('What to show: "architecture" for an architecture diagram, "schema" for the schema of a message'),
|
|
423
|
+
resourceId: z.string().describe('The id of the resource to show'),
|
|
424
|
+
resourceVersion: optionalVersion('resource'),
|
|
425
|
+
resourceCollection: viewCollectionSchema.describe('The collection of the resource (defaults to events)').default('events'),
|
|
426
|
+
};
|
|
427
|
+
|
|
428
|
+
type ResourceViewParams = {
|
|
429
|
+
view: (typeof RESOURCE_VIEWS)[number];
|
|
430
|
+
resourceId: string;
|
|
431
|
+
resourceVersion?: string;
|
|
432
|
+
resourceCollection: string;
|
|
433
|
+
detail?: 'overview' | 'full';
|
|
434
|
+
};
|
|
435
|
+
|
|
436
|
+
const loadArchitectureView = async ({ view, ...params }: ResourceViewParams) => {
|
|
437
|
+
const result = await tools.getArchitectureDiagramAsMermaid(params);
|
|
438
|
+
if (result.error !== undefined) return { error: result.error };
|
|
439
|
+
return {
|
|
440
|
+
forModel: {
|
|
441
|
+
note: mcpAppNote('diagram', 'redraw it as Mermaid or ASCII', 'show the user the mermaidCode'),
|
|
442
|
+
view,
|
|
443
|
+
...result,
|
|
444
|
+
},
|
|
445
|
+
label: `the architecture diagram for ${result.resourceCollection}/${result.resourceId}`,
|
|
446
|
+
getPayload: async (): Promise<ViewerPayload> => ({
|
|
447
|
+
view: 'architecture',
|
|
448
|
+
diagram: await getArchitectureDiagramPayload(result),
|
|
449
|
+
}),
|
|
450
|
+
};
|
|
451
|
+
};
|
|
452
|
+
|
|
453
|
+
const loadSchemaView = async ({ view, ...params }: ResourceViewParams) => {
|
|
454
|
+
const payload = await getSchemaViewerPayload(params);
|
|
455
|
+
if ('error' in payload) return payload;
|
|
456
|
+
const { resource, schemas } = payload;
|
|
457
|
+
return {
|
|
458
|
+
// The model reads the schema code; the view gets it parsed for its Properties tab
|
|
459
|
+
forModel: {
|
|
460
|
+
note: mcpAppNote('schema', 'print the whole schema again', 'show the user the relevant parts of the code'),
|
|
461
|
+
view,
|
|
462
|
+
resourceId: resource.id,
|
|
463
|
+
resourceVersion: resource.version,
|
|
464
|
+
resourceCollection: resource.collection,
|
|
465
|
+
resource,
|
|
466
|
+
schemas: schemas.map(({ name, format, code }) => ({ name, format, code })),
|
|
467
|
+
...(schemas.length === 0 && { message: `${resource.name} has no schema` }),
|
|
468
|
+
},
|
|
469
|
+
label: `the schema for ${resource.collection}/${resource.id}`,
|
|
470
|
+
getPayload: async (): Promise<ViewerPayload> => ({ view: 'schema', schema: payload }),
|
|
471
|
+
};
|
|
472
|
+
};
|
|
473
|
+
|
|
474
|
+
registerMcpApp(server, {
|
|
475
|
+
loadView: loadViewerView,
|
|
476
|
+
resource: {
|
|
477
|
+
name: 'EventCatalog viewer',
|
|
478
|
+
uri: VIEWER_RESOURCE_URI,
|
|
479
|
+
description:
|
|
480
|
+
'Interactive EventCatalog viewer (architecture diagrams and schemas), shown by MCP hosts that support MCP Apps',
|
|
481
|
+
// Diagram nodes show icons (languages, databases...) served by this EventCatalog
|
|
482
|
+
csp: { resourceDomains: [catalogUrl] },
|
|
483
|
+
// Diagrams and schemas need the room, so hosts that can open the viewer full screen straight away
|
|
484
|
+
displayModes: { preferred: 'fullscreen', available: ['inline', 'fullscreen'] },
|
|
485
|
+
},
|
|
486
|
+
// One viewer per server: each result updates the viewer the host already shows
|
|
487
|
+
sessionId: scope ? `eventcatalog:${scope.ref.kind}:${scope.ref.id}` : 'eventcatalog',
|
|
488
|
+
metaKey: VIEWER_META_KEY,
|
|
489
|
+
tool: {
|
|
490
|
+
name: 'showResource',
|
|
491
|
+
title: 'Show a resource',
|
|
492
|
+
description: SHOW_RESOURCE_DESCRIPTION,
|
|
493
|
+
input: {
|
|
494
|
+
...resourceViewInput,
|
|
495
|
+
detail: z
|
|
496
|
+
.enum(['overview', 'full'])
|
|
497
|
+
.optional()
|
|
498
|
+
.describe(
|
|
499
|
+
'For view "architecture" of domains and systems: "overview" shows only domains, systems and their relationships; "full" (default) also shows services, messages and channels'
|
|
500
|
+
),
|
|
501
|
+
},
|
|
502
|
+
},
|
|
503
|
+
viewTool: {
|
|
504
|
+
name: VIEWER_VIEW_TOOL,
|
|
505
|
+
title: 'Load a resource for the viewer',
|
|
506
|
+
description:
|
|
507
|
+
'Loads the architecture diagram or schema shown by the EventCatalog viewer. To show the user a resource, use showResource instead.',
|
|
508
|
+
input: resourceViewInput,
|
|
509
|
+
},
|
|
510
|
+
annotations: readOnlyAnnotations,
|
|
511
|
+
errorMessage: 'Failed to show resource',
|
|
512
|
+
load: (params) => (params.view === 'schema' ? loadSchemaView(params) : loadArchitectureView(params)),
|
|
513
|
+
});
|
|
514
|
+
|
|
254
515
|
server.registerTool(
|
|
255
516
|
'findMessageBySchemaId',
|
|
256
517
|
{
|
|
518
|
+
title: 'Find a message from a schema',
|
|
257
519
|
description: catalogTools.toolDescriptions.findMessageBySchemaId,
|
|
258
520
|
inputSchema: z.object({
|
|
259
521
|
messageId: z.string().describe('The message id (from x-eventcatalog-id in the schema)'),
|
|
@@ -267,6 +529,7 @@ function createMcpServer(scope?: McpScope) {
|
|
|
267
529
|
.optional()
|
|
268
530
|
.describe('Optional hint for which collection to search (events, commands, or queries)'),
|
|
269
531
|
}),
|
|
532
|
+
annotations: readOnlyAnnotations,
|
|
270
533
|
},
|
|
271
534
|
createToolHandler(tools.findMessageBySchemaId, 'Failed to find message')
|
|
272
535
|
);
|
|
@@ -275,25 +538,57 @@ function createMcpServer(scope?: McpScope) {
|
|
|
275
538
|
server.registerTool(
|
|
276
539
|
'explainUbiquitousLanguageTerms',
|
|
277
540
|
{
|
|
541
|
+
title: 'Explain ubiquitous language terms',
|
|
278
542
|
description: catalogTools.toolDescriptions.explainUbiquitousLanguageTerms,
|
|
279
543
|
inputSchema: z.object({
|
|
280
544
|
domainId: z.string().describe('The id of the domain to get ubiquitous language terms for'),
|
|
281
|
-
domainVersion:
|
|
545
|
+
domainVersion: optionalVersion('domain'),
|
|
282
546
|
}),
|
|
547
|
+
annotations: readOnlyAnnotations,
|
|
283
548
|
},
|
|
284
549
|
createToolHandler(tools.explainUbiquitousLanguageTerms, 'Failed to get ubiquitous language terms')
|
|
285
550
|
);
|
|
286
551
|
}
|
|
287
552
|
|
|
288
553
|
if (!scope) {
|
|
554
|
+
server.registerTool(
|
|
555
|
+
'getDataProductInputs',
|
|
556
|
+
{
|
|
557
|
+
title: 'Get data product inputs',
|
|
558
|
+
description: catalogTools.toolDescriptions.getDataProductInputs,
|
|
559
|
+
inputSchema: z.object({
|
|
560
|
+
dataProductId: z.string().describe('The id of the data product'),
|
|
561
|
+
dataProductVersion: optionalVersion('data product'),
|
|
562
|
+
}),
|
|
563
|
+
annotations: readOnlyAnnotations,
|
|
564
|
+
},
|
|
565
|
+
createToolHandler(catalogTools.getDataProductInputs, 'Failed to get data product inputs')
|
|
566
|
+
);
|
|
567
|
+
|
|
568
|
+
server.registerTool(
|
|
569
|
+
'getDataProductOutputs',
|
|
570
|
+
{
|
|
571
|
+
title: 'Get data product outputs and contracts',
|
|
572
|
+
description: catalogTools.toolDescriptions.getDataProductOutputs,
|
|
573
|
+
inputSchema: z.object({
|
|
574
|
+
dataProductId: z.string().describe('The id of the data product'),
|
|
575
|
+
dataProductVersion: optionalVersion('data product'),
|
|
576
|
+
}),
|
|
577
|
+
annotations: readOnlyAnnotations,
|
|
578
|
+
},
|
|
579
|
+
createToolHandler(catalogTools.getDataProductOutputs, 'Failed to get data product outputs')
|
|
580
|
+
);
|
|
581
|
+
|
|
289
582
|
server.registerTool(
|
|
290
583
|
'getCustomDocs',
|
|
291
584
|
{
|
|
585
|
+
title: 'List custom documentation',
|
|
292
586
|
description: catalogTools.toolDescriptions.getCustomDocs,
|
|
293
587
|
inputSchema: z.object({
|
|
294
588
|
cursor: z.string().optional().describe('Pagination cursor from previous response'),
|
|
295
589
|
search: z.string().optional().describe('Search term to filter docs by title, id, or summary (case-insensitive)'),
|
|
296
590
|
}),
|
|
591
|
+
annotations: readOnlyAnnotations,
|
|
297
592
|
},
|
|
298
593
|
createToolHandler(catalogTools.getCustomDocs, 'Failed to get custom documentation pages')
|
|
299
594
|
);
|
|
@@ -301,11 +596,13 @@ function createMcpServer(scope?: McpScope) {
|
|
|
301
596
|
server.registerTool(
|
|
302
597
|
'searchCustomDocs',
|
|
303
598
|
{
|
|
599
|
+
title: 'Search custom documentation',
|
|
304
600
|
description: catalogTools.toolDescriptions.searchCustomDocs,
|
|
305
601
|
inputSchema: z.object({
|
|
306
602
|
query: z.string().describe('Full-text search query, e.g. keywords describing the topic to find'),
|
|
307
603
|
limit: z.number().optional().describe('Maximum number of results to return (default 10)'),
|
|
308
604
|
}),
|
|
605
|
+
annotations: readOnlyAnnotations,
|
|
309
606
|
},
|
|
310
607
|
createToolHandler(catalogTools.searchCustomDocs, 'Failed to search custom documentation')
|
|
311
608
|
);
|
|
@@ -313,11 +610,13 @@ function createMcpServer(scope?: McpScope) {
|
|
|
313
610
|
server.registerTool(
|
|
314
611
|
'getCustomDoc',
|
|
315
612
|
{
|
|
613
|
+
title: 'Get a custom documentation page',
|
|
316
614
|
description: catalogTools.toolDescriptions.getCustomDoc,
|
|
317
615
|
inputSchema: z.object({
|
|
318
616
|
id: z.string().describe('The id or slug of the custom documentation page'),
|
|
319
617
|
section: z.string().optional().describe('Optional section heading to return only that section of the page'),
|
|
320
618
|
}),
|
|
619
|
+
annotations: readOnlyAnnotations,
|
|
321
620
|
},
|
|
322
621
|
createToolHandler(catalogTools.getCustomDoc, 'Failed to get custom documentation page')
|
|
323
622
|
);
|
|
@@ -329,7 +628,7 @@ function createMcpServer(scope?: McpScope) {
|
|
|
329
628
|
|
|
330
629
|
// Extract tool properties (Vercel AI SDK format)
|
|
331
630
|
// The AI SDK tool() helper uses "inputSchema" for Zod schemas
|
|
332
|
-
const { description, parameters, inputSchema, execute } = toolConfig;
|
|
631
|
+
const { title, description, parameters, inputSchema, annotations, execute } = toolConfig;
|
|
333
632
|
|
|
334
633
|
if (!description || !execute) {
|
|
335
634
|
console.warn(`[MCP] Skipping invalid extended tool: ${toolName}`);
|
|
@@ -339,8 +638,10 @@ function createMcpServer(scope?: McpScope) {
|
|
|
339
638
|
server.registerTool(
|
|
340
639
|
toolName,
|
|
341
640
|
{
|
|
641
|
+
...(title && { title }),
|
|
342
642
|
description: description || `Custom tool: ${toolName}`,
|
|
343
643
|
inputSchema: inputSchema || parameters || z.object({}),
|
|
644
|
+
...(annotations && { annotations }),
|
|
344
645
|
},
|
|
345
646
|
async (params: any) => {
|
|
346
647
|
try {
|
|
@@ -537,7 +838,8 @@ function createMcpServer(scope?: McpScope) {
|
|
|
537
838
|
// "Stateless transport cannot be reused across requests" errors.
|
|
538
839
|
|
|
539
840
|
// Create Hono app for MCP routes
|
|
540
|
-
|
|
841
|
+
// Not strict, so /docs/mcp/ works too: MCP clients are often configured with a trailing slash
|
|
842
|
+
const app = new Hono({ strict: false }).basePath('/docs/mcp');
|
|
541
843
|
|
|
542
844
|
const globalBuiltInTools = [
|
|
543
845
|
'getResources',
|
|
@@ -556,17 +858,28 @@ const globalBuiltInTools = [
|
|
|
556
858
|
'getUser',
|
|
557
859
|
'findMessageBySchemaId',
|
|
558
860
|
'explainUbiquitousLanguageTerms',
|
|
861
|
+
'getDataProductInputs',
|
|
862
|
+
'getDataProductOutputs',
|
|
863
|
+
'showResource',
|
|
864
|
+
'getCustomDocs',
|
|
865
|
+
'searchCustomDocs',
|
|
866
|
+
'getCustomDoc',
|
|
867
|
+
];
|
|
868
|
+
|
|
869
|
+
const globalOnlyTools = [
|
|
870
|
+
'getC4Diagram',
|
|
871
|
+
'getTeams',
|
|
872
|
+
'getTeam',
|
|
873
|
+
'getUsers',
|
|
874
|
+
'getUser',
|
|
875
|
+
'getDataProductInputs',
|
|
876
|
+
'getDataProductOutputs',
|
|
559
877
|
'getCustomDocs',
|
|
560
878
|
'searchCustomDocs',
|
|
561
879
|
'getCustomDoc',
|
|
562
880
|
];
|
|
563
881
|
|
|
564
|
-
const scopedBuiltInTools = globalBuiltInTools.filter(
|
|
565
|
-
(tool) =>
|
|
566
|
-
!['getC4Diagram', 'getTeams', 'getTeam', 'getUsers', 'getUser', 'getCustomDocs', 'searchCustomDocs', 'getCustomDoc'].includes(
|
|
567
|
-
tool
|
|
568
|
-
)
|
|
569
|
-
);
|
|
882
|
+
const scopedBuiltInTools = globalBuiltInTools.filter((tool) => !globalOnlyTools.includes(tool));
|
|
570
883
|
|
|
571
884
|
const getScopedBuiltInTools = (scope: McpScope) =>
|
|
572
885
|
scope.ref.kind === 'system'
|
|
@@ -605,7 +918,7 @@ const getMcpResourceUris = (scope?: McpScope) =>
|
|
|
605
918
|
|
|
606
919
|
const getScopeRef = (c: Context, kind: McpScopeKind) => ({
|
|
607
920
|
kind,
|
|
608
|
-
id: c.req.param('id'),
|
|
921
|
+
id: c.req.param('id') ?? '',
|
|
609
922
|
version: c.req.param('version') || 'latest',
|
|
610
923
|
});
|
|
611
924
|
|
|
@@ -648,7 +961,7 @@ const handleGetRequest = async (c: Context, kind?: McpScopeKind) => {
|
|
|
648
961
|
const scope = await resolveRequestScope(c, kind);
|
|
649
962
|
return c.json({
|
|
650
963
|
name: scope ? `EventCatalog MCP Server — ${scope.name} ${scope.ref.kind}` : 'EventCatalog MCP Server',
|
|
651
|
-
version:
|
|
964
|
+
version: MCP_SERVER_VERSION,
|
|
652
965
|
status: 'running',
|
|
653
966
|
...(scope && { scope: scope.ref }),
|
|
654
967
|
tools: scope ? getScopedBuiltInTools(scope) : [...globalBuiltInTools, ...extendedToolNames],
|
|
@@ -670,7 +983,7 @@ const handleMcpRequest = async (c: Context, kind?: McpScopeKind) => {
|
|
|
670
983
|
}
|
|
671
984
|
|
|
672
985
|
const scope = await resolveRequestScope(c, kind);
|
|
673
|
-
const server = createMcpServer(scope);
|
|
986
|
+
const server = createMcpServer(scope, { catalogUrl: new URL(c.req.url).origin });
|
|
674
987
|
const transport = new WebStandardStreamableHTTPServerTransport({
|
|
675
988
|
sessionIdGenerator: undefined,
|
|
676
989
|
});
|
|
@@ -709,7 +1022,7 @@ for (const kind of ['domain', 'system'] as const) {
|
|
|
709
1022
|
app.post('/', (c: Context) => handleMcpRequest(c));
|
|
710
1023
|
|
|
711
1024
|
// Astro API route handler - delegates all requests to Hono
|
|
712
|
-
// Note: SSR
|
|
1025
|
+
// Note: SSR checks are handled at build time by the integration
|
|
713
1026
|
// This route is only injected when isEventCatalogMCPEnabled() returns true
|
|
714
1027
|
export const ALL: APIRoute = async ({ request }) => {
|
|
715
1028
|
return app.fetch(request);
|