@payloadcms/plugin-mcp 4.0.0-internal.c2b57ce → 4.0.0-internal.c6494b5

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 (241) hide show
  1. package/LICENSE.md +1 -1
  2. package/dist/defaultAccess.d.ts +3 -0
  3. package/dist/defaultAccess.d.ts.map +1 -0
  4. package/dist/defaultAccess.js +3 -0
  5. package/dist/defaultAccess.js.map +1 -0
  6. package/dist/defineTool.d.ts +8 -8
  7. package/dist/defineTool.d.ts.map +1 -1
  8. package/dist/endpoint/access.d.ts +12 -5
  9. package/dist/endpoint/access.d.ts.map +1 -1
  10. package/dist/endpoint/access.js +75 -88
  11. package/dist/endpoint/access.js.map +1 -1
  12. package/dist/endpoint/index.d.ts +1 -1
  13. package/dist/endpoint/index.d.ts.map +1 -1
  14. package/dist/endpoint/index.js +98 -18
  15. package/dist/endpoint/index.js.map +1 -1
  16. package/dist/exports/client.d.ts +1 -1
  17. package/dist/exports/client.d.ts.map +1 -1
  18. package/dist/exports/client.js +1 -1
  19. package/dist/exports/client.js.map +1 -1
  20. package/dist/exports/internal.d.ts +2 -0
  21. package/dist/exports/internal.d.ts.map +1 -0
  22. package/dist/exports/internal.js +3 -0
  23. package/dist/exports/internal.js.map +1 -0
  24. package/dist/index.d.ts +2 -2
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +15 -20
  27. package/dist/index.js.map +1 -1
  28. package/dist/mcp/buildMcpServer.d.ts +6 -6
  29. package/dist/mcp/buildMcpServer.d.ts.map +1 -1
  30. package/dist/mcp/buildMcpServer.js +146 -74
  31. package/dist/mcp/buildMcpServer.js.map +1 -1
  32. package/dist/mcp/builtin/collections/authTools.d.ts.map +1 -1
  33. package/dist/mcp/builtin/collections/authTools.js +123 -61
  34. package/dist/mcp/builtin/collections/authTools.js.map +1 -1
  35. package/dist/mcp/builtin/collections/countTool.d.ts +2 -0
  36. package/dist/mcp/builtin/collections/countTool.d.ts.map +1 -0
  37. package/dist/mcp/builtin/collections/countTool.js +63 -0
  38. package/dist/mcp/builtin/collections/countTool.js.map +1 -0
  39. package/dist/mcp/builtin/collections/countVersionsTool.d.ts +2 -0
  40. package/dist/mcp/builtin/collections/countVersionsTool.d.ts.map +1 -0
  41. package/dist/mcp/builtin/collections/countVersionsTool.js +60 -0
  42. package/dist/mcp/builtin/collections/countVersionsTool.js.map +1 -0
  43. package/dist/mcp/builtin/collections/createTool.d.ts +1 -1
  44. package/dist/mcp/builtin/collections/createTool.d.ts.map +1 -1
  45. package/dist/mcp/builtin/collections/createTool.js +114 -64
  46. package/dist/mcp/builtin/collections/createTool.js.map +1 -1
  47. package/dist/mcp/builtin/collections/deleteTool.d.ts +1 -1
  48. package/dist/mcp/builtin/collections/deleteTool.d.ts.map +1 -1
  49. package/dist/mcp/builtin/collections/deleteTool.js +55 -61
  50. package/dist/mcp/builtin/collections/deleteTool.js.map +1 -1
  51. package/dist/mcp/builtin/collections/duplicateTool.d.ts +2 -0
  52. package/dist/mcp/builtin/collections/duplicateTool.d.ts.map +1 -0
  53. package/dist/mcp/builtin/collections/duplicateTool.js +90 -0
  54. package/dist/mcp/builtin/collections/duplicateTool.js.map +1 -0
  55. package/dist/mcp/builtin/collections/fileInput.d.ts +28 -0
  56. package/dist/mcp/builtin/collections/fileInput.d.ts.map +1 -0
  57. package/dist/mcp/builtin/collections/fileInput.js +88 -0
  58. package/dist/mcp/builtin/collections/fileInput.js.map +1 -0
  59. package/dist/mcp/builtin/collections/findDistinctTool.d.ts +2 -0
  60. package/dist/mcp/builtin/collections/findDistinctTool.d.ts.map +1 -0
  61. package/dist/mcp/builtin/collections/findDistinctTool.js +77 -0
  62. package/dist/mcp/builtin/collections/findDistinctTool.js.map +1 -0
  63. package/dist/mcp/builtin/collections/findTool.d.ts +1 -1
  64. package/dist/mcp/builtin/collections/findTool.d.ts.map +1 -1
  65. package/dist/mcp/builtin/collections/findTool.js +61 -74
  66. package/dist/mcp/builtin/collections/findTool.js.map +1 -1
  67. package/dist/mcp/builtin/collections/findVersionByIDTool.d.ts +2 -0
  68. package/dist/mcp/builtin/collections/findVersionByIDTool.d.ts.map +1 -0
  69. package/dist/mcp/builtin/collections/findVersionByIDTool.js +74 -0
  70. package/dist/mcp/builtin/collections/findVersionByIDTool.js.map +1 -0
  71. package/dist/mcp/builtin/collections/findVersionsTool.d.ts +2 -0
  72. package/dist/mcp/builtin/collections/findVersionsTool.d.ts.map +1 -0
  73. package/dist/mcp/builtin/collections/findVersionsTool.js +84 -0
  74. package/dist/mcp/builtin/collections/findVersionsTool.js.map +1 -0
  75. package/dist/mcp/builtin/collections/getCollectionSchemaTool.d.ts +2 -0
  76. package/dist/mcp/builtin/collections/getCollectionSchemaTool.d.ts.map +1 -0
  77. package/dist/mcp/builtin/collections/getCollectionSchemaTool.js +103 -0
  78. package/dist/mcp/builtin/collections/getCollectionSchemaTool.js.map +1 -0
  79. package/dist/mcp/builtin/collections/restoreVersionTool.d.ts +2 -0
  80. package/dist/mcp/builtin/collections/restoreVersionTool.d.ts.map +1 -0
  81. package/dist/mcp/builtin/collections/restoreVersionTool.js +69 -0
  82. package/dist/mcp/builtin/collections/restoreVersionTool.js.map +1 -0
  83. package/dist/mcp/builtin/collections/updateTool.d.ts +1 -1
  84. package/dist/mcp/builtin/collections/updateTool.d.ts.map +1 -1
  85. package/dist/mcp/builtin/collections/updateTool.js +118 -133
  86. package/dist/mcp/builtin/collections/updateTool.js.map +1 -1
  87. package/dist/mcp/builtin/collections/uploadInstructionsTool.d.ts +2 -0
  88. package/dist/mcp/builtin/collections/uploadInstructionsTool.d.ts.map +1 -0
  89. package/dist/mcp/builtin/collections/uploadInstructionsTool.js +55 -0
  90. package/dist/mcp/builtin/collections/uploadInstructionsTool.js.map +1 -0
  91. package/dist/mcp/builtin/formatEntityError.d.ts +16 -0
  92. package/dist/mcp/builtin/formatEntityError.d.ts.map +1 -0
  93. package/dist/mcp/builtin/formatEntityError.js +55 -0
  94. package/dist/mcp/builtin/formatEntityError.js.map +1 -0
  95. package/dist/mcp/builtin/getConfigInfoTool.d.ts +2 -0
  96. package/dist/mcp/builtin/getConfigInfoTool.d.ts.map +1 -0
  97. package/dist/mcp/builtin/getConfigInfoTool.js +69 -0
  98. package/dist/mcp/builtin/getConfigInfoTool.js.map +1 -0
  99. package/dist/mcp/builtin/globals/countVersionsTool.d.ts +2 -0
  100. package/dist/mcp/builtin/globals/countVersionsTool.d.ts.map +1 -0
  101. package/dist/mcp/builtin/globals/countVersionsTool.js +60 -0
  102. package/dist/mcp/builtin/globals/countVersionsTool.js.map +1 -0
  103. package/dist/mcp/builtin/globals/findTool.d.ts.map +1 -1
  104. package/dist/mcp/builtin/globals/findTool.js +27 -36
  105. package/dist/mcp/builtin/globals/findTool.js.map +1 -1
  106. package/dist/mcp/builtin/globals/findVersionByIDTool.d.ts +2 -0
  107. package/dist/mcp/builtin/globals/findVersionByIDTool.d.ts.map +1 -0
  108. package/dist/mcp/builtin/globals/findVersionByIDTool.js +68 -0
  109. package/dist/mcp/builtin/globals/findVersionByIDTool.js.map +1 -0
  110. package/dist/mcp/builtin/globals/findVersionsTool.d.ts +2 -0
  111. package/dist/mcp/builtin/globals/findVersionsTool.d.ts.map +1 -0
  112. package/dist/mcp/builtin/globals/findVersionsTool.js +78 -0
  113. package/dist/mcp/builtin/globals/findVersionsTool.js.map +1 -0
  114. package/dist/mcp/builtin/globals/getGlobalSchemaTool.d.ts +2 -0
  115. package/dist/mcp/builtin/globals/getGlobalSchemaTool.d.ts.map +1 -0
  116. package/dist/mcp/builtin/globals/getGlobalSchemaTool.js +81 -0
  117. package/dist/mcp/builtin/globals/getGlobalSchemaTool.js.map +1 -0
  118. package/dist/mcp/builtin/globals/restoreVersionTool.d.ts +2 -0
  119. package/dist/mcp/builtin/globals/restoreVersionTool.d.ts.map +1 -0
  120. package/dist/mcp/builtin/globals/restoreVersionTool.js +70 -0
  121. package/dist/mcp/builtin/globals/restoreVersionTool.js.map +1 -0
  122. package/dist/mcp/builtin/globals/updateTool.d.ts.map +1 -1
  123. package/dist/mcp/builtin/globals/updateTool.js +44 -58
  124. package/dist/mcp/builtin/globals/updateTool.js.map +1 -1
  125. package/dist/mcp/builtinTools.d.ts +150 -19
  126. package/dist/mcp/builtinTools.d.ts.map +1 -1
  127. package/dist/mcp/builtinTools.js +125 -20
  128. package/dist/mcp/builtinTools.js.map +1 -1
  129. package/dist/mcp/sanitizeMCPConfig.d.ts +0 -1
  130. package/dist/mcp/sanitizeMCPConfig.d.ts.map +1 -1
  131. package/dist/mcp/sanitizeMCPConfig.js +124 -58
  132. package/dist/mcp/sanitizeMCPConfig.js.map +1 -1
  133. package/dist/stdio.d.ts +3 -3
  134. package/dist/stdio.d.ts.map +1 -1
  135. package/dist/stdio.js +86 -47
  136. package/dist/stdio.js.map +1 -1
  137. package/dist/types.d.ts +123 -114
  138. package/dist/types.d.ts.map +1 -1
  139. package/dist/types.js +2 -4
  140. package/dist/types.js.map +1 -1
  141. package/dist/utils/camelCase.d.ts.map +1 -1
  142. package/dist/utils/getPluginConfig.d.ts +1 -1
  143. package/dist/utils/getPluginConfig.js +1 -1
  144. package/dist/utils/getPluginConfig.js.map +1 -1
  145. package/dist/utils/resolveProjectRoot.d.ts.map +1 -1
  146. package/dist/utils/toStandardSchema.d.ts.map +1 -1
  147. package/package.json +14 -21
  148. package/src/defaultAccess.ts +3 -0
  149. package/src/endpoint/access.ts +80 -101
  150. package/src/endpoint/index.ts +88 -16
  151. package/src/exports/client.ts +2 -1
  152. package/src/exports/internal.ts +1 -0
  153. package/src/index.ts +12 -20
  154. package/src/mcp/buildMcpServer.ts +180 -110
  155. package/src/mcp/builtin/collections/authTools.ts +122 -75
  156. package/src/mcp/builtin/collections/countTool.ts +61 -0
  157. package/src/mcp/builtin/collections/countVersionsTool.ts +60 -0
  158. package/src/mcp/builtin/collections/createTool.ts +117 -88
  159. package/src/mcp/builtin/collections/deleteTool.ts +48 -74
  160. package/src/mcp/builtin/collections/duplicateTool.ts +84 -0
  161. package/src/mcp/builtin/collections/fileInput.spec.ts +93 -0
  162. package/src/mcp/builtin/collections/fileInput.ts +127 -0
  163. package/src/mcp/builtin/collections/findDistinctTool.ts +67 -0
  164. package/src/mcp/builtin/collections/findTool.ts +57 -110
  165. package/src/mcp/builtin/collections/findVersionByIDTool.ts +66 -0
  166. package/src/mcp/builtin/collections/findVersionsTool.ts +83 -0
  167. package/src/mcp/builtin/collections/getCollectionSchemaTool.ts +91 -0
  168. package/src/mcp/builtin/collections/restoreVersionTool.ts +65 -0
  169. package/src/mcp/builtin/collections/updateTool.ts +106 -138
  170. package/src/mcp/builtin/collections/uploadInstructionsTool.ts +64 -0
  171. package/src/mcp/builtin/formatEntityError.ts +77 -0
  172. package/src/mcp/builtin/getConfigInfoTool.ts +68 -0
  173. package/src/mcp/builtin/globals/countVersionsTool.ts +60 -0
  174. package/src/mcp/builtin/globals/findTool.ts +27 -57
  175. package/src/mcp/builtin/globals/findVersionByIDTool.ts +64 -0
  176. package/src/mcp/builtin/globals/findVersionsTool.ts +69 -0
  177. package/src/mcp/builtin/globals/getGlobalSchemaTool.ts +73 -0
  178. package/src/mcp/builtin/globals/restoreVersionTool.ts +68 -0
  179. package/src/mcp/builtin/globals/updateTool.ts +51 -77
  180. package/src/mcp/builtinTools.ts +118 -41
  181. package/src/mcp/sanitizeMCPConfig.ts +120 -78
  182. package/src/stdio.ts +80 -47
  183. package/src/types.ts +141 -120
  184. package/src/utils/getPluginConfig.ts +1 -1
  185. package/dist/collection/getAccessField.d.ts +0 -12
  186. package/dist/collection/getAccessField.d.ts.map +0 -1
  187. package/dist/collection/getAccessField.js +0 -57
  188. package/dist/collection/getAccessField.js.map +0 -1
  189. package/dist/collection/index.d.ts +0 -6
  190. package/dist/collection/index.d.ts.map +0 -1
  191. package/dist/collection/index.js +0 -59
  192. package/dist/collection/index.js.map +0 -1
  193. package/dist/components/AccessField/index.client.d.ts +0 -10
  194. package/dist/components/AccessField/index.client.d.ts.map +0 -1
  195. package/dist/components/AccessField/index.client.js +0 -305
  196. package/dist/components/AccessField/index.client.js.map +0 -1
  197. package/dist/components/AccessField/index.css +0 -93
  198. package/dist/utils/getVirtualFieldNames.d.ts +0 -14
  199. package/dist/utils/getVirtualFieldNames.d.ts.map +0 -1
  200. package/dist/utils/getVirtualFieldNames.js +0 -35
  201. package/dist/utils/getVirtualFieldNames.js.map +0 -1
  202. package/dist/utils/localAPIDefaults.d.ts +0 -20
  203. package/dist/utils/localAPIDefaults.d.ts.map +0 -1
  204. package/dist/utils/localAPIDefaults.js +0 -19
  205. package/dist/utils/localAPIDefaults.js.map +0 -1
  206. package/dist/utils/schemaConversion/prepareCollectionSchema.d.ts +0 -7
  207. package/dist/utils/schemaConversion/prepareCollectionSchema.d.ts.map +0 -1
  208. package/dist/utils/schemaConversion/prepareCollectionSchema.js +0 -37
  209. package/dist/utils/schemaConversion/prepareCollectionSchema.js.map +0 -1
  210. package/dist/utils/schemaConversion/removeVirtualFieldsFromSchema.d.ts +0 -7
  211. package/dist/utils/schemaConversion/removeVirtualFieldsFromSchema.d.ts.map +0 -1
  212. package/dist/utils/schemaConversion/removeVirtualFieldsFromSchema.js +0 -20
  213. package/dist/utils/schemaConversion/removeVirtualFieldsFromSchema.js.map +0 -1
  214. package/dist/utils/schemaConversion/sanitizeJsonSchema.d.ts +0 -13
  215. package/dist/utils/schemaConversion/sanitizeJsonSchema.d.ts.map +0 -1
  216. package/dist/utils/schemaConversion/sanitizeJsonSchema.js +0 -56
  217. package/dist/utils/schemaConversion/sanitizeJsonSchema.js.map +0 -1
  218. package/dist/utils/schemaConversion/simplifyRelationshipFields.d.ts +0 -20
  219. package/dist/utils/schemaConversion/simplifyRelationshipFields.d.ts.map +0 -1
  220. package/dist/utils/schemaConversion/simplifyRelationshipFields.js +0 -56
  221. package/dist/utils/schemaConversion/simplifyRelationshipFields.js.map +0 -1
  222. package/dist/utils/schemaConversion/transformPointFields.d.ts +0 -3
  223. package/dist/utils/schemaConversion/transformPointFields.d.ts.map +0 -1
  224. package/dist/utils/schemaConversion/transformPointFields.js +0 -57
  225. package/dist/utils/schemaConversion/transformPointFields.js.map +0 -1
  226. package/dist/utils/transformPointDataToPayload.d.ts +0 -7
  227. package/dist/utils/transformPointDataToPayload.d.ts.map +0 -1
  228. package/dist/utils/transformPointDataToPayload.js +0 -28
  229. package/dist/utils/transformPointDataToPayload.js.map +0 -1
  230. package/src/collection/getAccessField.ts +0 -64
  231. package/src/collection/index.ts +0 -63
  232. package/src/components/AccessField/index.client.tsx +0 -344
  233. package/src/components/AccessField/index.css +0 -93
  234. package/src/utils/getVirtualFieldNames.ts +0 -53
  235. package/src/utils/localAPIDefaults.ts +0 -22
  236. package/src/utils/schemaConversion/prepareCollectionSchema.ts +0 -39
  237. package/src/utils/schemaConversion/removeVirtualFieldsFromSchema.ts +0 -27
  238. package/src/utils/schemaConversion/sanitizeJsonSchema.ts +0 -62
  239. package/src/utils/schemaConversion/simplifyRelationshipFields.ts +0 -70
  240. package/src/utils/schemaConversion/transformPointFields.ts +0 -56
  241. package/src/utils/transformPointDataToPayload.ts +0 -40
