@payloadcms/plugin-mcp 4.0.0-internal.1f9ae9a → 4.0.0-internal.2fddfc0

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 (227) hide show
  1. package/dist/@types/assets.d.js +2 -0
  2. package/dist/@types/assets.d.js.map +1 -0
  3. package/dist/defaultAccess.d.ts +3 -0
  4. package/dist/defaultAccess.d.ts.map +1 -0
  5. package/dist/defaultAccess.js +3 -0
  6. package/dist/defaultAccess.js.map +1 -0
  7. package/dist/endpoint/access.d.ts +17 -5
  8. package/dist/endpoint/access.d.ts.map +1 -1
  9. package/dist/endpoint/access.js +82 -88
  10. package/dist/endpoint/access.js.map +1 -1
  11. package/dist/endpoint/index.d.ts.map +1 -1
  12. package/dist/endpoint/index.js +11 -0
  13. package/dist/endpoint/index.js.map +1 -1
  14. package/dist/exports/client.d.ts +1 -1
  15. package/dist/exports/client.d.ts.map +1 -1
  16. package/dist/exports/client.js +1 -1
  17. package/dist/exports/client.js.map +1 -1
  18. package/dist/exports/internal.d.ts +2 -0
  19. package/dist/exports/internal.d.ts.map +1 -0
  20. package/dist/exports/internal.js +3 -0
  21. package/dist/exports/internal.js.map +1 -0
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +13 -18
  24. package/dist/index.js.map +1 -1
  25. package/dist/mcp/buildMcpServer.d.ts.map +1 -1
  26. package/dist/mcp/buildMcpServer.js +102 -64
  27. package/dist/mcp/buildMcpServer.js.map +1 -1
  28. package/dist/mcp/builtin/collections/authTools.d.ts.map +1 -1
  29. package/dist/mcp/builtin/collections/authTools.js +44 -6
  30. package/dist/mcp/builtin/collections/authTools.js.map +1 -1
  31. package/dist/mcp/builtin/collections/countTool.d.ts +2 -0
  32. package/dist/mcp/builtin/collections/countTool.d.ts.map +1 -0
  33. package/dist/mcp/builtin/collections/countTool.js +69 -0
  34. package/dist/mcp/builtin/collections/countTool.js.map +1 -0
  35. package/dist/mcp/builtin/collections/countVersionsTool.d.ts +2 -0
  36. package/dist/mcp/builtin/collections/countVersionsTool.d.ts.map +1 -0
  37. package/dist/mcp/builtin/collections/countVersionsTool.js +65 -0
  38. package/dist/mcp/builtin/collections/countVersionsTool.js.map +1 -0
  39. package/dist/mcp/builtin/collections/createTool.d.ts +1 -1
  40. package/dist/mcp/builtin/collections/createTool.d.ts.map +1 -1
  41. package/dist/mcp/builtin/collections/createTool.js +38 -38
  42. package/dist/mcp/builtin/collections/createTool.js.map +1 -1
  43. package/dist/mcp/builtin/collections/deleteTool.d.ts +1 -1
  44. package/dist/mcp/builtin/collections/deleteTool.d.ts.map +1 -1
  45. package/dist/mcp/builtin/collections/deleteTool.js +14 -20
  46. package/dist/mcp/builtin/collections/deleteTool.js.map +1 -1
  47. package/dist/mcp/builtin/collections/duplicateTool.d.ts +2 -0
  48. package/dist/mcp/builtin/collections/duplicateTool.d.ts.map +1 -0
  49. package/dist/mcp/builtin/collections/duplicateTool.js +97 -0
  50. package/dist/mcp/builtin/collections/duplicateTool.js.map +1 -0
  51. package/dist/mcp/builtin/collections/findDistinctTool.d.ts +2 -0
  52. package/dist/mcp/builtin/collections/findDistinctTool.d.ts.map +1 -0
  53. package/dist/mcp/builtin/collections/findDistinctTool.js +93 -0
  54. package/dist/mcp/builtin/collections/findDistinctTool.js.map +1 -0
  55. package/dist/mcp/builtin/collections/findTool.d.ts +1 -1
  56. package/dist/mcp/builtin/collections/findTool.d.ts.map +1 -1
  57. package/dist/mcp/builtin/collections/findTool.js +49 -43
  58. package/dist/mcp/builtin/collections/findTool.js.map +1 -1
  59. package/dist/mcp/builtin/collections/findVersionByIDTool.d.ts +2 -0
  60. package/dist/mcp/builtin/collections/findVersionByIDTool.d.ts.map +1 -0
  61. package/dist/mcp/builtin/collections/findVersionByIDTool.js +84 -0
  62. package/dist/mcp/builtin/collections/findVersionByIDTool.js.map +1 -0
  63. package/dist/mcp/builtin/collections/findVersionsTool.d.ts +2 -0
  64. package/dist/mcp/builtin/collections/findVersionsTool.d.ts.map +1 -0
  65. package/dist/mcp/builtin/collections/findVersionsTool.js +99 -0
  66. package/dist/mcp/builtin/collections/findVersionsTool.js.map +1 -0
  67. package/dist/mcp/builtin/collections/formatCollectionError.d.ts +9 -0
  68. package/dist/mcp/builtin/collections/formatCollectionError.d.ts.map +1 -0
  69. package/dist/mcp/builtin/collections/formatCollectionError.js +60 -0
  70. package/dist/mcp/builtin/collections/formatCollectionError.js.map +1 -0
  71. package/dist/mcp/builtin/collections/getCollectionSchemaTool.d.ts +2 -0
  72. package/dist/mcp/builtin/collections/getCollectionSchemaTool.d.ts.map +1 -0
  73. package/dist/mcp/builtin/collections/getCollectionSchemaTool.js +47 -0
  74. package/dist/mcp/builtin/collections/getCollectionSchemaTool.js.map +1 -0
  75. package/dist/mcp/builtin/collections/restoreVersionTool.d.ts +2 -0
  76. package/dist/mcp/builtin/collections/restoreVersionTool.d.ts.map +1 -0
  77. package/dist/mcp/builtin/collections/restoreVersionTool.js +82 -0
  78. package/dist/mcp/builtin/collections/restoreVersionTool.js.map +1 -0
  79. package/dist/mcp/builtin/collections/updateTool.d.ts +1 -1
  80. package/dist/mcp/builtin/collections/updateTool.d.ts.map +1 -1
  81. package/dist/mcp/builtin/collections/updateTool.js +87 -82
  82. package/dist/mcp/builtin/collections/updateTool.js.map +1 -1
  83. package/dist/mcp/builtin/getConfigInfoTool.d.ts +2 -0
  84. package/dist/mcp/builtin/getConfigInfoTool.d.ts.map +1 -0
  85. package/dist/mcp/builtin/getConfigInfoTool.js +71 -0
  86. package/dist/mcp/builtin/getConfigInfoTool.js.map +1 -0
  87. package/dist/mcp/builtin/globals/countVersionsTool.d.ts +2 -0
  88. package/dist/mcp/builtin/globals/countVersionsTool.d.ts.map +1 -0
  89. package/dist/mcp/builtin/globals/countVersionsTool.js +65 -0
  90. package/dist/mcp/builtin/globals/countVersionsTool.js.map +1 -0
  91. package/dist/mcp/builtin/globals/findTool.d.ts.map +1 -1
  92. package/dist/mcp/builtin/globals/findTool.js +18 -21
  93. package/dist/mcp/builtin/globals/findTool.js.map +1 -1
  94. package/dist/mcp/builtin/globals/findVersionByIDTool.d.ts +2 -0
  95. package/dist/mcp/builtin/globals/findVersionByIDTool.d.ts.map +1 -0
  96. package/dist/mcp/builtin/globals/findVersionByIDTool.js +80 -0
  97. package/dist/mcp/builtin/globals/findVersionByIDTool.js.map +1 -0
  98. package/dist/mcp/builtin/globals/findVersionsTool.d.ts +2 -0
  99. package/dist/mcp/builtin/globals/findVersionsTool.d.ts.map +1 -0
  100. package/dist/mcp/builtin/globals/findVersionsTool.js +95 -0
  101. package/dist/mcp/builtin/globals/findVersionsTool.js.map +1 -0
  102. package/dist/mcp/builtin/globals/getGlobalSchemaTool.d.ts +2 -0
  103. package/dist/mcp/builtin/globals/getGlobalSchemaTool.d.ts.map +1 -0
  104. package/dist/mcp/builtin/globals/getGlobalSchemaTool.js +47 -0
  105. package/dist/mcp/builtin/globals/getGlobalSchemaTool.js.map +1 -0
  106. package/dist/mcp/builtin/globals/restoreVersionTool.d.ts +2 -0
  107. package/dist/mcp/builtin/globals/restoreVersionTool.d.ts.map +1 -0
  108. package/dist/mcp/builtin/globals/restoreVersionTool.js +78 -0
  109. package/dist/mcp/builtin/globals/restoreVersionTool.js.map +1 -0
  110. package/dist/mcp/builtin/globals/updateTool.d.ts.map +1 -1
  111. package/dist/mcp/builtin/globals/updateTool.js +31 -36
  112. package/dist/mcp/builtin/globals/updateTool.js.map +1 -1
  113. package/dist/mcp/builtin/validateEntityData.d.ts +14 -0
  114. package/dist/mcp/builtin/validateEntityData.d.ts.map +1 -0
  115. package/dist/mcp/builtin/validateEntityData.js +82 -0
  116. package/dist/mcp/builtin/validateEntityData.js.map +1 -0
  117. package/dist/mcp/builtinTools.d.ts +144 -19
  118. package/dist/mcp/builtinTools.d.ts.map +1 -1
  119. package/dist/mcp/builtinTools.js +119 -20
  120. package/dist/mcp/builtinTools.js.map +1 -1
  121. package/dist/mcp/sanitizeMCPConfig.d.ts +0 -1
  122. package/dist/mcp/sanitizeMCPConfig.d.ts.map +1 -1
  123. package/dist/mcp/sanitizeMCPConfig.js +120 -58
  124. package/dist/mcp/sanitizeMCPConfig.js.map +1 -1
  125. package/dist/stdio.d.ts +3 -2
  126. package/dist/stdio.d.ts.map +1 -1
  127. package/dist/stdio.js +27 -8
  128. package/dist/stdio.js.map +1 -1
  129. package/dist/types.d.ts +62 -108
  130. package/dist/types.d.ts.map +1 -1
  131. package/dist/types.js +4 -4
  132. package/dist/types.js.map +1 -1
  133. package/dist/utils/getPluginConfig.d.ts +1 -1
  134. package/dist/utils/getPluginConfig.js +1 -1
  135. package/dist/utils/getPluginConfig.js.map +1 -1
  136. package/dist/utils/schemaConversion/getEntityInputSchema.d.ts +11 -0
  137. package/dist/utils/schemaConversion/getEntityInputSchema.d.ts.map +1 -0
  138. package/dist/utils/schemaConversion/getEntityInputSchema.js +34 -0
  139. package/dist/utils/schemaConversion/getEntityInputSchema.js.map +1 -0
  140. package/dist/utils/schemaConversion/sanitizeEntitySchema.d.ts +15 -0
  141. package/dist/utils/schemaConversion/sanitizeEntitySchema.d.ts.map +1 -0
  142. package/dist/utils/schemaConversion/sanitizeEntitySchema.js +464 -0
  143. package/dist/utils/schemaConversion/sanitizeEntitySchema.js.map +1 -0
  144. package/dist/utils/schemaConversion/sanitizeEntitySchema.spec.js +158 -0
  145. package/dist/utils/schemaConversion/sanitizeEntitySchema.spec.js.map +1 -0
  146. package/dist/utils/whereSchema.d.ts +9 -0
  147. package/dist/utils/whereSchema.d.ts.map +1 -0
  148. package/dist/utils/whereSchema.js +13 -0
  149. package/dist/utils/whereSchema.js.map +1 -0
  150. package/package.json +8 -11
  151. package/src/@types/assets.d.ts +3 -0
  152. package/src/defaultAccess.ts +3 -0
  153. package/src/endpoint/access.ts +88 -101
  154. package/src/endpoint/index.ts +14 -1
  155. package/src/exports/client.ts +2 -1
  156. package/src/exports/internal.ts +1 -0
  157. package/src/index.ts +8 -16
  158. package/src/mcp/buildMcpServer.ts +130 -90
  159. package/src/mcp/builtin/collections/authTools.ts +45 -9
  160. package/src/mcp/builtin/collections/countTool.ts +74 -0
  161. package/src/mcp/builtin/collections/countVersionsTool.ts +70 -0
  162. package/src/mcp/builtin/collections/createTool.ts +55 -59
  163. package/src/mcp/builtin/collections/deleteTool.ts +19 -16
  164. package/src/mcp/builtin/collections/duplicateTool.ts +135 -0
  165. package/src/mcp/builtin/collections/findDistinctTool.ts +120 -0
  166. package/src/mcp/builtin/collections/findTool.ts +63 -33
  167. package/src/mcp/builtin/collections/findVersionByIDTool.ts +110 -0
  168. package/src/mcp/builtin/collections/findVersionsTool.ts +155 -0
  169. package/src/mcp/builtin/collections/formatCollectionError.ts +84 -0
  170. package/src/mcp/builtin/collections/getCollectionSchemaTool.ts +46 -0
  171. package/src/mcp/builtin/collections/restoreVersionTool.ts +108 -0
  172. package/src/mcp/builtin/collections/updateTool.ts +111 -105
  173. package/src/mcp/builtin/getConfigInfoTool.ts +69 -0
  174. package/src/mcp/builtin/globals/countVersionsTool.ts +69 -0
  175. package/src/mcp/builtin/globals/findTool.ts +26 -17
  176. package/src/mcp/builtin/globals/findVersionByIDTool.ts +104 -0
  177. package/src/mcp/builtin/globals/findVersionsTool.ts +148 -0
  178. package/src/mcp/builtin/globals/getGlobalSchemaTool.ts +41 -0
  179. package/src/mcp/builtin/globals/restoreVersionTool.ts +100 -0
  180. package/src/mcp/builtin/globals/updateTool.ts +50 -53
  181. package/src/mcp/builtin/validateEntityData.ts +132 -0
  182. package/src/mcp/builtinTools.ts +111 -41
  183. package/src/mcp/sanitizeMCPConfig.ts +116 -78
  184. package/src/stdio.ts +23 -8
  185. package/src/types.ts +77 -112
  186. package/src/utils/getPluginConfig.ts +1 -1
  187. package/src/utils/schemaConversion/getEntityInputSchema.ts +78 -0
  188. package/src/utils/schemaConversion/sanitizeEntitySchema.spec.ts +103 -0
  189. package/src/utils/schemaConversion/sanitizeEntitySchema.ts +529 -0
  190. package/src/utils/whereSchema.ts +24 -0
  191. package/dist/collection/getAccessField.d.ts +0 -12
  192. package/dist/collection/getAccessField.d.ts.map +0 -1
  193. package/dist/collection/getAccessField.js +0 -57
  194. package/dist/collection/getAccessField.js.map +0 -1
  195. package/dist/collection/index.d.ts +0 -6
  196. package/dist/collection/index.d.ts.map +0 -1
  197. package/dist/collection/index.js +0 -59
  198. package/dist/collection/index.js.map +0 -1
  199. package/dist/components/AccessField/index.client.d.ts +0 -10
  200. package/dist/components/AccessField/index.client.d.ts.map +0 -1
  201. package/dist/components/AccessField/index.client.js +0 -305
  202. package/dist/components/AccessField/index.client.js.map +0 -1
  203. package/dist/components/AccessField/index.css +0 -93
  204. package/dist/utils/schemaConversion/prepareCollectionSchema.d.ts +0 -7
  205. package/dist/utils/schemaConversion/prepareCollectionSchema.d.ts.map +0 -1
  206. package/dist/utils/schemaConversion/prepareCollectionSchema.js +0 -37
  207. package/dist/utils/schemaConversion/prepareCollectionSchema.js.map +0 -1
  208. package/dist/utils/schemaConversion/sanitizeJsonSchema.d.ts +0 -13
  209. package/dist/utils/schemaConversion/sanitizeJsonSchema.d.ts.map +0 -1
  210. package/dist/utils/schemaConversion/sanitizeJsonSchema.js +0 -56
  211. package/dist/utils/schemaConversion/sanitizeJsonSchema.js.map +0 -1
  212. package/dist/utils/schemaConversion/simplifyRelationshipFields.d.ts +0 -20
  213. package/dist/utils/schemaConversion/simplifyRelationshipFields.d.ts.map +0 -1
  214. package/dist/utils/schemaConversion/simplifyRelationshipFields.js +0 -56
  215. package/dist/utils/schemaConversion/simplifyRelationshipFields.js.map +0 -1
  216. package/dist/utils/schemaConversion/transformPointFields.d.ts +0 -3
  217. package/dist/utils/schemaConversion/transformPointFields.d.ts.map +0 -1
  218. package/dist/utils/schemaConversion/transformPointFields.js +0 -57
  219. package/dist/utils/schemaConversion/transformPointFields.js.map +0 -1
  220. package/src/collection/getAccessField.ts +0 -64
  221. package/src/collection/index.ts +0 -63
  222. package/src/components/AccessField/index.client.tsx +0 -344
  223. package/src/components/AccessField/index.css +0 -93
  224. package/src/utils/schemaConversion/prepareCollectionSchema.ts +0 -39
  225. package/src/utils/schemaConversion/sanitizeJsonSchema.ts +0 -62
  226. package/src/utils/schemaConversion/simplifyRelationshipFields.ts +0 -70
  227. package/src/utils/schemaConversion/transformPointFields.ts +0 -56
