@payloadcms/plugin-mcp 4.0.0-canary.3 → 4.0.0-canary.5

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 (432) 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 +81 -103
  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 -4
  13. package/dist/exports/client.d.ts.map +1 -1
  14. package/dist/exports/client.js +1 -4
  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 +1 -54
  22. package/dist/index.js.map +1 -1
  23. package/dist/mcp/buildMcpServer.d.ts.map +1 -1
  24. package/dist/mcp/buildMcpServer.js.map +1 -1
  25. package/dist/mcp/builtin/collections/countTool.d.ts +2 -0
  26. package/dist/mcp/builtin/collections/countTool.d.ts.map +1 -0
  27. package/dist/mcp/builtin/collections/countTool.js +69 -0
  28. package/dist/mcp/builtin/collections/countTool.js.map +1 -0
  29. package/dist/mcp/builtin/collections/countVersionsTool.d.ts +2 -0
  30. package/dist/mcp/builtin/collections/countVersionsTool.d.ts.map +1 -0
  31. package/dist/mcp/builtin/collections/countVersionsTool.js +65 -0
  32. package/dist/mcp/builtin/collections/countVersionsTool.js.map +1 -0
  33. package/dist/mcp/builtin/collections/createTool.d.ts.map +1 -1
  34. package/dist/mcp/builtin/collections/createTool.js +2 -0
  35. package/dist/mcp/builtin/collections/createTool.js.map +1 -1
  36. package/dist/mcp/builtin/collections/deleteTool.d.ts.map +1 -1
  37. package/dist/mcp/builtin/collections/deleteTool.js +2 -0
  38. package/dist/mcp/builtin/collections/deleteTool.js.map +1 -1
  39. package/dist/mcp/builtin/collections/duplicateTool.d.ts +2 -0
  40. package/dist/mcp/builtin/collections/duplicateTool.d.ts.map +1 -0
  41. package/dist/mcp/builtin/collections/duplicateTool.js +97 -0
  42. package/dist/mcp/builtin/collections/duplicateTool.js.map +1 -0
  43. package/dist/mcp/builtin/collections/findDistinctTool.d.ts +2 -0
  44. package/dist/mcp/builtin/collections/findDistinctTool.d.ts.map +1 -0
  45. package/dist/mcp/builtin/collections/findDistinctTool.js +93 -0
  46. package/dist/mcp/builtin/collections/findDistinctTool.js.map +1 -0
  47. package/dist/mcp/builtin/collections/findTool.d.ts.map +1 -1
  48. package/dist/mcp/builtin/collections/findTool.js +2 -0
  49. package/dist/mcp/builtin/collections/findTool.js.map +1 -1
  50. package/dist/mcp/builtin/collections/findVersionByIDTool.d.ts +2 -0
  51. package/dist/mcp/builtin/collections/findVersionByIDTool.d.ts.map +1 -0
  52. package/dist/mcp/builtin/collections/findVersionByIDTool.js +84 -0
  53. package/dist/mcp/builtin/collections/findVersionByIDTool.js.map +1 -0
  54. package/dist/mcp/builtin/collections/findVersionsTool.d.ts +2 -0
  55. package/dist/mcp/builtin/collections/findVersionsTool.d.ts.map +1 -0
  56. package/dist/mcp/builtin/collections/findVersionsTool.js +99 -0
  57. package/dist/mcp/builtin/collections/findVersionsTool.js.map +1 -0
  58. package/dist/mcp/builtin/collections/formatCollectionError.d.ts +1 -1
  59. package/dist/mcp/builtin/collections/formatCollectionError.d.ts.map +1 -1
  60. package/dist/mcp/builtin/collections/formatCollectionError.js.map +1 -1
  61. package/dist/mcp/builtin/collections/getCollectionSchemaTool.d.ts.map +1 -1
  62. package/dist/mcp/builtin/collections/getCollectionSchemaTool.js +5 -0
  63. package/dist/mcp/builtin/collections/getCollectionSchemaTool.js.map +1 -1
  64. package/dist/mcp/builtin/collections/restoreVersionTool.d.ts +2 -0
  65. package/dist/mcp/builtin/collections/restoreVersionTool.d.ts.map +1 -0
  66. package/dist/mcp/builtin/collections/restoreVersionTool.js +82 -0
  67. package/dist/mcp/builtin/collections/restoreVersionTool.js.map +1 -0
  68. package/dist/mcp/builtin/collections/updateTool.d.ts.map +1 -1
  69. package/dist/mcp/builtin/collections/updateTool.js +2 -0
  70. package/dist/mcp/builtin/collections/updateTool.js.map +1 -1
  71. package/dist/mcp/builtin/getConfigInfoTool.d.ts.map +1 -1
  72. package/dist/mcp/builtin/getConfigInfoTool.js +20 -5
  73. package/dist/mcp/builtin/getConfigInfoTool.js.map +1 -1
  74. package/dist/mcp/builtin/globals/countVersionsTool.d.ts +2 -0
  75. package/dist/mcp/builtin/globals/countVersionsTool.d.ts.map +1 -0
  76. package/dist/mcp/builtin/globals/countVersionsTool.js +65 -0
  77. package/dist/mcp/builtin/globals/countVersionsTool.js.map +1 -0
  78. package/dist/mcp/builtin/globals/findTool.d.ts.map +1 -1
  79. package/dist/mcp/builtin/globals/findTool.js +2 -0
  80. package/dist/mcp/builtin/globals/findTool.js.map +1 -1
  81. package/dist/mcp/builtin/globals/findVersionByIDTool.d.ts +2 -0
  82. package/dist/mcp/builtin/globals/findVersionByIDTool.d.ts.map +1 -0
  83. package/dist/mcp/builtin/globals/findVersionByIDTool.js +80 -0
  84. package/dist/mcp/builtin/globals/findVersionByIDTool.js.map +1 -0
  85. package/dist/mcp/builtin/globals/findVersionsTool.d.ts +2 -0
  86. package/dist/mcp/builtin/globals/findVersionsTool.d.ts.map +1 -0
  87. package/dist/mcp/builtin/globals/findVersionsTool.js +95 -0
  88. package/dist/mcp/builtin/globals/findVersionsTool.js.map +1 -0
  89. package/dist/mcp/builtin/globals/getGlobalSchemaTool.d.ts.map +1 -1
  90. package/dist/mcp/builtin/globals/getGlobalSchemaTool.js +5 -0
  91. package/dist/mcp/builtin/globals/getGlobalSchemaTool.js.map +1 -1
  92. package/dist/mcp/builtin/globals/restoreVersionTool.d.ts +2 -0
  93. package/dist/mcp/builtin/globals/restoreVersionTool.d.ts.map +1 -0
  94. package/dist/mcp/builtin/globals/restoreVersionTool.js +78 -0
  95. package/dist/mcp/builtin/globals/restoreVersionTool.js.map +1 -0
  96. package/dist/mcp/builtin/globals/updateTool.d.ts.map +1 -1
  97. package/dist/mcp/builtin/globals/updateTool.js +2 -0
  98. package/dist/mcp/builtin/globals/updateTool.js.map +1 -1
  99. package/dist/mcp/builtinTools.d.ts +67 -2
  100. package/dist/mcp/builtinTools.d.ts.map +1 -1
  101. package/dist/mcp/builtinTools.js +64 -0
  102. package/dist/mcp/builtinTools.js.map +1 -1
  103. package/dist/mcp/sanitizeMCPConfig.d.ts +0 -1
  104. package/dist/mcp/sanitizeMCPConfig.d.ts.map +1 -1
  105. package/dist/mcp/sanitizeMCPConfig.js +44 -17
  106. package/dist/mcp/sanitizeMCPConfig.js.map +1 -1
  107. package/dist/stdio.d.ts +3 -2
  108. package/dist/stdio.d.ts.map +1 -1
  109. package/dist/stdio.js +27 -8
  110. package/dist/stdio.js.map +1 -1
  111. package/dist/types.d.ts +43 -85
  112. package/dist/types.d.ts.map +1 -1
  113. package/dist/types.js +4 -4
  114. package/dist/types.js.map +1 -1
  115. package/dist/utils/getPluginConfig.d.ts +1 -1
  116. package/dist/utils/getPluginConfig.js +1 -1
  117. package/dist/utils/getPluginConfig.js.map +1 -1
  118. package/dist/utils/schemaConversion/getEntityInputSchema.d.ts.map +1 -1
  119. package/dist/utils/schemaConversion/getEntityInputSchema.js +7 -9
  120. package/dist/utils/schemaConversion/getEntityInputSchema.js.map +1 -1
  121. package/dist/utils/schemaConversion/sanitizeEntitySchema.d.ts +5 -10
  122. package/dist/utils/schemaConversion/sanitizeEntitySchema.d.ts.map +1 -1
  123. package/dist/utils/schemaConversion/sanitizeEntitySchema.js +15 -95
  124. package/dist/utils/schemaConversion/sanitizeEntitySchema.js.map +1 -1
  125. package/dist/utils/schemaConversion/sanitizeEntitySchema.spec.js +15 -40
  126. package/dist/utils/schemaConversion/sanitizeEntitySchema.spec.js.map +1 -1
  127. package/package.json +9 -13
  128. package/src/defaultAccess.ts +3 -0
  129. package/src/endpoint/access.ts +87 -112
  130. package/src/endpoint/index.ts +14 -1
  131. package/src/exports/client.ts +2 -4
  132. package/src/exports/internal.ts +1 -0
  133. package/src/index.ts +1 -58
  134. package/src/mcp/buildMcpServer.ts +6 -1
  135. package/src/mcp/builtin/collections/countTool.ts +74 -0
  136. package/src/mcp/builtin/collections/countVersionsTool.ts +73 -0
  137. package/src/mcp/builtin/collections/createTool.ts +3 -0
  138. package/src/mcp/builtin/collections/deleteTool.ts +3 -0
  139. package/src/mcp/builtin/collections/duplicateTool.ts +135 -0
  140. package/src/mcp/builtin/collections/findDistinctTool.ts +119 -0
  141. package/src/mcp/builtin/collections/findTool.ts +3 -0
  142. package/src/mcp/builtin/collections/findVersionByIDTool.ts +110 -0
  143. package/src/mcp/builtin/collections/findVersionsTool.ts +155 -0
  144. package/src/mcp/builtin/collections/formatCollectionError.ts +1 -1
  145. package/src/mcp/builtin/collections/getCollectionSchemaTool.ts +11 -0
  146. package/src/mcp/builtin/collections/restoreVersionTool.ts +108 -0
  147. package/src/mcp/builtin/collections/updateTool.ts +3 -0
  148. package/src/mcp/builtin/getConfigInfoTool.ts +22 -4
  149. package/src/mcp/builtin/globals/countVersionsTool.ts +72 -0
  150. package/src/mcp/builtin/globals/findTool.ts +3 -0
  151. package/src/mcp/builtin/globals/findVersionByIDTool.ts +104 -0
  152. package/src/mcp/builtin/globals/findVersionsTool.ts +148 -0
  153. package/src/mcp/builtin/globals/getGlobalSchemaTool.ts +6 -0
  154. package/src/mcp/builtin/globals/restoreVersionTool.ts +99 -0
  155. package/src/mcp/builtin/globals/updateTool.ts +3 -0
  156. package/src/mcp/builtinTools.ts +63 -4
  157. package/src/mcp/sanitizeMCPConfig.ts +32 -19
  158. package/src/stdio.ts +23 -8
  159. package/src/types.ts +50 -88
  160. package/src/utils/getPluginConfig.ts +1 -1
  161. package/src/utils/schemaConversion/getEntityInputSchema.ts +10 -26
  162. package/src/utils/schemaConversion/sanitizeEntitySchema.spec.ts +12 -19
  163. package/src/utils/schemaConversion/sanitizeEntitySchema.ts +17 -114
  164. package/dist/collection/getAccessField.d.ts +0 -12
  165. package/dist/collection/getAccessField.d.ts.map +0 -1
  166. package/dist/collection/getAccessField.js +0 -72
  167. package/dist/collection/getAccessField.js.map +0 -1
  168. package/dist/collection/index.d.ts +0 -6
  169. package/dist/collection/index.d.ts.map +0 -1
  170. package/dist/collection/index.js +0 -105
  171. package/dist/collection/index.js.map +0 -1
  172. package/dist/components/APIKeyField/index.client.d.ts +0 -9
  173. package/dist/components/APIKeyField/index.client.d.ts.map +0 -1
  174. package/dist/components/APIKeyField/index.client.js +0 -85
  175. package/dist/components/APIKeyField/index.client.js.map +0 -1
  176. package/dist/components/APIKeyField/index.css +0 -105
  177. package/dist/components/APIKeysEmptyState/index.client.d.ts +0 -4
  178. package/dist/components/APIKeysEmptyState/index.client.d.ts.map +0 -1
  179. package/dist/components/APIKeysEmptyState/index.client.js +0 -21
  180. package/dist/components/APIKeysEmptyState/index.client.js.map +0 -1
  181. package/dist/components/AccessField/index.client.d.ts +0 -10
  182. package/dist/components/AccessField/index.client.d.ts.map +0 -1
  183. package/dist/components/AccessField/index.client.js +0 -247
  184. package/dist/components/AccessField/index.client.js.map +0 -1
  185. package/dist/components/AccessField/index.css +0 -99
  186. package/dist/components/SettingsMenu/index.client.d.ts +0 -8
  187. package/dist/components/SettingsMenu/index.client.d.ts.map +0 -1
  188. package/dist/components/SettingsMenu/index.client.js +0 -24
  189. package/dist/components/SettingsMenu/index.client.js.map +0 -1
  190. package/dist/translations/index.d.ts +0 -11
  191. package/dist/translations/index.d.ts.map +0 -1
  192. package/dist/translations/index.js +0 -92
  193. package/dist/translations/index.js.map +0 -1
  194. package/dist/translations/languages/ar.d.ts +0 -31
  195. package/dist/translations/languages/ar.d.ts.map +0 -1
  196. package/dist/translations/languages/ar.js +0 -34
  197. package/dist/translations/languages/ar.js.map +0 -1
  198. package/dist/translations/languages/az.d.ts +0 -31
  199. package/dist/translations/languages/az.d.ts.map +0 -1
  200. package/dist/translations/languages/az.js +0 -34
  201. package/dist/translations/languages/az.js.map +0 -1
  202. package/dist/translations/languages/bg.d.ts +0 -31
  203. package/dist/translations/languages/bg.d.ts.map +0 -1
  204. package/dist/translations/languages/bg.js +0 -34
  205. package/dist/translations/languages/bg.js.map +0 -1
  206. package/dist/translations/languages/bnBd.d.ts +0 -31
  207. package/dist/translations/languages/bnBd.d.ts.map +0 -1
  208. package/dist/translations/languages/bnBd.js +0 -34
  209. package/dist/translations/languages/bnBd.js.map +0 -1
  210. package/dist/translations/languages/bnIn.d.ts +0 -31
  211. package/dist/translations/languages/bnIn.d.ts.map +0 -1
  212. package/dist/translations/languages/bnIn.js +0 -34
  213. package/dist/translations/languages/bnIn.js.map +0 -1
  214. package/dist/translations/languages/ca.d.ts +0 -31
  215. package/dist/translations/languages/ca.d.ts.map +0 -1
  216. package/dist/translations/languages/ca.js +0 -34
  217. package/dist/translations/languages/ca.js.map +0 -1
  218. package/dist/translations/languages/cs.d.ts +0 -31
  219. package/dist/translations/languages/cs.d.ts.map +0 -1
  220. package/dist/translations/languages/cs.js +0 -34
  221. package/dist/translations/languages/cs.js.map +0 -1
  222. package/dist/translations/languages/da.d.ts +0 -31
  223. package/dist/translations/languages/da.d.ts.map +0 -1
  224. package/dist/translations/languages/da.js +0 -34
  225. package/dist/translations/languages/da.js.map +0 -1
  226. package/dist/translations/languages/de.d.ts +0 -31
  227. package/dist/translations/languages/de.d.ts.map +0 -1
  228. package/dist/translations/languages/de.js +0 -34
  229. package/dist/translations/languages/de.js.map +0 -1
  230. package/dist/translations/languages/en.d.ts +0 -31
  231. package/dist/translations/languages/en.d.ts.map +0 -1
  232. package/dist/translations/languages/en.js +0 -34
  233. package/dist/translations/languages/en.js.map +0 -1
  234. package/dist/translations/languages/es.d.ts +0 -31
  235. package/dist/translations/languages/es.d.ts.map +0 -1
  236. package/dist/translations/languages/es.js +0 -34
  237. package/dist/translations/languages/es.js.map +0 -1
  238. package/dist/translations/languages/et.d.ts +0 -31
  239. package/dist/translations/languages/et.d.ts.map +0 -1
  240. package/dist/translations/languages/et.js +0 -34
  241. package/dist/translations/languages/et.js.map +0 -1
  242. package/dist/translations/languages/fa.d.ts +0 -31
  243. package/dist/translations/languages/fa.d.ts.map +0 -1
  244. package/dist/translations/languages/fa.js +0 -34
  245. package/dist/translations/languages/fa.js.map +0 -1
  246. package/dist/translations/languages/fr.d.ts +0 -31
  247. package/dist/translations/languages/fr.d.ts.map +0 -1
  248. package/dist/translations/languages/fr.js +0 -34
  249. package/dist/translations/languages/fr.js.map +0 -1
  250. package/dist/translations/languages/he.d.ts +0 -31
  251. package/dist/translations/languages/he.d.ts.map +0 -1
  252. package/dist/translations/languages/he.js +0 -34
  253. package/dist/translations/languages/he.js.map +0 -1
  254. package/dist/translations/languages/hr.d.ts +0 -31
  255. package/dist/translations/languages/hr.d.ts.map +0 -1
  256. package/dist/translations/languages/hr.js +0 -34
  257. package/dist/translations/languages/hr.js.map +0 -1
  258. package/dist/translations/languages/hu.d.ts +0 -31
  259. package/dist/translations/languages/hu.d.ts.map +0 -1
  260. package/dist/translations/languages/hu.js +0 -34
  261. package/dist/translations/languages/hu.js.map +0 -1
  262. package/dist/translations/languages/hy.d.ts +0 -31
  263. package/dist/translations/languages/hy.d.ts.map +0 -1
  264. package/dist/translations/languages/hy.js +0 -34
  265. package/dist/translations/languages/hy.js.map +0 -1
  266. package/dist/translations/languages/id.d.ts +0 -31
  267. package/dist/translations/languages/id.d.ts.map +0 -1
  268. package/dist/translations/languages/id.js +0 -34
  269. package/dist/translations/languages/id.js.map +0 -1
  270. package/dist/translations/languages/is.d.ts +0 -31
  271. package/dist/translations/languages/is.d.ts.map +0 -1
  272. package/dist/translations/languages/is.js +0 -34
  273. package/dist/translations/languages/is.js.map +0 -1
  274. package/dist/translations/languages/it.d.ts +0 -31
  275. package/dist/translations/languages/it.d.ts.map +0 -1
  276. package/dist/translations/languages/it.js +0 -34
  277. package/dist/translations/languages/it.js.map +0 -1
  278. package/dist/translations/languages/ja.d.ts +0 -31
  279. package/dist/translations/languages/ja.d.ts.map +0 -1
  280. package/dist/translations/languages/ja.js +0 -34
  281. package/dist/translations/languages/ja.js.map +0 -1
  282. package/dist/translations/languages/ko.d.ts +0 -31
  283. package/dist/translations/languages/ko.d.ts.map +0 -1
  284. package/dist/translations/languages/ko.js +0 -34
  285. package/dist/translations/languages/ko.js.map +0 -1
  286. package/dist/translations/languages/lt.d.ts +0 -31
  287. package/dist/translations/languages/lt.d.ts.map +0 -1
  288. package/dist/translations/languages/lt.js +0 -34
  289. package/dist/translations/languages/lt.js.map +0 -1
  290. package/dist/translations/languages/lv.d.ts +0 -31
  291. package/dist/translations/languages/lv.d.ts.map +0 -1
  292. package/dist/translations/languages/lv.js +0 -34
  293. package/dist/translations/languages/lv.js.map +0 -1
  294. package/dist/translations/languages/my.d.ts +0 -31
  295. package/dist/translations/languages/my.d.ts.map +0 -1
  296. package/dist/translations/languages/my.js +0 -34
  297. package/dist/translations/languages/my.js.map +0 -1
  298. package/dist/translations/languages/nb.d.ts +0 -31
  299. package/dist/translations/languages/nb.d.ts.map +0 -1
  300. package/dist/translations/languages/nb.js +0 -34
  301. package/dist/translations/languages/nb.js.map +0 -1
  302. package/dist/translations/languages/nl.d.ts +0 -31
  303. package/dist/translations/languages/nl.d.ts.map +0 -1
  304. package/dist/translations/languages/nl.js +0 -34
  305. package/dist/translations/languages/nl.js.map +0 -1
  306. package/dist/translations/languages/pl.d.ts +0 -31
  307. package/dist/translations/languages/pl.d.ts.map +0 -1
  308. package/dist/translations/languages/pl.js +0 -34
  309. package/dist/translations/languages/pl.js.map +0 -1
  310. package/dist/translations/languages/pt.d.ts +0 -31
  311. package/dist/translations/languages/pt.d.ts.map +0 -1
  312. package/dist/translations/languages/pt.js +0 -34
  313. package/dist/translations/languages/pt.js.map +0 -1
  314. package/dist/translations/languages/ro.d.ts +0 -31
  315. package/dist/translations/languages/ro.d.ts.map +0 -1
  316. package/dist/translations/languages/ro.js +0 -34
  317. package/dist/translations/languages/ro.js.map +0 -1
  318. package/dist/translations/languages/rs.d.ts +0 -31
  319. package/dist/translations/languages/rs.d.ts.map +0 -1
  320. package/dist/translations/languages/rs.js +0 -34
  321. package/dist/translations/languages/rs.js.map +0 -1
  322. package/dist/translations/languages/rsLatin.d.ts +0 -31
  323. package/dist/translations/languages/rsLatin.d.ts.map +0 -1
  324. package/dist/translations/languages/rsLatin.js +0 -34
  325. package/dist/translations/languages/rsLatin.js.map +0 -1
  326. package/dist/translations/languages/ru.d.ts +0 -31
  327. package/dist/translations/languages/ru.d.ts.map +0 -1
  328. package/dist/translations/languages/ru.js +0 -34
  329. package/dist/translations/languages/ru.js.map +0 -1
  330. package/dist/translations/languages/sk.d.ts +0 -31
  331. package/dist/translations/languages/sk.d.ts.map +0 -1
  332. package/dist/translations/languages/sk.js +0 -34
  333. package/dist/translations/languages/sk.js.map +0 -1
  334. package/dist/translations/languages/sl.d.ts +0 -31
  335. package/dist/translations/languages/sl.d.ts.map +0 -1
  336. package/dist/translations/languages/sl.js +0 -34
  337. package/dist/translations/languages/sl.js.map +0 -1
  338. package/dist/translations/languages/sv.d.ts +0 -31
  339. package/dist/translations/languages/sv.d.ts.map +0 -1
  340. package/dist/translations/languages/sv.js +0 -34
  341. package/dist/translations/languages/sv.js.map +0 -1
  342. package/dist/translations/languages/ta.d.ts +0 -31
  343. package/dist/translations/languages/ta.d.ts.map +0 -1
  344. package/dist/translations/languages/ta.js +0 -34
  345. package/dist/translations/languages/ta.js.map +0 -1
  346. package/dist/translations/languages/th.d.ts +0 -31
  347. package/dist/translations/languages/th.d.ts.map +0 -1
  348. package/dist/translations/languages/th.js +0 -34
  349. package/dist/translations/languages/th.js.map +0 -1
  350. package/dist/translations/languages/tr.d.ts +0 -31
  351. package/dist/translations/languages/tr.d.ts.map +0 -1
  352. package/dist/translations/languages/tr.js +0 -34
  353. package/dist/translations/languages/tr.js.map +0 -1
  354. package/dist/translations/languages/uk.d.ts +0 -31
  355. package/dist/translations/languages/uk.d.ts.map +0 -1
  356. package/dist/translations/languages/uk.js +0 -34
  357. package/dist/translations/languages/uk.js.map +0 -1
  358. package/dist/translations/languages/vi.d.ts +0 -31
  359. package/dist/translations/languages/vi.d.ts.map +0 -1
  360. package/dist/translations/languages/vi.js +0 -34
  361. package/dist/translations/languages/vi.js.map +0 -1
  362. package/dist/translations/languages/zh.d.ts +0 -31
  363. package/dist/translations/languages/zh.d.ts.map +0 -1
  364. package/dist/translations/languages/zh.js +0 -34
  365. package/dist/translations/languages/zh.js.map +0 -1
  366. package/dist/translations/languages/zhTw.d.ts +0 -31
  367. package/dist/translations/languages/zhTw.d.ts.map +0 -1
  368. package/dist/translations/languages/zhTw.js +0 -34
  369. package/dist/translations/languages/zhTw.js.map +0 -1
  370. package/dist/translations/types.d.ts +0 -32
  371. package/dist/translations/types.d.ts.map +0 -1
  372. package/dist/translations/types.js +0 -3
  373. package/dist/translations/types.js.map +0 -1
  374. package/dist/utils/schemaConversion/removeVirtualFieldsFromSchema.d.ts +0 -7
  375. package/dist/utils/schemaConversion/removeVirtualFieldsFromSchema.d.ts.map +0 -1
  376. package/dist/utils/schemaConversion/removeVirtualFieldsFromSchema.js +0 -20
  377. package/dist/utils/schemaConversion/removeVirtualFieldsFromSchema.js.map +0 -1
  378. package/src/collection/getAccessField.ts +0 -84
  379. package/src/collection/index.ts +0 -105
  380. package/src/components/APIKeyField/index.client.tsx +0 -68
  381. package/src/components/APIKeyField/index.css +0 -105
  382. package/src/components/APIKeysEmptyState/index.client.tsx +0 -33
  383. package/src/components/AccessField/index.client.tsx +0 -296
  384. package/src/components/AccessField/index.css +0 -99
  385. package/src/components/SettingsMenu/index.client.tsx +0 -30
  386. package/src/translations/index.ts +0 -105
  387. package/src/translations/languages/ar.ts +0 -38
  388. package/src/translations/languages/az.ts +0 -38
  389. package/src/translations/languages/bg.ts +0 -39
  390. package/src/translations/languages/bnBd.ts +0 -39
  391. package/src/translations/languages/bnIn.ts +0 -39
  392. package/src/translations/languages/ca.ts +0 -39
  393. package/src/translations/languages/cs.ts +0 -39
  394. package/src/translations/languages/da.ts +0 -38
  395. package/src/translations/languages/de.ts +0 -39
  396. package/src/translations/languages/en.ts +0 -39
  397. package/src/translations/languages/es.ts +0 -39
  398. package/src/translations/languages/et.ts +0 -38
  399. package/src/translations/languages/fa.ts +0 -39
  400. package/src/translations/languages/fr.ts +0 -39
  401. package/src/translations/languages/he.ts +0 -37
  402. package/src/translations/languages/hr.ts +0 -39
  403. package/src/translations/languages/hu.ts +0 -39
  404. package/src/translations/languages/hy.ts +0 -39
  405. package/src/translations/languages/id.ts +0 -39
  406. package/src/translations/languages/is.ts +0 -39
  407. package/src/translations/languages/it.ts +0 -39
  408. package/src/translations/languages/ja.ts +0 -39
  409. package/src/translations/languages/ko.ts +0 -39
  410. package/src/translations/languages/lt.ts +0 -39
  411. package/src/translations/languages/lv.ts +0 -38
  412. package/src/translations/languages/my.ts +0 -39
  413. package/src/translations/languages/nb.ts +0 -39
  414. package/src/translations/languages/nl.ts +0 -39
  415. package/src/translations/languages/pl.ts +0 -38
  416. package/src/translations/languages/pt.ts +0 -39
  417. package/src/translations/languages/ro.ts +0 -39
  418. package/src/translations/languages/rs.ts +0 -38
  419. package/src/translations/languages/rsLatin.ts +0 -38
  420. package/src/translations/languages/ru.ts +0 -39
  421. package/src/translations/languages/sk.ts +0 -39
  422. package/src/translations/languages/sl.ts +0 -38
  423. package/src/translations/languages/sv.ts +0 -39
  424. package/src/translations/languages/ta.ts +0 -39
  425. package/src/translations/languages/th.ts +0 -38
  426. package/src/translations/languages/tr.ts +0 -38
  427. package/src/translations/languages/uk.ts +0 -39
  428. package/src/translations/languages/vi.ts +0 -39
  429. package/src/translations/languages/zh.ts +0 -36
  430. package/src/translations/languages/zhTw.ts +0 -36
  431. package/src/translations/types.ts +0 -34
  432. package/src/utils/schemaConversion/removeVirtualFieldsFromSchema.ts +0 -27
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
 
