@payloadcms/plugin-mcp 4.0.0-internal.38b7f1d → 4.0.0-internal.40de3ec

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,344 @@
1
+ 'use client'
2
+
3
+ import type { JSONFieldClientProps } from 'payload'
4
+
5
+ import { CheckboxInput, Collapsible, useField } from '@payloadcms/ui'
6
+ import React from 'react'
7
+
8
+ import type { ClientMCPPluginConfig, MCPAPIKeysDocAccessTree } from '../../types.js'
9
+
10
+ import './index.css'
11
+
12
+ const baseClass = 'mcp-access-field'
13
+
14
+ type ClientItem = ClientMCPPluginConfig['items'][number]
15
+ type ScopeKey = 'collections' | 'globals'
16
+ type FlatKey = 'prompts' | 'resources' | 'tools'
17
+
18
+ type Props = {
19
+ pluginConfig: ClientMCPPluginConfig
20
+ } & JSONFieldClientProps
21
+
22
+ /** Drop a key from an object and return a new object — or `undefined` if it'd be empty. */
23
+ const without = <T extends Record<string, unknown>>(
24
+ obj: T | undefined,
25
+ key: string,
26
+ ): T | undefined => {
27
+ if (!obj || !(key in obj)) {
28
+ return obj
29
+ }
30
+ const { [key]: _omitted, ...rest } = obj
31
+ return Object.keys(rest).length === 0 ? undefined : (rest as T)
32
+ }
33
+
34
+ const setKey = <T extends Record<string, unknown>>(
35
+ obj: T | undefined,
36
+ key: string,
37
+ value: unknown,
38
+ ): T => ({ ...(obj ?? {}), [key]: value }) as T
39
+
40
+ export const AccessField: React.FC<Props> = ({ path, pluginConfig }) => {
41
+ const { setValue, value } = useField<MCPAPIKeysDocAccessTree>({ path })
42
+ const access = value ?? {}
43
+
44
+ // Bucket items for rendering. (Bucketing is cheap and runs once per render;
45
+ // memoizing would mean managing inputs/refs for marginal benefit.)
46
+ const collectionsBySlug: Record<string, ClientItem[]> = {}
47
+ const globalsBySlug: Record<string, ClientItem[]> = {}
48
+ const tools: ClientItem[] = []
49
+ const prompts: ClientItem[] = []
50
+ const resources: ClientItem[] = []
51
+ for (const item of pluginConfig.items) {
52
+ switch (item.type) {
53
+ case 'collectionTool':
54
+ ;(collectionsBySlug[item.collectionSlug!] ??= []).push(item)
55
+ break
56
+ case 'globalTool':
57
+ ;(globalsBySlug[item.globalSlug!] ??= []).push(item)
58
+ break
59
+ case 'prompt':
60
+ prompts.push(item)
61
+ break
62
+ case 'resource':
63
+ resources.push(item)
64
+ break
65
+ case 'tool':
66
+ tools.push(item)
67
+ break
68
+ }
69
+ }
70
+
71
+ const isScopedAllowed = (scope: ScopeKey, slug: string, key: string): boolean =>
72
+ access[scope]?.[slug]?.[key] !== false
73
+
74
+ const isFlatAllowed = (scope: FlatKey, key: string): boolean => access[scope]?.[key] !== false
75
+
76
+ const toggleScoped = (scope: ScopeKey, slug: string, key: string, allow: boolean) => {
77
+ if (allow) {
78
+ const slugBucket = without(access[scope]?.[slug], key)
79
+ const scopeBucket = slugBucket
80
+ ? setKey(access[scope], slug, slugBucket)
81
+ : without(access[scope], slug)
82
+ setValue(scopeBucket ? setKey(access, scope, scopeBucket) : (without(access, scope) ?? {}))
83
+ } else {
84
+ setValue(
85
+ setKey(
86
+ access,
87
+ scope,
88
+ setKey(access[scope], slug, setKey(access[scope]?.[slug], key, false)),
89
+ ),
90
+ )
91
+ }
92
+ }
93
+
94
+ const toggleFlat = (scope: FlatKey, key: string, allow: boolean) => {
95
+ if (allow) {
96
+ const bucket = without(access[scope], key)
97
+ setValue(bucket ? setKey(access, scope, bucket) : (without(access, scope) ?? {}))
98
+ } else {
99
+ setValue(setKey(access, scope, setKey(access[scope], key, false)))
100
+ }
101
+ }
102
+
103
+ const setAllScoped = (scope: ScopeKey, slug: string, leaves: ClientItem[], allow: boolean) => {
104
+ if (allow) {
105
+ const scopeBucket = without(access[scope], slug)
106
+ setValue(scopeBucket ? setKey(access, scope, scopeBucket) : (without(access, scope) ?? {}))
107
+ } else {
108
+ const slugBucket = leaves.reduce<Record<string, boolean>>(
109
+ (acc, leaf) => ({ ...acc, [leaf.key]: false }),
110
+ {},
111
+ )
112
+ setValue(setKey(access, scope, setKey(access[scope], slug, slugBucket)))
113
+ }
114
+ }
115
+
116
+ const setAllFlat = (scope: FlatKey, leaves: ClientItem[], allow: boolean) => {
117
+ if (allow) {
118
+ setValue(without(access, scope) ?? {})
119
+ } else {
120
+ const bucket = leaves.reduce<Record<string, boolean>>(
121
+ (acc, leaf) => ({ ...acc, [leaf.key]: false }),
122
+ {},
123
+ )
124
+ setValue(setKey(access, scope, bucket))
125
+ }
126
+ }
127
+
128
+ const collectionSlugs = Object.keys(collectionsBySlug)
129
+ const globalSlugs = Object.keys(globalsBySlug)
130
+
131
+ return (
132
+ <div className={baseClass}>
133
+ {collectionSlugs.length > 0 && (
134
+ <section className={`${baseClass}__section`}>
135
+ <header className={`${baseClass}__section-header`}>
136
+ {/* TODO: needs i18n once design is finalized */}
137
+ <h4>Collection-level permissions</h4>
138
+ {/* TODO: needs i18n once design is finalized */}
139
+ <p>Allow MCP clients to perform the following actions within these collections:</p>
140
+ </header>
141
+ {collectionSlugs.map((slug) => {
142
+ const leaves = collectionsBySlug[slug]!
143
+ return (
144
+ <Collapsible
145
+ actions={
146
+ <GroupActions
147
+ onSetAll={(allow) => setAllScoped('collections', slug, leaves, allow)}
148
+ />
149
+ }
150
+ className={`${baseClass}__group`}
151
+ header={<span className={`${baseClass}__group-label`}>{titleCase(slug)}</span>}
152
+ initCollapsed
153
+ key={`collection-${slug}`}
154
+ >
155
+ <ul className={`${baseClass}__list`}>
156
+ {leaves.map((leaf) => (
157
+ <li key={leaf.key}>
158
+ <CheckboxInput
159
+ checked={isScopedAllowed('collections', slug, leaf.key)}
160
+ id={`${path}.collections.${slug}.${leaf.key}`}
161
+ label={leaf.label}
162
+ onToggle={(e) =>
163
+ toggleScoped('collections', slug, leaf.key, e.target.checked)
164
+ }
165
+ tooltip={leaf.description}
166
+ />
167
+ </li>
168
+ ))}
169
+ </ul>
170
+ </Collapsible>
171
+ )
172
+ })}
173
+ </section>
174
+ )}
175
+
176
+ {globalSlugs.length > 0 && (
177
+ <section className={`${baseClass}__section`}>
178
+ <header className={`${baseClass}__section-header`}>
179
+ {/* TODO: needs i18n once design is finalized */}
180
+ <h4>Global-level permissions</h4>
181
+ {/* TODO: needs i18n once design is finalized */}
182
+ <p>Allow MCP clients to perform the following actions on these globals:</p>
183
+ </header>
184
+ {globalSlugs.map((slug) => {
185
+ const leaves = globalsBySlug[slug]!
186
+ return (
187
+ <Collapsible
188
+ actions={
189
+ <GroupActions
190
+ onSetAll={(allow) => setAllScoped('globals', slug, leaves, allow)}
191
+ />
192
+ }
193
+ className={`${baseClass}__group`}
194
+ header={<span className={`${baseClass}__group-label`}>{titleCase(slug)}</span>}
195
+ initCollapsed
196
+ key={`global-${slug}`}
197
+ >
198
+ <ul className={`${baseClass}__list`}>
199
+ {leaves.map((leaf) => (
200
+ <li key={leaf.key}>
201
+ <CheckboxInput
202
+ checked={isScopedAllowed('globals', slug, leaf.key)}
203
+ id={`${path}.globals.${slug}.${leaf.key}`}
204
+ label={leaf.label}
205
+ onToggle={(e) => toggleScoped('globals', slug, leaf.key, e.target.checked)}
206
+ tooltip={leaf.description}
207
+ />
208
+ </li>
209
+ ))}
210
+ </ul>
211
+ </Collapsible>
212
+ )
213
+ })}
214
+ </section>
215
+ )}
216
+
217
+ {(tools.length > 0 || prompts.length > 0 || resources.length > 0) && (
218
+ <section className={`${baseClass}__section`}>
219
+ <header className={`${baseClass}__section-header`}>
220
+ {/* TODO: needs i18n once design is finalized */}
221
+ <h4>Project-level permissions</h4>
222
+ {/* TODO: needs i18n once design is finalized */}
223
+ <p>Cross-cutting tools, prompts, and resources not scoped to a single collection.</p>
224
+ </header>
225
+ {tools.length > 0 && (
226
+ <Collapsible
227
+ actions={<GroupActions onSetAll={(allow) => setAllFlat('tools', tools, allow)} />}
228
+ className={`${baseClass}__group`}
229
+ header={
230
+ /* TODO: needs i18n once design is finalized */
231
+ <span className={`${baseClass}__group-label`}>Tools</span>
232
+ }
233
+ initCollapsed
234
+ >
235
+ <ul className={`${baseClass}__list`}>
236
+ {tools.map((leaf) => (
237
+ <li key={leaf.key}>
238
+ <CheckboxInput
239
+ checked={isFlatAllowed('tools', leaf.key)}
240
+ id={`${path}.tools.${leaf.key}`}
241
+ label={leaf.label}
242
+ onToggle={(e) => toggleFlat('tools', leaf.key, e.target.checked)}
243
+ tooltip={leaf.description}
244
+ />
245
+ </li>
246
+ ))}
247
+ </ul>
248
+ </Collapsible>
249
+ )}
250
+ {prompts.length > 0 && (
251
+ <Collapsible
252
+ actions={<GroupActions onSetAll={(allow) => setAllFlat('prompts', prompts, allow)} />}
253
+ className={`${baseClass}__group`}
254
+ header={
255
+ /* TODO: needs i18n once design is finalized */
256
+ <span className={`${baseClass}__group-label`}>Prompts</span>
257
+ }
258
+ initCollapsed
259
+ >
260
+ <ul className={`${baseClass}__list`}>
261
+ {prompts.map((leaf) => (
262
+ <li key={leaf.key}>
263
+ <CheckboxInput
264
+ checked={isFlatAllowed('prompts', leaf.key)}
265
+ id={`${path}.prompts.${leaf.key}`}
266
+ label={leaf.label}
267
+ onToggle={(e) => toggleFlat('prompts', leaf.key, e.target.checked)}
268
+ tooltip={leaf.description}
269
+ />
270
+ </li>
271
+ ))}
272
+ </ul>
273
+ </Collapsible>
274
+ )}
275
+ {resources.length > 0 && (
276
+ <Collapsible
277
+ actions={
278
+ <GroupActions onSetAll={(allow) => setAllFlat('resources', resources, allow)} />
279
+ }
280
+ className={`${baseClass}__group`}
281
+ header={
282
+ /* TODO: needs i18n once design is finalized */
283
+ <span className={`${baseClass}__group-label`}>Resources</span>
284
+ }
285
+ initCollapsed
286
+ >
287
+ <ul className={`${baseClass}__list`}>
288
+ {resources.map((leaf) => (
289
+ <li key={leaf.key}>
290
+ <CheckboxInput
291
+ checked={isFlatAllowed('resources', leaf.key)}
292
+ id={`${path}.resources.${leaf.key}`}
293
+ label={leaf.label}
294
+ onToggle={(e) => toggleFlat('resources', leaf.key, e.target.checked)}
295
+ tooltip={leaf.description}
296
+ />
297
+ </li>
298
+ ))}
299
+ </ul>
300
+ </Collapsible>
301
+ )}
302
+ </section>
303
+ )}
304
+ </div>
305
+ )
306
+ }
307
+
308
+ const GroupActions: React.FC<{ onSetAll: (allow: boolean) => void }> = ({ onSetAll }) => (
309
+ // TODO: button labels + aria-labels need i18n once design is finalized
310
+ <div className={`${baseClass}__group-actions`}>
311
+ <button
312
+ aria-label="Select all"
313
+ className={`${baseClass}__action`}
314
+ onClick={(e) => {
315
+ e.stopPropagation()
316
+ onSetAll(true)
317
+ }}
318
+ title="Select all"
319
+ type="button"
320
+ >
321
+ all
322
+ </button>
323
+ <span aria-hidden className={`${baseClass}__action-sep`}>
324
+ /
325
+ </span>
326
+ <button
327
+ aria-label="Clear all"
328
+ className={`${baseClass}__action`}
329
+ onClick={(e) => {
330
+ e.stopPropagation()
331
+ onSetAll(false)
332
+ }}
333
+ title="Clear all"
334
+ type="button"
335
+ >
336
+ none
337
+ </button>
338
+ </div>
339
+ )
340
+
341
+ const titleCase = (slug: string): string =>
342
+ slug.replace(/(^|[-_])(.)/g, (_, sep: string, ch: string) =>
343
+ sep ? ` ${ch.toUpperCase()}` : ch.toUpperCase(),
344
+ )
@@ -0,0 +1,93 @@
1
+ @layer payload-default {
2
+ .mcp-access-field {
3
+ display: flex;
4
+ flex-direction: column;
5
+ gap: var(--base);
6
+ }
7
+
8
+ .mcp-access-field__section {
9
+ display: flex;
10
+ flex-direction: column;
11
+ gap: calc(var(--base) / 2);
12
+ padding-bottom: var(--base);
13
+ /* Full-bleed separator: extend past the sidebar's horizontal gutter so the
14
+ border-block-end spans the entire sidebar width. */
15
+ margin-inline-start: calc(-1 * var(--sidebar-gutter-h-left, var(--gutter-h)));
16
+ margin-inline-end: calc(-1 * var(--sidebar-gutter-h-right, var(--gutter-h)));
17
+ padding-inline-start: var(--sidebar-gutter-h-left, var(--gutter-h));
18
+ padding-inline-end: var(--sidebar-gutter-h-right, var(--gutter-h));
19
+ border-block-end: 1px solid var(--theme-elevation-100);
20
+ }
21
+
22
+ .mcp-access-field__section:last-child {
23
+ border-block-end: none;
24
+ }
25
+
26
+ .mcp-access-field__section-header {
27
+ display: flex;
28
+ flex-direction: column;
29
+ }
30
+
31
+ .mcp-access-field__section-header h4 {
32
+ margin: 0;
33
+ color: var(--color-text);
34
+ font-family: var(--text-heading-small-font-family);
35
+ font-size: var(--text-heading-small-font-size);
36
+ font-weight: var(--text-heading-small-font-weight);
37
+ line-height: var(--text-heading-small-line-height);
38
+ letter-spacing: var(--text-heading-small-letter-spacing);
39
+ }
40
+
41
+ .mcp-access-field__section-header p {
42
+ margin: 0;
43
+ color: var(--color-text-secondary);
44
+ font-family: var(--text-body-medium-font-family);
45
+ font-size: var(--text-body-medium-font-size);
46
+ font-weight: var(--text-body-medium-font-weight);
47
+ line-height: var(--text-body-medium-line-height);
48
+ letter-spacing: var(--text-body-medium-letter-spacing);
49
+ }
50
+
51
+ .mcp-access-field__group {
52
+ margin-block-end: calc(var(--base) / 2);
53
+ }
54
+
55
+ .mcp-access-field__group-label {
56
+ font-weight: 600;
57
+ }
58
+
59
+ .mcp-access-field__group-actions {
60
+ display: flex;
61
+ align-items: center;
62
+ gap: calc(var(--base) / 6);
63
+ }
64
+
65
+ .mcp-access-field__action {
66
+ appearance: none;
67
+ background: none;
68
+ border: none;
69
+ color: var(--theme-elevation-500);
70
+ cursor: pointer;
71
+ font-size: 0.75rem;
72
+ padding: 0;
73
+ }
74
+
75
+ .mcp-access-field__action:hover {
76
+ color: var(--theme-text);
77
+ text-decoration: underline;
78
+ }
79
+
80
+ .mcp-access-field__action-sep {
81
+ color: var(--theme-elevation-300);
82
+ font-size: 0.75rem;
83
+ }
84
+
85
+ .mcp-access-field__list {
86
+ list-style: none;
87
+ margin: 0;
88
+ padding: 0;
89
+ display: flex;
90
+ flex-direction: column;
91
+ gap: calc(var(--base) / 3);
92
+ }
93
+ }
@@ -0,0 +1,44 @@
1
+ import type { CollectionTool, GlobalTool, Prompt, Tool, ToolInputSchema } from './types.js'
2
+
3
+ /**
4
+ * Two-stage builder: pass the schema/metadata first, then chain `.handler(fn)`. Splitting the
5
+ * call lets TypeScript resolve `TSchema` from `input` (call 1) before contextually typing the
6
+ * handler (call 2). A single-call API hit a TS limitation where property order in the literal
7
+ * decided whether `TSchema` was inferred or pinned to its default.
8
+ *
9
+ * defineCollectionTool({ description, input })
10
+ * .handler(({ input }) => …) // ← input is fully typed here regardless of order
11
+ *
12
+ * Config and handler signatures are derived from `Tool` / `CollectionTool` / `GlobalTool` /
13
+ * `Prompt` via `Omit` + indexed access so there's no duplication with `types.ts`.
14
+ */
15
+
16
+ export const defineTool = <
17
+ TSchema extends ToolInputSchema | undefined = ToolInputSchema | undefined,
18
+ >(
19
+ args: Omit<Tool<TSchema>, 'handler'>,
20
+ ): { handler: (fn: Tool<TSchema>['handler']) => Tool } => ({
21
+ handler: (fn) => ({ ...args, handler: fn }) as unknown as Tool,
22
+ })
23
+
24
+ export const defineCollectionTool = <
25
+ TSchema extends ToolInputSchema | undefined = ToolInputSchema | undefined,
26
+ >(
27
+ args: Omit<CollectionTool<TSchema>, 'handler'>,
28
+ ): { handler: (fn: CollectionTool<TSchema>['handler']) => CollectionTool } => ({
29
+ handler: (fn) => ({ ...args, handler: fn }) as unknown as CollectionTool,
30
+ })
31
+
32
+ export const defineGlobalTool = <
33
+ TSchema extends ToolInputSchema | undefined = ToolInputSchema | undefined,
34
+ >(
35
+ args: Omit<GlobalTool<TSchema>, 'handler'>,
36
+ ): { handler: (fn: GlobalTool<TSchema>['handler']) => GlobalTool } => ({
37
+ handler: (fn) => ({ ...args, handler: fn }) as unknown as GlobalTool,
38
+ })
39
+
40
+ export const definePrompt = <TSchema extends ToolInputSchema = ToolInputSchema>(
41
+ args: Omit<Prompt<TSchema>, 'handler'>,
42
+ ): { handler: (fn: Prompt<TSchema>['handler']) => Prompt } => ({
43
+ handler: (fn) => ({ ...args, handler: fn }) as unknown as Prompt,
44
+ })
@@ -0,0 +1,132 @@
1
+ import type { DefaultDocumentIDType, PayloadRequest, TypedUser } from 'payload'
2
+
3
+ import crypto from 'crypto'
4
+ import { UnauthorizedError } from 'payload'
5
+
6
+ import type { AuthorizedMCP, MCPAPIKeysDoc } from '../types.js'
7
+
8
+ import { getLogger } from '../utils/getLogger.js'
9
+ import { getPluginConfig } from '../utils/getPluginConfig.js'
10
+
11
+ /**
12
+ * Resolves the API key (or dev-mode session) and returns the items the caller
13
+ * may use. Denied items are dropped from the array.
14
+ */
15
+ export const getAuthorizedMCP: (args: { req: PayloadRequest }) => Promise<AuthorizedMCP> = async ({
16
+ req,
17
+ }) => {
18
+ const logger = getLogger({ payload: req.payload })
19
+ const pluginConfig = getPluginConfig({ config: req.payload.config })
20
+
21
+ const authHeader = req.headers.get('Authorization')
22
+ const hasBearerToken = authHeader?.startsWith('Bearer ')
23
+
24
+ const buildAuthorized = (apiKeyDoc: MCPAPIKeysDoc): AuthorizedMCP => ({
25
+ items: pluginConfig.items.filter((item) => {
26
+ switch (item.type) {
27
+ case 'collectionTool':
28
+ return apiKeyDoc.access.collections?.[item.collectionSlug]?.[item.key] !== false
29
+ case 'globalTool':
30
+ return apiKeyDoc.access.globals?.[item.globalSlug]?.[item.key] !== false
31
+ case 'prompt':
32
+ return apiKeyDoc.access.prompts?.[item.key] !== false
33
+ case 'resource':
34
+ return apiKeyDoc.access.resources?.[item.key] !== false
35
+ case 'tool':
36
+ return apiKeyDoc.access.tools?.[item.key] !== false
37
+ }
38
+ }),
39
+ overrideAccess:
40
+ typeof apiKeyDoc.overrideAccess === 'boolean' ? apiKeyDoc.overrideAccess : false,
41
+ user: apiKeyDoc.user,
42
+ })
43
+
44
+ if (pluginConfig.overrideAuth) {
45
+ return await pluginConfig.overrideAuth({
46
+ getAPIKeyDoc: (overrideApiKey) => getAPIKeyDoc({ logger, overrideApiKey, pluginConfig, req }),
47
+ getAuthorizedMCP: ({ apiKeyDoc }) => buildAuthorized(apiKeyDoc),
48
+ pluginConfig,
49
+ req,
50
+ })
51
+ }
52
+
53
+ if (process.env.NODE_ENV === 'development' && !hasBearerToken) {
54
+ logger.info('Dev mode: skipping API key check, using session user')
55
+ return buildAuthorized({
56
+ id: -1,
57
+ access: {},
58
+ overrideAccess: true,
59
+ user: req.user ?? null,
60
+ })
61
+ }
62
+
63
+ return buildAuthorized(await getAPIKeyDoc({ logger, pluginConfig, req }))
64
+ }
65
+
66
+ const getAPIKeyDoc = async ({
67
+ logger,
68
+ overrideApiKey,
69
+ pluginConfig,
70
+ req,
71
+ }: {
72
+ logger: ReturnType<typeof getLogger>
73
+ overrideApiKey?: string
74
+ pluginConfig: ReturnType<typeof getPluginConfig>
75
+ req: PayloadRequest
76
+ }): Promise<MCPAPIKeysDoc> => {
77
+ const authHeader = req.headers.get('Authorization')
78
+ const hasBearerToken = authHeader?.startsWith('Bearer ')
79
+
80
+ const apiKey =
81
+ overrideApiKey ?? (hasBearerToken ? authHeader?.replace('Bearer ', '').trim() || null : null)
82
+
83
+ if (!apiKey) {
84
+ throw new UnauthorizedError()
85
+ }
86
+
87
+ const sha256APIKeyIndex = crypto
88
+ .createHmac('sha256', req.payload.secret)
89
+ .update(apiKey)
90
+ .digest('hex')
91
+
92
+ const doc = await req.payload.db.findOne<MCPAPIKeysDoc>({
93
+ collection: 'payload-mcp-api-keys',
94
+ req,
95
+ where: {
96
+ apiKeyIndex: { equals: sha256APIKeyIndex },
97
+ },
98
+ })
99
+
100
+ if (!doc || !doc.user) {
101
+ throw new UnauthorizedError()
102
+ }
103
+
104
+ logger.info('API Key is valid')
105
+
106
+ const userRef = doc.user
107
+ const userID =
108
+ typeof userRef === 'object' && userRef !== null && 'id' in userRef
109
+ ? userRef.id
110
+ : (userRef as unknown as DefaultDocumentIDType)
111
+
112
+ const user = (await req.payload.findByID({
113
+ id: userID,
114
+ collection: pluginConfig.userCollection,
115
+ depth: 0,
116
+ disableErrors: true,
117
+ req,
118
+ })) as null | TypedUser
119
+
120
+ if (!user) {
121
+ throw new UnauthorizedError()
122
+ }
123
+
124
+ return {
125
+ ...doc,
126
+ user: {
127
+ ...user,
128
+ _strategy: 'mcp-api-key' as const,
129
+ collection: pluginConfig.userCollection,
130
+ },
131
+ }
132
+ }
@@ -0,0 +1,35 @@
1
+ import { WebStandardStreamableHTTPServerTransport } from '@modelcontextprotocol/server'
2
+ import { APIError, type PayloadHandler } from 'payload'
3
+
4
+ import { buildMcpServer } from '../mcp/buildMcpServer.js'
5
+ import { getPluginConfig } from '../utils/getPluginConfig.js'
6
+ import { getAuthorizedMCP } from './access.js'
7
+
8
+ export const mcpEndpoint: PayloadHandler = async (req) => {
9
+ if (!req.url) {
10
+ throw new APIError('Missing request URL', 400)
11
+ }
12
+
13
+ req.payloadAPI = 'MCP' as const
14
+
15
+ const pluginConfig = getPluginConfig({ config: req.payload.config })
16
+ const authorizedMCP = await getAuthorizedMCP({ req })
17
+
18
+ const server = buildMcpServer({ authorizedMCP, pluginConfig, req })
19
+
20
+ const transport = new WebStandardStreamableHTTPServerTransport({
21
+ enableJsonResponse: true,
22
+ sessionIdGenerator: undefined, // stateless mode
23
+ })
24
+
25
+ await server.connect(transport)
26
+
27
+ const mcpRequest = new Request(req.url, {
28
+ body: req.body,
29
+ duplex: 'half',
30
+ headers: req.headers,
31
+ method: req.method,
32
+ } as { duplex: 'half' } & RequestInit)
33
+
34
+ return await transport.handleRequest(mcpRequest)
35
+ }
@@ -0,0 +1,2 @@
1
+ 'use client'
2
+ export { AccessField } from '../components/AccessField/index.client.js'