@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,96 @@
1
+ import { toArray } from '@directus/utils';
2
+ import { z } from 'zod';
3
+ import { FoldersService } from '../../services/folders.js';
4
+ import { defineTool } from '../define.js';
5
+ import { FolderItemInputSchema, FolderItemValidateSchema, PrimaryKeyInputSchema, PrimaryKeyValidateSchema, QueryInputSchema, QueryValidateSchema, } from '../schema.js';
6
+ import prompts from './prompts/index.js';
7
+ const FoldersValidateSchema = z.discriminatedUnion('action', [
8
+ z.strictObject({
9
+ action: z.literal('create'),
10
+ data: z.union([z.array(FolderItemValidateSchema), FolderItemValidateSchema]),
11
+ query: QueryValidateSchema.optional(),
12
+ }),
13
+ z.strictObject({
14
+ action: z.literal('read'),
15
+ keys: z.array(PrimaryKeyValidateSchema).optional(),
16
+ query: QueryValidateSchema.optional(),
17
+ }),
18
+ z.strictObject({
19
+ action: z.literal('update'),
20
+ data: FolderItemValidateSchema,
21
+ keys: z.array(PrimaryKeyValidateSchema).optional(),
22
+ query: QueryValidateSchema.optional(),
23
+ }),
24
+ z.strictObject({
25
+ action: z.literal('delete'),
26
+ keys: z.array(PrimaryKeyValidateSchema),
27
+ }),
28
+ ]);
29
+ const FoldersInputSchema = z.object({
30
+ action: z.enum(['create', 'read', 'update', 'delete']).describe('The operation to perform'),
31
+ query: QueryInputSchema.optional(),
32
+ keys: z.array(PrimaryKeyInputSchema).optional(),
33
+ data: z.array(FolderItemInputSchema).optional(),
34
+ });
35
+ export const folders = defineTool({
36
+ name: 'folders',
37
+ description: prompts.folders,
38
+ annotations: {
39
+ title: 'Directus - Folders',
40
+ },
41
+ inputSchema: FoldersInputSchema,
42
+ validateSchema: FoldersValidateSchema,
43
+ async handler({ args, schema, accountability, sanitizedQuery }) {
44
+ const service = new FoldersService({
45
+ schema,
46
+ accountability,
47
+ });
48
+ if (args.action === 'create') {
49
+ const data = toArray(args.data);
50
+ const savedKeys = await service.createMany(data);
51
+ const result = await service.readMany(savedKeys, sanitizedQuery);
52
+ return {
53
+ type: 'text',
54
+ data: result || null,
55
+ };
56
+ }
57
+ if (args.action === 'read') {
58
+ let result = null;
59
+ if (args.keys) {
60
+ result = await service.readMany(args.keys, sanitizedQuery);
61
+ }
62
+ else {
63
+ result = await service.readByQuery(sanitizedQuery);
64
+ }
65
+ return {
66
+ type: 'text',
67
+ data: result || null,
68
+ };
69
+ }
70
+ if (args.action === 'update') {
71
+ let updatedKeys = [];
72
+ if (Array.isArray(args.data)) {
73
+ updatedKeys = await service.updateBatch(args.data);
74
+ }
75
+ else if (args.keys) {
76
+ updatedKeys = await service.updateMany(args.keys, args.data);
77
+ }
78
+ else {
79
+ updatedKeys = await service.updateByQuery(sanitizedQuery, args.data);
80
+ }
81
+ const result = await service.readMany(updatedKeys, sanitizedQuery);
82
+ return {
83
+ type: 'text',
84
+ data: result,
85
+ };
86
+ }
87
+ if (args.action === 'delete') {
88
+ const deletedKeys = await service.deleteMany(args.keys);
89
+ return {
90
+ type: 'text',
91
+ data: deletedKeys,
92
+ };
93
+ }
94
+ throw new Error('Invalid action.');
95
+ },
96
+ });
@@ -0,0 +1,15 @@
1
+ import type { ToolConfig } from '../types.js';
2
+ import { collections } from './collections.js';
3
+ import { fields } from './fields.js';
4
+ import { files } from './files.js';
5
+ import { flows } from './flows.js';
6
+ import { items } from './items.js';
7
+ import { operations } from './operations.js';
8
+ import { relations } from './relations.js';
9
+ import { schema } from './schema.js';
10
+ import { system } from './system.js';
11
+ import { triggerFlow } from './trigger-flow.js';
12
+ export declare const ALL_TOOLS: ToolConfig<any>[];
13
+ export declare const getAllMcpTools: () => ToolConfig<any>[];
14
+ export declare const findMcpTool: (name: string) => ToolConfig<any> | undefined;
15
+ export { collections, fields, files, flows, items, operations, relations, schema, system, triggerFlow };
@@ -0,0 +1,29 @@
1
+ import { assets } from './assets.js';
2
+ import { collections } from './collections.js';
3
+ import { fields } from './fields.js';
4
+ import { files } from './files.js';
5
+ import { flows } from './flows.js';
6
+ import { folders } from './folders.js';
7
+ import { items } from './items.js';
8
+ import { operations } from './operations.js';
9
+ import { relations } from './relations.js';
10
+ import { schema } from './schema.js';
11
+ import { system } from './system.js';
12
+ import { triggerFlow } from './trigger-flow.js';
13
+ export const ALL_TOOLS = [
14
+ system,
15
+ items,
16
+ files,
17
+ folders,
18
+ assets,
19
+ flows,
20
+ triggerFlow,
21
+ operations,
22
+ schema,
23
+ collections,
24
+ fields,
25
+ relations,
26
+ ];
27
+ export const getAllMcpTools = () => ALL_TOOLS;
28
+ export const findMcpTool = (name) => ALL_TOOLS.find((tool) => tool.name === name);
29
+ export { collections, fields, files, flows, items, operations, relations, schema, system, triggerFlow };
@@ -0,0 +1,87 @@
1
+ export declare const items: import("../types.js").ToolConfig<{
2
+ collection: string;
3
+ action: "create";
4
+ data: Record<string, any> | Record<string, any>[];
5
+ query?: {
6
+ fields?: string[] | undefined;
7
+ sort?: string[] | undefined;
8
+ filter?: Record<string, any> | undefined;
9
+ limit?: number | undefined;
10
+ offset?: number | undefined;
11
+ page?: number | undefined;
12
+ search?: string | undefined;
13
+ deep?: Record<string, any> | undefined;
14
+ alias?: Record<string, string> | undefined;
15
+ aggregate?: {
16
+ count: string[];
17
+ sum: string[];
18
+ avg: string[];
19
+ min: string[];
20
+ max: string[];
21
+ } | undefined;
22
+ backlink?: boolean | undefined;
23
+ version?: string | undefined;
24
+ versionRaw?: boolean | undefined;
25
+ export?: string | undefined;
26
+ group?: string[] | undefined;
27
+ } | undefined;
28
+ } | {
29
+ collection: string;
30
+ action: "read";
31
+ keys?: (string | number)[] | undefined;
32
+ query?: {
33
+ fields?: string[] | undefined;
34
+ sort?: string[] | undefined;
35
+ filter?: Record<string, any> | undefined;
36
+ limit?: number | undefined;
37
+ offset?: number | undefined;
38
+ page?: number | undefined;
39
+ search?: string | undefined;
40
+ deep?: Record<string, any> | undefined;
41
+ alias?: Record<string, string> | undefined;
42
+ aggregate?: {
43
+ count: string[];
44
+ sum: string[];
45
+ avg: string[];
46
+ min: string[];
47
+ max: string[];
48
+ } | undefined;
49
+ backlink?: boolean | undefined;
50
+ version?: string | undefined;
51
+ versionRaw?: boolean | undefined;
52
+ export?: string | undefined;
53
+ group?: string[] | undefined;
54
+ } | undefined;
55
+ } | {
56
+ collection: string;
57
+ action: "update";
58
+ data: Record<string, any> | Record<string, any>[];
59
+ keys?: (string | number)[] | undefined;
60
+ query?: {
61
+ fields?: string[] | undefined;
62
+ sort?: string[] | undefined;
63
+ filter?: Record<string, any> | undefined;
64
+ limit?: number | undefined;
65
+ offset?: number | undefined;
66
+ page?: number | undefined;
67
+ search?: string | undefined;
68
+ deep?: Record<string, any> | undefined;
69
+ alias?: Record<string, string> | undefined;
70
+ aggregate?: {
71
+ count: string[];
72
+ sum: string[];
73
+ avg: string[];
74
+ min: string[];
75
+ max: string[];
76
+ } | undefined;
77
+ backlink?: boolean | undefined;
78
+ version?: string | undefined;
79
+ versionRaw?: boolean | undefined;
80
+ export?: string | undefined;
81
+ group?: string[] | undefined;
82
+ } | undefined;
83
+ } | {
84
+ collection: string;
85
+ action: "delete";
86
+ keys: (string | number)[];
87
+ }>;
@@ -0,0 +1,141 @@
1
+ import { ForbiddenError, InvalidPayloadError } from '@directus/errors';
2
+ import { isSystemCollection } from '@directus/system-data';
3
+ import { toArray } from '@directus/utils';
4
+ import { isObject } from 'graphql-compose';
5
+ import { z } from 'zod';
6
+ import { ItemsService } from '../../services/items.js';
7
+ import { defineTool } from '../define.js';
8
+ import { ItemInputSchema, ItemValidateSchema, PrimaryKeyInputSchema, PrimaryKeyValidateSchema, QueryInputSchema, QueryValidateSchema, } from '../schema.js';
9
+ import prompts from './prompts/index.js';
10
+ const PartialItemInputSchema = z.strictObject({
11
+ collection: z.string(),
12
+ });
13
+ const ItemsValidateSchema = z.discriminatedUnion('action', [
14
+ PartialItemInputSchema.extend({
15
+ action: z.literal('create'),
16
+ data: z.union([z.array(ItemValidateSchema), ItemValidateSchema]),
17
+ query: QueryValidateSchema.optional(),
18
+ }),
19
+ PartialItemInputSchema.extend({
20
+ action: z.literal('read'),
21
+ keys: z.array(PrimaryKeyValidateSchema).optional(),
22
+ query: QueryValidateSchema.optional(),
23
+ }),
24
+ PartialItemInputSchema.extend({
25
+ action: z.literal('update'),
26
+ data: z.union([z.array(ItemValidateSchema), ItemValidateSchema]),
27
+ keys: z.array(PrimaryKeyValidateSchema).optional(),
28
+ query: QueryValidateSchema.optional(),
29
+ }),
30
+ PartialItemInputSchema.extend({
31
+ action: z.literal('delete'),
32
+ keys: z.array(PrimaryKeyValidateSchema),
33
+ }),
34
+ ]);
35
+ const ItemsInputSchema = z.object({
36
+ action: z.enum(['create', 'read', 'update', 'delete']).describe('The operation to perform'),
37
+ collection: z.string().describe('The name of the collection'),
38
+ query: QueryInputSchema.optional(),
39
+ keys: z.array(PrimaryKeyInputSchema).optional(),
40
+ data: z.array(ItemInputSchema).optional(),
41
+ });
42
+ export const items = defineTool({
43
+ name: 'items',
44
+ description: prompts.items,
45
+ annotations: {
46
+ title: 'Directus - Items',
47
+ },
48
+ inputSchema: ItemsInputSchema,
49
+ validateSchema: ItemsValidateSchema,
50
+ endpoint({ input, data }) {
51
+ if (!isObject(data) || !('id' in data)) {
52
+ return;
53
+ }
54
+ return ['content', input.collection, data['id']];
55
+ },
56
+ async handler({ args, schema, accountability, sanitizedQuery }) {
57
+ if (isSystemCollection(args.collection)) {
58
+ throw new InvalidPayloadError({ reason: 'Cannot provide a core collection' });
59
+ }
60
+ if (args.collection in schema.collections === false) {
61
+ throw new ForbiddenError();
62
+ }
63
+ const isSingleton = schema.collections[args.collection]?.singleton ?? false;
64
+ const itemsService = new ItemsService(args.collection, {
65
+ schema,
66
+ accountability,
67
+ });
68
+ if (args.action === 'create') {
69
+ const data = toArray(args.data);
70
+ if (isSingleton) {
71
+ if (Array.isArray(args.data)) {
72
+ throw new InvalidPayloadError({ reason: 'Invalid data payload, object exptected' });
73
+ }
74
+ await itemsService.upsertSingleton(args.data);
75
+ const item = await itemsService.readSingleton(sanitizedQuery);
76
+ return {
77
+ type: 'text',
78
+ data: item || null,
79
+ };
80
+ }
81
+ const savedKeys = await itemsService.createMany(data);
82
+ const result = await itemsService.readMany(savedKeys, sanitizedQuery);
83
+ return {
84
+ type: 'text',
85
+ data: result || null,
86
+ };
87
+ }
88
+ if (args.action === 'read') {
89
+ let result = null;
90
+ if (isSingleton) {
91
+ result = await itemsService.readSingleton(sanitizedQuery);
92
+ }
93
+ else if (args.keys) {
94
+ result = await itemsService.readMany(args.keys, sanitizedQuery);
95
+ }
96
+ else {
97
+ result = await itemsService.readByQuery(sanitizedQuery);
98
+ }
99
+ return {
100
+ type: 'text',
101
+ data: result,
102
+ };
103
+ }
104
+ if (args.action === 'update') {
105
+ if (isSingleton) {
106
+ if (Array.isArray(args.data)) {
107
+ throw new InvalidPayloadError({ reason: 'Invalid data payload, object exptected' });
108
+ }
109
+ await itemsService.upsertSingleton(args.data);
110
+ const item = await itemsService.readSingleton(sanitizedQuery);
111
+ return {
112
+ type: 'text',
113
+ data: item || null,
114
+ };
115
+ }
116
+ let updatedKeys = [];
117
+ if (Array.isArray(args.data)) {
118
+ updatedKeys = await itemsService.updateBatch(args.data);
119
+ }
120
+ else if (args.keys) {
121
+ updatedKeys = await itemsService.updateMany(args.keys, args.data);
122
+ }
123
+ else {
124
+ updatedKeys = await itemsService.updateByQuery(sanitizedQuery, args.data);
125
+ }
126
+ const result = await itemsService.readMany(updatedKeys, sanitizedQuery);
127
+ return {
128
+ type: 'text',
129
+ data: result,
130
+ };
131
+ }
132
+ if (args.action === 'delete') {
133
+ const deletedKeys = await itemsService.deleteMany(args.keys);
134
+ return {
135
+ type: 'text',
136
+ data: deletedKeys,
137
+ };
138
+ }
139
+ throw new Error('Invalid action.');
140
+ },
141
+ });
@@ -0,0 +1,171 @@
1
+ import { z } from 'zod';
2
+ export declare const OperationsValidationSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
3
+ action: z.ZodLiteral<"create">;
4
+ data: z.ZodObject<{
5
+ id: z.ZodOptional<z.ZodString>;
6
+ name: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNull]>>;
7
+ key: z.ZodOptional<z.ZodString>;
8
+ type: z.ZodOptional<z.ZodString>;
9
+ position_x: z.ZodOptional<z.ZodNumber>;
10
+ position_y: z.ZodOptional<z.ZodNumber>;
11
+ options: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
12
+ resolve: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNull]>>;
13
+ reject: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNull]>>;
14
+ flow: z.ZodOptional<z.ZodString>;
15
+ date_created: z.ZodOptional<z.ZodString>;
16
+ user_created: z.ZodOptional<z.ZodString>;
17
+ }, z.core.$strip>;
18
+ }, z.core.$strict>, z.ZodObject<{
19
+ action: z.ZodLiteral<"read">;
20
+ query: z.ZodOptional<z.ZodObject<{
21
+ fields: z.ZodOptional<z.ZodArray<z.ZodString>>;
22
+ sort: z.ZodOptional<z.ZodArray<z.ZodString>>;
23
+ filter: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
24
+ limit: z.ZodOptional<z.ZodNumber>;
25
+ offset: z.ZodOptional<z.ZodNumber>;
26
+ page: z.ZodOptional<z.ZodNumber>;
27
+ search: z.ZodOptional<z.ZodString>;
28
+ deep: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
29
+ alias: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
30
+ aggregate: z.ZodOptional<z.ZodObject<{
31
+ count: z.ZodArray<z.ZodString>;
32
+ sum: z.ZodArray<z.ZodString>;
33
+ avg: z.ZodArray<z.ZodString>;
34
+ min: z.ZodArray<z.ZodString>;
35
+ max: z.ZodArray<z.ZodString>;
36
+ }, z.core.$strip>>;
37
+ backlink: z.ZodOptional<z.ZodBoolean>;
38
+ version: z.ZodOptional<z.ZodString>;
39
+ versionRaw: z.ZodOptional<z.ZodBoolean>;
40
+ export: z.ZodOptional<z.ZodString>;
41
+ group: z.ZodOptional<z.ZodArray<z.ZodString>>;
42
+ }, z.core.$strip>>;
43
+ }, z.core.$strict>, z.ZodObject<{
44
+ action: z.ZodLiteral<"update">;
45
+ data: z.ZodObject<{
46
+ id: z.ZodOptional<z.ZodString>;
47
+ name: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNull]>>;
48
+ key: z.ZodOptional<z.ZodString>;
49
+ type: z.ZodOptional<z.ZodString>;
50
+ position_x: z.ZodOptional<z.ZodNumber>;
51
+ position_y: z.ZodOptional<z.ZodNumber>;
52
+ options: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
53
+ resolve: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNull]>>;
54
+ reject: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNull]>>;
55
+ flow: z.ZodOptional<z.ZodString>;
56
+ date_created: z.ZodOptional<z.ZodString>;
57
+ user_created: z.ZodOptional<z.ZodString>;
58
+ }, z.core.$strip>;
59
+ key: z.ZodString;
60
+ }, z.core.$strict>, z.ZodObject<{
61
+ action: z.ZodLiteral<"delete">;
62
+ key: z.ZodString;
63
+ }, z.core.$strict>]>;
64
+ export declare const OperationsInputSchema: z.ZodObject<{
65
+ action: z.ZodEnum<{
66
+ delete: "delete";
67
+ update: "update";
68
+ create: "create";
69
+ read: "read";
70
+ }>;
71
+ query: z.ZodOptional<z.ZodObject<{
72
+ fields: z.ZodOptional<z.ZodArray<z.ZodString>>;
73
+ sort: z.ZodOptional<z.ZodArray<z.ZodString>>;
74
+ filter: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
75
+ limit: z.ZodOptional<z.ZodNumber>;
76
+ offset: z.ZodOptional<z.ZodNumber>;
77
+ page: z.ZodOptional<z.ZodNumber>;
78
+ search: z.ZodOptional<z.ZodString>;
79
+ deep: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
80
+ alias: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
81
+ aggregate: z.ZodOptional<z.ZodObject<{
82
+ count: z.ZodArray<z.ZodString>;
83
+ sum: z.ZodArray<z.ZodString>;
84
+ avg: z.ZodArray<z.ZodString>;
85
+ min: z.ZodArray<z.ZodString>;
86
+ max: z.ZodArray<z.ZodString>;
87
+ }, z.core.$strip>>;
88
+ backlink: z.ZodOptional<z.ZodBoolean>;
89
+ version: z.ZodOptional<z.ZodString>;
90
+ versionRaw: z.ZodOptional<z.ZodBoolean>;
91
+ export: z.ZodOptional<z.ZodString>;
92
+ group: z.ZodOptional<z.ZodArray<z.ZodString>>;
93
+ }, z.core.$strip>>;
94
+ data: z.ZodOptional<z.ZodObject<{
95
+ id: z.ZodOptional<z.ZodString>;
96
+ name: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNull]>>;
97
+ key: z.ZodOptional<z.ZodString>;
98
+ type: z.ZodOptional<z.ZodString>;
99
+ position_x: z.ZodOptional<z.ZodNumber>;
100
+ position_y: z.ZodOptional<z.ZodNumber>;
101
+ options: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
102
+ resolve: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNull]>>;
103
+ reject: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNull]>>;
104
+ flow: z.ZodOptional<z.ZodString>;
105
+ date_created: z.ZodOptional<z.ZodString>;
106
+ user_created: z.ZodOptional<z.ZodString>;
107
+ }, z.core.$strip>>;
108
+ key: z.ZodOptional<z.ZodString>;
109
+ }, z.core.$strip>;
110
+ export declare const operations: import("../types.js").ToolConfig<{
111
+ action: "create";
112
+ data: {
113
+ id?: string | undefined;
114
+ name?: string | null | undefined;
115
+ key?: string | undefined;
116
+ type?: string | undefined;
117
+ position_x?: number | undefined;
118
+ position_y?: number | undefined;
119
+ options?: Record<string, any> | undefined;
120
+ resolve?: string | null | undefined;
121
+ reject?: string | null | undefined;
122
+ flow?: string | undefined;
123
+ date_created?: string | undefined;
124
+ user_created?: string | undefined;
125
+ };
126
+ } | {
127
+ action: "read";
128
+ query?: {
129
+ fields?: string[] | undefined;
130
+ sort?: string[] | undefined;
131
+ filter?: Record<string, any> | undefined;
132
+ limit?: number | undefined;
133
+ offset?: number | undefined;
134
+ page?: number | undefined;
135
+ search?: string | undefined;
136
+ deep?: Record<string, any> | undefined;
137
+ alias?: Record<string, string> | undefined;
138
+ aggregate?: {
139
+ count: string[];
140
+ sum: string[];
141
+ avg: string[];
142
+ min: string[];
143
+ max: string[];
144
+ } | undefined;
145
+ backlink?: boolean | undefined;
146
+ version?: string | undefined;
147
+ versionRaw?: boolean | undefined;
148
+ export?: string | undefined;
149
+ group?: string[] | undefined;
150
+ } | undefined;
151
+ } | {
152
+ action: "update";
153
+ data: {
154
+ id?: string | undefined;
155
+ name?: string | null | undefined;
156
+ key?: string | undefined;
157
+ type?: string | undefined;
158
+ position_x?: number | undefined;
159
+ position_y?: number | undefined;
160
+ options?: Record<string, any> | undefined;
161
+ resolve?: string | null | undefined;
162
+ reject?: string | null | undefined;
163
+ flow?: string | undefined;
164
+ date_created?: string | undefined;
165
+ user_created?: string | undefined;
166
+ };
167
+ key: string;
168
+ } | {
169
+ action: "delete";
170
+ key: string;
171
+ }>;
@@ -0,0 +1,77 @@
1
+ import { z } from 'zod';
2
+ import { OperationsService } from '../../services/operations.js';
3
+ import { defineTool } from '../define.js';
4
+ import { OperationItemInputSchema, OperationItemValidateSchema, QueryInputSchema, QueryValidateSchema, } from '../schema.js';
5
+ import prompts from './prompts/index.js';
6
+ export const OperationsValidationSchema = z.discriminatedUnion('action', [
7
+ z.strictObject({
8
+ action: z.literal('create'),
9
+ data: OperationItemValidateSchema,
10
+ }),
11
+ z.strictObject({
12
+ action: z.literal('read'),
13
+ query: QueryValidateSchema.optional(),
14
+ }),
15
+ z.strictObject({
16
+ action: z.literal('update'),
17
+ data: OperationItemValidateSchema,
18
+ key: z.string(),
19
+ }),
20
+ z.strictObject({
21
+ action: z.literal('delete'),
22
+ key: z.string(),
23
+ }),
24
+ ]);
25
+ export const OperationsInputSchema = z.object({
26
+ action: z.enum(['create', 'read', 'update', 'delete']).describe('The operation to perform'),
27
+ query: QueryInputSchema.optional(),
28
+ data: OperationItemInputSchema.optional(),
29
+ key: z.string().optional(),
30
+ });
31
+ export const operations = defineTool({
32
+ name: 'operations',
33
+ admin: true,
34
+ description: prompts.operations,
35
+ annotations: {
36
+ title: 'Directus - Operations',
37
+ },
38
+ inputSchema: OperationsInputSchema,
39
+ validateSchema: OperationsValidationSchema,
40
+ async handler({ args, schema, accountability, sanitizedQuery }) {
41
+ const operationService = new OperationsService({
42
+ schema,
43
+ accountability,
44
+ });
45
+ if (args.action === 'create') {
46
+ const savedKey = await operationService.createOne(args.data);
47
+ const result = await operationService.readOne(savedKey);
48
+ return {
49
+ type: 'text',
50
+ data: result || null,
51
+ };
52
+ }
53
+ if (args.action === 'read') {
54
+ const result = await operationService.readByQuery(sanitizedQuery);
55
+ return {
56
+ type: 'text',
57
+ data: result || null,
58
+ };
59
+ }
60
+ if (args.action === 'update') {
61
+ const updatedKey = await operationService.updateOne(args.key, args.data);
62
+ const result = await operationService.readOne(updatedKey, sanitizedQuery);
63
+ return {
64
+ type: 'text',
65
+ data: result || null,
66
+ };
67
+ }
68
+ if (args.action === 'delete') {
69
+ const deletedKey = await operationService.deleteOne(args.key);
70
+ return {
71
+ type: 'text',
72
+ data: deletedKey,
73
+ };
74
+ }
75
+ throw new Error('Invalid action.');
76
+ },
77
+ });
@@ -0,0 +1,8 @@
1
+ Retrieve base64-encoded file content from Directus. Returns raw file data suitable for AI vision models, image analysis,
2
+ and file operations.
3
+
4
+ **Input**: `{"id": "file-uuid"}`
5
+
6
+ **Output**: `{"data": "base64-string", "mimeType": "image/jpeg"}`
7
+
8
+ **Note**: Supports images and audio files. Respects Directus permissions.