@fractalizer/mcp-core 0.1.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 (111) hide show
  1. package/README.md +398 -0
  2. package/dist/definition/definition-validator.d.ts +102 -0
  3. package/dist/definition/definition-validator.d.ts.map +1 -0
  4. package/dist/definition/definition-validator.js +151 -0
  5. package/dist/definition/definition-validator.js.map +1 -0
  6. package/dist/definition/index.d.ts +16 -0
  7. package/dist/definition/index.d.ts.map +1 -0
  8. package/dist/definition/index.js +19 -0
  9. package/dist/definition/index.js.map +1 -0
  10. package/dist/definition/schema-to-definition.d.ts +131 -0
  11. package/dist/definition/schema-to-definition.d.ts.map +1 -0
  12. package/dist/definition/schema-to-definition.js +124 -0
  13. package/dist/definition/schema-to-definition.js.map +1 -0
  14. package/dist/definition/zod-json-schema-adapter.d.ts +87 -0
  15. package/dist/definition/zod-json-schema-adapter.d.ts.map +1 -0
  16. package/dist/definition/zod-json-schema-adapter.js +121 -0
  17. package/dist/definition/zod-json-schema-adapter.js.map +1 -0
  18. package/dist/index.d.ts +6 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +10 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/tool-registry/index.d.ts +9 -0
  23. package/dist/tool-registry/index.d.ts.map +1 -0
  24. package/dist/tool-registry/index.js +8 -0
  25. package/dist/tool-registry/index.js.map +1 -0
  26. package/dist/tool-registry/tool-filter.service.d.ts +45 -0
  27. package/dist/tool-registry/tool-filter.service.d.ts.map +1 -0
  28. package/dist/tool-registry/tool-filter.service.js +174 -0
  29. package/dist/tool-registry/tool-filter.service.js.map +1 -0
  30. package/dist/tool-registry/tool-registry.d.ts +99 -0
  31. package/dist/tool-registry/tool-registry.d.ts.map +1 -0
  32. package/dist/tool-registry/tool-registry.js +253 -0
  33. package/dist/tool-registry/tool-registry.js.map +1 -0
  34. package/dist/tool-registry/tool-sorter.d.ts +41 -0
  35. package/dist/tool-registry/tool-sorter.d.ts.map +1 -0
  36. package/dist/tool-registry/tool-sorter.js +79 -0
  37. package/dist/tool-registry/tool-sorter.js.map +1 -0
  38. package/dist/tool-registry/types.d.ts +29 -0
  39. package/dist/tool-registry/types.d.ts.map +1 -0
  40. package/dist/tool-registry/types.js +14 -0
  41. package/dist/tool-registry/types.js.map +1 -0
  42. package/dist/tools/base/base-definition.d.ts +114 -0
  43. package/dist/tools/base/base-definition.d.ts.map +1 -0
  44. package/dist/tools/base/base-definition.js +153 -0
  45. package/dist/tools/base/base-definition.js.map +1 -0
  46. package/dist/tools/base/base-tool.d.ts +134 -0
  47. package/dist/tools/base/base-tool.d.ts.map +1 -0
  48. package/dist/tools/base/base-tool.js +215 -0
  49. package/dist/tools/base/base-tool.js.map +1 -0
  50. package/dist/tools/base/base.types.d.ts +28 -0
  51. package/dist/tools/base/base.types.d.ts.map +1 -0
  52. package/dist/tools/base/base.types.js +8 -0
  53. package/dist/tools/base/base.types.js.map +1 -0
  54. package/dist/tools/base/index.d.ts +9 -0
  55. package/dist/tools/base/index.d.ts.map +1 -0
  56. package/dist/tools/base/index.js +7 -0
  57. package/dist/tools/base/index.js.map +1 -0
  58. package/dist/tools/base/tool-metadata.d.ts +117 -0
  59. package/dist/tools/base/tool-metadata.d.ts.map +1 -0
  60. package/dist/tools/base/tool-metadata.js +56 -0
  61. package/dist/tools/base/tool-metadata.js.map +1 -0
  62. package/dist/tools/common/index.d.ts +6 -0
  63. package/dist/tools/common/index.d.ts.map +1 -0
  64. package/dist/tools/common/index.js +6 -0
  65. package/dist/tools/common/index.js.map +1 -0
  66. package/dist/tools/common/schemas/fields.schema.d.ts +41 -0
  67. package/dist/tools/common/schemas/fields.schema.d.ts.map +1 -0
  68. package/dist/tools/common/schemas/fields.schema.js +40 -0
  69. package/dist/tools/common/schemas/fields.schema.js.map +1 -0
  70. package/dist/tools/common/schemas/index.d.ts +6 -0
  71. package/dist/tools/common/schemas/index.d.ts.map +1 -0
  72. package/dist/tools/common/schemas/index.js +5 -0
  73. package/dist/tools/common/schemas/index.js.map +1 -0
  74. package/dist/tools/common/utils/index.d.ts +6 -0
  75. package/dist/tools/common/utils/index.d.ts.map +1 -0
  76. package/dist/tools/common/utils/index.js +6 -0
  77. package/dist/tools/common/utils/index.js.map +1 -0
  78. package/dist/tools/common/utils/safety-warning-builder.d.ts +42 -0
  79. package/dist/tools/common/utils/safety-warning-builder.d.ts.map +1 -0
  80. package/dist/tools/common/utils/safety-warning-builder.js +60 -0
  81. package/dist/tools/common/utils/safety-warning-builder.js.map +1 -0
  82. package/dist/tools/common/utils/tool-name.d.ts +22 -0
  83. package/dist/tools/common/utils/tool-name.d.ts.map +1 -0
  84. package/dist/tools/common/utils/tool-name.js +34 -0
  85. package/dist/tools/common/utils/tool-name.js.map +1 -0
  86. package/dist/tsconfig.tsbuildinfo +1 -0
  87. package/dist/utils/batch-result-processor.d.ts +59 -0
  88. package/dist/utils/batch-result-processor.d.ts.map +1 -0
  89. package/dist/utils/batch-result-processor.js +86 -0
  90. package/dist/utils/batch-result-processor.js.map +1 -0
  91. package/dist/utils/index.d.ts +10 -0
  92. package/dist/utils/index.d.ts.map +1 -0
  93. package/dist/utils/index.js +6 -0
  94. package/dist/utils/index.js.map +1 -0
  95. package/dist/utils/response-field-filter.d.ts +102 -0
  96. package/dist/utils/response-field-filter.d.ts.map +1 -0
  97. package/dist/utils/response-field-filter.js +284 -0
  98. package/dist/utils/response-field-filter.js.map +1 -0
  99. package/dist/utils/result-logger.d.ts +49 -0
  100. package/dist/utils/result-logger.d.ts.map +1 -0
  101. package/dist/utils/result-logger.js +54 -0
  102. package/dist/utils/result-logger.js.map +1 -0
  103. package/dist/utils/tool-registration-validator.d.ts +86 -0
  104. package/dist/utils/tool-registration-validator.d.ts.map +1 -0
  105. package/dist/utils/tool-registration-validator.js +207 -0
  106. package/dist/utils/tool-registration-validator.js.map +1 -0
  107. package/dist/utils/zod-error-formatter.d.ts +58 -0
  108. package/dist/utils/zod-error-formatter.d.ts.map +1 -0
  109. package/dist/utils/zod-error-formatter.js +174 -0
  110. package/dist/utils/zod-error-formatter.js.map +1 -0
  111. package/package.json +75 -0
