@contractspec/bundle.library 3.0.0 → 3.2.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 (50) hide show
  1. package/.turbo/turbo-build.log +178 -166
  2. package/AGENTS.md +19 -12
  3. package/CHANGELOG.md +74 -0
  4. package/dist/application/context-storage/index.d.ts +18 -0
  5. package/dist/application/context-storage/index.js +29 -0
  6. package/dist/application/index.d.ts +1 -0
  7. package/dist/application/index.js +662 -2
  8. package/dist/application/mcp/cliMcp.js +12 -2
  9. package/dist/application/mcp/common.d.ts +11 -1
  10. package/dist/application/mcp/common.js +12 -2
  11. package/dist/application/mcp/contractsMcp.d.ts +51 -0
  12. package/dist/application/mcp/contractsMcp.js +531 -0
  13. package/dist/application/mcp/contractsMcpResources.d.ts +7 -0
  14. package/dist/application/mcp/contractsMcpResources.js +124 -0
  15. package/dist/application/mcp/contractsMcpTools.d.ts +9 -0
  16. package/dist/application/mcp/contractsMcpTools.js +200 -0
  17. package/dist/application/mcp/contractsMcpTypes.d.ts +50 -0
  18. package/dist/application/mcp/contractsMcpTypes.js +1 -0
  19. package/dist/application/mcp/docsMcp.js +12 -2
  20. package/dist/application/mcp/index.d.ts +2 -0
  21. package/dist/application/mcp/index.js +635 -2
  22. package/dist/application/mcp/internalMcp.js +12 -2
  23. package/dist/application/mcp/providerRankingMcp.d.ts +46 -0
  24. package/dist/application/mcp/providerRankingMcp.js +494 -0
  25. package/dist/node/application/context-storage/index.js +28 -0
  26. package/dist/node/application/index.js +662 -2
  27. package/dist/node/application/mcp/cliMcp.js +12 -2
  28. package/dist/node/application/mcp/common.js +12 -2
  29. package/dist/node/application/mcp/contractsMcp.js +530 -0
  30. package/dist/node/application/mcp/contractsMcpResources.js +123 -0
  31. package/dist/node/application/mcp/contractsMcpTools.js +199 -0
  32. package/dist/node/application/mcp/contractsMcpTypes.js +0 -0
  33. package/dist/node/application/mcp/docsMcp.js +12 -2
  34. package/dist/node/application/mcp/index.js +635 -2
  35. package/dist/node/application/mcp/internalMcp.js +12 -2
  36. package/dist/node/application/mcp/providerRankingMcp.js +493 -0
  37. package/package.json +113 -25
  38. package/src/application/context-storage/index.ts +58 -0
  39. package/src/application/index.ts +1 -0
  40. package/src/application/mcp/common.ts +28 -1
  41. package/src/application/mcp/contractsMcp.ts +34 -0
  42. package/src/application/mcp/contractsMcpResources.ts +142 -0
  43. package/src/application/mcp/contractsMcpTools.ts +246 -0
  44. package/src/application/mcp/contractsMcpTypes.ts +47 -0
  45. package/src/application/mcp/index.ts +2 -0
  46. package/src/application/mcp/providerRankingMcp.ts +380 -0
  47. package/src/components/docs/generated/docs-index._common.json +879 -1
  48. package/src/components/docs/generated/docs-index.manifest.json +5 -5
  49. package/src/components/docs/generated/docs-index.metrics.json +8 -0
  50. package/src/components/docs/generated/docs-index.platform-integrations.json +8 -0
