@payloadcms/plugin-mcp 3.91.0-internal.c1569dc → 3.92.0

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 (33) hide show
  1. package/dist/mcp/tools/auth/auth.d.ts.map +1 -1
  2. package/dist/mcp/tools/auth/auth.js +3 -9
  3. package/dist/mcp/tools/auth/auth.js.map +1 -1
  4. package/dist/mcp/tools/auth/auth.spec.js +2 -2
  5. package/dist/mcp/tools/auth/auth.spec.js.map +1 -1
  6. package/dist/mcp/tools/global/find.d.ts.map +1 -1
  7. package/dist/mcp/tools/global/find.js +8 -22
  8. package/dist/mcp/tools/global/find.js.map +1 -1
  9. package/dist/mcp/tools/global/update.d.ts.map +1 -1
  10. package/dist/mcp/tools/global/update.js +3 -20
  11. package/dist/mcp/tools/global/update.js.map +1 -1
  12. package/dist/mcp/tools/resource/create.d.ts.map +1 -1
  13. package/dist/mcp/tools/resource/create.js +3 -20
  14. package/dist/mcp/tools/resource/create.js.map +1 -1
  15. package/dist/mcp/tools/resource/find.d.ts.map +1 -1
  16. package/dist/mcp/tools/resource/find.js +28 -25
  17. package/dist/mcp/tools/resource/find.js.map +1 -1
  18. package/dist/mcp/tools/resource/update.d.ts.map +1 -1
  19. package/dist/mcp/tools/resource/update.js +5 -22
  20. package/dist/mcp/tools/resource/update.js.map +1 -1
  21. package/dist/mcp/tools/schemas.d.ts +33 -18
  22. package/dist/mcp/tools/schemas.d.ts.map +1 -1
  23. package/dist/mcp/tools/schemas.js +14 -6
  24. package/dist/mcp/tools/schemas.js.map +1 -1
  25. package/package.json +3 -3
  26. package/src/mcp/tools/auth/auth.spec.ts +2 -2
  27. package/src/mcp/tools/auth/auth.ts +4 -10
  28. package/src/mcp/tools/global/find.ts +10 -24
  29. package/src/mcp/tools/global/update.ts +6 -24
  30. package/src/mcp/tools/resource/create.ts +5 -24
  31. package/src/mcp/tools/resource/find.ts +35 -25
  32. package/src/mcp/tools/resource/update.ts +6 -25
  33. package/src/mcp/tools/schemas.ts +38 -14
@@ -1,5 +1,5 @@
1
1
  import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
2
- import type { PayloadRequest, SelectType, TypedUser } from 'payload'
2
+ import type { PayloadRequest, PopulateType, SelectType, TypedUser } from 'payload'
3
3
 
4
4
  import type { MCPPluginConfig } from '../../../types.js'
5
5
 
