@centrali-io/centrali-mcp 4.2.0 → 4.2.2
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 +25 -1
- package/dist/index.js +4 -0
- package/dist/tools/compute.js +323 -0
- package/dist/tools/describe.d.ts +10 -0
- package/dist/tools/describe.js +1485 -0
- package/dist/tools/orchestrations.js +146 -0
- package/dist/tools/pages.d.ts +3 -0
- package/dist/tools/pages.js +477 -0
- package/dist/tools/smart-queries.js +152 -0
- package/dist/tools/structures.js +117 -0
- package/package.json +2 -2
- package/src/index.ts +4 -0
- package/src/tools/compute.ts +371 -0
- package/src/tools/describe.ts +1798 -0
- package/src/tools/orchestrations.ts +167 -0
- package/src/tools/pages.ts +573 -0
- package/src/tools/smart-queries.ts +175 -0
- package/src/tools/structures.ts +123 -0
|
@@ -100,4 +100,179 @@ export function registerSmartQueryTools(server: McpServer, sdk: CentraliSDK) {
|
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
102
|
);
|
|
103
|
+
|
|
104
|
+
server.tool(
|
|
105
|
+
"get_smart_query",
|
|
106
|
+
"Get a smart query by ID. Returns the full query definition including filters, sort, and variable declarations.",
|
|
107
|
+
{
|
|
108
|
+
recordSlug: z.string().describe("The structure's record slug the query belongs to"),
|
|
109
|
+
queryId: z.string().describe("The smart query ID (UUID)"),
|
|
110
|
+
},
|
|
111
|
+
async ({ recordSlug, queryId }) => {
|
|
112
|
+
try {
|
|
113
|
+
const result = await sdk.smartQueries.get(recordSlug, queryId);
|
|
114
|
+
return {
|
|
115
|
+
content: [
|
|
116
|
+
{ type: "text", text: JSON.stringify(result.data, null, 2) },
|
|
117
|
+
],
|
|
118
|
+
};
|
|
119
|
+
} catch (error: unknown) {
|
|
120
|
+
return {
|
|
121
|
+
content: [
|
|
122
|
+
{
|
|
123
|
+
type: "text",
|
|
124
|
+
text: formatError(error, `getting smart query '${queryId}'`),
|
|
125
|
+
},
|
|
126
|
+
],
|
|
127
|
+
isError: true,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
server.tool(
|
|
134
|
+
"create_smart_query",
|
|
135
|
+
"Create a new smart query for a collection. Smart queries are reusable, parameterized queries with filter, sort, and variable support.",
|
|
136
|
+
{
|
|
137
|
+
recordSlug: z.string().describe("The structure's record slug to create the query for"),
|
|
138
|
+
name: z.string().describe("Display name for the smart query"),
|
|
139
|
+
description: z.string().optional().describe("Optional description"),
|
|
140
|
+
queryDefinition: z
|
|
141
|
+
.record(z.string(), z.any())
|
|
142
|
+
.describe("The query definition object with where, sort, limit, select, join, etc."),
|
|
143
|
+
},
|
|
144
|
+
async ({ recordSlug, name, description, queryDefinition }) => {
|
|
145
|
+
try {
|
|
146
|
+
const input: Record<string, any> = { name, queryDefinition };
|
|
147
|
+
if (description !== undefined) input.description = description;
|
|
148
|
+
|
|
149
|
+
const result = await sdk.smartQueries.create(recordSlug, input as any);
|
|
150
|
+
return {
|
|
151
|
+
content: [
|
|
152
|
+
{ type: "text", text: JSON.stringify(result.data, null, 2) },
|
|
153
|
+
],
|
|
154
|
+
};
|
|
155
|
+
} catch (error: unknown) {
|
|
156
|
+
return {
|
|
157
|
+
content: [
|
|
158
|
+
{
|
|
159
|
+
type: "text",
|
|
160
|
+
text: formatError(error, `creating smart query '${name}' for '${recordSlug}'`),
|
|
161
|
+
},
|
|
162
|
+
],
|
|
163
|
+
isError: true,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
server.tool(
|
|
170
|
+
"update_smart_query",
|
|
171
|
+
"Update an existing smart query. Only include the fields you want to change.",
|
|
172
|
+
{
|
|
173
|
+
recordSlug: z.string().describe("The structure's record slug the query belongs to"),
|
|
174
|
+
queryId: z.string().describe("The smart query ID (UUID) to update"),
|
|
175
|
+
name: z.string().optional().describe("Updated display name"),
|
|
176
|
+
description: z.string().optional().describe("Updated description"),
|
|
177
|
+
queryDefinition: z
|
|
178
|
+
.record(z.string(), z.any())
|
|
179
|
+
.optional()
|
|
180
|
+
.describe("Updated query definition object"),
|
|
181
|
+
},
|
|
182
|
+
async ({ recordSlug, queryId, name, description, queryDefinition }) => {
|
|
183
|
+
try {
|
|
184
|
+
const input: Record<string, any> = {};
|
|
185
|
+
if (name !== undefined) input.name = name;
|
|
186
|
+
if (description !== undefined) input.description = description;
|
|
187
|
+
if (queryDefinition !== undefined) input.queryDefinition = queryDefinition;
|
|
188
|
+
|
|
189
|
+
const result = await sdk.smartQueries.update(recordSlug, queryId, input as any);
|
|
190
|
+
return {
|
|
191
|
+
content: [
|
|
192
|
+
{ type: "text", text: JSON.stringify(result.data, null, 2) },
|
|
193
|
+
],
|
|
194
|
+
};
|
|
195
|
+
} catch (error: unknown) {
|
|
196
|
+
return {
|
|
197
|
+
content: [
|
|
198
|
+
{
|
|
199
|
+
type: "text",
|
|
200
|
+
text: formatError(error, `updating smart query '${queryId}'`),
|
|
201
|
+
},
|
|
202
|
+
],
|
|
203
|
+
isError: true,
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
);
|
|
208
|
+
|
|
209
|
+
server.tool(
|
|
210
|
+
"delete_smart_query",
|
|
211
|
+
"Delete a smart query by ID.",
|
|
212
|
+
{
|
|
213
|
+
recordSlug: z.string().describe("The structure's record slug the query belongs to"),
|
|
214
|
+
queryId: z.string().describe("The smart query ID (UUID) to delete"),
|
|
215
|
+
},
|
|
216
|
+
async ({ recordSlug, queryId }) => {
|
|
217
|
+
try {
|
|
218
|
+
await sdk.smartQueries.delete(recordSlug, queryId);
|
|
219
|
+
return {
|
|
220
|
+
content: [
|
|
221
|
+
{
|
|
222
|
+
type: "text",
|
|
223
|
+
text: `Smart query '${queryId}' deleted from '${recordSlug}'.`,
|
|
224
|
+
},
|
|
225
|
+
],
|
|
226
|
+
};
|
|
227
|
+
} catch (error: unknown) {
|
|
228
|
+
return {
|
|
229
|
+
content: [
|
|
230
|
+
{
|
|
231
|
+
type: "text",
|
|
232
|
+
text: formatError(error, `deleting smart query '${queryId}'`),
|
|
233
|
+
},
|
|
234
|
+
],
|
|
235
|
+
isError: true,
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
);
|
|
240
|
+
|
|
241
|
+
server.tool(
|
|
242
|
+
"test_smart_query",
|
|
243
|
+
"Test execute a query definition without saving it. Useful for validating query syntax and previewing results before creating a smart query.",
|
|
244
|
+
{
|
|
245
|
+
recordSlug: z.string().describe("The structure's record slug to test against"),
|
|
246
|
+
queryDefinition: z
|
|
247
|
+
.record(z.string(), z.any())
|
|
248
|
+
.describe("The query definition to test (where, sort, limit, select, etc.)"),
|
|
249
|
+
variables: z
|
|
250
|
+
.record(z.string(), z.string())
|
|
251
|
+
.optional()
|
|
252
|
+
.describe("Optional variables to substitute in the query"),
|
|
253
|
+
},
|
|
254
|
+
async ({ recordSlug, queryDefinition, variables }) => {
|
|
255
|
+
try {
|
|
256
|
+
const input: Record<string, any> = { queryDefinition };
|
|
257
|
+
if (variables !== undefined) input.variables = variables;
|
|
258
|
+
|
|
259
|
+
const result = await sdk.smartQueries.test(recordSlug, input as any);
|
|
260
|
+
return {
|
|
261
|
+
content: [
|
|
262
|
+
{ type: "text", text: JSON.stringify(result.data, null, 2) },
|
|
263
|
+
],
|
|
264
|
+
};
|
|
265
|
+
} catch (error: unknown) {
|
|
266
|
+
return {
|
|
267
|
+
content: [
|
|
268
|
+
{
|
|
269
|
+
type: "text",
|
|
270
|
+
text: formatError(error, `test-executing smart query for '${recordSlug}'`),
|
|
271
|
+
},
|
|
272
|
+
],
|
|
273
|
+
isError: true,
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
);
|
|
103
278
|
}
|
package/src/tools/structures.ts
CHANGED
|
@@ -143,4 +143,127 @@ 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("Array of property definitions. Each property has name, type, and optional config (required, unique, defaultValue, description, config)"),
|
|
158
|
+
enableVersioning: z.boolean().optional().describe("Enable record versioning (default: false)"),
|
|
159
|
+
schemaDiscoveryMode: z
|
|
160
|
+
.enum(["strict", "flexible"])
|
|
161
|
+
.optional()
|
|
162
|
+
.describe("Schema discovery mode: 'strict' rejects unknown fields, 'flexible' auto-adds them"),
|
|
163
|
+
tags: z.array(z.string()).optional().describe("Optional tags for organizing collections"),
|
|
164
|
+
},
|
|
165
|
+
async ({ name, slug, description, properties, enableVersioning, schemaDiscoveryMode, tags }) => {
|
|
166
|
+
try {
|
|
167
|
+
const input: Record<string, any> = { name, slug };
|
|
168
|
+
if (description !== undefined) input.description = description;
|
|
169
|
+
if (properties !== undefined) input.properties = properties;
|
|
170
|
+
if (enableVersioning !== undefined) input.enableVersioning = enableVersioning;
|
|
171
|
+
if (schemaDiscoveryMode !== undefined) input.schemaDiscoveryMode = schemaDiscoveryMode;
|
|
172
|
+
if (tags !== undefined) input.tags = tags;
|
|
173
|
+
|
|
174
|
+
const result = await sdk.collections.create(input as any);
|
|
175
|
+
return {
|
|
176
|
+
content: [
|
|
177
|
+
{ type: "text", text: JSON.stringify(result.data, null, 2) },
|
|
178
|
+
],
|
|
179
|
+
};
|
|
180
|
+
} catch (error: unknown) {
|
|
181
|
+
return {
|
|
182
|
+
content: [
|
|
183
|
+
{
|
|
184
|
+
type: "text",
|
|
185
|
+
text: formatError(error, `creating collection '${slug}'`),
|
|
186
|
+
},
|
|
187
|
+
],
|
|
188
|
+
isError: true,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
);
|
|
193
|
+
|
|
194
|
+
server.tool(
|
|
195
|
+
"update_collection",
|
|
196
|
+
"Update an existing collection by ID. Only include the fields you want to change.",
|
|
197
|
+
{
|
|
198
|
+
collectionId: z.string().describe("The collection ID (UUID) to update"),
|
|
199
|
+
name: z.string().optional().describe("Updated display name"),
|
|
200
|
+
description: z.string().optional().describe("Updated description"),
|
|
201
|
+
properties: z
|
|
202
|
+
.array(z.record(z.string(), z.any()))
|
|
203
|
+
.optional()
|
|
204
|
+
.describe("Updated array of property definitions (replaces existing properties)"),
|
|
205
|
+
enableVersioning: z.boolean().optional().describe("Enable or disable record versioning"),
|
|
206
|
+
tags: z.array(z.string()).optional().describe("Updated tags"),
|
|
207
|
+
defaultTtlSeconds: z.number().nullable().optional().describe("Default TTL in seconds for new records. Set to null to clear."),
|
|
208
|
+
},
|
|
209
|
+
async ({ collectionId, name, description, properties, enableVersioning, tags, defaultTtlSeconds }) => {
|
|
210
|
+
try {
|
|
211
|
+
const input: Record<string, any> = {};
|
|
212
|
+
if (name !== undefined) input.name = name;
|
|
213
|
+
if (description !== undefined) input.description = description;
|
|
214
|
+
if (properties !== undefined) input.properties = properties;
|
|
215
|
+
if (enableVersioning !== undefined) input.enableVersioning = enableVersioning;
|
|
216
|
+
if (tags !== undefined) input.tags = tags;
|
|
217
|
+
if (defaultTtlSeconds !== undefined) input.defaultTtlSeconds = defaultTtlSeconds;
|
|
218
|
+
|
|
219
|
+
const result = await sdk.collections.update(collectionId, input as any);
|
|
220
|
+
return {
|
|
221
|
+
content: [
|
|
222
|
+
{ type: "text", text: JSON.stringify(result.data, null, 2) },
|
|
223
|
+
],
|
|
224
|
+
};
|
|
225
|
+
} catch (error: unknown) {
|
|
226
|
+
return {
|
|
227
|
+
content: [
|
|
228
|
+
{
|
|
229
|
+
type: "text",
|
|
230
|
+
text: formatError(error, `updating collection '${collectionId}'`),
|
|
231
|
+
},
|
|
232
|
+
],
|
|
233
|
+
isError: true,
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
);
|
|
238
|
+
|
|
239
|
+
server.tool(
|
|
240
|
+
"delete_collection",
|
|
241
|
+
"Delete a collection by ID. This permanently removes the collection schema and all its records.",
|
|
242
|
+
{
|
|
243
|
+
collectionId: z.string().describe("The collection ID (UUID) to delete"),
|
|
244
|
+
},
|
|
245
|
+
async ({ collectionId }) => {
|
|
246
|
+
try {
|
|
247
|
+
await sdk.collections.delete(collectionId);
|
|
248
|
+
return {
|
|
249
|
+
content: [
|
|
250
|
+
{
|
|
251
|
+
type: "text",
|
|
252
|
+
text: `Collection '${collectionId}' deleted successfully.`,
|
|
253
|
+
},
|
|
254
|
+
],
|
|
255
|
+
};
|
|
256
|
+
} catch (error: unknown) {
|
|
257
|
+
return {
|
|
258
|
+
content: [
|
|
259
|
+
{
|
|
260
|
+
type: "text",
|
|
261
|
+
text: formatError(error, `deleting collection '${collectionId}'`),
|
|
262
|
+
},
|
|
263
|
+
],
|
|
264
|
+
isError: true,
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
);
|
|
146
269
|
}
|