@payloadcms/plugin-mcp 4.0.0-internal.c7d5de4 → 4.0.0-internal.cc18726

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 (166) hide show
  1. package/dist/endpoint/access.js +2 -2
  2. package/dist/endpoint/access.js.map +1 -1
  3. package/dist/mcp/buildMcpServer.d.ts +1 -1
  4. package/dist/mcp/buildMcpServer.d.ts.map +1 -1
  5. package/dist/mcp/buildMcpServer.js +35 -23
  6. package/dist/mcp/buildMcpServer.js.map +1 -1
  7. package/dist/mcp/builtin/collections/authTools.d.ts.map +1 -1
  8. package/dist/mcp/builtin/collections/authTools.js +79 -56
  9. package/dist/mcp/builtin/collections/authTools.js.map +1 -1
  10. package/dist/mcp/builtin/collections/countTool.d.ts.map +1 -1
  11. package/dist/mcp/builtin/collections/countTool.js +9 -14
  12. package/dist/mcp/builtin/collections/countTool.js.map +1 -1
  13. package/dist/mcp/builtin/collections/countVersionsTool.d.ts.map +1 -1
  14. package/dist/mcp/builtin/collections/countVersionsTool.js +9 -13
  15. package/dist/mcp/builtin/collections/countVersionsTool.js.map +1 -1
  16. package/dist/mcp/builtin/collections/createTool.d.ts +1 -1
  17. package/dist/mcp/builtin/collections/createTool.d.ts.map +1 -1
  18. package/dist/mcp/builtin/collections/createTool.js +94 -60
  19. package/dist/mcp/builtin/collections/createTool.js.map +1 -1
  20. package/dist/mcp/builtin/collections/deleteTool.d.ts.map +1 -1
  21. package/dist/mcp/builtin/collections/deleteTool.js +40 -43
  22. package/dist/mcp/builtin/collections/deleteTool.js.map +1 -1
  23. package/dist/mcp/builtin/collections/duplicateTool.d.ts.map +1 -1
  24. package/dist/mcp/builtin/collections/duplicateTool.js +15 -34
  25. package/dist/mcp/builtin/collections/duplicateTool.js.map +1 -1
  26. package/dist/mcp/builtin/collections/fileInput.d.ts +21 -13
  27. package/dist/mcp/builtin/collections/fileInput.d.ts.map +1 -1
  28. package/dist/mcp/builtin/collections/fileInput.js +40 -17
  29. package/dist/mcp/builtin/collections/fileInput.js.map +1 -1
  30. package/dist/mcp/builtin/collections/fileInput.spec.js +20 -6
  31. package/dist/mcp/builtin/collections/fileInput.spec.js.map +1 -1
  32. package/dist/mcp/builtin/collections/findDistinctTool.d.ts.map +1 -1
  33. package/dist/mcp/builtin/collections/findDistinctTool.js +11 -26
  34. package/dist/mcp/builtin/collections/findDistinctTool.js.map +1 -1
  35. package/dist/mcp/builtin/collections/findTool.d.ts.map +1 -1
  36. package/dist/mcp/builtin/collections/findTool.js +21 -43
  37. package/dist/mcp/builtin/collections/findTool.js.map +1 -1
  38. package/dist/mcp/builtin/collections/findVersionByIDTool.d.ts.map +1 -1
  39. package/dist/mcp/builtin/collections/findVersionByIDTool.js +17 -26
  40. package/dist/mcp/builtin/collections/findVersionByIDTool.js.map +1 -1
  41. package/dist/mcp/builtin/collections/findVersionsTool.d.ts.map +1 -1
  42. package/dist/mcp/builtin/collections/findVersionsTool.js +16 -30
  43. package/dist/mcp/builtin/collections/findVersionsTool.js.map +1 -1
  44. package/dist/mcp/builtin/collections/formatCollectionError.d.ts +2 -2
  45. package/dist/mcp/builtin/collections/formatCollectionError.d.ts.map +1 -1
  46. package/dist/mcp/builtin/collections/formatCollectionError.js +6 -6
  47. package/dist/mcp/builtin/collections/formatCollectionError.js.map +1 -1
  48. package/dist/mcp/builtin/collections/getCollectionSchemaTool.d.ts.map +1 -1
  49. package/dist/mcp/builtin/collections/getCollectionSchemaTool.js +15 -14
  50. package/dist/mcp/builtin/collections/getCollectionSchemaTool.js.map +1 -1
  51. package/dist/mcp/builtin/collections/restoreVersionTool.d.ts.map +1 -1
  52. package/dist/mcp/builtin/collections/restoreVersionTool.js +14 -26
  53. package/dist/mcp/builtin/collections/restoreVersionTool.js.map +1 -1
  54. package/dist/mcp/builtin/collections/updateTool.d.ts.map +1 -1
  55. package/dist/mcp/builtin/collections/updateTool.js +38 -80
  56. package/dist/mcp/builtin/collections/updateTool.js.map +1 -1
  57. package/dist/mcp/builtin/collections/uploadInstructionsTool.d.ts +2 -0
  58. package/dist/mcp/builtin/collections/uploadInstructionsTool.d.ts.map +1 -0
  59. package/dist/mcp/builtin/collections/uploadInstructionsTool.js +55 -0
  60. package/dist/mcp/builtin/collections/uploadInstructionsTool.js.map +1 -0
  61. package/dist/mcp/builtin/getConfigInfoTool.d.ts.map +1 -1
  62. package/dist/mcp/builtin/getConfigInfoTool.js +3 -2
  63. package/dist/mcp/builtin/getConfigInfoTool.js.map +1 -1
  64. package/dist/mcp/builtin/globals/countVersionsTool.d.ts.map +1 -1
  65. package/dist/mcp/builtin/globals/countVersionsTool.js +9 -13
  66. package/dist/mcp/builtin/globals/countVersionsTool.js.map +1 -1
  67. package/dist/mcp/builtin/globals/findTool.d.ts.map +1 -1
  68. package/dist/mcp/builtin/globals/findTool.js +10 -16
  69. package/dist/mcp/builtin/globals/findTool.js.map +1 -1
  70. package/dist/mcp/builtin/globals/findVersionByIDTool.d.ts.map +1 -1
  71. package/dist/mcp/builtin/globals/findVersionByIDTool.js +13 -24
  72. package/dist/mcp/builtin/globals/findVersionByIDTool.js.map +1 -1
  73. package/dist/mcp/builtin/globals/findVersionsTool.d.ts.map +1 -1
  74. package/dist/mcp/builtin/globals/findVersionsTool.js +13 -29
  75. package/dist/mcp/builtin/globals/findVersionsTool.js.map +1 -1
  76. package/dist/mcp/builtin/globals/getGlobalSchemaTool.d.ts.map +1 -1
  77. package/dist/mcp/builtin/globals/getGlobalSchemaTool.js +11 -11
  78. package/dist/mcp/builtin/globals/getGlobalSchemaTool.js.map +1 -1
  79. package/dist/mcp/builtin/globals/restoreVersionTool.d.ts.map +1 -1
  80. package/dist/mcp/builtin/globals/restoreVersionTool.js +15 -22
  81. package/dist/mcp/builtin/globals/restoreVersionTool.js.map +1 -1
  82. package/dist/mcp/builtin/globals/updateTool.d.ts.map +1 -1
  83. package/dist/mcp/builtin/globals/updateTool.js +18 -23
  84. package/dist/mcp/builtin/globals/updateTool.js.map +1 -1
  85. package/dist/mcp/builtin/validateEntityData.d.ts +4 -4
  86. package/dist/mcp/builtin/validateEntityData.d.ts.map +1 -1
  87. package/dist/mcp/builtin/validateEntityData.js +7 -7
  88. package/dist/mcp/builtin/validateEntityData.js.map +1 -1
  89. package/dist/mcp/builtinTools.d.ts +6 -0
  90. package/dist/mcp/builtinTools.d.ts.map +1 -1
  91. package/dist/mcp/builtinTools.js +9 -3
  92. package/dist/mcp/builtinTools.js.map +1 -1
  93. package/dist/mcp/sanitizeMCPConfig.js +4 -1
  94. package/dist/mcp/sanitizeMCPConfig.js.map +1 -1
  95. package/dist/stdio.d.ts.map +1 -1
  96. package/dist/stdio.js +2 -1
  97. package/dist/stdio.js.map +1 -1
  98. package/dist/types.d.ts +4 -4
  99. package/dist/types.d.ts.map +1 -1
  100. package/dist/types.js.map +1 -1
  101. package/package.json +6 -8
  102. package/src/endpoint/access.ts +2 -3
  103. package/src/mcp/buildMcpServer.ts +39 -29
  104. package/src/mcp/builtin/collections/authTools.ts +77 -69
  105. package/src/mcp/builtin/collections/countTool.ts +9 -21
  106. package/src/mcp/builtin/collections/countVersionsTool.ts +9 -18
  107. package/src/mcp/builtin/collections/createTool.ts +87 -84
  108. package/src/mcp/builtin/collections/deleteTool.ts +36 -64
  109. package/src/mcp/builtin/collections/duplicateTool.ts +21 -83
  110. package/src/mcp/builtin/collections/fileInput.spec.ts +20 -6
  111. package/src/mcp/builtin/collections/fileInput.ts +53 -23
  112. package/src/mcp/builtin/collections/findDistinctTool.ts +11 -63
  113. package/src/mcp/builtin/collections/findTool.ts +21 -103
  114. package/src/mcp/builtin/collections/findVersionByIDTool.ts +15 -58
  115. package/src/mcp/builtin/collections/findVersionsTool.ts +14 -85
  116. package/src/mcp/builtin/collections/formatCollectionError.ts +8 -8
  117. package/src/mcp/builtin/collections/getCollectionSchemaTool.ts +16 -12
  118. package/src/mcp/builtin/collections/restoreVersionTool.ts +14 -56
  119. package/src/mcp/builtin/collections/updateTool.ts +47 -101
  120. package/src/mcp/builtin/collections/uploadInstructionsTool.ts +64 -0
  121. package/src/mcp/builtin/getConfigInfoTool.ts +2 -1
  122. package/src/mcp/builtin/globals/countVersionsTool.ts +9 -17
  123. package/src/mcp/builtin/globals/findTool.ts +12 -51
  124. package/src/mcp/builtin/globals/findVersionByIDTool.ts +13 -52
  125. package/src/mcp/builtin/globals/findVersionsTool.ts +14 -92
  126. package/src/mcp/builtin/globals/getGlobalSchemaTool.ts +10 -10
  127. package/src/mcp/builtin/globals/restoreVersionTool.ts +14 -45
  128. package/src/mcp/builtin/globals/updateTool.ts +34 -52
  129. package/src/mcp/builtin/validateEntityData.ts +10 -13
  130. package/src/mcp/builtinTools.ts +9 -2
  131. package/src/mcp/sanitizeMCPConfig.ts +4 -1
  132. package/src/stdio.ts +2 -1
  133. package/src/types.ts +4 -4
  134. package/dist/utils/getVirtualFieldNames.d.ts +0 -14
  135. package/dist/utils/getVirtualFieldNames.d.ts.map +0 -1
  136. package/dist/utils/getVirtualFieldNames.js +0 -35
  137. package/dist/utils/getVirtualFieldNames.js.map +0 -1
  138. package/dist/utils/schemaConversion/filterFieldsByAccess.d.ts +0 -28
  139. package/dist/utils/schemaConversion/filterFieldsByAccess.d.ts.map +0 -1
  140. package/dist/utils/schemaConversion/filterFieldsByAccess.js +0 -71
  141. package/dist/utils/schemaConversion/filterFieldsByAccess.js.map +0 -1
  142. package/dist/utils/schemaConversion/getEntityInputSchema.d.ts +0 -13
  143. package/dist/utils/schemaConversion/getEntityInputSchema.d.ts.map +0 -1
  144. package/dist/utils/schemaConversion/getEntityInputSchema.js +0 -66
  145. package/dist/utils/schemaConversion/getEntityInputSchema.js.map +0 -1
  146. package/dist/utils/schemaConversion/sanitizeEntitySchema.d.ts +0 -10
  147. package/dist/utils/schemaConversion/sanitizeEntitySchema.d.ts.map +0 -1
  148. package/dist/utils/schemaConversion/sanitizeEntitySchema.js +0 -384
  149. package/dist/utils/schemaConversion/sanitizeEntitySchema.js.map +0 -1
  150. package/dist/utils/schemaConversion/sanitizeEntitySchema.spec.js +0 -133
  151. package/dist/utils/schemaConversion/sanitizeEntitySchema.spec.js.map +0 -1
  152. package/dist/utils/transformPointDataToPayload.d.ts +0 -7
  153. package/dist/utils/transformPointDataToPayload.d.ts.map +0 -1
  154. package/dist/utils/transformPointDataToPayload.js +0 -28
  155. package/dist/utils/transformPointDataToPayload.js.map +0 -1
  156. package/dist/utils/whereSchema.d.ts +0 -9
  157. package/dist/utils/whereSchema.d.ts.map +0 -1
  158. package/dist/utils/whereSchema.js +0 -13
  159. package/dist/utils/whereSchema.js.map +0 -1
  160. package/src/utils/getVirtualFieldNames.ts +0 -53
  161. package/src/utils/schemaConversion/filterFieldsByAccess.ts +0 -123
  162. package/src/utils/schemaConversion/getEntityInputSchema.ts +0 -96
  163. package/src/utils/schemaConversion/sanitizeEntitySchema.spec.ts +0 -96
  164. package/src/utils/schemaConversion/sanitizeEntitySchema.ts +0 -432
  165. package/src/utils/transformPointDataToPayload.ts +0 -40
  166. package/src/utils/whereSchema.ts +0 -24