@@ -0,0 +1,58 @@
1
+ import type {
2
+ DatabaseProvider,
3
+ EmbeddingProvider,
4
+ VectorStoreProvider,
5
+ } from '@contractspec/lib.contracts-integrations';
6
+ import {
7
+ DocumentProcessor,
8
+ EmbeddingService,
9
+ VectorIndexer,
10
+ type VectorIndexConfig,
11
+ } from '@contractspec/lib.knowledge/ingestion';
12
+ import {
13
+ ContextSnapshotPipeline,
14
+ PostgresContextStorage,
15
+ } from '@contractspec/module.context-storage';
16
+
17
+ export interface ContextStorageServiceOptions {
18
+ database: DatabaseProvider;
19
+ schema?: string;
20
+ createTablesIfMissing?: boolean;
21
+ documentProcessor?: DocumentProcessor;
22
+ embeddingProvider?: EmbeddingProvider;
23
+ embeddingBatchSize?: number;
24
+ vectorStoreProvider?: VectorStoreProvider;
25
+ vectorIndex?: VectorIndexConfig;
26
+ }
27
+
28
+ export interface ContextStorageService {
29
+ store: PostgresContextStorage;
30
+ pipeline: ContextSnapshotPipeline;
31
+ }
32
+
33
+ export function createContextStorageService(
34
+ options: ContextStorageServiceOptions
35
+ ): ContextStorageService {
36
+ const store = new PostgresContextStorage({
37
+ database: options.database,
38
+ schema: options.schema,
39
+ createTablesIfMissing: options.createTablesIfMissing,
40
+ });
41
+ const embeddingService = options.embeddingProvider
42
+ ? new EmbeddingService(
43
+ options.embeddingProvider,
44
+ options.embeddingBatchSize
45
+ )
46
+ : undefined;
47
+ const vectorIndexer =
48
+ options.vectorStoreProvider && options.vectorIndex
49
+ ? new VectorIndexer(options.vectorStoreProvider, options.vectorIndex)
50
+ : undefined;
51
+ const pipeline = new ContextSnapshotPipeline({
52
+ store,
53
+ documentProcessor: options.documentProcessor,
54
+ embeddingService,
55
+ vectorIndexer,
56
+ });
57
+ return { store, pipeline };
58
+ }
@@ -1 +1,2 @@
1
1
  export * from './mcp';
2
+ export * from './context-storage';
@@ -11,6 +11,13 @@ import { WebStandardStreamableHTTPServerTransport } from '@modelcontextprotocol/
11
11
  import { Elysia } from 'elysia';
12
12
  import { Logger } from '@contractspec/lib.logger';
13
13
  import { randomUUID } from 'node:crypto';
14
+ import type { IntegrationAuthType } from '@contractspec/lib.contracts-integrations/integrations';
15
+
16
+ export interface McpAuthValidationResult {
17
+ valid: boolean;
18
+ actor?: string;
19
+ reason?: string;
20
+ }
14
21
 
