@payloadcms/plugin-mcp 4.0.0-internal.38b7f1d → 4.0.0-internal.4804abd

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 (419) hide show
  1. package/bin.js +39 -0
  2. package/dist/@types/assets.d.js +2 -0
  3. package/dist/@types/assets.d.js.map +1 -0
  4. package/dist/defaultAccess.d.ts +3 -0
  5. package/dist/defaultAccess.d.ts.map +1 -0
  6. package/dist/defaultAccess.js +3 -0
  7. package/dist/defaultAccess.js.map +1 -0
  8. package/dist/defineTool.d.ts +26 -0
  9. package/dist/defineTool.d.ts.map +1 -0
  10. package/dist/defineTool.js +37 -0
  11. package/dist/defineTool.js.map +1 -0
  12. package/dist/endpoint/access.d.ts +22 -0
  13. package/dist/endpoint/access.d.ts.map +1 -0
  14. package/dist/endpoint/access.js +100 -0
  15. package/dist/endpoint/access.js.map +1 -0
  16. package/dist/endpoint/index.d.ts +3 -0
  17. package/dist/endpoint/index.d.ts.map +1 -0
  18. package/dist/endpoint/index.js +47 -0
  19. package/dist/endpoint/index.js.map +1 -0
  20. package/dist/exports/client.d.ts +2 -0
  21. package/dist/exports/client.d.ts.map +1 -0
  22. package/dist/exports/client.js +4 -0
  23. package/dist/exports/client.js.map +1 -0
  24. package/dist/exports/internal.d.ts +2 -0
  25. package/dist/exports/internal.d.ts.map +1 -0
  26. package/dist/exports/internal.js +3 -0
  27. package/dist/exports/internal.js.map +1 -0
  28. package/dist/index.d.ts +4 -7
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +39 -67
  31. package/dist/index.js.map +1 -1
  32. package/dist/mcp/buildMcpServer.d.ts +19 -0
  33. package/dist/mcp/buildMcpServer.d.ts.map +1 -0
  34. package/dist/mcp/buildMcpServer.js +201 -0
  35. package/dist/mcp/buildMcpServer.js.map +1 -0
  36. package/dist/mcp/builtin/collections/authTools.d.ts +7 -0
  37. package/dist/mcp/builtin/collections/authTools.d.ts.map +1 -0
  38. package/dist/mcp/builtin/collections/authTools.js +288 -0
  39. package/dist/mcp/builtin/collections/authTools.js.map +1 -0
  40. package/dist/mcp/builtin/collections/countTool.d.ts +2 -0
  41. package/dist/mcp/builtin/collections/countTool.d.ts.map +1 -0
  42. package/dist/mcp/builtin/collections/countTool.js +69 -0
  43. package/dist/mcp/builtin/collections/countTool.js.map +1 -0
  44. package/dist/mcp/builtin/collections/countVersionsTool.d.ts +2 -0
  45. package/dist/mcp/builtin/collections/countVersionsTool.d.ts.map +1 -0
  46. package/dist/mcp/builtin/collections/countVersionsTool.js +65 -0
  47. package/dist/mcp/builtin/collections/countVersionsTool.js.map +1 -0
  48. package/dist/mcp/builtin/collections/createTool.d.ts +2 -0
  49. package/dist/mcp/builtin/collections/createTool.d.ts.map +1 -0
  50. package/dist/mcp/builtin/collections/createTool.js +87 -0
  51. package/dist/mcp/builtin/collections/createTool.js.map +1 -0
  52. package/dist/mcp/builtin/collections/deleteTool.d.ts +2 -0
  53. package/dist/mcp/builtin/collections/deleteTool.d.ts.map +1 -0
  54. package/dist/mcp/builtin/collections/deleteTool.js +111 -0
  55. package/dist/mcp/builtin/collections/deleteTool.js.map +1 -0
  56. package/dist/mcp/builtin/collections/duplicateTool.d.ts +2 -0
  57. package/dist/mcp/builtin/collections/duplicateTool.d.ts.map +1 -0
  58. package/dist/mcp/builtin/collections/duplicateTool.js +97 -0
  59. package/dist/mcp/builtin/collections/duplicateTool.js.map +1 -0
  60. package/dist/mcp/builtin/collections/findDistinctTool.d.ts +2 -0
  61. package/dist/mcp/builtin/collections/findDistinctTool.d.ts.map +1 -0
  62. package/dist/mcp/builtin/collections/findDistinctTool.js +93 -0
  63. package/dist/mcp/builtin/collections/findDistinctTool.js.map +1 -0
  64. package/dist/mcp/builtin/collections/findTool.d.ts +2 -0
  65. package/dist/mcp/builtin/collections/findTool.d.ts.map +1 -0
  66. package/dist/mcp/builtin/collections/findTool.js +165 -0
  67. package/dist/mcp/builtin/collections/findTool.js.map +1 -0
  68. package/dist/mcp/builtin/collections/findVersionByIDTool.d.ts +2 -0
  69. package/dist/mcp/builtin/collections/findVersionByIDTool.d.ts.map +1 -0
  70. package/dist/mcp/builtin/collections/findVersionByIDTool.js +84 -0
  71. package/dist/mcp/builtin/collections/findVersionByIDTool.js.map +1 -0
  72. package/dist/mcp/builtin/collections/findVersionsTool.d.ts +2 -0
  73. package/dist/mcp/builtin/collections/findVersionsTool.d.ts.map +1 -0
  74. package/dist/mcp/builtin/collections/findVersionsTool.js +99 -0
  75. package/dist/mcp/builtin/collections/findVersionsTool.js.map +1 -0
  76. package/dist/mcp/builtin/collections/formatCollectionError.d.ts +9 -0
  77. package/dist/mcp/builtin/collections/formatCollectionError.d.ts.map +1 -0
  78. package/dist/mcp/builtin/collections/formatCollectionError.js +60 -0
  79. package/dist/mcp/builtin/collections/formatCollectionError.js.map +1 -0
  80. package/dist/mcp/builtin/collections/getCollectionSchemaTool.d.ts +2 -0
  81. package/dist/mcp/builtin/collections/getCollectionSchemaTool.d.ts.map +1 -0
  82. package/dist/mcp/builtin/collections/getCollectionSchemaTool.js +47 -0
  83. package/dist/mcp/builtin/collections/getCollectionSchemaTool.js.map +1 -0
  84. package/dist/mcp/builtin/collections/restoreVersionTool.d.ts +2 -0
  85. package/dist/mcp/builtin/collections/restoreVersionTool.d.ts.map +1 -0
  86. package/dist/mcp/builtin/collections/restoreVersionTool.js +82 -0
  87. package/dist/mcp/builtin/collections/restoreVersionTool.js.map +1 -0
  88. package/dist/mcp/builtin/collections/updateTool.d.ts +2 -0
  89. package/dist/mcp/builtin/collections/updateTool.d.ts.map +1 -0
  90. package/dist/mcp/builtin/collections/updateTool.js +192 -0
  91. package/dist/mcp/builtin/collections/updateTool.js.map +1 -0
  92. package/dist/mcp/builtin/getConfigInfoTool.d.ts +2 -0
  93. package/dist/mcp/builtin/getConfigInfoTool.d.ts.map +1 -0
  94. package/dist/mcp/builtin/getConfigInfoTool.js +71 -0
  95. package/dist/mcp/builtin/getConfigInfoTool.js.map +1 -0
  96. package/dist/mcp/builtin/globals/countVersionsTool.d.ts +2 -0
  97. package/dist/mcp/builtin/globals/countVersionsTool.d.ts.map +1 -0
  98. package/dist/mcp/builtin/globals/countVersionsTool.js +65 -0
  99. package/dist/mcp/builtin/globals/countVersionsTool.js.map +1 -0
  100. package/dist/mcp/builtin/globals/findTool.d.ts +2 -0
  101. package/dist/mcp/builtin/globals/findTool.d.ts.map +1 -0
  102. package/dist/mcp/builtin/globals/findTool.js +73 -0
  103. package/dist/mcp/builtin/globals/findTool.js.map +1 -0
  104. package/dist/mcp/builtin/globals/findVersionByIDTool.d.ts +2 -0
  105. package/dist/mcp/builtin/globals/findVersionByIDTool.d.ts.map +1 -0
  106. package/dist/mcp/builtin/globals/findVersionByIDTool.js +80 -0
  107. package/dist/mcp/builtin/globals/findVersionByIDTool.js.map +1 -0
  108. package/dist/mcp/builtin/globals/findVersionsTool.d.ts +2 -0
  109. package/dist/mcp/builtin/globals/findVersionsTool.d.ts.map +1 -0
  110. package/dist/mcp/builtin/globals/findVersionsTool.js +95 -0
  111. package/dist/mcp/builtin/globals/findVersionsTool.js.map +1 -0
  112. package/dist/mcp/builtin/globals/getGlobalSchemaTool.d.ts +2 -0
  113. package/dist/mcp/builtin/globals/getGlobalSchemaTool.d.ts.map +1 -0
  114. package/dist/mcp/builtin/globals/getGlobalSchemaTool.js +47 -0
  115. package/dist/mcp/builtin/globals/getGlobalSchemaTool.js.map +1 -0
  116. package/dist/mcp/builtin/globals/restoreVersionTool.d.ts +2 -0
  117. package/dist/mcp/builtin/globals/restoreVersionTool.d.ts.map +1 -0
  118. package/dist/mcp/builtin/globals/restoreVersionTool.js +78 -0
  119. package/dist/mcp/builtin/globals/restoreVersionTool.js.map +1 -0
  120. package/dist/mcp/builtin/globals/updateTool.d.ts +2 -0
  121. package/dist/mcp/builtin/globals/updateTool.d.ts.map +1 -0
  122. package/dist/mcp/builtin/globals/updateTool.js +87 -0
  123. package/dist/mcp/builtin/globals/updateTool.js.map +1 -0
  124. package/dist/mcp/builtin/validateEntityData.d.ts +14 -0
  125. package/dist/mcp/builtin/validateEntityData.d.ts.map +1 -0
  126. package/dist/mcp/builtin/validateEntityData.js +82 -0
  127. package/dist/mcp/builtin/validateEntityData.js.map +1 -0
  128. package/dist/mcp/builtinTools.d.ts +162 -0
  129. package/dist/mcp/builtinTools.d.ts.map +1 -0
  130. package/dist/mcp/builtinTools.js +163 -0
  131. package/dist/mcp/builtinTools.js.map +1 -0
  132. package/dist/mcp/sanitizeMCPConfig.d.ts +16 -0
  133. package/dist/mcp/sanitizeMCPConfig.d.ts.map +1 -0
  134. package/dist/mcp/sanitizeMCPConfig.js +229 -0
  135. package/dist/mcp/sanitizeMCPConfig.js.map +1 -0
  136. package/dist/stdio.d.ts +9 -0
  137. package/dist/stdio.d.ts.map +1 -0
  138. package/dist/stdio.js +108 -0
  139. package/dist/stdio.js.map +1 -0
  140. package/dist/types.d.ts +222 -461
  141. package/dist/types.d.ts.map +1 -1
  142. package/dist/types.js +6 -1
  143. package/dist/types.js.map +1 -1
  144. package/dist/utils/camelCase.d.ts.map +1 -1
  145. package/dist/utils/getLogger.d.ts +10 -0
  146. package/dist/utils/getLogger.d.ts.map +1 -0
  147. package/dist/utils/getLogger.js +22 -0
  148. package/dist/utils/getLogger.js.map +1 -0
  149. package/dist/utils/getPluginConfig.d.ts +12 -0
  150. package/dist/utils/getPluginConfig.d.ts.map +1 -0
  151. package/dist/utils/getPluginConfig.js +15 -0
  152. package/dist/utils/getPluginConfig.js.map +1 -0
  153. package/dist/utils/localAPIDefaults.d.ts +20 -0
  154. package/dist/utils/localAPIDefaults.d.ts.map +1 -0
  155. package/dist/utils/localAPIDefaults.js +19 -0
  156. package/dist/utils/localAPIDefaults.js.map +1 -0
  157. package/dist/utils/resolveProjectRoot.d.ts +7 -0
  158. package/dist/utils/resolveProjectRoot.d.ts.map +1 -0
  159. package/dist/utils/resolveProjectRoot.js +15 -0
  160. package/dist/utils/resolveProjectRoot.js.map +1 -0
  161. package/dist/utils/schemaConversion/getEntityInputSchema.d.ts +11 -0
  162. package/dist/utils/schemaConversion/getEntityInputSchema.d.ts.map +1 -0
  163. package/dist/utils/schemaConversion/getEntityInputSchema.js +32 -0
  164. package/dist/utils/schemaConversion/getEntityInputSchema.js.map +1 -0
  165. package/dist/utils/schemaConversion/sanitizeEntitySchema.d.ts +10 -0
  166. package/dist/utils/schemaConversion/sanitizeEntitySchema.d.ts.map +1 -0
  167. package/dist/utils/schemaConversion/sanitizeEntitySchema.js +384 -0
  168. package/dist/utils/schemaConversion/sanitizeEntitySchema.js.map +1 -0
  169. package/dist/utils/schemaConversion/sanitizeEntitySchema.spec.js +133 -0
  170. package/dist/utils/schemaConversion/sanitizeEntitySchema.spec.js.map +1 -0
  171. package/dist/utils/toStandardSchema.d.ts +5 -0
  172. package/dist/utils/toStandardSchema.d.ts.map +1 -0
  173. package/dist/utils/toStandardSchema.js +4 -0
  174. package/dist/utils/toStandardSchema.js.map +1 -0
  175. package/dist/utils/whereSchema.d.ts +9 -0
  176. package/dist/utils/whereSchema.d.ts.map +1 -0
  177. package/dist/utils/whereSchema.js +13 -0
  178. package/dist/utils/whereSchema.js.map +1 -0
  179. package/package.json +32 -10
  180. package/src/@types/assets.d.ts +3 -0
  181. package/src/defaultAccess.ts +3 -0
  182. package/src/defineTool.ts +44 -0
  183. package/src/endpoint/access.ts +119 -0
  184. package/src/endpoint/index.ts +48 -0
  185. package/src/exports/client.ts +3 -0
  186. package/src/exports/internal.ts +1 -0
  187. package/src/index.ts +29 -87
  188. package/src/mcp/buildMcpServer.ts +264 -0
  189. package/src/mcp/builtin/collections/authTools.ts +269 -0
  190. package/src/mcp/builtin/collections/countTool.ts +74 -0
  191. package/src/mcp/builtin/collections/countVersionsTool.ts +70 -0
  192. package/src/mcp/builtin/collections/createTool.ts +112 -0
  193. package/src/mcp/builtin/collections/deleteTool.ts +126 -0
  194. package/src/mcp/builtin/collections/duplicateTool.ts +135 -0
  195. package/src/mcp/builtin/collections/findDistinctTool.ts +120 -0
  196. package/src/mcp/builtin/collections/findTool.ts +217 -0
  197. package/src/mcp/builtin/collections/findVersionByIDTool.ts +110 -0
  198. package/src/mcp/builtin/collections/findVersionsTool.ts +155 -0
  199. package/src/mcp/builtin/collections/formatCollectionError.ts +84 -0
  200. package/src/mcp/builtin/collections/getCollectionSchemaTool.ts +46 -0
  201. package/src/mcp/builtin/collections/restoreVersionTool.ts +108 -0
  202. package/src/mcp/builtin/collections/updateTool.ts +211 -0
  203. package/src/mcp/builtin/getConfigInfoTool.ts +69 -0
  204. package/src/mcp/builtin/globals/countVersionsTool.ts +69 -0
  205. package/src/mcp/builtin/globals/findTool.ts +105 -0
  206. package/src/mcp/builtin/globals/findVersionByIDTool.ts +104 -0
  207. package/src/mcp/builtin/globals/findVersionsTool.ts +148 -0
  208. package/src/mcp/builtin/globals/getGlobalSchemaTool.ts +41 -0
  209. package/src/mcp/builtin/globals/restoreVersionTool.ts +100 -0
  210. package/src/mcp/builtin/globals/updateTool.ts +115 -0
  211. package/src/mcp/builtin/validateEntityData.ts +132 -0
  212. package/src/mcp/builtinTools.ts +154 -0
  213. package/src/mcp/sanitizeMCPConfig.ts +277 -0
  214. package/src/stdio.ts +113 -0
  215. package/src/types.ts +263 -493
  216. package/src/utils/getLogger.ts +22 -0
  217. package/src/utils/getPluginConfig.ts +24 -0
  218. package/src/utils/localAPIDefaults.ts +22 -0
  219. package/src/utils/resolveProjectRoot.ts +17 -0
  220. package/src/utils/schemaConversion/getEntityInputSchema.ts +62 -0
  221. package/src/utils/schemaConversion/sanitizeEntitySchema.spec.ts +96 -0
  222. package/src/utils/schemaConversion/sanitizeEntitySchema.ts +432 -0
  223. package/src/utils/toStandardSchema.ts +9 -0
  224. package/src/utils/whereSchema.ts +24 -0
  225. package/dist/collections/createApiKeysCollection.d.ts +0 -7
  226. package/dist/collections/createApiKeysCollection.d.ts.map +0 -1
  227. package/dist/collections/createApiKeysCollection.js +0 -317
  228. package/dist/collections/createApiKeysCollection.js.map +0 -1
  229. package/dist/defaults.d.ts +0 -4
  230. package/dist/defaults.d.ts.map +0 -1
  231. package/dist/defaults.js +0 -5
  232. package/dist/defaults.js.map +0 -1
  233. package/dist/endpoints/mcp.d.ts +0 -4
  234. package/dist/endpoints/mcp.d.ts.map +0 -1
  235. package/dist/endpoints/mcp.js +0 -71
  236. package/dist/endpoints/mcp.js.map +0 -1
  237. package/dist/mcp/createRequest.d.ts +0 -3
  238. package/dist/mcp/createRequest.d.ts.map +0 -1
  239. package/dist/mcp/createRequest.js +0 -14
  240. package/dist/mcp/createRequest.js.map +0 -1
  241. package/dist/mcp/getMcpHandler.d.ts +0 -4
  242. package/dist/mcp/getMcpHandler.d.ts.map +0 -1
  243. package/dist/mcp/getMcpHandler.js +0 -231
  244. package/dist/mcp/getMcpHandler.js.map +0 -1
  245. package/dist/mcp/helpers/config.d.ts +0 -22
  246. package/dist/mcp/helpers/config.d.ts.map +0 -1
  247. package/dist/mcp/helpers/config.js +0 -153
  248. package/dist/mcp/helpers/config.js.map +0 -1
  249. package/dist/mcp/helpers/fields.d.ts +0 -19
  250. package/dist/mcp/helpers/fields.d.ts.map +0 -1
  251. package/dist/mcp/helpers/fields.js +0 -102
  252. package/dist/mcp/helpers/fields.js.map +0 -1
  253. package/dist/mcp/helpers/fileValidation.d.ts +0 -67
  254. package/dist/mcp/helpers/fileValidation.d.ts.map +0 -1
  255. package/dist/mcp/helpers/fileValidation.js +0 -267
  256. package/dist/mcp/helpers/fileValidation.js.map +0 -1
  257. package/dist/mcp/registerTool.d.ts +0 -6
  258. package/dist/mcp/registerTool.d.ts.map +0 -1
  259. package/dist/mcp/registerTool.js +0 -18
  260. package/dist/mcp/registerTool.js.map +0 -1
  261. package/dist/mcp/tools/auth/auth.d.ts +0 -4
  262. package/dist/mcp/tools/auth/auth.d.ts.map +0 -1
  263. package/dist/mcp/tools/auth/auth.js +0 -57
  264. package/dist/mcp/tools/auth/auth.js.map +0 -1
  265. package/dist/mcp/tools/auth/forgotPassword.d.ts +0 -4
  266. package/dist/mcp/tools/auth/forgotPassword.d.ts.map +0 -1
  267. package/dist/mcp/tools/auth/forgotPassword.js +0 -48
  268. package/dist/mcp/tools/auth/forgotPassword.js.map +0 -1
  269. package/dist/mcp/tools/auth/login.d.ts +0 -4
  270. package/dist/mcp/tools/auth/login.d.ts.map +0 -1
  271. package/dist/mcp/tools/auth/login.js +0 -51
  272. package/dist/mcp/tools/auth/login.js.map +0 -1
  273. package/dist/mcp/tools/auth/resetPassword.d.ts +0 -4
  274. package/dist/mcp/tools/auth/resetPassword.d.ts.map +0 -1
  275. package/dist/mcp/tools/auth/resetPassword.js +0 -49
  276. package/dist/mcp/tools/auth/resetPassword.js.map +0 -1
  277. package/dist/mcp/tools/auth/unlock.d.ts +0 -4
  278. package/dist/mcp/tools/auth/unlock.d.ts.map +0 -1
  279. package/dist/mcp/tools/auth/unlock.js +0 -48
  280. package/dist/mcp/tools/auth/unlock.js.map +0 -1
  281. package/dist/mcp/tools/auth/verify.d.ts +0 -4
  282. package/dist/mcp/tools/auth/verify.d.ts.map +0 -1
  283. package/dist/mcp/tools/auth/verify.js +0 -45
  284. package/dist/mcp/tools/auth/verify.js.map +0 -1
  285. package/dist/mcp/tools/collection/create.d.ts +0 -10
  286. package/dist/mcp/tools/collection/create.d.ts.map +0 -1
  287. package/dist/mcp/tools/collection/create.js +0 -139
  288. package/dist/mcp/tools/collection/create.js.map +0 -1
  289. package/dist/mcp/tools/collection/delete.d.ts +0 -10
  290. package/dist/mcp/tools/collection/delete.d.ts.map +0 -1
  291. package/dist/mcp/tools/collection/delete.js +0 -154
  292. package/dist/mcp/tools/collection/delete.js.map +0 -1
  293. package/dist/mcp/tools/collection/find.d.ts +0 -10
  294. package/dist/mcp/tools/collection/find.d.ts.map +0 -1
  295. package/dist/mcp/tools/collection/find.js +0 -165
  296. package/dist/mcp/tools/collection/find.js.map +0 -1
  297. package/dist/mcp/tools/collection/update.d.ts +0 -10
  298. package/dist/mcp/tools/collection/update.d.ts.map +0 -1
  299. package/dist/mcp/tools/collection/update.js +0 -209
  300. package/dist/mcp/tools/collection/update.js.map +0 -1
  301. package/dist/mcp/tools/config/find.d.ts +0 -10
  302. package/dist/mcp/tools/config/find.d.ts.map +0 -1
  303. package/dist/mcp/tools/config/find.js +0 -97
  304. package/dist/mcp/tools/config/find.js.map +0 -1
  305. package/dist/mcp/tools/config/update.d.ts +0 -10
  306. package/dist/mcp/tools/config/update.d.ts.map +0 -1
  307. package/dist/mcp/tools/config/update.js +0 -215
  308. package/dist/mcp/tools/config/update.js.map +0 -1
  309. package/dist/mcp/tools/global/find.d.ts +0 -5
  310. package/dist/mcp/tools/global/find.d.ts.map +0 -1
  311. package/dist/mcp/tools/global/find.js +0 -82
  312. package/dist/mcp/tools/global/find.js.map +0 -1
  313. package/dist/mcp/tools/global/update.d.ts +0 -6
  314. package/dist/mcp/tools/global/update.d.ts.map +0 -1
  315. package/dist/mcp/tools/global/update.js +0 -124
  316. package/dist/mcp/tools/global/update.js.map +0 -1
  317. package/dist/mcp/tools/job/create.d.ts +0 -10
  318. package/dist/mcp/tools/job/create.d.ts.map +0 -1
  319. package/dist/mcp/tools/job/create.js +0 -293
  320. package/dist/mcp/tools/job/create.js.map +0 -1
  321. package/dist/mcp/tools/job/run.d.ts +0 -10
  322. package/dist/mcp/tools/job/run.d.ts.map +0 -1
  323. package/dist/mcp/tools/job/run.js +0 -129
  324. package/dist/mcp/tools/job/run.js.map +0 -1
  325. package/dist/mcp/tools/job/update.d.ts +0 -11
  326. package/dist/mcp/tools/job/update.d.ts.map +0 -1
  327. package/dist/mcp/tools/job/update.js +0 -186
  328. package/dist/mcp/tools/job/update.js.map +0 -1
  329. package/dist/mcp/tools/resource/create.d.ts +0 -6
  330. package/dist/mcp/tools/resource/create.d.ts.map +0 -1
  331. package/dist/mcp/tools/resource/create.js +0 -124
  332. package/dist/mcp/tools/resource/create.js.map +0 -1
  333. package/dist/mcp/tools/resource/delete.d.ts +0 -5
  334. package/dist/mcp/tools/resource/delete.d.ts.map +0 -1
  335. package/dist/mcp/tools/resource/delete.js +0 -151
  336. package/dist/mcp/tools/resource/delete.js.map +0 -1
  337. package/dist/mcp/tools/resource/find.d.ts +0 -5
  338. package/dist/mcp/tools/resource/find.d.ts.map +0 -1
  339. package/dist/mcp/tools/resource/find.js +0 -170
  340. package/dist/mcp/tools/resource/find.js.map +0 -1
  341. package/dist/mcp/tools/resource/update.d.ts +0 -6
  342. package/dist/mcp/tools/resource/update.d.ts.map +0 -1
  343. package/dist/mcp/tools/resource/update.js +0 -256
  344. package/dist/mcp/tools/resource/update.js.map +0 -1
  345. package/dist/mcp/tools/schemas.d.ts +0 -457
  346. package/dist/mcp/tools/schemas.d.ts.map +0 -1
  347. package/dist/mcp/tools/schemas.js +0 -243
  348. package/dist/mcp/tools/schemas.js.map +0 -1
  349. package/dist/utils/adminEntitySettings.d.ts +0 -17
  350. package/dist/utils/adminEntitySettings.d.ts.map +0 -1
  351. package/dist/utils/adminEntitySettings.js +0 -41
  352. package/dist/utils/adminEntitySettings.js.map +0 -1
  353. package/dist/utils/createApiKeyFields.d.ts +0 -15
  354. package/dist/utils/createApiKeyFields.d.ts.map +0 -1
  355. package/dist/utils/createApiKeyFields.js +0 -57
  356. package/dist/utils/createApiKeyFields.js.map +0 -1
  357. package/dist/utils/getEnabledSlugs.d.ts +0 -13
  358. package/dist/utils/getEnabledSlugs.d.ts.map +0 -1
  359. package/dist/utils/getEnabledSlugs.js +0 -32
  360. package/dist/utils/getEnabledSlugs.js.map +0 -1
  361. package/dist/utils/schemaConversion/convertCollectionSchemaToZod.d.ts +0 -3
  362. package/dist/utils/schemaConversion/convertCollectionSchemaToZod.d.ts.map +0 -1
  363. package/dist/utils/schemaConversion/convertCollectionSchemaToZod.js +0 -43
  364. package/dist/utils/schemaConversion/convertCollectionSchemaToZod.js.map +0 -1
  365. package/dist/utils/schemaConversion/removeVirtualFieldsFromSchema.d.ts +0 -7
  366. package/dist/utils/schemaConversion/removeVirtualFieldsFromSchema.d.ts.map +0 -1
  367. package/dist/utils/schemaConversion/removeVirtualFieldsFromSchema.js +0 -20
  368. package/dist/utils/schemaConversion/removeVirtualFieldsFromSchema.js.map +0 -1
  369. package/dist/utils/schemaConversion/sanitizeJsonSchema.d.ts +0 -13
  370. package/dist/utils/schemaConversion/sanitizeJsonSchema.d.ts.map +0 -1
  371. package/dist/utils/schemaConversion/sanitizeJsonSchema.js +0 -56
  372. package/dist/utils/schemaConversion/sanitizeJsonSchema.js.map +0 -1
  373. package/dist/utils/schemaConversion/simplifyRelationshipFields.d.ts +0 -20
  374. package/dist/utils/schemaConversion/simplifyRelationshipFields.d.ts.map +0 -1
  375. package/dist/utils/schemaConversion/simplifyRelationshipFields.js +0 -53
  376. package/dist/utils/schemaConversion/simplifyRelationshipFields.js.map +0 -1
  377. package/dist/utils/schemaConversion/transformPointFields.d.ts +0 -3
  378. package/dist/utils/schemaConversion/transformPointFields.d.ts.map +0 -1
  379. package/dist/utils/schemaConversion/transformPointFields.js +0 -51
  380. package/dist/utils/schemaConversion/transformPointFields.js.map +0 -1
  381. package/src/collections/createApiKeysCollection.ts +0 -373
  382. package/src/defaults.ts +0 -3
  383. package/src/endpoints/mcp.ts +0 -91
  384. package/src/mcp/createRequest.ts +0 -13
  385. package/src/mcp/getMcpHandler.ts +0 -545
  386. package/src/mcp/helpers/config.ts +0 -213
  387. package/src/mcp/helpers/fields.ts +0 -154
  388. package/src/mcp/helpers/fileValidation.ts +0 -362
  389. package/src/mcp/registerTool.ts +0 -22
  390. package/src/mcp/tools/auth/auth.ts +0 -71
  391. package/src/mcp/tools/auth/forgotPassword.ts +0 -70
  392. package/src/mcp/tools/auth/login.ts +0 -72
  393. package/src/mcp/tools/auth/resetPassword.ts +0 -61
  394. package/src/mcp/tools/auth/unlock.ts +0 -64
  395. package/src/mcp/tools/auth/verify.ts +0 -57
  396. package/src/mcp/tools/collection/create.ts +0 -210
  397. package/src/mcp/tools/collection/delete.ts +0 -211
  398. package/src/mcp/tools/collection/find.ts +0 -224
  399. package/src/mcp/tools/collection/update.ts +0 -290
  400. package/src/mcp/tools/config/find.ts +0 -128
  401. package/src/mcp/tools/config/update.ts +0 -280
  402. package/src/mcp/tools/global/find.ts +0 -128
  403. package/src/mcp/tools/global/update.ts +0 -207
  404. package/src/mcp/tools/job/create.ts +0 -416
  405. package/src/mcp/tools/job/run.ts +0 -167
  406. package/src/mcp/tools/job/update.ts +0 -274
  407. package/src/mcp/tools/resource/create.ts +0 -211
  408. package/src/mcp/tools/resource/delete.ts +0 -218
  409. package/src/mcp/tools/resource/find.ts +0 -246
  410. package/src/mcp/tools/resource/update.ts +0 -383
  411. package/src/mcp/tools/schemas.ts +0 -520
  412. package/src/utils/adminEntitySettings.ts +0 -40
  413. package/src/utils/createApiKeyFields.ts +0 -72
  414. package/src/utils/getEnabledSlugs.ts +0 -42
  415. package/src/utils/schemaConversion/convertCollectionSchemaToZod.ts +0 -52
  416. package/src/utils/schemaConversion/removeVirtualFieldsFromSchema.ts +0 -27
  417. package/src/utils/schemaConversion/sanitizeJsonSchema.ts +0 -62
  418. package/src/utils/schemaConversion/simplifyRelationshipFields.ts +0 -65
  419. package/src/utils/schemaConversion/transformPointFields.ts +0 -55
