@payloadcms/plugin-mcp 4.0.0-canary.1 → 4.0.0-canary.2

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 (278) hide show
  1. package/dist/collection/getAccessField.d.ts.map +1 -1
  2. package/dist/collection/getAccessField.js +24 -9
  3. package/dist/collection/getAccessField.js.map +1 -1
  4. package/dist/collection/index.d.ts.map +1 -1
  5. package/dist/collection/index.js +71 -26
  6. package/dist/collection/index.js.map +1 -1
  7. package/dist/components/APIKeyField/index.client.d.ts +9 -0
  8. package/dist/components/APIKeyField/index.client.d.ts.map +1 -0
  9. package/dist/components/APIKeyField/index.client.js +85 -0
  10. package/dist/components/APIKeyField/index.client.js.map +1 -0
  11. package/dist/components/APIKeyField/index.css +105 -0
  12. package/dist/components/APIKeysEmptyState/index.client.d.ts +4 -0
  13. package/dist/components/APIKeysEmptyState/index.client.d.ts.map +1 -0
  14. package/dist/components/APIKeysEmptyState/index.client.js +21 -0
  15. package/dist/components/APIKeysEmptyState/index.client.js.map +1 -0
  16. package/dist/components/AccessField/index.client.d.ts.map +1 -1
  17. package/dist/components/AccessField/index.client.js +139 -197
  18. package/dist/components/AccessField/index.client.js.map +1 -1
  19. package/dist/components/AccessField/index.css +50 -44
  20. package/dist/components/SettingsMenu/index.client.d.ts +8 -0
  21. package/dist/components/SettingsMenu/index.client.d.ts.map +1 -0
  22. package/dist/components/SettingsMenu/index.client.js +29 -0
  23. package/dist/components/SettingsMenu/index.client.js.map +1 -0
  24. package/dist/endpoint/access.js +16 -0
  25. package/dist/endpoint/access.js.map +1 -1
  26. package/dist/exports/client.d.ts +3 -0
  27. package/dist/exports/client.d.ts.map +1 -1
  28. package/dist/exports/client.js +3 -0
  29. package/dist/exports/client.js.map +1 -1
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +46 -3
  32. package/dist/index.js.map +1 -1
  33. package/dist/translations/index.d.ts +11 -0
  34. package/dist/translations/index.d.ts.map +1 -0
  35. package/dist/translations/index.js +92 -0
  36. package/dist/translations/index.js.map +1 -0
  37. package/dist/translations/languages/ar.d.ts +31 -0
  38. package/dist/translations/languages/ar.d.ts.map +1 -0
  39. package/dist/translations/languages/ar.js +34 -0
  40. package/dist/translations/languages/ar.js.map +1 -0
  41. package/dist/translations/languages/az.d.ts +31 -0
  42. package/dist/translations/languages/az.d.ts.map +1 -0
  43. package/dist/translations/languages/az.js +34 -0
  44. package/dist/translations/languages/az.js.map +1 -0
  45. package/dist/translations/languages/bg.d.ts +31 -0
  46. package/dist/translations/languages/bg.d.ts.map +1 -0
  47. package/dist/translations/languages/bg.js +34 -0
  48. package/dist/translations/languages/bg.js.map +1 -0
  49. package/dist/translations/languages/bnBd.d.ts +31 -0
  50. package/dist/translations/languages/bnBd.d.ts.map +1 -0
  51. package/dist/translations/languages/bnBd.js +34 -0
  52. package/dist/translations/languages/bnBd.js.map +1 -0
  53. package/dist/translations/languages/bnIn.d.ts +31 -0
  54. package/dist/translations/languages/bnIn.d.ts.map +1 -0
  55. package/dist/translations/languages/bnIn.js +34 -0
  56. package/dist/translations/languages/bnIn.js.map +1 -0
  57. package/dist/translations/languages/ca.d.ts +31 -0
  58. package/dist/translations/languages/ca.d.ts.map +1 -0
  59. package/dist/translations/languages/ca.js +34 -0
  60. package/dist/translations/languages/ca.js.map +1 -0
  61. package/dist/translations/languages/cs.d.ts +31 -0
  62. package/dist/translations/languages/cs.d.ts.map +1 -0
  63. package/dist/translations/languages/cs.js +34 -0
  64. package/dist/translations/languages/cs.js.map +1 -0
  65. package/dist/translations/languages/da.d.ts +31 -0
  66. package/dist/translations/languages/da.d.ts.map +1 -0
  67. package/dist/translations/languages/da.js +34 -0
  68. package/dist/translations/languages/da.js.map +1 -0
  69. package/dist/translations/languages/de.d.ts +31 -0
  70. package/dist/translations/languages/de.d.ts.map +1 -0
  71. package/dist/translations/languages/de.js +34 -0
  72. package/dist/translations/languages/de.js.map +1 -0
  73. package/dist/translations/languages/en.d.ts +31 -0
  74. package/dist/translations/languages/en.d.ts.map +1 -0
  75. package/dist/translations/languages/en.js +34 -0
  76. package/dist/translations/languages/en.js.map +1 -0
  77. package/dist/translations/languages/es.d.ts +31 -0
  78. package/dist/translations/languages/es.d.ts.map +1 -0
  79. package/dist/translations/languages/es.js +34 -0
  80. package/dist/translations/languages/es.js.map +1 -0
  81. package/dist/translations/languages/et.d.ts +31 -0
  82. package/dist/translations/languages/et.d.ts.map +1 -0
  83. package/dist/translations/languages/et.js +34 -0
  84. package/dist/translations/languages/et.js.map +1 -0
  85. package/dist/translations/languages/fa.d.ts +31 -0
  86. package/dist/translations/languages/fa.d.ts.map +1 -0
  87. package/dist/translations/languages/fa.js +34 -0
  88. package/dist/translations/languages/fa.js.map +1 -0
  89. package/dist/translations/languages/fr.d.ts +31 -0
  90. package/dist/translations/languages/fr.d.ts.map +1 -0
  91. package/dist/translations/languages/fr.js +34 -0
  92. package/dist/translations/languages/fr.js.map +1 -0
  93. package/dist/translations/languages/he.d.ts +31 -0
  94. package/dist/translations/languages/he.d.ts.map +1 -0
  95. package/dist/translations/languages/he.js +34 -0
  96. package/dist/translations/languages/he.js.map +1 -0
  97. package/dist/translations/languages/hr.d.ts +31 -0
  98. package/dist/translations/languages/hr.d.ts.map +1 -0
  99. package/dist/translations/languages/hr.js +34 -0
  100. package/dist/translations/languages/hr.js.map +1 -0
  101. package/dist/translations/languages/hu.d.ts +31 -0
  102. package/dist/translations/languages/hu.d.ts.map +1 -0
  103. package/dist/translations/languages/hu.js +34 -0
  104. package/dist/translations/languages/hu.js.map +1 -0
  105. package/dist/translations/languages/hy.d.ts +31 -0
  106. package/dist/translations/languages/hy.d.ts.map +1 -0
  107. package/dist/translations/languages/hy.js +34 -0
  108. package/dist/translations/languages/hy.js.map +1 -0
  109. package/dist/translations/languages/id.d.ts +31 -0
  110. package/dist/translations/languages/id.d.ts.map +1 -0
  111. package/dist/translations/languages/id.js +34 -0
  112. package/dist/translations/languages/id.js.map +1 -0
  113. package/dist/translations/languages/is.d.ts +31 -0
  114. package/dist/translations/languages/is.d.ts.map +1 -0
  115. package/dist/translations/languages/is.js +34 -0
  116. package/dist/translations/languages/is.js.map +1 -0
  117. package/dist/translations/languages/it.d.ts +31 -0
  118. package/dist/translations/languages/it.d.ts.map +1 -0
  119. package/dist/translations/languages/it.js +34 -0
  120. package/dist/translations/languages/it.js.map +1 -0
  121. package/dist/translations/languages/ja.d.ts +31 -0
  122. package/dist/translations/languages/ja.d.ts.map +1 -0
  123. package/dist/translations/languages/ja.js +34 -0
  124. package/dist/translations/languages/ja.js.map +1 -0
  125. package/dist/translations/languages/ko.d.ts +31 -0
  126. package/dist/translations/languages/ko.d.ts.map +1 -0
  127. package/dist/translations/languages/ko.js +34 -0
  128. package/dist/translations/languages/ko.js.map +1 -0
  129. package/dist/translations/languages/lt.d.ts +31 -0
  130. package/dist/translations/languages/lt.d.ts.map +1 -0
  131. package/dist/translations/languages/lt.js +34 -0
  132. package/dist/translations/languages/lt.js.map +1 -0
  133. package/dist/translations/languages/lv.d.ts +31 -0
  134. package/dist/translations/languages/lv.d.ts.map +1 -0
  135. package/dist/translations/languages/lv.js +34 -0
  136. package/dist/translations/languages/lv.js.map +1 -0
  137. package/dist/translations/languages/my.d.ts +31 -0
  138. package/dist/translations/languages/my.d.ts.map +1 -0
  139. package/dist/translations/languages/my.js +34 -0
  140. package/dist/translations/languages/my.js.map +1 -0
  141. package/dist/translations/languages/nb.d.ts +31 -0
  142. package/dist/translations/languages/nb.d.ts.map +1 -0
  143. package/dist/translations/languages/nb.js +34 -0
  144. package/dist/translations/languages/nb.js.map +1 -0
  145. package/dist/translations/languages/nl.d.ts +31 -0
  146. package/dist/translations/languages/nl.d.ts.map +1 -0
  147. package/dist/translations/languages/nl.js +34 -0
  148. package/dist/translations/languages/nl.js.map +1 -0
  149. package/dist/translations/languages/pl.d.ts +31 -0
  150. package/dist/translations/languages/pl.d.ts.map +1 -0
  151. package/dist/translations/languages/pl.js +34 -0
  152. package/dist/translations/languages/pl.js.map +1 -0
  153. package/dist/translations/languages/pt.d.ts +31 -0
  154. package/dist/translations/languages/pt.d.ts.map +1 -0
  155. package/dist/translations/languages/pt.js +34 -0
  156. package/dist/translations/languages/pt.js.map +1 -0
  157. package/dist/translations/languages/ro.d.ts +31 -0
  158. package/dist/translations/languages/ro.d.ts.map +1 -0
  159. package/dist/translations/languages/ro.js +34 -0
  160. package/dist/translations/languages/ro.js.map +1 -0
  161. package/dist/translations/languages/rs.d.ts +31 -0
  162. package/dist/translations/languages/rs.d.ts.map +1 -0
  163. package/dist/translations/languages/rs.js +34 -0
  164. package/dist/translations/languages/rs.js.map +1 -0
  165. package/dist/translations/languages/rsLatin.d.ts +31 -0
  166. package/dist/translations/languages/rsLatin.d.ts.map +1 -0
  167. package/dist/translations/languages/rsLatin.js +34 -0
  168. package/dist/translations/languages/rsLatin.js.map +1 -0
  169. package/dist/translations/languages/ru.d.ts +31 -0
  170. package/dist/translations/languages/ru.d.ts.map +1 -0
  171. package/dist/translations/languages/ru.js +34 -0
  172. package/dist/translations/languages/ru.js.map +1 -0
  173. package/dist/translations/languages/sk.d.ts +31 -0
  174. package/dist/translations/languages/sk.d.ts.map +1 -0
  175. package/dist/translations/languages/sk.js +34 -0
  176. package/dist/translations/languages/sk.js.map +1 -0
  177. package/dist/translations/languages/sl.d.ts +31 -0
  178. package/dist/translations/languages/sl.d.ts.map +1 -0
  179. package/dist/translations/languages/sl.js +34 -0
  180. package/dist/translations/languages/sl.js.map +1 -0
  181. package/dist/translations/languages/sv.d.ts +31 -0
  182. package/dist/translations/languages/sv.d.ts.map +1 -0
  183. package/dist/translations/languages/sv.js +34 -0
  184. package/dist/translations/languages/sv.js.map +1 -0
  185. package/dist/translations/languages/ta.d.ts +31 -0
  186. package/dist/translations/languages/ta.d.ts.map +1 -0
  187. package/dist/translations/languages/ta.js +34 -0
  188. package/dist/translations/languages/ta.js.map +1 -0
  189. package/dist/translations/languages/th.d.ts +31 -0
  190. package/dist/translations/languages/th.d.ts.map +1 -0
  191. package/dist/translations/languages/th.js +34 -0
  192. package/dist/translations/languages/th.js.map +1 -0
  193. package/dist/translations/languages/tr.d.ts +31 -0
  194. package/dist/translations/languages/tr.d.ts.map +1 -0
  195. package/dist/translations/languages/tr.js +34 -0
  196. package/dist/translations/languages/tr.js.map +1 -0
  197. package/dist/translations/languages/uk.d.ts +31 -0
  198. package/dist/translations/languages/uk.d.ts.map +1 -0
  199. package/dist/translations/languages/uk.js +34 -0
  200. package/dist/translations/languages/uk.js.map +1 -0
  201. package/dist/translations/languages/vi.d.ts +31 -0
  202. package/dist/translations/languages/vi.d.ts.map +1 -0
  203. package/dist/translations/languages/vi.js +34 -0
  204. package/dist/translations/languages/vi.js.map +1 -0
  205. package/dist/translations/languages/zh.d.ts +31 -0
  206. package/dist/translations/languages/zh.d.ts.map +1 -0
  207. package/dist/translations/languages/zh.js +34 -0
  208. package/dist/translations/languages/zh.js.map +1 -0
  209. package/dist/translations/languages/zhTw.d.ts +31 -0
  210. package/dist/translations/languages/zhTw.d.ts.map +1 -0
  211. package/dist/translations/languages/zhTw.js +34 -0
  212. package/dist/translations/languages/zhTw.js.map +1 -0
  213. package/dist/translations/types.d.ts +32 -0
  214. package/dist/translations/types.d.ts.map +1 -0
  215. package/dist/translations/types.js +3 -0
  216. package/dist/translations/types.js.map +1 -0
  217. package/dist/types.d.ts +6 -1
  218. package/dist/types.d.ts.map +1 -1
  219. package/dist/types.js.map +1 -1
  220. package/package.json +7 -6
  221. package/src/collection/getAccessField.ts +33 -13
  222. package/src/collection/index.ts +63 -22
  223. package/src/components/APIKeyField/index.client.tsx +73 -0
  224. package/src/components/APIKeyField/index.css +105 -0
  225. package/src/components/APIKeysEmptyState/index.client.tsx +36 -0
  226. package/src/components/AccessField/index.client.tsx +163 -211
  227. package/src/components/AccessField/index.css +50 -44
  228. package/src/components/SettingsMenu/index.client.tsx +34 -0
  229. package/src/endpoint/access.ts +12 -0
  230. package/src/exports/client.ts +3 -0
  231. package/src/index.ts +49 -3
  232. package/src/translations/index.ts +108 -0
  233. package/src/translations/languages/ar.ts +35 -0
  234. package/src/translations/languages/az.ts +35 -0
  235. package/src/translations/languages/bg.ts +35 -0
  236. package/src/translations/languages/bnBd.ts +35 -0
  237. package/src/translations/languages/bnIn.ts +35 -0
  238. package/src/translations/languages/ca.ts +35 -0
  239. package/src/translations/languages/cs.ts +35 -0
  240. package/src/translations/languages/da.ts +35 -0
  241. package/src/translations/languages/de.ts +35 -0
  242. package/src/translations/languages/en.ts +35 -0
  243. package/src/translations/languages/es.ts +35 -0
  244. package/src/translations/languages/et.ts +35 -0
  245. package/src/translations/languages/fa.ts +35 -0
  246. package/src/translations/languages/fr.ts +35 -0
  247. package/src/translations/languages/he.ts +35 -0
  248. package/src/translations/languages/hr.ts +35 -0
  249. package/src/translations/languages/hu.ts +35 -0
  250. package/src/translations/languages/hy.ts +35 -0
  251. package/src/translations/languages/id.ts +35 -0
  252. package/src/translations/languages/is.ts +35 -0
  253. package/src/translations/languages/it.ts +35 -0
  254. package/src/translations/languages/ja.ts +35 -0
  255. package/src/translations/languages/ko.ts +35 -0
  256. package/src/translations/languages/lt.ts +35 -0
  257. package/src/translations/languages/lv.ts +35 -0
  258. package/src/translations/languages/my.ts +35 -0
  259. package/src/translations/languages/nb.ts +35 -0
  260. package/src/translations/languages/nl.ts +35 -0
  261. package/src/translations/languages/pl.ts +35 -0
  262. package/src/translations/languages/pt.ts +35 -0
  263. package/src/translations/languages/ro.ts +35 -0
  264. package/src/translations/languages/rs.ts +35 -0
  265. package/src/translations/languages/rsLatin.ts +35 -0
  266. package/src/translations/languages/ru.ts +35 -0
  267. package/src/translations/languages/sk.ts +35 -0
  268. package/src/translations/languages/sl.ts +35 -0
  269. package/src/translations/languages/sv.ts +35 -0
  270. package/src/translations/languages/ta.ts +35 -0
  271. package/src/translations/languages/th.ts +35 -0
  272. package/src/translations/languages/tr.ts +35 -0
  273. package/src/translations/languages/uk.ts +35 -0
  274. package/src/translations/languages/vi.ts +35 -0
  275. package/src/translations/languages/zh.ts +35 -0
  276. package/src/translations/languages/zhTw.ts +35 -0
  277. package/src/translations/types.ts +34 -0
  278. package/src/types.ts +6 -1