@@ -18,7 +18,8 @@ export const findGlobalTool = (
18
18
  depth: number = 0,
19
19
  locale?: string,
20
20
  fallbackLocale?: string,
21
- select?: string,
21
+ select?: Record<string, unknown>,
22
+ populate?: Record<string, unknown>,
22
23
  ): Promise<{
23
24
  content: Array<{
24
25
  text: string
@@ -42,24 +43,6 @@ export const findGlobalTool = (
42
43
  user,
43
44
  }
44
45
 
45
- let selectClause: SelectType | undefined
46
- if (select) {
47
- try {
48
- selectClause = JSON.parse(select) as SelectType
49
- } catch (_parseError) {
50
- payload.logger.warn(`[payload-mcp] Invalid select clause JSON for global: ${select}`)
51
- const response = {
52
- content: [{ type: 'text' as const, text: 'Error: Invalid JSON in select clause' }],
53
- }
54
- return (globals?.[globalSlug]?.overrideResponse?.(response, {}, req) || response) as {
55
- content: Array<{
56
- text: string
57
- type: 'text'
58
- }>
59
- }
60
- }
61
- }
62
-
63
46
  // Add locale parameters if provided
64
47
  if (locale) {
65
48
  findOptions.locale = locale
@@ -67,8 +50,11 @@ export const findGlobalTool = (
67
50
  if (fallbackLocale) {
68
51
  findOptions.fallbackLocale = fallbackLocale
69
52
  }
70
- if (selectClause) {
71
- findOptions.select = selectClause
53
+ if (select) {
54
+ findOptions.select = select as SelectType
55
+ }
56
+ if (populate) {
57
+ findOptions.populate = populate as PopulateType
72
58
  }
73
59
 
74
60
  const result = await payload.findGlobal(findOptions)
@@ -122,8 +108,8 @@ ${JSON.stringify(result)}
122
108
  description: `${toolSchemas.findGlobal.description.trim()}\n\n${globals?.[globalSlug]?.description || ''}`,
123
109
  inputSchema: toolSchemas.findGlobal.parameters.shape,
124
110
  },
125
- async ({ depth, fallbackLocale, locale, select }) => {
126
- return await tool(depth, locale, fallbackLocale, select)
111
+ async ({ depth, fallbackLocale, locale, populate, select }) => {
112
+ return await tool(depth, locale, fallbackLocale, select, populate)
127
113
  },
128
114
  )
129
115
  }
@@ -29,7 +29,7 @@ export const updateGlobalTool = (
29
29
  depth: number = 0,
30
30
  locale?: string,
31
31
  fallbackLocale?: string,
32
- select?: string,
32
+ select?: Record<string, unknown>,
33
33
  ): Promise<{
34
34
  content: Array<{
35
35
  text: string
@@ -71,24 +71,6 @@ export const updateGlobalTool = (
71
71
  }
72
72
  }
73
73
 
74
- let selectClause: SelectType | undefined
75
- if (select) {
76
- try {
77
- selectClause = JSON.parse(select) as SelectType
78
- } catch (_parseError) {
79
- payload.logger.warn(`[payload-mcp] Invalid select clause JSON for global: ${select}`)
80
- const response = {
81
- content: [{ type: 'text' as const, text: 'Error: Invalid JSON in select clause' }],
82
- }
83
- return (globals?.[globalSlug]?.overrideResponse?.(response, {}, req) || response) as {
84
- content: Array<{
85
- text: string
86
- type: 'text'
87
- }>
88
- }
89
- }
90
- }
91
-
92
74
  const updateOptions: Parameters<typeof payload.updateGlobal>[0] = {
93
75
  slug: globalSlug,
94
76
  data: parsedData,
@@ -106,8 +88,8 @@ export const updateGlobalTool = (
106
88
  if (fallbackLocale) {
107
89
  updateOptions.fallbackLocale = fallbackLocale
108
90
  }
109
- if (selectClause) {
110
- updateOptions.select = selectClause
91
+ if (select) {
92
+ updateOptions.select = select as SelectType
111
93
  }
112
94
 
113
95
  const result = await payload.updateGlobal(updateOptions)
@@ -179,10 +161,10 @@ ${JSON.stringify(result)}
179
161
  'Optional: locale code to update data in (e.g., "en", "es"). Use "all" to update all locales for localized fields',
180
162
  ),
181
163
  select: z
182
- .string()
164
+ .record(z.string(), z.unknown())
183
165
  .optional()
184
166
  .describe(
185
- 'Optional: define exactly which fields you\'d like to return in the response (JSON), e.g., \'{"siteName": "My Site"}\'',
167
+ "Optional: define exactly which fields you'd like to return in the response, e.g., {\"siteName\": true}",
186
168
  ),
187
169
  })
188
170
 
@@ -201,7 +183,7 @@ ${JSON.stringify(result)}
201
183
  depth as number,
202
184
  locale as string,
203
185
  fallbackLocale as string,
204
- select as string | undefined,
186
+ select as Record<string, unknown> | undefined,
205
187
  )
206
188
  },
207
189
  )
@@ -29,7 +29,7 @@ export const createResourceTool = (
29
29
  draft: boolean,
30
30
  locale?: string,
31
31
  fallbackLocale?: string,
32
- select?: string,
32
+ select?: Record<string, unknown>,
33
33
  ): Promise<{
34
34
  content: Array<{
35
35
  text: string
@@ -68,25 +68,6 @@ export const createResourceTool = (
68
68
  }
69
69
  }
70
70
 
71
- let selectClause: SelectType | undefined
72
- if (select) {
73
- try {
74
- selectClause = JSON.parse(select) as SelectType
75
- } catch (_parseError) {
76
- payload.logger.warn(`[payload-mcp] Invalid select clause JSON: ${select}`)
77
- const response = {
78
- content: [{ type: 'text' as const, text: 'Error: Invalid JSON in select clause' }],
79
- }
80
- return (collections?.[collectionSlug]?.overrideResponse?.(response, {}, req) ||
81
- response) as {
82
- content: Array<{
83
- text: string
84
- type: 'text'
85
- }>
86
- }
87
- }
88
- }
89
-
90
71
  // Create the resource
91
72
  const result = await payload.create({
92
73
  collection: collectionSlug,
@@ -98,7 +79,7 @@ export const createResourceTool = (
98
79
  user,
99
80
  ...(locale && { locale }),
100
81
  ...(fallbackLocale && { fallbackLocale }),
101
- ...(selectClause && { select: selectClause }),
82
+ ...(select && { select: select as SelectType }),
102
83
  })
103
84
 
104
85
  if (verboseLogs) {
@@ -181,10 +162,10 @@ ${JSON.stringify(result)}
181
162
  'Optional: locale code to create the document in (e.g., "en", "es"). Defaults to the default locale',
182
163
  ),
183
164
  select: z
184
- .string()
165
+ .record(z.string(), z.unknown())
185
166
  .optional()
186
167
  .describe(
187
- 'Optional: define exactly which fields you\'d like to create (JSON), e.g., \'{"title": "My Post"}\'',
168
+ "Optional: define exactly which fields you'd like to return in the response, e.g., {\"title\": true}",
188
169
  ),
189
170
  })
190
171
 
@@ -203,7 +184,7 @@ ${JSON.stringify(result)}
203
184
  draft as boolean,
204
185
  locale as string | undefined,
205
186
  fallbackLocale as string | undefined,
206
- select as string | undefined,
187
+ select as Record<string, unknown> | undefined,
207
188
  )
