@centrali-io/centrali-mcp 4.2.1 → 4.2.3

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.
@@ -143,4 +143,131 @@ export function registerCollectionTools(server: McpServer, sdk: CentraliSDK) {
143
143
  }
144
144
  }
145
145
  );
146
+
147
+ server.tool(
148
+ "create_collection",
149
+ "Create a new data collection (schema). Define the name, slug, description, and properties (fields) for the collection.",
150
+ {
151
+ name: z.string().describe("Display name for the collection (e.g., 'Customers')"),
152
+ slug: z.string().describe("URL-safe identifier used in API calls (e.g., 'customers')"),
153
+ description: z.string().optional().describe("Optional description of the collection"),
154
+ properties: z
155
+ .array(z.record(z.string(), z.any()))
156
+ .optional()
157
+ .describe(
158
+ "Array of property definitions. Each property needs 'name' and 'type' (string|number|boolean|datetime|array|object|reference). Type-specific options go at the top level, NOT inside a 'config' key. Use describe_collections for full schema reference."
159
+ ),
160
+ enableVersioning: z.boolean().optional().describe("Enable record versioning (default: false)"),
161
+ schemaDiscoveryMode: z
162
+ .enum(["strict", "flexible"])
163
+ .optional()
164
+ .describe("Schema discovery mode: 'strict' rejects unknown fields, 'flexible' auto-adds them"),
165
+ tags: z.array(z.string()).optional().describe("Optional tags for organizing collections"),
166
+ },
167
+ async ({ name, slug, description, properties, enableVersioning, schemaDiscoveryMode, tags }) => {
168
+ try {
169
+ const input: Record<string, any> = { name, slug };
170
+ if (description !== undefined) input.description = description;
171
+ if (properties !== undefined) input.properties = properties;
172
+ if (enableVersioning !== undefined) input.enableVersioning = enableVersioning;
173
+ if (schemaDiscoveryMode !== undefined) input.schemaDiscoveryMode = schemaDiscoveryMode;
174
+ if (tags !== undefined) input.tags = tags;
175
+ const result = await sdk.collections.create(input as any);
176
+ return {
177
+ content: [
178
+ { type: "text", text: JSON.stringify(result.data, null, 2) },
179
+ ],
180
+ };
181
+ } catch (error: unknown) {
182
+ return {
183
+ content: [
184
+ {
185
+ type: "text",
186
+ text: formatError(error, `creating collection '${slug}'`),
187
+ },
188
+ ],
189
+ isError: true,
190
+ };
191
+ }
192
+ }
193
+ );
194
+
195
+ server.tool(
196
+ "update_collection",
197
+ "Update an existing collection by ID. Only include the fields you want to change.",
198
+ {
199
+ collectionId: z.string().describe("The collection ID (UUID) to update"),
200
+ name: z.string().optional().describe("Updated display name"),
201
+ description: z.string().optional().describe("Updated description"),
202
+ properties: z
203
+ .array(z.record(z.string(), z.any()))
204
+ .optional()
205
+ .describe("Updated array of property definitions (replaces existing properties)"),
206
+ enableVersioning: z.boolean().optional().describe("Enable or disable record versioning"),
207
+ tags: z.array(z.string()).optional().describe("Updated tags"),
208
+ defaultTtlSeconds: z
209
+ .number()
210
+ .nullable()
211
+ .optional()
212
+ .describe("Default TTL in seconds for new records. Set to null to clear."),
213
+ },
214
+ async ({ collectionId, name, description, properties, enableVersioning, tags, defaultTtlSeconds }) => {
215
+ try {
216
+ const input: Record<string, any> = {};
217
+ if (name !== undefined) input.name = name;
218
+ if (description !== undefined) input.description = description;
219
+ if (properties !== undefined) input.properties = properties;
220
+ if (enableVersioning !== undefined) input.enableVersioning = enableVersioning;
221
+ if (tags !== undefined) input.tags = tags;
222
+ if (defaultTtlSeconds !== undefined) input.defaultTtlSeconds = defaultTtlSeconds;
223
+ const result = await sdk.collections.update(collectionId, input as any);
224
+ return {
225
+ content: [
226
+ { type: "text", text: JSON.stringify(result.data, null, 2) },
227
+ ],
228
+ };
229
+ } catch (error: unknown) {
230
+ return {
231
+ content: [
232
+ {
233
+ type: "text",
234
+ text: formatError(error, `updating collection '${collectionId}'`),
235
+ },
236
+ ],
237
+ isError: true,
238
+ };
239
+ }
240
+ }
241
+ );
242
+
243
+ server.tool(
244
+ "delete_collection",
245
+ "Delete a collection by ID. This permanently removes the collection schema and all its records.",
246
+ {
247
+ collectionId: z.string().describe("The collection ID (UUID) to delete"),
248
+ },
249
+ async ({ collectionId }) => {
250
+ try {
251
+ await sdk.collections.delete(collectionId);
252
+ return {
253
+ content: [
254
+ {
255
+ type: "text",
256
+ text: `Collection '${collectionId}' deleted successfully.`,
257
+ },
258
+ ],
259
+ };
260
+ } catch (error: unknown) {
261
+ return {
262
+ content: [
263
+ {
264
+ type: "text",
265
+ text: formatError(error, `deleting collection '${collectionId}'`),
266
+ },
267
+ ],
268
+ isError: true,
269
+ };
270
+ }
271
+ }
272
+ );
146
273
  }