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

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 (201) hide show
  1. package/dist/defaultAccess.d.ts +3 -0
  2. package/dist/defaultAccess.d.ts.map +1 -0
  3. package/dist/defaultAccess.js +3 -0
  4. package/dist/defaultAccess.js.map +1 -0
  5. package/dist/endpoint/access.d.ts +17 -5
  6. package/dist/endpoint/access.d.ts.map +1 -1
  7. package/dist/endpoint/access.js +82 -88
  8. package/dist/endpoint/access.js.map +1 -1
  9. package/dist/endpoint/index.d.ts.map +1 -1
  10. package/dist/endpoint/index.js +11 -0
  11. package/dist/endpoint/index.js.map +1 -1
  12. package/dist/exports/client.d.ts +1 -1
  13. package/dist/exports/client.d.ts.map +1 -1
  14. package/dist/exports/client.js +1 -1
  15. package/dist/exports/client.js.map +1 -1
  16. package/dist/exports/internal.d.ts +2 -0
  17. package/dist/exports/internal.d.ts.map +1 -0
  18. package/dist/exports/internal.js +3 -0
  19. package/dist/exports/internal.js.map +1 -0
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +13 -18
  22. package/dist/index.js.map +1 -1
  23. package/dist/mcp/buildMcpServer.d.ts.map +1 -1
  24. package/dist/mcp/buildMcpServer.js +102 -71
  25. package/dist/mcp/buildMcpServer.js.map +1 -1
  26. package/dist/mcp/builtin/collections/authTools.d.ts.map +1 -1
  27. package/dist/mcp/builtin/collections/authTools.js +44 -6
  28. package/dist/mcp/builtin/collections/authTools.js.map +1 -1
  29. package/dist/mcp/builtin/collections/countTool.d.ts +2 -0
  30. package/dist/mcp/builtin/collections/countTool.d.ts.map +1 -0
  31. package/dist/mcp/builtin/collections/countTool.js +69 -0
  32. package/dist/mcp/builtin/collections/countTool.js.map +1 -0
  33. package/dist/mcp/builtin/collections/countVersionsTool.d.ts +2 -0
  34. package/dist/mcp/builtin/collections/countVersionsTool.d.ts.map +1 -0
  35. package/dist/mcp/builtin/collections/countVersionsTool.js +65 -0
  36. package/dist/mcp/builtin/collections/countVersionsTool.js.map +1 -0
  37. package/dist/mcp/builtin/collections/createTool.d.ts +1 -1
  38. package/dist/mcp/builtin/collections/createTool.d.ts.map +1 -1
  39. package/dist/mcp/builtin/collections/createTool.js +38 -42
  40. package/dist/mcp/builtin/collections/createTool.js.map +1 -1
  41. package/dist/mcp/builtin/collections/deleteTool.d.ts +1 -1
  42. package/dist/mcp/builtin/collections/deleteTool.d.ts.map +1 -1
  43. package/dist/mcp/builtin/collections/deleteTool.js +14 -20
  44. package/dist/mcp/builtin/collections/deleteTool.js.map +1 -1
  45. package/dist/mcp/builtin/collections/duplicateTool.d.ts +2 -0
  46. package/dist/mcp/builtin/collections/duplicateTool.d.ts.map +1 -0
  47. package/dist/mcp/builtin/collections/duplicateTool.js +97 -0
  48. package/dist/mcp/builtin/collections/duplicateTool.js.map +1 -0
  49. package/dist/mcp/builtin/collections/findDistinctTool.d.ts +2 -0
  50. package/dist/mcp/builtin/collections/findDistinctTool.d.ts.map +1 -0
  51. package/dist/mcp/builtin/collections/findDistinctTool.js +93 -0
  52. package/dist/mcp/builtin/collections/findDistinctTool.js.map +1 -0
  53. package/dist/mcp/builtin/collections/findTool.d.ts +1 -1
  54. package/dist/mcp/builtin/collections/findTool.d.ts.map +1 -1
  55. package/dist/mcp/builtin/collections/findTool.js +49 -43
  56. package/dist/mcp/builtin/collections/findTool.js.map +1 -1
  57. package/dist/mcp/builtin/collections/findVersionByIDTool.d.ts +2 -0
  58. package/dist/mcp/builtin/collections/findVersionByIDTool.d.ts.map +1 -0
  59. package/dist/mcp/builtin/collections/findVersionByIDTool.js +84 -0
  60. package/dist/mcp/builtin/collections/findVersionByIDTool.js.map +1 -0
  61. package/dist/mcp/builtin/collections/findVersionsTool.d.ts +2 -0
  62. package/dist/mcp/builtin/collections/findVersionsTool.d.ts.map +1 -0
  63. package/dist/mcp/builtin/collections/findVersionsTool.js +99 -0
  64. package/dist/mcp/builtin/collections/findVersionsTool.js.map +1 -0
  65. package/dist/mcp/builtin/collections/formatCollectionError.d.ts +9 -0
  66. package/dist/mcp/builtin/collections/formatCollectionError.d.ts.map +1 -0
  67. package/dist/mcp/builtin/collections/formatCollectionError.js +60 -0
  68. package/dist/mcp/builtin/collections/formatCollectionError.js.map +1 -0
  69. package/dist/mcp/builtin/collections/getCollectionSchemaTool.d.ts +2 -0
  70. package/dist/mcp/builtin/collections/getCollectionSchemaTool.d.ts.map +1 -0
  71. package/dist/mcp/builtin/collections/getCollectionSchemaTool.js +47 -0
  72. package/dist/mcp/builtin/collections/getCollectionSchemaTool.js.map +1 -0
  73. package/dist/mcp/builtin/collections/restoreVersionTool.d.ts +2 -0
  74. package/dist/mcp/builtin/collections/restoreVersionTool.d.ts.map +1 -0
  75. package/dist/mcp/builtin/collections/restoreVersionTool.js +82 -0
  76. package/dist/mcp/builtin/collections/restoreVersionTool.js.map +1 -0
  77. package/dist/mcp/builtin/collections/updateTool.d.ts +1 -1
  78. package/dist/mcp/builtin/collections/updateTool.d.ts.map +1 -1
  79. package/dist/mcp/builtin/collections/updateTool.js +87 -86
  80. package/dist/mcp/builtin/collections/updateTool.js.map +1 -1
  81. package/dist/mcp/builtin/getConfigInfoTool.d.ts +2 -0
  82. package/dist/mcp/builtin/getConfigInfoTool.d.ts.map +1 -0
  83. package/dist/mcp/builtin/getConfigInfoTool.js +71 -0
  84. package/dist/mcp/builtin/getConfigInfoTool.js.map +1 -0
  85. package/dist/mcp/builtin/globals/countVersionsTool.d.ts +2 -0
  86. package/dist/mcp/builtin/globals/countVersionsTool.d.ts.map +1 -0
  87. package/dist/mcp/builtin/globals/countVersionsTool.js +65 -0
  88. package/dist/mcp/builtin/globals/countVersionsTool.js.map +1 -0
  89. package/dist/mcp/builtin/globals/findTool.d.ts.map +1 -1
  90. package/dist/mcp/builtin/globals/findTool.js +18 -21
  91. package/dist/mcp/builtin/globals/findTool.js.map +1 -1
  92. package/dist/mcp/builtin/globals/findVersionByIDTool.d.ts +2 -0
  93. package/dist/mcp/builtin/globals/findVersionByIDTool.d.ts.map +1 -0
  94. package/dist/mcp/builtin/globals/findVersionByIDTool.js +80 -0
  95. package/dist/mcp/builtin/globals/findVersionByIDTool.js.map +1 -0
  96. package/dist/mcp/builtin/globals/findVersionsTool.d.ts +2 -0
  97. package/dist/mcp/builtin/globals/findVersionsTool.d.ts.map +1 -0
  98. package/dist/mcp/builtin/globals/findVersionsTool.js +95 -0
  99. package/dist/mcp/builtin/globals/findVersionsTool.js.map +1 -0
  100. package/dist/mcp/builtin/globals/getGlobalSchemaTool.d.ts +2 -0
  101. package/dist/mcp/builtin/globals/getGlobalSchemaTool.d.ts.map +1 -0
  102. package/dist/mcp/builtin/globals/getGlobalSchemaTool.js +47 -0
  103. package/dist/mcp/builtin/globals/getGlobalSchemaTool.js.map +1 -0
  104. package/dist/mcp/builtin/globals/restoreVersionTool.d.ts +2 -0
  105. package/dist/mcp/builtin/globals/restoreVersionTool.d.ts.map +1 -0
  106. package/dist/mcp/builtin/globals/restoreVersionTool.js +78 -0
  107. package/dist/mcp/builtin/globals/restoreVersionTool.js.map +1 -0
  108. package/dist/mcp/builtin/globals/updateTool.d.ts.map +1 -1
  109. package/dist/mcp/builtin/globals/updateTool.js +31 -40
  110. package/dist/mcp/builtin/globals/updateTool.js.map +1 -1
  111. package/dist/mcp/builtin/validateEntityData.d.ts +14 -0
  112. package/dist/mcp/builtin/validateEntityData.d.ts.map +1 -0
  113. package/dist/mcp/builtin/validateEntityData.js +82 -0
  114. package/dist/mcp/builtin/validateEntityData.js.map +1 -0
  115. package/dist/mcp/builtinTools.d.ts +144 -19
  116. package/dist/mcp/builtinTools.d.ts.map +1 -1
  117. package/dist/mcp/builtinTools.js +119 -20
  118. package/dist/mcp/builtinTools.js.map +1 -1
  119. package/dist/mcp/sanitizeMCPConfig.d.ts +0 -1
  120. package/dist/mcp/sanitizeMCPConfig.d.ts.map +1 -1
  121. package/dist/mcp/sanitizeMCPConfig.js +120 -58
  122. package/dist/mcp/sanitizeMCPConfig.js.map +1 -1
  123. package/dist/stdio.d.ts +3 -2
  124. package/dist/stdio.d.ts.map +1 -1
  125. package/dist/stdio.js +27 -8
  126. package/dist/stdio.js.map +1 -1
  127. package/dist/types.d.ts +62 -108
  128. package/dist/types.d.ts.map +1 -1
  129. package/dist/types.js +4 -4
  130. package/dist/types.js.map +1 -1
  131. package/dist/utils/getPluginConfig.d.ts +1 -1
  132. package/dist/utils/getPluginConfig.js +1 -1
  133. package/dist/utils/getPluginConfig.js.map +1 -1
  134. package/dist/utils/schemaConversion/getEntityInputSchema.d.ts +11 -0
  135. package/dist/utils/schemaConversion/getEntityInputSchema.d.ts.map +1 -0
  136. package/dist/utils/schemaConversion/getEntityInputSchema.js +34 -0
  137. package/dist/utils/schemaConversion/getEntityInputSchema.js.map +1 -0
  138. package/dist/utils/whereSchema.d.ts +9 -0
  139. package/dist/utils/whereSchema.d.ts.map +1 -0
  140. package/dist/utils/whereSchema.js +13 -0
  141. package/dist/utils/whereSchema.js.map +1 -0
  142. package/package.json +8 -11
  143. package/src/defaultAccess.ts +3 -0
  144. package/src/endpoint/access.ts +88 -101
  145. package/src/endpoint/index.ts +14 -1
  146. package/src/exports/client.ts +2 -1
  147. package/src/exports/internal.ts +1 -0
  148. package/src/index.ts +8 -16
  149. package/src/mcp/buildMcpServer.ts +131 -96
  150. package/src/mcp/builtin/collections/authTools.ts +45 -9
  151. package/src/mcp/builtin/collections/countTool.ts +74 -0
  152. package/src/mcp/builtin/collections/countVersionsTool.ts +70 -0
  153. package/src/mcp/builtin/collections/createTool.ts +55 -59
  154. package/src/mcp/builtin/collections/deleteTool.ts +19 -16
  155. package/src/mcp/builtin/collections/duplicateTool.ts +135 -0
  156. package/src/mcp/builtin/collections/findDistinctTool.ts +120 -0
  157. package/src/mcp/builtin/collections/findTool.ts +63 -33
  158. package/src/mcp/builtin/collections/findVersionByIDTool.ts +110 -0
  159. package/src/mcp/builtin/collections/findVersionsTool.ts +155 -0
  160. package/src/mcp/builtin/collections/formatCollectionError.ts +84 -0
  161. package/src/mcp/builtin/collections/getCollectionSchemaTool.ts +46 -0
  162. package/src/mcp/builtin/collections/restoreVersionTool.ts +108 -0
  163. package/src/mcp/builtin/collections/updateTool.ts +111 -110
  164. package/src/mcp/builtin/getConfigInfoTool.ts +69 -0
  165. package/src/mcp/builtin/globals/countVersionsTool.ts +69 -0
  166. package/src/mcp/builtin/globals/findTool.ts +26 -17
  167. package/src/mcp/builtin/globals/findVersionByIDTool.ts +104 -0
  168. package/src/mcp/builtin/globals/findVersionsTool.ts +148 -0
  169. package/src/mcp/builtin/globals/getGlobalSchemaTool.ts +41 -0
  170. package/src/mcp/builtin/globals/restoreVersionTool.ts +100 -0
  171. package/src/mcp/builtin/globals/updateTool.ts +50 -55
  172. package/src/mcp/builtin/validateEntityData.ts +132 -0
  173. package/src/mcp/builtinTools.ts +111 -41
  174. package/src/mcp/sanitizeMCPConfig.ts +116 -78
  175. package/src/stdio.ts +23 -8
  176. package/src/types.ts +77 -112
  177. package/src/utils/getPluginConfig.ts +1 -1
  178. package/src/utils/schemaConversion/getEntityInputSchema.ts +78 -0
  179. package/src/utils/whereSchema.ts +24 -0
  180. package/dist/collection/getAccessField.d.ts +0 -12
  181. package/dist/collection/getAccessField.d.ts.map +0 -1
  182. package/dist/collection/getAccessField.js +0 -57
  183. package/dist/collection/getAccessField.js.map +0 -1
  184. package/dist/collection/index.d.ts +0 -6
  185. package/dist/collection/index.d.ts.map +0 -1
  186. package/dist/collection/index.js +0 -60
  187. package/dist/collection/index.js.map +0 -1
  188. package/dist/components/AccessField/index.client.d.ts +0 -10
  189. package/dist/components/AccessField/index.client.d.ts.map +0 -1
  190. package/dist/components/AccessField/index.client.js +0 -305
  191. package/dist/components/AccessField/index.client.js.map +0 -1
  192. package/dist/components/AccessField/index.css +0 -93
  193. package/dist/utils/schemaConversion/buildToolInput.d.ts +0 -29
  194. package/dist/utils/schemaConversion/buildToolInput.d.ts.map +0 -1
  195. package/dist/utils/schemaConversion/buildToolInput.js +0 -51
  196. package/dist/utils/schemaConversion/buildToolInput.js.map +0 -1
  197. package/src/collection/getAccessField.ts +0 -64
  198. package/src/collection/index.ts +0 -64
  199. package/src/components/AccessField/index.client.tsx +0 -344
  200. package/src/components/AccessField/index.css +0 -93
  201. package/src/utils/schemaConversion/buildToolInput.ts +0 -68
