@directus/api 30.0.0 → 31.0.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 (83) hide show
  1. package/dist/app.js +5 -0
  2. package/dist/auth/drivers/oauth2.js +17 -3
  3. package/dist/auth/drivers/openid.js +17 -3
  4. package/dist/controllers/mcp.d.ts +2 -0
  5. package/dist/controllers/mcp.js +33 -0
  6. package/dist/controllers/users.js +17 -7
  7. package/dist/controllers/versions.js +3 -2
  8. package/dist/database/errors/dialects/mssql.d.ts +1 -1
  9. package/dist/database/errors/dialects/mssql.js +18 -10
  10. package/dist/database/migrations/20250813A-add-mcp.d.ts +3 -0
  11. package/dist/database/migrations/20250813A-add-mcp.js +18 -0
  12. package/dist/database/run-ast/README.md +46 -0
  13. package/dist/mcp/define.d.ts +2 -0
  14. package/dist/mcp/define.js +3 -0
  15. package/dist/mcp/index.d.ts +1 -0
  16. package/dist/mcp/index.js +1 -0
  17. package/dist/mcp/schema.d.ts +485 -0
  18. package/dist/mcp/schema.js +219 -0
  19. package/dist/mcp/server.d.ts +97 -0
  20. package/dist/mcp/server.js +310 -0
  21. package/dist/mcp/tools/assets.d.ts +3 -0
  22. package/dist/mcp/tools/assets.js +54 -0
  23. package/dist/mcp/tools/collections.d.ts +84 -0
  24. package/dist/mcp/tools/collections.js +90 -0
  25. package/dist/mcp/tools/fields.d.ts +101 -0
  26. package/dist/mcp/tools/fields.js +157 -0
  27. package/dist/mcp/tools/files.d.ts +235 -0
  28. package/dist/mcp/tools/files.js +103 -0
  29. package/dist/mcp/tools/flows.d.ts +323 -0
  30. package/dist/mcp/tools/flows.js +85 -0
  31. package/dist/mcp/tools/folders.d.ts +95 -0
  32. package/dist/mcp/tools/folders.js +96 -0
  33. package/dist/mcp/tools/index.d.ts +15 -0
  34. package/dist/mcp/tools/index.js +29 -0
  35. package/dist/mcp/tools/items.d.ts +87 -0
  36. package/dist/mcp/tools/items.js +141 -0
  37. package/dist/mcp/tools/operations.d.ts +171 -0
  38. package/dist/mcp/tools/operations.js +77 -0
  39. package/dist/mcp/tools/prompts/assets.md +8 -0
  40. package/dist/mcp/tools/prompts/collections.md +336 -0
  41. package/dist/mcp/tools/prompts/fields.md +521 -0
  42. package/dist/mcp/tools/prompts/files.md +180 -0
  43. package/dist/mcp/tools/prompts/flows.md +495 -0
  44. package/dist/mcp/tools/prompts/folders.md +34 -0
  45. package/dist/mcp/tools/prompts/index.d.ts +16 -0
  46. package/dist/mcp/tools/prompts/index.js +19 -0
  47. package/dist/mcp/tools/prompts/items.md +317 -0
  48. package/dist/mcp/tools/prompts/operations.md +721 -0
  49. package/dist/mcp/tools/prompts/relations.md +386 -0
  50. package/dist/mcp/tools/prompts/schema.md +130 -0
  51. package/dist/mcp/tools/prompts/system-prompt-description.md +1 -0
  52. package/dist/mcp/tools/prompts/system-prompt.md +44 -0
  53. package/dist/mcp/tools/prompts/trigger-flow.md +214 -0
  54. package/dist/mcp/tools/relations.d.ts +73 -0
  55. package/dist/mcp/tools/relations.js +93 -0
  56. package/dist/mcp/tools/schema.d.ts +54 -0
  57. package/dist/mcp/tools/schema.js +317 -0
  58. package/dist/mcp/tools/system.d.ts +3 -0
  59. package/dist/mcp/tools/system.js +22 -0
  60. package/dist/mcp/tools/trigger-flow.d.ts +8 -0
  61. package/dist/mcp/tools/trigger-flow.js +48 -0
  62. package/dist/mcp/transport.d.ts +13 -0
  63. package/dist/mcp/transport.js +18 -0
  64. package/dist/mcp/types.d.ts +56 -0
  65. package/dist/mcp/types.js +1 -0
  66. package/dist/services/authentication.js +36 -0
  67. package/dist/services/fields.js +4 -4
  68. package/dist/services/items.js +14 -4
  69. package/dist/services/payload.d.ts +7 -3
  70. package/dist/services/payload.js +26 -12
  71. package/dist/services/server.js +1 -0
  72. package/dist/services/tfa.d.ts +1 -1
  73. package/dist/services/tfa.js +20 -5
  74. package/dist/services/versions.d.ts +6 -4
  75. package/dist/services/versions.js +84 -25
  76. package/dist/types/auth.d.ts +2 -1
  77. package/dist/utils/versioning/deep-map-with-schema.d.ts +23 -0
  78. package/dist/utils/versioning/deep-map-with-schema.js +81 -0
  79. package/dist/utils/versioning/handle-version.d.ts +2 -2
  80. package/dist/utils/versioning/handle-version.js +47 -43
  81. package/dist/utils/versioning/split-recursive.d.ts +4 -0
  82. package/dist/utils/versioning/split-recursive.js +27 -0
  83. package/package.json +30 -29
