@eventcatalog/core 5.2.1 → 5.4.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/dist/analytics/analytics.cjs +1 -1
- package/dist/analytics/analytics.js +2 -2
- package/dist/analytics/count-resources.cjs +10 -0
- package/dist/analytics/count-resources.js +1 -1
- package/dist/analytics/log-build.cjs +11 -1
- package/dist/analytics/log-build.js +4 -4
- package/dist/{chunk-VEQLCFU6.js → chunk-EPDVXHC7.js} +4 -4
- package/dist/{chunk-OVEXZEJJ.js → chunk-O2K4VPDO.js} +1 -1
- package/dist/{chunk-QSD6WMYE.js → chunk-OT2U5OES.js} +1 -1
- package/dist/{chunk-NCEZDQSW.js → chunk-OX6TSVHY.js} +8 -8
- package/dist/{chunk-HVCPU4V3.js → chunk-PAS36QHK.js} +1 -1
- package/dist/{chunk-MESHMXLR.js → chunk-TERJXCLK.js} +1 -1
- package/dist/{chunk-ZAZHAVKB.js → chunk-YRZK7HKX.js} +10 -0
- package/dist/constants.cjs +1 -1
- package/dist/constants.js +1 -1
- package/dist/docs/development/guides/fitness-functions/01-what-are-fitness-functions.md +116 -0
- package/dist/docs/development/guides/fitness-functions/02-create-fitness-function.md +222 -0
- package/dist/docs/development/guides/fitness-functions/03-global-and-resource-functions.md +198 -0
- package/dist/docs/development/guides/fitness-functions/04-run-in-ci.md +223 -0
- package/dist/docs/development/guides/fitness-functions/05-api-reference.md +271 -0
- package/dist/docs/development/guides/fitness-functions/06-examples.md +354 -0
- package/dist/docs/development/guides/fitness-functions/_category_.json +11 -0
- package/dist/eventcatalog.cjs +25 -1
- package/dist/eventcatalog.js +29 -15
- package/dist/federation/federate.js +5 -5
- package/dist/federation/source-provider.js +2 -2
- package/dist/generate.cjs +1 -1
- package/dist/generate.js +3 -3
- package/dist/runtime-dependencies/@eventcatalog__fitness.mjs +3 -0
- package/dist/runtime-dependencies/@modelcontextprotocol__client.mjs +3 -0
- package/dist/runtime-dependencies/@modelcontextprotocol__server.mjs +3 -0
- package/dist/runtime-dependencies/manifest.json +3 -4
- package/dist/utils/cli-logger.cjs +1 -1
- package/dist/utils/cli-logger.js +2 -2
- package/eventcatalog/src/features/mcp/apps/generated/canvas.html +73 -74
- package/eventcatalog/src/features/mcp/apps/generated/viewer.html +71 -73
- package/eventcatalog/src/features/mcp/apps/shared/app-view.tsx +1 -1
- package/eventcatalog/src/features/mcp/custom-tool-input.ts +38 -0
- package/eventcatalog/src/features/mcp/mcp-apps.ts +6 -4
- package/eventcatalog/src/features/mcp/mcp-server.ts +24 -17
- package/eventcatalog/src/features/studio/server/canvas-mcp.ts +2 -4
- package/package.json +9 -6
- package/dist/runtime-dependencies/@modelcontextprotocol__sdk.mjs +0 -3
- package/dist/runtime-dependencies/@modelcontextprotocol__sdk__server__mcp.js.mjs +0 -3
- package/dist/runtime-dependencies/@modelcontextprotocol__sdk__server__webStandardStreamableHttp.js.mjs +0 -3
- package/dist/runtime-dependencies/@modelcontextprotocol__sdk__types.js.mjs +0 -3
- package/eventcatalog/src/features/studio/server/tool-icons.ts +0 -30
- package/dist/{chunk-A2RZR3U4.js → chunk-6K7XZAYI.js} +3 -3
|
@@ -7,7 +7,7 @@ import { config as configureZod } from 'zod';
|
|
|
7
7
|
import { createRoot } from 'react-dom/client';
|
|
8
8
|
import type { App, McpUiHostContext } from '@modelcontextprotocol/ext-apps';
|
|
9
9
|
import { useApp } from '@modelcontextprotocol/ext-apps/react';
|
|
10
|
-
import type { CallToolResult } from '@modelcontextprotocol/
|
|
10
|
+
import type { CallToolResult } from '@modelcontextprotocol/client';
|
|
11
11
|
|
|
12
12
|
// MCP hosts block eval in views, so stop zod (used by the MCP Apps SDK) from probing for it
|
|
13
13
|
configureZod({ jitless: true });
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { fromJsonSchema, type JsonSchemaType, type StandardSchemaWithJSON } from '@modelcontextprotocol/server';
|
|
2
|
+
import { asSchema, type FlexibleSchema } from 'ai';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
|
|
5
|
+
/** Zod 4.2+ (and other Standard JSON Schema) schemas, which the MCP SDK lists and validates itself */
|
|
6
|
+
const hasJsonSchema = (schema: unknown): schema is StandardSchemaWithJSON =>
|
|
7
|
+
typeof schema === 'object' &&
|
|
8
|
+
schema !== null &&
|
|
9
|
+
typeof (schema as { '~standard'?: { jsonSchema?: { input?: unknown } } })['~standard']?.jsonSchema?.input === 'function';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* A custom tool's input schema (eventcatalog.chat.js, in the AI SDK's format) for the MCP SDK. Zod 4.2+ schemas are
|
|
13
|
+
* used as they are. The others the AI SDK takes (zod 3, jsonSchema()) are listed from their JSON Schema and validated
|
|
14
|
+
* by the schema itself, so coercion, defaults and transforms work as before: checking the JSON Schema first would turn
|
|
15
|
+
* away input the schema accepts, such as "5" for a coerced number. MCP SDK 2 can't list zod 3 schemas, and one failed
|
|
16
|
+
* tools/list for every tool.
|
|
17
|
+
*/
|
|
18
|
+
export const toCustomToolInput = async (schema: unknown): Promise<StandardSchemaWithJSON> => {
|
|
19
|
+
if (!schema) return z.object({});
|
|
20
|
+
if (hasJsonSchema(schema)) return schema;
|
|
21
|
+
|
|
22
|
+
const { jsonSchema, validate } = asSchema(schema as FlexibleSchema<unknown>);
|
|
23
|
+
const json = (await jsonSchema) as JsonSchemaType;
|
|
24
|
+
// jsonSchema() can leave out a validator, and then the arguments are checked against the JSON Schema
|
|
25
|
+
if (!validate) return fromJsonSchema(json);
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
'~standard': {
|
|
29
|
+
version: 1,
|
|
30
|
+
vendor: 'eventcatalog',
|
|
31
|
+
jsonSchema: { input: () => json, output: () => json },
|
|
32
|
+
validate: async (value) => {
|
|
33
|
+
const result = await validate(value);
|
|
34
|
+
return result.success ? { value: result.value } : { issues: [{ message: result.error.message }] };
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type { McpServer } from '@modelcontextprotocol/
|
|
2
|
-
import type { ToolAnnotations } from '@modelcontextprotocol/sdk/types.js';
|
|
1
|
+
import type { Icon, McpServer, ToolAnnotations } from '@modelcontextprotocol/server';
|
|
3
2
|
import type { McpUiDisplayMode } from '@modelcontextprotocol/ext-apps';
|
|
4
3
|
import { registerAppResource, RESOURCE_MIME_TYPE, RESOURCE_URI_META_KEY } from '@modelcontextprotocol/ext-apps/server';
|
|
5
4
|
import { z } from 'zod';
|
|
@@ -40,6 +39,8 @@ type ToolDefinition<Shape extends z.ZodRawShape> = {
|
|
|
40
39
|
input: Shape;
|
|
41
40
|
/** More `_meta` for the tool, e.g. host extensions such as ChatGPT's `openai/ui` entrypoints */
|
|
42
41
|
meta?: Record<string, unknown>;
|
|
42
|
+
/** Icons listed with the tool (MCP 2025-11-25 tool icons, which ChatGPT shows on entrypoints) */
|
|
43
|
+
icons?: Icon[];
|
|
43
44
|
};
|
|
44
45
|
|
|
45
46
|
export type McpAppDefinition<Shape extends z.ZodRawShape, ViewShape extends z.ZodRawShape, Payload> = {
|
|
@@ -106,13 +107,14 @@ export function registerMcpApp<Shape extends z.ZodRawShape, ViewShape extends z.
|
|
|
106
107
|
};
|
|
107
108
|
|
|
108
109
|
const toolInput = z.object(app.tool.input);
|
|
109
|
-
server.registerTool
|
|
110
|
+
server.registerTool(
|
|
110
111
|
app.tool.name,
|
|
111
112
|
{
|
|
112
113
|
title: app.tool.title,
|
|
113
114
|
description: app.tool.description,
|
|
114
115
|
inputSchema: toolInput,
|
|
115
116
|
annotations: app.annotations,
|
|
117
|
+
...(app.tool.icons && { icons: app.tool.icons }),
|
|
116
118
|
_meta: loadView ? { ...appViewMeta(app.resource.uri), ...app.tool.meta } : undefined,
|
|
117
119
|
},
|
|
118
120
|
showInView
|
|
@@ -130,7 +132,7 @@ export function registerMcpApp<Shape extends z.ZodRawShape, ViewShape extends z.
|
|
|
130
132
|
};
|
|
131
133
|
|
|
132
134
|
const viewToolInput = z.object(app.viewTool.input);
|
|
133
|
-
server.registerTool
|
|
135
|
+
server.registerTool(
|
|
134
136
|
app.viewTool.name,
|
|
135
137
|
{
|
|
136
138
|
title: app.viewTool.title,
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { APIRoute } from 'astro';
|
|
2
2
|
import { Hono, type Context } from 'hono';
|
|
3
|
-
import { McpServer } from '@modelcontextprotocol/
|
|
4
|
-
import { WebStandardStreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js';
|
|
3
|
+
import { McpServer, WebStandardStreamableHTTPServerTransport, type StandardSchemaWithJSON } from '@modelcontextprotocol/server';
|
|
5
4
|
import { z } from 'zod';
|
|
6
5
|
import { join } from 'node:path';
|
|
7
6
|
import * as catalogTools from '@features/tools/catalog-tools';
|
|
@@ -21,6 +20,7 @@ import type { SchemaViewerPayload } from './apps/schema-viewer/shared';
|
|
|
21
20
|
import { RESOURCE_VIEWS, VIEWER_META_KEY, VIEWER_RESOURCE_URI, VIEWER_VIEW_TOOL, type ViewerPayload } from './apps/viewer/shared';
|
|
22
21
|
import { toSchemaViewerSchemas } from './schema-viewer';
|
|
23
22
|
import { getMcpAppViewLoader, mcpAppNote, registerMcpApp } from './mcp-apps';
|
|
23
|
+
import { toCustomToolInput } from './custom-tool-input';
|
|
24
24
|
import { buildUrl } from '@utils/url-builder';
|
|
25
25
|
import { isCanvasEnabled } from '@utils/feature';
|
|
26
26
|
import { CANVAS_TOOL_NAMES, registerCanvasTools } from '@features/studio/server/canvas-mcp';
|
|
@@ -74,19 +74,34 @@ function createToolHandler<T>(fn: (params: T) => Promise<any>, errorMessage: str
|
|
|
74
74
|
|
|
75
75
|
// Load extended tools from user configuration
|
|
76
76
|
let extendedTools: Record<string, any> = {};
|
|
77
|
-
let extendedToolNames: string[] = [];
|
|
78
77
|
|
|
79
78
|
try {
|
|
80
79
|
const providerConfiguration = await import(/* @vite-ignore */ join(catalogDirectory, 'eventcatalog.chat.js'));
|
|
81
80
|
|
|
82
81
|
if (providerConfiguration.tools) {
|
|
83
82
|
extendedTools = providerConfiguration.tools;
|
|
84
|
-
extendedToolNames = Object.keys(extendedTools);
|
|
85
83
|
}
|
|
86
84
|
} catch (error) {
|
|
87
85
|
// No chat configuration or tools defined - this is fine
|
|
88
86
|
}
|
|
89
87
|
|
|
88
|
+
// The extended tools the MCP server offers, each with its input for the MCP SDK. Worked out once (converting a
|
|
89
|
+
// schema can be async), so the tools registered and the tools listed by GET /docs/mcp are the same ones.
|
|
90
|
+
const extendedToolInputs = new Map<string, StandardSchemaWithJSON>();
|
|
91
|
+
for (const [toolName, toolConfig] of Object.entries(extendedTools)) {
|
|
92
|
+
if (!toolConfig || typeof toolConfig !== 'object') continue;
|
|
93
|
+
if (!toolConfig.description || !toolConfig.execute) {
|
|
94
|
+
console.warn(`[MCP] Skipping invalid extended tool: ${toolName}`);
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
try {
|
|
98
|
+
extendedToolInputs.set(toolName, await toCustomToolInput(toolConfig.inputSchema || toolConfig.parameters));
|
|
99
|
+
} catch (error) {
|
|
100
|
+
console.warn(`[MCP] Skipping extended tool ${toolName}: its input schema could not be read (${error})`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const extendedToolNames = [...extendedToolInputs.keys()];
|
|
104
|
+
|
|
90
105
|
const MCP_SERVER_VERSION = '1.3.0';
|
|
91
106
|
|
|
92
107
|
// Every built-in tool only reads the catalog, so clients can safely auto-approve them
|
|
@@ -633,24 +648,16 @@ function createMcpServer(
|
|
|
633
648
|
}
|
|
634
649
|
|
|
635
650
|
// Register extended tools from user configuration
|
|
636
|
-
for (const [toolName,
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
// Extract tool properties (Vercel AI SDK format)
|
|
640
|
-
// The AI SDK tool() helper uses "inputSchema" for Zod schemas
|
|
641
|
-
const { title, description, parameters, inputSchema, annotations, execute } = toolConfig;
|
|
642
|
-
|
|
643
|
-
if (!description || !execute) {
|
|
644
|
-
console.warn(`[MCP] Skipping invalid extended tool: ${toolName}`);
|
|
645
|
-
continue;
|
|
646
|
-
}
|
|
651
|
+
for (const [toolName, input] of scope ? [] : extendedToolInputs) {
|
|
652
|
+
// Tool properties in the Vercel AI SDK format
|
|
653
|
+
const { title, description, annotations, execute } = extendedTools[toolName];
|
|
647
654
|
|
|
648
655
|
server.registerTool(
|
|
649
656
|
toolName,
|
|
650
657
|
{
|
|
651
658
|
...(title && { title }),
|
|
652
|
-
description
|
|
653
|
-
inputSchema:
|
|
659
|
+
description,
|
|
660
|
+
inputSchema: input,
|
|
654
661
|
...(annotations && { annotations }),
|
|
655
662
|
},
|
|
656
663
|
async (params: any) => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { McpServer } from '@modelcontextprotocol/
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/server';
|
|
2
2
|
import type * as Y from 'yjs';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
import { buildUrl } from '@utils/url-builder';
|
|
@@ -37,7 +37,6 @@ import {
|
|
|
37
37
|
} from '../agent-choreography';
|
|
38
38
|
import { STUDIO_SOCKET_PATH, findStudioRuntime } from './runtime';
|
|
39
39
|
import { getAgent } from '../agents';
|
|
40
|
-
import { addToolIcons } from './tool-icons';
|
|
41
40
|
|
|
42
41
|
/**
|
|
43
42
|
* MCP tools for the collaborative canvas: agents create canvases, join the ones people are on, and
|
|
@@ -139,6 +138,7 @@ export function registerCanvasTools(server: McpServer, { catalogUrl, userAgent }
|
|
|
139
138
|
// ChatGPT entrypoints (OpenAI MCP extensions): people can open canvases from the sidebar or as a tab in a
|
|
140
139
|
// thread, which calls the tool with {} (the list of canvases)
|
|
141
140
|
meta: { 'openai/ui': { entrypoints: [{ type: 'global' }, { type: 'thread' }] } },
|
|
141
|
+
icons: [CANVAS_ICON],
|
|
142
142
|
input: {
|
|
143
143
|
canvasId: canvasId.optional(),
|
|
144
144
|
title: z.string().optional().describe('For a new canvas: what it is for'),
|
|
@@ -490,6 +490,4 @@ export function registerCanvasTools(server: McpServer, { catalogUrl, userAgent }
|
|
|
490
490
|
return found ? text({ threadId, resolved }) : text({ error: `No comment thread "${threadId}"` }, true);
|
|
491
491
|
}
|
|
492
492
|
);
|
|
493
|
-
|
|
494
|
-
addToolIcons(server, { openCanvas: [CANVAS_ICON] });
|
|
495
493
|
}
|
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
},
|
|
8
8
|
"license": "BUSL-1.1",
|
|
9
9
|
"type": "module",
|
|
10
|
-
"version": "5.
|
|
10
|
+
"version": "5.4.0",
|
|
11
11
|
"publishConfig": {
|
|
12
12
|
"access": "public"
|
|
13
13
|
},
|
|
@@ -65,8 +65,9 @@
|
|
|
65
65
|
"@iconify-json/logos": "^1.2.4",
|
|
66
66
|
"@mcp-b/webmcp-polyfill": "5.1.0",
|
|
67
67
|
"@mermaid-js/layout-elk": "^0.2.0",
|
|
68
|
-
"@modelcontextprotocol/
|
|
69
|
-
"@modelcontextprotocol/
|
|
68
|
+
"@modelcontextprotocol/client": "2.3.1",
|
|
69
|
+
"@modelcontextprotocol/ext-apps": "2.0.3",
|
|
70
|
+
"@modelcontextprotocol/server": "2.3.1",
|
|
70
71
|
"@nanostores/react": "^1.0.0",
|
|
71
72
|
"@parcel/watcher": "^2.4.1",
|
|
72
73
|
"@radix-ui/react-context-menu": "^2.2.6",
|
|
@@ -140,9 +141,10 @@
|
|
|
140
141
|
"y-protocols": "^1.0.7",
|
|
141
142
|
"yjs": "^13.6.33",
|
|
142
143
|
"zod": "^4.6.6",
|
|
143
|
-
"@eventcatalog/
|
|
144
|
-
"@eventcatalog/
|
|
145
|
-
"@eventcatalog/
|
|
144
|
+
"@eventcatalog/fitness": "0.1.0",
|
|
145
|
+
"@eventcatalog/sdk": "2.31.2",
|
|
146
|
+
"@eventcatalog/linter": "1.2.4",
|
|
147
|
+
"@eventcatalog/exporters": "0.1.2",
|
|
146
148
|
"@eventcatalog/visualiser": "^5.0.0"
|
|
147
149
|
},
|
|
148
150
|
"devDependencies": {
|
|
@@ -188,6 +190,7 @@
|
|
|
188
190
|
"start:catalog:server": "node scripts/start-server-locally.js",
|
|
189
191
|
"preview:catalog": "node scripts/preview-catalog-locally.js",
|
|
190
192
|
"generate:catalog": "node scripts/generate-catalog-locally.js",
|
|
193
|
+
"fitness:catalog": "node scripts/fitness-catalog-locally.js",
|
|
191
194
|
"verify-build:catalog": "rimraf dist && pnpm run build:cd",
|
|
192
195
|
"generate": "pnpm run build:bin && npx . generate",
|
|
193
196
|
"format": "prettier --config .prettierrc --write \"**/*.{js,jsx,ts,tsx,json,astro}\"",
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
-
|
|
3
|
-
/** A tool icon (MCP 2025-11-25) */
|
|
4
|
-
export type ToolIcon = { src: string; mimeType?: string; sizes?: string[] };
|
|
5
|
-
type ListTools = (request: unknown, extra: unknown) => Promise<{ tools: { name: string }[] }>;
|
|
6
|
-
|
|
7
|
-
/** The SDK's request handlers (private in SDK 1.x, so checked rather than assumed) */
|
|
8
|
-
const getRequestHandlers = (server: McpServer): Map<string, ListTools> | undefined => {
|
|
9
|
-
const handlers: unknown = Reflect.get(server.server, '_requestHandlers');
|
|
10
|
-
return handlers instanceof Map ? handlers : undefined;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Adds icons to tools in tools/list (MCP 2025-11-25 tool icons, which ChatGPT shows on entrypoints). The MCP
|
|
15
|
-
* TypeScript SDK 1.x doesn't list tool icons, so this wraps its tools/list handler. If a new SDK changes how
|
|
16
|
-
* it keeps handlers, tools are listed without icons and this says so.
|
|
17
|
-
*/
|
|
18
|
-
export const addToolIcons = (server: McpServer, icons: Record<string, ToolIcon[]>) => {
|
|
19
|
-
const handlers = getRequestHandlers(server);
|
|
20
|
-
const listTools = handlers?.get('tools/list');
|
|
21
|
-
if (!handlers || !listTools) {
|
|
22
|
-
console.warn('[EventCatalog MCP] Could not add tool icons: the MCP SDK no longer exposes its tools/list handler');
|
|
23
|
-
return false;
|
|
24
|
-
}
|
|
25
|
-
handlers.set('tools/list', async (request, extra) => {
|
|
26
|
-
const result = await listTools(request, extra);
|
|
27
|
-
return { ...result, tools: result.tools.map((tool) => (icons[tool.name] ? { ...tool, icons: icons[tool.name] } : tool)) };
|
|
28
|
-
});
|
|
29
|
-
return true;
|
|
30
|
-
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createFileSystemSourceProvider
|
|
3
|
-
} from "./chunk-SDZQJTJW.js";
|
|
4
1
|
import {
|
|
5
2
|
createGitHubSourceProvider
|
|
6
3
|
} from "./chunk-352FGP6W.js";
|
|
4
|
+
import {
|
|
5
|
+
createFileSystemSourceProvider
|
|
6
|
+
} from "./chunk-SDZQJTJW.js";
|
|
7
7
|
|
|
8
8
|
// src/federation/source-provider.ts
|
|
9
9
|
var createFederationSourceProvider = (projectDirectory, providers = {}) => {
|