@@ -1,7 +1,8 @@
1
- import { z } from 'zod'
1
+ import { createPayloadRequest, strictObject, z } from 'payload'
2
2
 
3
3
  import type { MCPToolResponse } from '../../../types.js'
4
4
 
5
+ import { defaultAccess } from '../../../defaultAccess.js'
5
6
  import { defineCollectionTool } from '../../../defineTool.js'
6
7
  import { getLogger } from '../../../utils/getLogger.js'
7
8
 
@@ -16,43 +17,65 @@ import { getLogger } from '../../../utils/getLogger.js'
16
17
  * users collection so all auth-shaped tools live in one place.
17
18
  */
18
19
 
19
- const emailSchema = z.string().email().describe('The user email address')
20
+ const emailSchema = z.email().check(z.describe('The user email address.'))
20
21
 
21
22
  const wrapError =
22
23
  (name: string) =>
23
- ({ collectionSlug, message }: { collectionSlug: string; message: string }): MCPToolResponse => {
24
+ ({ slug, message }: { message: string; slug: string }): MCPToolResponse => {
24
25
  return {
25
26
  content: [
26
27
  {
27
28
  type: 'text',
28
- text: `❌ **Error in ${name}** on ${collectionSlug}: ${message}`,
29
+ text: `❌ **Error in ${name}** on ${slug}: ${message}`,
29
30
  },
30
31
  ],
31
32
  }
32
33
  }
33
34
 
34
35
  export const authCollectionTool = defineCollectionTool({
36
+ annotations: {
37
+ destructiveHint: false,
38
+ idempotentHint: true,
39
+ openWorldHint: false,
40
+ readOnlyHint: true,
41
+ title: 'Check Auth Status',
42
+ },
35
43
  description: 'Checks authentication status for the current user.',
36
- input: z.object({
44
+ input: strictObject({
37
45
  headers: z
38
- .string()
39
- .describe(
40
- 'Optional JSON string containing custom headers to send with the authentication request',
41
- )
42
- .optional(),
46
+ .optional(z.record(z.string(), z.string()))
47
+ .check(z.describe('Custom headers to send with the authentication request.')),
43
48
  }),
44
- }).handler(async ({ collectionSlug, input, req }) => {
49
+ }).handler(async ({ slug, authorizedMCP, input, req }) => {
45
50
  const logger = getLogger({ payload: req.payload })
46
51
  try {
47
52
  let authHeaders = new Headers()
48
53
  if (input.headers) {
49
- try {
50
- authHeaders = new Headers(JSON.parse(input.headers) as Record<string, string>)
51
- } catch {
52
- logger.warn(`Invalid headers JSON for auth: ${input.headers}, using empty headers`)
54
+ authHeaders = new Headers(input.headers)
55
+ }
56
+ const authReq = await createPayloadRequest({
57
+ payload: req.payload,
58
+ req: { headers: authHeaders },
59
+ })
60
+ const result = await req.payload.auth({ headers: authHeaders, req: authReq })
61
+
62
+ if (result.user) {
63
+ const authenticatedUser = result.user
64
+ // Auth strategies read users with trusted Local API access. Re-read the user with the MCP
65
+ // caller's access level before returning it to the client.
66
+ const user = await req.payload.findByID({
67
+ id: authenticatedUser.id,
68
+ collection: authenticatedUser.collection,
69
+ overrideAccess: authorizedMCP.overrideAccess,
70
+ req: authReq,
71
+ })
72
+ result.user = {
73
+ ...user,
74
+ _sid: authenticatedUser._sid,
75
+ _strategy: authenticatedUser._strategy,
76
+ collection: authenticatedUser.collection,
53
77
  }
54
78
  }
55
- const result = await req.payload.auth({ headers: authHeaders })
56
79
  return {
57
80
  content: [
58
81
  {
@@ -64,170 +87,194 @@ export const authCollectionTool = defineCollectionTool({
64
87
  }
65
88
  } catch (error) {
66
89
  const errorMessage = error instanceof Error ? error.message : 'Unknown error'
67
- logger.error(`Error in auth tool on ${collectionSlug}: ${errorMessage}`)
68
- return wrapError('auth')({ collectionSlug, message: errorMessage })
90
+ logger.error(`Error in auth tool on ${slug}: ${errorMessage}`)
91
+ return wrapError('auth')({ slug, message: errorMessage })
69
92
  }
70
93
  })
71
94
 
72
95
  export const forgotPasswordCollectionTool = defineCollectionTool({
96
+ annotations: {
97
+ destructiveHint: false,
98
+ idempotentHint: false,
99
+ openWorldHint: true,
100
+ readOnlyHint: false,
101
+ title: 'Forgot Password',
102
+ },
73
103
  description: 'Sends a password reset email to a user.',
74
- input: z.object({
75
- disableEmail: z
76
- .boolean()
77
- .describe('Whether to disable sending the email (for testing)')
78
- .optional()
79
- .default(false),
104
+ input: strictObject({
80
105
  email: emailSchema,
81
106
  }),
82
- }).handler(async ({ collectionSlug, input, req }) => {
107
+ }).handler(async ({ slug, input, req }) => {
83
108
  const logger = getLogger({ payload: req.payload })
84
109
  try {
85
- const result = await req.payload.forgotPassword({
86
- collection: collectionSlug,
110
+ await req.payload.forgotPassword({
111
+ collection: slug,
87
112
  data: { email: input.email },
88
- disableEmail: input.disableEmail,
113
+ disableEmail: false,
114
+ overrideAccess: false,
115
+ req,
89
116
  })
90
117
  return {
91
118
  content: [
92
119
  {
93
120
  type: 'text',
94
- text: `# Forgot Password Email Sent\n\n**Collection:** ${collectionSlug}\n**Email:** ${input.email}\n\n\`\`\`json\n${JSON.stringify(result)}\n\`\`\``,
121
+ text: 'If an account matches that email, password reset instructions have been sent.',
95
122
  },
96
123
  ],
97
- doc: { result } as Record<string, unknown>,
98
124
  }
99
125
  } catch (error) {
100
126
  const errorMessage = error instanceof Error ? error.message : 'Unknown error'
101
- logger.error(`Error in forgotPassword tool on ${collectionSlug}: ${errorMessage}`)
102
- return wrapError('forgotPassword')({ collectionSlug, message: errorMessage })
127
+ logger.error(`Error in forgotPassword tool on ${slug}: ${errorMessage}`)
128
+ return wrapError('forgotPassword')({ slug, message: errorMessage })
103
129
  }
104
130
  })
105
131
 
106
132
  export const loginCollectionTool = defineCollectionTool({
133
+ annotations: {
134
+ destructiveHint: false,
135
+ idempotentHint: false,
136
+ openWorldHint: false,
137
+ readOnlyHint: false,
138
+ title: 'User Login',
139
+ },
107
140
  description: 'Authenticates a user with email and password.',
108
- input: z.object({
141
+ input: strictObject({
109
142
  depth: z
110
- .number()
111
- .int()
112
- .min(0)
113
- .max(10)
114
- .describe('Depth of population for relationships')
115
- .optional()
116
- .default(0),
143
+ ._default(z.int().check(z.minimum(0), z.maximum(10)), 0)
144
+ .check(z.describe('Depth of population for relationships.')),
117
145
  email: emailSchema,
118
- password: z.string().describe('The user password'),
119
- showHiddenFields: z
120
- .boolean()
121
- .describe('Whether to show hidden fields in the response')
122
- .optional()
123
- .default(false),
146
+ password: z.string().check(z.describe('The user password.')),
124
147
  }),
125
- }).handler(async ({ collectionSlug, input, req }) => {
148
+ }).handler(async ({ slug, authorizedMCP, input, req }) => {
126
149
  const logger = getLogger({ payload: req.payload })
127
150
  try {
128
151
  const result = await req.payload.login({
129
- collection: collectionSlug,
152
+ collection: slug,
130
153
  data: { email: input.email, password: input.password },
131
154
  depth: input.depth,
132
- showHiddenFields: input.showHiddenFields,
155
+ overrideAccess: authorizedMCP.overrideAccess,
133
156
  })
134
157
  return {
135
158
  content: [
136
159
  {
137
160
  type: 'text',
138
- text: `# Login Successful\n\n**User:** ${input.email}\n**Collection:** ${collectionSlug}\n\n\`\`\`json\n${JSON.stringify(result)}\n\`\`\``,
161
+ text: `# Login Successful\n\n**User:** ${input.email}\n**Collection:** ${slug}\n\n\`\`\`json\n${JSON.stringify(result)}\n\`\`\``,
139
162
  },
140
163
  ],
141
164
  doc: result as unknown as Record<string, unknown>,
142
165
  }
143
166
  } catch (error) {
144
167
  const errorMessage = error instanceof Error ? error.message : 'Unknown error'
145
- logger.error(`Error in login tool on ${collectionSlug}: ${errorMessage}`)
146
- return wrapError('login')({ collectionSlug, message: errorMessage })
168
+ logger.error(`Error in login tool on ${slug}: ${errorMessage}`)
169
+ return wrapError('login')({ slug, message: errorMessage })
147
170
  }
148
171
  })
149
172
 
150
173
  export const resetPasswordCollectionTool = defineCollectionTool({
174
+ annotations: {
175
+ destructiveHint: false,
176
+ idempotentHint: false,
177
+ openWorldHint: false,
178
+ readOnlyHint: false,
179
+ title: 'Reset Password',
180
+ },
151
181
  description: 'Resets a user password with a reset token.',
152
- input: z.object({
153
- password: z.string().describe('The new password for the user'),
154
- token: z.string().describe('The password reset token sent to the user email'),
182
+ input: strictObject({
183
+ password: z.string().check(z.describe('The new password for the user.')),
184
+ token: z.string().check(z.describe('The password reset token sent to the user email.')),
155
185
  }),
156
- }).handler(async ({ collectionSlug, input, req }) => {
186
+ }).handler(async ({ slug, authorizedMCP, input, req }) => {
157
187
  const logger = getLogger({ payload: req.payload })
158
188
  try {
159
189
  const result = await req.payload.resetPassword({
160
- collection: collectionSlug,
190
+ collection: slug,
161
191
  data: { password: input.password, token: input.token },
162
- overrideAccess: true,
192
+ overrideAccess: authorizedMCP.overrideAccess,
163
193
  })
164
194
  return {
165
195
  content: [
166
196
  {
167
197
  type: 'text',
168
- text: `# Password Reset Successful\n\n**Collection:** ${collectionSlug}\n\n\`\`\`json\n${JSON.stringify(result)}\n\`\`\``,
198
+ text: `# Password Reset Successful\n\n**Collection:** ${slug}\n\n\`\`\`json\n${JSON.stringify(result)}\n\`\`\``,
169
199
  },
170
200
  ],
171
201
  doc: result as unknown as Record<string, unknown>,
172
202
  }
173
203
  } catch (error) {
174
204
  const errorMessage = error instanceof Error ? error.message : 'Unknown error'
175
- logger.error(`Error in resetPassword tool on ${collectionSlug}: ${errorMessage}`)
176
- return wrapError('resetPassword')({ collectionSlug, message: errorMessage })
205
+ logger.error(`Error in resetPassword tool on ${slug}: ${errorMessage}`)
206
+ return wrapError('resetPassword')({ slug, message: errorMessage })
177
207
  }
178
208
  })
179
209
 
180
210
  export const unlockCollectionTool = defineCollectionTool({
211
+ access: (args) =>
212
+ defaultAccess(args) && Boolean(args.permissions?.collections?.[args.slug]?.unlock),
213
+ annotations: {
214
+ destructiveHint: false,
215
+ idempotentHint: true,
216
+ openWorldHint: false,
217
+ readOnlyHint: false,
218
+ title: 'Unlock Account',
219
+ },
181
220
  description: 'Unlocks a user account that has been locked due to failed login attempts.',
182
- input: z.object({ email: emailSchema }),
183
- }).handler(async ({ collectionSlug, input, req }) => {
221
+ input: strictObject({ email: emailSchema }),
222
+ }).handler(async ({ slug, authorizedMCP, input, req }) => {
184
223
  const logger = getLogger({ payload: req.payload })
185
224
  try {
186
225
  const result = await req.payload.unlock({
187
- collection: collectionSlug,
226
+ collection: slug,
188
227
  data: { email: input.email },
189
- overrideAccess: true,
228
+ overrideAccess: authorizedMCP.overrideAccess,
229
+ req,
190
230
  })
191
231
  return {
192
232
  content: [
193
233
  {
194
234
  type: 'text',
195
- text: `# Account Unlocked\n\n**Collection:** ${collectionSlug}\n**Email:** ${input.email}\n**Result:** ${result ? 'Success' : 'Failed'}`,
235
+ text: `# Account Unlocked\n\n**Collection:** ${slug}\n**Email:** ${input.email}\n**Result:** ${result ? 'Success' : 'Failed'}`,
196
236
  },
197
237
  ],
198
238
  doc: { result } as Record<string, unknown>,
199
239
  }
200
240
  } catch (error) {
201
241
  const errorMessage = error instanceof Error ? error.message : 'Unknown error'
202
- logger.error(`Error in unlock tool on ${collectionSlug}: ${errorMessage}`)
203
- return wrapError('unlock')({ collectionSlug, message: errorMessage })
242
+ logger.error(`Error in unlock tool on ${slug}: ${errorMessage}`)
243
+ return wrapError('unlock')({ slug, message: errorMessage })
204
244
  }
205
245
  })
206
246
 
207
247
  export const verifyCollectionTool = defineCollectionTool({
248
+ annotations: {
249
+ destructiveHint: false,
250
+ idempotentHint: false,
251
+ openWorldHint: false,
252
+ readOnlyHint: false,
253
+ title: 'Email Verification',
254
+ },
208
255
  description: 'Verifies a user email with a verification token.',
209
- input: z.object({
210
- token: z.string().describe('The verification token sent to the user email'),
256
+ input: strictObject({
257
+ token: z.string().check(z.describe('The verification token sent to the user email.')),
211
258
  }),
212
- }).handler(async ({ collectionSlug, input, req }) => {
259
+ }).handler(async ({ slug, input, req }) => {
213
260
  const logger = getLogger({ payload: req.payload })
214
261
  try {
215
262
  const result = await req.payload.verifyEmail({
216
- collection: collectionSlug,
263
+ collection: slug,
217
264
  token: input.token,
218
265
  })
219
266
  return {
220
267
  content: [
221
268
  {
222
269
  type: 'text',
223
- text: `# Email Verification Successful\n\n**Collection:** ${collectionSlug}\n**Result:** ${result ? 'Success' : 'Failed'}`,
270
+ text: `# Email Verification Successful\n\n**Collection:** ${slug}\n**Result:** ${result ? 'Success' : 'Failed'}`,
224
271
  },
225
272
  ],
226
273
  doc: { result } as Record<string, unknown>,
227
274
  }
228
275
  } catch (error) {
229
276
  const errorMessage = error instanceof Error ? error.message : 'Unknown error'
230
- logger.error(`Error in verify tool on ${collectionSlug}: ${errorMessage}`)
231
- return wrapError('verify')({ collectionSlug, message: errorMessage })
277
+ logger.error(`Error in verify tool on ${slug}: ${errorMessage}`)
278
+ return wrapError('verify')({ slug, message: errorMessage })
232
279
  }
233
280
  })
@@ -0,0 +1,61 @@
1
+ import { countDocumentsInputSchema } from 'payload'
2
+
3
+ import { defaultAccess } from '../../../defaultAccess.js'
4
+ import { defineCollectionTool } from '../../../defineTool.js'
5
+ import { getLogger } from '../../../utils/getLogger.js'
6
+
7
+ const DEFAULT_DESCRIPTION =
8
+ 'Count documents in any collection by passing the collection slug and optional where clause.'
9
+
10
+ export const countDocumentsTool = defineCollectionTool({
11
+ access: (args) =>
12
+ defaultAccess(args) && Boolean(args.permissions?.collections?.[args.slug]?.read),
13
+ annotations: {
14
+ destructiveHint: false,
15
+ idempotentHint: true,
16
+ openWorldHint: false,
17
+ readOnlyHint: true,
18
+ title: 'Count Documents',
19
+ },
20
+ description: DEFAULT_DESCRIPTION,
21
+ input: countDocumentsInputSchema,
22
+ }).handler(async ({ slug, authorizedMCP, input, req }) => {
23
+ const payload = req.payload
24
+ const logger = getLogger({ payload })
25
+ const { locale, trash, where } = input
26
+
27
+ logger.info(`Counting documents in collection: ${slug}`)
28
+
29
+ try {
30
+ const result = await payload.count({
31
+ collection: slug,
32
+ overrideAccess: authorizedMCP.overrideAccess,
33
+ req,
34
+ ...(locale ? { locale } : {}),
35
+ ...(trash !== undefined ? { trash } : {}),
36
+ ...(where ? { where } : {}),
37
+ })
38
+
39
+ return {
40
+ content: [
41
+ {
42
+ type: 'text',
43
+ text: `Collection "${slug}" contains ${result.totalDocs} matching documents.\n\`\`\`json\n${JSON.stringify(result)}\n\`\`\``,
44
+ },
45
+ ],
46
+ doc: result,
47
+ }
48
+ } catch (error) {
49
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error'
50
+ logger.error(`Error counting documents in ${slug}: ${errorMessage}`)
51
+ return {
52
+ content: [
53
+ {
54
+ type: 'text',
55
+ text: `❌ **Error counting documents in collection "${slug}":** ${errorMessage}`,
56
+ },
57
+ ],
58
+ isError: true,
59
+ }
60
+ }
61
+ })
@@ -0,0 +1,60 @@
1
+ import { countVersionsInputSchema } from 'payload'
2
+
3
+ import { defaultAccess } from '../../../defaultAccess.js'
4
+ import { defineCollectionTool } from '../../../defineTool.js'
5
+ import { getLogger } from '../../../utils/getLogger.js'
6
+
7
+ const DEFAULT_DESCRIPTION =
8
+ 'Count document versions in any version-enabled collection by passing the collection slug and optional where clause.'
9
+
10
+ export const countVersionsTool = defineCollectionTool({
11
+ access: (args) =>
12
+ defaultAccess(args) && Boolean(args.permissions?.collections?.[args.slug]?.readVersions),
13
+ annotations: {
14
+ destructiveHint: false,
15
+ idempotentHint: true,
16
+ openWorldHint: false,
17
+ readOnlyHint: true,
18
+ title: 'Count Versions',
19
+ },
20
+ description: DEFAULT_DESCRIPTION,
21
+ input: countVersionsInputSchema,
22
+ }).handler(async ({ slug, authorizedMCP, input, req }) => {
23
+ const payload = req.payload
24
+ const logger = getLogger({ payload })
25
+ const { locale, where } = input
26
+
27
+ logger.info(`Counting versions in collection: ${slug}`)
28
+
29
+ try {
30
+ const result = await payload.countVersions({
31
+ collection: slug,
32
+ overrideAccess: authorizedMCP.overrideAccess,
33
+ req,
34
+ ...(locale ? { locale } : {}),
35
+ ...(where ? { where } : {}),
36
+ })
37
+
38
+ return {
39
+ content: [
40
+ {
41
+ type: 'text',
42
+ text: `Collection "${slug}" contains ${result.totalDocs} matching versions.\n\`\`\`json\n${JSON.stringify(result)}\n\`\`\``,
43
+ },
44
+ ],
45
+ doc: result,
46
+ }
47
+ } catch (error) {
48
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error'
49
+ logger.error(`Error counting versions in ${slug}: ${errorMessage}`)
50
+ return {
51
+ content: [
52
+ {
53
+ type: 'text',
54
+ text: `❌ **Error counting versions in collection "${slug}":** ${errorMessage}`,
55
+ },
56
+ ],
57
+ isError: true,
58
+ }
59
+ }
60
+ })