package/src/types.ts CHANGED
@@ -10,15 +10,15 @@ import type {
10
10
  } from '@modelcontextprotocol/server'
11
11
  import type {
12
12
  AuthCollectionSlug,
13
- CollectionConfig,
14
13
  CollectionSlug,
15
- DefaultDocumentIDType,
16
14
  GlobalSlug,
17
15
  MaybePromise,
18
16
  PayloadRequest,
17
+ SanitizedPermissions,
19
18
  TypedUser,
20
19
  } from 'payload'
21
20
 
21
+ import type { GetAuthorizedMCPArgs } from './endpoint/access.js'
22
22
  import type {
23
23
  MCPCollectionAuthToolName,
24
24
  MCPCollectionBuiltinName,
@@ -36,27 +36,6 @@ export type { JsonSchemaType, StandardSchemaWithJSON, ToolAnnotations }
36
36
  */
37
37
  export type ToolInputSchema = JsonSchemaType | StandardSchemaWithJSON
38
38
 
39
- /**
40
- * Serializable mirror of `SanitizedMCPPluginConfig` for client components —
41
- * the full sanitized config carries functions (tool handlers, etc.) that can't
42
- * cross the server→client boundary. Built by `sanitizeClientPluginConfig` and
43
- * passed to the `AccessField` component via `clientProps`.
44
- *
45
- * @internal
46
- */
47
- export type ClientMCPPluginConfig = {
48
- items: Array<{
49
- collectionSlug?: string
50
- configKey: string
51
- description?: string
52
- globalSlug?: string
53
- /** Admin-UI bucket for collection/global tools: built-in CRUD, auth, or custom. */
54
- group?: 'auth' | 'custom' | 'operations'
55
- label: string
56
- type: 'collectionTool' | 'globalTool' | 'prompt' | 'resource' | 'tool'
57
- }>
58
- }
59
-
60
39
  export type MCPToolResponse = {
61
40
  content: ContentBlock[]
62
41
  /**
@@ -83,6 +62,19 @@ export type TypedInput<TSchema> = TSchema extends StandardSchemaWithJSON
83
62
  : StandardSchemaWithJSON.InferOutput<TSchema>
84
63
  : Record<string, unknown>
85
64
 
65
+ export type MCPAccessArgs = {
66
+ permissions?: SanitizedPermissions
67
+ req: PayloadRequest
68
+ }
69
+
70
+ export type CollectionMCPAccessArgs = {
71
+ collectionSlug: CollectionSlug
72
+ } & MCPAccessArgs
73
+
74
+ export type GlobalMCPAccessArgs = {
75
+ globalSlug: GlobalSlug
76
+ } & MCPAccessArgs
77
+
86
78
  export type ToolHandlerArgs<TSchema = undefined> = {
87
79
  authorizedMCP: AuthorizedMCP
88
80
  input: TypedInput<TSchema>
@@ -99,6 +91,7 @@ export type GlobalToolHandlerArgs<TSchema = undefined> = {
99
91
  } & ToolHandlerArgs<TSchema>
100
92
 
101
93
  export type Tool<TSchema extends ToolInputSchema | undefined = ToolInputSchema | undefined> = {
94
+ access?: (args: MCPAccessArgs) => MaybePromise<boolean>
102
95
  annotations?: ToolAnnotations
103
96
  description: string
104
97
  handler: (args: ToolHandlerArgs<TSchema>) => MaybePromise<MCPToolResponse>
@@ -112,12 +105,14 @@ export type Tool<TSchema extends ToolInputSchema | undefined = ToolInputSchema |
112
105
  export type CollectionTool<
113
106
  TSchema extends ToolInputSchema | undefined = ToolInputSchema | undefined,
114
107
  > = {
108
+ access?: (args: CollectionMCPAccessArgs) => MaybePromise<boolean>
115
109
  handler: (args: CollectionToolHandlerArgs<TSchema>) => MaybePromise<MCPToolResponse>
116
110
  input?: TSchema
117
111
  } & Pick<Tool, 'annotations' | 'description' | 'overrideResponse'>
118
112
 
119
113
  export type GlobalTool<TSchema extends ToolInputSchema | undefined = ToolInputSchema | undefined> =
120
114
  {
115
+ access?: (args: GlobalMCPAccessArgs) => MaybePromise<boolean>
121
116
  handler: (args: GlobalToolHandlerArgs<TSchema>) => MaybePromise<MCPToolResponse>
122
117
  input?: TSchema
123
118
  } & Pick<Tool, 'annotations' | 'description' | 'overrideResponse'>
@@ -127,7 +122,16 @@ export type GlobalTool<TSchema extends ToolInputSchema | undefined = ToolInputSc
127
122
  * `handler?: never` prevents a full `CollectionTool`/`GlobalTool` (which has a
128
123
  * required handler) from being silently accepted at a built-in key slot.
129
124
  */
130
- export type MCPBuiltInToolOverride = {
125
+ export type MCPBuiltInCollectionToolOverride = {
126
+ access?: (args: CollectionMCPAccessArgs) => MaybePromise<boolean>
127
+ annotations?: ToolAnnotations
128
+ description?: string
129
+ handler?: never
130
+ overrideResponse?: MCPResponseOverride
131
+ }
132
+
133
+ export type MCPBuiltInGlobalToolOverride = {
134
+ access?: (args: GlobalMCPAccessArgs) => MaybePromise<boolean>
131
135
  annotations?: ToolAnnotations
132
136
  description?: string
133
137
  handler?: never
@@ -142,13 +146,13 @@ export type MCPBuiltInToolOverride = {
142
146
  export type MCPTopLevelToolEntry = Tool
143
147
 
144
148
  export type MCPCollectionToolsMap = {
145
- [customToolName: string]: boolean | CollectionTool | MCPBuiltInToolOverride | undefined
149
+ [customToolName: string]: boolean | CollectionTool | MCPBuiltInCollectionToolOverride | undefined
146
150
  } & {
147
- [K in MCPCollectionBuiltinName]?: false | MCPBuiltInToolOverride
151
+ [K in MCPCollectionBuiltinName]?: false | MCPBuiltInCollectionToolOverride
148
152
  }
149
153
 
150
154
  export type MCPAuthCollectionToolsMap = {
151
- [K in MCPCollectionAuthToolName]?: MCPBuiltInToolOverride | true
155
+ [K in MCPCollectionAuthToolName]?: MCPBuiltInCollectionToolOverride | true
152
156
  } & MCPCollectionToolsMap
153
157
 
154
158
  /** Auth-enabled collections get auth-tool name autocomplete; others get CRUD-only. */
@@ -157,9 +161,9 @@ export type MCPToolsMapForCollection<Slug extends CollectionSlug> = Slug extends
157
161
  : MCPCollectionToolsMap
158
162
 
159
163
  export type MCPGlobalToolsMap = {
160
- [customToolName: string]: boolean | GlobalTool | MCPBuiltInToolOverride | undefined
164
+ [customToolName: string]: boolean | GlobalTool | MCPBuiltInGlobalToolOverride | undefined
161
165
  } & {
162
- [K in MCPGlobalBuiltinName]?: false | MCPBuiltInToolOverride
166
+ [K in MCPGlobalBuiltinName]?: false | MCPBuiltInGlobalToolOverride
163
167
  }
164
168
 
165
169
  export type MCPTopLevelToolsMap = Record<string, Tool>
@@ -171,6 +175,7 @@ export type PromptHandlerArgs<TSchema = undefined> = {
171
175
  }
172
176
 
173
177
  export type Prompt<TSchema extends ToolInputSchema = ToolInputSchema> = {
178
+ access?: (args: MCPAccessArgs) => MaybePromise<boolean>
174
179
  argsSchema: TSchema
175
180
  description: string
176
181
  handler: (args: PromptHandlerArgs<TSchema>) => MaybePromise<{
@@ -188,6 +193,7 @@ export type ResourceHandlerArgs = {
188
193
  }
189
194
 
190
195
  export type Resource = {
196
+ access?: (args: MCPAccessArgs) => MaybePromise<boolean>
191
197
  description: string
192
198
  handler: (args: ResourceHandlerArgs) => MaybePromise<{
193
199
  contents: Array<{ text: string; uri: string }>
@@ -221,7 +227,7 @@ export type MCPPluginConfig = {
221
227
  collections?: {
222
228
  [Slug in CollectionSlug]?: MCPPluginCollectionConfig<Slug>
223
229
  }
224
- /** Skip MCP registration. The API key collection is still added (so DB / types stay stable). */
230
+ /** Skip MCP endpoint registration. */
225
231
  disabled?: boolean
226
232
  globals?: {
227
233
  [Slug in GlobalSlug]?: MCPPluginGlobalConfig
@@ -230,25 +236,21 @@ export type MCPPluginConfig = {
230
236
  serverOptions?: MCPServerOptions
231
237
  verboseLogs?: boolean
232
238
  }
233
- overrideApiKeyCollection?: (collection: CollectionConfig) => CollectionConfig
234
- /** Replace the default API-key auth with a custom resolver. */
235
- overrideAuth?: (args: {
236
- getAPIKeyDoc: (overrideApiKey?: string) => Promise<MCPAPIKeysDoc>
237
- getAuthorizedMCP: (args: { apiKeyDoc: MCPAPIKeysDoc }) => AuthorizedMCP
238
- pluginConfig: SanitizedMCPPluginConfig
239
- req: PayloadRequest
240
- }) => MaybePromise<AuthorizedMCP>
239
+ /** Replace the default MCP authorization resolver. */
240
+ overrideGetAuthorizedMCP?: (
241
+ args: {
242
+ pluginConfig: SanitizedMCPPluginConfig
243
+ } & GetAuthorizedMCPArgs,
244
+ ) => MaybePromise<AuthorizedMCP>
241
245
  prompts?: Record<string, Prompt>
242
246
  resources?: Record<string, Resource>
243
247
  /** Cross-cutting tools (not scoped to any collection or global). */
244
248
  tools?: MCPTopLevelToolsMap
245
- userCollection?: CollectionSlug
246
249
  }
247
250
 
248
251
  export type SanitizedMCPPluginConfig = {
249
252
  items: MCPItem[]
250
- userCollection: CollectionSlug
251
- } & Pick<MCPPluginConfig, 'disabled' | 'mcp' | 'overrideApiKeyCollection' | 'overrideAuth'>
253
+ } & Pick<MCPPluginConfig, 'disabled' | 'mcp' | 'overrideGetAuthorizedMCP'>
252
254
 
253
255
  export type MCPServerOptions = {
254
256
  options?: ConstructorParameters<typeof McpServer>[1]
@@ -256,52 +258,12 @@ export type MCPServerOptions = {
256
258
  }
257
259
 
258
260
  /**
259
- * Nested access tree as stored in the collection.
260
- * A `false` leaf disables that tool; missing keys defer to
261
- * defaults (built-in CRUD is on, opt-in tools are off).
262
- */
263
- export type MCPAPIKeysDocAccessTree = {
264
- collections?: {
265
- [CollectionSlug: CollectionSlug]: {
266
- [ToolKey: string]: boolean
267
- }
268
- }
269
- globals?: {
270
- [GlobalSlug: GlobalSlug]: {
271
- [ToolKey: string]: boolean
272
- }
273
- }
274
- prompts?: {
275
- [PromptKey: string]: boolean
276
- }
277
- resources?: {
278
- [ResourceKey: string]: boolean
279
- }
280
- tools?: {
281
- [ToolKey: string]: boolean
282
- }
283
- }
284
-
285
- /**
286
- * Stored on `payload-mcp-api-keys` docs
287
- */
288
- export type MCPAPIKeysDoc = {
289
- access: MCPAPIKeysDocAccessTree
290
- apiKey?: string
291
- apiKeyIndex?: string
292
- id: DefaultDocumentIDType
293
- lastUsed?: string
294
- overrideAccess?: boolean
295
- user: null | TypedUser
296
- }
297
-
298
- /**
299
- * One MCP primitive plus the metadata needed for access checks, admin UI, and
261
+ * One MCP primitive plus the metadata needed for config-driven filtering and
300
262
  * registration.
301
263
  *
302
- * - `configKey`: the config/API-key identifier, e.g. `find` or `echo`.
264
+ * - `configKey`: the config identifier, e.g. `find` or `echo`.
303
265
  * - `mcpName`: the MCP wire name, e.g. `findDocuments` or `echo`.
304
- * - `label`: human-readable admin checkbox text.
266
+ * - `label`: human-readable display text.
305
267
  */
306
268
  export type MCPItemBase = {
307
269
  configKey: string
@@ -338,10 +300,10 @@ export type MCPItem =
338
300
  | GlobalMCPItem
339
301
 
340
302
  /**
341
- * The caller's identity + the MCP items they can use for this request. Returned
342
- * by `getAuthorizedMCP`; denied items are simply absent from `items`. Handlers
343
- * receive this via `args.authorizedMCP` so they can spread
344
- * `localAPIDefaults(authorizedMCP)` into every local API call.
303
+ * The caller's identity + the MCP items authorized for this request. Disabled
304
+ * items and items blocked by access callbacks or Payload operation access are
305
+ * absent from `items`. Tool handlers receive this via `args.authorizedMCP` so
306
+ * they can spread `localAPIDefaults(authorizedMCP)` into every local API call.
345
307
  */
346
308
  export type AuthorizedMCP = {
347
309
  items: MCPItem[]
@@ -5,7 +5,7 @@ import type { SanitizedMCPPluginConfig } from '../types.js'
5
5
  /**
6
6
  * Returns the sanitized plugin config — the form produced by
7
7
  * `sanitizeMCPConfig` and stashed back on the plugin's `options` during init.
8
- * Callers downstream of plugin init can rely on `items`, `userCollection`, etc.
8
+ * Callers downstream of plugin init can rely on `items` and other defaults
9
9
  * being fully resolved.
10
10
  */
11
11
  export const getPluginConfig: (args: { config: SanitizedConfig }) => SanitizedMCPPluginConfig = ({
@@ -9,11 +9,6 @@ import {
9
9
 
10
10
  import type { JsonSchemaType } from '../../types.js'
11
11
 
12
- import {
13
- getCollectionVirtualFieldNames,
14
- getGlobalVirtualFieldNames,
15
- } from '../getVirtualFieldNames.js'
16
- import { removeVirtualFieldsFromSchema } from './removeVirtualFieldsFromSchema.js'
17
12
  import { sanitizeEntitySchema } from './sanitizeEntitySchema.js'
18
13
 
19
14
  export const getCollectionInputSchema = ({
@@ -29,11 +24,7 @@ export const getCollectionInputSchema = ({
29
24
  return null
30
25
  }
31
26
 
32
- return buildEntityInputSchema({
33
- entity: collection,
34
- req,
35
- virtualFieldNames: getCollectionVirtualFieldNames(req.payload.config, collectionSlug),
36
- })
27
+ return buildEntityInputSchema({ entity: collection, req })
37
28
  }
38
29
 
39
30
  export const getGlobalInputSchema = ({
@@ -49,30 +40,23 @@ export const getGlobalInputSchema = ({
49
40
  return null
50
41
  }
51
42
 
52
- return buildEntityInputSchema({
53
- entity: global,
54
- req,
55
- virtualFieldNames: getGlobalVirtualFieldNames(req.payload.config, globalSlug),
56
- })
43
+ return buildEntityInputSchema({ entity: global, req })
57
44
  }
58
45
 
59
46
  const buildEntityInputSchema = ({
60
47
  entity,
61
48
  req,
62
- virtualFieldNames,
63
49
  }: {
64
50
  entity: SanitizedCollectionConfig | SanitizedGlobalConfig
65
51
  req: PayloadRequest
66
- virtualFieldNames: string[]
67
52
  }): JsonSchemaType =>
53
+ // The `input` variant is already the write shape; sanitizeEntitySchema only adds MCP-specific passes.
68
54
  sanitizeEntitySchema(
69
- removeVirtualFieldsFromSchema(
70
- entityToStandaloneJSONSchema({
71
- config: req.payload.config,
72
- defaultIDType: req.payload.db.defaultIDType,
73
- entity,
74
- i18n: req.i18n,
75
- }) as unknown as JsonSchemaType,
76
- virtualFieldNames,
77
- ),
55
+ entityToStandaloneJSONSchema({
56
+ config: req.payload.config,
57
+ defaultIDType: req.payload.db.defaultIDType,
58
+ entity,
59
+ i18n: req.i18n,
60
+ variant: 'input',
61
+ }) as unknown as JsonSchemaType,
78
62
  )
@@ -5,10 +5,11 @@ import type { JsonSchemaType } from '../../types.js'
5
5
  import { sanitizeEntitySchema } from './sanitizeEntitySchema.js'
6
6
 
7
7
  describe('sanitizeEntitySchema', () => {
8
- it('keeps a Lexical node union strict (oneOf) while simplifying relationship values to IDs', () => {
9
- // Shaped like the schema the MCP server prepares for a collection with a Lexical richText field:
10
- // a `$defs` node union (a `oneOf` of node shapes) where a relationship node's `value` is either
11
- // an ID or a `$ref` to the populated related collection.
8
+ it('renames the Lexical node-union definition to a short name and keeps it a strict oneOf', () => {
9
+ // Shaped like the schema the MCP server prepares for a collection with a Lexical richText field
10
+ // (Payload's `input` variant): a `$defs` node union (a `oneOf` of node shapes). The input variant
11
+ // already types the relationship node's `value` as a bare ID - there is no populated-doc `$ref` to
12
+ // reduce here (the variant did that upstream), so sanitize leaves the value untouched.
12
13
  const standalone: JsonSchemaType = {
13
14
  type: 'object',
14
15
  $defs: {
@@ -25,17 +26,12 @@ describe('sanitizeEntitySchema', () => {
25
26
  additionalProperties: false,
26
27
  properties: {
27
28
  type: { const: 'relationship' },
28
- value: { oneOf: [{ type: 'string' }, { $ref: '#/$defs/posts' }] },
29
+ value: { type: 'string', description: 'The related document ID.' },
29
30
  },
30
31
  required: ['type'],
31
32
  },
32
33
  ],
33
34
  },
34
- posts: {
35
- type: 'object',
36
- additionalProperties: false,
37
- properties: { id: { type: 'string' }, title: { type: 'string' } },
38
- },
39
35
  },
40
36
  properties: {
41
37
  id: { type: 'string' },
@@ -57,7 +53,7 @@ describe('sanitizeEntitySchema', () => {
57
53
  type: 'object',
58
54
  $defs: {
59
55
  // The node union is renamed to a short, readable `node`, and stays a strict discriminated
60
- // `oneOf` - not loosened to `anyOf`...
56
+ // `oneOf` - not loosened to `anyOf`.
61
57
  node: {
62
58
  oneOf: [
63
59
  {
@@ -71,21 +67,18 @@ describe('sanitizeEntitySchema', () => {
71
67
  additionalProperties: false,
72
68
  properties: {
73
69
  type: { const: 'relationship' },
74
- // ...while the relationship `value` is simplified to a bare ID (the populated-doc `$ref` is dropped).
75
- value: { type: 'string', description: 'The ID of the related "posts" document.' },
70
+ // The value is already ID-only from the input variant - left as-is.
71
+ value: { type: 'string', description: 'The related document ID.' },
76
72
  },
77
73
  required: ['type'],
78
74
  },
79
75
  ],
80
76
  },
81
- posts: {
82
- type: 'object',
83
- additionalProperties: false,
84
- properties: { id: { type: 'string' }, title: { type: 'string' } },
85
- },
86
77
  },
87
78
  properties: {
88
- // `id` is dropped - it's a Payload-managed field MCP clients never set.
79
+ // Managed fields (createdAt/updatedAt/_status) are excluded upstream by the `input` variant;
80
+ // `id` stays because it's a valid optional input (a client may supply a custom ID).
81
+ id: { type: 'string' },
89
82
  content: {
90
83
  type: 'object',
91
84
  properties: {
@@ -1,30 +1,22 @@
1
1
  import type { JsonSchemaType } from '../../types.js'
2
2
 
3
3
  /**
4
- * Turns the JSON Schema that Payload generates for a collection or global into the input schema for
5
- * an MCP create/update tool. In short, it:
6
- *
7
- * - drops fields a client can't set (`id`, `createdAt`, the draft `_status`, …),
8
- * - rewrites Payload-specific field shapes (points, relationships) into plain JSON the model can fill,
9
- * - and shrinks the result so it's cheaper for the model to read,
10
- *
11
- * while keeping every node valid JSON Schema draft 2020-12. Each step below is tagged with why it runs -
12
- * **Correctness** (valid input the API accepts), **Size** (equivalence-preserving shrink), or **LLM
13
- * ergonomics** (easier for the model to read/fill) - and carries a before/after example on its definition.
4
+ * Refines Payload's `input`-variant JSON Schema into an MCP create/update tool's input schema. The
5
+ * variant already covers correctness (ID-only relationships, no managed/virtual/join fields); the
6
+ * passes here are MCP-specific - reshaping fields for the model and shrinking the result - and keep
7
+ * every node valid JSON Schema draft 2020-12. Each is tagged **Correctness**, **Size**, or **LLM
8
+ * ergonomics**, with a before/after example on its definition.
14
9
  */
15
10
  export const sanitizeEntitySchema = (schema: JsonSchemaType): JsonSchemaType => {
16
11
  // Work on a copy — the caller reuses the original schema elsewhere (e.g. when listing tools).
17
12
  let result = structuredClone(schema)
18
13
 
19
- // Correctness — drop the fields a client can't set (id, createdAt, updatedAt, draft _status) + collapse nullable types.
20
- result = removeManagedFields(result)
14
+ // LLM ergonomics — drop the redundant `'null'` from optional arrays/objects (`['array','null']` `'array'`).
15
+ result = collapseOptionalContainerTypes(result)
21
16
 
22
17
  // LLM ergonomics — rewrite point fields from a `[number, number]` tuple into a `{ longitude, latitude }` object.
23
18
  result = pointFieldsToObjects(result)
24
19
 
25
- // Correctness — a relationship value can be an ID or a populated doc; on input only the ID is valid, so keep that.
26
- result = relationshipsToIds(result)
27
-
28
20
  // Size — strip inert type-gen leftovers that only bloat the schema (`tsType`, block-collision notes).
29
21
  result = removeTypeGenArtifacts(result)
30
22
 
@@ -58,26 +50,20 @@ const mapNodes = (node: unknown, visit: (node: JsonSchemaType) => JsonSchemaType
58
50
  for (const [key, value] of Object.entries(node)) {
59
51
  out[key] = mapNodes(value, visit)
60
52
  }
61
- return visit(out as JsonSchemaType)
53
+ return visit(out)
62
54
  }
63
55
 
64
- // Payload sets these on every document, so an MCP client never provides them when creating/updating.
65
- const PAYLOAD_MANAGED_FIELDS = new Set(['_status', 'createdAt', 'id', 'updatedAt'])
66
-
67
56
  /**
68
- * **Correctness.** Removes the fields a client can't set on create/update - `id`, `createdAt`, `updatedAt`, and the draft
69
- * `_status` - from every field object's `properties` and `required` (recursing into nested objects and
70
- * array items). Along the way it also collapses optional array/object types via {@link collapseNullableType}.
57
+ * **LLM ergonomics.** Collapses optional array/object types (`['array', 'null']` `'array'`) via
58
+ * {@link collapseNullableType}, recursing through `properties` and array items. The `required` list
59
+ * already conveys optionality, so the `'null'` is redundant noise for the model.
71
60
  *
72
61
  * @example
73
- * { properties: { id: { type: 'string' }, tags: { type: ['array', 'null'], items: {} } }, required: ['id', 'tags'] }
74
- * → { properties: { tags: { type: 'array', items: {} } }, required: ['tags'] }
62
+ * { properties: { tags: { type: ['array', 'null'], items: {} } }, required: [] }
63
+ * → { properties: { tags: { type: 'array', items: {} } }, required: [] }
75
64
  */
76
- const removeManagedFields = (schema: JsonSchemaType): JsonSchemaType => {
65
+ const collapseOptionalContainerTypes = (schema: JsonSchemaType): JsonSchemaType => {
77
66
  if (schema.properties && typeof schema.properties === 'object') {
78
- for (const field of PAYLOAD_MANAGED_FIELDS) {
79
- delete schema.properties[field]
80
- }
81
67
  for (const key of Object.keys(schema.properties)) {
82
68
  const prop = schema.properties[key] as JsonSchemaType
83
69
  if (!prop || typeof prop !== 'object') {
@@ -86,21 +72,14 @@ const removeManagedFields = (schema: JsonSchemaType): JsonSchemaType => {
86
72
  const isRequired = Array.isArray(schema.required) && schema.required.includes(key)
87
73
  collapseNullableType(prop, isRequired)
88
74
  if (prop.properties) {
89
- removeManagedFields(prop)
75
+ collapseOptionalContainerTypes(prop)
90
76
  }
91
77
  if (prop.items && typeof prop.items === 'object' && !Array.isArray(prop.items)) {
92
- removeManagedFields(prop.items)
78
+ collapseOptionalContainerTypes(prop.items)
93
79
  }
94
80
  }
95
81
  }
96
82
 
97
- if (Array.isArray(schema.required)) {
98
- schema.required = schema.required.filter((name) => !PAYLOAD_MANAGED_FIELDS.has(name))
99
- if (schema.required.length === 0) {
100
- delete schema.required
101
- }
102
- }
103
-
104
83
  return schema
105
84
  }
106
85
 
@@ -193,82 +172,6 @@ const pointFieldsToObjects = (schema: JsonSchemaType): JsonSchemaType => {
193
172
  return transformed
194
173
  }
195
174
 
196
- /**
197
- * **Correctness.** Reduces relationship/upload fields to the IDs a client actually sends. Payload types the value as
198
- * "an ID or the full related document" - but the populated-document form only appears in read responses;
199
- * on create/update you always reference a relationship by its ID. So we drop that `$ref` option, leaving
200
- * the bare ID. A single remaining target collapses inline (with a description naming the target
201
- * collection); several targets become an `anyOf` of IDs.
202
- *
203
- * @example
204
- * { oneOf: [{ type: 'string' }, { $ref: '#/$defs/posts' }] }
205
- * → { type: 'string', description: 'The ID of the related "posts" document.' }
206
- */
207
- const relationshipsToIds = (schema: JsonSchemaType): JsonSchemaType => {
208
- if (!schema || typeof schema !== 'object') {
209
- return schema
210
- }
211
-
212
- const processed = { ...schema }
213
-
214
- if (Array.isArray(processed.oneOf)) {
215
- const isRelatedDocRef = (option: unknown): option is { $ref: string } =>
216
- !!option && typeof option === 'object' && '$ref' in option
217
-
218
- if (processed.oneOf.some(isRelatedDocRef)) {
219
- // A relationship value is "an ID, or the populated related document". Keep the ID option(s) and
220
- // drop the `$ref`s to the related collections, since a client only ever sends the ID.
221
- const idOptions = processed.oneOf
222
- .filter((option) => !isRelatedDocRef(option))
223
- .map((option) => (typeof option === 'object' ? relationshipsToIds(option) : option))
224
- const targetCollections = processed.oneOf
225
- .filter(isRelatedDocRef)
226
- .map((option) => option.$ref.replace('#/$defs/', ''))
227
-
228
- if (idOptions.length === 1) {
229
- delete processed.oneOf
230
- Object.assign(processed, idOptions[0])
231
- if (targetCollections.length > 0 && !processed.description) {
232
- processed.description = `The ID of the related "${targetCollections.join('" or "')}" document.`
233
- }
234
- } else if (idOptions.length > 1) {
235
- delete processed.oneOf
236
- processed.anyOf = idOptions
237
- }
238
- } else {
239
- processed.oneOf = processed.oneOf.map((option) =>
240
- typeof option === 'object' ? relationshipsToIds(option) : option,
241
- )
242
- }
243
- }
244
-
245
- if (processed.properties && typeof processed.properties === 'object') {
246
- processed.properties = Object.fromEntries(
247
- Object.entries(processed.properties).map(([key, value]) => [
248
- key,
249
- typeof value === 'object' ? relationshipsToIds(value) : value,
250
- ]),
251
- )
252
- }
253
-
254
- if (processed.items && typeof processed.items === 'object' && !Array.isArray(processed.items)) {
255
- processed.items = relationshipsToIds(processed.items)
256
- }
257
-
258
- // Lexical node unions and blocks live under `$defs` and have their own relationship fields, so walk
259
- // those too — otherwise their `$ref`s would dangle once we don't bundle the related collections.
260
- if (processed.$defs && typeof processed.$defs === 'object') {
261
- processed.$defs = Object.fromEntries(
262
- Object.entries(processed.$defs).map(([key, value]) => [
263
- key,
264
- typeof value === 'object' ? relationshipsToIds(value) : value,
265
- ]),
266
- )
267
- }
268
-
269
- return processed
270
- }
271
-
272
175
  /**
273
176
  * **Size.** Strips type-generation leftovers that bloat the schema without helping the model: the `tsType`
274
177
  * hint (a `json-schema-to-typescript` extension; JSON Schema validators just ignore it, they don't reject it)
@@ -448,7 +351,7 @@ const deduplicateIntoDefinitions = (schema: JsonSchemaType): JsonSchemaType => {
448
351
  if (!name) {
449
352
  name = `shared_${nameByKey.size}`
450
353
  nameByKey.set(key, name)
451
- sharedEntries[name] = node as JsonSchemaType
354
+ sharedEntries[name] = node
452
355
  }
453
356
  return { $ref: `#/$defs/${name}` }
454
357
  }
@@ -1,12 +0,0 @@
1
- import type { JSONField } from 'payload';
2
- import type { SanitizedMCPPluginConfig } from '../types.js';
3
- /**
4
- * Returns the API key collection's `access` field — a JSON field whose value
5
- * is the `MCPAPIKeysDocAccessTree` the endpoint consults. The actual UI is
6
- * a custom client component (`AccessField`) which renders a permissions
7
- * matrix; the field's stored shape is just the runtime access tree.
8
- */
9
- export declare const getAccessField: ({ pluginConfig, }: {
10
- pluginConfig: SanitizedMCPPluginConfig;
11
- }) => JSONField;
12
- //# sourceMappingURL=getAccessField.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"getAccessField.d.ts","sourceRoot":"","sources":["../../src/collection/getAccessField.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAExC,OAAO,KAAK,EAAkC,wBAAwB,EAAE,MAAM,aAAa,CAAA;AAQ3F;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GAAI,mBAE5B;IACD,YAAY,EAAE,wBAAwB,CAAA;CACvC,KAAG,SAiBH,CAAA"}