@@ -0,0 +1,495 @@
1
+ Manage automation flows that enable event-driven data processing and task automation. Flows consist of a trigger and a
2
+ series of operations forming a data chain.
3
+
4
+ <flow_concepts>
5
+
6
+ ## Key Concepts
7
+
8
+ **Flow** = Trigger + Operations + Data Chain
9
+
10
+ - Each flow has ONE trigger that starts execution
11
+ - Operations execute sequentially, passing data through the chain
12
+ - Data chain accumulates results from each step
13
+
14
+ After creating a flow, use the `operations` tool to add individual operations with detailed operation syntax,
15
+ positioning, and data chain usage. </flow_concepts>
16
+
17
+ <core_fields>
18
+
19
+ ## Flow Data Structure
20
+
21
+ All flows share these core fields for creation:
22
+
23
+ - `name` (required) - Flow display name
24
+ - `trigger` (required) - Trigger type: `event`, `webhook`, `schedule`, `operation`, `manual`
25
+ - `status` - `active` or `inactive` (default: `active`)
26
+ - `accountability` - `all`, `activity`, or `null` (default: `all`)
27
+ - `icon` - Icon identifier (optional)
28
+ - `color` - Hex color code (optional)
29
+ - `description` - Flow description (optional)
30
+ - `options` - Trigger-specific configuration object (optional)
31
+ - `operation` - UUID of first operation (optional, set after creating operations) </core_fields>
32
+
33
+ <crud_actions>
34
+
35
+ ## Actions
36
+
37
+ - ALWAYS show the flow URL if it is present in the result
38
+
39
+ ### `read` - List/Query Flows
40
+
41
+ ```json
42
+ {
43
+ "action": "read",
44
+ "query": {
45
+ "fields": ["id", "name", "status", "trigger", "operations"],
46
+ "filter": { "status": { "_eq": "active" } },
47
+ "limit": 10
48
+ }
49
+ }
50
+ ```
51
+
52
+ ### `create` - Create New Flow
53
+
54
+ **Required**: `name`, `trigger`
55
+
56
+ ```json
57
+ {
58
+ "action": "create",
59
+ "data": {
60
+ "name": "Send email when new post is published",
61
+ "icon": "bolt", // Optional icon
62
+ "color": "#FFA439", // Optional hex color
63
+ "description": "checks if new post is published and emails admin",
64
+ "status": "active", // active|inactive
65
+ "accountability": "all", // all|activity|null
66
+ "trigger": "event", // event|webhook|schedule|operation|manual
67
+ "options": {
68
+ // Trigger-specific configuration
69
+ "type": "action",
70
+ "scope": ["items.create"],
71
+ "collections": ["posts"]
72
+ }
73
+ }
74
+ }
75
+ ```
76
+
77
+ ### `update` - Modify Existing Flow
78
+
79
+ ```json
80
+ {
81
+ "action": "update",
82
+ "key": "flow-uuid",
83
+ "data": {
84
+ "status": "inactive",
85
+ "description": "Updated description"
86
+ }
87
+ }
88
+ ```
89
+
90
+ ### `delete` - Remove Flow
91
+
92
+ ```json
93
+ {
94
+ "action": "delete",
95
+ "key": "flow-uuid"
96
+ }
97
+ ```
98
+
99
+ </crud_actions>
100
+
101
+ <trigger_types>
102
+
103
+ ## Trigger Types & Options
104
+
105
+ ### Event Hook Trigger
106
+
107
+ Responds to data changes and system events
108
+
109
+ ```json
110
+ {
111
+ "trigger": "event",
112
+ "options": {
113
+ "type": "filter", // filter (blocking) | action (non-blocking)
114
+ "scope": ["items.create", "items.update"],
115
+ "collections": ["orders", "products"],
116
+ "return": "process_data" // For filter only: <operationKey>|$all|$last (avoid $last)
117
+ }
118
+ }
119
+ ```
120
+
121
+ **Common Scopes**:
122
+
123
+ - `items.create`, `items.update`, `items.delete` - Data operations
124
+ - `auth.login` - User authentication
125
+ - **Note**: Multiple scopes trigger flow for ANY matching event
126
+
127
+ ### Webhook Trigger
128
+
129
+ ```json
130
+ {
131
+ "trigger": "webhook",
132
+ "options": {
133
+ "method": "POST", // GET|POST
134
+ "async": false, // true = immediate response, false = wait for completion
135
+ "return": "transform_result", // Response body: <operationKey>|$all|$last (avoid $last)
136
+ "cache": false // Cache GET responses
137
+ }
138
+ }
139
+ ```
140
+
141
+ ### Schedule Trigger (CRON)
142
+
143
+ ```json
144
+ {
145
+ "trigger": "schedule",
146
+ "options": {
147
+ "cron": "0 */15 * * * *" // Every 15 minutes
148
+ }
149
+ }
150
+ ```
151
+
152
+ **CRON Format**: `second minute hour day month weekday` **Examples**:
153
+
154
+ - `"0 0 9 * * *"` - Daily at 9 AM
155
+ - `"0 30 * * * *"` - Every 30 minutes (note: runs at :30 of each hour)
156
+ - `"0 */15 * * * *"` - Every 15 minutes
157
+
158
+ ### Manual Trigger
159
+
160
+ UI button that users click to start flows
161
+
162
+ ```json
163
+ {
164
+ "trigger": "manual",
165
+ "options": {
166
+ "collections": ["posts", "products"],
167
+ "location": "item", // item|collection|both
168
+ "requireSelection": false, // Default true - requires item selection
169
+ "requireConfirmation": true,
170
+ "confirmationDescription": "AI Ghostwriter",
171
+ "async": true, // Run in background
172
+ "fields": [
173
+ {
174
+ "field": "prompt",
175
+ "type": "text",
176
+ "name": "Prompt",
177
+ "meta": {
178
+ "interface": "input-multiline",
179
+ "note": "Describe what you want to create.",
180
+ "width": "full",
181
+ "required": true
182
+ }
183
+ },
184
+ {
185
+ "field": "voice",
186
+ "type": "json",
187
+ "name": "Tone Of Voice",
188
+ "meta": {
189
+ "interface": "tags",
190
+ "options": {
191
+ "presets": ["friendly", "professional", "casual"]
192
+ }
193
+ }
194
+ },
195
+ {
196
+ "field": "colors",
197
+ "type": "json",
198
+ "name": "Color Palette",
199
+ "meta": {
200
+ "interface": "list",
201
+ "options": {
202
+ "fields": [
203
+ {
204
+ "field": "color",
205
+ "type": "string",
206
+ "meta": { "interface": "select-color" }
207
+ },
208
+ {
209
+ "field": "name",
210
+ "type": "string",
211
+ "meta": { "interface": "input" }
212
+ }
213
+ ]
214
+ }
215
+ }
216
+ }
217
+ ]
218
+ }
219
+ }
220
+ // Access confirmation inputs: {{ $trigger.body.prompt }}, {{ $trigger.body.voice }}
221
+ ```
222
+
223
+ **Field Options**: Supports non-relational Directus interfaces - `input`, `input-multiline`, `input-rich-text-md`,
224
+ `tags`, `list`, `select-color`, `select-radio`, `collection-item-dropdown`, etc.
225
+
226
+ ### Operation Trigger (Another Flow)
227
+
228
+ ```json
229
+ {
230
+ "trigger": "operation",
231
+ "options": {
232
+ "return": "final_result" // Data to return to calling flow: <operationKey>|$all|$last (avoid $last)
233
+ }
234
+ }
235
+ ```
236
+
237
+ </trigger_types>
238
+
239
+ <operations_integration>
240
+
241
+ ## Working with Operations
242
+
243
+ **Use the `operations` tool for complete details on:**
244
+
245
+ - Creating and linking operations
246
+ - 14x14 grid positioning system
247
+ - Data chain variable syntax
248
+ - Operation-specific configuration
249
+
250
+ **Workflow Process:**
251
+
252
+ 1. Create flow first to get flow ID
253
+ 2. Use `operations` tool to add/manage operations
254
+ 3. Operations execute in sequence based on resolve/reject paths
255
+ 4. Link operations via UUIDs in resolve/reject fields </operations_integration>
256
+
257
+ <flow_chaining>
258
+
259
+ ## 🔗 Flow Chaining
260
+
261
+ **When to Chain**: Reusable utilities, complex multi-step workflows, conditional branching
262
+
263
+ **How to Chain**:
264
+
265
+ 1. Child flow: `"trigger": "operation"`, `"return": "final_key"` or `"$last"`
266
+ 2. Parent flow: Use `trigger` operation with child flow UUID and payload
267
+ 3. Access child results: `{{ trigger_operation_key }}`
268
+
269
+ **Common Utility Patterns**:
270
+
271
+ ```json
272
+ // Utils → Get Globals (called by multiple flows)
273
+ {
274
+ "name": "Utils → Get Globals",
275
+ "trigger": "operation",
276
+ "options": { "return": "$last" }
277
+ }
278
+
279
+ // Utils → Send Email (reusable email sender)
280
+ {
281
+ "name": "Utils → Send Email",
282
+ "trigger": "operation",
283
+ "options": { "return": "$last" }
284
+ }
285
+
286
+ // Main flow calls utility
287
+ {
288
+ "type": "trigger",
289
+ "key": "globals",
290
+ "options": {
291
+ "flow": "utils-globals-uuid"
292
+ }
293
+ }
294
+ // Access: {{ globals.openai_api_key }}
295
+ ```
296
+
297
+ **Multi-Chain Example** (Form Notifications):
298
+
299
+ ```json
300
+ // Chains: Read Form → Format → Render Template → Send Email
301
+ {
302
+ "type": "trigger",
303
+ "key": "render",
304
+ "options": {
305
+ "flow": "utils-render-template-uuid",
306
+ "payload": "{{ format }}"
307
+ }
308
+ }
309
+ ```
310
+
311
+ **Best Practices**:
312
+
313
+ - Name utilities with "Utils →" prefix for clarity
314
+ - Use `$last` return for simple utilities, specific keys for complex ones
315
+ - Chain utilities together for modular, reusable workflows
316
+ - Keep each utility focused on single responsibility </flow_chaining>
317
+
318
+ <data_chain_warning>
319
+
320
+ ## Data Chain Access
321
+
322
+ **See the `operations` tool for complete data chain syntax and examples.**
323
+
324
+ Operations can access:
325
+
326
+ - `$trigger` - Initial trigger data
327
+ - `$accountability` - User/permission context
328
+ - `$env` - Environment variables
329
+ - `<operationKey>` - Result of specific operation (recommended)
330
+ - `$last` - Result of previous operation (avoid - breaks when reordered) </data_chain_warning>
331
+
332
+ <real_world_examples>
333
+
334
+ ## Real-World Examples
335
+
336
+ ### Post Approval Email (Event-Driven)
337
+
338
+ ```json
339
+ {
340
+ "action": "create",
341
+ "data": {
342
+ "name": "[Website] Post Approval",
343
+ "icon": "mark_email_read",
344
+ "color": "#18222F",
345
+ "description": "Send email when posts are ready for review",
346
+ "status": "active",
347
+ "trigger": "event",
348
+ "accountability": "all",
349
+ "options": {
350
+ "type": "action", // Non-blocking
351
+ "scope": ["items.update"],
352
+ "collections": ["posts"]
353
+ }
354
+ }
355
+ }
356
+ // Then add operations: Check Status → Send Email
357
+ ```
358
+
359
+ ### Auto-Generate Slugs (Event-Driven)
360
+
361
+ ```json
362
+ {
363
+ "action": "create",
364
+ "data": {
365
+ "name": "[Website] Slugify",
366
+ "icon": "link",
367
+ "color": "#18222F",
368
+ "description": "Generate slugs for pages, posts, and categories",
369
+ "status": "active",
370
+ "trigger": "event",
371
+ "accountability": "all",
372
+ "options": {
373
+ "type": "action",
374
+ "scope": ["items.create"],
375
+ "collections": ["pages", "posts", "categories"]
376
+ }
377
+ }
378
+ }
379
+ ```
380
+
381
+ ### Create Scheduled Task
382
+
383
+ ```json
384
+ {
385
+ "action": "create",
386
+ "data": {
387
+ "name": "Daily Report",
388
+ "trigger": "schedule",
389
+ "status": "active",
390
+ "options": {
391
+ "cron": "0 0 9 * * *" // 9 AM daily
392
+ }
393
+ }
394
+ }
395
+ ```
396
+
397
+ ### Project Creator with Template (Manual + Confirmation)
398
+
399
+ ```json
400
+ {
401
+ "action": "create",
402
+ "data": {
403
+ "name": "[Projects] Create Project",
404
+ "trigger": "manual",
405
+ "status": "active",
406
+ "options": {
407
+ "collections": ["os_projects", "organizations"],
408
+ "requireSelection": false, // Can trigger without selection
409
+ "requireConfirmation": true,
410
+ "confirmationDescription": "Create a New Project 🚀",
411
+ "fields": [
412
+ {
413
+ "field": "name",
414
+ "type": "string",
415
+ "name": "Project Name",
416
+ "meta": {
417
+ "interface": "input",
418
+ "required": true
419
+ }
420
+ },
421
+ {
422
+ "field": "organization",
423
+ "type": "json",
424
+ "name": "Organization",
425
+ "meta": {
426
+ "interface": "collection-item-dropdown",
427
+ "required": true,
428
+ "options": {
429
+ "selectedCollection": "organizations"
430
+ }
431
+ }
432
+ }
433
+ ]
434
+ }
435
+ }
436
+ }
437
+ ```
438
+
439
+ ### Utility Flow (Operation Trigger)
440
+
441
+ ````json
442
+ {
443
+ "action": "create",
444
+ "data": {
445
+ "name": "[Util] Get Globals",
446
+ "trigger": "operation",
447
+ "accountability": "all",
448
+ "options": {
449
+ "return": "global_data" // Returns data to calling flow: <operationKey>|$all|$last
450
+ }
451
+ }
452
+ }
453
+ // Called by other flows using trigger operation
454
+ ```
455
+ </real_world_examples>
456
+
457
+ <important_notes>
458
+ ## Important Notes
459
+
460
+ - **Admin Required**: This tool requires admin permissions
461
+ - **Data Format**: Pass `data` as native objects, NOT stringified JSON
462
+ - **Flow Execution**: Flows with `operations` array will include their operations
463
+ - **Webhook URL**: After creating webhook trigger, URL is `/flows/trigger/<flow-id>`
464
+ - **Event Blocking**: Filter events pause transaction until flow completes
465
+ - **Logs**: Flow executions are logged (check `accountability` setting)
466
+ </important_notes>
467
+
468
+ <common_mistakes>
469
+ ## Common Mistakes to Avoid
470
+
471
+ 1. **DO NOT** create operations here - use the `operations` tool
472
+ 2. **DO NOT** trigger flows here - use the `trigger-flow` tool
473
+ 3. **DO NOT** pass stringified JSON in data parameter
474
+ 4. **DO NOT** forget required fields: `name` and `trigger` for creation
475
+ 5. **DO NOT** put options outside of data - it goes inside the flow object:
476
+ ```json
477
+ // ✅ CORRECT
478
+ {
479
+ "action": "create",
480
+ "data": {
481
+ "name": "My Flow",
482
+ "trigger": "event",
483
+ "options": { "type": "action" }
484
+ }
485
+ }
486
+
487
+ // ❌ WRONG
488
+ {
489
+ "action": "create",
490
+ "data": { "name": "My Flow", "trigger": "event" },
491
+ "options": { "type": "action" }
492
+ }
493
+ ```
494
+ </common_mistakes>
495
+ ````
@@ -0,0 +1,34 @@
1
+ Perform CRUD operations on Directus Folders. Folders are used to organize files in Directus.
2
+
3
+ ## Available Actions
4
+
5
+ - `create`: Add new folders records
6
+ - `read`: List/query metadata or get specific items by ID
7
+ - `update`: Modify existing metadata (title, description, tags, folder)
8
+ - `delete`: Remove folders by keys
9
+
10
+ ## Common Operations
11
+
12
+ ### Create Folder
13
+
14
+ ```json
15
+ {
16
+ "action": "create",
17
+ "data": {
18
+ "name": "Product Images",
19
+ "parent": "parent-folder-uuid"
20
+ }
21
+ }
22
+ ```
23
+
24
+ ## Important Notes
25
+
26
+ - **Folders are virtual**: Folders are not mirrored with the storage adaptor, only stored in the database.
27
+ - **Permissions**: Respects Directus access control - only accessible files are returned. If you don't see something
28
+ that the user says you should have access to, it could be a permissions issue.
29
+ - **Folder Hierarchy**: Deleting a folder requires it to be empty or will cascade based on settings
30
+
31
+ ## Mistakes to Avoid
32
+
33
+ 1. **Remember** that `keys` expects an array even for single items
34
+ 2. **Tags must be arrays**: Use `["tag1", "tag2"]` not `"tag1, tag2"`
@@ -0,0 +1,16 @@
1
+ declare const _default: {
2
+ assets: string;
3
+ collections: string;
4
+ fields: string;
5
+ files: string;
6
+ folders: string;
7
+ flows: string;
8
+ items: string;
9
+ operations: string;
10
+ relations: string;
11
+ schema: string;
12
+ systemPrompt: string;
13
+ systemPromptDescription: string;
14
+ triggerFlow: string;
15
+ };
16
+ export default _default;
@@ -0,0 +1,19 @@
1
+ import fse from 'fs-extra';
2
+ import { dirname, join } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ const __dirname = dirname(fileURLToPath(import.meta.url));
5
+ export default {
6
+ assets: fse.readFileSync(join(__dirname, 'assets.md'), 'utf8'),
7
+ collections: fse.readFileSync(join(__dirname, 'collections.md'), 'utf8'),
8
+ fields: fse.readFileSync(join(__dirname, 'fields.md'), 'utf8'),
9
+ files: fse.readFileSync(join(__dirname, 'files.md'), 'utf8'),
10
+ folders: fse.readFileSync(join(__dirname, 'folders.md'), 'utf8'),
11
+ flows: fse.readFileSync(join(__dirname, 'flows.md'), 'utf8'),
12
+ items: fse.readFileSync(join(__dirname, 'items.md'), 'utf8'),
13
+ operations: fse.readFileSync(join(__dirname, 'operations.md'), 'utf8'),
14
+ relations: fse.readFileSync(join(__dirname, 'relations.md'), 'utf8'),
15
+ schema: fse.readFileSync(join(__dirname, 'schema.md'), 'utf8'),
16
+ systemPrompt: fse.readFileSync(join(__dirname, 'system-prompt.md'), 'utf8'),
17
+ systemPromptDescription: fse.readFileSync(join(__dirname, 'system-prompt-description.md'), 'utf8'),
18
+ triggerFlow: fse.readFileSync(join(__dirname, 'trigger-flow.md'), 'utf8'),
19
+ };