@payloadcms/plugin-mcp 4.0.0-internal.5b1e7cd → 4.0.0-internal.a0ef1b8

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 (340) 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/collection/getAccessField.d.ts +12 -0
  5. package/dist/collection/getAccessField.d.ts.map +1 -0
  6. package/dist/collection/getAccessField.js +57 -0
  7. package/dist/collection/getAccessField.js.map +1 -0
  8. package/dist/collection/index.d.ts +6 -0
  9. package/dist/collection/index.d.ts.map +1 -0
  10. package/dist/collection/index.js +60 -0
  11. package/dist/collection/index.js.map +1 -0
  12. package/dist/components/AccessField/index.client.d.ts +10 -0
  13. package/dist/components/AccessField/index.client.d.ts.map +1 -0
  14. package/dist/components/AccessField/index.client.js +305 -0
  15. package/dist/components/AccessField/index.client.js.map +1 -0
  16. package/dist/components/AccessField/index.css +93 -0
  17. package/dist/defineTool.d.ts +26 -0
  18. package/dist/defineTool.d.ts.map +1 -0
  19. package/dist/defineTool.js +37 -0
  20. package/dist/defineTool.js.map +1 -0
  21. package/dist/endpoint/access.d.ts +10 -0
  22. package/dist/endpoint/access.d.ts.map +1 -0
  23. package/dist/endpoint/access.js +106 -0
  24. package/dist/endpoint/access.js.map +1 -0
  25. package/dist/endpoint/index.d.ts +3 -0
  26. package/dist/endpoint/index.d.ts.map +1 -0
  27. package/dist/endpoint/index.js +36 -0
  28. package/dist/endpoint/index.js.map +1 -0
  29. package/dist/exports/client.d.ts +2 -0
  30. package/dist/exports/client.d.ts.map +1 -0
  31. package/dist/exports/client.js +4 -0
  32. package/dist/exports/client.js.map +1 -0
  33. package/dist/index.d.ts +4 -7
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +44 -67
  36. package/dist/index.js.map +1 -1
  37. package/dist/mcp/buildMcpServer.d.ts +19 -0
  38. package/dist/mcp/buildMcpServer.d.ts.map +1 -0
  39. package/dist/mcp/buildMcpServer.js +170 -0
  40. package/dist/mcp/buildMcpServer.js.map +1 -0
  41. package/dist/mcp/builtin/collections/authTools.d.ts +7 -0
  42. package/dist/mcp/builtin/collections/authTools.d.ts.map +1 -0
  43. package/dist/mcp/builtin/collections/authTools.js +250 -0
  44. package/dist/mcp/builtin/collections/authTools.js.map +1 -0
  45. package/dist/mcp/builtin/collections/createTool.d.ts +2 -0
  46. package/dist/mcp/builtin/collections/createTool.d.ts.map +1 -0
  47. package/dist/mcp/builtin/collections/createTool.js +91 -0
  48. package/dist/mcp/builtin/collections/createTool.js.map +1 -0
  49. package/dist/mcp/builtin/collections/deleteTool.d.ts +2 -0
  50. package/dist/mcp/builtin/collections/deleteTool.d.ts.map +1 -0
  51. package/dist/mcp/builtin/collections/deleteTool.js +117 -0
  52. package/dist/mcp/builtin/collections/deleteTool.js.map +1 -0
  53. package/dist/mcp/builtin/collections/findTool.d.ts +2 -0
  54. package/dist/mcp/builtin/collections/findTool.d.ts.map +1 -0
  55. package/dist/mcp/builtin/collections/findTool.js +159 -0
  56. package/dist/mcp/builtin/collections/findTool.js.map +1 -0
  57. package/dist/mcp/builtin/collections/updateTool.d.ts +2 -0
  58. package/dist/mcp/builtin/collections/updateTool.d.ts.map +1 -0
  59. package/dist/mcp/builtin/collections/updateTool.js +191 -0
  60. package/dist/mcp/builtin/collections/updateTool.js.map +1 -0
  61. package/dist/mcp/builtin/globals/findTool.d.ts +2 -0
  62. package/dist/mcp/builtin/globals/findTool.d.ts.map +1 -0
  63. package/dist/mcp/builtin/globals/findTool.js +76 -0
  64. package/dist/mcp/builtin/globals/findTool.js.map +1 -0
  65. package/dist/mcp/builtin/globals/updateTool.d.ts +2 -0
  66. package/dist/mcp/builtin/globals/updateTool.d.ts.map +1 -0
  67. package/dist/mcp/builtin/globals/updateTool.js +96 -0
  68. package/dist/mcp/builtin/globals/updateTool.js.map +1 -0
  69. package/dist/mcp/builtinTools.d.ts +37 -0
  70. package/dist/mcp/builtinTools.d.ts.map +1 -0
  71. package/dist/mcp/builtinTools.js +64 -0
  72. package/dist/mcp/builtinTools.js.map +1 -0
  73. package/dist/mcp/sanitizeMCPConfig.d.ts +17 -0
  74. package/dist/mcp/sanitizeMCPConfig.d.ts.map +1 -0
  75. package/dist/mcp/sanitizeMCPConfig.js +167 -0
  76. package/dist/mcp/sanitizeMCPConfig.js.map +1 -0
  77. package/dist/stdio.d.ts +8 -0
  78. package/dist/stdio.d.ts.map +1 -0
  79. package/dist/stdio.js +89 -0
  80. package/dist/stdio.js.map +1 -0
  81. package/dist/types.d.ts +262 -455
  82. package/dist/types.d.ts.map +1 -1
  83. package/dist/types.js +6 -1
  84. package/dist/types.js.map +1 -1
  85. package/dist/utils/camelCase.d.ts.map +1 -1
  86. package/dist/utils/getLogger.d.ts +10 -0
  87. package/dist/utils/getLogger.d.ts.map +1 -0
  88. package/dist/utils/getLogger.js +22 -0
  89. package/dist/utils/getLogger.js.map +1 -0
  90. package/dist/utils/getPluginConfig.d.ts +12 -0
  91. package/dist/utils/getPluginConfig.d.ts.map +1 -0
  92. package/dist/utils/getPluginConfig.js +15 -0
  93. package/dist/utils/getPluginConfig.js.map +1 -0
  94. package/dist/utils/localAPIDefaults.d.ts +20 -0
  95. package/dist/utils/localAPIDefaults.d.ts.map +1 -0
  96. package/dist/utils/localAPIDefaults.js +19 -0
  97. package/dist/utils/localAPIDefaults.js.map +1 -0
  98. package/dist/utils/resolveProjectRoot.d.ts +7 -0
  99. package/dist/utils/resolveProjectRoot.d.ts.map +1 -0
  100. package/dist/utils/resolveProjectRoot.js +15 -0
  101. package/dist/utils/resolveProjectRoot.js.map +1 -0
  102. package/dist/utils/schemaConversion/buildToolInput.d.ts +29 -0
  103. package/dist/utils/schemaConversion/buildToolInput.d.ts.map +1 -0
  104. package/dist/utils/schemaConversion/buildToolInput.js +51 -0
  105. package/dist/utils/schemaConversion/buildToolInput.js.map +1 -0
  106. package/dist/utils/schemaConversion/removeVirtualFieldsFromSchema.d.ts +2 -2
  107. package/dist/utils/schemaConversion/removeVirtualFieldsFromSchema.d.ts.map +1 -1
  108. package/dist/utils/schemaConversion/removeVirtualFieldsFromSchema.js.map +1 -1
  109. package/dist/utils/schemaConversion/sanitizeEntitySchema.d.ts +15 -0
  110. package/dist/utils/schemaConversion/sanitizeEntitySchema.d.ts.map +1 -0
  111. package/dist/utils/schemaConversion/sanitizeEntitySchema.js +464 -0
  112. package/dist/utils/schemaConversion/sanitizeEntitySchema.js.map +1 -0
  113. package/dist/utils/schemaConversion/sanitizeEntitySchema.spec.js +158 -0
  114. package/dist/utils/schemaConversion/sanitizeEntitySchema.spec.js.map +1 -0
  115. package/dist/utils/toStandardSchema.d.ts +5 -0
  116. package/dist/utils/toStandardSchema.d.ts.map +1 -0
  117. package/dist/utils/toStandardSchema.js +4 -0
  118. package/dist/utils/toStandardSchema.js.map +1 -0
  119. package/package.json +35 -10
  120. package/src/@types/assets.d.ts +3 -0
  121. package/src/collection/getAccessField.ts +64 -0
  122. package/src/collection/index.ts +64 -0
  123. package/src/components/AccessField/index.client.tsx +344 -0
  124. package/src/components/AccessField/index.css +93 -0
  125. package/src/defineTool.ts +44 -0
  126. package/src/endpoint/access.ts +132 -0
  127. package/src/endpoint/index.ts +35 -0
  128. package/src/exports/client.ts +2 -0
  129. package/src/index.ts +35 -85
  130. package/src/mcp/buildMcpServer.ts +229 -0
  131. package/src/mcp/builtin/collections/authTools.ts +233 -0
  132. package/src/mcp/builtin/collections/createTool.ts +116 -0
  133. package/src/mcp/builtin/collections/deleteTool.ts +123 -0
  134. package/src/mcp/builtin/collections/findTool.ts +187 -0
  135. package/src/mcp/builtin/collections/updateTool.ts +210 -0
  136. package/src/mcp/builtin/globals/findTool.ts +96 -0
  137. package/src/mcp/builtin/globals/updateTool.ts +120 -0
  138. package/src/mcp/builtinTools.ts +84 -0
  139. package/src/mcp/sanitizeMCPConfig.ts +239 -0
  140. package/src/stdio.ts +98 -0
  141. package/src/types.ts +295 -490
  142. package/src/utils/getLogger.ts +22 -0
  143. package/src/utils/getPluginConfig.ts +24 -0
  144. package/src/utils/localAPIDefaults.ts +22 -0
  145. package/src/utils/resolveProjectRoot.ts +17 -0
  146. package/src/utils/schemaConversion/buildToolInput.ts +68 -0
  147. package/src/utils/schemaConversion/removeVirtualFieldsFromSchema.ts +3 -3
  148. package/src/utils/schemaConversion/sanitizeEntitySchema.spec.ts +103 -0
  149. package/src/utils/schemaConversion/sanitizeEntitySchema.ts +529 -0
  150. package/src/utils/toStandardSchema.ts +9 -0
  151. package/dist/collections/createApiKeysCollection.d.ts +0 -7
  152. package/dist/collections/createApiKeysCollection.d.ts.map +0 -1
  153. package/dist/collections/createApiKeysCollection.js +0 -317
  154. package/dist/collections/createApiKeysCollection.js.map +0 -1
  155. package/dist/defaults.d.ts +0 -4
  156. package/dist/defaults.d.ts.map +0 -1
  157. package/dist/defaults.js +0 -5
  158. package/dist/defaults.js.map +0 -1
  159. package/dist/endpoints/mcp.d.ts +0 -4
  160. package/dist/endpoints/mcp.d.ts.map +0 -1
  161. package/dist/endpoints/mcp.js +0 -71
  162. package/dist/endpoints/mcp.js.map +0 -1
  163. package/dist/mcp/createRequest.d.ts +0 -3
  164. package/dist/mcp/createRequest.d.ts.map +0 -1
  165. package/dist/mcp/createRequest.js +0 -14
  166. package/dist/mcp/createRequest.js.map +0 -1
  167. package/dist/mcp/getMcpHandler.d.ts +0 -4
  168. package/dist/mcp/getMcpHandler.d.ts.map +0 -1
  169. package/dist/mcp/getMcpHandler.js +0 -231
  170. package/dist/mcp/getMcpHandler.js.map +0 -1
  171. package/dist/mcp/helpers/config.d.ts +0 -22
  172. package/dist/mcp/helpers/config.d.ts.map +0 -1
  173. package/dist/mcp/helpers/config.js +0 -153
  174. package/dist/mcp/helpers/config.js.map +0 -1
  175. package/dist/mcp/helpers/fields.d.ts +0 -19
  176. package/dist/mcp/helpers/fields.d.ts.map +0 -1
  177. package/dist/mcp/helpers/fields.js +0 -102
  178. package/dist/mcp/helpers/fields.js.map +0 -1
  179. package/dist/mcp/helpers/fileValidation.d.ts +0 -67
  180. package/dist/mcp/helpers/fileValidation.d.ts.map +0 -1
  181. package/dist/mcp/helpers/fileValidation.js +0 -267
  182. package/dist/mcp/helpers/fileValidation.js.map +0 -1
  183. package/dist/mcp/registerTool.d.ts +0 -6
  184. package/dist/mcp/registerTool.d.ts.map +0 -1
  185. package/dist/mcp/registerTool.js +0 -18
  186. package/dist/mcp/registerTool.js.map +0 -1
  187. package/dist/mcp/tools/auth/auth.d.ts +0 -4
  188. package/dist/mcp/tools/auth/auth.d.ts.map +0 -1
  189. package/dist/mcp/tools/auth/auth.js +0 -57
  190. package/dist/mcp/tools/auth/auth.js.map +0 -1
  191. package/dist/mcp/tools/auth/forgotPassword.d.ts +0 -4
  192. package/dist/mcp/tools/auth/forgotPassword.d.ts.map +0 -1
  193. package/dist/mcp/tools/auth/forgotPassword.js +0 -48
  194. package/dist/mcp/tools/auth/forgotPassword.js.map +0 -1
  195. package/dist/mcp/tools/auth/login.d.ts +0 -4
  196. package/dist/mcp/tools/auth/login.d.ts.map +0 -1
  197. package/dist/mcp/tools/auth/login.js +0 -51
  198. package/dist/mcp/tools/auth/login.js.map +0 -1
  199. package/dist/mcp/tools/auth/resetPassword.d.ts +0 -4
  200. package/dist/mcp/tools/auth/resetPassword.d.ts.map +0 -1
  201. package/dist/mcp/tools/auth/resetPassword.js +0 -49
  202. package/dist/mcp/tools/auth/resetPassword.js.map +0 -1
  203. package/dist/mcp/tools/auth/unlock.d.ts +0 -4
  204. package/dist/mcp/tools/auth/unlock.d.ts.map +0 -1
  205. package/dist/mcp/tools/auth/unlock.js +0 -48
  206. package/dist/mcp/tools/auth/unlock.js.map +0 -1
  207. package/dist/mcp/tools/auth/verify.d.ts +0 -4
  208. package/dist/mcp/tools/auth/verify.d.ts.map +0 -1
  209. package/dist/mcp/tools/auth/verify.js +0 -45
  210. package/dist/mcp/tools/auth/verify.js.map +0 -1
  211. package/dist/mcp/tools/collection/create.d.ts +0 -10
  212. package/dist/mcp/tools/collection/create.d.ts.map +0 -1
  213. package/dist/mcp/tools/collection/create.js +0 -139
  214. package/dist/mcp/tools/collection/create.js.map +0 -1
  215. package/dist/mcp/tools/collection/delete.d.ts +0 -10
  216. package/dist/mcp/tools/collection/delete.d.ts.map +0 -1
  217. package/dist/mcp/tools/collection/delete.js +0 -154
  218. package/dist/mcp/tools/collection/delete.js.map +0 -1
  219. package/dist/mcp/tools/collection/find.d.ts +0 -10
  220. package/dist/mcp/tools/collection/find.d.ts.map +0 -1
  221. package/dist/mcp/tools/collection/find.js +0 -165
  222. package/dist/mcp/tools/collection/find.js.map +0 -1
  223. package/dist/mcp/tools/collection/update.d.ts +0 -10
  224. package/dist/mcp/tools/collection/update.d.ts.map +0 -1
  225. package/dist/mcp/tools/collection/update.js +0 -209
  226. package/dist/mcp/tools/collection/update.js.map +0 -1
  227. package/dist/mcp/tools/config/find.d.ts +0 -10
  228. package/dist/mcp/tools/config/find.d.ts.map +0 -1
  229. package/dist/mcp/tools/config/find.js +0 -97
  230. package/dist/mcp/tools/config/find.js.map +0 -1
  231. package/dist/mcp/tools/config/update.d.ts +0 -10
  232. package/dist/mcp/tools/config/update.d.ts.map +0 -1
  233. package/dist/mcp/tools/config/update.js +0 -215
  234. package/dist/mcp/tools/config/update.js.map +0 -1
  235. package/dist/mcp/tools/global/find.d.ts +0 -5
  236. package/dist/mcp/tools/global/find.d.ts.map +0 -1
  237. package/dist/mcp/tools/global/find.js +0 -82
  238. package/dist/mcp/tools/global/find.js.map +0 -1
  239. package/dist/mcp/tools/global/update.d.ts +0 -6
  240. package/dist/mcp/tools/global/update.d.ts.map +0 -1
  241. package/dist/mcp/tools/global/update.js +0 -124
  242. package/dist/mcp/tools/global/update.js.map +0 -1
  243. package/dist/mcp/tools/job/create.d.ts +0 -10
  244. package/dist/mcp/tools/job/create.d.ts.map +0 -1
  245. package/dist/mcp/tools/job/create.js +0 -293
  246. package/dist/mcp/tools/job/create.js.map +0 -1
  247. package/dist/mcp/tools/job/run.d.ts +0 -10
  248. package/dist/mcp/tools/job/run.d.ts.map +0 -1
  249. package/dist/mcp/tools/job/run.js +0 -129
  250. package/dist/mcp/tools/job/run.js.map +0 -1
  251. package/dist/mcp/tools/job/update.d.ts +0 -11
  252. package/dist/mcp/tools/job/update.d.ts.map +0 -1
  253. package/dist/mcp/tools/job/update.js +0 -186
  254. package/dist/mcp/tools/job/update.js.map +0 -1
  255. package/dist/mcp/tools/resource/create.d.ts +0 -6
  256. package/dist/mcp/tools/resource/create.d.ts.map +0 -1
  257. package/dist/mcp/tools/resource/create.js +0 -124
  258. package/dist/mcp/tools/resource/create.js.map +0 -1
  259. package/dist/mcp/tools/resource/delete.d.ts +0 -5
  260. package/dist/mcp/tools/resource/delete.d.ts.map +0 -1
  261. package/dist/mcp/tools/resource/delete.js +0 -151
  262. package/dist/mcp/tools/resource/delete.js.map +0 -1
  263. package/dist/mcp/tools/resource/find.d.ts +0 -5
  264. package/dist/mcp/tools/resource/find.d.ts.map +0 -1
  265. package/dist/mcp/tools/resource/find.js +0 -170
  266. package/dist/mcp/tools/resource/find.js.map +0 -1
  267. package/dist/mcp/tools/resource/update.d.ts +0 -6
  268. package/dist/mcp/tools/resource/update.d.ts.map +0 -1
  269. package/dist/mcp/tools/resource/update.js +0 -256
  270. package/dist/mcp/tools/resource/update.js.map +0 -1
  271. package/dist/mcp/tools/schemas.d.ts +0 -457
  272. package/dist/mcp/tools/schemas.d.ts.map +0 -1
  273. package/dist/mcp/tools/schemas.js +0 -243
  274. package/dist/mcp/tools/schemas.js.map +0 -1
  275. package/dist/utils/adminEntitySettings.d.ts +0 -17
  276. package/dist/utils/adminEntitySettings.d.ts.map +0 -1
  277. package/dist/utils/adminEntitySettings.js +0 -41
  278. package/dist/utils/adminEntitySettings.js.map +0 -1
  279. package/dist/utils/createApiKeyFields.d.ts +0 -15
  280. package/dist/utils/createApiKeyFields.d.ts.map +0 -1
  281. package/dist/utils/createApiKeyFields.js +0 -57
  282. package/dist/utils/createApiKeyFields.js.map +0 -1
  283. package/dist/utils/getEnabledSlugs.d.ts +0 -13
  284. package/dist/utils/getEnabledSlugs.d.ts.map +0 -1
  285. package/dist/utils/getEnabledSlugs.js +0 -32
  286. package/dist/utils/getEnabledSlugs.js.map +0 -1
  287. package/dist/utils/schemaConversion/convertCollectionSchemaToZod.d.ts +0 -3
  288. package/dist/utils/schemaConversion/convertCollectionSchemaToZod.d.ts.map +0 -1
  289. package/dist/utils/schemaConversion/convertCollectionSchemaToZod.js +0 -43
  290. package/dist/utils/schemaConversion/convertCollectionSchemaToZod.js.map +0 -1
  291. package/dist/utils/schemaConversion/sanitizeJsonSchema.d.ts +0 -13
  292. package/dist/utils/schemaConversion/sanitizeJsonSchema.d.ts.map +0 -1
  293. package/dist/utils/schemaConversion/sanitizeJsonSchema.js +0 -56
  294. package/dist/utils/schemaConversion/sanitizeJsonSchema.js.map +0 -1
  295. package/dist/utils/schemaConversion/simplifyRelationshipFields.d.ts +0 -20
  296. package/dist/utils/schemaConversion/simplifyRelationshipFields.d.ts.map +0 -1
  297. package/dist/utils/schemaConversion/simplifyRelationshipFields.js +0 -53
  298. package/dist/utils/schemaConversion/simplifyRelationshipFields.js.map +0 -1
  299. package/dist/utils/schemaConversion/transformPointFields.d.ts +0 -3
  300. package/dist/utils/schemaConversion/transformPointFields.d.ts.map +0 -1
  301. package/dist/utils/schemaConversion/transformPointFields.js +0 -51
  302. package/dist/utils/schemaConversion/transformPointFields.js.map +0 -1
  303. package/src/collections/createApiKeysCollection.ts +0 -373
  304. package/src/defaults.ts +0 -3
  305. package/src/endpoints/mcp.ts +0 -91
  306. package/src/mcp/createRequest.ts +0 -13
  307. package/src/mcp/getMcpHandler.ts +0 -545
  308. package/src/mcp/helpers/config.ts +0 -213
  309. package/src/mcp/helpers/fields.ts +0 -154
  310. package/src/mcp/helpers/fileValidation.ts +0 -362
  311. package/src/mcp/registerTool.ts +0 -22
  312. package/src/mcp/tools/auth/auth.ts +0 -71
  313. package/src/mcp/tools/auth/forgotPassword.ts +0 -70
  314. package/src/mcp/tools/auth/login.ts +0 -72
  315. package/src/mcp/tools/auth/resetPassword.ts +0 -61
  316. package/src/mcp/tools/auth/unlock.ts +0 -64
  317. package/src/mcp/tools/auth/verify.ts +0 -57
  318. package/src/mcp/tools/collection/create.ts +0 -210
  319. package/src/mcp/tools/collection/delete.ts +0 -211
  320. package/src/mcp/tools/collection/find.ts +0 -224
  321. package/src/mcp/tools/collection/update.ts +0 -290
  322. package/src/mcp/tools/config/find.ts +0 -128
  323. package/src/mcp/tools/config/update.ts +0 -280
  324. package/src/mcp/tools/global/find.ts +0 -128
  325. package/src/mcp/tools/global/update.ts +0 -207
  326. package/src/mcp/tools/job/create.ts +0 -416
  327. package/src/mcp/tools/job/run.ts +0 -167
  328. package/src/mcp/tools/job/update.ts +0 -274
  329. package/src/mcp/tools/resource/create.ts +0 -211
  330. package/src/mcp/tools/resource/delete.ts +0 -218
  331. package/src/mcp/tools/resource/find.ts +0 -246
  332. package/src/mcp/tools/resource/update.ts +0 -383
  333. package/src/mcp/tools/schemas.ts +0 -520
  334. package/src/utils/adminEntitySettings.ts +0 -40
  335. package/src/utils/createApiKeyFields.ts +0 -72
  336. package/src/utils/getEnabledSlugs.ts +0 -42
  337. package/src/utils/schemaConversion/convertCollectionSchemaToZod.ts +0 -52
  338. package/src/utils/schemaConversion/sanitizeJsonSchema.ts +0 -62
  339. package/src/utils/schemaConversion/simplifyRelationshipFields.ts +0 -65
  340. package/src/utils/schemaConversion/transformPointFields.ts +0 -55