package/README.md ADDED
@@ -0,0 +1,398 @@
1
+ # @fractalizer/mcp-core
2
+
3
+ **Core framework for building MCP tools: base classes, utilities, registry**
4
+
5
+ [![npm version](https://img.shields.io/npm/v/@fractalizer/mcp-core.svg)](https://www.npmjs.com/package/@fractalizer/mcp-core)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ ---
9
+
10
+ ## 🎯 Purpose
11
+
12
+ **Principle:** Core provides reusable base classes and utilities for building MCP tools
13
+
14
+ **Generic Design:** `BaseTool<TFacade>` is facade-agnostic — works with any API facade
15
+
16
+ **Architecture rule:** Core depends ONLY on `@fractalizer/mcp-infrastructure`
17
+
18
+ ---
19
+
20
+ ## ⚠️ Scope Restrictions
21
+
22
+ Этот пакет содержит **ТОЛЬКО** инфраструктуру для MCP tools:
23
+
24
+ | ✅ Входит в scope | ❌ НЕ входит в scope |
25
+ |-------------------|---------------------|
26
+ | `BaseTool` и связанные типы | HTTP клиенты → `@fractalizer/mcp-infrastructure` |
27
+ | `ToolRegistry` и фильтрация | CLI логика → `@fractalizer/mcp-cli` |
28
+ | Schema → Definition генерация | Поиск tools → `@fractalizer/mcp-search` |
29
+ | Утилиты для результатов tools | Бизнес-логика серверов → `packages/servers/*` |
30
+ | Общие Zod-схемы для tools | Logging, caching → `@fractalizer/mcp-infrastructure` |
31
+
32
+ **Правило:** Если функционал не связан напрямую с созданием/регистрацией/выполнением MCP tools — ему здесь не место
33
+
34
+ ---
35
+
36
+ ## 📦 Installation
37
+
38
+ ```bash
39
+ npm install @fractalizer/mcp-core
40
+ ```
41
+
42
+ **Dependencies:**
43
+ - `@fractalizer/mcp-infrastructure` (HTTP, logging, config)
44
+ - `@modelcontextprotocol/sdk` (MCP protocol)
45
+ - `zod` (validation)
46
+
47
+ ---
48
+
49
+ ## 📁 Structure
50
+
51
+ ```
52
+ src/
53
+ ├── definition/ # Schema-to-Definition generation
54
+ │ ├── schema-to-definition.ts # Auto-generate definitions from Zod
55
+ │ ├── definition-validator.ts # ToolDefinition validation
56
+ │ └── zod-json-schema-adapter.ts # Zod → JSON Schema converter
57
+ ├── tool-registry/ # Tool registration and filtering
58
+ │ ├── tool-registry.ts # Tool registration and routing
59
+ │ ├── tool-filter.service.ts # Category/subcategory filtering
60
+ │ ├── tool-sorter.ts # Priority-based sorting
61
+ │ └── types.ts # Registry types
62
+ ├── tools/
63
+ │ ├── base/ # Base classes for tools
64
+ │ │ ├── base-tool.ts # Generic BaseTool<TSchema>
65
+ │ │ └── tool-metadata.ts # StaticToolMetadata interface
66
+ │ └── common/ # Common utilities
67
+ │ ├── schemas/ # Reusable Zod schemas
68
+ │ └── utils/ # Tool utilities
69
+ ├── utils/ # General utilities
70
+ │ ├── response-field-filter.ts # Filter response fields
71
+ │ ├── batch-result-processor.ts # Process batch results
72
+ │ └── result-logger.ts # Log tool results
73
+ └── index.ts # Public exports
74
+ ```
75
+
76
+ ---
77
+
78
+ ## 🔧 Core Components
79
+
80
+ ### BaseTool<TFacade>
81
+
82
+ **Generic base class** for creating MCP tools that work with any API facade.
83
+
84
+ **Key features:**
85
+ - ✅ Generic `<TFacade>` — facade-agnostic design
86
+ - ✅ Automatic parameter validation (Zod schemas via `getParamsSchema()`)
87
+ - ✅ Auto-generates MCP definitions from schema (DRY principle)
88
+ - ✅ Built-in logging, error handling
89
+ - ✅ Integration with ToolRegistry
90
+
91
+ **Implementation:** [src/tools/base/base-tool.ts](src/tools/base/base-tool.ts)
92
+
93
+ **Abstract interface:**
94
+ ```typescript
95
+ abstract class BaseTool<TFacade = unknown> {
96
+ static readonly METADATA: StaticToolMetadata; // Required!
97
+
98
+ constructor(facade: TFacade, logger: Logger);
99
+
100
+ getDefinition(): ToolDefinition; // Auto-generated from schema
101
+ getParamsSchema?(): ZodSchema; // Optional: enables auto-generation
102
+ abstract execute(params: unknown): Promise<ToolResult>;
103
+ }
104
+ ```
105
+
106
+ **Reference implementation:** See any tool in `packages/servers/yandex-tracker/src/tools/api/` (e.g., `issues/get/get-issues.tool.ts`)
107
+
108
+ ### generateDefinitionFromSchema()
109
+
110
+ **✅ Auto-generates MCP definitions from Zod schemas** (eliminates schema-definition mismatch)
111
+
112
+ **Key features:**
113
+ - ✅ Single source of truth (Zod schema with `.describe()`)
114
+ - ✅ Uses Zod v4 native `schema.toJSONSchema()` API
115
+ - ✅ Automatic required/optional field detection
116
+ - ✅ Physically impossible to create schema ↔ definition mismatch
117
+
118
+ **Implementation:** [src/definition/schema-to-definition.ts](src/definition/schema-to-definition.ts)
119
+
120
+ **Function signature:**
121
+ ```typescript
122
+ function generateDefinitionFromSchema(
123
+ schema: ZodSchema,
124
+ options?: { includeDescriptions?: boolean }
125
+ ): JSONSchema7
126
+ ```
127
+
128
+ **Benefits:** DRY principle, type-safe, no separate `*.definition.ts` files
129
+
130
+ **Migration guide:** [../../ARCHITECTURE.md](../../ARCHITECTURE.md) → "Schema-to-Definition Generator"
131
+
132
+ ---
133
+
134
+ ### BaseDefinition (Deprecated)
135
+
136
+ **⚠️ Deprecated** in v2.0 — use `generateDefinitionFromSchema()` instead.
137
+
138
+ **Problem with old approach:** Manual sync between Zod validation schema and MCP definition → frequent mismatch bugs.
139
+
140
+ ---
141
+
142
+ ### ToolRegistry
143
+
144
+ **Tool registration and routing** — maps tool names to handlers, provides filtering and sorting.
145
+
146
+ **Key features:**
147
+ - ✅ Lazy initialization (tools created on-demand via DI container)
148
+ - ✅ **Priority-based sorting:** critical → high → normal → low
149
+ - ✅ **Category filtering** (via `ToolFilterService`)
150
+ - ✅ Type-safe tool registration
151
+ - ✅ Error handling for unknown tools
152
+
153
+ **Implementation:** [src/tool-registry/tool-registry.ts](src/tool-registry/tool-registry.ts)
154
+
155
+ **Class signature:**
156
+ ```typescript
157
+ class ToolRegistry {
158
+ constructor(
159
+ container: Container,
160
+ logger: Logger,
161
+ toolClasses: ReadonlyArray<ToolClass>,
162
+ filterService?: ToolFilterService
163
+ );
164
+
165
+ getDefinitions(): ToolDefinition[]; // Filtered & sorted
166
+ executeToolByName(name: string, params: ToolCallParams): Promise<ToolResult>;
167
+ }
168
+ ```
169
+
170
+ ---
171
+
172
+ ## 🛠️ Utilities
173
+
174
+ ### ResponseFieldFilter
175
+
176
+ **Filter response fields** to reduce token usage (80-90% savings).
177
+
178
+ **Usage:**
179
+ ```typescript
180
+ import { ResponseFieldFilter } from '@fractalizer/mcp-core';
181
+
182
+ const data = {
183
+ id: '123',
184
+ name: 'Item',
185
+ description: 'Long description...',
186
+ metadata: { /* ... */ },
187
+ };
188
+
189
+ // Filter to specific fields
190
+ const filtered = ResponseFieldFilter.filter(data, ['id', 'name']);
191
+ // Result: { id: '123', name: 'Item' }
192
+
193
+ // No fields specified = return all
194
+ const all = ResponseFieldFilter.filter(data);
195
+ // Result: full data object
196
+ ```
197
+
198
+ ### BatchResultProcessor
199
+
200
+ **Process batch operation results** (fulfilled + rejected).
201
+
202
+ **Usage:**
203
+ ```typescript
204
+ import { BatchResultProcessor } from '@fractalizer/mcp-core';
205
+
206
+ const results: BatchResult<string, Item> = [
207
+ { status: 'fulfilled', value: { id: '1', name: 'Item 1' } },
208
+ { status: 'rejected', reason: new Error('Not found') },
209
+ ];
210
+
211
+ // Separate successful and failed
212
+ const { successful, failed } = BatchResultProcessor.separateResults(results);
213
+
214
+ // Format for response
215
+ const formatted = BatchResultProcessor.formatBatchResponse(
216
+ successful,
217
+ failed,
218
+ 'items'
219
+ );
220
+ // Result: { items: [...], errors: [...] }
221
+ ```
222
+
223
+ ### ResultLogger
224
+
225
+ **Log tool execution results** with structured output.
226
+
227
+ **Usage:**
228
+ ```typescript
229
+ import { ResultLogger } from '@fractalizer/mcp-core';
230
+
231
+ // Log successful result
232
+ ResultLogger.logSuccess(logger, 'get_item', result, { itemId: '123' });
233
+
234
+ // Log error
235
+ ResultLogger.logError(logger, 'get_item', error, { itemId: '123' });
236
+ ```
237
+
238
+ ---
239
+
240
+ ## 🚨 Critical Rules
241
+
242
+ ### 1. BaseTool is generic — facade-agnostic
243
+
244
+ ```typescript
245
+ // ✅ CORRECT (generic facade)
246
+ class MyTool extends BaseTool<MyApiFacade> {
247
+ async execute(params: Params) {
248
+ // Use this.facade (type: MyApiFacade)
249
+ return this.facade.someMethod();
250
+ }
251
+ }
252
+
253
+ // ❌ WRONG (hardcoded facade type in BaseTool)
254
+ class BaseTool {
255
+ constructor(private facade: SpecificFacade) {} // BAD!
256
+ }
257
+ ```
258
+
259
+ ### 2. Always validate params with Zod
260
+
261
+ ```typescript
262
+ // ✅ CORRECT
263
+ const validated = this.validateParams(ParamsSchema, params);
264
+
265
+ // ❌ WRONG (no validation)
266
+ const id = params.id; // Unsafe!
267
+ ```
268
+
269
+ ### 3. Use METADATA for tool discovery
270
+
271
+ ```typescript
272
+ // ✅ CORRECT — Extended metadata with categorization
273
+ static readonly METADATA: ToolMetadata = {
274
+ name: 'my_tool',
275
+ description: '[Category/Action] Brief description',
276
+ category: 'api', // REQUIRED
277
+ subcategory: 'read', // Optional (read/write/workflow)
278
+ priority: 'critical', // Optional (critical/high/normal/low)
279
+ tags: ['tag1', 'tag2'], // Optional (for search)
280
+ requiresExplicitUserConsent: false, // or true for write operations
281
+ inputSchema: {...}
282
+ };
283
+
284
+ // ❌ WRONG (missing required category)
285
+ static readonly METADATA = {
286
+ name: 'my_tool',
287
+ description: 'Tool description',
288
+ // Missing category — will fail type check
289
+ };
290
+ ```
291
+
292
+ **Tool Categorization & Priority:**
293
+
294
+ **Priority levels** (for sorting in tools/list):
295
+ - `critical` — Frequently used, key operations (shown first)
296
+ - `high` — Important but not critical
297
+ - `normal` — Regular operations (default)
298
+ - `low` — Rarely used, debug tools (shown last)
299
+
300
+ **Tools are sorted:** critical → high → normal → low → alphabetically
301
+
302
+ **Description convention:** `[Category/Subcategory] Brief description`
303
+ - Keep descriptions concise (≤80 chars)
304
+ - Use category prefix for structure
305
+ - Details go in inputSchema parameter descriptions
306
+
307
+ **Example:**
308
+ ```typescript
309
+ static readonly METADATA: ToolMetadata = {
310
+ name: 'create_issue',
311
+ description: '[Issues/Write] Create new issue',
312
+ category: 'issues',
313
+ subcategory: 'write',
314
+ priority: 'critical',
315
+ tags: ['create', 'new', 'write', 'issue'],
316
+ inputSchema: {...}
317
+ };
318
+ ```
319
+
320
+ ### 4. Filter fields before returning
321
+
322
+ ```typescript
323
+ // ✅ CORRECT (filter to save tokens)
324
+ const filtered = ResponseFieldFilter.filter(data, params.fields);
325
+ return { content: [{ type: 'text', text: JSON.stringify(filtered) }] };
326
+
327
+ // ❌ WRONG (return everything)
328
+ return { content: [{ type: 'text', text: JSON.stringify(data) }] };
329
+ ```
330
+
331
+ ---
332
+
333
+ ## 📖 API Reference
334
+
335
+ ### Exports
336
+
337
+ ```typescript
338
+ // Base classes
339
+ export { BaseTool } from './tools/base/base-tool.js';
340
+ export { BaseDefinition } from './tools/base/base-definition.js';
341
+ export type { StaticToolMetadata } from './tools/base/tool-metadata.js';
342
+
343
+ // Utilities
344
+ export { ResponseFieldFilter } from './utils/response-field-filter.js';
345
+ export { BatchResultProcessor } from './utils/batch-result-processor.js';
346
+ export { ResultLogger } from './utils/result-logger.js';
347
+
348
+ // Registry
349
+ export { ToolRegistry } from './tool-registry.js';
350
+
351
+ // Common utilities
352
+ export { buildToolName, SafetyWarningBuilder } from './tools/common/utils/index.js';
353
+
354
+ // Types
355
+ export type { BatchResult, FulfilledResult, RejectedResult } from '@fractalizer/mcp-infrastructure';
356
+ ```
357
+
358
+ ---
359
+
360
+ ## 🧪 Testing
361
+
362
+ **Run tests:**
363
+ ```bash
364
+ cd packages/framework/core
365
+ npm run test
366
+ ```
367
+
368
+ **With coverage:**
369
+ ```bash
370
+ npm run test:coverage
371
+ ```
372
+
373
+ **Watch mode:**
374
+ ```bash
375
+ npm run test:watch
376
+ ```
377
+
378
+ ---
379
+
380
+ ## 🤝 Contributing
381
+
382
+ See [../../.github/CONTRIBUTING.md](../../.github/CONTRIBUTING.md)
383
+
384
+ **Architecture rules:** [../../CLAUDE.md](../../CLAUDE.md)
385
+
386
+ ---
387
+
388
+ ## 📄 License
389
+
390
+ MIT License
391
+
392
+ ---
393
+
394
+ ## 🔗 Links
395
+
396
+ - **Monorepo root:** [../../README.md](../../README.md)
397
+ - **Architecture:** [../../ARCHITECTURE.md](../../ARCHITECTURE.md)
398
+ - **Infrastructure package:** [../infrastructure/README.md](../infrastructure/README.md)
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Валидатор соответствия Zod Schema ↔ MCP Definition
3
+ *
4
+ * Используется для проверки, что MCP definition корректно описывает Zod schema.
5
+ * Критично для предотвращения багов schema-definition mismatch.
6
+ */
7
+ import type { z } from 'zod';
8
+ import type { ToolInputSchema } from './zod-json-schema-adapter.js';
9
+ /**
10
+ * Типы ошибок валидации
11
+ */
12
+ export declare enum ValidationErrorType {
13
+ /** Поле присутствует в schema, но отсутствует в definition.properties */
14
+ MISSING_PROPERTY = "missing_property",
15
+ /** Поле отсутствует в schema, но присутствует в definition.properties */
16
+ EXTRA_PROPERTY = "extra_property",
17
+ /** Поле обязательно в schema, но не указано в definition.required */
18
+ REQUIRED_MISMATCH = "required_mismatch",
19
+ /** Поле опционально в schema, но указано в definition.required */
20
+ OPTIONAL_MISMATCH = "optional_mismatch",
21
+ /** Различие в типах данных между schema и definition */
22
+ TYPE_MISMATCH = "type_mismatch",
23
+ /** Структурное различие (nested objects, arrays) */
24
+ STRUCTURE_MISMATCH = "structure_mismatch"
25
+ }
26
+ /**
27
+ * Описание ошибки валидации
28
+ */
29
+ export interface ValidationError {
30
+ /** Тип ошибки */
31
+ type: ValidationErrorType;
32
+ /** Имя поля, в котором обнаружена ошибка */
33
+ field: string;
34
+ /** Человекочитаемое сообщение об ошибке */
35
+ message: string;
36
+ /** Ожидаемое значение (если применимо) */
37
+ expected?: unknown;
38
+ /** Фактическое значение (если применимо) */
39
+ actual?: unknown;
40
+ }
41
+ /**
42
+ * Результат валидации
43
+ */
44
+ export interface ValidationResult {
45
+ /** Успешна ли валидация (нет ошибок) */
46
+ success: boolean;
47
+ /** Список ошибок (пустой если success: true) */
48
+ errors: ValidationError[];
49
+ }
50
+ /**
51
+ * Проверить соответствие Zod schema и MCP definition
52
+ *
53
+ * Выполняет полную проверку соответствия между Zod схемой и MCP definition:
54
+ * 1. Проверяет, что все поля из schema присутствуют в definition.properties
55
+ * 2. Проверяет, что required поля совпадают
56
+ * 3. Проверяет базовые типы данных
57
+ *
58
+ * @param schema - Zod схема параметров
59
+ * @param definition - MCP definition inputSchema
60
+ * @returns Результат валидации с списком ошибок (если есть)
61
+ *
62
+ * @example
63
+ * ```typescript
64
+ * const schema = z.object({
65
+ * issueKey: z.string(),
66
+ * fields: z.array(z.string()).optional(),
67
+ * });
68
+ *
69
+ * const definition: ToolInputSchema = {
70
+ * type: 'object',
71
+ * properties: {
72
+ * issueKey: { type: 'string' },
73
+ * // fields отсутствует - это ошибка!
74
+ * },
75
+ * required: ['issueKey'],
76
+ * };
77
+ *
78
+ * const result = validateSchemaDefinitionMatch(schema, definition);
79
+ * // result.success === false
80
+ * // result.errors[0].type === ValidationErrorType.MISSING_PROPERTY
81
+ * // result.errors[0].field === 'fields'
82
+ * ```
83
+ */
84
+ export declare function validateSchemaDefinitionMatch<T extends z.ZodRawShape>(schema: z.ZodObject<T>, definition: ToolInputSchema): ValidationResult;
85
+ /**
86
+ * Helper: Форматировать результат валидации в человекочитаемую строку
87
+ *
88
+ * @param result - Результат валидации
89
+ * @returns Строка с описанием ошибок (или 'OK' если ошибок нет)
90
+ *
91
+ * @example
92
+ * ```typescript
93
+ * const result = validateSchemaDefinitionMatch(schema, definition);
94
+ * console.log(formatValidationResult(result));
95
+ * // Вывод:
96
+ * // ❌ Schema-Definition Mismatch (2 errors):
97
+ * // 1. [missing_property] fields: Поле 'fields' присутствует в schema, но отсутствует в definition.properties
98
+ * // 2. [required_mismatch] issueKey: Поле 'issueKey' обязательно в schema, но не указано в definition.required
99
+ * ```
100
+ */
101
+ export declare function formatValidationResult(result: ValidationResult): string;
102
+ //# sourceMappingURL=definition-validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definition-validator.d.ts","sourceRoot":"","sources":["../../src/definition/definition-validator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAE7B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAEpE;;GAEG;AACH,oBAAY,mBAAmB;IAC7B,yEAAyE;IACzE,gBAAgB,qBAAqB;IAErC,yEAAyE;IACzE,cAAc,mBAAmB;IAEjC,qEAAqE;IACrE,iBAAiB,sBAAsB;IAEvC,kEAAkE;IAClE,iBAAiB,sBAAsB;IAEvC,wDAAwD;IACxD,aAAa,kBAAkB;IAE/B,oDAAoD;IACpD,kBAAkB,uBAAuB;CAC1C;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,iBAAiB;IACjB,IAAI,EAAE,mBAAmB,CAAC;IAE1B,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;IAEd,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAC;IAEhB,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,4CAA4C;IAC5C,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,wCAAwC;IACxC,OAAO,EAAE,OAAO,CAAC;IAEjB,gDAAgD;IAChD,MAAM,EAAE,eAAe,EAAE,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,6BAA6B,CAAC,CAAC,SAAS,CAAC,CAAC,WAAW,EACnE,MAAM,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EACtB,UAAU,EAAE,eAAe,GAC1B,gBAAgB,CAoElB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAevE"}
@@ -0,0 +1,151 @@
1
+ /**
2
+ * Валидатор соответствия Zod Schema ↔ MCP Definition
3
+ *
4
+ * Используется для проверки, что MCP definition корректно описывает Zod schema.
5
+ * Критично для предотвращения багов schema-definition mismatch.
6
+ */
7
+ import { extractRequiredFields } from './zod-json-schema-adapter.js';
8
+ /**
9
+ * Типы ошибок валидации
10
+ */
11
+ export var ValidationErrorType;
12
+ (function (ValidationErrorType) {
13
+ /** Поле присутствует в schema, но отсутствует в definition.properties */
14
+ ValidationErrorType["MISSING_PROPERTY"] = "missing_property";
15
+ /** Поле отсутствует в schema, но присутствует в definition.properties */
16
+ ValidationErrorType["EXTRA_PROPERTY"] = "extra_property";
17
+ /** Поле обязательно в schema, но не указано в definition.required */
18
+ ValidationErrorType["REQUIRED_MISMATCH"] = "required_mismatch";
19
+ /** Поле опционально в schema, но указано в definition.required */
20
+ ValidationErrorType["OPTIONAL_MISMATCH"] = "optional_mismatch";
21
+ /** Различие в типах данных между schema и definition */
22
+ ValidationErrorType["TYPE_MISMATCH"] = "type_mismatch";
23
+ /** Структурное различие (nested objects, arrays) */
24
+ ValidationErrorType["STRUCTURE_MISMATCH"] = "structure_mismatch";
25
+ })(ValidationErrorType || (ValidationErrorType = {}));
26
+ /**
27
+ * Проверить соответствие Zod schema и MCP definition
28
+ *
29
+ * Выполняет полную проверку соответствия между Zod схемой и MCP definition:
30
+ * 1. Проверяет, что все поля из schema присутствуют в definition.properties
31
+ * 2. Проверяет, что required поля совпадают
32
+ * 3. Проверяет базовые типы данных
33
+ *
34
+ * @param schema - Zod схема параметров
35
+ * @param definition - MCP definition inputSchema
36
+ * @returns Результат валидации с списком ошибок (если есть)
37
+ *
38
+ * @example
39
+ * ```typescript
40
+ * const schema = z.object({
41
+ * issueKey: z.string(),
42
+ * fields: z.array(z.string()).optional(),
43
+ * });
44
+ *
45
+ * const definition: ToolInputSchema = {
46
+ * type: 'object',
47
+ * properties: {
48
+ * issueKey: { type: 'string' },
49
+ * // fields отсутствует - это ошибка!
50
+ * },
51
+ * required: ['issueKey'],
52
+ * };
53
+ *
54
+ * const result = validateSchemaDefinitionMatch(schema, definition);
55
+ * // result.success === false
56
+ * // result.errors[0].type === ValidationErrorType.MISSING_PROPERTY
57
+ * // result.errors[0].field === 'fields'
58
+ * ```
59
+ */
60
+ export function validateSchemaDefinitionMatch(schema, definition) {
61
+ const errors = [];
62
+ // 1. Извлекаем информацию из schema
63
+ const schemaFields = Object.keys(schema.shape);
64
+ const schemaRequiredFields = extractRequiredFields(schema);
65
+ // 2. Извлекаем информацию из definition
66
+ const definitionFields = Object.keys(definition.properties);
67
+ const definitionRequiredFields = definition.required ?? [];
68
+ // 3. Проверка: все поля из schema присутствуют в definition.properties
69
+ for (const field of schemaFields) {
70
+ if (!definitionFields.includes(field)) {
71
+ errors.push({
72
+ type: ValidationErrorType.MISSING_PROPERTY,
73
+ field,
74
+ message: `Поле '${field}' присутствует в schema, но отсутствует в definition.properties`,
75
+ expected: `Поле должно быть в definition.properties`,
76
+ actual: `Поле отсутствует`,
77
+ });
78
+ }
79
+ }
80
+ // 4. Проверка: нет лишних полей в definition.properties
81
+ for (const field of definitionFields) {
82
+ if (!schemaFields.includes(field)) {
83
+ errors.push({
84
+ type: ValidationErrorType.EXTRA_PROPERTY,
85
+ field,
86
+ message: `Поле '${field}' присутствует в definition.properties, но отсутствует в schema`,
87
+ expected: `Поле должно отсутствовать`,
88
+ actual: `Поле присутствует`,
89
+ });
90
+ }
91
+ }
92
+ // 5. Проверка: required поля совпадают
93
+ for (const field of schemaRequiredFields) {
94
+ if (!definitionRequiredFields.includes(field)) {
95
+ errors.push({
96
+ type: ValidationErrorType.REQUIRED_MISMATCH,
97
+ field,
98
+ message: `Поле '${field}' обязательно в schema, но не указано в definition.required`,
99
+ expected: `required: [..., '${field}']`,
100
+ actual: `required: [${definitionRequiredFields.join(', ')}]`,
101
+ });
102
+ }
103
+ }
104
+ // 6. Проверка: нет лишних required полей в definition
105
+ for (const field of definitionRequiredFields) {
106
+ if (!schemaRequiredFields.includes(field)) {
107
+ errors.push({
108
+ type: ValidationErrorType.OPTIONAL_MISMATCH,
109
+ field,
110
+ message: `Поле '${field}' опционально в schema, но указано в definition.required`,
111
+ expected: `required: [${schemaRequiredFields.join(', ')}]`,
112
+ actual: `required: [..., '${field}']`,
113
+ });
114
+ }
115
+ }
116
+ // 7. Формируем результат
117
+ return {
118
+ success: errors.length === 0,
119
+ errors,
120
+ };
121
+ }
122
+ /**
123
+ * Helper: Форматировать результат валидации в человекочитаемую строку
124
+ *
125
+ * @param result - Результат валидации
126
+ * @returns Строка с описанием ошибок (или 'OK' если ошибок нет)
127
+ *
128
+ * @example
129
+ * ```typescript
130
+ * const result = validateSchemaDefinitionMatch(schema, definition);
131
+ * console.log(formatValidationResult(result));
132
+ * // Вывод:
133
+ * // ❌ Schema-Definition Mismatch (2 errors):
134
+ * // 1. [missing_property] fields: Поле 'fields' присутствует в schema, но отсутствует в definition.properties
135
+ * // 2. [required_mismatch] issueKey: Поле 'issueKey' обязательно в schema, но не указано в definition.required
136
+ * ```
137
+ */
138
+ export function formatValidationResult(result) {
139
+ if (result.success) {
140
+ return '✅ Schema-Definition Match: OK';
141
+ }
142
+ const lines = [`❌ Schema-Definition Mismatch (${result.errors.length} errors):`];
143
+ for (let i = 0; i < result.errors.length; i++) {
144
+ const error = result.errors[i];
145
+ if (error) {
146
+ lines.push(`${i + 1}. [${error.type}] ${error.field}: ${error.message}`);
147
+ }
148
+ }
149
+ return lines.join('\n');
150
+ }
151
+ //# sourceMappingURL=definition-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definition-validator.js","sourceRoot":"","sources":["../../src/definition/definition-validator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Definition Generator Module
3
+ *
4
+ * Автоматическая генерация MCP definition из Zod schema
5
+ *
6
+ * Основная функциональность:
7
+ * - Генерация inputSchema из Zod схемы (DRY принцип)
8
+ * - Валидация соответствия schema ↔ definition
9
+ * - Адаптер для конвертации Zod → JSON Schema
10
+ *
11
+ * @module @fractalizer/mcp-core/definition
12
+ */
13
+ export { generateDefinitionFromSchema, type SchemaToDefinitionOptions, } from './schema-to-definition.js';
14
+ export { zodToMcpInputSchema, extractRequiredFields, type ToolInputSchema, type ZodToJsonSchemaOptions, } from './zod-json-schema-adapter.js';
15
+ export { validateSchemaDefinitionMatch, formatValidationResult, ValidationErrorType, type ValidationError, type ValidationResult, } from './definition-validator.js';
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/definition/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EACL,4BAA4B,EAC5B,KAAK,yBAAyB,GAC/B,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,KAAK,eAAe,EACpB,KAAK,sBAAsB,GAC5B,MAAM,8BAA8B,CAAC;AAGtC,OAAO,EACL,6BAA6B,EAC7B,sBAAsB,EACtB,mBAAmB,EACnB,KAAK,eAAe,EACpB,KAAK,gBAAgB,GACtB,MAAM,2BAA2B,CAAC"}