@decocms/bindings 1.0.1-alpha.12 → 1.0.1-alpha.14

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decocms/bindings",
3
- "version": "1.0.1-alpha.12",
3
+ "version": "1.0.1-alpha.14",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "test": "vitest run",
@@ -83,7 +83,12 @@ export const createServerClient = async (
83
83
  headers.set(key, value);
84
84
  }
85
85
 
86
- return fetch(mcpServer.connection.url + `/call-tool/${tool}`, {
86
+ const url = new URL(mcpServer.connection.url);
87
+ // Trim trailing slashes from pathname, ensuring it starts with '/'
88
+ const trimmedPath = url.pathname.replace(/\/+$/, "") || "/";
89
+ url.pathname = `${trimmedPath}/call-tool/${encodeURIComponent(tool)}`;
90
+
91
+ return fetch(url.href, {
87
92
  method: "POST",
88
93
  redirect: "manual",
89
94
  body: JSON.stringify(args),
package/src/index.ts CHANGED
@@ -13,3 +13,10 @@ export {
13
13
  type ToolBinder,
14
14
  type ToolWithSchemas,
15
15
  } from "./core/binder";
16
+
17
+ // Re-export registry binding types
18
+ export {
19
+ MCPRegistryServerSchema,
20
+ type RegistryAppCollectionEntity,
21
+ REGISTRY_APP_BINDING,
22
+ } from "./well-known/registry";
@@ -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: z
27
- .any()
28
- .describe(
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
@@ -4,7 +4,7 @@
4
4
  * Defines the interface for retrieving MCP configuration.
5
5
  */
6
6
 
7
- import { z } from "zod/v3";
7
+ import { z } from "zod";
8
8
  import type { Binder } from "../core/binder";
9
9
 
10
10
  /**
@@ -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;