15
22
  interface McpHttpHandlerConfig {
16
23
  path: string;
@@ -20,6 +27,10 @@ interface McpHttpHandlerConfig {
20
27
  prompts: PromptRegistry;
21
28
  presentations?: PresentationSpec[];
22
29
  logger: Logger;
30
+ /** Callback to validate auth credentials from the incoming request. */
31
+ validateAuth?: (request: Request) => Promise<McpAuthValidationResult>;
32
+ /** Auth methods this MCP handler requires callers to present. */
33
+ requiredAuthMethods?: IntegrationAuthType[];
23
34
  }
24
35
 
25
36
  const baseCtx = {
@@ -116,8 +127,12 @@ export function createMcpElysiaHandler({
116
127
  resources,
117
128
  prompts,
118
129
  presentations,
130
+ validateAuth,
131
+ requiredAuthMethods,
119
132
  }: McpHttpHandlerConfig) {
120
- logger.info('Setting up MCP handler...');
133
+ logger.info('Setting up MCP handler...', {
134
+ requiredAuthMethods: requiredAuthMethods ?? [],
135
+ });
121
136
 
122
137
  const isStateful = process.env.CONTRACTSPEC_MCP_STATEFUL === '1';
123
138
  const sessions = new Map<string, McpSessionState>();
@@ -200,6 +215,18 @@ export function createMcpElysiaHandler({
200
215
  path,
201
216
  async ({ request }) => {
202
217
  try {
218
+ if (validateAuth) {
219
+ const authResult = await validateAuth(request);
220
+ if (!authResult.valid) {
221
+ return createJsonRpcErrorResponse(
222
+ 401,
223
+ -32002,
224
+ 'Authentication failed',
225
+ authResult.reason
226
+ );
227
+ }
228
+ }
229
+
203
230
  if (isStateful) {
204
231
  return await handleStateful(request);
205
232
  }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Contracts MCP server.
3
+ *
4
+ * Exposes contract management operations (list, get, create, update,
5
+ * delete, validate, build) as MCP tools, resources, and prompts.
6
+ *
7
+ * Services are injected at creation time so this bundle stays
8
+ * decoupled from bundle.workspace — the app layer provides real impls.
9
+ */
10
+
11
+ import { createMcpElysiaHandler } from './common';
12
+ import { appLogger } from '../../infrastructure/elysia/logger';
13
+ import { buildContractsOps } from './contractsMcpTools';
14
+ import {
15
+ buildContractsResources,
16
+ buildContractsPrompts,
17
+ } from './contractsMcpResources';
18
+ import type { ContractsMcpServices } from './contractsMcpTypes';
19
+
20
+ export type { ContractsMcpServices, ContractInfo } from './contractsMcpTypes';
21
+
22
+ export function createContractsMcpHandler(
23
+ path = '/api/mcp/contracts',
24
+ services: ContractsMcpServices
25
+ ) {
26
+ return createMcpElysiaHandler({
27
+ logger: appLogger,
28
+ path,
29
+ serverName: 'contractspec-contracts-mcp',
30
+ ops: buildContractsOps(services),
31
+ resources: buildContractsResources(services),
32
+ prompts: buildContractsPrompts(),
33
+ });
34
+ }
@@ -0,0 +1,142 @@
1
+ /**
2
+ * Contract management MCP resource and prompt definitions.
3
+ */
4
+
5
+ import {
6
+ definePrompt,
7
+ defineResourceTemplate,
8
+ PromptRegistry,
9
+ ResourceRegistry,
10
+ } from '@contractspec/lib.contracts-spec';
11
+ import z from 'zod';
12
+ import type { ContractsMcpServices } from './contractsMcpTypes';
13
+
14
+ const OWNERS = ['@contractspec'];
15
+ const TAGS = ['contracts', 'mcp'];
16
+
17
+ export function buildContractsResources(services: ContractsMcpServices) {
18
+ const resources = new ResourceRegistry();
19
+
20
+ resources.register(
21
+ defineResourceTemplate({
22
+ meta: {
23
+ uriTemplate: 'contracts://list',
24
+ title: 'Contract specs list',
25
+ description: 'JSON list of all contract specs in the workspace.',
26
+ mimeType: 'application/json',
27
+ tags: TAGS,
28
+ },
29
+ input: z.object({}),
30
+ resolve: async () => {
31
+ const specs = await services.listSpecs();
32
+ return {
33
+ uri: 'contracts://list',
34
+ mimeType: 'application/json',
35
+ data: JSON.stringify(specs, null, 2),
36
+ };
37
+ },
38
+ })
39
+ );
40
+
41
+ resources.register(
42
+ defineResourceTemplate({
43
+ meta: {
44
+ uriTemplate: 'contracts://spec/{path}',
45
+ title: 'Contract spec content',
46
+ description: 'Read a single contract spec file by path.',
47
+ mimeType: 'text/plain',
48
+ tags: TAGS,
49
+ },
50
+ input: z.object({ path: z.string() }),
51
+ resolve: async ({ path }) => {
52
+ const result = await services.getSpec(path);
53
+ if (!result) {
54
+ return {
55
+ uri: `contracts://spec/${encodeURIComponent(path)}`,
56
+ mimeType: 'text/plain',
57
+ data: `Spec not found: ${path}`,
58
+ };
59
+ }
60
+ return {
61
+ uri: `contracts://spec/${encodeURIComponent(path)}`,
62
+ mimeType: 'text/plain',
63
+ data: result.content,
64
+ };
65
+ },
66
+ })
67
+ );
68
+
69
+ resources.register(
70
+ defineResourceTemplate({
71
+ meta: {
72
+ uriTemplate: 'contracts://registry/manifest',
73
+ title: 'Remote registry manifest',
74
+ description: 'Contract registry manifest from the remote server.',
75
+ mimeType: 'application/json',
76
+ tags: TAGS,
77
+ },
78
+ input: z.object({}),
79
+ resolve: async () => {
80
+ const manifest = await services.fetchRegistryManifest();
81
+ return {
82
+ uri: 'contracts://registry/manifest',
83
+ mimeType: 'application/json',
84
+ data: JSON.stringify(manifest, null, 2),
85
+ };
86
+ },
87
+ })
88
+ );
89
+
90
+ return resources;
91
+ }
92
+
93
+ export function buildContractsPrompts() {
94
+ const prompts = new PromptRegistry();
95
+
96
+ prompts.register(
97
+ definePrompt({
98
+ meta: {
99
+ key: 'contracts.editor',
100
+ version: '1.0.0',
101
+ title: 'Contract editing guide',
102
+ description:
103
+ 'Guide AI agents through reading, editing, and validating contracts.',
104
+ tags: TAGS,
105
+ stability: 'beta',
106
+ owners: OWNERS,
107
+ },
108
+ args: [
109
+ {
110
+ name: 'goal',
111
+ description: 'What the agent wants to achieve with the contract.',
112
+ required: false,
113
+ schema: z.string().optional(),
114
+ },
115
+ ],
116
+ input: z.object({ goal: z.string().optional() }),
117
+ render: async ({ goal }) => [
118
+ {
119
+ type: 'text' as const,
120
+ text: [
121
+ 'Contract editing workflow:',
122
+ '1. Use contracts.list to discover specs',
123
+ '2. Use contracts.get to read a spec',
124
+ '3. Edit content and call contracts.update',
125
+ '4. Run contracts.validate to verify changes',
126
+ '5. Run contracts.build to regenerate artifacts',
127
+ goal ? `Agent goal: ${goal}` : '',
128
+ ]
129
+ .filter(Boolean)
130
+ .join('\n'),
131
+ },
132
+ {
133
+ type: 'resource' as const,
134
+ uri: 'contracts://list',
135
+ title: 'Available contracts',
136
+ },
137
+ ],
138
+ })
139
+ );
140
+
141
+ return prompts;
142
+ }
@@ -0,0 +1,246 @@
1
+ /**
2
+ * Contract management MCP tool definitions.
3
+ *
4
+ * Each tool delegates to an injected service so the bundle stays
5
+ * decoupled from bundle.workspace (apps layer does the wiring).
6
+ */
7
+
8
+ import {
9
+ defineCommand,
10
+ installOp,
11
+ OperationSpecRegistry,
12
+ } from '@contractspec/lib.contracts-spec';
13
+ import { defineSchemaModel, ScalarTypeEnum } from '@contractspec/lib.schema';
14
+ import type { ContractsMcpServices } from './contractsMcpTypes';
15
+
16
+ const OWNERS = ['@contractspec'];
17
+ const TAGS = ['contracts', 'mcp'];
18
+
19
+ export function buildContractsOps(services: ContractsMcpServices) {
20
+ const registry = new OperationSpecRegistry();
21
+
22
+ // -- contracts.list --
23
+ const ListInput = defineSchemaModel({
24
+ name: 'ContractsListInput',
25
+ fields: {
26
+ pattern: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
27
+ type: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
28
+ },
29
+ });
30
+ const ListOutput = defineSchemaModel({
31
+ name: 'ContractsListOutput',
32
+ fields: {
33
+ specs: { type: ScalarTypeEnum.JSON(), isOptional: false },
34
+ total: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },
35
+ },
36
+ });
37
+ installOp(
38
+ registry,
39
+ defineCommand({
40
+ meta: {
41
+ key: 'contracts.list',
42
+ version: '1.0.0',
43
+ stability: 'beta',
44
+ owners: OWNERS,
45
+ tags: TAGS,
46
+ description: 'List contract specs in the workspace.',
47
+ goal: 'Discover available contracts by type, pattern, or owner.',
48
+ context: 'Contracts MCP server.',
49
+ },
50
+ io: { input: ListInput, output: ListOutput },
51
+ policy: { auth: 'anonymous' },
52
+ }),
53
+ async ({ pattern, type }) => {
54
+ const specs = await services.listSpecs({ pattern, type });
55
+ return { specs, total: specs.length };
56
+ }
57
+ );
58
+
59
+ // -- contracts.get --
60
+ const GetInput = defineSchemaModel({
61
+ name: 'ContractsGetInput',
62
+ fields: {
63
+ path: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
64
+ },
65
+ });
66
+ const GetOutput = defineSchemaModel({
67
+ name: 'ContractsGetOutput',
68
+ fields: {
69
+ content: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
70
+ info: { type: ScalarTypeEnum.JSON(), isOptional: false },
71
+ },
72
+ });
73
+ installOp(
74
+ registry,
75
+ defineCommand({
76
+ meta: {
77
+ key: 'contracts.get',
78
+ version: '1.0.0',
79
+ stability: 'beta',
80
+ owners: OWNERS,
81
+ tags: TAGS,
82
+ description: 'Read a single contract spec file.',
83
+ goal: 'Fetch spec content and parsed metadata.',
84
+ context: 'Contracts MCP server.',
85
+ },
86
+ io: { input: GetInput, output: GetOutput },
87
+ policy: { auth: 'anonymous' },
88
+ }),
89
+ async ({ path }) => {
90
+ const result = await services.getSpec(path);
91
+ if (!result) throw new Error(`Spec not found: ${path}`);
92
+ return result;
93
+ }
94
+ );
95
+
96
+ // -- contracts.validate --
97
+ const ValidateInput = defineSchemaModel({
98
+ name: 'ContractsValidateInput',
99
+ fields: {
100
+ path: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
101
+ },
102
+ });
103
+ const ValidateOutput = defineSchemaModel({
104
+ name: 'ContractsValidateOutput',
105
+ fields: {
106
+ valid: { type: ScalarTypeEnum.Boolean(), isOptional: false },
107
+ errors: { type: ScalarTypeEnum.JSON(), isOptional: false },
108
+ warnings: { type: ScalarTypeEnum.JSON(), isOptional: false },
109
+ },
110
+ });
111
+ installOp(
112
+ registry,
113
+ defineCommand({
114
+ meta: {
115
+ key: 'contracts.validate',
116
+ version: '1.0.0',
117
+ stability: 'beta',
118
+ owners: OWNERS,
119
+ tags: TAGS,
120
+ description: 'Validate a contract spec structure.',
121
+ goal: 'Check spec for structural or policy issues.',
122
+ context: 'Contracts MCP server.',
123
+ },
124
+ io: { input: ValidateInput, output: ValidateOutput },
125
+ policy: { auth: 'anonymous' },
126
+ }),
127
+ async ({ path }) => services.validateSpec(path)
128
+ );
129
+
130
+ // -- contracts.build --
131
+ const BuildInput = defineSchemaModel({
132
+ name: 'ContractsBuildInput',
133
+ fields: {
134
+ path: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
135
+ dryRun: { type: ScalarTypeEnum.Boolean(), isOptional: true },
136
+ },
137
+ });
138
+ const BuildOutput = defineSchemaModel({
139
+ name: 'ContractsBuildOutput',
140
+ fields: {
141
+ results: { type: ScalarTypeEnum.JSON(), isOptional: false },
142
+ },
143
+ });
144
+ installOp(
145
+ registry,
146
+ defineCommand({
147
+ meta: {
148
+ key: 'contracts.build',
149
+ version: '1.0.0',
150
+ stability: 'beta',
151
+ owners: OWNERS,
152
+ tags: TAGS,
153
+ description: 'Generate implementation code from a contract spec.',
154
+ goal: 'Produce handler, component, or test skeletons.',
155
+ context: 'Contracts MCP server.',
156
+ },
157
+ io: { input: BuildInput, output: BuildOutput },
158
+ policy: { auth: 'user' },
159
+ }),
160
+ async ({ path, dryRun }) => services.buildSpec(path, { dryRun })
161
+ );
162
+
163
+ registerMutationTools(registry, services);
164
+
165
+ return registry;
166
+ }
167
+
168
+ function registerMutationTools(
169
+ registry: OperationSpecRegistry,
170
+ services: ContractsMcpServices
171
+ ) {
172
+ // -- contracts.update --
173
+ const UpdateInput = defineSchemaModel({
174
+ name: 'ContractsUpdateInput',
175
+ fields: {
176
+ path: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
177
+ content: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
178
+ fields: { type: ScalarTypeEnum.JSON(), isOptional: true },
179
+ },
180
+ });
181
+ const UpdateOutput = defineSchemaModel({
182
+ name: 'ContractsUpdateOutput',
183
+ fields: {
184
+ updated: { type: ScalarTypeEnum.Boolean(), isOptional: false },
185
+ errors: { type: ScalarTypeEnum.JSON(), isOptional: false },
186
+ warnings: { type: ScalarTypeEnum.JSON(), isOptional: false },
187
+ },
188
+ });
189
+ installOp(
190
+ registry,
191
+ defineCommand({
192
+ meta: {
193
+ key: 'contracts.update',
194
+ version: '1.0.0',
195
+ stability: 'beta',
196
+ owners: OWNERS,
197
+ tags: TAGS,
198
+ description: 'Update an existing contract spec.',
199
+ goal: 'Modify spec content or individual fields with validation.',
200
+ context: 'Contracts MCP server.',
201
+ },
202
+ io: { input: UpdateInput, output: UpdateOutput },
203
+ policy: { auth: 'user' },
204
+ }),
205
+ async ({ path, content, fields }) =>
206
+ services.updateSpec(path, {
207
+ content,
208
+ fields: Array.isArray(fields) ? (fields as unknown[]) : undefined,
209
+ })
210
+ );
211
+
212
+ // -- contracts.delete --
213
+ const DeleteInput = defineSchemaModel({
214
+ name: 'ContractsDeleteInput',
215
+ fields: {
216
+ path: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
217
+ clean: { type: ScalarTypeEnum.Boolean(), isOptional: true },
218
+ },
219
+ });
220
+ const DeleteOutput = defineSchemaModel({
221
+ name: 'ContractsDeleteOutput',
222
+ fields: {
223
+ deleted: { type: ScalarTypeEnum.Boolean(), isOptional: false },
224
+ cleanedFiles: { type: ScalarTypeEnum.JSON(), isOptional: false },
225
+ errors: { type: ScalarTypeEnum.JSON(), isOptional: false },
226
+ },
227
+ });
228
+ installOp(
229
+ registry,
230
+ defineCommand({
231
+ meta: {
232
+ key: 'contracts.delete',
233
+ version: '1.0.0',
234
+ stability: 'beta',
235
+ owners: OWNERS,
236
+ tags: TAGS,
237
+ description: 'Delete a contract spec and optionally its artifacts.',
238
+ goal: 'Remove a spec file and clean generated handlers/tests.',
239
+ context: 'Contracts MCP server.',
240
+ },
241
+ io: { input: DeleteInput, output: DeleteOutput },
242
+ policy: { auth: 'user' },
243
+ }),
244
+ async ({ path, clean }) => services.deleteSpec(path, { clean })
245
+ );
246
+ }
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Contracts MCP service interface.
3
+ *
4
+ * Defines the dependency-injection boundary so `bundle.library` stays
5
+ * decoupled from `bundle.workspace`. The app layer wires real impls.
6
+ */
7
+
8
+ export interface ContractInfo {
9
+ specType: string;
10
+ filePath: string;
11
+ key?: string;
12
+ version?: string;
13
+ kind?: string;
14
+ description?: string;
15
+ }
16
+
17
+ export interface ContractsMcpServices {
18
+ listSpecs(options?: {
19
+ pattern?: string;
20
+ type?: string;
21
+ }): Promise<ContractInfo[]>;
22
+
23
+ getSpec(
24
+ path: string
25
+ ): Promise<{ content: string; info: ContractInfo } | null>;
26
+
27
+ validateSpec(
28
+ path: string
29
+ ): Promise<{ valid: boolean; errors: string[]; warnings: string[] }>;
30
+
31
+ buildSpec(
32
+ path: string,
33
+ options?: { dryRun?: boolean }
34
+ ): Promise<{ results: unknown[] }>;
35
+
36
+ updateSpec(
37
+ path: string,
38
+ options: { content?: string; fields?: unknown[] }
39
+ ): Promise<{ updated: boolean; errors: string[]; warnings: string[] }>;
40
+
41
+ deleteSpec(
42
+ path: string,
43
+ options?: { clean?: boolean }
44
+ ): Promise<{ deleted: boolean; cleanedFiles: string[]; errors: string[] }>;
45
+
46
+ fetchRegistryManifest(): Promise<unknown>;
47
+ }
@@ -1,3 +1,5 @@
1
1
  export * from './docsMcp';
2
2
  export * from './cliMcp';
3
3
  export * from './internalMcp';
4
+ export * from './providerRankingMcp';
5
+ export * from './contractsMcp';