@decocms/bindings 1.0.1-alpha.3 → 1.0.1
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/README.md +3 -3
- package/package.json +9 -11
- package/src/core/binder.ts +15 -77
- package/src/core/client/index.ts +10 -0
- package/src/core/client/mcp-client.ts +18 -5
- package/src/core/client/mcp.ts +48 -11
- package/src/core/client/proxy.ts +64 -48
- package/src/index.ts +57 -0
- package/src/well-known/assistant.ts +87 -0
- package/src/well-known/collections.ts +105 -84
- package/src/well-known/event-bus.ts +454 -0
- package/src/well-known/event-subscriber.ts +259 -0
- package/src/well-known/language-model.ts +217 -5
- package/src/well-known/mcp.ts +36 -0
- package/src/well-known/prompt.ts +110 -0
- package/src/well-known/registry.ts +128 -0
- package/src/well-known/workflow.ts +297 -0
- package/test/index.test.ts +3 -2
- package/test/mcp.test.ts +40 -0
- package/src/core/subset.ts +0 -514
- package/src/well-known/agent.ts +0 -60
- package/vitest.config.ts +0 -8
|
@@ -17,17 +17,229 @@ import {
|
|
|
17
17
|
createCollectionBindings,
|
|
18
18
|
} from "./collections";
|
|
19
19
|
|
|
20
|
+
/**
|
|
21
|
+
* JSON Value Schema
|
|
22
|
+
* Represents any valid JSON value: null, string, number, boolean, object, or array
|
|
23
|
+
*/
|
|
24
|
+
const JSONValueSchema: z.ZodType<unknown> = z.lazy(() =>
|
|
25
|
+
z.union([
|
|
26
|
+
z.null(),
|
|
27
|
+
z.string(),
|
|
28
|
+
z.number(),
|
|
29
|
+
z.boolean(),
|
|
30
|
+
z.record(z.string(), JSONValueSchema),
|
|
31
|
+
z.array(JSONValueSchema),
|
|
32
|
+
]),
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Provider Options Schema
|
|
37
|
+
* Additional provider-specific options passed through to the provider
|
|
38
|
+
*/
|
|
39
|
+
const ProviderOptionsSchema = z
|
|
40
|
+
.record(z.string(), z.record(z.string(), JSONValueSchema))
|
|
41
|
+
.optional()
|
|
42
|
+
.describe(
|
|
43
|
+
"Additional provider-specific options. Outer record keyed by provider name, inner by option key",
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Text Part Schema
|
|
48
|
+
* Text content part of a prompt
|
|
49
|
+
*/
|
|
50
|
+
const TextPartSchema = z.object({
|
|
51
|
+
type: z.literal("text"),
|
|
52
|
+
text: z.string().describe("The text content"),
|
|
53
|
+
providerOptions: ProviderOptionsSchema,
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Data Content Schema
|
|
58
|
+
* File data can be Uint8Array (as base64 string), base64 encoded string, or URL string
|
|
59
|
+
*/
|
|
60
|
+
const DataContentSchema = z
|
|
61
|
+
.union([z.string(), z.instanceof(Uint8Array)])
|
|
62
|
+
.describe("File data as base64 encoded string, URL string, or Uint8Array");
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* File Part Schema
|
|
66
|
+
* File content part of a prompt
|
|
67
|
+
*/
|
|
68
|
+
const FilePartSchema = z.object({
|
|
69
|
+
type: z.literal("file"),
|
|
70
|
+
filename: z.string().optional().describe("Optional filename of the file"),
|
|
71
|
+
data: DataContentSchema,
|
|
72
|
+
mediaType: z
|
|
73
|
+
.string()
|
|
74
|
+
.describe("IANA media type of the file (e.g., image/png, audio/mp3)"),
|
|
75
|
+
providerOptions: ProviderOptionsSchema,
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Reasoning Part Schema
|
|
80
|
+
* Reasoning content part of a prompt
|
|
81
|
+
*/
|
|
82
|
+
const ReasoningPartSchema = z.object({
|
|
83
|
+
type: z.literal("reasoning"),
|
|
84
|
+
text: z.string().describe("The reasoning text"),
|
|
85
|
+
providerOptions: ProviderOptionsSchema,
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Tool Call Part Schema
|
|
90
|
+
* Tool call content part of a prompt (usually generated by the AI model)
|
|
91
|
+
*/
|
|
92
|
+
const ToolCallPartSchema = z.object({
|
|
93
|
+
type: z.literal("tool-call"),
|
|
94
|
+
toolCallId: z
|
|
95
|
+
.string()
|
|
96
|
+
.describe("ID of the tool call, used to match with tool result"),
|
|
97
|
+
toolName: z.string().describe("Name of the tool being called"),
|
|
98
|
+
input: z
|
|
99
|
+
.unknown()
|
|
100
|
+
.describe(
|
|
101
|
+
"Arguments of the tool call (JSON-serializable object matching tool input schema)",
|
|
102
|
+
),
|
|
103
|
+
providerExecuted: z
|
|
104
|
+
.boolean()
|
|
105
|
+
.optional()
|
|
106
|
+
.describe("Whether the tool call will be executed by the provider"),
|
|
107
|
+
providerOptions: ProviderOptionsSchema,
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Tool Result Output Schema
|
|
112
|
+
* The output of a tool result
|
|
113
|
+
*/
|
|
114
|
+
const ToolResultOutputSchema = z.union([
|
|
115
|
+
z.object({
|
|
116
|
+
type: z.literal("text"),
|
|
117
|
+
value: z.string(),
|
|
118
|
+
}),
|
|
119
|
+
z.object({
|
|
120
|
+
type: z.literal("json"),
|
|
121
|
+
value: JSONValueSchema,
|
|
122
|
+
}),
|
|
123
|
+
z.object({
|
|
124
|
+
type: z.literal("error-text"),
|
|
125
|
+
value: z.string(),
|
|
126
|
+
}),
|
|
127
|
+
z.object({
|
|
128
|
+
type: z.literal("error-json"),
|
|
129
|
+
value: JSONValueSchema,
|
|
130
|
+
}),
|
|
131
|
+
z.object({
|
|
132
|
+
type: z.literal("content"),
|
|
133
|
+
value: z.array(
|
|
134
|
+
z.union([
|
|
135
|
+
z.object({
|
|
136
|
+
type: z.literal("text"),
|
|
137
|
+
text: z.string().describe("Text content"),
|
|
138
|
+
}),
|
|
139
|
+
z.object({
|
|
140
|
+
type: z.literal("media"),
|
|
141
|
+
data: z.string().describe("Base-64 encoded media data"),
|
|
142
|
+
mediaType: z.string().describe("IANA media type"),
|
|
143
|
+
}),
|
|
144
|
+
]),
|
|
145
|
+
),
|
|
146
|
+
}),
|
|
147
|
+
]);
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Tool Result Part Schema
|
|
151
|
+
* Tool result content part of a prompt
|
|
152
|
+
*/
|
|
153
|
+
const ToolResultPartSchema = z.object({
|
|
154
|
+
type: z.literal("tool-result"),
|
|
155
|
+
toolCallId: z
|
|
156
|
+
.string()
|
|
157
|
+
.describe("ID of the tool call that this result is associated with"),
|
|
158
|
+
toolName: z.string().describe("Name of the tool that generated this result"),
|
|
159
|
+
output: ToolResultOutputSchema.describe("Result of the tool call"),
|
|
160
|
+
providerOptions: ProviderOptionsSchema,
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* System Message Schema
|
|
165
|
+
*/
|
|
166
|
+
const SystemMessageSchema = z.object({
|
|
167
|
+
role: z.literal("system"),
|
|
168
|
+
content: z.string().describe("System message content"),
|
|
169
|
+
providerOptions: ProviderOptionsSchema,
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* User Message Schema
|
|
174
|
+
*/
|
|
175
|
+
const UserMessageSchema = z.object({
|
|
176
|
+
role: z.literal("user"),
|
|
177
|
+
content: z
|
|
178
|
+
.array(z.union([TextPartSchema, FilePartSchema]))
|
|
179
|
+
.describe("User message content parts (text or file)"),
|
|
180
|
+
providerOptions: ProviderOptionsSchema,
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Assistant Message Schema
|
|
185
|
+
*/
|
|
186
|
+
const AssistantMessageSchema = z.object({
|
|
187
|
+
role: z.literal("assistant"),
|
|
188
|
+
content: z
|
|
189
|
+
.array(
|
|
190
|
+
z.union([
|
|
191
|
+
TextPartSchema,
|
|
192
|
+
FilePartSchema,
|
|
193
|
+
ReasoningPartSchema,
|
|
194
|
+
ToolCallPartSchema,
|
|
195
|
+
ToolResultPartSchema,
|
|
196
|
+
]),
|
|
197
|
+
)
|
|
198
|
+
.describe(
|
|
199
|
+
"Assistant message content parts (text, file, reasoning, tool-call, or tool-result)",
|
|
200
|
+
),
|
|
201
|
+
providerOptions: ProviderOptionsSchema,
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Tool Message Schema
|
|
206
|
+
*/
|
|
207
|
+
const ToolMessageSchema = z.object({
|
|
208
|
+
role: z.literal("tool"),
|
|
209
|
+
content: z
|
|
210
|
+
.array(ToolResultPartSchema)
|
|
211
|
+
.describe("Tool message content (tool results)"),
|
|
212
|
+
providerOptions: ProviderOptionsSchema,
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Language Model Message Schema
|
|
217
|
+
* A message in a language model prompt
|
|
218
|
+
*/
|
|
219
|
+
export const LanguageModelMessageSchema = z.union([
|
|
220
|
+
SystemMessageSchema,
|
|
221
|
+
UserMessageSchema,
|
|
222
|
+
AssistantMessageSchema,
|
|
223
|
+
ToolMessageSchema,
|
|
224
|
+
]);
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Language Model Prompt Schema
|
|
228
|
+
* A prompt is a list of messages based on LanguageModelV2Prompt from @ai-sdk/provider
|
|
229
|
+
*/
|
|
230
|
+
export const LanguageModelPromptSchema = z
|
|
231
|
+
.array(LanguageModelMessageSchema)
|
|
232
|
+
.describe("A list of messages forming the prompt");
|
|
233
|
+
|
|
20
234
|
/**
|
|
21
235
|
* Language Model Call Options Schema
|
|
22
236
|
* Based on LanguageModelV2CallOptions from @ai-sdk/provider
|
|
23
237
|
*/
|
|
24
238
|
export const LanguageModelCallOptionsSchema = z.object({
|
|
25
239
|
// Core parameters
|
|
26
|
-
prompt:
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"A language mode prompt is a standardized prompt type (messages, system, etc.)",
|
|
30
|
-
),
|
|
240
|
+
prompt: LanguageModelPromptSchema.describe(
|
|
241
|
+
"A language model prompt is a standardized prompt type (array of messages with roles: system, user, assistant, tool)",
|
|
242
|
+
),
|
|
31
243
|
|
|
32
244
|
// Generation parameters
|
|
33
245
|
maxOutputTokens: z
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Well-Known Binding
|
|
3
|
+
*
|
|
4
|
+
* Defines the interface for retrieving MCP configuration.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
import type { Binder } from "../core/binder";
|
|
9
|
+
export type { ServerClient } from "../core/client/mcp-client";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* MCP Configuration Output Schema
|
|
13
|
+
*/
|
|
14
|
+
export const McpConfigurationOutputSchema = z.object({
|
|
15
|
+
scopes: z.array(z.string()).describe("List of scopes available"),
|
|
16
|
+
stateSchema: z
|
|
17
|
+
.record(z.string(), z.unknown())
|
|
18
|
+
.describe("JSON Schema (draft-07) defining the state structure"),
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
export type McpConfigurationOutput = z.infer<
|
|
22
|
+
typeof McpConfigurationOutputSchema
|
|
23
|
+
>;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* MCP Binding
|
|
27
|
+
*
|
|
28
|
+
* Tool to retrieve the MCP configuration including scopes and state schema.
|
|
29
|
+
*/
|
|
30
|
+
export const MCP_BINDING = [
|
|
31
|
+
{
|
|
32
|
+
name: "MCP_CONFIGURATION",
|
|
33
|
+
inputSchema: z.object({}),
|
|
34
|
+
outputSchema: McpConfigurationOutputSchema,
|
|
35
|
+
},
|
|
36
|
+
] as const satisfies Binder;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prompts Well-Known Binding
|
|
3
|
+
*
|
|
4
|
+
* Defines the interface for prompt providers.
|
|
5
|
+
* Any MCP that implements this binding can expose prompts as a collection.
|
|
6
|
+
*
|
|
7
|
+
* This binding uses collection bindings for full CRUD operations.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { z } from "zod";
|
|
11
|
+
import type { Binder } from "../core/binder";
|
|
12
|
+
import {
|
|
13
|
+
BaseCollectionEntitySchema,
|
|
14
|
+
createCollectionBindings,
|
|
15
|
+
} from "./collections";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Schema for prompt arguments that can be passed when getting a prompt
|
|
19
|
+
*/
|
|
20
|
+
export const PromptArgumentSchema = z.object({
|
|
21
|
+
name: z.string().describe("Argument name"),
|
|
22
|
+
description: z.string().optional().describe("Argument description"),
|
|
23
|
+
required: z.boolean().optional().describe("Whether argument is required"),
|
|
24
|
+
});
|
|
25
|
+
export type PromptArgument = z.infer<typeof PromptArgumentSchema>;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Schema for prompt icons for display in user interfaces
|
|
29
|
+
*/
|
|
30
|
+
export const PromptIconSchema = z.object({
|
|
31
|
+
src: z.string().url().describe("Icon URL"),
|
|
32
|
+
mimeType: z.string().optional().describe("Icon MIME type"),
|
|
33
|
+
sizes: z.array(z.string()).optional().describe("Icon sizes"),
|
|
34
|
+
});
|
|
35
|
+
export type PromptIcon = z.infer<typeof PromptIconSchema>;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Schema for content within a prompt message
|
|
39
|
+
*/
|
|
40
|
+
export const PromptMessageContentSchema = z.object({
|
|
41
|
+
type: z.enum(["text", "image", "audio", "resource"]).describe("Content type"),
|
|
42
|
+
text: z.string().optional().describe("Text content"),
|
|
43
|
+
data: z.string().optional().describe("Base64-encoded data for image/audio"),
|
|
44
|
+
mimeType: z
|
|
45
|
+
.string()
|
|
46
|
+
.optional()
|
|
47
|
+
.describe("MIME type for image/audio/resource"),
|
|
48
|
+
resource: z
|
|
49
|
+
.object({
|
|
50
|
+
uri: z.string().describe("Resource URI"),
|
|
51
|
+
mimeType: z.string().optional().describe("Resource MIME type"),
|
|
52
|
+
text: z.string().optional().describe("Resource text content"),
|
|
53
|
+
blob: z.string().optional().describe("Base64-encoded resource blob"),
|
|
54
|
+
})
|
|
55
|
+
.optional()
|
|
56
|
+
.describe("Embedded resource"),
|
|
57
|
+
});
|
|
58
|
+
export type PromptMessageContent = z.infer<typeof PromptMessageContentSchema>;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Schema for a message in a prompt
|
|
62
|
+
*/
|
|
63
|
+
export const PromptMessageSchema = z.object({
|
|
64
|
+
role: z.enum(["user", "assistant"]).describe("Message role"),
|
|
65
|
+
content: PromptMessageContentSchema.describe("Message content"),
|
|
66
|
+
});
|
|
67
|
+
export type PromptMessage = z.infer<typeof PromptMessageSchema>;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Full prompt entity schema extending base collection fields
|
|
71
|
+
*/
|
|
72
|
+
export const PromptSchema = BaseCollectionEntitySchema.extend({
|
|
73
|
+
arguments: z
|
|
74
|
+
.array(PromptArgumentSchema)
|
|
75
|
+
.optional()
|
|
76
|
+
.describe("Arguments that can be passed when getting this prompt"),
|
|
77
|
+
icons: z
|
|
78
|
+
.array(PromptIconSchema)
|
|
79
|
+
.optional()
|
|
80
|
+
.describe("Icons for display in user interfaces"),
|
|
81
|
+
messages: z.array(PromptMessageSchema).describe("Prompt messages template"),
|
|
82
|
+
});
|
|
83
|
+
export type Prompt = z.infer<typeof PromptSchema>;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* PROMPT Collection Binding
|
|
87
|
+
*
|
|
88
|
+
* Collection bindings for prompts.
|
|
89
|
+
* Provides full CRUD operations (LIST, GET, CREATE, UPDATE, DELETE) for prompts.
|
|
90
|
+
*/
|
|
91
|
+
export const PROMPTS_COLLECTION_BINDING = createCollectionBindings(
|
|
92
|
+
"prompt",
|
|
93
|
+
PromptSchema,
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* PROMPTS Binding
|
|
98
|
+
*
|
|
99
|
+
* Required tools:
|
|
100
|
+
* - COLLECTION_PROMPT_LIST
|
|
101
|
+
* - COLLECTION_PROMPT_GET
|
|
102
|
+
*
|
|
103
|
+
* Optional tools:
|
|
104
|
+
* - COLLECTION_PROMPT_CREATE
|
|
105
|
+
* - COLLECTION_PROMPT_UPDATE
|
|
106
|
+
* - COLLECTION_PROMPT_DELETE
|
|
107
|
+
*/
|
|
108
|
+
export const PROMPTS_BINDING = [
|
|
109
|
+
...PROMPTS_COLLECTION_BINDING,
|
|
110
|
+
] as const satisfies Binder;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registry App Well-Known Binding
|
|
3
|
+
*
|
|
4
|
+
* Defines the interface for accessing public registry apps.
|
|
5
|
+
* Any MCP that implements this binding can provide a list of available apps
|
|
6
|
+
* with their configurations and tools.
|
|
7
|
+
*
|
|
8
|
+
* This binding includes:
|
|
9
|
+
* - Collection bindings for LIST and GET operations (read-only)
|
|
10
|
+
* - Only exposes public apps (unlisted: false)
|
|
11
|
+
* - Removes sensitive fields (connection details, workspace info)
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { z } from "zod";
|
|
15
|
+
import {
|
|
16
|
+
BaseCollectionEntitySchema,
|
|
17
|
+
createCollectionBindings,
|
|
18
|
+
} from "./collections";
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Tool definition schema from registry
|
|
22
|
+
*/
|
|
23
|
+
const RegistryToolSchema = z.object({
|
|
24
|
+
id: z.string(),
|
|
25
|
+
name: z.string(),
|
|
26
|
+
description: z.string().optional(),
|
|
27
|
+
inputSchema: z.record(z.unknown()),
|
|
28
|
+
outputSchema: z.record(z.unknown()).optional(),
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* MCP Registry Server schema extending Collection Entity base
|
|
33
|
+
* Combines BaseCollectionEntitySchema with MCP Registry Spec format
|
|
34
|
+
* https://spec.modelcontextprotocol.io/specification/2025-03-26/registry/
|
|
35
|
+
*/
|
|
36
|
+
export const MCPRegistryServerSchema = BaseCollectionEntitySchema.extend({
|
|
37
|
+
// MCP Registry Spec structure
|
|
38
|
+
_meta: z
|
|
39
|
+
.object({
|
|
40
|
+
"io.decocms": z
|
|
41
|
+
.object({
|
|
42
|
+
id: z.string(),
|
|
43
|
+
verified: z.boolean(),
|
|
44
|
+
scopeName: z.string(),
|
|
45
|
+
appName: z.string(),
|
|
46
|
+
friendlyName: z.string().nullable().optional(),
|
|
47
|
+
metadata: z.record(z.unknown()).nullable().optional(),
|
|
48
|
+
publishedAt: z.string().datetime().optional(),
|
|
49
|
+
updatedAt: z.string().datetime().optional(),
|
|
50
|
+
tools: z
|
|
51
|
+
.array(RegistryToolSchema)
|
|
52
|
+
.nullable()
|
|
53
|
+
.optional()
|
|
54
|
+
.describe("Available tools exposed by this app"),
|
|
55
|
+
})
|
|
56
|
+
.optional(),
|
|
57
|
+
})
|
|
58
|
+
.optional(),
|
|
59
|
+
server: z.object({
|
|
60
|
+
$schema: z.string().optional(),
|
|
61
|
+
_meta: z.record(z.unknown()).optional(),
|
|
62
|
+
name: z.string().describe("The server name (scope/app)"),
|
|
63
|
+
title: z.string().optional().describe("User-friendly title"),
|
|
64
|
+
description: z.string().optional().describe("Server description"),
|
|
65
|
+
icons: z
|
|
66
|
+
.array(
|
|
67
|
+
z.object({
|
|
68
|
+
src: z.string(),
|
|
69
|
+
mimeType: z.string().optional(),
|
|
70
|
+
sizes: z.array(z.string()).optional(),
|
|
71
|
+
theme: z.enum(["light", "dark"]).optional(),
|
|
72
|
+
}),
|
|
73
|
+
)
|
|
74
|
+
.optional(),
|
|
75
|
+
remotes: z
|
|
76
|
+
.array(
|
|
77
|
+
z.object({
|
|
78
|
+
type: z.enum(["http", "stdio", "sse"]),
|
|
79
|
+
url: z.string().optional(),
|
|
80
|
+
headers: z.array(z.unknown()).optional(),
|
|
81
|
+
}),
|
|
82
|
+
)
|
|
83
|
+
.optional(),
|
|
84
|
+
packages: z.array(z.unknown()).optional(),
|
|
85
|
+
repository: z
|
|
86
|
+
.object({
|
|
87
|
+
url: z.string(),
|
|
88
|
+
source: z.string().optional(),
|
|
89
|
+
subfolder: z.string().optional(),
|
|
90
|
+
})
|
|
91
|
+
.optional(),
|
|
92
|
+
version: z.string().optional(),
|
|
93
|
+
websiteUrl: z.string().optional(),
|
|
94
|
+
}),
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
export type RegistryAppCollectionEntity = z.infer<
|
|
98
|
+
typeof MCPRegistryServerSchema
|
|
99
|
+
>;
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Registry App Collection Binding (read-only)
|
|
103
|
+
*
|
|
104
|
+
* Collection bindings for registry apps (read-only).
|
|
105
|
+
* Provides LIST and GET operations for public apps.
|
|
106
|
+
* Only includes public apps (unlisted: false).
|
|
107
|
+
*
|
|
108
|
+
* Returns servers in MCP Registry Spec format with:
|
|
109
|
+
* - _meta: DecoCMS-specific metadata (id, verified, tools, etc.)
|
|
110
|
+
* - server: MCP Registry Spec compliant server definition
|
|
111
|
+
*/
|
|
112
|
+
const REGISTRY_APP_COLLECTION_BINDING = createCollectionBindings(
|
|
113
|
+
"registry_app",
|
|
114
|
+
MCPRegistryServerSchema,
|
|
115
|
+
{ readOnly: true },
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Registry App Binding
|
|
120
|
+
*
|
|
121
|
+
* Defines the interface for accessing public registry apps.
|
|
122
|
+
* Any MCP that implements this binding can provide a searchable list of apps.
|
|
123
|
+
*
|
|
124
|
+
* Required tools:
|
|
125
|
+
* - COLLECTION_REGISTRY_APP_LIST: List available apps with filtering and pagination
|
|
126
|
+
* - COLLECTION_REGISTRY_APP_GET: Get a single app by ID
|
|
127
|
+
*/
|
|
128
|
+
export const REGISTRY_APP_BINDING = REGISTRY_APP_COLLECTION_BINDING;
|