@payloadcms/plugin-mcp 4.0.0-internal.bc5cf8c → 4.0.0-internal.bf4bcce

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 (204) hide show
  1. package/LICENSE.md +1 -1
  2. package/dist/defaultAccess.d.ts.map +1 -1
  3. package/dist/defineTool.d.ts +8 -8
  4. package/dist/defineTool.d.ts.map +1 -1
  5. package/dist/endpoint/access.d.ts +2 -7
  6. package/dist/endpoint/access.d.ts.map +1 -1
  7. package/dist/endpoint/access.js +17 -14
  8. package/dist/endpoint/access.js.map +1 -1
  9. package/dist/endpoint/index.d.ts +1 -1
  10. package/dist/endpoint/index.d.ts.map +1 -1
  11. package/dist/endpoint/index.js +91 -16
  12. package/dist/endpoint/index.js.map +1 -1
  13. package/dist/endpoint/oauth.d.ts +27 -0
  14. package/dist/endpoint/oauth.d.ts.map +1 -0
  15. package/dist/endpoint/oauth.js +61 -0
  16. package/dist/endpoint/oauth.js.map +1 -0
  17. package/dist/index.d.ts +3 -2
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +9 -2
  20. package/dist/index.js.map +1 -1
  21. package/dist/mcp/buildMcpServer.d.ts +6 -6
  22. package/dist/mcp/buildMcpServer.d.ts.map +1 -1
  23. package/dist/mcp/buildMcpServer.js +68 -34
  24. package/dist/mcp/buildMcpServer.js.map +1 -1
  25. package/dist/mcp/builtin/collections/authTools.d.ts.map +1 -1
  26. package/dist/mcp/builtin/collections/authTools.js +80 -56
  27. package/dist/mcp/builtin/collections/authTools.js.map +1 -1
  28. package/dist/mcp/builtin/collections/countTool.d.ts.map +1 -1
  29. package/dist/mcp/builtin/collections/countTool.js +10 -16
  30. package/dist/mcp/builtin/collections/countTool.js.map +1 -1
  31. package/dist/mcp/builtin/collections/countVersionsTool.d.ts.map +1 -1
  32. package/dist/mcp/builtin/collections/countVersionsTool.js +10 -15
  33. package/dist/mcp/builtin/collections/countVersionsTool.js.map +1 -1
  34. package/dist/mcp/builtin/collections/createTool.d.ts +1 -1
  35. package/dist/mcp/builtin/collections/createTool.d.ts.map +1 -1
  36. package/dist/mcp/builtin/collections/createTool.js +104 -54
  37. package/dist/mcp/builtin/collections/createTool.js.map +1 -1
  38. package/dist/mcp/builtin/collections/deleteTool.d.ts.map +1 -1
  39. package/dist/mcp/builtin/collections/deleteTool.js +45 -45
  40. package/dist/mcp/builtin/collections/deleteTool.js.map +1 -1
  41. package/dist/mcp/builtin/collections/duplicateTool.d.ts.map +1 -1
  42. package/dist/mcp/builtin/collections/duplicateTool.js +32 -39
  43. package/dist/mcp/builtin/collections/duplicateTool.js.map +1 -1
  44. package/dist/mcp/builtin/collections/fileInput.d.ts +28 -0
  45. package/dist/mcp/builtin/collections/fileInput.d.ts.map +1 -0
  46. package/dist/mcp/builtin/collections/fileInput.js +88 -0
  47. package/dist/mcp/builtin/collections/fileInput.js.map +1 -0
  48. package/dist/mcp/builtin/collections/findDistinctTool.d.ts.map +1 -1
  49. package/dist/mcp/builtin/collections/findDistinctTool.js +12 -28
  50. package/dist/mcp/builtin/collections/findDistinctTool.js.map +1 -1
  51. package/dist/mcp/builtin/collections/findTool.d.ts.map +1 -1
  52. package/dist/mcp/builtin/collections/findTool.js +29 -48
  53. package/dist/mcp/builtin/collections/findTool.js.map +1 -1
  54. package/dist/mcp/builtin/collections/findVersionByIDTool.d.ts.map +1 -1
  55. package/dist/mcp/builtin/collections/findVersionByIDTool.js +18 -28
  56. package/dist/mcp/builtin/collections/findVersionByIDTool.js.map +1 -1
  57. package/dist/mcp/builtin/collections/findVersionsTool.d.ts.map +1 -1
  58. package/dist/mcp/builtin/collections/findVersionsTool.js +17 -32
  59. package/dist/mcp/builtin/collections/findVersionsTool.js.map +1 -1
  60. package/dist/mcp/builtin/collections/getCollectionSchemaTool.d.ts.map +1 -1
  61. package/dist/mcp/builtin/collections/getCollectionSchemaTool.js +68 -12
  62. package/dist/mcp/builtin/collections/getCollectionSchemaTool.js.map +1 -1
  63. package/dist/mcp/builtin/collections/restoreVersionTool.d.ts.map +1 -1
  64. package/dist/mcp/builtin/collections/restoreVersionTool.js +15 -28
  65. package/dist/mcp/builtin/collections/restoreVersionTool.js.map +1 -1
  66. package/dist/mcp/builtin/collections/updateTool.d.ts.map +1 -1
  67. package/dist/mcp/builtin/collections/updateTool.js +67 -87
  68. package/dist/mcp/builtin/collections/updateTool.js.map +1 -1
  69. package/dist/mcp/builtin/collections/uploadInstructionsTool.d.ts +2 -0
  70. package/dist/mcp/builtin/collections/uploadInstructionsTool.d.ts.map +1 -0
  71. package/dist/mcp/builtin/collections/uploadInstructionsTool.js +55 -0
  72. package/dist/mcp/builtin/collections/uploadInstructionsTool.js.map +1 -0
  73. package/dist/mcp/builtin/formatEntityError.d.ts +16 -0
  74. package/dist/mcp/builtin/formatEntityError.d.ts.map +1 -0
  75. package/dist/mcp/builtin/formatEntityError.js +55 -0
  76. package/dist/mcp/builtin/formatEntityError.js.map +1 -0
  77. package/dist/mcp/builtin/getConfigInfoTool.d.ts.map +1 -1
  78. package/dist/mcp/builtin/getConfigInfoTool.js +5 -7
  79. package/dist/mcp/builtin/getConfigInfoTool.js.map +1 -1
  80. package/dist/mcp/builtin/globals/countVersionsTool.d.ts.map +1 -1
  81. package/dist/mcp/builtin/globals/countVersionsTool.js +10 -15
  82. package/dist/mcp/builtin/globals/countVersionsTool.js.map +1 -1
  83. package/dist/mcp/builtin/globals/findTool.d.ts.map +1 -1
  84. package/dist/mcp/builtin/globals/findTool.js +12 -18
  85. package/dist/mcp/builtin/globals/findTool.js.map +1 -1
  86. package/dist/mcp/builtin/globals/findVersionByIDTool.d.ts.map +1 -1
  87. package/dist/mcp/builtin/globals/findVersionByIDTool.js +14 -26
  88. package/dist/mcp/builtin/globals/findVersionByIDTool.js.map +1 -1
  89. package/dist/mcp/builtin/globals/findVersionsTool.d.ts.map +1 -1
  90. package/dist/mcp/builtin/globals/findVersionsTool.js +14 -31
  91. package/dist/mcp/builtin/globals/findVersionsTool.js.map +1 -1
  92. package/dist/mcp/builtin/globals/getGlobalSchemaTool.d.ts.map +1 -1
  93. package/dist/mcp/builtin/globals/getGlobalSchemaTool.js +46 -12
  94. package/dist/mcp/builtin/globals/getGlobalSchemaTool.js.map +1 -1
  95. package/dist/mcp/builtin/globals/restoreVersionTool.d.ts.map +1 -1
  96. package/dist/mcp/builtin/globals/restoreVersionTool.js +16 -24
  97. package/dist/mcp/builtin/globals/restoreVersionTool.js.map +1 -1
  98. package/dist/mcp/builtin/globals/updateTool.d.ts.map +1 -1
  99. package/dist/mcp/builtin/globals/updateTool.js +28 -37
  100. package/dist/mcp/builtin/globals/updateTool.js.map +1 -1
  101. package/dist/mcp/builtinTools.d.ts +6 -0
  102. package/dist/mcp/builtinTools.d.ts.map +1 -1
  103. package/dist/mcp/builtinTools.js +9 -3
  104. package/dist/mcp/builtinTools.js.map +1 -1
  105. package/dist/mcp/sanitizeMCPConfig.d.ts.map +1 -1
  106. package/dist/mcp/sanitizeMCPConfig.js +6 -1
  107. package/dist/mcp/sanitizeMCPConfig.js.map +1 -1
  108. package/dist/stdio.d.ts +3 -4
  109. package/dist/stdio.d.ts.map +1 -1
  110. package/dist/stdio.js +65 -45
  111. package/dist/stdio.js.map +1 -1
  112. package/dist/types.d.ts +94 -16
  113. package/dist/types.d.ts.map +1 -1
  114. package/dist/types.js +2 -4
  115. package/dist/types.js.map +1 -1
  116. package/dist/utils/camelCase.d.ts.map +1 -1
  117. package/dist/utils/resolveProjectRoot.d.ts.map +1 -1
  118. package/dist/utils/toStandardSchema.d.ts.map +1 -1
  119. package/package.json +9 -13
  120. package/src/endpoint/access.ts +14 -14
  121. package/src/endpoint/index.ts +79 -14
  122. package/src/endpoint/oauth.ts +72 -0
  123. package/src/index.ts +11 -4
  124. package/src/mcp/buildMcpServer.ts +80 -50
  125. package/src/mcp/builtin/collections/authTools.ts +80 -69
  126. package/src/mcp/builtin/collections/countTool.ts +10 -23
  127. package/src/mcp/builtin/collections/countVersionsTool.ts +10 -20
  128. package/src/mcp/builtin/collections/createTool.ts +110 -77
  129. package/src/mcp/builtin/collections/deleteTool.ts +36 -65
  130. package/src/mcp/builtin/collections/duplicateTool.ts +36 -87
  131. package/src/mcp/builtin/collections/fileInput.spec.ts +93 -0
  132. package/src/mcp/builtin/collections/fileInput.ts +127 -0
  133. package/src/mcp/builtin/collections/findDistinctTool.ts +12 -65
  134. package/src/mcp/builtin/collections/findTool.ts +25 -108
  135. package/src/mcp/builtin/collections/findVersionByIDTool.ts +16 -60
  136. package/src/mcp/builtin/collections/findVersionsTool.ts +15 -87
  137. package/src/mcp/builtin/collections/getCollectionSchemaTool.ts +60 -15
  138. package/src/mcp/builtin/collections/restoreVersionTool.ts +15 -58
  139. package/src/mcp/builtin/collections/updateTool.ts +63 -101
  140. package/src/mcp/builtin/collections/uploadInstructionsTool.ts +64 -0
  141. package/src/mcp/builtin/formatEntityError.ts +77 -0
  142. package/src/mcp/builtin/getConfigInfoTool.ts +4 -5
  143. package/src/mcp/builtin/globals/countVersionsTool.ts +10 -19
  144. package/src/mcp/builtin/globals/findTool.ts +14 -53
  145. package/src/mcp/builtin/globals/findVersionByIDTool.ts +14 -54
  146. package/src/mcp/builtin/globals/findVersionsTool.ts +15 -94
  147. package/src/mcp/builtin/globals/getGlobalSchemaTool.ts +41 -9
  148. package/src/mcp/builtin/globals/restoreVersionTool.ts +15 -47
  149. package/src/mcp/builtin/globals/updateTool.ts +39 -62
  150. package/src/mcp/builtinTools.ts +9 -2
  151. package/src/mcp/sanitizeMCPConfig.ts +6 -1
  152. package/src/stdio.ts +63 -45
  153. package/src/types.ts +95 -16
  154. package/dist/@types/assets.d.js +0 -2
  155. package/dist/@types/assets.d.js.map +0 -1
  156. package/dist/mcp/builtin/collections/formatCollectionError.d.ts +0 -9
  157. package/dist/mcp/builtin/collections/formatCollectionError.d.ts.map +0 -1
  158. package/dist/mcp/builtin/collections/formatCollectionError.js +0 -60
  159. package/dist/mcp/builtin/collections/formatCollectionError.js.map +0 -1
  160. package/dist/mcp/builtin/validateEntityData.d.ts +0 -14
  161. package/dist/mcp/builtin/validateEntityData.d.ts.map +0 -1
  162. package/dist/mcp/builtin/validateEntityData.js +0 -82
  163. package/dist/mcp/builtin/validateEntityData.js.map +0 -1
  164. package/dist/utils/getVirtualFieldNames.d.ts +0 -14
  165. package/dist/utils/getVirtualFieldNames.d.ts.map +0 -1
  166. package/dist/utils/getVirtualFieldNames.js +0 -35
  167. package/dist/utils/getVirtualFieldNames.js.map +0 -1
  168. package/dist/utils/localAPIDefaults.d.ts +0 -20
  169. package/dist/utils/localAPIDefaults.d.ts.map +0 -1
  170. package/dist/utils/localAPIDefaults.js +0 -19
  171. package/dist/utils/localAPIDefaults.js.map +0 -1
  172. package/dist/utils/schemaConversion/getEntityInputSchema.d.ts +0 -11
  173. package/dist/utils/schemaConversion/getEntityInputSchema.d.ts.map +0 -1
  174. package/dist/utils/schemaConversion/getEntityInputSchema.js +0 -34
  175. package/dist/utils/schemaConversion/getEntityInputSchema.js.map +0 -1
  176. package/dist/utils/schemaConversion/removeVirtualFieldsFromSchema.d.ts +0 -7
  177. package/dist/utils/schemaConversion/removeVirtualFieldsFromSchema.d.ts.map +0 -1
  178. package/dist/utils/schemaConversion/removeVirtualFieldsFromSchema.js +0 -20
  179. package/dist/utils/schemaConversion/removeVirtualFieldsFromSchema.js.map +0 -1
  180. package/dist/utils/schemaConversion/sanitizeEntitySchema.d.ts +0 -15
  181. package/dist/utils/schemaConversion/sanitizeEntitySchema.d.ts.map +0 -1
  182. package/dist/utils/schemaConversion/sanitizeEntitySchema.js +0 -464
  183. package/dist/utils/schemaConversion/sanitizeEntitySchema.js.map +0 -1
  184. package/dist/utils/schemaConversion/sanitizeEntitySchema.spec.js +0 -158
  185. package/dist/utils/schemaConversion/sanitizeEntitySchema.spec.js.map +0 -1
  186. package/dist/utils/transformPointDataToPayload.d.ts +0 -7
  187. package/dist/utils/transformPointDataToPayload.d.ts.map +0 -1
  188. package/dist/utils/transformPointDataToPayload.js +0 -28
  189. package/dist/utils/transformPointDataToPayload.js.map +0 -1
  190. package/dist/utils/whereSchema.d.ts +0 -9
  191. package/dist/utils/whereSchema.d.ts.map +0 -1
  192. package/dist/utils/whereSchema.js +0 -13
  193. package/dist/utils/whereSchema.js.map +0 -1
  194. package/src/@types/assets.d.ts +0 -3
  195. package/src/mcp/builtin/collections/formatCollectionError.ts +0 -84
  196. package/src/mcp/builtin/validateEntityData.ts +0 -132
  197. package/src/utils/getVirtualFieldNames.ts +0 -53
  198. package/src/utils/localAPIDefaults.ts +0 -22
  199. package/src/utils/schemaConversion/getEntityInputSchema.ts +0 -78
  200. package/src/utils/schemaConversion/removeVirtualFieldsFromSchema.ts +0 -27
  201. package/src/utils/schemaConversion/sanitizeEntitySchema.spec.ts +0 -103
  202. package/src/utils/schemaConversion/sanitizeEntitySchema.ts +0 -529
  203. package/src/utils/transformPointDataToPayload.ts +0 -40
  204. package/src/utils/whereSchema.ts +0 -24