@@ -2,6 +2,7 @@ import type { SelectType } from 'payload'
2
2
 
3
3
  import { z } from 'zod'
4
4
 
5
+ import { defaultAccess } from '../../../defaultAccess.js'
5
6
  import { defineGlobalTool } from '../../../defineTool.js'
6
7
  import { getLogger } from '../../../utils/getLogger.js'
7
8
  import {
@@ -9,52 +10,51 @@ import {
9
10
  stripVirtualFields,
10
11
  } from '../../../utils/getVirtualFieldNames.js'
11
12
  import { localAPIDefaults } from '../../../utils/localAPIDefaults.js'
12
- import { prepareCollectionSchema } from '../../../utils/schemaConversion/prepareCollectionSchema.js'
13
+ import { transformPointDataToPayload } from '../../../utils/transformPointDataToPayload.js'
14
+ import { validateGlobalData } from '../validateEntityData.js'
13
15
 
14
- const DEFAULT_DESCRIPTION = 'Update a Payload global singleton configuration.'
16
+ const DEFAULT_DESCRIPTION = 'Update any Payload global by passing the global slug and data.'
15
17
 
16
18
  export const updateGlobalTool = defineGlobalTool({
17
- description: DEFAULT_DESCRIPTION,
18
- input: ({ globalSchema }) => {
19
- const partialSchema = prepareCollectionSchema(globalSchema)
20
- // Global updates do not require all required fields to be passed => delete .required.
21
- //
22
- // Local API equivalent: packages/payload/src/global/operations/local/update.ts#BaseOptions#data:
23
- // data: DeepPartial<Omit<DataFromGlobalSlug<TSlug>, 'id'>>
24
- delete partialSchema.required
25
-
26
- return z.object({
27
- data: z
28
- .fromJSONSchema(partialSchema as unknown as z.core.JSONSchema.JSONSchema)
29
- .describe('The fields to update'),
30
- depth: z
31
- .number()
32
- .describe('Optional: Depth of relationships to populate')
33
- .optional()
34
- .default(0),
35
- draft: z
36
- .boolean()
37
- .describe('Optional: Whether to save as draft (default: false)')
38
- .optional()
39
- .default(false),
40
- fallbackLocale: z
41
- .string()
42
- .describe('Optional: fallback locale code to use when requested locale is not available')
43
- .optional(),
44
- locale: z
45
- .string()
46
- .describe(
47
- 'Optional: locale code to update data in (e.g., "en", "es"). Use "all" to update all locales for localized fields',
48
- )
49
- .optional(),
50
- select: z
51
- .string()
52
- .describe(
53
- 'Optional: define exactly which fields you\'d like to return in the response (JSON), e.g., \'{"siteName": "My Site"}\'',
54
- )
55
- .optional(),
56
- })
19
+ access: (args) =>
20
+ defaultAccess(args) && Boolean(args.permissions?.globals?.[args.globalSlug]?.update),
21
+ annotations: {
22
+ destructiveHint: true,
23
+ idempotentHint: false,
24
+ openWorldHint: false,
25
+ readOnlyHint: false,
26
+ title: 'Update Global',
57
27
  },
28
+ description: DEFAULT_DESCRIPTION,
29
+ input: z.object({
30
+ data: z.record(z.string(), z.unknown()).describe('The global fields to update'),
31
+ depth: z
32
+ .number()
33
+ .describe('Optional: Depth of relationships to populate')
34
+ .optional()
35
+ .default(0),
36
+ draft: z
37
+ .boolean()
38
+ .describe('Optional: Whether to save as draft (default: false)')
39
+ .optional()
40
+ .default(false),
41
+ fallbackLocale: z
42
+ .string()
43
+ .describe('Optional: fallback locale code to use when requested locale is not available')
44
+ .optional(),
45
+ locale: z
46
+ .string()
47
+ .describe(
48
+ 'Optional: locale code to update data in (e.g., "en", "es"). Use "all" to update all locales for localized fields',
49
+ )
50
+ .optional(),
51
+ select: z
52
+ .record(z.string(), z.unknown())
53
+ .describe(
54
+ 'Optional: define exactly which fields you\'d like to return in the response, e.g., {"siteName": true}',
55
+ )
56
+ .optional(),
57
+ }),
58
58
  }).handler(async ({ authorizedMCP, globalSlug, input, req }) => {
59
59
  const payload = req.payload
60
60
  const logger = getLogger({ payload })
@@ -67,18 +67,15 @@ export const updateGlobalTool = defineGlobalTool({
67
67
 
68
68
  try {
69
69
  const virtualFieldNames = getGlobalVirtualFieldNames(payload.config, globalSlug)
70
- const parsedData = stripVirtualFields(data as Record<string, unknown>, virtualFieldNames)
70
+ const inputData = stripVirtualFields(data, virtualFieldNames)
71
+ const validationError = validateGlobalData({ data: inputData, globalSlug, req })
71
72
 
72
- let selectClause: SelectType | undefined
73
- if (select) {
74
- try {
75
- selectClause = JSON.parse(select) as SelectType
76
- } catch {
77
- logger.warn(`Invalid select clause JSON for global: ${select}`)
78
- return { content: [{ type: 'text', text: 'Error: Invalid JSON in select clause' }] }
79
- }
73
+ if (validationError) {
74
+ return validationError
80
75
  }
81
76
 
77
+ const parsedData = transformPointDataToPayload(inputData)
78
+
82
79
  const updateOptions: Parameters<typeof payload.updateGlobal>[0] = {
83
80
  slug: globalSlug,
84
81
  data: parsedData,
@@ -93,8 +90,8 @@ export const updateGlobalTool = defineGlobalTool({
93
90
  if (fallbackLocale) {
94
91
  updateOptions.fallbackLocale = fallbackLocale
95
92
  }
96
- if (selectClause) {
97
- updateOptions.select = selectClause
93
+ if (select) {
94
+ updateOptions.select = select as SelectType
98
95
  }
99
96
 
100
97
  const result = await payload.updateGlobal(updateOptions)
@@ -0,0 +1,132 @@
1
+ import type { CollectionSlug, GlobalSlug, PayloadRequest, SanitizedConfig } from 'payload'
2
+
3
+ import { CfWorkerJsonSchemaValidator } from '@modelcontextprotocol/server'
4
+
5
+ import type { JsonSchemaType, MCPToolResponse } from '../../types.js'
6
+
7
+ import {
8
+ getCollectionInputSchema,
9
+ getGlobalInputSchema,
10
+ } from '../../utils/schemaConversion/getEntityInputSchema.js'
11
+
12
+ /**
13
+ * Keep the default `shortcircuit: true` - `false` makes validating nested rich text exponentially slow.
14
+ */
15
+ const validator = new CfWorkerJsonSchemaValidator({ shortcircuit: true })
16
+
17
+ type EntityValidator = {
18
+ schema: JsonSchemaType
19
+ validate: ReturnType<(typeof validator)['getValidator']>
20
+ }
21
+
22
+ /**
23
+ * - Caches each entity's schema and validator, so both are only built on the first request.
24
+ * - Keyed by payload config, then by entity type, slug, partial and language.
25
+ */
26
+ const validatorCache = new WeakMap<SanitizedConfig, Map<string, EntityValidator>>()
27
+
28
+ export const validateCollectionData = ({
29
+ collectionSlug,
30
+ data,
31
+ partial,
32
+ req,
33
+ }: {
34
+ collectionSlug: CollectionSlug
35
+ data: Record<string, unknown>
36
+ partial?: boolean
37
+ req: PayloadRequest
38
+ }): MCPToolResponse | null =>
39
+ validateData({
40
+ slug: collectionSlug,
41
+ buildSchema: () => getCollectionInputSchema({ collectionSlug, req }),
42
+ data,
43
+ entity: 'collection',
44
+ partial,
45
+ req,
46
+ })
47
+
48
+ export const validateGlobalData = ({
49
+ data,
50
+ globalSlug,
51
+ req,
52
+ }: {
53
+ data: Record<string, unknown>
54
+ globalSlug: GlobalSlug
55
+ req: PayloadRequest
56
+ }): MCPToolResponse | null =>
57
+ validateData({
58
+ slug: globalSlug,
59
+ buildSchema: () => getGlobalInputSchema({ globalSlug, req }),
60
+ data,
61
+ entity: 'global',
62
+ partial: true,
63
+ req,
64
+ })
65
+
66
+ const validateData = ({
67
+ slug,
68
+ buildSchema,
69
+ data,
70
+ entity,
71
+ partial,
72
+ req,
73
+ }: {
74
+ buildSchema: () => JsonSchemaType | null
75
+ data: Record<string, unknown>
76
+ entity: 'collection' | 'global'
77
+ partial?: boolean
78
+ req: PayloadRequest
79
+ slug: string
80
+ }): MCPToolResponse | null => {
81
+ let cache = validatorCache.get(req.payload.config)
82
+ if (!cache) {
83
+ cache = new Map()
84
+ validatorCache.set(req.payload.config, cache)
85
+ }
86
+
87
+ const cacheKey = `${entity}:${slug}:${partial ? 'partial' : 'full'}:${req.i18n.language}`
88
+ let entityValidator = cache.get(cacheKey)
89
+
90
+ if (!entityValidator) {
91
+ const schema = buildSchema()
92
+
93
+ if (!schema) {
94
+ return null
95
+ }
96
+
97
+ entityValidator = {
98
+ schema,
99
+ validate: validator.getValidator(partial ? withoutRequired(schema) : schema),
100
+ }
101
+ cache.set(cacheKey, entityValidator)
102
+ }
103
+
104
+ const result = entityValidator.validate(data)
105
+
106
+ if (result.valid) {
107
+ return null
108
+ }
109
+
110
+ const { schema } = entityValidator
111
+
112
+ return {
113
+ content: [
114
+ {
115
+ type: 'text',
116
+ text: `Invalid data for ${entity} "${slug}": ${result.errorMessage}\n\nUse this schema for data:\n\`\`\`json\n${JSON.stringify(schema)}\n\`\`\``,
117
+ },
118
+ ],
119
+ isError: true,
120
+ structuredContent: {
121
+ [`${entity}Slug`]: slug,
122
+ errors: [{ message: result.errorMessage }],
123
+ schema,
124
+ },
125
+ }
126
+ }
127
+
128
+ /** Updates are partial — drop the schema's top-level `required` before validating. */
129
+ const withoutRequired = (schema: JsonSchemaType): JsonSchemaType => {
130
+ const { required: _required, ...rest } = schema
131
+ return rest
132
+ }
@@ -1,4 +1,4 @@
1
- import type { CollectionTool, GlobalTool } from '../types.js'
1
+ import type { CollectionTool, GlobalTool, Tool } from '../types.js'
2
2
 
3
3
  import {
4
4
  authCollectionTool,
@@ -8,62 +8,128 @@ import {
8
8
  unlockCollectionTool,
9
9
  verifyCollectionTool,
10
10
  } from './builtin/collections/authTools.js'
11
- import { createCollectionTool } from './builtin/collections/createTool.js'
12
- import { deleteCollectionTool } from './builtin/collections/deleteTool.js'
13
- import { findCollectionTool } from './builtin/collections/findTool.js'
14
- import { updateCollectionTool } from './builtin/collections/updateTool.js'
11
+ import { countDocumentsTool } from './builtin/collections/countTool.js'
12
+ import { countVersionsTool } from './builtin/collections/countVersionsTool.js'
13
+ import { createDocumentTool } from './builtin/collections/createTool.js'
14
+ import { deleteDocumentsTool } from './builtin/collections/deleteTool.js'
15
+ import { duplicateDocumentTool } from './builtin/collections/duplicateTool.js'
16
+ import { findDistinctTool } from './builtin/collections/findDistinctTool.js'
17
+ import { findDocumentsTool } from './builtin/collections/findTool.js'
18
+ import { findVersionByIDTool } from './builtin/collections/findVersionByIDTool.js'
19
+ import { findVersionsTool } from './builtin/collections/findVersionsTool.js'
20
+ import { getCollectionSchemaTool } from './builtin/collections/getCollectionSchemaTool.js'
21
+ import { restoreVersionTool } from './builtin/collections/restoreVersionTool.js'
22
+ import { updateDocumentTool } from './builtin/collections/updateTool.js'
23
+ import { getConfigInfoTool } from './builtin/getConfigInfoTool.js'
24
+ import { countGlobalVersionsTool } from './builtin/globals/countVersionsTool.js'
15
25
  import { findGlobalTool } from './builtin/globals/findTool.js'
26
+ import { findGlobalVersionByIDTool } from './builtin/globals/findVersionByIDTool.js'
27
+ import { findGlobalVersionsTool } from './builtin/globals/findVersionsTool.js'
28
+ import { getGlobalSchemaTool } from './builtin/globals/getGlobalSchemaTool.js'
29
+ import { restoreGlobalVersionTool } from './builtin/globals/restoreVersionTool.js'
16
30
  import { updateGlobalTool } from './builtin/globals/updateTool.js'
17
31
 
32
+ type CollectionBuiltin = {
33
+ mcpName: string
34
+ requiresDuplicateEnabled?: boolean
35
+ requiresVersions?: boolean
36
+ tool: CollectionTool
37
+ }
38
+
39
+ type GlobalBuiltin = {
40
+ mcpName: string
41
+ requiresVersions?: boolean
42
+ tool: GlobalTool
43
+ }
44
+
45
+ export const TOOL_BUILTINS = {
46
+ getConfigInfo: { mcpName: 'getConfigInfo', tool: getConfigInfoTool },
47
+ } satisfies Record<string, { mcpName: string; tool: Tool }>
48
+
18
49
  /**
19
50
  * The static built-in collection CRUD tools. Keys here are the source of truth
20
51
  * for `MCPCollectionBuiltinName` — adding/removing an entry updates the type
21
52
  * automatically.
22
53
  */
23
- export const COLLECTION_BUILTINS: Record<MCPCollectionBuiltinName, CollectionTool> = {
24
- create: createCollectionTool,
25
- delete: deleteCollectionTool,
26
- find: findCollectionTool,
27
- update: updateCollectionTool,
28
- }
54
+ export const COLLECTION_BUILTINS = {
55
+ count: { mcpName: 'countDocuments', tool: countDocumentsTool },
56
+ countVersions: { mcpName: 'countVersions', requiresVersions: true, tool: countVersionsTool },
57
+ create: { mcpName: 'createDocument', tool: createDocumentTool },
58
+ delete: { mcpName: 'deleteDocuments', tool: deleteDocumentsTool },
59
+ duplicate: {
60
+ mcpName: 'duplicateDocument',
61
+ requiresDuplicateEnabled: true,
62
+ tool: duplicateDocumentTool,
63
+ },
64
+ find: { mcpName: 'findDocuments', tool: findDocumentsTool },
65
+ findDistinct: { mcpName: 'findDistinct', tool: findDistinctTool },
66
+ findVersionByID: {
67
+ mcpName: 'findVersionByID',
68
+ requiresVersions: true,
69
+ tool: findVersionByIDTool,
70
+ },
71
+ findVersions: { mcpName: 'findVersions', requiresVersions: true, tool: findVersionsTool },
72
+ getCollectionSchema: { mcpName: 'getCollectionSchema', tool: getCollectionSchemaTool },
73
+ restoreVersion: { mcpName: 'restoreVersion', requiresVersions: true, tool: restoreVersionTool },
74
+ update: { mcpName: 'updateDocument', tool: updateDocumentTool },
75
+ } satisfies Record<string, CollectionBuiltin>
29
76
 
30
77
  /**
31
- * The static auth tools surfaced under auth-enabled collections. Each entry
32
- * carries the admin-UI label alongside the tool. Keys are the source of truth
33
- * for `MCPCollectionAuthToolName`.
78
+ * The static auth tools surfaced under auth-enabled collections. Keys are the
79
+ * source of truth for `MCPCollectionAuthToolName`.
34
80
  */
35
- export const COLLECTION_AUTH_BUILTINS: Record<
36
- MCPCollectionAuthToolName,
37
- { label: string; tool: CollectionTool }
38
- > = {
39
- auth: { label: 'Check Auth Status', tool: authCollectionTool },
40
- forgotPassword: { label: 'Forgot Password', tool: forgotPasswordCollectionTool },
41
- login: { label: 'User Login', tool: loginCollectionTool },
42
- resetPassword: { label: 'Reset Password', tool: resetPasswordCollectionTool },
43
- unlock: { label: 'Unlock Account', tool: unlockCollectionTool },
44
- verify: { label: 'Email Verification', tool: verifyCollectionTool },
45
- }
81
+ export const COLLECTION_AUTH_BUILTINS = {
82
+ auth: { mcpName: 'auth', tool: authCollectionTool },
83
+ forgotPassword: {
84
+ mcpName: 'forgotPassword',
85
+ tool: forgotPasswordCollectionTool,
86
+ },
87
+ login: { mcpName: 'login', tool: loginCollectionTool },
88
+ resetPassword: {
89
+ mcpName: 'resetPassword',
90
+ tool: resetPasswordCollectionTool,
91
+ },
92
+ unlock: { mcpName: 'unlock', tool: unlockCollectionTool },
93
+ verify: { mcpName: 'verify', tool: verifyCollectionTool },
94
+ } satisfies Record<string, { mcpName: string; tool: CollectionTool }>
46
95
 
47
96
  /**
48
97
  * The static built-in global tools. Keys are the source of truth for
49
98
  * `MCPGlobalBuiltinName`.
50
99
  */
51
- export const GLOBAL_BUILTINS: Record<MCPGlobalBuiltinName, GlobalTool> = {
52
- find: findGlobalTool,
53
- update: updateGlobalTool,
54
- }
100
+ export const GLOBAL_BUILTINS = {
101
+ countGlobalVersions: {
102
+ mcpName: 'countGlobalVersions',
103
+ requiresVersions: true,
104
+ tool: countGlobalVersionsTool,
105
+ },
106
+ find: { mcpName: 'findGlobal', tool: findGlobalTool },
107
+ findGlobalVersionByID: {
108
+ mcpName: 'findGlobalVersionByID',
109
+ requiresVersions: true,
110
+ tool: findGlobalVersionByIDTool,
111
+ },
112
+ findGlobalVersions: {
113
+ mcpName: 'findGlobalVersions',
114
+ requiresVersions: true,
115
+ tool: findGlobalVersionsTool,
116
+ },
117
+ getGlobalSchema: { mcpName: 'getGlobalSchema', tool: getGlobalSchemaTool },
118
+ restoreGlobalVersion: {
119
+ mcpName: 'restoreGlobalVersion',
120
+ requiresVersions: true,
121
+ tool: restoreGlobalVersionTool,
122
+ },
123
+ update: { mcpName: 'updateGlobal', tool: updateGlobalTool },
124
+ } satisfies Record<string, GlobalBuiltin>
125
+
126
+ export type MCPCollectionBuiltinName = keyof typeof COLLECTION_BUILTINS
55
127
 
56
- export type MCPCollectionBuiltinName = 'create' | 'delete' | 'find' | 'update'
128
+ export type MCPCollectionAuthToolName = keyof typeof COLLECTION_AUTH_BUILTINS
57
129
 
58
- export type MCPCollectionAuthToolName =
59
- | 'auth'
60
- | 'forgotPassword'
61
- | 'login'
62
- | 'resetPassword'
63
- | 'unlock'
64
- | 'verify'
130
+ export type MCPGlobalBuiltinName = keyof typeof GLOBAL_BUILTINS
65
131
 
66
- export type MCPGlobalBuiltinName = 'find' | 'update'
132
+ export type MCPTopLevelBuiltinName = keyof typeof TOOL_BUILTINS
67
133
 
68
134
  /**
69
135
  * Pre-typed `Object.entries` for each registry. The cast from `string` to the
@@ -71,14 +137,18 @@ export type MCPGlobalBuiltinName = 'find' | 'update'
71
137
  * cast — TypeScript's `Object.entries` always widens keys to `string`, which
72
138
  * defeats the narrow type lookups on `MCPCollectionToolsMap`.
73
139
  */
140
+ export const TOOL_BUILTIN_ENTRIES = Object.entries(TOOL_BUILTINS) as Array<
141
+ [MCPTopLevelBuiltinName, (typeof TOOL_BUILTINS)[MCPTopLevelBuiltinName]]
142
+ >
143
+
74
144
  export const COLLECTION_BUILTIN_ENTRIES = Object.entries(COLLECTION_BUILTINS) as Array<
75
- [MCPCollectionBuiltinName, CollectionTool]
145
+ [MCPCollectionBuiltinName, CollectionBuiltin]
76
146
  >
77
147
 
78
148
  export const COLLECTION_AUTH_BUILTIN_ENTRIES = Object.entries(COLLECTION_AUTH_BUILTINS) as Array<
79
- [MCPCollectionAuthToolName, { label: string; tool: CollectionTool }]
149
+ [MCPCollectionAuthToolName, (typeof COLLECTION_AUTH_BUILTINS)[MCPCollectionAuthToolName]]
80
150
  >
81
151
 
82
152
  export const GLOBAL_BUILTIN_ENTRIES = Object.entries(GLOBAL_BUILTINS) as Array<
83
- [MCPGlobalBuiltinName, GlobalTool]
153
+ [MCPGlobalBuiltinName, GlobalBuiltin]
84
154
  >