@@ -0,0 +1,22 @@
1
+ import type { Payload } from 'payload'
2
+
3
+ import { getPluginConfig } from './getPluginConfig.js'
4
+
5
+ /**
6
+ * Get the logger for the MCP plugin. Child of the main Payload logger, prefixed with `[plugin-mcp]`
7
+ * and tagged with a structured `plugin: 'mcp'` field. When `verboseLogs` is off, info/debug calls
8
+ * are silenced; warn/error still surface so operators don't lose error signal.
9
+ */
10
+ export const getLogger: (args: { payload: Payload }) => Payload['logger'] = ({ payload }) => {
11
+ const pluginConfig = getPluginConfig({ config: payload.config })
12
+
13
+ const useVerboseLogs = pluginConfig?.mcp?.verboseLogs ?? false
14
+
15
+ const logger = payload.logger.child({ plugin: 'mcp' }, { msgPrefix: '[plugin-mcp] ' })
16
+
17
+ if (!useVerboseLogs) {
18
+ logger.level = 'warn'
19
+ }
20
+
21
+ return logger
22
+ }
@@ -0,0 +1,24 @@
1
+ import type { PluginsMap, SanitizedConfig } from 'payload'
2
+
3
+ import type { SanitizedMCPPluginConfig } from '../types.js'
4
+
5
+ /**
6
+ * Returns the sanitized plugin config — the form produced by
7
+ * `sanitizeMCPConfig` and stashed back on the plugin's `options` during init.
8
+ * Callers downstream of plugin init can rely on `items` and other defaults
9
+ * being fully resolved.
10
+ */
11
+ export const getPluginConfig: (args: { config: SanitizedConfig }) => SanitizedMCPPluginConfig = ({
12
+ config,
13
+ }) => {
14
+ const plugin = config.plugins?.find(
15
+ (plugin) => plugin.slug === '@payloadcms/plugin-mcp',
16
+ ) as PluginsMap['@payloadcms/plugin-mcp']
17
+
18
+ if (!plugin) {
19
+ throw new Error('MCP Plugin not found in config.plugins.')
20
+ }
21
+
22
+ // @ts-expect-error
23
+ return plugin.sanitizedOptions
24
+ }
@@ -0,0 +1,22 @@
1
+ import type { AuthorizedMCP } from '../types.js'
2
+
3
+ /**
4
+ * Returns the `user` and `overrideAccess` arguments every Payload local API call
5
+ * should receive when initiated from an MCP request. Spread the result into the
6
+ * call's arg object so the two pieces of caller state can't drift apart.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * await req.payload.create({
11
+ * collection: 'posts',
12
+ * data,
13
+ * ...localAPIDefaults(authorizedMCP),
14
+ * })
15
+ * ```
16
+ */
17
+ export const localAPIDefaults = (
18
+ authorizedMCP: AuthorizedMCP,
19
+ ): { overrideAccess: boolean; user: AuthorizedMCP['user'] } => ({
20
+ overrideAccess: authorizedMCP.overrideAccess,
21
+ user: authorizedMCP.user,
22
+ })
@@ -0,0 +1,17 @@
1
+ import path from 'path'
2
+
3
+ /**
4
+ * Returns the project root: the parent of the outermost `node_modules` segment in
5
+ * `fromPath`. Returns `null` when the path has no `node_modules` (e.g. running from
6
+ * source inside the Payload monorepo).
7
+ */
8
+ export const resolveProjectRoot = (fromPath: string): null | string => {
9
+ const segments = fromPath.split(path.sep)
10
+ const nodeModulesIndex = segments.indexOf('node_modules')
11
+
12
+ if (nodeModulesIndex <= 0) {
13
+ return null
14
+ }
15
+
16
+ return segments.slice(0, nodeModulesIndex).join(path.sep) || null
17
+ }
@@ -0,0 +1,62 @@
1
+ import {
2
+ type CollectionSlug,
3
+ entityToStandaloneJSONSchema,
4
+ type GlobalSlug,
5
+ type PayloadRequest,
6
+ type SanitizedCollectionConfig,
7
+ type SanitizedGlobalConfig,
8
+ } from 'payload'
9
+
10
+ import type { JsonSchemaType } from '../../types.js'
11
+
12
+ import { sanitizeEntitySchema } from './sanitizeEntitySchema.js'
13
+
14
+ export const getCollectionInputSchema = ({
15
+ collectionSlug,
16
+ req,
17
+ }: {
18
+ collectionSlug: CollectionSlug
19
+ req: PayloadRequest
20
+ }): JsonSchemaType | null => {
21
+ const collection = req.payload.collections[collectionSlug]?.config
22
+
23
+ if (!collection) {
24
+ return null
25
+ }
26
+
27
+ return buildEntityInputSchema({ entity: collection, req })
28
+ }
29
+
30
+ export const getGlobalInputSchema = ({
31
+ globalSlug,
32
+ req,
33
+ }: {
34
+ globalSlug: GlobalSlug
35
+ req: PayloadRequest
36
+ }): JsonSchemaType | null => {
37
+ const global = req.payload.config.globals.find((globalConfig) => globalConfig.slug === globalSlug)
38
+
39
+ if (!global) {
40
+ return null
41
+ }
42
+
43
+ return buildEntityInputSchema({ entity: global, req })
44
+ }
45
+
46
+ const buildEntityInputSchema = ({
47
+ entity,
48
+ req,
49
+ }: {
50
+ entity: SanitizedCollectionConfig | SanitizedGlobalConfig
51
+ req: PayloadRequest
52
+ }): JsonSchemaType =>
53
+ // The `input` variant is already the write shape; sanitizeEntitySchema only adds MCP-specific passes.
54
+ sanitizeEntitySchema(
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,
62
+ )
@@ -0,0 +1,96 @@
1
+ import { describe, expect, it } from 'vitest'
2
+
3
+ import type { JsonSchemaType } from '../../types.js'
4
+
5
+ import { sanitizeEntitySchema } from './sanitizeEntitySchema.js'
6
+
7
+ describe('sanitizeEntitySchema', () => {
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.
13
+ const standalone: JsonSchemaType = {
14
+ type: 'object',
15
+ $defs: {
16
+ LexicalNodes_ABCDEF12: {
17
+ oneOf: [
18
+ {
19
+ type: 'object',
20
+ additionalProperties: false,
21
+ properties: { type: { const: 'paragraph' } },
22
+ required: ['type'],
23
+ },
24
+ {
25
+ type: 'object',
26
+ additionalProperties: false,
27
+ properties: {
28
+ type: { const: 'relationship' },
29
+ value: { type: 'string', description: 'The related document ID.' },
30
+ },
31
+ required: ['type'],
32
+ },
33
+ ],
34
+ },
35
+ },
36
+ properties: {
37
+ id: { type: 'string' },
38
+ content: {
39
+ type: 'object',
40
+ properties: {
41
+ root: {
42
+ type: 'object',
43
+ properties: {
44
+ children: { type: 'array', items: { $ref: '#/$defs/LexicalNodes_ABCDEF12' } },
45
+ },
46
+ },
47
+ },
48
+ },
49
+ },
50
+ }
51
+
52
+ expect(sanitizeEntitySchema(standalone)).toStrictEqual({
53
+ type: 'object',
54
+ $defs: {
55
+ // The node union is renamed to a short, readable `node`, and stays a strict discriminated
56
+ // `oneOf` - not loosened to `anyOf`.
57
+ node: {
58
+ oneOf: [
59
+ {
60
+ type: 'object',
61
+ additionalProperties: false,
62
+ properties: { type: { const: 'paragraph' } },
63
+ required: ['type'],
64
+ },
65
+ {
66
+ type: 'object',
67
+ additionalProperties: false,
68
+ properties: {
69
+ type: { const: 'relationship' },
70
+ // The value is already ID-only from the input variant - left as-is.
71
+ value: { type: 'string', description: 'The related document ID.' },
72
+ },
73
+ required: ['type'],
74
+ },
75
+ ],
76
+ },
77
+ },
78
+ properties: {
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' },
82
+ content: {
83
+ type: 'object',
84
+ properties: {
85
+ root: {
86
+ type: 'object',
87
+ properties: {
88
+ children: { type: 'array', items: { $ref: '#/$defs/node' } },
89
+ },
90
+ },
91
+ },
92
+ },
93
+ },
94
+ })
95
+ })
96
+ })
@@ -0,0 +1,432 @@
1
+ import type { JsonSchemaType } from '../../types.js'
2
+
3
+ /**
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.
9
+ */
10
+ export const sanitizeEntitySchema = (schema: JsonSchemaType): JsonSchemaType => {
11
+ // Work on a copy — the caller reuses the original schema elsewhere (e.g. when listing tools).
12
+ let result = structuredClone(schema)
13
+
14
+ // LLM ergonomics — drop the redundant `'null'` from optional arrays/objects (`['array','null']` → `'array'`).
15
+ result = collapseOptionalContainerTypes(result)
16
+
17
+ // LLM ergonomics — rewrite point fields from a `[number, number]` tuple into a `{ longitude, latitude }` object.
18
+ result = pointFieldsToObjects(result)
19
+
20
+ // Size — strip inert type-gen leftovers that only bloat the schema (`tsType`, block-collision notes).
21
+ result = removeTypeGenArtifacts(result)
22
+
23
+ // Size — where a `const` already pins a value, the sibling `type` is redundant; remove it.
24
+ result = dropRedundantConstType(result)
25
+
26
+ // Size — fold per-collection relationship/upload variants (identical but for `relationTo`) into one `enum`.
27
+ result = mergeConstDiscriminatedUnions(result)
28
+
29
+ // Size — pull any subschema that appears more than once into a single shared `$defs` entry.
30
+ result = deduplicateIntoDefinitions(result)
31
+
32
+ // LLM ergonomics — give `$defs` short, readable names (`Code`, `paragraph`, `node`) so the `$ref`s read nicely.
33
+ result = shortenDefinitionNames(result)
34
+
35
+ return result
36
+ }
37
+
38
+ /**
39
+ * Rebuilds a schema bottom-up, calling `visit` on each node after its children. Shared by the
40
+ * transforms that need to touch every node in the tree.
41
+ */
42
+ const mapNodes = (node: unknown, visit: (node: JsonSchemaType) => JsonSchemaType): unknown => {
43
+ if (Array.isArray(node)) {
44
+ return node.map((child) => mapNodes(child, visit))
45
+ }
46
+ if (!node || typeof node !== 'object') {
47
+ return node
48
+ }
49
+ const out: Record<string, unknown> = {}
50
+ for (const [key, value] of Object.entries(node)) {
51
+ out[key] = mapNodes(value, visit)
52
+ }
53
+ return visit(out)
54
+ }
55
+
56
+ /**
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.
60
+ *
61
+ * @example
62
+ * { properties: { tags: { type: ['array', 'null'], items: {} } }, required: [] }
63
+ * → { properties: { tags: { type: 'array', items: {} } }, required: [] }
64
+ */
65
+ const collapseOptionalContainerTypes = (schema: JsonSchemaType): JsonSchemaType => {
66
+ if (schema.properties && typeof schema.properties === 'object') {
67
+ for (const key of Object.keys(schema.properties)) {
68
+ const prop = schema.properties[key] as JsonSchemaType
69
+ if (!prop || typeof prop !== 'object') {
70
+ continue
71
+ }
72
+ const isRequired = Array.isArray(schema.required) && schema.required.includes(key)
73
+ collapseNullableType(prop, isRequired)
74
+ if (prop.properties) {
75
+ collapseOptionalContainerTypes(prop)
76
+ }
77
+ if (prop.items && typeof prop.items === 'object' && !Array.isArray(prop.items)) {
78
+ collapseOptionalContainerTypes(prop.items)
79
+ }
80
+ }
81
+ }
82
+
83
+ return schema
84
+ }
85
+
86
+ /**
87
+ * Drops the `'null'` from an optional array/object type (`['array', 'null']` → `'array'`, likewise
88
+ * `'object'`). Payload marks a field optional by unioning its type with `'null'`, but a create/update
89
+ * tool already conveys "optional" through the `required` list - the client just omits the field - so the
90
+ * `'null'` is redundant here. Dropping it shows the model a plain `type: 'array'` instead of implying it
91
+ * should send a literal `null`.
92
+ *
93
+ * We never touch the `required` list, so this can't change whether a field is required. And we skip fields
94
+ * that ARE required (`isRequired`): there a `'null'` is a value the field genuinely accepts, not optionality
95
+ * encoding. Nullable scalars (`['string', 'null']`) are also left alone - they read fine as `string | null`.
96
+ *
97
+ * @example
98
+ * optional { type: ['array', 'null'] } → { type: 'array' } (still optional, just no longer null-valued)
99
+ * required { type: ['array', 'null'] } → unchanged
100
+ * { type: ['string', 'null'] } → unchanged
101
+ */
102
+ const collapseNullableType = (schema: JsonSchemaType, isRequired: boolean): void => {
103
+ if (isRequired || !Array.isArray(schema.type)) {
104
+ return
105
+ }
106
+ const nonNullTypes = schema.type.filter((t) => t !== 'null')
107
+ if (nonNullTypes.length === 1 && (nonNullTypes[0] === 'array' || nonNullTypes[0] === 'object')) {
108
+ schema.type = nonNullTypes[0]
109
+ }
110
+ }
111
+
112
+ /**
113
+ * **LLM ergonomics.** Rewrites a point field (stored as a two-number tuple) into a `{ longitude, latitude }` object, which
114
+ * is far easier for the model to fill in than a positional array. This is input-only and lossless: the
115
+ * create/update handler converts the object back to the `[longitude, latitude]` tuple Payload stores,
116
+ * via `transformPointDataToPayload`.
117
+ *
118
+ * @example
119
+ * { type: 'array', items: [{ type: 'number' }, { type: 'number' }] }
120
+ * → { type: 'object', properties: { longitude: { type: 'number' }, latitude: { type: 'number' } }, required: ['longitude', 'latitude'] }
121
+ */
122
+ const pointFieldsToObjects = (schema: JsonSchemaType): JsonSchemaType => {
123
+ if (!schema || typeof schema !== 'object') {
124
+ return schema
125
+ }
126
+
127
+ const transformed = { ...schema }
128
+
129
+ if (transformed.properties && typeof transformed.properties === 'object') {
130
+ transformed.properties = Object.fromEntries(
131
+ Object.entries(transformed.properties).map(([key, value]) => {
132
+ if (!value || typeof value !== 'object') {
133
+ return [key, value]
134
+ }
135
+ const isArrayType =
136
+ value.type === 'array' || (Array.isArray(value.type) && value.type.includes('array'))
137
+ const isPointField =
138
+ isArrayType &&
139
+ Array.isArray(value.items) &&
140
+ value.items.length === 2 &&
141
+ value.items.every((item) => item && typeof item === 'object' && item.type === 'number')
142
+
143
+ if (isPointField) {
144
+ const isNullable = Array.isArray(value.type) && value.type.includes('null')
145
+ return [
146
+ key,
147
+ {
148
+ type: isNullable ? ['object', 'null'] : 'object',
149
+ description: value.description || 'Geographic coordinates (longitude, latitude)',
150
+ properties: {
151
+ latitude: { type: 'number', description: 'Latitude coordinate' },
152
+ longitude: { type: 'number', description: 'Longitude coordinate' },
153
+ },
154
+ required: ['longitude', 'latitude'],
155
+ },
156
+ ]
157
+ }
158
+
159
+ return [key, pointFieldsToObjects(value)]
160
+ }),
161
+ )
162
+ }
163
+
164
+ if (
165
+ transformed.items &&
166
+ typeof transformed.items === 'object' &&
167
+ !Array.isArray(transformed.items)
168
+ ) {
169
+ transformed.items = pointFieldsToObjects(transformed.items)
170
+ }
171
+
172
+ return transformed
173
+ }
174
+
175
+ /**
176
+ * **Size.** Strips type-generation leftovers that bloat the schema without helping the model: the `tsType`
177
+ * hint (a `json-schema-to-typescript` extension; JSON Schema validators just ignore it, they don't reject it)
178
+ * and the block-interface-collision note Payload adds to some block descriptions (the
179
+ * `block-interface-name-collisions` docs link set in `registerBlockInterface`, see configToJSONSchema.ts).
180
+ * Both are inert here - removing them only shrinks the schema (and spares the model irrelevant noise).
181
+ *
182
+ * @example
183
+ * { type: 'object', tsType: 'SerializedBlockNode', description: 'see …#block-interface-name-collisions' }
184
+ * → { type: 'object' }
185
+ */
186
+ const removeTypeGenArtifacts = (schema: JsonSchemaType): JsonSchemaType =>
187
+ mapNodes(schema, (node) => {
188
+ delete (node as { tsType?: unknown }).tsType
189
+ const { description } = node as { description?: string }
190
+ if (
191
+ typeof description === 'string' &&
192
+ description.includes('block-interface-name-collisions')
193
+ ) {
194
+ delete (node as { description?: unknown }).description
195
+ }
196
+ return node
197
+ }) as JsonSchemaType
198
+
199
+ /**
200
+ * **Size.** Removes `type` whenever a `const` sits next to it — the constant already fixes the value.
201
+ *
202
+ * @example
203
+ * { type: 'string', const: 'paragraph' } → { const: 'paragraph' }
204
+ */
205
+ const dropRedundantConstType = (schema: JsonSchemaType): JsonSchemaType =>
206
+ mapNodes(schema, (node) => {
207
+ if ('const' in node && 'type' in node) {
208
+ delete (node as { type?: unknown }).type
209
+ }
210
+ return node
211
+ }) as JsonSchemaType
212
+
213
+ /**
214
+ * **Size.** Merges the members of a `oneOf`/`anyOf` that are identical except for one `const`-valued property
215
+ * into a single member with that property as an `enum`. Since the members differ only by that one
216
+ * constant, the `enum` form accepts exactly the same values - it's just smaller. This folds the
217
+ * per-collection relationship and upload variants, which differ only in their `relationTo` constant.
218
+ *
219
+ * @example
220
+ * { oneOf: [
221
+ * { properties: { relationTo: { const: 'posts' }, value: { type: 'string' } } },
222
+ * { properties: { relationTo: { const: 'pages' }, value: { type: 'string' } } },
223
+ * ] }
224
+ * → { properties: { relationTo: { enum: ['posts', 'pages'] }, value: { type: 'string' } } }
225
+ */
226
+ const mergeConstDiscriminatedUnions = (schema: JsonSchemaType): JsonSchemaType =>
227
+ mapNodes(schema, (node) => {
228
+ for (const keyword of ['oneOf', 'anyOf'] as const) {
229
+ const members = node[keyword]
230
+ if (Array.isArray(members) && members.length > 1) {
231
+ const merged = mergeMembersByConst(members)
232
+ if (merged) {
233
+ delete node[keyword]
234
+ Object.assign(node, merged)
235
+ }
236
+ }
237
+ }
238
+ return node
239
+ }) as JsonSchemaType
240
+
241
+ /** Returns the merged member for {@link mergeConstDiscriminatedUnions}, or `null` if they can't merge. */
242
+ const mergeMembersByConst = (members: Array<boolean | JsonSchemaType>): JsonSchemaType | null => {
243
+ const objects = members.filter(
244
+ (member): member is JsonSchemaType =>
245
+ typeof member === 'object' && member !== null && typeof member.properties === 'object',
246
+ )
247
+ if (objects.length < 2 || objects.length !== members.length) {
248
+ return null
249
+ }
250
+
251
+ for (const discriminator of Object.keys(objects[0]!.properties!)) {
252
+ // Each member must pin this property to a `const`...
253
+ const constValues: unknown[] = []
254
+ const everyMemberPinsConst = objects.every((member) => {
255
+ const prop = member.properties![discriminator]
256
+ if (prop && typeof prop === 'object' && 'const' in prop) {
257
+ constValues.push(prop.const)
258
+ return true
259
+ }
260
+ return false
261
+ })
262
+ if (!everyMemberPinsConst) {
263
+ continue
264
+ }
265
+
266
+ // ...and be otherwise identical (compare each member with the discriminator removed).
267
+ const fingerprintWithoutDiscriminator = (member: JsonSchemaType): string => {
268
+ const { [discriminator]: _discriminator, ...otherProperties } = member.properties!
269
+ return JSON.stringify({ ...member, properties: otherProperties })
270
+ }
271
+ if (new Set(objects.map(fingerprintWithoutDiscriminator)).size !== 1) {
272
+ continue
273
+ }
274
+
275
+ const uniqueConstValues = [...new Set(constValues)]
276
+ if (uniqueConstValues.length < 2) {
277
+ continue
278
+ }
279
+
280
+ // Replace the per-member `const` with a single `enum` of every value.
281
+ const merged = structuredClone(objects[0]!)
282
+ const discriminatorProp = merged.properties![discriminator]
283
+ if (discriminatorProp && typeof discriminatorProp === 'object') {
284
+ delete discriminatorProp.const
285
+ discriminatorProp.enum = uniqueConstValues as NonNullable<typeof discriminatorProp.enum>
286
+ }
287
+ return merged
288
+ }
289
+ return null
290
+ }
291
+
292
+ // A `$ref` costs ~30 characters once names are shortened, so sharing a subschema only pays off when
293
+ // it's larger than that and appears more than once.
294
+ const MIN_SHARED_SIZE = 64
295
+
296
+ /** A subschema worth sharing: a standalone object/union/described schema, not a `$ref` or a primitive. */
297
+ const isShareable = (node: unknown): node is Record<string, unknown> => {
298
+ if (!node || typeof node !== 'object' || Array.isArray(node) || '$ref' in node) {
299
+ return false
300
+ }
301
+ const schema = node as JsonSchemaType
302
+ return (
303
+ Array.isArray(schema.oneOf) ||
304
+ Array.isArray(schema.anyOf) ||
305
+ Boolean(schema.properties) ||
306
+ Boolean(schema.items) ||
307
+ typeof schema.description === 'string'
308
+ )
309
+ }
310
+
311
+ /**
312
+ * **Size.** Replaces any subschema that appears more than once with a single shared `$defs` entry referenced by
313
+ * `$ref`. Lossless — only the serialized size shrinks. A collection with several rich-text fields, for
314
+ * example, inlines the same large lexical node schema once per field; this collapses them into one.
315
+ *
316
+ * @example
317
+ * { properties: { billing: address, shipping: address } }
318
+ * → { properties: { billing: { $ref: '#/$defs/shared_0' }, shipping: { $ref: '#/$defs/shared_0' } }, $defs: { shared_0: address } }
319
+ */
320
+ const deduplicateIntoDefinitions = (schema: JsonSchemaType): JsonSchemaType => {
321
+ // Count how often each shareable subschema appears, keyed by its serialized form.
322
+ const counts = new Map<string, number>()
323
+ const count = (node: unknown): void => {
324
+ if (isShareable(node)) {
325
+ const key = JSON.stringify(node)
326
+ if (key.length >= MIN_SHARED_SIZE) {
327
+ counts.set(key, (counts.get(key) ?? 0) + 1)
328
+ }
329
+ }
330
+ if (Array.isArray(node)) {
331
+ node.forEach(count)
332
+ } else if (node && typeof node === 'object') {
333
+ Object.values(node).forEach(count)
334
+ }
335
+ }
336
+ count(schema)
337
+
338
+ if (![...counts.values()].some((n) => n >= 2)) {
339
+ return schema
340
+ }
341
+
342
+ // Replace each subschema seen 2+ times with a `$ref`. The first time we meet one it becomes a shared
343
+ // entry; we never descend into a stored entry, so shared entries never reference one another.
344
+ const sharedEntries: Record<string, JsonSchemaType> = {}
345
+ const nameByKey = new Map<string, string>()
346
+ const share = (node: unknown): unknown => {
347
+ if (isShareable(node)) {
348
+ const key = JSON.stringify(node)
349
+ if ((counts.get(key) ?? 0) >= 2) {
350
+ let name = nameByKey.get(key)
351
+ if (!name) {
352
+ name = `shared_${nameByKey.size}`
353
+ nameByKey.set(key, name)
354
+ sharedEntries[name] = node
355
+ }
356
+ return { $ref: `#/$defs/${name}` }
357
+ }
358
+ }
359
+ if (Array.isArray(node)) {
360
+ return node.map(share)
361
+ }
362
+ if (node && typeof node === 'object') {
363
+ return Object.fromEntries(
364
+ Object.entries(node).map(([childKey, value]) => [childKey, share(value)]),
365
+ )
366
+ }
367
+ return node
368
+ }
369
+
370
+ const result = share(schema) as JsonSchemaType
371
+ result.$defs = { ...result.$defs, ...sharedEntries }
372
+ return result
373
+ }
374
+
375
+ /**
376
+ * **LLM ergonomics.** Renames `$defs` entries to short, readable names so the `$ref`s stay legible to the model: a block's
377
+ * `blockType` (`Code`), a node's `type` (`paragraph`), `node` for a rich-text node union, otherwise the
378
+ * generated name with its disambiguating hash dropped. A numeric suffix keeps collisions unique.
379
+ *
380
+ * @example
381
+ * { properties: { body: { $ref: '#/$defs/LexicalNodes_9FBEC708' } }, $defs: { LexicalNodes_9FBEC708: {} } }
382
+ * → { properties: { body: { $ref: '#/$defs/node' } }, $defs: { node: {} } }
383
+ */
384
+ const shortenDefinitionNames = (schema: JsonSchemaType): JsonSchemaType => {
385
+ const definitions = schema.$defs
386
+ if (!definitions || Object.keys(definitions).length === 0) {
387
+ return schema
388
+ }
389
+
390
+ const shortNameFor = (name: string, definition: boolean | JsonSchemaType): string => {
391
+ const properties = (typeof definition === 'object' && definition.properties) || {}
392
+ const constString = (key: string): string | undefined => {
393
+ const prop = properties[key]
394
+ return prop && typeof prop === 'object' && typeof prop.const === 'string'
395
+ ? prop.const
396
+ : undefined
397
+ }
398
+ const members =
399
+ typeof definition === 'object' ? (definition.anyOf ?? definition.oneOf) : undefined
400
+ const isNodeUnion =
401
+ Array.isArray(members) &&
402
+ members.some((m) => typeof m === 'object' && Boolean(m.$ref || m.properties?.type))
403
+ return (
404
+ constString('blockType') ??
405
+ constString('type') ??
406
+ (isNodeUnion ? 'node' : undefined) ??
407
+ name.replace(/_[0-9A-F]{6,}$/i, '')
408
+ )
409
+ }
410
+
411
+ const prefix = '#/$defs/'
412
+ const usedNames = new Map<string, number>()
413
+ const rename = new Map<string, string>()
414
+ for (const [name, definition] of Object.entries(definitions)) {
415
+ const shortName = shortNameFor(name, definition)
416
+ const used = usedNames.get(shortName) ?? 0
417
+ usedNames.set(shortName, used + 1)
418
+ rename.set(name, used === 0 ? shortName : `${shortName}${used + 1}`)
419
+ }
420
+
421
+ const result = mapNodes(schema, (node) => {
422
+ if (typeof node.$ref === 'string' && node.$ref.startsWith(prefix)) {
423
+ const name = node.$ref.slice(prefix.length)
424
+ node.$ref = `${prefix}${rename.get(name) ?? name}`
425
+ }
426
+ return node
427
+ }) as JsonSchemaType
428
+ result.$defs = Object.fromEntries(
429
+ Object.entries(result.$defs!).map(([name, body]) => [rename.get(name) ?? name, body]),
430
+ )
431
+ return result
432
+ }
@@ -0,0 +1,9 @@
1
+ import { fromJsonSchema, type StandardSchemaWithJSON } from '@modelcontextprotocol/server'
2
+
3
+ import type { ToolInputSchema } from '../types.js'
4
+
5
+ /** Normalize a tool/prompt input to a Standard Schema. Raw JSON Schema gets wrapped; Standard Schema instances pass through. */
6
+ export const toStandardSchema = (schema: ToolInputSchema): StandardSchemaWithJSON =>
7
+ typeof schema === 'object' && schema !== null && '~standard' in schema
8
+ ? (schema as StandardSchemaWithJSON)
9
+ : fromJsonSchema(schema)