208
189
  },
209
190
  )
@@ -1,5 +1,5 @@
1
1
  import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
2
- import type { PayloadRequest, SelectType, TypedUser } from 'payload'
2
+ import type { JoinQuery, PayloadRequest, PopulateType, SelectType, TypedUser } from 'payload'
3
3
 
4
4
  import type { MCPPluginConfig } from '../../../types.js'
5
5
 
@@ -20,11 +20,15 @@ export const findResourceTool = (
20
20
  page: number = 1,
21
21
  sort?: string,
22
22
  where?: string,
23
- select?: string,
23
+ select?: Record<string, unknown>,
24
24
  depth: number = 0,
25
25
  locale?: string,
26
26
  fallbackLocale?: string,
27
27
  draft?: boolean,
28
+ populate?: Record<string, unknown>,
29
+ joins?: false | Record<string, unknown>,
30
+ trash?: boolean,
31
+ pagination?: boolean,
28
32
  ): Promise<{
29
33
  content: Array<{
30
34
  text: string
@@ -63,26 +67,6 @@ export const findResourceTool = (
63
67
  }
64
68
  }
65
69
 
66
- // Parse select clause if provided
67
- let selectClause: SelectType | undefined
68
- if (select) {
69
- try {
70
- selectClause = JSON.parse(select) as SelectType
71
- } catch (_parseError) {
72
- payload.logger.warn(`[payload-mcp] Invalid select clause JSON: ${select}`)
73
- const response = {
74
- content: [{ type: 'text' as const, text: 'Error: Invalid JSON in select clause' }],
75
- }
76
- return (collections?.[collectionSlug]?.overrideResponse?.(response, {}, req) ||
77
- response) as {
78
- content: Array<{
79
- text: string
80
- type: 'text'
81
- }>
82
- }
83
- }
84
- }
85
-
86
70
  // If ID is provided, use findByID
87
71
  if (id) {
88
72
  try {
@@ -90,13 +74,16 @@ export const findResourceTool = (
90
74
  id,
91
75
  collection: collectionSlug,
92
76
  depth,
93
- ...(selectClause && { select: selectClause }),
77
+ ...(select && { select: select as SelectType }),
78
+ ...(populate && { populate: populate as PopulateType }),
79
+ ...(joins !== undefined && { joins: joins as JoinQuery }),
94
80
  overrideAccess: false,
95
81
  req,
96
82
  user,
97
83
  ...(locale && { locale }),
98
84
  ...(fallbackLocale && { fallbackLocale }),
99
85
  ...(draft !== undefined && { draft }),
86
+ ...(trash !== undefined && { trash }),
100
87
  })
101
88
 
102
89
  if (verboseLogs) {
@@ -151,10 +138,14 @@ ${JSON.stringify(doc)}`,
151
138
  page,
152
139
  req,
153
140
  user,
154
- ...(selectClause && { select: selectClause }),
141
+ ...(select && { select: select as SelectType }),
142
+ ...(populate && { populate: populate as PopulateType }),
143
+ ...(joins !== undefined && { joins: joins as JoinQuery }),
155
144
  ...(locale && { locale }),
156
145
  ...(fallbackLocale && { fallbackLocale }),
157
146
  ...(draft !== undefined && { draft }),
147
+ ...(pagination !== undefined && { pagination }),
148
+ ...(trash !== undefined && { trash }),
158
149
  }
159
150
 
160
151
  if (sort) {
@@ -227,7 +218,22 @@ Page: ${result.page} of ${result.totalPages}
227
218
  description: `${collections?.[collectionSlug]?.description || toolSchemas.findResources.description.trim()}`,
228
219
  inputSchema: toolSchemas.findResources.parameters.shape,
229
220
  },
230
- async ({ id, depth, draft, fallbackLocale, limit, locale, page, select, sort, where }) => {
221
+ async ({
222
+ id,
223
+ depth,
224
+ draft,
225
+ fallbackLocale,
226
+ joins,
227
+ limit,
228
+ locale,
229
+ page,
230
+ pagination,
231
+ populate,
232
+ select,
233
+ sort,
234
+ trash,
235
+ where,
236
+ }) => {
231
237
  return await tool(
232
238
  id,
233
239
  limit,
@@ -239,6 +245,10 @@ Page: ${result.page} of ${result.totalPages}
239
245
  locale,
240
246
  fallbackLocale,
241
247
  draft,
248
+ populate,
249
+ joins,
250
+ trash,
251
+ pagination,
242
252
  )
243
253
  },
244
254
  )
@@ -32,7 +32,7 @@ export const updateResourceTool = (
32
32
  overrideLock: boolean = true,
33
33
  locale?: string,
34
34
  fallbackLocale?: string,
35
- select?: string,
35
+ select?: Record<string, unknown>,
36
36
  ): Promise<{
37
37
  content: Array<{
38
38
  text: string
@@ -118,25 +118,6 @@ export const updateResourceTool = (
118
118
  }
119
119
  }
120
120
 
121
- let selectClause: SelectType | undefined
122
- if (select) {
123
- try {
124
- selectClause = JSON.parse(select) as SelectType
125
- } catch (_parseError) {
126
- payload.logger.warn(`[payload-mcp] Invalid select clause JSON: ${select}`)
127
- const response = {
128
- content: [{ type: 'text' as const, text: 'Error: Invalid JSON in select clause' }],
129
- }
130
- return (collections?.[collectionSlug]?.overrideResponse?.(response, {}, req) ||
131
- response) as {
132
- content: Array<{
133
- text: string
134
- type: 'text'
135
- }>
136
- }
137
- }
138
- }
139
-
140
121
  // Update by ID or where clause
141
122
  if (id) {
142
123
  // Single document update
@@ -152,7 +133,7 @@ export const updateResourceTool = (
152
133
  user,
153
134
  ...(locale && { locale }),
154
135
  ...(fallbackLocale && { fallbackLocale }),
155
- ...(selectClause && { select: selectClause }),
136
+ ...(select && { select: select as SelectType }),
156
137
  }
157
138
 
158
139
  if (verboseLogs) {
@@ -201,7 +182,7 @@ ${JSON.stringify(result)}
201
182
  where: whereClause,
202
183
  ...(locale && { locale }),
203
184
  ...(fallbackLocale && { fallbackLocale }),
204
- ...(selectClause && { select: selectClause }),
185
+ ...(select && { select: select as SelectType }),
205
186
  }
206
187
 
207
188
  if (verboseLogs) {
@@ -319,10 +300,10 @@ ${JSON.stringify(errors)}
319
300
  .default(true)
320
301
  .describe('Whether to override document locks'),
321
302
  select: z
322
- .string()
303
+ .record(z.string(), z.unknown())
323
304
  .optional()
324
305
  .describe(
325
- 'Optional: define exactly which fields you\'d like to return in the response (JSON), e.g., \'{"title": "My Post"}\'',
306
+ "Optional: define exactly which fields you'd like to return in the response, e.g., {\"title\": true}",
326
307
  ),
327
308
  where: z
328
309
  .string()
@@ -359,7 +340,7 @@ ${JSON.stringify(errors)}
359
340
  overrideLock as boolean,
360
341
  locale as string | undefined,
361
342
  fallbackLocale as string | undefined,
362
- select as string | undefined,
343
+ select as Record<string, unknown> | undefined,
363
344
  )
364
345
  },
365
346
  )
@@ -22,11 +22,17 @@ export const toolSchemas = {
22
22
  .describe(
23
23
  'Optional: locale code to retrieve data in (e.g., "en", "es"). Use "all" to retrieve all locales for localized fields',
24
24
  ),
25
+ populate: z
26
+ .record(z.string(), z.unknown())
27
+ .optional()
28
+ .describe(
29
+ 'Optional: control which fields to include from populated relationship or upload documents.',
30
+ ),
25
31
  select: z
26
- .string()
32
+ .record(z.string(), z.unknown())
27
33
  .optional()
28
34
  .describe(
29
- "Optional: define exactly which fields you'd like to return in the response (JSON), e.g., '{\"title\": true}'",
35
+ "Optional: define exactly which fields you'd like to return in the response, e.g., {\"title\": true}",
30
36
  ),
31
37
  }),
32
38
  },
@@ -58,6 +64,12 @@ export const toolSchemas = {
58
64
  .string()
59
65
  .optional()
60
66
  .describe('Optional: fallback locale code to use when requested locale is not available'),
67
+ joins: z
68
+ .union([z.record(z.string(), z.unknown()), z.literal(false)])
69
+ .optional()
70
+ .describe(
71
+ 'Optional: configure join field queries, or pass false to disable all join fields.',
72
+ ),
61
73
  limit: z
62
74
  .number()
63
75
  .int()
@@ -79,16 +91,30 @@ export const toolSchemas = {
79
91
  .optional()
80
92
  .default(1)
81
93
  .describe('Page number for pagination (default: 1)'),
94
+ pagination: z
95
+ .boolean()
96
+ .optional()
97
+ .describe('Optional: set to false to skip the count query overhead'),
98
+ populate: z
99
+ .record(z.string(), z.unknown())
100
+ .optional()
101
+ .describe(
102
+ 'Optional: control which fields to include from populated relationship or upload documents.',
103
+ ),
82
104
  select: z
83
- .string()
105
+ .record(z.string(), z.unknown())
84
106
  .optional()
85
107
  .describe(
86
- "Optional: define exactly which fields you'd like to return in the response (JSON), e.g., '{\"title\": true}'",
108
+ "Optional: define exactly which fields you'd like to return in the response, e.g., {\"title\": true}",
87
109
  ),
88
110
  sort: z
89
111
  .string()
90
112
  .optional()
91
113
  .describe('Field to sort by (e.g., "createdAt", "-updatedAt" for descending)'),
114
+ trash: z
115
+ .boolean()
116
+ .optional()
117
+ .describe('Optional: include soft-deleted documents when trash is enabled on the collection'),
92
118
  where: z
93
119
  .string()
94
120
  .optional()
@@ -126,10 +152,10 @@ export const toolSchemas = {
126
152
  'Optional: locale code to create the document in (e.g., "en", "es"). Defaults to the default locale',
127
153
  ),
128
154
  select: z
129
- .string()
155
+ .record(z.string(), z.unknown())
130
156
  .optional()
131
157
  .describe(
132
- "Optional: define exactly which fields you'd like to return in the response (JSON), e.g., '{\"title\": true}'",
158
+ "Optional: define exactly which fields you'd like to return in the response, e.g., {\"title\": true}",
133
159
  ),
134
160
  }),
135
161
  },
@@ -167,10 +193,10 @@ export const toolSchemas = {
167
193
  .default(true)
168
194
  .describe('Whether to override document locks'),
169
195
  select: z
170
- .string()
196
+ .record(z.string(), z.unknown())
171
197
  .optional()
172
198
  .describe(
173
- "Optional: define exactly which fields you'd like to return in the response (JSON), e.g., '{\"title\": true}'",
199
+ "Optional: define exactly which fields you'd like to return in the response, e.g., {\"title\": true}",
174
200
  ),
175
201
  where: z
176
202
  .string()
@@ -235,10 +261,10 @@ export const toolSchemas = {
235
261
  'Optional: locale code to update data in (e.g., "en", "es"). Use "all" to update all locales for localized fields',
236
262
  ),
237
263
  select: z
238
- .string()
264
+ .record(z.string(), z.unknown())
239
265
  .optional()
240
266
  .describe(
241
- "Optional: define exactly which fields you'd like to return in the response (JSON), e.g., '{\"siteName\": true}'",
267
+ "Optional: define exactly which fields you'd like to return in the response, e.g., {\"siteName\": true}",
242
268
  ),
243
269
  }),
244
270
  },
@@ -369,11 +395,9 @@ export const toolSchemas = {
369
395
  description: 'Checks authentication status for the current user.',
370
396
  parameters: z.object({
371
397
  headers: z
372
- .string()
398
+ .record(z.string(), z.string())
373
399
  .optional()
374
- .describe(
375
- 'Optional JSON string containing custom headers to send with the authentication request',
376
- ),
400
+ .describe('Optional custom headers to send with the authentication request'),
377
401
  }),
378
402
  },
379
403