@@ -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
  >
@@ -8,16 +8,16 @@ import type {
8
8
  } from 'payload'
9
9
 
10
10
  import type {
11
+ CollectionMCPItem,
11
12
  CollectionTool,
13
+ GlobalMCPItem,
12
14
  GlobalTool,
13
- MCPBuiltInToolOverride,
14
15
  MCPItem,
15
- MCPPluginCollectionConfig,
16
16
  MCPPluginConfig,
17
- MCPPluginGlobalConfig,
18
17
  SanitizedMCPPluginConfig,
19
18
  } from '../types.js'
20
19
 
20
+ import { defaultAccess } from '../defaultAccess.js'
21
21
  import {
22
22
  COLLECTION_AUTH_BUILTIN_ENTRIES,
23
23
  COLLECTION_AUTH_BUILTINS,
@@ -25,6 +25,8 @@ import {
25
25
  COLLECTION_BUILTINS,
26
26
  GLOBAL_BUILTIN_ENTRIES,
27
27
  GLOBAL_BUILTINS,
28
+ TOOL_BUILTIN_ENTRIES,
29
+ TOOL_BUILTINS,
28
30
  } from './builtinTools.js'
29
31
 
30
32
  /**
@@ -32,7 +34,6 @@ import {
32
34
  * - Flattens `tools` / `prompts` / `resources` / per-collection / per-global
33
35
  * tool maps into a single `items` array.
34
36
  * - Applies built-in tools for collections and globals, respecting opt-out user overrides.
35
- * - Applies the `userCollection` default
36
37
  *
37
38
  * Called once during plugin init. After that, `plugins['@payloadcms/plugin-mcp']
38
39
  * ?.options` holds the sanitized result
@@ -54,44 +55,54 @@ export const sanitizeMCPConfig = ({
54
55
  items.push(...sanitizeGlobalConfig({ global, pluginConfig }))
55
56
  }
56
57
 
57
- for (const [key, tool] of Object.entries(pluginConfig.tools ?? {})) {
58
+ for (const [configKey, { mcpName, tool }] of TOOL_BUILTIN_ENTRIES) {
58
59
  items.push({
59
60
  type: 'tool',
60
- key,
61
- label: key,
62
- tool,
61
+ configKey,
62
+ label: tool.annotations?.title ?? configKey,
63
+ mcpName,
64
+ tool: { ...tool, access: tool.access ?? defaultAccess },
63
65
  })
64
66
  }
65
67
 
66
- for (const [key, prompt] of Object.entries(pluginConfig.prompts ?? {})) {
68
+ for (const [configKey, tool] of Object.entries(pluginConfig.tools ?? {})) {
69
+ if (configKey in TOOL_BUILTINS) {
70
+ continue
71
+ }
72
+ items.push({
73
+ type: 'tool',
74
+ configKey,
75
+ label: tool.annotations?.title ?? configKey,
76
+ mcpName: configKey,
77
+ tool: { ...tool, access: tool.access ?? defaultAccess },
78
+ })
79
+ }
80
+
81
+ for (const [configKey, prompt] of Object.entries(pluginConfig.prompts ?? {})) {
67
82
  items.push({
68
83
  type: 'prompt',
69
- key,
70
- label: prompt.title ?? key,
71
- prompt,
84
+ configKey,
85
+ label: prompt.title ?? configKey,
86
+ mcpName: configKey,
87
+ prompt: { ...prompt, access: prompt.access ?? defaultAccess },
72
88
  })
73
89
  }
74
90
 
75
- for (const [key, resource] of Object.entries(pluginConfig.resources ?? {})) {
91
+ for (const [configKey, resource] of Object.entries(pluginConfig.resources ?? {})) {
76
92
  items.push({
77
93
  type: 'resource',
78
- key,
79
- label: resource.title ?? key,
80
- resource,
94
+ configKey,
95
+ label: resource.title ?? configKey,
96
+ mcpName: configKey,
97
+ resource: { ...resource, access: resource.access ?? defaultAccess },
81
98
  })
82
99
  }
83
100
 
84
- // Mirror Payload's own admin.user detection (sanitize.ts) since plugins run first.
85
- const firstCollectionWithAuth = config.collections!.find(({ auth }) => Boolean(auth))
86
-
87
101
  return {
88
102
  disabled: pluginConfig.disabled,
89
103
  items,
90
104
  mcp: pluginConfig.mcp,
91
- overrideApiKeyCollection: pluginConfig.overrideApiKeyCollection,
92
- overrideAuth: pluginConfig.overrideAuth,
93
- userCollection:
94
- pluginConfig.userCollection ?? config.admin?.user ?? firstCollectionWithAuth?.slug ?? 'users',
105
+ overrideGetAuthorizedMCP: pluginConfig.overrideGetAuthorizedMCP,
95
106
  }
96
107
  }
97
108
 
@@ -101,42 +112,78 @@ const sanitizeCollectionConfig = ({
101
112
  }: {
102
113
  collection: CollectionConfig | SanitizedCollectionConfig
103
114
  pluginConfig: MCPPluginConfig
104
- }): MCPItem[] => {
105
- if (collection.slug === 'payload-mcp-api-keys') {
106
- return []
107
- }
115
+ }): CollectionMCPItem[] => {
108
116
  const slug = collection.slug
109
117
  const collectionPluginConfig = pluginConfig.collections?.[slug]
110
- const items: MCPItem[] = []
118
+ const items: CollectionMCPItem[] = []
119
+ /**
120
+ * Payload disables duplicate for auth collections by default unless the
121
+ * collection explicitly opts back in with `disableDuplicate: false`.
122
+ */
123
+ const isDuplicateDisabled =
124
+ collection.disableDuplicate === true ||
125
+ (Boolean(collection.auth) && collection.disableDuplicate !== false)
111
126
 
112
- for (const [toolKey, tool] of COLLECTION_BUILTIN_ENTRIES) {
127
+ for (const [
128
+ toolKey,
129
+ { mcpName, requiresDuplicateEnabled, requiresVersions, tool },
130
+ ] of COLLECTION_BUILTIN_ENTRIES) {
131
+ if (requiresVersions && !collection.versions) {
132
+ continue
133
+ }
134
+ if (requiresDuplicateEnabled && isDuplicateDisabled) {
135
+ continue
136
+ }
113
137
  const matchedConfigEntry = collectionPluginConfig?.tools?.[toolKey]
114
138
  if (matchedConfigEntry === false) {
115
139
  continue
116
140
  }
141
+ const override = typeof matchedConfigEntry === 'object' ? matchedConfigEntry : undefined
142
+ const annotations = { ...tool.annotations, ...override?.annotations }
117
143
  items.push({
118
144
  type: 'collectionTool',
119
145
  collectionSlug: slug,
120
- key: toolKey,
121
- label: capitalize(toolKey),
122
- tool: overrideBuiltinTool(tool, matchedConfigEntry, collectionPluginConfig),
146
+ configKey: toolKey,
147
+ label: annotations.title ?? toolKey,
148
+ mcpName,
149
+ tool: {
150
+ ...tool,
151
+ access: override?.access ?? tool.access ?? defaultAccess,
152
+ annotations,
153
+ description: override?.description ?? tool.description,
154
+ overrideResponse:
155
+ override?.overrideResponse ??
156
+ collectionPluginConfig?.overrideResponse ??
157
+ tool.overrideResponse,
158
+ },
123
159
  })
124
160
  }
125
161
 
126
162
  if (collection.auth) {
127
- for (const [authToolKey, { label, tool }] of COLLECTION_AUTH_BUILTIN_ENTRIES) {
163
+ for (const [authToolKey, { mcpName, tool }] of COLLECTION_AUTH_BUILTIN_ENTRIES) {
128
164
  const matchedConfigEntry = collectionPluginConfig?.tools?.[authToolKey]
129
165
  if (!matchedConfigEntry) {
130
166
  continue
131
167
  }
132
168
  // `true` means "enable, no override"; only the object form carries fields.
133
169
  const override = typeof matchedConfigEntry === 'object' ? matchedConfigEntry : undefined
170
+ const annotations = { ...tool.annotations, ...override?.annotations }
134
171
  items.push({
135
172
  type: 'collectionTool',
136
173
  collectionSlug: slug,
137
- key: authToolKey,
138
- label,
139
- tool: overrideBuiltinTool(tool, override, collectionPluginConfig),
174
+ configKey: authToolKey,
175
+ label: annotations.title ?? authToolKey,
176
+ mcpName,
177
+ tool: {
178
+ ...tool,
179
+ access: override?.access ?? tool.access ?? defaultAccess,
180
+ annotations,
181
+ description: override?.description ?? tool.description,
182
+ overrideResponse:
183
+ override?.overrideResponse ??
184
+ collectionPluginConfig?.overrideResponse ??
185
+ tool.overrideResponse,
186
+ },
140
187
  })
141
188
  }
142
189
  }
@@ -146,8 +193,8 @@ const sanitizeCollectionConfig = ({
146
193
  const customEntries = Object.entries(collectionPluginConfig?.tools ?? {}) as Array<
147
194
  [string, CollectionTool | undefined]
148
195
  >
149
- for (const [key, customTool] of customEntries) {
150
- if (key in COLLECTION_BUILTINS || key in COLLECTION_AUTH_BUILTINS) {
196
+ for (const [configKey, customTool] of customEntries) {
197
+ if (configKey in COLLECTION_BUILTINS || configKey in COLLECTION_AUTH_BUILTINS) {
151
198
  continue
152
199
  }
153
200
  if (!customTool) {
@@ -156,9 +203,10 @@ const sanitizeCollectionConfig = ({
156
203
  items.push({
157
204
  type: 'collectionTool',
158
205
  collectionSlug: slug,
159
- key,
160
- label: key,
161
- tool: customTool,
206
+ configKey,
207
+ label: customTool.annotations?.title ?? configKey,
208
+ mcpName: configKey,
209
+ tool: { ...customTool, access: customTool.access ?? defaultAccess },
162
210
  })
163
211
  }
164
212
 
@@ -171,30 +219,45 @@ const sanitizeGlobalConfig = ({
171
219
  }: {
172
220
  global: GlobalConfig | SanitizedGlobalConfig
173
221
  pluginConfig: MCPPluginConfig
174
- }): MCPItem[] => {
222
+ }): GlobalMCPItem[] => {
175
223
  const slug = global.slug
176
224
  const globalPluginConfig = pluginConfig.globals?.[slug]
177
- const items: MCPItem[] = []
225
+ const items: GlobalMCPItem[] = []
178
226
 
179
- for (const [toolKey, baseTool] of GLOBAL_BUILTIN_ENTRIES) {
227
+ for (const [toolKey, { mcpName, requiresVersions, tool }] of GLOBAL_BUILTIN_ENTRIES) {
228
+ if (requiresVersions && !global.versions) {
229
+ continue
230
+ }
180
231
  const matchedConfigEntry = globalPluginConfig?.tools?.[toolKey]
181
232
  if (matchedConfigEntry === false) {
182
233
  continue
183
234
  }
235
+ const override = typeof matchedConfigEntry === 'object' ? matchedConfigEntry : undefined
236
+ const annotations = { ...tool.annotations, ...override?.annotations }
184
237
  items.push({
185
238
  type: 'globalTool',
239
+ configKey: toolKey,
186
240
  globalSlug: slug,
187
- key: toolKey,
188
- label: capitalize(toolKey),
189
- tool: overrideBuiltinTool(baseTool, matchedConfigEntry, globalPluginConfig),
241
+ label: annotations.title ?? toolKey,
242
+ mcpName,
243
+ tool: {
244
+ ...tool,
245
+ access: override?.access ?? tool.access ?? defaultAccess,
246
+ annotations,
247
+ description: override?.description ?? tool.description,
248
+ overrideResponse:
249
+ override?.overrideResponse ??
250
+ globalPluginConfig?.overrideResponse ??
251
+ tool.overrideResponse,
252
+ },
190
253
  })
191
254
  }
192
255
 
193
256
  const customEntries = Object.entries(globalPluginConfig?.tools ?? {}) as Array<
194
257
  [string, GlobalTool | undefined]
195
258
  >
196
- for (const [key, customTool] of customEntries) {
197
- if (key in GLOBAL_BUILTINS) {
259
+ for (const [configKey, customTool] of customEntries) {
260
+ if (configKey in GLOBAL_BUILTINS) {
198
261
  continue
199
262
  }
200
263
  if (!customTool) {
@@ -202,38 +265,13 @@ const sanitizeGlobalConfig = ({
202
265
  }
203
266
  items.push({
204
267
  type: 'globalTool',
268
+ configKey,
205
269
  globalSlug: slug,
206
- key,
207
- label: key,
208
- tool: customTool,
270
+ label: customTool.annotations?.title ?? configKey,
271
+ mcpName: configKey,
272
+ tool: { ...customTool, access: customTool.access ?? defaultAccess },
209
273
  })
210
274
  }
211
275
 
212
276
  return items
213
277
  }
214
-
215
- const capitalize = (s: string): string => s.charAt(0).toUpperCase() + s.slice(1)
216
-
217
- /**
218
- * Spread the static built-in tool and apply consumer-side overrides.
219
- * Precedence: per-tool override > scope-level (collection/global) override >
220
- * the static tool's defaults. `toolEntry` is whatever the user put under
221
- * `tools: { find: ... }` — could be `true`, `false`, or an override object —
222
- * so it's narrowed internally.
223
- */
224
- const overrideBuiltinTool = <TTool extends CollectionTool | GlobalTool>(
225
- tool: TTool,
226
- toolOverride?: MCPBuiltInToolOverride,
227
- entityPluginConfig?: TTool extends CollectionTool
228
- ? MCPPluginCollectionConfig<any>
229
- : MCPPluginGlobalConfig,
230
- ): TTool => {
231
- return {
232
- ...tool,
233
- description: toolOverride?.description ?? entityPluginConfig?.description ?? tool.description,
234
- overrideResponse:
235
- toolOverride?.overrideResponse ??
236
- entityPluginConfig?.overrideResponse ??
237
- tool.overrideResponse,
238
- }
239
- }
package/src/stdio.ts CHANGED
@@ -6,8 +6,9 @@ import { fileURLToPath, pathToFileURL } from 'node:url'
6
6
  import { createLocalReq, getPayload } from 'payload'
7
7
  import { findConfig } from 'payload/node'
8
8
 
9
- import type { AuthorizedMCP, SanitizedMCPPluginConfig } from './types.js'
9
+ import type { SanitizedMCPPluginConfig } from './types.js'
10
10
 
11
+ import { getAuthorizedMCP } from './endpoint/access.js'
11
12
  import { buildMcpServer } from './mcp/buildMcpServer.js'
12
13
  import { sanitizeMCPConfig } from './mcp/sanitizeMCPConfig.js'
13
14
  import { getPluginConfig } from './utils/getPluginConfig.js'
@@ -16,8 +17,9 @@ import { resolveProjectRoot } from './utils/resolveProjectRoot.js'
16
17
  /**
17
18
  * Stdio adapter for the Payload MCP server.
18
19
  *
19
- * Do not use in production. There's no auth; whoever can spawn the process gets
20
- * full access to your local data.
20
+ * Pass PAYLOAD_MCP_AUTHORIZATION when stdio should authenticate with the same
21
+ * Payload auth header as HTTP. In development, PAYLOAD_MCP_OVERRIDE_ACCESS=true
22
+ * skips access control for local setup.
21
23
  */
22
24
  export const runMcpStdio = async (): Promise<void> => {
23
25
  /**
@@ -62,14 +64,27 @@ export const runMcpStdio = async (): Promise<void> => {
62
64
  ;(payload.config.plugins ??= []).push(fakePluginFn)
63
65
  }
64
66
 
65
- const authorizedMCP: AuthorizedMCP = {
66
- items: pluginConfig.items,
67
- overrideAccess: true,
68
- user: null,
67
+ const overrideAccessEnv = process.env.PAYLOAD_MCP_OVERRIDE_ACCESS
68
+ let overrideAccess = false
69
+
70
+ if (overrideAccessEnv === 'true') {
71
+ overrideAccess = true
72
+ } else if (overrideAccessEnv && overrideAccessEnv !== 'false') {
73
+ throw new Error('PAYLOAD_MCP_OVERRIDE_ACCESS must be "true" or "false".')
74
+ }
75
+
76
+ if (overrideAccess && process.env.NODE_ENV !== 'development') {
77
+ throw new Error('PAYLOAD_MCP_OVERRIDE_ACCESS is only available in development.')
78
+ }
79
+
80
+ const headers = new Headers()
81
+ if (process.env.PAYLOAD_MCP_AUTHORIZATION) {
82
+ headers.set('Authorization', process.env.PAYLOAD_MCP_AUTHORIZATION)
69
83
  }
70
84
 
71
- const req = await createLocalReq({}, payload)
85
+ const req = await createLocalReq({ req: { headers } }, payload)
72
86
  req.payloadAPI = 'MCP' as const
87
+ const authorizedMCP = await getAuthorizedMCP({ overrideAccess, req })
73
88
 
74
89
  const server = buildMcpServer({ authorizedMCP, pluginConfig, req })
75
90