@@ -0,0 +1,96 @@
1
+ import type { SelectType } from 'payload'
2
+
3
+ import { z } from 'zod'
4
+
5
+ import { defineGlobalTool } from '../../../defineTool.js'
6
+ import { getLogger } from '../../../utils/getLogger.js'
7
+ import { localAPIDefaults } from '../../../utils/localAPIDefaults.js'
8
+
9
+ const DEFAULT_DESCRIPTION = 'Find a Payload global singleton configuration.'
10
+
11
+ export const findGlobalTool = defineGlobalTool({
12
+ description: DEFAULT_DESCRIPTION,
13
+ input: z.object({
14
+ depth: z
15
+ .number()
16
+ .int()
17
+ .min(0)
18
+ .max(10)
19
+ .describe('Depth of population for relationships')
20
+ .optional()
21
+ .default(0),
22
+ fallbackLocale: z
23
+ .string()
24
+ .describe('Optional: fallback locale code to use when requested locale is not available')
25
+ .optional(),
26
+ locale: z
27
+ .string()
28
+ .describe(
29
+ 'Optional: locale code to retrieve data in (e.g., "en", "es"). Use "all" to retrieve all locales for localized fields',
30
+ )
31
+ .optional(),
32
+ select: z
33
+ .string()
34
+ .describe(
35
+ "Optional: define exactly which fields you'd like to return in the response (JSON), e.g., '{\"title\": true}'",
36
+ )
37
+ .optional(),
38
+ }),
39
+ }).handler(async ({ authorizedMCP, globalSlug, input, req }) => {
40
+ const payload = req.payload
41
+ const logger = getLogger({ payload })
42
+
43
+ const { depth, fallbackLocale, locale, select } = input
44
+
45
+ logger.info(
46
+ `Reading global: ${globalSlug}, depth: ${depth}${locale ? `, locale: ${locale}` : ''}`,
47
+ )
48
+
49
+ try {
50
+ const findOptions: Parameters<typeof payload.findGlobal>[0] = {
51
+ slug: globalSlug,
52
+ depth,
53
+ ...localAPIDefaults(authorizedMCP),
54
+ }
55
+
56
+ let selectClause: SelectType | undefined
57
+ if (select) {
58
+ try {
59
+ selectClause = JSON.parse(select) as SelectType
60
+ } catch {
61
+ logger.warn(`Invalid select clause JSON for global: ${select}`)
62
+ return { content: [{ type: 'text', text: 'Error: Invalid JSON in select clause' }] }
63
+ }
64
+ }
65
+
66
+ if (locale) {
67
+ findOptions.locale = locale
68
+ }
69
+ if (fallbackLocale) {
70
+ findOptions.fallbackLocale = fallbackLocale
71
+ }
72
+ if (selectClause) {
73
+ findOptions.select = selectClause
74
+ }
75
+
76
+ const result = await payload.findGlobal(findOptions)
77
+
78
+ return {
79
+ content: [
80
+ {
81
+ type: 'text',
82
+ text: `Global "${globalSlug}":\n\`\`\`json\n${JSON.stringify(result)}\n\`\`\``,
83
+ },
84
+ ],
85
+ doc: result as Record<string, unknown>,
86
+ }
87
+ } catch (error) {
88
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error'
89
+ logger.error(`Error reading global ${globalSlug}: ${errorMessage}`)
90
+ return {
91
+ content: [
92
+ { type: 'text', text: `❌ **Error reading global "${globalSlug}":** ${errorMessage}` },
93
+ ],
94
+ }
95
+ }
96
+ })
@@ -0,0 +1,120 @@
1
+ import type { SelectType } from 'payload'
2
+
3
+ import { z } from 'zod'
4
+
5
+ import { defineGlobalTool } from '../../../defineTool.js'
6
+ import { getLogger } from '../../../utils/getLogger.js'
7
+ import {
8
+ getGlobalVirtualFieldNames,
9
+ stripVirtualFields,
10
+ } from '../../../utils/getVirtualFieldNames.js'
11
+ import { localAPIDefaults } from '../../../utils/localAPIDefaults.js'
12
+ import { buildToolInput } from '../../../utils/schemaConversion/buildToolInput.js'
13
+ import { sanitizeEntitySchema } from '../../../utils/schemaConversion/sanitizeEntitySchema.js'
14
+
15
+ const DEFAULT_DESCRIPTION = 'Update a Payload global singleton configuration.'
16
+
17
+ export const updateGlobalTool = defineGlobalTool({
18
+ description: DEFAULT_DESCRIPTION,
19
+ input: ({ globalSchema }) => {
20
+ const partialSchema = sanitizeEntitySchema(globalSchema)
21
+ // Global updates do not require all required fields to be passed => delete .required.
22
+ //
23
+ // Local API equivalent: packages/payload/src/global/operations/local/update.ts#BaseOptions#data:
24
+ // data: DeepPartial<Omit<DataFromGlobalSlug<TSlug>, 'id'>>
25
+ delete partialSchema.required
26
+
27
+ return buildToolInput({
28
+ controls: {
29
+ depth: z
30
+ .number()
31
+ .describe('Optional: Depth of relationships to populate')
32
+ .optional()
33
+ .default(0),
34
+ draft: z
35
+ .boolean()
36
+ .describe('Optional: Whether to save as draft (default: false)')
37
+ .optional()
38
+ .default(false),
39
+ fallbackLocale: z
40
+ .string()
41
+ .describe('Optional: fallback locale code to use when requested locale is not available')
42
+ .optional(),
43
+ locale: z
44
+ .string()
45
+ .describe(
46
+ 'Optional: locale code to update data in (e.g., "en", "es"). Use "all" to update all locales for localized fields',
47
+ )
48
+ .optional(),
49
+ select: z
50
+ .string()
51
+ .describe(
52
+ 'Optional: define exactly which fields you\'d like to return in the response (JSON), e.g., \'{"siteName": "My Site"}\'',
53
+ )
54
+ .optional(),
55
+ },
56
+ dataDescription: 'The fields to update',
57
+ dataSchema: partialSchema,
58
+ })
59
+ },
60
+ }).handler(async ({ authorizedMCP, globalSlug, input, req }) => {
61
+ const payload = req.payload
62
+ const logger = getLogger({ payload })
63
+
64
+ const { data, depth, draft, fallbackLocale, locale, select } = input
65
+
66
+ logger.info(
67
+ `Updating global: ${globalSlug}, draft: ${draft}${locale ? `, locale: ${locale}` : ''}`,
68
+ )
69
+
70
+ try {
71
+ const virtualFieldNames = getGlobalVirtualFieldNames(payload.config, globalSlug)
72
+ const parsedData = stripVirtualFields(data, virtualFieldNames)
73
+
74
+ let selectClause: SelectType | undefined
75
+ if (select) {
76
+ try {
77
+ selectClause = JSON.parse(select) as SelectType
78
+ } catch {
79
+ logger.warn(`Invalid select clause JSON for global: ${select}`)
80
+ return { content: [{ type: 'text', text: 'Error: Invalid JSON in select clause' }] }
81
+ }
82
+ }
83
+
84
+ const updateOptions: Parameters<typeof payload.updateGlobal>[0] = {
85
+ slug: globalSlug,
86
+ data: parsedData,
87
+ depth,
88
+ draft,
89
+ ...localAPIDefaults(authorizedMCP),
90
+ }
91
+
92
+ if (locale) {
93
+ updateOptions.locale = locale
94
+ }
95
+ if (fallbackLocale) {
96
+ updateOptions.fallbackLocale = fallbackLocale
97
+ }
98
+ if (selectClause) {
99
+ updateOptions.select = selectClause
100
+ }
101
+
102
+ const result = await payload.updateGlobal(updateOptions)
103
+
104
+ return {
105
+ content: [
106
+ {
107
+ type: 'text',
108
+ text: `Global "${globalSlug}" updated successfully!\n\`\`\`json\n${JSON.stringify(result)}\n\`\`\``,
109
+ },
110
+ ],
111
+ doc: result as Record<string, unknown>,
112
+ }
113
+ } catch (error) {
114
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error'
115
+ logger.error(`Error updating global ${globalSlug}: ${errorMessage}`)
116
+ return {
117
+ content: [{ type: 'text', text: `Error updating global "${globalSlug}": ${errorMessage}` }],
118
+ }
119
+ }
120
+ })
@@ -0,0 +1,84 @@
1
+ import type { CollectionTool, GlobalTool } from '../types.js'
2
+
3
+ import {
4
+ authCollectionTool,
5
+ forgotPasswordCollectionTool,
6
+ loginCollectionTool,
7
+ resetPasswordCollectionTool,
8
+ unlockCollectionTool,
9
+ verifyCollectionTool,
10
+ } from './builtin/collections/authTools.js'
11
+ import { createCollectionTool } from './builtin/collections/createTool.js'
12
+ import { deleteCollectionTool } from './builtin/collections/deleteTool.js'
13
+ import { findCollectionTool } from './builtin/collections/findTool.js'
14
+ import { updateCollectionTool } from './builtin/collections/updateTool.js'
15
+ import { findGlobalTool } from './builtin/globals/findTool.js'
16
+ import { updateGlobalTool } from './builtin/globals/updateTool.js'
17
+
18
+ /**
19
+ * The static built-in collection CRUD tools. Keys here are the source of truth
20
+ * for `MCPCollectionBuiltinName` — adding/removing an entry updates the type
21
+ * automatically.
22
+ */
23
+ export const COLLECTION_BUILTINS: Record<MCPCollectionBuiltinName, CollectionTool> = {
24
+ create: createCollectionTool,
25
+ delete: deleteCollectionTool,
26
+ find: findCollectionTool,
27
+ update: updateCollectionTool,
28
+ }
29
+
30
+ /**
31
+ * The static auth tools surfaced under auth-enabled collections. Each entry
32
+ * carries the admin-UI label alongside the tool. Keys are the source of truth
33
+ * for `MCPCollectionAuthToolName`.
34
+ */
35
+ export const COLLECTION_AUTH_BUILTINS: Record<
36
+ MCPCollectionAuthToolName,
37
+ { label: string; tool: CollectionTool }
38
+ > = {
39
+ auth: { label: 'Check Auth Status', tool: authCollectionTool },
40
+ forgotPassword: { label: 'Forgot Password', tool: forgotPasswordCollectionTool },
41
+ login: { label: 'User Login', tool: loginCollectionTool },
42
+ resetPassword: { label: 'Reset Password', tool: resetPasswordCollectionTool },
43
+ unlock: { label: 'Unlock Account', tool: unlockCollectionTool },
44
+ verify: { label: 'Email Verification', tool: verifyCollectionTool },
45
+ }
46
+
47
+ /**
48
+ * The static built-in global tools. Keys are the source of truth for
49
+ * `MCPGlobalBuiltinName`.
50
+ */
51
+ export const GLOBAL_BUILTINS: Record<MCPGlobalBuiltinName, GlobalTool> = {
52
+ find: findGlobalTool,
53
+ update: updateGlobalTool,
54
+ }
55
+
56
+ export type MCPCollectionBuiltinName = 'create' | 'delete' | 'find' | 'update'
57
+
58
+ export type MCPCollectionAuthToolName =
59
+ | 'auth'
60
+ | 'forgotPassword'
61
+ | 'login'
62
+ | 'resetPassword'
63
+ | 'unlock'
64
+ | 'verify'
65
+
66
+ export type MCPGlobalBuiltinName = 'find' | 'update'
67
+
68
+ /**
69
+ * Pre-typed `Object.entries` for each registry. The cast from `string` to the
70
+ * literal key union lives here once so consumers can iterate without their own
71
+ * cast — TypeScript's `Object.entries` always widens keys to `string`, which
72
+ * defeats the narrow type lookups on `MCPCollectionToolsMap`.
73
+ */
74
+ export const COLLECTION_BUILTIN_ENTRIES = Object.entries(COLLECTION_BUILTINS) as Array<
75
+ [MCPCollectionBuiltinName, CollectionTool]
76
+ >
77
+
78
+ export const COLLECTION_AUTH_BUILTIN_ENTRIES = Object.entries(COLLECTION_AUTH_BUILTINS) as Array<
79
+ [MCPCollectionAuthToolName, { label: string; tool: CollectionTool }]
80
+ >
81
+
82
+ export const GLOBAL_BUILTIN_ENTRIES = Object.entries(GLOBAL_BUILTINS) as Array<
83
+ [MCPGlobalBuiltinName, GlobalTool]
84
+ >
@@ -0,0 +1,239 @@
1
+ import type {
2
+ CollectionConfig,
3
+ Config,
4
+ GlobalConfig,
5
+ SanitizedCollectionConfig,
6
+ SanitizedConfig,
7
+ SanitizedGlobalConfig,
8
+ } from 'payload'
9
+
10
+ import type {
11
+ CollectionTool,
12
+ GlobalTool,
13
+ MCPBuiltInToolOverride,
14
+ MCPItem,
15
+ MCPPluginCollectionConfig,
16
+ MCPPluginConfig,
17
+ MCPPluginGlobalConfig,
18
+ SanitizedMCPPluginConfig,
19
+ } from '../types.js'
20
+
21
+ import {
22
+ COLLECTION_AUTH_BUILTIN_ENTRIES,
23
+ COLLECTION_AUTH_BUILTINS,
24
+ COLLECTION_BUILTIN_ENTRIES,
25
+ COLLECTION_BUILTINS,
26
+ GLOBAL_BUILTIN_ENTRIES,
27
+ GLOBAL_BUILTINS,
28
+ } from './builtinTools.js'
29
+
30
+ /**
31
+ * Converts the user-configured `MCPPluginConfig` into a `SanitizedMCPPluginConfig`:
32
+ * - Flattens `tools` / `prompts` / `resources` / per-collection / per-global
33
+ * tool maps into a single `items` array.
34
+ * - Applies built-in tools for collections and globals, respecting opt-out user overrides.
35
+ * - Applies the `userCollection` default
36
+ *
37
+ * Called once during plugin init. After that, `plugins['@payloadcms/plugin-mcp']
38
+ * ?.options` holds the sanitized result
39
+ */
40
+ export const sanitizeMCPConfig = ({
41
+ config,
42
+ pluginConfig,
43
+ }: {
44
+ config: Config | SanitizedConfig
45
+ pluginConfig: MCPPluginConfig
46
+ }): SanitizedMCPPluginConfig => {
47
+ const items: MCPItem[] = []
48
+
49
+ for (const collection of config.collections ?? []) {
50
+ items.push(...sanitizeCollectionConfig({ collection, pluginConfig }))
51
+ }
52
+
53
+ for (const global of config.globals ?? []) {
54
+ items.push(...sanitizeGlobalConfig({ global, pluginConfig }))
55
+ }
56
+
57
+ for (const [key, tool] of Object.entries(pluginConfig.tools ?? {})) {
58
+ items.push({
59
+ type: 'tool',
60
+ key,
61
+ label: key,
62
+ tool,
63
+ })
64
+ }
65
+
66
+ for (const [key, prompt] of Object.entries(pluginConfig.prompts ?? {})) {
67
+ items.push({
68
+ type: 'prompt',
69
+ key,
70
+ label: prompt.title ?? key,
71
+ prompt,
72
+ })
73
+ }
74
+
75
+ for (const [key, resource] of Object.entries(pluginConfig.resources ?? {})) {
76
+ items.push({
77
+ type: 'resource',
78
+ key,
79
+ label: resource.title ?? key,
80
+ resource,
81
+ })
82
+ }
83
+
84
+ // Mirror Payload's own admin.user detection (sanitize.ts) since plugins run first.
85
+ const firstCollectionWithAuth = config.collections!.find(({ auth }) => Boolean(auth))
86
+
87
+ return {
88
+ disabled: pluginConfig.disabled,
89
+ items,
90
+ mcp: pluginConfig.mcp,
91
+ overrideApiKeyCollection: pluginConfig.overrideApiKeyCollection,
92
+ overrideAuth: pluginConfig.overrideAuth,
93
+ userCollection:
94
+ pluginConfig.userCollection ?? config.admin?.user ?? firstCollectionWithAuth?.slug ?? 'users',
95
+ }
96
+ }
97
+
98
+ const sanitizeCollectionConfig = ({
99
+ collection,
100
+ pluginConfig,
101
+ }: {
102
+ collection: CollectionConfig | SanitizedCollectionConfig
103
+ pluginConfig: MCPPluginConfig
104
+ }): MCPItem[] => {
105
+ if (collection.slug === 'payload-mcp-api-keys') {
106
+ return []
107
+ }
108
+ const slug = collection.slug
109
+ const collectionPluginConfig = pluginConfig.collections?.[slug]
110
+ const items: MCPItem[] = []
111
+
112
+ for (const [toolKey, tool] of COLLECTION_BUILTIN_ENTRIES) {
113
+ const matchedConfigEntry = collectionPluginConfig?.tools?.[toolKey]
114
+ if (matchedConfigEntry === false) {
115
+ continue
116
+ }
117
+ items.push({
118
+ type: 'collectionTool',
119
+ collectionSlug: slug,
120
+ key: toolKey,
121
+ label: capitalize(toolKey),
122
+ tool: overrideBuiltinTool(tool, matchedConfigEntry, collectionPluginConfig),
123
+ })
124
+ }
125
+
126
+ if (collection.auth) {
127
+ for (const [authToolKey, { label, tool }] of COLLECTION_AUTH_BUILTIN_ENTRIES) {
128
+ const matchedConfigEntry = collectionPluginConfig?.tools?.[authToolKey]
129
+ if (!matchedConfigEntry) {
130
+ continue
131
+ }
132
+ // `true` means "enable, no override"; only the object form carries fields.
133
+ const override = typeof matchedConfigEntry === 'object' ? matchedConfigEntry : undefined
134
+ items.push({
135
+ type: 'collectionTool',
136
+ collectionSlug: slug,
137
+ key: authToolKey,
138
+ label,
139
+ tool: overrideBuiltinTool(tool, override, collectionPluginConfig),
140
+ })
141
+ }
142
+ }
143
+
144
+ // Cast: builtin keys are filtered out below, so the remaining values are
145
+ // always custom tools (`CollectionTool`) or undefined
146
+ const customEntries = Object.entries(collectionPluginConfig?.tools ?? {}) as Array<
147
+ [string, CollectionTool | undefined]
148
+ >
149
+ for (const [key, customTool] of customEntries) {
150
+ if (key in COLLECTION_BUILTINS || key in COLLECTION_AUTH_BUILTINS) {
151
+ continue
152
+ }
153
+ if (!customTool) {
154
+ continue
155
+ }
156
+ items.push({
157
+ type: 'collectionTool',
158
+ collectionSlug: slug,
159
+ key,
160
+ label: key,
161
+ tool: customTool,
162
+ })
163
+ }
164
+
165
+ return items
166
+ }
167
+
168
+ const sanitizeGlobalConfig = ({
169
+ global,
170
+ pluginConfig,
171
+ }: {
172
+ global: GlobalConfig | SanitizedGlobalConfig
173
+ pluginConfig: MCPPluginConfig
174
+ }): MCPItem[] => {
175
+ const slug = global.slug
176
+ const globalPluginConfig = pluginConfig.globals?.[slug]
177
+ const items: MCPItem[] = []
178
+
179
+ for (const [toolKey, baseTool] of GLOBAL_BUILTIN_ENTRIES) {
180
+ const matchedConfigEntry = globalPluginConfig?.tools?.[toolKey]
181
+ if (matchedConfigEntry === false) {
182
+ continue
183
+ }
184
+ items.push({
185
+ type: 'globalTool',
186
+ globalSlug: slug,
187
+ key: toolKey,
188
+ label: capitalize(toolKey),
189
+ tool: overrideBuiltinTool(baseTool, matchedConfigEntry, globalPluginConfig),
190
+ })
191
+ }
192
+
193
+ const customEntries = Object.entries(globalPluginConfig?.tools ?? {}) as Array<
194
+ [string, GlobalTool | undefined]
195
+ >
196
+ for (const [key, customTool] of customEntries) {
197
+ if (key in GLOBAL_BUILTINS) {
198
+ continue
199
+ }
200
+ if (!customTool) {
201
+ continue
202
+ }
203
+ items.push({
204
+ type: 'globalTool',
205
+ globalSlug: slug,
206
+ key,
207
+ label: key,
208
+ tool: customTool,
209
+ })
210
+ }
211
+
212
+ return items
213
+ }
214
+
215
+ const capitalize = (s: string): string => s.charAt(0).toUpperCase() + s.slice(1)
216
+
217
+ /**
218
+ * Spread the static built-in tool and apply consumer-side overrides.
219
+ * Precedence: per-tool override > scope-level (collection/global) override >
220
+ * the static tool's defaults. `toolEntry` is whatever the user put under
221
+ * `tools: { find: ... }` — could be `true`, `false`, or an override object —
222
+ * so it's narrowed internally.
223
+ */
224
+ const overrideBuiltinTool = <TTool extends CollectionTool | GlobalTool>(
225
+ tool: TTool,
226
+ toolOverride?: MCPBuiltInToolOverride,
227
+ entityPluginConfig?: TTool extends CollectionTool
228
+ ? MCPPluginCollectionConfig<any>
229
+ : MCPPluginGlobalConfig,
230
+ ): TTool => {
231
+ return {
232
+ ...tool,
233
+ description: toolOverride?.description ?? entityPluginConfig?.description ?? tool.description,
234
+ overrideResponse:
235
+ toolOverride?.overrideResponse ??
236
+ entityPluginConfig?.overrideResponse ??
237
+ tool.overrideResponse,
238
+ }
239
+ }
package/src/stdio.ts ADDED
@@ -0,0 +1,98 @@
1
+ import type { MaybePromise, Plugin, SanitizedConfig } from 'payload'
2
+
3
+ /* eslint-disable no-console */
4
+ import { StdioServerTransport } from '@modelcontextprotocol/server'
5
+ import { fileURLToPath, pathToFileURL } from 'node:url'
6
+ import { createLocalReq, getPayload } from 'payload'
7
+ import { findConfig } from 'payload/node'
8
+
9
+ import type { AuthorizedMCP, SanitizedMCPPluginConfig } from './types.js'
10
+
11
+ import { buildMcpServer } from './mcp/buildMcpServer.js'
12
+ import { sanitizeMCPConfig } from './mcp/sanitizeMCPConfig.js'
13
+ import { getPluginConfig } from './utils/getPluginConfig.js'
14
+ import { resolveProjectRoot } from './utils/resolveProjectRoot.js'
15
+
16
+ /**
17
+ * Stdio adapter for the Payload MCP server.
18
+ *
19
+ * Do not use in production. There's no auth; whoever can spawn the process gets
20
+ * full access to your local data.
21
+ */
22
+ export const runMcpStdio = async (): Promise<void> => {
23
+ /**
24
+ * If MCP clients spawn stdio servers from an arbitrary working directory,
25
+ * Payload's cwd-anchored `findConfig()` can't locate the project on
26
+ * its own. This module always lives inside the project's `node_modules`, so
27
+ * we derive the project root from its own path and `chdir` into it.
28
+ *
29
+ * An absolute `PAYLOAD_CONFIG_PATH` still overrides everything; unusual
30
+ * layouts (e.g. a monorepo where the package is hoisted above the app) can
31
+ * fall back to it. See the implementation of findConfig for details.
32
+ */
33
+ const projectRoot = resolveProjectRoot(fileURLToPath(import.meta.url))
34
+ if (projectRoot) {
35
+ process.chdir(projectRoot)
36
+ }
37
+
38
+ const configPath = findConfig()
39
+ const configModule = await import(pathToFileURL(configPath).toString())
40
+ const config = (await (configModule.default ?? configModule)) as MaybePromise<SanitizedConfig>
41
+
42
+ const payload = await getPayload({ config })
43
+
44
+ /**
45
+ * If the user added `mcpPlugin({...})` to their `plugins` array, read the
46
+ * sanitized config they registered. Otherwise fall back to the defaults. That way,
47
+ * the mcp works on any project that has `@payloadcms/plugin-mcp` installed,
48
+ * even if the plugin is not added to the plugins array.
49
+ */
50
+ let pluginConfig: SanitizedMCPPluginConfig
51
+ try {
52
+ pluginConfig = getPluginConfig({ config: payload.config })
53
+ } catch {
54
+ pluginConfig = sanitizeMCPConfig({ config: payload.config, pluginConfig: {} })
55
+
56
+ const fakePluginFn: Plugin = (config) => config
57
+ fakePluginFn.slug = '@payloadcms/plugin-mcp'
58
+ // @ts-expect-error
59
+ fakePluginFn.sanitizedOptions = pluginConfig
60
+
61
+ // Push to payload config, to ensure consecutive calls to `getPluginConfig()` work
62
+ ;(payload.config.plugins ??= []).push(fakePluginFn)
63
+ }
64
+
65
+ const authorizedMCP: AuthorizedMCP = {
66
+ items: pluginConfig.items,
67
+ overrideAccess: true,
68
+ user: null,
69
+ }
70
+
71
+ const req = await createLocalReq({}, payload)
72
+ req.payloadAPI = 'MCP' as const
73
+
74
+ const server = buildMcpServer({ authorizedMCP, pluginConfig, req })
75
+
76
+ const transport = new StdioServerTransport()
77
+ await server.connect(transport)
78
+
79
+ // Process now lives until stdin closes. Wire graceful shutdown so DB
80
+ // connections (and any other Payload-managed resources) get released.
81
+ const shutdown = async (code = 0) => {
82
+ try {
83
+ await server.close()
84
+ } catch (err) {
85
+ console.error('[payload-mcp] error closing server:', err)
86
+ }
87
+ try {
88
+ await payload.destroy()
89
+ } catch (err) {
90
+ console.error('[payload-mcp] error destroying payload:', err)
91
+ }
92
+ process.exit(code)
93
+ }
94
+
95
+ process.on('SIGINT', () => void shutdown(0))
96
+ process.on('SIGTERM', () => void shutdown(0))
97
+ process.stdin.on('close', () => void shutdown(0))
98
+ }