@@ -1,20 +1,15 @@
1
- import type { PopulateType, SelectType } from 'payload'
2
-
3
- import { z } from 'zod'
1
+ import { findVersionsInputSchema } from 'payload'
4
2
 
5
3
  import { defaultAccess } from '../../../defaultAccess.js'
6
4
  import { defineCollectionTool } from '../../../defineTool.js'
7
5
  import { getLogger } from '../../../utils/getLogger.js'
8
- import { localAPIDefaults } from '../../../utils/localAPIDefaults.js'
9
- import { whereSchema } from '../../../utils/whereSchema.js'
10
6
 
11
7
  const DEFAULT_DESCRIPTION =
12
8
  'Find document versions in any version-enabled collection by passing the collection slug and optional where clause.'
13
9
 
14
10
  export const findVersionsTool = defineCollectionTool({
15
11
  access: (args) =>
16
- defaultAccess(args) &&
17
- Boolean(args.permissions?.collections?.[args.collectionSlug]?.readVersions),
12
+ defaultAccess(args) && Boolean(args.permissions?.collections?.[args.slug]?.readVersions),
18
13
  annotations: {
19
14
  destructiveHint: false,
20
15
  idempotentHint: true,
@@ -23,79 +18,13 @@ export const findVersionsTool = defineCollectionTool({
23
18
  title: 'Find Versions',
24
19
  },
25
20
  description: DEFAULT_DESCRIPTION,
26
- input: z.object({
27
- depth: z
28
- .number()
29
- .int()
30
- .min(0)
31
- .max(10)
32
- .describe('How many levels deep to populate relationships in version documents')
33
- .optional()
34
- .default(0),
35
- fallbackLocale: z
36
- .string()
37
- .describe('Optional: fallback locale code to use when requested locale is not available')
38
- .optional(),
39
- limit: z
40
- .number()
41
- .int()
42
- .min(1)
43
- .max(100)
44
- .describe('Maximum number of versions to return (default: 10, max: 100)')
45
- .optional()
46
- .default(10),
47
- locale: z
48
- .string()
49
- .describe(
50
- 'Optional: locale code to retrieve data in (e.g., "en", "es"). Use "all" to retrieve all locales for localized fields',
51
- )
52
- .optional(),
53
- page: z
54
- .number()
55
- .int()
56
- .min(1)
57
- .describe('Page number for pagination (default: 1)')
58
- .optional()
59
- .default(1),
60
- pagination: z
61
- .boolean()
62
- .describe('Optional: set to false to skip the count query overhead')
63
- .optional(),
64
- populate: z
65
- .record(z.string(), z.unknown())
66
- .describe(
67
- 'Optional: control which fields to include from populated relationship or upload documents.',
68
- )
69
- .optional(),
70
- select: z
71
- .record(z.string(), z.unknown())
72
- .describe(
73
- 'Optional: define exactly which fields you\'d like to return in the response, e.g., {"version.title": true}',
74
- )
75
- .optional(),
76
- showHiddenFields: z
77
- .boolean()
78
- .describe('Optional: include hidden fields in returned version documents')
79
- .optional(),
80
- sort: z
81
- .string()
82
- .describe('Field to sort by (e.g., "-updatedAt", "-version.updatedAt" for descending)')
83
- .optional(),
84
- trash: z
85
- .boolean()
86
- .describe('Optional: include versions for soft-deleted documents when trash is enabled')
87
- .optional(),
88
- where: whereSchema
89
- .describe(
90
- 'Optional: where clause for filtering versions. Version document fields are usually under "version". Example: {"version.title":{"contains":"test"}}',
91
- )
92
- .optional(),
93
- }),
94
- }).handler(async ({ authorizedMCP, collectionSlug, input, req }) => {
21
+ input: findVersionsInputSchema,
22
+ }).handler(async ({ slug, authorizedMCP, input, req }) => {
95
23
  const payload = req.payload
96
24
  const logger = getLogger({ payload })
97
25
  const {
98
26
  depth,
27
+ draft,
99
28
  fallbackLocale,
100
29
  limit,
101
30
  locale,
@@ -103,28 +32,27 @@ export const findVersionsTool = defineCollectionTool({
103
32
  pagination,
104
33
  populate,
105
34
  select,
106
- showHiddenFields,
107
35
  sort,
108
36
  trash,
109
37
  where,
110
38
  } = input
111
39
 
112
- logger.info(`Finding versions in collection: ${collectionSlug}, limit: ${limit}, page: ${page}`)
40
+ logger.info(`Finding versions in collection: ${slug}, limit: ${limit}, page: ${page}`)
113
41
 
114
42
  try {
115
43
  const result = await payload.findVersions({
116
- collection: collectionSlug,
44
+ collection: slug,
117
45
  depth,
118
46
  limit,
47
+ overrideAccess: authorizedMCP.overrideAccess,
119
48
  page,
120
49
  req,
121
- ...localAPIDefaults(authorizedMCP),
122
- ...(fallbackLocale ? { fallbackLocale } : {}),
50
+ ...(draft !== undefined ? { draft } : {}),
51
+ ...(fallbackLocale !== undefined ? { fallbackLocale } : {}),
123
52
  ...(locale ? { locale } : {}),
124
53
  ...(pagination !== undefined ? { pagination } : {}),
125
- ...(populate ? { populate: populate as PopulateType } : {}),
126
- ...(select ? { select: select as SelectType } : {}),
127
- ...(showHiddenFields !== undefined ? { showHiddenFields } : {}),
54
+ ...(populate ? { populate } : {}),
55
+ ...(select ? { select } : {}),
128
56
  ...(sort ? { sort } : {}),
129
57
  ...(trash !== undefined ? { trash } : {}),
130
58
  ...(where ? { where } : {}),
@@ -134,19 +62,19 @@ export const findVersionsTool = defineCollectionTool({
134
62
  content: [
135
63
  {
136
64
  type: 'text',
137
- text: `Versions for collection "${collectionSlug}":\n\`\`\`json\n${JSON.stringify(result)}\n\`\`\``,
65
+ text: `Versions for collection "${slug}":\n\`\`\`json\n${JSON.stringify(result)}\n\`\`\``,
138
66
  },
139
67
  ],
140
68
  doc: result as unknown as Record<string, unknown>,
141
69
  }
142
70
  } catch (error) {
143
71
  const errorMessage = error instanceof Error ? error.message : 'Unknown error'
144
- logger.error(`Error finding versions in ${collectionSlug}: ${errorMessage}`)
72
+ logger.error(`Error finding versions in ${slug}: ${errorMessage}`)
145
73
  return {
146
74
  content: [
147
75
  {
148
76
  type: 'text',
149
- text: `❌ **Error finding versions in collection "${collectionSlug}":** ${errorMessage}`,
77
+ text: `❌ **Error finding versions in collection "${slug}":** ${errorMessage}`,
150
78
  },
151
79
  ],
152
80
  isError: true,
@@ -1,17 +1,14 @@
1
+ import { getAccessResults, getCollectionInputSchema, getCollectionSchemaInputSchema } from 'payload'
2
+ import { getLLMInstructions } from 'payload/internal'
3
+
1
4
  import { defaultAccess } from '../../../defaultAccess.js'
2
5
  import { defineCollectionTool } from '../../../defineTool.js'
3
- import { getCollectionInputSchema } from '../../../utils/schemaConversion/getEntityInputSchema.js'
4
6
 
5
7
  export const getCollectionSchemaTool = defineCollectionTool({
6
8
  access: (args) => {
7
- const permissions = args.permissions?.collections?.[args.collectionSlug]
8
-
9
- return (
10
- defaultAccess(args) &&
11
- Boolean(
12
- permissions?.create || permissions?.delete || permissions?.read || permissions?.update,
13
- )
14
- )
9
+ const permissions = args.permissions?.collections?.[args.slug]
10
+
11
+ return defaultAccess(args) && Boolean(permissions?.create || permissions?.update)
15
12
  },
16
13
  annotations: {
17
14
  destructiveHint: false,
@@ -20,27 +17,75 @@ export const getCollectionSchemaTool = defineCollectionTool({
20
17
  readOnlyHint: true,
21
18
  title: 'Get Collection Schema',
22
19
  },
23
- description: 'Get the input schema for creating or updating documents in a collection.',
24
- }).handler(({ collectionSlug, req }) => {
25
- const inputSchema = getCollectionInputSchema({ collectionSlug, req })
20
+ description:
21
+ 'Get the input schema and LLM instructions before creating or updating documents in a collection.',
22
+ input: getCollectionSchemaInputSchema,
23
+ }).handler(async ({ slug, authorizedMCP, req }) => {
24
+ const permissions = authorizedMCP.overrideAccess
25
+ ? null
26
+ : (await getAccessResults({ req })).collections?.[slug]
27
+
28
+ if (!authorizedMCP.overrideAccess && !permissions?.create && !permissions?.update) {
29
+ return {
30
+ content: [
31
+ {
32
+ type: 'text',
33
+ text: `Error: MCP access to "getCollectionSchema" is not enabled for collection "${slug}"`,
34
+ },
35
+ ],
36
+ isError: true,
37
+ }
38
+ }
39
+
40
+ const inputSchema = getCollectionInputSchema({
41
+ collectionSlug: slug,
42
+ req,
43
+ ...(permissions ? { permissions } : {}),
44
+ })
26
45
 
27
46
  if (!inputSchema) {
28
47
  return {
29
- content: [{ type: 'text', text: `Error: Collection "${collectionSlug}" not found` }],
48
+ content: [{ type: 'text', text: `Error: Collection "${slug}" not found` }],
30
49
  isError: true,
31
50
  }
32
51
  }
33
52
 
53
+ const uploadConfig = req.payload.collections[slug]?.config.upload
54
+ const maxFileSize = req.payload.config.upload.limits?.fileSize
55
+ const upload = uploadConfig
56
+ ? {
57
+ enabled: true,
58
+ filesRequiredOnCreate: uploadConfig.filesRequiredOnCreate !== false,
59
+ mimeTypes: uploadConfig.mimeTypes ?? ['*/*'],
60
+ sources: [
61
+ ...(uploadConfig.pasteURL !== false ? ['externalURL'] : []),
62
+ 'base64',
63
+ 'uploadReference',
64
+ ],
65
+ ...(typeof maxFileSize === 'number' && Number.isFinite(maxFileSize) ? { maxFileSize } : {}),
66
+ }
67
+ : { enabled: false }
68
+
69
+ const instructions = await getLLMInstructions({
70
+ slug,
71
+ type: 'collection',
72
+ overrideAccess: authorizedMCP.overrideAccess,
73
+ req,
74
+ })
75
+
34
76
  return {
35
77
  content: [
36
78
  {
37
79
  type: 'text',
38
- text: `Schema for collection "${collectionSlug}":\n\`\`\`json\n${JSON.stringify(inputSchema)}\n\`\`\``,
80
+ text: `Schema for collection "${slug}":\n\`\`\`json\n${JSON.stringify(inputSchema)}\n\`\`\`\nUpload configuration:\n\`\`\`json\n${JSON.stringify(upload)}\n\`\`\``,
39
81
  },
82
+ ...(instructions ? [{ type: 'text' as const, text: instructions }] : []),
40
83
  ],
41
84
  structuredContent: {
42
- collectionSlug,
85
+ slug,
43
86
  schema: inputSchema,
87
+ upload,
88
+ ...(instructions ? { instructions } : {}),
44
89
  },
45
90
  }
46
91
  })
@@ -1,18 +1,15 @@
1
- import type { PopulateType, SelectType } from 'payload'
2
-
3
- import { z } from 'zod'
1
+ import { restoreVersionInputSchema } from 'payload'
4
2
 
5
3
  import { defaultAccess } from '../../../defaultAccess.js'
6
4
  import { defineCollectionTool } from '../../../defineTool.js'
7
5
  import { getLogger } from '../../../utils/getLogger.js'
8
- import { localAPIDefaults } from '../../../utils/localAPIDefaults.js'
9
6
 
10
7
  const DEFAULT_DESCRIPTION =
11
8
  'Restore a document from a previous version in any version-enabled collection.'
12
9
 
13
10
  export const restoreVersionTool = defineCollectionTool({
14
11
  access: (args) =>
15
- defaultAccess(args) && Boolean(args.permissions?.collections?.[args.collectionSlug]?.update),
12
+ defaultAccess(args) && Boolean(args.permissions?.collections?.[args.slug]?.update),
16
13
  annotations: {
17
14
  destructiveHint: true,
18
15
  idempotentHint: false,
@@ -21,85 +18,45 @@ export const restoreVersionTool = defineCollectionTool({
21
18
  title: 'Restore Version',
22
19
  },
23
20
  description: DEFAULT_DESCRIPTION,
24
- input: z.object({
25
- id: z.string().describe('The ID of the version to restore'),
26
- depth: z
27
- .number()
28
- .int()
29
- .min(0)
30
- .max(10)
31
- .describe('How many levels deep to populate relationships in response')
32
- .optional()
33
- .default(0),
34
- draft: z
35
- .boolean()
36
- .describe('Whether to restore the version as a draft')
37
- .optional()
38
- .default(false),
39
- fallbackLocale: z
40
- .string()
41
- .describe('Optional: fallback locale code to use when requested locale is not available')
42
- .optional(),
43
- locale: z
44
- .string()
45
- .describe('Optional: locale code to restore in (e.g., "en", "es")')
46
- .optional(),
47
- populate: z
48
- .record(z.string(), z.unknown())
49
- .describe(
50
- 'Optional: control which fields to include from populated relationship or upload documents.',
51
- )
52
- .optional(),
53
- select: z
54
- .record(z.string(), z.unknown())
55
- .describe(
56
- 'Optional: define exactly which fields you\'d like to return in the response, e.g., {"title": true}',
57
- )
58
- .optional(),
59
- showHiddenFields: z
60
- .boolean()
61
- .describe('Optional: include hidden fields in the restored document response')
62
- .optional(),
63
- }),
64
- }).handler(async ({ authorizedMCP, collectionSlug, input, req }) => {
21
+ input: restoreVersionInputSchema,
22
+ }).handler(async ({ slug, authorizedMCP, input, req }) => {
65
23
  const payload = req.payload
66
24
  const logger = getLogger({ payload })
67
- const { id, depth, draft, fallbackLocale, locale, populate, select, showHiddenFields } = input
25
+ const { id, depth, draft, fallbackLocale, locale, populate, select } = input
68
26
 
69
- logger.info(`Restoring version in collection: ${collectionSlug} with ID: ${id}`)
27
+ logger.info(`Restoring version in collection: ${slug} with ID: ${id}`)
70
28
 
71
29
  try {
72
30
  const result = await payload.restoreVersion({
73
- id,
74
- collection: collectionSlug,
31
+ id: String(id),
32
+ collection: slug,
75
33
  depth,
76
34
  draft,
35
+ overrideAccess: authorizedMCP.overrideAccess,
77
36
  req,
78
- ...localAPIDefaults(authorizedMCP),
79
- ...(fallbackLocale ? { fallbackLocale } : {}),
37
+ ...(fallbackLocale !== undefined ? { fallbackLocale } : {}),
80
38
  ...(locale ? { locale } : {}),
81
- ...(populate ? { populate: populate as PopulateType } : {}),
82
- ...(select ? { select: select as SelectType } : {}),
83
- ...(showHiddenFields !== undefined ? { showHiddenFields } : {}),
39
+ ...(populate ? { populate } : {}),
40
+ ...(select ? { select } : {}),
84
41
  })
85
42
 
86
43
  return {
87
44
  content: [
88
45
  {
89
46
  type: 'text',
90
- text: `Version "${id}" restored successfully in collection "${collectionSlug}"!\nRestored document:\n\`\`\`json\n${JSON.stringify(result)}\n\`\`\``,
47
+ text: `Version "${id}" restored successfully in collection "${slug}"!\nRestored document:\n\`\`\`json\n${JSON.stringify(result)}\n\`\`\``,
91
48
  },
92
49
  ],
93
50
  doc: result as Record<string, unknown>,
94
51
  }
95
52
  } catch (error) {
96
53
  const errorMessage = error instanceof Error ? error.message : 'Unknown error'
97
- logger.error(`Error restoring version ${id} in ${collectionSlug}: ${errorMessage}`)
54
+ logger.error(`Error restoring version ${id} in ${slug}: ${errorMessage}`)
98
55
  return {
99
56
  content: [
100
57
  {
101
58
  type: 'text',
102
- text: `❌ **Error restoring version "${id}" in collection "${collectionSlug}":** ${errorMessage}`,
59
+ text: `❌ **Error restoring version "${id}" in collection "${slug}":** ${errorMessage}`,
103
60
  },
104
61
  ],
105
62
  isError: true,
@@ -1,27 +1,27 @@
1
- import type { SelectType, Where } from 'payload'
1
+ import type { Where } from 'payload'
2
2
 
3
- import { z } from 'zod'
3
+ import {
4
+ getCollectionInputSchema,
5
+ getCollectionVirtualFieldNames,
6
+ parseDocumentID,
7
+ stripVirtualFields,
8
+ transformPointDataToPayload,
9
+ updateDocumentInputSchema,
10
+ validateCollectionData,
11
+ } from 'payload'
4
12
 
5
13
  import { defaultAccess } from '../../../defaultAccess.js'
6
14
  import { defineCollectionTool } from '../../../defineTool.js'
7
15
  import { getLogger } from '../../../utils/getLogger.js'
8
- import {
9
- getCollectionVirtualFieldNames,
10
- stripVirtualFields,
11
- } from '../../../utils/getVirtualFieldNames.js'
12
- import { localAPIDefaults } from '../../../utils/localAPIDefaults.js'
13
- import { getCollectionInputSchema } from '../../../utils/schemaConversion/getEntityInputSchema.js'
14
- import { transformPointDataToPayload } from '../../../utils/transformPointDataToPayload.js'
15
- import { whereSchema } from '../../../utils/whereSchema.js'
16
- import { validateCollectionData } from '../validateEntityData.js'
17
- import { formatCollectionError } from './formatCollectionError.js'
16
+ import { formatEntityError } from '../formatEntityError.js'
17
+ import { fileInputSchema, resolveFile } from './fileInput.js'
18
18
 
19
19
  const DEFAULT_DESCRIPTION =
20
- 'Update documents in any collection by passing the collection slug and data.'
20
+ 'Update documents. Prefer uploadReference after upload, externalURL for URLs, or base64 for small local files.'
21
21
 
22
22
  export const updateDocumentTool = defineCollectionTool({
23
23
  access: (args) =>
24
- defaultAccess(args) && Boolean(args.permissions?.collections?.[args.collectionSlug]?.update),
24
+ defaultAccess(args) && Boolean(args.permissions?.collections?.[args.slug]?.update),
25
25
  annotations: {
26
26
  destructiveHint: true,
27
27
  idempotentHint: false,
@@ -30,53 +30,8 @@ export const updateDocumentTool = defineCollectionTool({
30
30
  title: 'Update Document',
31
31
  },
32
32
  description: DEFAULT_DESCRIPTION,
33
- input: z.object({
34
- id: z.union([z.string(), z.number()]).describe('The ID of the document to update').optional(),
35
- data: z.record(z.string(), z.unknown()).describe('The fields to update'),
36
- depth: z
37
- .number()
38
- .describe('How many levels deep to populate relationships')
39
- .optional()
40
- .default(0),
41
- draft: z
42
- .boolean()
43
- .describe('Whether to update the document as a draft')
44
- .optional()
45
- .default(false),
46
- fallbackLocale: z
47
- .string()
48
- .describe('Optional: fallback locale code to use when requested locale is not available')
49
- .optional(),
50
- filePath: z.string().describe('File path for file uploads').optional(),
51
- locale: z
52
- .string()
53
- .describe(
54
- 'Optional: locale code to update the document in (e.g., "en", "es"). Defaults to the default locale',
55
- )
56
- .optional(),
57
- overrideLock: z
58
- .boolean()
59
- .describe('Whether to override document locks')
60
- .optional()
61
- .default(true),
62
- overwriteExistingFiles: z
63
- .boolean()
64
- .describe('Whether to overwrite existing files')
65
- .optional()
66
- .default(false),
67
- select: z
68
- .record(z.string(), z.unknown())
69
- .describe(
70
- 'Optional: define exactly which fields you\'d like to return in the response, e.g., {"title": true}',
71
- )
72
- .optional(),
73
- where: whereSchema
74
- .describe(
75
- 'Where clause to update multiple documents. Use field names with Payload operators, and/or arrays for grouping. Example: {"title":{"contains":"test"}}',
76
- )
77
- .optional(),
78
- }),
79
- }).handler(async ({ authorizedMCP, collectionSlug, input, req }) => {
33
+ input: updateDocumentInputSchema({ file: fileInputSchema }),
34
+ }).handler(async ({ slug, authorizedMCP, input, req }) => {
80
35
  const payload = req.payload
81
36
  const logger = getLogger({ payload })
82
37
 
@@ -86,97 +41,104 @@ export const updateDocumentTool = defineCollectionTool({
86
41
  depth,
87
42
  draft,
88
43
  fallbackLocale,
89
- filePath,
44
+ file: fileInput,
45
+ limit,
90
46
  locale,
91
47
  overrideLock,
92
- overwriteExistingFiles,
48
+ populate,
49
+ publishAllLocales,
50
+ returning,
93
51
  select,
52
+ sort,
53
+ trash,
54
+ unpublishAllLocales,
94
55
  where,
95
56
  } = input
96
57
 
97
58
  logger.info(
98
- `Updating document in collection: ${collectionSlug}${id ? ` with ID: ${id}` : ' with where clause'}, draft: ${draft}${locale ? `, locale: ${locale}` : ''}`,
59
+ `Updating document in collection: ${slug}${id ? ` with ID: ${id}` : ' with where clause'}, draft: ${draft}${locale ? `, locale: ${locale}` : ''}`,
99
60
  )
100
61
 
101
62
  try {
102
- if (!id && !where) {
103
- return {
104
- content: [{ type: 'text', text: 'Error: Either id or where clause must be provided' }],
105
- }
106
- }
107
-
108
- const virtualFieldNames = getCollectionVirtualFieldNames(payload.config, collectionSlug)
63
+ const virtualFieldNames = getCollectionVirtualFieldNames(payload.config, slug)
109
64
  const inputData = stripVirtualFields(data, virtualFieldNames)
110
- const validationError = validateCollectionData({
111
- collectionSlug,
65
+ validateCollectionData({
66
+ slug,
112
67
  data: inputData,
113
68
  partial: true,
114
69
  req,
115
70
  })
116
71
 
117
- if (validationError) {
118
- return validationError
119
- }
120
-
121
72
  const parsedData = transformPointDataToPayload(inputData)
73
+ const file = await resolveFile({ slug, input: fileInput, req })
122
74
 
123
75
  const whereClause: Where = where ?? {}
124
76
 
125
- if (id) {
77
+ if (id !== undefined) {
126
78
  const result = await payload.update({
127
- id,
128
- collection: collectionSlug,
79
+ id: parseDocumentID({ id, collectionSlug: slug, payload }),
80
+ collection: slug,
129
81
  data: parsedData,
130
82
  depth,
131
83
  draft,
84
+ fallbackLocale,
85
+ locale,
86
+ overrideAccess: authorizedMCP.overrideAccess,
132
87
  overrideLock,
88
+ populate,
89
+ publishAllLocales,
133
90
  req,
134
- ...localAPIDefaults(authorizedMCP),
135
- ...(filePath ? { filePath } : {}),
136
- ...(overwriteExistingFiles ? { overwriteExistingFiles } : {}),
137
- ...(locale ? { locale } : {}),
138
- ...(fallbackLocale ? { fallbackLocale } : {}),
139
- ...(select ? { select: select as SelectType } : {}),
91
+ select: returning ? select : { id: true },
92
+ trash,
93
+ unpublishAllLocales,
94
+ ...(file ? { file } : {}),
140
95
  })
141
96
 
97
+ const responseResult = returning ? result : { id: result.id }
98
+
142
99
  return {
143
100
  content: [
144
101
  {
145
102
  type: 'text',
146
- text: `Document updated successfully in collection "${collectionSlug}"!\nUpdated document:\n\`\`\`json\n${JSON.stringify(result)}\n\`\`\``,
103
+ text: `Document updated successfully in collection "${slug}"!\nResult:\n\`\`\`json\n${JSON.stringify(responseResult)}\n\`\`\``,
147
104
  },
148
105
  ],
149
- doc: result as Record<string, unknown>,
106
+ doc: responseResult as Record<string, unknown>,
150
107
  }
151
108
  }
152
109
 
153
110
  const result = await payload.update({
154
- collection: collectionSlug,
111
+ collection: slug,
155
112
  data: parsedData,
156
113
  depth,
157
114
  draft,
115
+ fallbackLocale,
116
+ limit,
117
+ locale,
118
+ overrideAccess: authorizedMCP.overrideAccess,
158
119
  overrideLock,
120
+ populate,
121
+ publishAllLocales,
159
122
  req,
123
+ select: returning ? select : { id: true },
124
+ sort,
125
+ trash,
126
+ unpublishAllLocales,
160
127
  where: whereClause,
161
- ...localAPIDefaults(authorizedMCP),
162
- ...(filePath ? { filePath } : {}),
163
- ...(overwriteExistingFiles ? { overwriteExistingFiles } : {}),
164
- ...(locale ? { locale } : {}),
165
- ...(fallbackLocale ? { fallbackLocale } : {}),
166
- ...(select ? { select: select as SelectType } : {}),
128
+ ...(file ? { file } : {}),
167
129
  })
168
130
 
169
- const docs = result.docs || []
131
+ const docs = returning ? result.docs : result.docs.map(({ id }) => ({ id }))
170
132
  const errors = result.errors || []
171
133
 
172
- let responseText = `Multiple documents updated in collection "${collectionSlug}"!\nUpdated: ${docs.length} documents\nErrors: ${errors.length}\n---`
134
+ let responseText = `Multiple documents updated in collection "${slug}"!\nUpdated: ${docs.length} documents\nErrors: ${errors.length}\n---`
173
135
  if (docs.length > 0) {
174
136
  responseText += `\n\nUpdated documents:\n\`\`\`json\n${JSON.stringify(docs)}\n\`\`\``
175
137
  }
176
138
  if (errors.length > 0) {
177
139
  responseText += `\n\nErrors:\n\`\`\`json\n${JSON.stringify(errors)}\n\`\`\``
178
140
 
179
- const errorSchema = getCollectionInputSchema({ collectionSlug, req })
141
+ const errorSchema = getCollectionInputSchema({ collectionSlug: slug, req })
180
142
 
181
143
  if (errorSchema) {
182
144
  responseText += `\n\nUse this schema for data:\n\`\`\`json\n${JSON.stringify(errorSchema)}\n\`\`\``
@@ -189,7 +151,7 @@ export const updateDocumentTool = defineCollectionTool({
189
151
  ...(errorSchema
190
152
  ? {
191
153
  structuredContent: {
192
- collectionSlug,
154
+ slug,
193
155
  docs,
194
156
  errors,
195
157
  schema: errorSchema,
@@ -205,7 +167,7 @@ export const updateDocumentTool = defineCollectionTool({
205
167
  }
206
168
  } catch (error) {
207
169
  const errorMessage = error instanceof Error ? error.message : 'Unknown error'
208
- logger.error(`Error updating document in ${collectionSlug}: ${errorMessage}`)
209
- return formatCollectionError({ action: 'updating', collectionSlug, error, req })
170
+ logger.error(`Error updating document in ${slug}: ${errorMessage}`)
171
+ return formatEntityError({ slug, action: 'updating', entity: 'collection', error, req })
210
172
  }
211
173
  })