@@ -1,6 +1,4 @@
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'
@@ -11,7 +9,7 @@ const DEFAULT_DESCRIPTION =
11
9
 
12
10
  export const restoreVersionTool = defineCollectionTool({
13
11
  access: (args) =>
14
- defaultAccess(args) && Boolean(args.permissions?.collections?.[args.collectionSlug]?.update),
12
+ defaultAccess(args) && Boolean(args.permissions?.collections?.[args.slug]?.update),
15
13
  annotations: {
16
14
  destructiveHint: true,
17
15
  idempotentHint: false,
@@ -20,85 +18,45 @@ export const restoreVersionTool = defineCollectionTool({
20
18
  title: 'Restore Version',
21
19
  },
22
20
  description: DEFAULT_DESCRIPTION,
23
- input: z.object({
24
- id: z.string().describe('The ID of the version to restore'),
25
- depth: z
26
- .number()
27
- .int()
28
- .min(0)
29
- .max(10)
30
- .describe('How many levels deep to populate relationships in response')
31
- .optional()
32
- .default(0),
33
- draft: z
34
- .boolean()
35
- .describe('Whether to restore the version as a draft')
36
- .optional()
37
- .default(false),
38
- fallbackLocale: z
39
- .string()
40
- .describe('Optional: fallback locale code to use when requested locale is not available')
41
- .optional(),
42
- locale: z
43
- .string()
44
- .describe('Optional: locale code to restore in (e.g., "en", "es")')
45
- .optional(),
46
- populate: z
47
- .record(z.string(), z.unknown())
48
- .describe(
49
- 'Optional: control which fields to include from populated relationship or upload documents.',
50
- )
51
- .optional(),
52
- select: z
53
- .record(z.string(), z.unknown())
54
- .describe(
55
- 'Optional: define exactly which fields you\'d like to return in the response, e.g., {"title": true}',
56
- )
57
- .optional(),
58
- showHiddenFields: z
59
- .boolean()
60
- .describe('Optional: include hidden fields in the restored document response')
61
- .optional(),
62
- }),
63
- }).handler(async ({ authorizedMCP, collectionSlug, input, req }) => {
21
+ input: restoreVersionInputSchema,
22
+ }).handler(async ({ slug, authorizedMCP, input, req }) => {
64
23
  const payload = req.payload
65
24
  const logger = getLogger({ payload })
66
- const { id, depth, draft, fallbackLocale, locale, populate, select, showHiddenFields } = input
25
+ const { id, depth, draft, fallbackLocale, locale, populate, select } = input
67
26
 
68
- logger.info(`Restoring version in collection: ${collectionSlug} with ID: ${id}`)
27
+ logger.info(`Restoring version in collection: ${slug} with ID: ${id}`)
69
28
 
70
29
  try {
71
30
  const result = await payload.restoreVersion({
72
- id,
73
- collection: collectionSlug,
31
+ id: String(id),
32
+ collection: slug,
74
33
  depth,
75
34
  draft,
76
35
  overrideAccess: authorizedMCP.overrideAccess,
77
36
  req,
78
- ...(fallbackLocale ? { fallbackLocale } : {}),
37
+ ...(fallbackLocale !== undefined ? { fallbackLocale } : {}),
79
38
  ...(locale ? { locale } : {}),
80
- ...(populate ? { populate: populate as PopulateType } : {}),
81
- ...(select ? { select: select as SelectType } : {}),
82
- ...(showHiddenFields !== undefined ? { showHiddenFields } : {}),
39
+ ...(populate ? { populate } : {}),
40
+ ...(select ? { select } : {}),
83
41
  })
84
42
 
85
43
  return {
86
44
  content: [
87
45
  {
88
46
  type: 'text',
89
- 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\`\`\``,
90
48
  },
91
49
  ],
92
50
  doc: result as Record<string, unknown>,
93
51
  }
94
52
  } catch (error) {
95
53
  const errorMessage = error instanceof Error ? error.message : 'Unknown error'
96
- logger.error(`Error restoring version ${id} in ${collectionSlug}: ${errorMessage}`)
54
+ logger.error(`Error restoring version ${id} in ${slug}: ${errorMessage}`)
97
55
  return {
98
56
  content: [
99
57
  {
100
58
  type: 'text',
101
- text: `❌ **Error restoring version "${id}" in collection "${collectionSlug}":** ${errorMessage}`,
59
+ text: `❌ **Error restoring version "${id}" in collection "${slug}":** ${errorMessage}`,
102
60
  },
103
61
  ],
104
62
  isError: true,
@@ -1,27 +1,26 @@
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
+ stripVirtualFields,
7
+ transformPointDataToPayload,
8
+ updateDocumentInputSchema,
9
+ } from 'payload'
4
10
 
5
11
  import { defaultAccess } from '../../../defaultAccess.js'
6
12
  import { defineCollectionTool } from '../../../defineTool.js'
7
13
  import { getLogger } from '../../../utils/getLogger.js'
8
- import {
9
- getCollectionVirtualFieldNames,
10
- stripVirtualFields,
11
- } from '../../../utils/getVirtualFieldNames.js'
12
- import { getCollectionInputSchema } from '../../../utils/schemaConversion/getEntityInputSchema.js'
13
- import { transformPointDataToPayload } from '../../../utils/transformPointDataToPayload.js'
14
- import { whereSchema } from '../../../utils/whereSchema.js'
15
14
  import { validateCollectionData } from '../validateEntityData.js'
16
- import { fileInputSchema, resolveFileInput } from './fileInput.js'
15
+ import { fileInputSchema, resolveFile } from './fileInput.js'
17
16
  import { formatCollectionError } from './formatCollectionError.js'
18
17
 
19
18
  const DEFAULT_DESCRIPTION =
20
- 'Update documents in any collection by passing the collection slug and data.'
19
+ 'Update documents. Prefer uploadReference after upload, externalURL for URLs, or base64 for small local files.'
21
20
 
22
21
  export const updateDocumentTool = defineCollectionTool({
23
22
  access: (args) =>
24
- defaultAccess(args) && Boolean(args.permissions?.collections?.[args.collectionSlug]?.update),
23
+ defaultAccess(args) && Boolean(args.permissions?.collections?.[args.slug]?.update),
25
24
  annotations: {
26
25
  destructiveHint: true,
27
26
  idempotentHint: false,
@@ -30,65 +29,8 @@ export const updateDocumentTool = defineCollectionTool({
30
29
  title: 'Update Document',
31
30
  },
32
31
  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
36
- .record(z.string(), z.unknown())
37
- .describe(
38
- 'The fields to update. Only include fields permitted by the schema returned by getCollectionSchema.',
39
- ),
40
- depth: z
41
- .number()
42
- .describe('How many levels deep to populate relationships')
43
- .optional()
44
- .default(0),
45
- draft: z
46
- .boolean()
47
- .describe(
48
- 'Only if getCollectionSchema includes _status; otherwise _status does not exist. true saves only a draft version; false updates main and versions. data._status: "published" overrides true.',
49
- )
50
- .optional()
51
- .default(false),
52
- fallbackLocale: z
53
- .string()
54
- .describe('Optional: fallback locale code to use when requested locale is not available')
55
- .optional(),
56
- file: fileInputSchema.optional(),
57
- locale: z
58
- .string()
59
- .describe(
60
- 'Optional: locale code to update the document in (e.g., "en", "es"). Defaults to the default locale',
61
- )
62
- .optional(),
63
- overrideLock: z
64
- .boolean()
65
- .describe('Whether to override document locks')
66
- .optional()
67
- .default(true),
68
- overwriteExistingFiles: z
69
- .boolean()
70
- .describe('Whether to overwrite existing files')
71
- .optional()
72
- .default(false),
73
- publishAllLocales: z
74
- .boolean()
75
- .describe(
76
- 'For collections with localized publishing status, whether publishing should affect every locale. Set false with locale to publish only that locale.',
77
- )
78
- .optional(),
79
- select: z
80
- .record(z.string(), z.unknown())
81
- .describe(
82
- 'Optional: define exactly which fields you\'d like to return in the response, e.g., {"title": true}',
83
- )
84
- .optional(),
85
- where: whereSchema
86
- .describe(
87
- 'Where clause to update multiple documents. Use field names with Payload operators, and/or arrays for grouping. Example: {"title":{"contains":"test"}}',
88
- )
89
- .optional(),
90
- }),
91
- }).handler(async ({ authorizedMCP, collectionSlug, input, req }) => {
32
+ input: updateDocumentInputSchema({ file: fileInputSchema }),
33
+ }).handler(async ({ slug, authorizedMCP, input, req }) => {
92
34
  const payload = req.payload
93
35
  const logger = getLogger({ payload })
94
36
 
@@ -99,29 +41,27 @@ export const updateDocumentTool = defineCollectionTool({
99
41
  draft,
100
42
  fallbackLocale,
101
43
  file: fileInput,
44
+ limit,
102
45
  locale,
103
46
  overrideLock,
104
- overwriteExistingFiles,
47
+ populate,
105
48
  publishAllLocales,
106
49
  select,
50
+ sort,
51
+ trash,
52
+ unpublishAllLocales,
107
53
  where,
108
54
  } = input
109
55
 
110
56
  logger.info(
111
- `Updating document in collection: ${collectionSlug}${id ? ` with ID: ${id}` : ' with where clause'}, draft: ${draft}${locale ? `, locale: ${locale}` : ''}`,
57
+ `Updating document in collection: ${slug}${id ? ` with ID: ${id}` : ' with where clause'}, draft: ${draft}${locale ? `, locale: ${locale}` : ''}`,
112
58
  )
113
59
 
114
60
  try {
115
- if (!id && !where) {
116
- return {
117
- content: [{ type: 'text', text: 'Error: Either id or where clause must be provided' }],
118
- }
119
- }
120
-
121
- const virtualFieldNames = getCollectionVirtualFieldNames(payload.config, collectionSlug)
61
+ const virtualFieldNames = getCollectionVirtualFieldNames(payload.config, slug)
122
62
  const inputData = stripVirtualFields(data, virtualFieldNames)
123
63
  const validationError = validateCollectionData({
124
- collectionSlug,
64
+ slug,
125
65
  data: inputData,
126
66
  partial: true,
127
67
  req,
@@ -132,33 +72,35 @@ export const updateDocumentTool = defineCollectionTool({
132
72
  }
133
73
 
134
74
  const parsedData = transformPointDataToPayload(inputData)
135
- const file = await resolveFileInput({ collectionSlug, input: fileInput, req })
75
+ const file = await resolveFile({ slug, input: fileInput, req })
136
76
 
137
77
  const whereClause: Where = where ?? {}
138
78
 
139
- if (id) {
79
+ if (id !== undefined) {
140
80
  const result = await payload.update({
141
81
  id,
142
- collection: collectionSlug,
82
+ collection: slug,
143
83
  data: parsedData,
144
84
  depth,
145
85
  draft,
86
+ fallbackLocale,
87
+ locale,
146
88
  overrideAccess: authorizedMCP.overrideAccess,
147
89
  overrideLock,
90
+ populate,
91
+ publishAllLocales,
148
92
  req,
93
+ select,
94
+ trash,
95
+ unpublishAllLocales,
149
96
  ...(file ? { file } : {}),
150
- ...(overwriteExistingFiles ? { overwriteExistingFiles } : {}),
151
- ...(publishAllLocales !== undefined ? { publishAllLocales } : {}),
152
- ...(locale ? { locale } : {}),
153
- ...(fallbackLocale ? { fallbackLocale } : {}),
154
- ...(select ? { select: select as SelectType } : {}),
155
97
  })
156
98
 
157
99
  return {
158
100
  content: [
159
101
  {
160
102
  type: 'text',
161
- text: `Document updated successfully in collection "${collectionSlug}"!\nUpdated document:\n\`\`\`json\n${JSON.stringify(result)}\n\`\`\``,
103
+ text: `Document updated successfully in collection "${slug}"!\nUpdated document:\n\`\`\`json\n${JSON.stringify(result)}\n\`\`\``,
162
104
  },
163
105
  ],
164
106
  doc: result as Record<string, unknown>,
@@ -166,33 +108,37 @@ export const updateDocumentTool = defineCollectionTool({
166
108
  }
167
109
 
168
110
  const result = await payload.update({
169
- collection: collectionSlug,
111
+ collection: slug,
170
112
  data: parsedData,
171
113
  depth,
172
114
  draft,
115
+ fallbackLocale,
116
+ limit,
117
+ locale,
173
118
  overrideAccess: authorizedMCP.overrideAccess,
174
119
  overrideLock,
120
+ populate,
121
+ publishAllLocales,
175
122
  req,
123
+ select,
124
+ sort,
125
+ trash,
126
+ unpublishAllLocales,
176
127
  where: whereClause,
177
128
  ...(file ? { file } : {}),
178
- ...(overwriteExistingFiles ? { overwriteExistingFiles } : {}),
179
- ...(publishAllLocales !== undefined ? { publishAllLocales } : {}),
180
- ...(locale ? { locale } : {}),
181
- ...(fallbackLocale ? { fallbackLocale } : {}),
182
- ...(select ? { select: select as SelectType } : {}),
183
129
  })
184
130
 
185
131
  const docs = result.docs || []
186
132
  const errors = result.errors || []
187
133
 
188
- 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---`
189
135
  if (docs.length > 0) {
190
136
  responseText += `\n\nUpdated documents:\n\`\`\`json\n${JSON.stringify(docs)}\n\`\`\``
191
137
  }
192
138
  if (errors.length > 0) {
193
139
  responseText += `\n\nErrors:\n\`\`\`json\n${JSON.stringify(errors)}\n\`\`\``
194
140
 
195
- const errorSchema = getCollectionInputSchema({ collectionSlug, req })
141
+ const errorSchema = getCollectionInputSchema({ collectionSlug: slug, req })
196
142
 
197
143
  if (errorSchema) {
198
144
  responseText += `\n\nUse this schema for data:\n\`\`\`json\n${JSON.stringify(errorSchema)}\n\`\`\``
@@ -205,7 +151,7 @@ export const updateDocumentTool = defineCollectionTool({
205
151
  ...(errorSchema
206
152
  ? {
207
153
  structuredContent: {
208
- collectionSlug,
154
+ slug,
209
155
  docs,
210
156
  errors,
211
157
  schema: errorSchema,
@@ -221,7 +167,7 @@ export const updateDocumentTool = defineCollectionTool({
221
167
  }
222
168
  } catch (error) {
223
169
  const errorMessage = error instanceof Error ? error.message : 'Unknown error'
224
- logger.error(`Error updating document in ${collectionSlug}: ${errorMessage}`)
225
- return formatCollectionError({ action: 'updating', collectionSlug, error, req })
170
+ logger.error(`Error updating document in ${slug}: ${errorMessage}`)
171
+ return formatCollectionError({ slug, action: 'updating', error, req })
226
172
  }
227
173
  })
@@ -0,0 +1,64 @@
1
+ import { strictObject, z } from 'payload'
2
+ import { getUploadInstructions as getPayloadUploadInstructions } from 'payload/internal'
3
+
4
+ import { defaultAccess } from '../../../defaultAccess.js'
5
+ import { defineCollectionTool } from '../../../defineTool.js'
6
+
7
+ export const getUploadInstructionsTool = defineCollectionTool({
8
+ access: (args) =>
9
+ defaultAccess(args) &&
10
+ Boolean(
11
+ args.permissions?.collections?.[args.slug]?.create ||
12
+ args.permissions?.collections?.[args.slug]?.update,
13
+ ),
14
+ annotations: {
15
+ destructiveHint: false,
16
+ idempotentHint: false,
17
+ openWorldHint: true,
18
+ readOnlyHint: false,
19
+ title: 'Get Upload Instructions',
20
+ },
21
+ description:
22
+ 'Prepare uploads for createDocuments or updateDocument. This does not upload bytes; finish the returned action before use.',
23
+ input: strictObject({
24
+ docPrefix: z.optional(z.string()).check(z.describe('Document folder or prefix.')),
25
+ filename: z.string().check(z.describe('The original file name.')),
26
+ filesize: z.int().check(z.nonnegative(), z.describe('The file size in bytes.')),
27
+ mimeType: z.string().check(z.describe('The file MIME type.')),
28
+ }),
29
+ }).handler(async ({ slug, authorizedMCP, input, req }) => {
30
+ try {
31
+ const instructions = await getPayloadUploadInstructions({
32
+ ...input,
33
+ collectionSlug: slug,
34
+ overrideAccess: authorizedMCP.overrideAccess,
35
+ req,
36
+ })
37
+
38
+ const nextStep =
39
+ instructions.type === 'http'
40
+ ? 'Upload bytes with instructions.request. After success, pass { source: "uploadReference", file: instructions.file }.'
41
+ : `Call "${instructions.name}" with file and data. After success, pass { source: "uploadReference", file: instructions.file }.`
42
+
43
+ return {
44
+ content: [
45
+ {
46
+ type: 'text',
47
+ text: `Upload instructions for collection "${slug}":\n\`\`\`json\n${JSON.stringify(instructions)}\n\`\`\`\n${nextStep}`,
48
+ },
49
+ ],
50
+ structuredContent: { instructions },
51
+ }
52
+ } catch (error) {
53
+ const message = error instanceof Error ? error.message : 'Unknown error'
54
+ return {
55
+ content: [
56
+ {
57
+ type: 'text',
58
+ text: `Error getting upload instructions for collection "${slug}": ${message}`,
59
+ },
60
+ ],
61
+ isError: true,
62
+ }
63
+ }
64
+ })
@@ -1,4 +1,4 @@
1
- import { getAccessResults, isEntityHidden } from 'payload'
1
+ import { getAccessResults, getConfigInfoInputSchema, isEntityHidden } from 'payload'
2
2
 
3
3
  import { defineTool } from '../../defineTool.js'
4
4
 
@@ -11,6 +11,7 @@ export const getConfigInfoTool = defineTool({
11
11
  title: 'Config Info',
12
12
  },
13
13
  description: 'List the Payload collection and global slugs visible to this MCP client.',
14
+ input: getConfigInfoInputSchema,
14
15
  }).handler(async ({ authorizedMCP, req }) => {
15
16
  const user = req.user
16
17
  const permissions = authorizedMCP.overrideAccess ? null : await getAccessResults({ req })
@@ -1,16 +1,15 @@
1
- import { z } from 'zod'
1
+ import { countGlobalVersionsInputSchema } from 'payload'
2
2
 
3
3
  import { defaultAccess } from '../../../defaultAccess.js'
4
4
  import { defineGlobalTool } from '../../../defineTool.js'
5
5
  import { getLogger } from '../../../utils/getLogger.js'
6
- import { whereSchema } from '../../../utils/whereSchema.js'
7
6
 
8
7
  const DEFAULT_DESCRIPTION =
9
8
  'Count global versions in any version-enabled global by passing the global slug and optional where clause.'
10
9
 
11
10
  export const countGlobalVersionsTool = defineGlobalTool({
12
11
  access: (args) =>
13
- defaultAccess(args) && Boolean(args.permissions?.globals?.[args.globalSlug]?.readVersions),
12
+ defaultAccess(args) && Boolean(args.permissions?.globals?.[args.slug]?.readVersions),
14
13
  annotations: {
15
14
  destructiveHint: false,
16
15
  idempotentHint: true,
@@ -19,24 +18,17 @@ export const countGlobalVersionsTool = defineGlobalTool({
19
18
  title: 'Count Global Versions',
20
19
  },
21
20
  description: DEFAULT_DESCRIPTION,
22
- input: z.object({
23
- locale: z.string().describe('Optional: locale code to count versions in').optional(),
24
- where: whereSchema
25
- .describe(
26
- 'Optional: where clause for filtering versions. Version document fields are usually under "version". Example: {"version.siteName":{"contains":"test"}}',
27
- )
28
- .optional(),
29
- }),
30
- }).handler(async ({ authorizedMCP, globalSlug, input, req }) => {
21
+ input: countGlobalVersionsInputSchema,
22
+ }).handler(async ({ slug, authorizedMCP, input, req }) => {
31
23
  const payload = req.payload
32
24
  const logger = getLogger({ payload })
33
25
  const { locale, where } = input
34
26
 
35
- logger.info(`Counting versions for global: ${globalSlug}`)
27
+ logger.info(`Counting versions for global: ${slug}`)
36
28
 
37
29
  try {
38
30
  const result = await payload.countGlobalVersions({
39
- global: globalSlug,
31
+ global: slug,
40
32
  overrideAccess: authorizedMCP.overrideAccess,
41
33
  req,
42
34
  ...(locale ? { locale } : {}),
@@ -47,19 +39,19 @@ export const countGlobalVersionsTool = defineGlobalTool({
47
39
  content: [
48
40
  {
49
41
  type: 'text',
50
- text: `Global "${globalSlug}" contains ${result.totalDocs} matching versions.\n\`\`\`json\n${JSON.stringify(result)}\n\`\`\``,
42
+ text: `Global "${slug}" contains ${result.totalDocs} matching versions.\n\`\`\`json\n${JSON.stringify(result)}\n\`\`\``,
51
43
  },
52
44
  ],
53
45
  doc: result,
54
46
  }
55
47
  } catch (error) {
56
48
  const errorMessage = error instanceof Error ? error.message : 'Unknown error'
57
- logger.error(`Error counting versions for global ${globalSlug}: ${errorMessage}`)
49
+ logger.error(`Error counting versions for global ${slug}: ${errorMessage}`)
58
50
  return {
59
51
  content: [
60
52
  {
61
53
  type: 'text',
62
- text: `❌ **Error counting versions for global "${globalSlug}":** ${errorMessage}`,
54
+ text: `❌ **Error counting versions for global "${slug}":** ${errorMessage}`,
63
55
  },
64
56
  ],
65
57
  isError: true,
@@ -1,6 +1,4 @@
1
- import type { PopulateType, SelectType } from 'payload'
2
-
3
- import { z } from 'zod'
1
+ import { findGlobalInputSchema } from 'payload'
4
2
 
5
3
  import { defaultAccess } from '../../../defaultAccess.js'
6
4
  import { defineGlobalTool } from '../../../defineTool.js'
@@ -9,8 +7,7 @@ import { getLogger } from '../../../utils/getLogger.js'
9
7
  const DEFAULT_DESCRIPTION = 'Find any Payload global by passing the global slug.'
10
8
 
11
9
  export const findGlobalTool = defineGlobalTool({
12
- access: (args) =>
13
- defaultAccess(args) && Boolean(args.permissions?.globals?.[args.globalSlug]?.read),
10
+ access: (args) => defaultAccess(args) && Boolean(args.permissions?.globals?.[args.slug]?.read),
14
11
  annotations: {
15
12
  destructiveHint: false,
16
13
  idempotentHint: true,
@@ -19,51 +16,18 @@ export const findGlobalTool = defineGlobalTool({
19
16
  title: 'Find Global',
20
17
  },
21
18
  description: DEFAULT_DESCRIPTION,
22
- input: z.object({
23
- depth: z
24
- .number()
25
- .int()
26
- .min(0)
27
- .max(10)
28
- .describe('Depth of population for relationships')
29
- .optional()
30
- .default(0),
31
- fallbackLocale: z
32
- .string()
33
- .describe('Optional: fallback locale code to use when requested locale is not available')
34
- .optional(),
35
- locale: z
36
- .string()
37
- .describe(
38
- 'Optional: locale code to retrieve data in (e.g., "en", "es"). Use "all" to retrieve all locales for localized fields',
39
- )
40
- .optional(),
41
- populate: z
42
- .record(z.string(), z.unknown())
43
- .describe(
44
- 'Optional: control which fields to include from populated relationship or upload documents.',
45
- )
46
- .optional(),
47
- select: z
48
- .record(z.string(), z.unknown())
49
- .describe(
50
- 'Optional: define exactly which fields you\'d like to return in the response, e.g., {"title": true}',
51
- )
52
- .optional(),
53
- }),
54
- }).handler(async ({ authorizedMCP, globalSlug, input, req }) => {
19
+ input: findGlobalInputSchema,
20
+ }).handler(async ({ slug, authorizedMCP, input, req }) => {
55
21
  const payload = req.payload
56
22
  const logger = getLogger({ payload })
57
23
 
58
24
  const { depth, fallbackLocale, locale, populate, select } = input
59
25
 
60
- logger.info(
61
- `Reading global: ${globalSlug}, depth: ${depth}${locale ? `, locale: ${locale}` : ''}`,
62
- )
26
+ logger.info(`Reading global: ${slug}, depth: ${depth}${locale ? `, locale: ${locale}` : ''}`)
63
27
 
64
28
  try {
65
29
  const findOptions: Parameters<typeof payload.findGlobal>[0] = {
66
- slug: globalSlug,
30
+ slug,
67
31
  depth,
68
32
  overrideAccess: authorizedMCP.overrideAccess,
69
33
  req,
@@ -72,34 +36,31 @@ export const findGlobalTool = defineGlobalTool({
72
36
  if (locale) {
73
37
  findOptions.locale = locale
74
38
  }
75
- if (fallbackLocale) {
39
+ if (fallbackLocale !== undefined) {
76
40
  findOptions.fallbackLocale = fallbackLocale
77
41
  }
78
42
  if (select) {
79
- findOptions.select = select as SelectType
43
+ findOptions.select = select
80
44
  }
81
45
  if (populate) {
82
- findOptions.populate = populate as PopulateType
46
+ findOptions.populate = populate
83
47
  }
84
-
85
48
  const result = await payload.findGlobal(findOptions)
86
49
 
87
50
  return {
88
51
  content: [
89
52
  {
90
53
  type: 'text',
91
- text: `Global "${globalSlug}":\n\`\`\`json\n${JSON.stringify(result)}\n\`\`\``,
54
+ text: `Global "${slug}":\n\`\`\`json\n${JSON.stringify(result)}\n\`\`\``,
92
55
  },
93
56
  ],
94
57
  doc: result as Record<string, unknown>,
95
58
  }
96
59
  } catch (error) {
97
60
  const errorMessage = error instanceof Error ? error.message : 'Unknown error'
98
- logger.error(`Error reading global ${globalSlug}: ${errorMessage}`)
61
+ logger.error(`Error reading global ${slug}: ${errorMessage}`)
99
62
  return {
100
- content: [
101
- { type: 'text', text: `❌ **Error reading global "${globalSlug}":** ${errorMessage}` },
102
- ],
63
+ content: [{ type: 'text', text: `❌ **Error reading global "${slug}":** ${errorMessage}` }],
103
64
  }
104
65
  }
105
66
  })