@@ -3,32 +3,22 @@
3
3
  display: flex;
4
4
  flex-direction: column;
5
5
  gap: var(--base);
6
+ /* Breathing room below the API-key section's divider - the fields
7
+ container itself adds no gap between these two fields. */
8
+ padding-block-start: var(--spacer-4);
9
+ /* This custom field renders straight into `render-fields` (no `.field-type`
10
+ wrapper), so it must carry the standard inter-field margin itself -
11
+ otherwise the next field (e.g. an overrideApiKeyCollection field) butts
12
+ against the last card. */
13
+ margin-block-end: var(--spacer-3);
6
14
  }
7
15
 
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 {
16
+ .mcp-access-field__header {
27
17
  display: flex;
28
18
  flex-direction: column;
29
19
  }
30
20
 
31
- .mcp-access-field__section-header h4 {
21
+ .mcp-access-field__header h4 {
32
22
  margin: 0;
33
23
  color: var(--color-text);
34
24
  font-family: var(--text-heading-small-font-family);
@@ -38,7 +28,7 @@
38
28
  letter-spacing: var(--text-heading-small-letter-spacing);
39
29
  }
40
30
 
41
- .mcp-access-field__section-header p {
31
+ .mcp-access-field__header p {
42
32
  margin: 0;
43
33
  color: var(--color-text-secondary);
44
34
  font-family: var(--text-body-medium-font-family);
@@ -48,38 +38,46 @@
48
38
  letter-spacing: var(--text-body-medium-letter-spacing);
49
39
  }
50
40
 
51
- .mcp-access-field__group {
52
- margin-block-end: calc(var(--base) / 2);
41
+ .mcp-access-field__tabbed-content {
42
+ display: flex;
43
+ flex-direction: column;
53
44
  }
54
45
 
55
- .mcp-access-field__group-label {
56
- font-weight: 600;
46
+ .mcp-access-field__cards {
47
+ display: flex;
48
+ flex-direction: column;
49
+ gap: calc(var(--base) / 2);
57
50
  }
58
51
 
59
- .mcp-access-field__group-actions {
60
- display: flex;
61
- align-items: center;
62
- gap: calc(var(--base) / 6);
52
+ /* The collapsible header is pointer-events: none so clicks reach the toggle
53
+ overlay; re-enable events on the checkbox and lift it above the toggle. */
54
+ .mcp-access-field__card-checkbox {
55
+ position: relative;
56
+ z-index: 1;
57
+ display: inline-flex;
58
+ pointer-events: auto;
63
59
  }
64
60
 
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;
61
+ .mcp-access-field__leaf-group {
62
+ padding-block: calc(var(--base) / 2);
63
+ border-block-end: 1px solid var(--theme-elevation-100);
64
+ }
65
+
66
+ .mcp-access-field__leaf-group:first-child {
67
+ padding-block-start: 0;
73
68
  }
74
69
 
75
- .mcp-access-field__action:hover {
76
- color: var(--theme-text);
77
- text-decoration: underline;
70
+ .mcp-access-field__leaf-group:last-child {
71
+ border-block-end: none;
72
+ padding-block-end: 0;
78
73
  }
79
74
 
80
- .mcp-access-field__action-sep {
81
- color: var(--theme-elevation-300);
82
- font-size: 0.75rem;
75
+ .mcp-access-field__leaf-group-label {
76
+ margin: 0 0 calc(var(--base) / 2);
77
+ color: var(--color-text-secondary);
78
+ font-family: var(--text-body-medium-font-family);
79
+ font-size: var(--text-body-medium-font-size);
80
+ line-height: var(--text-body-medium-line-height);
83
81
  }
84
82
 
85
83
  .mcp-access-field__list {
@@ -88,6 +86,14 @@
88
86
  padding: 0;
89
87
  display: flex;
90
88
  flex-direction: column;
91
- gap: calc(var(--base) / 3);
89
+ gap: calc(var(--base) / 2);
90
+ }
91
+
92
+ .mcp-access-field__leaf-description {
93
+ margin: calc(var(--base) / 6) 0 0;
94
+ color: var(--color-text-secondary);
95
+ font-family: var(--text-body-medium-font-family);
96
+ font-size: var(--text-body-medium-font-size);
97
+ line-height: var(--text-body-medium-line-height);
92
98
  }
93
99
  }
@@ -0,0 +1,34 @@
1
+ 'use client'
2
+
3
+ import { PopupList, useConfig, useTranslation } from '@payloadcms/ui'
4
+ import { formatAdminURL } from 'payload/shared'
5
+ import React from 'react'
6
+
7
+ import type {
8
+ PluginMCPTranslationKeys,
9
+ PluginMCPTranslations,
10
+ } from '../../translations/index.js'
11
+
12
+ /**
13
+ * Entry in the user menu's Settings sub-popup linking to the API keys
14
+ * collection. The collection is excluded from the main nav
15
+ * (`admin.group: false`) and managed from here instead.
16
+ */
17
+ export const MCPSettingsMenu: React.FC = () => {
18
+ const { config } = useConfig()
19
+ const { t } = useTranslation<PluginMCPTranslations, PluginMCPTranslationKeys>()
20
+
21
+ return (
22
+ <PopupList.MenuItem>
23
+ <PopupList.GroupLabel label={t('plugin-mcp:mcp')} />
24
+ <PopupList.Button
25
+ href={formatAdminURL({
26
+ adminRoute: config.routes.admin,
27
+ path: '/collections/payload-mcp-api-keys',
28
+ })}
29
+ >
30
+ {t('plugin-mcp:manageAPIKeys')}
31
+ </PopupList.Button>
32
+ </PopupList.MenuItem>
33
+ )
34
+ }
@@ -121,6 +121,18 @@ const getAPIKeyDoc = async ({
121
121
  throw new UnauthorizedError()
122
122
  }
123
123
 
124
+ try {
125
+ await req.payload.db.updateOne({
126
+ id: doc.id,
127
+ collection: 'payload-mcp-api-keys',
128
+ data: { lastUsed: new Date().toISOString() },
129
+ req,
130
+ returning: false,
131
+ })
132
+ } catch (err) {
133
+ logger.warn({ err, msg: 'Failed to update MCP API key last-used timestamp' })
134
+ }
135
+
124
136
  return {
125
137
  ...doc,
126
138
  user: {
@@ -1,2 +1,5 @@
1
1
  'use client'
2
2
  export { AccessField } from '../components/AccessField/index.client.js'
3
+ export { APIKeyField } from '../components/APIKeyField/index.client.js'
4
+ export { APIKeysEmptyState } from '../components/APIKeysEmptyState/index.client.js'
5
+ export { MCPSettingsMenu } from '../components/SettingsMenu/index.client.js'
package/src/index.ts CHANGED
@@ -1,10 +1,14 @@
1
+ import type { AcceptedLanguages } from '@payloadcms/translations'
2
+
1
3
  import { defaultUserCollection, definePlugin } from 'payload'
2
4
 
5
+ import type { PluginDefaultTranslationsObject } from './translations/types.js'
3
6
  import type { AuthorizedMCP, MCPPluginConfig, SanitizedMCPPluginConfig } from './types.js'
4
7
 
5
8
  import { getAPIKeysCollection } from './collection/index.js'
6
9
  import { mcpEndpoint } from './endpoint/index.js'
7
10
  import { sanitizeMCPConfig } from './mcp/sanitizeMCPConfig.js'
11
+ import { translations } from './translations/index.js'
8
12
 
9
13
  declare module 'payload' {
10
14
  export interface PayloadRequest {
@@ -24,9 +28,8 @@ export const mcpPlugin = definePlugin<MCPPluginConfig>({
24
28
  slug: '@payloadcms/plugin-mcp',
25
29
  order: 10,
26
30
  plugin: ({ config, plugins, ...rawConfig }) => {
27
- // Our `payload-mcp-api-keys` is auth-enabled; if it'd be the only auth
28
- // collection, Payload's later sanitize would pick it as `admin.user`.
29
- // Pre-seed the default user collection to prevent that.
31
+ // If a project has no auth collection yet, add the default users collection
32
+ // so the relationship target and default `userCollection` exist.
30
33
  if (!config.admin?.user) {
31
34
  const firstCollectionWithAuth = (config.collections ?? []).find(({ auth }) => Boolean(auth))
32
35
  if (!firstCollectionWithAuth) {
@@ -45,6 +48,32 @@ export const mcpPlugin = definePlugin<MCPPluginConfig>({
45
48
 
46
49
  ;(config.collections ??= []).push(getAPIKeysCollection({ pluginConfig }))
47
50
 
51
+ if (!config.i18n) {
52
+ config.i18n = {}
53
+ }
54
+
55
+ if (!config.i18n.translations) {
56
+ config.i18n.translations = {}
57
+ }
58
+
59
+ const supportedLanguageKeys = config.i18n.supportedLanguages
60
+ ? Object.keys(config.i18n.supportedLanguages)
61
+ : ['en']
62
+
63
+ for (const lang of supportedLanguageKeys) {
64
+ const pluginEntry = translations[lang as keyof typeof translations]
65
+ if (!pluginEntry) {
66
+ continue
67
+ }
68
+
69
+ const typedLocale = lang as AcceptedLanguages
70
+ const existing = (config.i18n.translations[typedLocale] ?? {}) as Record<string, unknown>
71
+ config.i18n.translations[typedLocale] = {
72
+ ...existing,
73
+ 'plugin-mcp': pluginEntry.translations['plugin-mcp'],
74
+ } as PluginDefaultTranslationsObject
75
+ }
76
+
48
77
  // Keep the API-keys collection registered even when disabled, so DB schema
49
78
  // and generated types don't drift between enabled/disabled environments.
50
79
  if (pluginConfig.disabled) {
@@ -53,10 +82,27 @@ export const mcpPlugin = definePlugin<MCPPluginConfig>({
53
82
 
54
83
  return {
55
84
  ...config,
85
+ admin: {
86
+ ...config.admin,
87
+ components: {
88
+ ...config.admin?.components,
89
+ userMenuSettingsItems: [
90
+ ...(config.admin?.components?.userMenuSettingsItems ?? []),
91
+ '@payloadcms/plugin-mcp/client#MCPSettingsMenu',
92
+ ],
93
+ },
94
+ },
56
95
  endpoints: [
57
96
  ...(config.endpoints ?? []),
58
97
  // Payload prefixes /api, so the full path is /api/mcp.
59
98
  { handler: mcpEndpoint, method: 'post', path: '/mcp' },
99
+ // Streamable HTTP's optional server=>client GET stream. We don't offer
100
+ // one, so answer 405 per spec-— clients then skip it cleanly
101
+ {
102
+ handler: () => new Response(null, { headers: { Allow: 'POST' }, status: 405 }),
103
+ method: 'get',
104
+ path: '/mcp',
105
+ },
60
106
  ],
61
107
  }
62
108
  },
@@ -0,0 +1,108 @@
1
+ import type {
2
+ NestedKeysStripped,
3
+ SupportedLanguages,
4
+ } from '@payloadcms/translations'
5
+
6
+ import type { PluginDefaultTranslationsObject } from './types.js'
7
+
8
+ import { ar } from './languages/ar.js'
9
+ import { az } from './languages/az.js'
10
+ import { bg } from './languages/bg.js'
11
+ import { bnBd } from './languages/bnBd.js'
12
+ import { bnIn } from './languages/bnIn.js'
13
+ import { ca } from './languages/ca.js'
14
+ import { cs } from './languages/cs.js'
15
+ import { da } from './languages/da.js'
16
+ import { de } from './languages/de.js'
17
+ import { en } from './languages/en.js'
18
+ import { es } from './languages/es.js'
19
+ import { et } from './languages/et.js'
20
+ import { fa } from './languages/fa.js'
21
+ import { fr } from './languages/fr.js'
22
+ import { he } from './languages/he.js'
23
+ import { hr } from './languages/hr.js'
24
+ import { hu } from './languages/hu.js'
25
+ import { hy } from './languages/hy.js'
26
+ import { id } from './languages/id.js'
27
+ import { is } from './languages/is.js'
28
+ import { it } from './languages/it.js'
29
+ import { ja } from './languages/ja.js'
30
+ import { ko } from './languages/ko.js'
31
+ import { lt } from './languages/lt.js'
32
+ import { lv } from './languages/lv.js'
33
+ import { my } from './languages/my.js'
34
+ import { nb } from './languages/nb.js'
35
+ import { nl } from './languages/nl.js'
36
+ import { pl } from './languages/pl.js'
37
+ import { pt } from './languages/pt.js'
38
+ import { ro } from './languages/ro.js'
39
+ import { rs } from './languages/rs.js'
40
+ import { rsLatin } from './languages/rsLatin.js'
41
+ import { ru } from './languages/ru.js'
42
+ import { sk } from './languages/sk.js'
43
+ import { sl } from './languages/sl.js'
44
+ import { sv } from './languages/sv.js'
45
+ import { ta } from './languages/ta.js'
46
+ import { th } from './languages/th.js'
47
+ import { tr } from './languages/tr.js'
48
+ import { uk } from './languages/uk.js'
49
+ import { vi } from './languages/vi.js'
50
+ import { zh } from './languages/zh.js'
51
+ import { zhTw } from './languages/zhTw.js'
52
+
53
+ export const translations = {
54
+ id,
55
+ ar,
56
+ az,
57
+ bg,
58
+ 'bn-BD': bnBd,
59
+ 'bn-IN': bnIn,
60
+ ca,
61
+ cs,
62
+ da,
63
+ de,
64
+ en,
65
+ es,
66
+ et,
67
+ fa,
68
+ fr,
69
+ he,
70
+ hr,
71
+ hu,
72
+ hy,
73
+ is,
74
+ it,
75
+ ja,
76
+ ko,
77
+ lt,
78
+ lv,
79
+ my,
80
+ nb,
81
+ nl,
82
+ pl,
83
+ pt,
84
+ ro,
85
+ rs,
86
+ 'rs-latin': rsLatin,
87
+ ru,
88
+ sk,
89
+ sl,
90
+ sv,
91
+ ta,
92
+ th,
93
+ tr,
94
+ uk,
95
+ vi,
96
+ zh,
97
+ 'zh-TW': zhTw,
98
+ } as SupportedLanguages<PluginDefaultTranslationsObject>
99
+
100
+ export type PluginMCPTranslations = PluginDefaultTranslationsObject
101
+
102
+ export type PluginMCPTranslationKeys = NestedKeysStripped<PluginMCPTranslations>
103
+
104
+ declare module '@payloadcms/translations' {
105
+ interface CustomTranslationKeys {
106
+ 'plugin-mcp': PluginMCPTranslationKeys
107
+ }
108
+ }
@@ -0,0 +1,35 @@
1
+ import type { PluginLanguage } from '../types.js'
2
+
3
+ export const arTranslations = {
4
+ 'plugin-mcp': {
5
+ apiKeyDescription: 'تتحكم مفاتيح API في المجموعات والموارد والأدوات والمطالبات التي يمكن لعملاء MCP الوصول إليها.',
6
+ apiKeys: 'مفاتيح API',
7
+ authentication: 'المصادقة',
8
+ description: 'الوصف',
9
+ descriptionDescription: 'صف الغرض من مفتاح API.',
10
+ dismiss: 'إغلاق',
11
+ keepKeyPrivate: 'حافظ على سرية مفتاحك.',
12
+ keyPrivateDescription: 'هذا المفتاح يمنح MCP إمكانية الوصول إلى محتواك. لا تشاركه مع الآخرين!',
13
+ lastUsed: 'آخر استخدام',
14
+ manageAPIKeys: 'إدارة مفاتيح API',
15
+ mcp: 'MCP',
16
+ noAPIKeys: 'لا توجد مفاتيح API',
17
+ operations: 'العمليات',
18
+ overrideAccess: 'تجاوز التحكم في الوصول',
19
+ overrideAccessDescription: 'عند تفعيله، يتجاوز هذا المفتاح تحكم Payload في الوصول لكل عملية ينفذها. اتركه غير مفعل ما لم يكن لديك سبب محدد.',
20
+ permissions: 'الأذونات',
21
+ permissionsDescription: 'اسمح لعملاء MCP بالوصول إلى المجموعات والأدوات والموارد والمطالبات التالية.',
22
+ prompts: 'المطالبات',
23
+ resources: 'الموارد',
24
+ server: 'الخادم',
25
+ title: 'العنوان',
26
+ titleDescription: 'اسم مستعار مفيد لمفتاح API.',
27
+ tools: 'الأدوات',
28
+ userDescription: 'المستخدم الذي سيعمل MCP بصفته.',
29
+ },
30
+ }
31
+
32
+ export const ar: PluginLanguage = {
33
+ dateFNSKey: 'ar',
34
+ translations: arTranslations,
35
+ }
@@ -0,0 +1,35 @@
1
+ import type { PluginLanguage } from '../types.js'
2
+
3
+ export const azTranslations = {
4
+ 'plugin-mcp': {
5
+ apiKeyDescription: 'API açarları MCP müştərilərinin hansı kolleksiyalara, resurslara, alətlərə və promptlara daxil ola biləcəyini idarə edir.',
6
+ apiKeys: 'API açarları',
7
+ authentication: 'Autentifikasiya',
8
+ description: 'Təsvir',
9
+ descriptionDescription: 'API açarının məqsədini təsvir edin.',
10
+ dismiss: 'Bağla',
11
+ keepKeyPrivate: 'Açarınızı məxfi saxlayın.',
12
+ keyPrivateDescription: 'Bu açar MCP-yə məzmununuza giriş verir. Onu başqaları ilə paylaşmayın!',
13
+ lastUsed: 'Son istifadə',
14
+ manageAPIKeys: 'API açarlarını idarə et',
15
+ mcp: 'MCP',
16
+ noAPIKeys: 'API açarı yoxdur',
17
+ operations: 'Əməliyyatlar',
18
+ overrideAccess: 'Giriş nəzarətini keç',
19
+ overrideAccessDescription: 'İşarələndikdə bu açar icra etdiyi hər əməliyyatda Payload giriş qaydalarını keçir. Xüsusi səbəbiniz yoxdursa işarələməyin.',
20
+ permissions: 'İcazələr',
21
+ permissionsDescription: 'MCP müştərilərinə aşağıdakı kolleksiyalara, alətlərə, resurslara və promptlara giriş icazəsi verin.',
22
+ prompts: 'Promptlar',
23
+ resources: 'Resurslar',
24
+ server: 'Server',
25
+ title: 'Başlıq',
26
+ titleDescription: 'API açarı üçün faydalı qısa ad.',
27
+ tools: 'Alətlər',
28
+ userDescription: 'MCP-nin adından işləyəcəyi istifadəçi.',
29
+ },
30
+ }
31
+
32
+ export const az: PluginLanguage = {
33
+ dateFNSKey: 'az',
34
+ translations: azTranslations,
35
+ }
@@ -0,0 +1,35 @@
1
+ import type { PluginLanguage } from '../types.js'
2
+
3
+ export const bgTranslations = {
4
+ 'plugin-mcp': {
5
+ apiKeyDescription: 'API ключовете контролират до кои колекции, ресурси, инструменти и подкани имат достъп MCP клиентите.',
6
+ apiKeys: 'API ключове',
7
+ authentication: 'Удостоверяване',
8
+ description: 'Описание',
9
+ descriptionDescription: 'Опишете предназначението на API ключа.',
10
+ dismiss: 'Затвори',
11
+ keepKeyPrivate: 'Пазете ключа си поверителен.',
12
+ keyPrivateDescription: 'Този ключ дава на MCP достъп до съдържанието ви. Не го споделяйте с други!',
13
+ lastUsed: 'Последно използван',
14
+ manageAPIKeys: 'Управление на API ключове',
15
+ mcp: 'MCP',
16
+ noAPIKeys: 'Няма API ключове',
17
+ operations: 'Операции',
18
+ overrideAccess: 'Заобикаляне на контрола за достъп',
19
+ overrideAccessDescription: 'Когато е отметнато, този ключ заобикаля контрола за достъп на Payload при всяка операция. Оставете изключено, освен ако нямате конкретна причина.',
20
+ permissions: 'Разрешения',
21
+ permissionsDescription: 'Разрешете на MCP клиентите достъп до следните колекции, инструменти, ресурси и подкани.',
22
+ prompts: 'Подкани',
23
+ resources: 'Ресурси',
24
+ server: 'Сървър',
25
+ title: 'Заглавие',
26
+ titleDescription: 'Полезно име за API ключа.',
27
+ tools: 'Инструменти',
28
+ userDescription: 'Потребителят, от чието име ще действа MCP.',
29
+ },
30
+ }
31
+
32
+ export const bg: PluginLanguage = {
33
+ dateFNSKey: 'bg',
34
+ translations: bgTranslations,
35
+ }
@@ -0,0 +1,35 @@
1
+ import type { PluginLanguage } from '../types.js'
2
+
3
+ export const bnBdTranslations = {
4
+ 'plugin-mcp': {
5
+ apiKeyDescription: 'API কী নির্ধারণ করে MCP ক্লায়েন্ট কোন সংগ্রহ, রিসোর্স, টুল এবং প্রম্পটে প্রবেশ করতে পারবে।',
6
+ apiKeys: 'API কীসমূহ',
7
+ authentication: 'প্রমাণীকরণ',
8
+ description: 'বিবরণ',
9
+ descriptionDescription: 'API কী-এর উদ্দেশ্য লিখুন।',
10
+ dismiss: 'বন্ধ করুন',
11
+ keepKeyPrivate: 'আপনার কী ব্যক্তিগত রাখুন।',
12
+ keyPrivateDescription: 'এই কী MCP-কে আপনার কনটেন্টে প্রবেশাধিকার দেয়। এটি অন্যদের সাথে শেয়ার করবেন না!',
13
+ lastUsed: 'সর্বশেষ ব্যবহৃত',
14
+ manageAPIKeys: 'API কী পরিচালনা করুন',
15
+ mcp: 'MCP',
16
+ noAPIKeys: 'কোনো API কী নেই',
17
+ operations: 'অপারেশনসমূহ',
18
+ overrideAccess: 'অ্যাক্সেস নিয়ন্ত্রণ অগ্রাহ্য করুন',
19
+ overrideAccessDescription: 'চালু থাকলে, এই কী প্রতিটি অপারেশনে Payload অ্যাক্সেস নিয়ম অগ্রাহ্য করবে। নির্দিষ্ট কারণ না থাকলে বন্ধ রাখুন।',
20
+ permissions: 'অনুমতিসমূহ',
21
+ permissionsDescription: 'MCP ক্লায়েন্টকে নিচের সংগ্রহ, টুল, রিসোর্স এবং প্রম্পটে প্রবেশের অনুমতি দিন।',
22
+ prompts: 'প্রম্পটসমূহ',
23
+ resources: 'রিসোর্সসমূহ',
24
+ server: 'সার্ভার',
25
+ title: 'শিরোনাম',
26
+ titleDescription: 'API কী-এর জন্য একটি সহায়ক ডাকনাম।',
27
+ tools: 'টুলসমূহ',
28
+ userDescription: 'MCP যে ব্যবহারকারীর পক্ষ থেকে কাজ করবে।',
29
+ },
30
+ }
31
+
32
+ export const bnBd: PluginLanguage = {
33
+ dateFNSKey: 'bn-BD',
34
+ translations: bnBdTranslations,
35
+ }
@@ -0,0 +1,35 @@
1
+ import type { PluginLanguage } from '../types.js'
2
+
3
+ export const bnInTranslations = {
4
+ 'plugin-mcp': {
5
+ apiKeyDescription: 'API কী নির্ধারণ করে MCP ক্লায়েন্ট কোন সংগ্রহ, রিসোর্স, টুল এবং প্রম্পটে প্রবেশ করতে পারবে।',
6
+ apiKeys: 'API কীসমূহ',
7
+ authentication: 'প্রমাণীকরণ',
8
+ description: 'বিবরণ',
9
+ descriptionDescription: 'API কী-এর উদ্দেশ্য লিখুন।',
10
+ dismiss: 'বন্ধ করুন',
11
+ keepKeyPrivate: 'আপনার কী ব্যক্তিগত রাখুন।',
12
+ keyPrivateDescription: 'এই কী MCP-কে আপনার কনটেন্টে প্রবেশাধিকার দেয়। এটি অন্যদের সাথে শেয়ার করবেন না!',
13
+ lastUsed: 'সর্বশেষ ব্যবহৃত',
14
+ manageAPIKeys: 'API কী পরিচালনা করুন',
15
+ mcp: 'MCP',
16
+ noAPIKeys: 'কোনো API কী নেই',
17
+ operations: 'অপারেশনসমূহ',
18
+ overrideAccess: 'অ্যাক্সেস নিয়ন্ত্রণ অগ্রাহ্য করুন',
19
+ overrideAccessDescription: 'চালু থাকলে, এই কী প্রতিটি অপারেশনে Payload অ্যাক্সেস নিয়ম অগ্রাহ্য করবে। নির্দিষ্ট কারণ না থাকলে বন্ধ রাখুন।',
20
+ permissions: 'অনুমতিসমূহ',
21
+ permissionsDescription: 'MCP ক্লায়েন্টকে নিচের সংগ্রহ, টুল, রিসোর্স এবং প্রম্পটে প্রবেশের অনুমতি দিন।',
22
+ prompts: 'প্রম্পটসমূহ',
23
+ resources: 'রিসোর্সসমূহ',
24
+ server: 'সার্ভার',
25
+ title: 'শিরোনাম',
26
+ titleDescription: 'API কী-এর জন্য একটি সহায়ক ডাকনাম।',
27
+ tools: 'টুলসমূহ',
28
+ userDescription: 'MCP যে ব্যবহারকারীর পক্ষ থেকে কাজ করবে।',
29
+ },
30
+ }
31
+
32
+ export const bnIn: PluginLanguage = {
33
+ dateFNSKey: 'bn-IN',
34
+ translations: bnInTranslations,
35
+ }
@@ -0,0 +1,35 @@
1
+ import type { PluginLanguage } from '../types.js'
2
+
3
+ export const caTranslations = {
4
+ 'plugin-mcp': {
5
+ apiKeyDescription: 'Les claus API controlen a quines col·leccions, recursos, eines i prompts poden accedir els clients MCP.',
6
+ apiKeys: 'Claus API',
7
+ authentication: 'Autenticació',
8
+ description: 'Descripció',
9
+ descriptionDescription: 'Descriu el propòsit de la clau API.',
10
+ dismiss: 'Tanca',
11
+ keepKeyPrivate: 'Mantén la clau privada.',
12
+ keyPrivateDescription: 'Aquesta clau dona a MCP accés al teu contingut. No la comparteixis amb ningú!',
13
+ lastUsed: 'Darrer ús',
14
+ manageAPIKeys: 'Gestiona les claus API',
15
+ mcp: 'MCP',
16
+ noAPIKeys: 'No hi ha claus API',
17
+ operations: 'Operacions',
18
+ overrideAccess: 'Omet el control d’accés',
19
+ overrideAccessDescription: 'Quan està activat, aquesta clau omet el control d’accés de Payload en cada operació. Deixa-ho desactivat si no tens un motiu concret.',
20
+ permissions: 'Permisos',
21
+ permissionsDescription: 'Permet que els clients MCP accedeixin a les col·leccions, eines, recursos i prompts següents.',
22
+ prompts: 'Prompts',
23
+ resources: 'Recursos',
24
+ server: 'Servidor',
25
+ title: 'Títol',
26
+ titleDescription: 'Un sobrenom útil per a la clau API.',
27
+ tools: 'Eines',
28
+ userDescription: 'L’usuari en nom del qual actuarà MCP.',
29
+ },
30
+ }
31
+
32
+ export const ca: PluginLanguage = {
33
+ dateFNSKey: 'ca',
34
+ translations: caTranslations,
35
+ }
@@ -0,0 +1,35 @@
1
+ import type { PluginLanguage } from '../types.js'
2
+
3
+ export const csTranslations = {
4
+ 'plugin-mcp': {
5
+ apiKeyDescription: 'Klíče API určují, ke kterým kolekcím, zdrojům, nástrojům a promptům mají klienti MCP přístup.',
6
+ apiKeys: 'Klíče API',
7
+ authentication: 'Ověření',
8
+ description: 'Popis',
9
+ descriptionDescription: 'Popište účel klíče API.',
10
+ dismiss: 'Zavřít',
11
+ keepKeyPrivate: 'Udržujte svůj klíč v soukromí.',
12
+ keyPrivateDescription: 'Tento klíč dává MCP přístup k vašemu obsahu. Nesdílejte ho s ostatními!',
13
+ lastUsed: 'Naposledy použito',
14
+ manageAPIKeys: 'Spravovat klíče API',
15
+ mcp: 'MCP',
16
+ noAPIKeys: 'Žádné klíče API',
17
+ operations: 'Operace',
18
+ overrideAccess: 'Přepsat řízení přístupu',
19
+ overrideAccessDescription: 'Je-li zaškrtnuto, tento klíč obejde řízení přístupu Payload při každé operaci. Nechte nezaškrtnuté, pokud k tomu nemáte konkrétní důvod.',
20
+ permissions: 'Oprávnění',
21
+ permissionsDescription: 'Povolte klientům MCP přístup k následujícím kolekcím, nástrojům, zdrojům a promptům.',
22
+ prompts: 'Prompty',
23
+ resources: 'Zdroje',
24
+ server: 'Server',
25
+ title: 'Název',
26
+ titleDescription: 'Užitečná přezdívka pro klíč API.',
27
+ tools: 'Nástroje',
28
+ userDescription: 'Uživatel, za kterého bude MCP jednat.',
29
+ },
30
+ }
31
+
32
+ export const cs: PluginLanguage = {
33
+ dateFNSKey: 'cs',
34
+ translations: csTranslations,
35
+ }