@payloadcms/plugin-mcp 3.78.0-internal-debug.f663370 → 3.78.0-internal.ab11ffa

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 (97) hide show
  1. package/dist/index.d.ts +0 -1
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +0 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/mcp/getMcpHandler.d.ts.map +1 -1
  6. package/dist/mcp/getMcpHandler.js +8 -2
  7. package/dist/mcp/getMcpHandler.js.map +1 -1
  8. package/dist/mcp/helpers/config.d.ts +1 -9
  9. package/dist/mcp/helpers/config.d.ts.map +1 -1
  10. package/dist/mcp/helpers/config.js +0 -62
  11. package/dist/mcp/helpers/config.js.map +1 -1
  12. package/dist/mcp/helpers/fields.d.ts +6 -25
  13. package/dist/mcp/helpers/fields.d.ts.map +1 -1
  14. package/dist/mcp/helpers/fields.js +35 -29
  15. package/dist/mcp/helpers/fields.js.map +1 -1
  16. package/dist/mcp/helpers/fileValidation.d.ts +0 -2
  17. package/dist/mcp/helpers/fileValidation.d.ts.map +1 -1
  18. package/dist/mcp/helpers/fileValidation.js +44 -82
  19. package/dist/mcp/helpers/fileValidation.js.map +1 -1
  20. package/dist/mcp/tools/collection/create.d.ts.map +1 -1
  21. package/dist/mcp/tools/collection/create.js +2 -25
  22. package/dist/mcp/tools/collection/create.js.map +1 -1
  23. package/dist/mcp/tools/collection/delete.d.ts.map +1 -1
  24. package/dist/mcp/tools/collection/delete.js +1 -12
  25. package/dist/mcp/tools/collection/delete.js.map +1 -1
  26. package/dist/mcp/tools/config/update.d.ts +1 -1
  27. package/dist/mcp/tools/config/update.d.ts.map +1 -1
  28. package/dist/mcp/tools/config/update.js +3 -3
  29. package/dist/mcp/tools/config/update.js.map +1 -1
  30. package/dist/mcp/tools/global/update.d.ts.map +1 -1
  31. package/dist/mcp/tools/global/update.js +3 -0
  32. package/dist/mcp/tools/global/update.js.map +1 -1
  33. package/dist/mcp/tools/job/create.d.ts.map +1 -1
  34. package/dist/mcp/tools/job/create.js +3 -6
  35. package/dist/mcp/tools/job/create.js.map +1 -1
  36. package/dist/mcp/tools/job/run.d.ts +1 -1
  37. package/dist/mcp/tools/job/run.d.ts.map +1 -1
  38. package/dist/mcp/tools/job/run.js +5 -26
  39. package/dist/mcp/tools/job/run.js.map +1 -1
  40. package/dist/mcp/tools/job/update.d.ts.map +1 -1
  41. package/dist/mcp/tools/job/update.js +10 -38
  42. package/dist/mcp/tools/job/update.js.map +1 -1
  43. package/dist/mcp/tools/resource/create.d.ts.map +1 -1
  44. package/dist/mcp/tools/resource/create.js +3 -0
  45. package/dist/mcp/tools/resource/create.js.map +1 -1
  46. package/dist/mcp/tools/resource/update.d.ts.map +1 -1
  47. package/dist/mcp/tools/resource/update.js +3 -0
  48. package/dist/mcp/tools/resource/update.js.map +1 -1
  49. package/dist/mcp/tools/schemas.d.ts +2 -5
  50. package/dist/mcp/tools/schemas.d.ts.map +1 -1
  51. package/dist/mcp/tools/schemas.js +0 -1
  52. package/dist/mcp/tools/schemas.js.map +1 -1
  53. package/dist/utils/getVirtualFieldNames.d.ts +14 -0
  54. package/dist/utils/getVirtualFieldNames.d.ts.map +1 -0
  55. package/dist/utils/getVirtualFieldNames.js +35 -0
  56. package/dist/utils/getVirtualFieldNames.js.map +1 -0
  57. package/dist/utils/schemaConversion/convertCollectionSchemaToZod.d.ts.map +1 -1
  58. package/dist/utils/schemaConversion/convertCollectionSchemaToZod.js +1 -2
  59. package/dist/utils/schemaConversion/convertCollectionSchemaToZod.js.map +1 -1
  60. package/dist/utils/schemaConversion/removeVirtualFieldsFromSchema.d.ts +7 -0
  61. package/dist/utils/schemaConversion/removeVirtualFieldsFromSchema.d.ts.map +1 -0
  62. package/dist/utils/schemaConversion/removeVirtualFieldsFromSchema.js +20 -0
  63. package/dist/utils/schemaConversion/removeVirtualFieldsFromSchema.js.map +1 -0
  64. package/dist/utils/schemaConversion/sanitizeJsonSchema.d.ts +5 -0
  65. package/dist/utils/schemaConversion/sanitizeJsonSchema.d.ts.map +1 -1
  66. package/dist/utils/schemaConversion/sanitizeJsonSchema.js +38 -0
  67. package/dist/utils/schemaConversion/sanitizeJsonSchema.js.map +1 -1
  68. package/package.json +4 -4
  69. package/src/index.ts +0 -1
  70. package/src/mcp/getMcpHandler.ts +22 -2
  71. package/src/mcp/helpers/config.ts +1 -114
  72. package/src/mcp/helpers/fields.ts +46 -50
  73. package/src/mcp/helpers/fileValidation.ts +38 -93
  74. package/src/mcp/tools/collection/create.ts +2 -30
  75. package/src/mcp/tools/collection/delete.ts +1 -19
  76. package/src/mcp/tools/config/update.ts +0 -4
  77. package/src/mcp/tools/global/update.ts +8 -0
  78. package/src/mcp/tools/job/create.ts +5 -11
  79. package/src/mcp/tools/job/run.ts +14 -38
  80. package/src/mcp/tools/job/update.ts +29 -77
  81. package/src/mcp/tools/resource/create.ts +7 -0
  82. package/src/mcp/tools/resource/update.ts +7 -0
  83. package/src/mcp/tools/schemas.ts +0 -1
  84. package/src/utils/getVirtualFieldNames.ts +53 -0
  85. package/src/utils/schemaConversion/convertCollectionSchemaToZod.ts +1 -3
  86. package/src/utils/schemaConversion/removeVirtualFieldsFromSchema.ts +27 -0
  87. package/src/utils/schemaConversion/sanitizeJsonSchema.ts +41 -0
  88. package/dist/mcp/helpers/conversion.d.ts +0 -2
  89. package/dist/mcp/helpers/conversion.d.ts.map +0 -1
  90. package/dist/mcp/helpers/conversion.js +0 -5
  91. package/dist/mcp/helpers/conversion.js.map +0 -1
  92. package/dist/mcp/helpers/validation.d.ts +0 -9
  93. package/dist/mcp/helpers/validation.d.ts.map +0 -1
  94. package/dist/mcp/helpers/validation.js +0 -22
  95. package/dist/mcp/helpers/validation.js.map +0 -1
  96. package/src/mcp/helpers/conversion.ts +0 -3
  97. package/src/mcp/helpers/validation.ts +0 -32
@@ -1,10 +1,4 @@
1
- import type {
2
- AdminConfig,
3
- CollectionConfigUpdates,
4
- DatabaseConfig,
5
- GeneralConfig,
6
- PluginUpdates,
7
- } from '../../types.js'
1
+ import type { AdminConfig, DatabaseConfig, PluginUpdates } from '../../types.js'
8
2
 
9
3
  /**
10
4
  * Adds a collection to the payload.config.ts file
@@ -217,110 +211,3 @@ export function updatePluginsConfig(content: string, pluginUpdates: PluginUpdate
217
211
 
218
212
  return content
219
213
  }
220
-
221
- /**
222
- * Updates general configuration options in payload.config.ts
223
- */
224
- export function updateGeneralConfig(content: string, generalConfig: GeneralConfig): string {
225
- // Update various general configuration options
226
- Object.entries(generalConfig).forEach(([key, value]) => {
227
- if (value !== undefined && value !== null) {
228
- const configRegex = new RegExp(`${key}:\\s*[^,}]*`, 'g')
229
-
230
- if (content.match(configRegex)) {
231
- if (typeof value === 'string') {
232
- content = content.replace(configRegex, `${key}: '${value}'`)
233
- } else if (typeof value === 'boolean') {
234
- content = content.replace(configRegex, `${key}: ${value}`)
235
- } else if (typeof value === 'object') {
236
- content = content.replace(configRegex, `${key}: ${JSON.stringify(value, null, 2)}`)
237
- }
238
- } else {
239
- // Add new config option
240
- const configValue =
241
- typeof value === 'string'
242
- ? `'${value}'`
243
- : typeof value === 'object'
244
- ? JSON.stringify(value, null, 2)
245
- : value
246
- content = content.replace(
247
- /export default buildConfig\(\{/,
248
- `export default buildConfig({\n ${key}: ${configValue},`,
249
- )
250
- }
251
- }
252
- })
253
-
254
- return content
255
- }
256
-
257
- /**
258
- * Updates collection-level configuration in a collection file
259
- */
260
- export function updateCollectionConfig(
261
- content: string,
262
- updates: CollectionConfigUpdates,
263
- collectionName: string,
264
- ): string {
265
- let updatedContent = content
266
-
267
- if (updates.slug) {
268
- updatedContent = updatedContent.replace(/slug:\s*'[^']*'/, `slug: '${updates.slug}'`)
269
- }
270
-
271
- if (updates.access) {
272
- const accessRegex = /access:\s*\{[^}]*\}/
273
- if (updatedContent.match(accessRegex)) {
274
- // Update existing access config
275
- Object.entries(updates.access).forEach(([key, value]) => {
276
- if (value !== undefined) {
277
- updatedContent = updatedContent.replace(
278
- new RegExp(`${key}:\\s*[^,}]*`),
279
- `${key}: ${value}`,
280
- )
281
- }
282
- })
283
- } else {
284
- // Add access config
285
- const accessConfig = Object.entries(updates.access)
286
- .filter(([, value]) => value !== undefined)
287
- .map(([key, value]) => ` ${key}: ${value}`)
288
- .join(',\n')
289
-
290
- updatedContent = updatedContent.replace(
291
- /slug:\s*'[^']*',/,
292
- `slug: '${collectionName}',\n access: {\n${accessConfig}\n },`,
293
- )
294
- }
295
- }
296
-
297
- if (updates.timestamps !== undefined) {
298
- if (updatedContent.includes('timestamps:')) {
299
- updatedContent = updatedContent.replace(
300
- /timestamps:[^,}]*/,
301
- `timestamps: ${updates.timestamps}`,
302
- )
303
- } else {
304
- updatedContent = updatedContent.replace(
305
- /fields:\s*\[/,
306
- `timestamps: ${updates.timestamps},\n fields: [`,
307
- )
308
- }
309
- }
310
-
311
- if (updates.versioning !== undefined) {
312
- if (updatedContent.includes('versioning:')) {
313
- updatedContent = updatedContent.replace(
314
- /versioning:[^,}]*/,
315
- `versioning: ${updates.versioning}`,
316
- )
317
- } else {
318
- updatedContent = updatedContent.replace(
319
- /fields:\s*\[/,
320
- `versioning: ${updates.versioning},\n fields: [`,
321
- )
322
- }
323
- }
324
-
325
- return updatedContent
326
- }
@@ -1,21 +1,51 @@
1
- type FieldDefinition = {
2
- description?: string
3
- name: string
4
- options?: { label: string; value: string }[]
5
- position?: 'main' | 'sidebar'
6
- required?: boolean
7
- type: string
1
+ import type { FieldDefinition, FieldModification } from '../../types.js'
2
+
3
+ /** Escapes a value for safe embedding inside a single-quoted TypeScript string literal. */
4
+ function escapeSingleQuotedString(value: string): string {
5
+ return value
6
+ .replace(/\\/g, '\\\\')
7
+ .replace(/'/g, "\\'")
8
+ .replace(/\r/g, '\\r')
9
+ .replace(/\n/g, '\\n')
8
10
  }
9
11
 
10
- type FieldModification = {
11
- changes: {
12
- description?: string
13
- options?: { label: string; value: string }[]
14
- position?: 'main' | 'sidebar'
15
- required?: boolean
16
- type?: string
12
+ /**
13
+ * Generates the TypeScript source string for a single field definition block.
14
+ * Used when writing collection files to disk.
15
+ */
16
+ export function generateFieldDefinitionString(field: FieldDefinition): string {
17
+ const lines: string[] = []
18
+ lines.push(` {`)
19
+ lines.push(` name: '${escapeSingleQuotedString(field.name)}',`)
20
+ lines.push(` type: '${escapeSingleQuotedString(field.type)}',`)
21
+
22
+ if (field.required) {
23
+ lines.push(` required: true,`)
24
+ }
25
+
26
+ if (field.description || field.position) {
27
+ lines.push(` admin: {`)
28
+ if (field.description) {
29
+ lines.push(` description: '${escapeSingleQuotedString(field.description)}',`)
30
+ }
31
+ if (field.position) {
32
+ lines.push(` position: '${escapeSingleQuotedString(field.position)}',`)
33
+ }
34
+ lines.push(` },`)
17
35
  }
18
- fieldName: string
36
+
37
+ if (field.options && field.type === 'select') {
38
+ lines.push(` options: [`)
39
+ field.options.forEach((option) => {
40
+ lines.push(
41
+ ` { label: '${escapeSingleQuotedString(option.label)}', value: '${escapeSingleQuotedString(option.value)}' },`,
42
+ )
43
+ })
44
+ lines.push(` ],`)
45
+ }
46
+
47
+ lines.push(` },`)
48
+ return lines.join('\n')
19
49
  }
20
50
 
21
51
  /**
@@ -30,41 +60,7 @@ export function addFieldsToCollection(content: string, newFields: FieldDefinitio
30
60
  throw new Error('Could not find fields array in collection file')
31
61
  }
32
62
 
33
- // Generate new field definitions
34
- const newFieldDefinitions = newFields
35
- .map((field) => {
36
- const fieldConfig = []
37
- fieldConfig.push(` {`)
38
- fieldConfig.push(` name: '${field.name}',`)
39
- fieldConfig.push(` type: '${field.type}',`)
40
-
41
- if (field.required) {
42
- fieldConfig.push(` required: true,`)
43
- }
44
-
45
- if (field.description || field.position) {
46
- fieldConfig.push(` admin: {`)
47
- if (field.description) {
48
- fieldConfig.push(` description: '${field.description}',`)
49
- }
50
- if (field.position) {
51
- fieldConfig.push(` position: '${field.position}',`)
52
- }
53
- fieldConfig.push(` },`)
54
- }
55
-
56
- if (field.options && field.type === 'select') {
57
- fieldConfig.push(` options: [`)
58
- field.options.forEach((option: { label: string; value: string }) => {
59
- fieldConfig.push(` { label: '${option.label}', value: '${option.value}' },`)
60
- })
61
- fieldConfig.push(` ],`)
62
- }
63
-
64
- fieldConfig.push(` },`)
65
- return fieldConfig.join('\n')
66
- })
67
- .join('\n')
63
+ const newFieldDefinitions = newFields.map(generateFieldDefinitionString).join('\n')
68
64
 
69
65
  // Add new fields before the closing bracket
70
66
  const existingFields = match[1] || ''
@@ -219,8 +219,8 @@ function validateCollectionConfig(config: CollectionConfig): ValidationResult<Co
219
219
  // Validate each field has required properties
220
220
  if (config.fields) {
221
221
  for (let i = 0; i < config.fields.length; i++) {
222
- const field = config.fields[i] as Record<string, unknown>
223
- if (!field) {
222
+ const field = config.fields[i]
223
+ if (!field || typeof field !== 'object') {
224
224
  return {
225
225
  error: `Field at index ${i} is not a valid object`,
226
226
  success: false,
@@ -228,9 +228,9 @@ function validateCollectionConfig(config: CollectionConfig): ValidationResult<Co
228
228
  }
229
229
 
230
230
  // Check if field has type property
231
- if ('type' in field && field.type) {
231
+ if (!('type' in field) || !field.type) {
232
232
  return {
233
- error: `Field at index ${i} has invalid type property`,
233
+ error: `Field at index ${i} is missing a valid type property`,
234
234
  success: false,
235
235
  }
236
236
  }
@@ -240,6 +240,29 @@ function validateCollectionConfig(config: CollectionConfig): ValidationResult<Co
240
240
  return { config, success: true }
241
241
  }
242
242
 
243
+ /**
244
+ * Validates an array of schema fields (inputSchema / outputSchema).
245
+ * Returns an error string on the first invalid field, or null if all fields are valid.
246
+ */
247
+ function validateSchemaFields(fields: TaskConfig['inputSchema'], label: string): null | string {
248
+ if (!fields || !Array.isArray(fields)) {
249
+ return null
250
+ }
251
+ for (let i = 0; i < fields.length; i++) {
252
+ const field = fields[i]
253
+ if (!field) {
254
+ return `${label} field at index ${i} is not a valid object`
255
+ }
256
+ if (!field.name) {
257
+ return `${label} field at index ${i} must have a valid name property`
258
+ }
259
+ if (!field.type) {
260
+ return `${label} field at index ${i} must have a valid type property`
261
+ }
262
+ }
263
+ return null
264
+ }
265
+
243
266
  /**
244
267
  * Validate task configuration structure
245
268
  */
@@ -265,7 +288,6 @@ function validateTaskConfig(config: TaskConfig): ValidationResult<TaskConfig> {
265
288
  }
266
289
  }
267
290
 
268
- // Validate optional properties
269
291
  if (config.retries !== undefined && config.retries < 0) {
270
292
  return {
271
293
  error: 'Task config retries must be a non-negative number',
@@ -273,57 +295,14 @@ function validateTaskConfig(config: TaskConfig): ValidationResult<TaskConfig> {
273
295
  }
274
296
  }
275
297
 
276
- // Validate schemas if present
277
- if (config.inputSchema && Array.isArray(config.inputSchema)) {
278
- for (let i = 0; i < config.inputSchema.length; i++) {
279
- const field = config.inputSchema[i]
280
- if (!field) {
281
- return {
282
- error: `Input schema field at index ${i} is not a valid object`,
283
- success: false,
284
- }
285
- }
286
-
287
- if (!field.name) {
288
- return {
289
- error: `Input schema field at index ${i} must have a valid name property`,
290
- success: false,
291
- }
292
- }
293
-
294
- if (!field.type) {
295
- return {
296
- error: `Input schema field at index ${i} must have a valid type property`,
297
- success: false,
298
- }
299
- }
300
- }
298
+ const inputError = validateSchemaFields(config.inputSchema, 'Input schema')
299
+ if (inputError) {
300
+ return { error: inputError, success: false }
301
301
  }
302
302
 
303
- if (config.outputSchema && Array.isArray(config.outputSchema)) {
304
- for (let i = 0; i < config.outputSchema.length; i++) {
305
- const field = config.outputSchema[i]
306
- if (!field) {
307
- return {
308
- error: `Output schema field at index ${i} is not a valid object`,
309
- success: false,
310
- }
311
- }
312
-
313
- if (!field.name) {
314
- return {
315
- error: `Output schema field at index ${i} must have a valid name property`,
316
- success: false,
317
- }
318
- }
319
-
320
- if (!field.type) {
321
- return {
322
- error: `Output schema field at index ${i} must have a valid type property`,
323
- success: false,
324
- }
325
- }
326
- }
303
+ const outputError = validateSchemaFields(config.outputSchema, 'Output schema')
304
+ if (outputError) {
305
+ return { error: outputError, success: false }
327
306
  }
328
307
 
329
308
  return { config, success: true }
@@ -354,10 +333,9 @@ function validateWorkflowConfig(config: WorkflowConfig): ValidationResult<Workfl
354
333
  }
355
334
  }
356
335
 
357
- // Validate optional properties
358
- if (config.queue) {
336
+ if (config.queue !== undefined && typeof config.queue !== 'string') {
359
337
  return {
360
- error: 'Workflow config queue must be a string',
338
+ error: 'Workflow config queue must be a string if provided',
361
339
  success: false,
362
340
  }
363
341
  }
@@ -369,49 +347,16 @@ function validateWorkflowConfig(config: WorkflowConfig): ValidationResult<Workfl
369
347
  }
370
348
  }
371
349
 
372
- // Validate schema if present
373
- if (config.inputSchema && Array.isArray(config.inputSchema)) {
374
- for (let i = 0; i < config.inputSchema.length; i++) {
375
- const field = config.inputSchema[i]
376
- if (!field) {
377
- return {
378
- error: `Input schema field at index ${i} is not a valid object`,
379
- success: false,
380
- }
381
- }
382
-
383
- if (!field.name) {
384
- return {
385
- error: `Input schema field at index ${i} must have a valid name property`,
386
- success: false,
387
- }
388
- }
389
-
390
- if (!field.type) {
391
- return {
392
- error: `Input schema field at index ${i} must have a valid type property`,
393
- success: false,
394
- }
395
- }
396
- }
350
+ const inputError = validateSchemaFields(config.inputSchema, 'Input schema')
351
+ if (inputError) {
352
+ return { error: inputError, success: false }
397
353
  }
398
354
 
399
355
  return { config, success: true }
400
356
  }
401
357
 
402
- // Convenience functions for backward compatibility
403
358
  export const validateCollectionFile = async (
404
359
  fileName: string,
405
360
  ): Promise<ValidationResult<CollectionConfig>> => {
406
361
  return validatePayloadFile<CollectionConfig>(fileName, 'collection')
407
362
  }
408
-
409
- export const validateTaskFile = async (fileName: string): Promise<ValidationResult<TaskConfig>> => {
410
- return validatePayloadFile<TaskConfig>(fileName, 'task')
411
- }
412
-
413
- export const validateWorkflowFile = async (
414
- fileName: string,
415
- ): Promise<ValidationResult<WorkflowConfig>> => {
416
- return validatePayloadFile<WorkflowConfig>(fileName, 'workflow')
417
- }
@@ -4,6 +4,7 @@ import type { PayloadRequest } from 'payload'
4
4
  import { writeFileSync } from 'fs'
5
5
  import { join } from 'path'
6
6
 
7
+ import { generateFieldDefinitionString } from '../../helpers/fields.js'
7
8
  import { validateCollectionFile } from '../../helpers/fileValidation.js'
8
9
  import { toolSchemas } from '../schemas.js'
9
10
 
@@ -34,36 +35,7 @@ export const createCollection = async (
34
35
  payload.logger.info(`[payload-mcp] Generated slug: ${slug} for collection: ${collectionName}`)
35
36
  }
36
37
 
37
- // Generate TypeScript field definitions more systematically
38
- const generateFieldDefinition = (field: any) => {
39
- const fieldConfig = []
40
- fieldConfig.push(` {`)
41
- fieldConfig.push(` name: '${field.name}',`)
42
- fieldConfig.push(` type: '${field.type}',`)
43
-
44
- if (field.required) {
45
- fieldConfig.push(` required: true,`)
46
- }
47
-
48
- if (field.description) {
49
- fieldConfig.push(` admin: {`)
50
- fieldConfig.push(` description: '${field.description}',`)
51
- fieldConfig.push(` },`)
52
- }
53
-
54
- if (field.options && field.type === 'select') {
55
- fieldConfig.push(` options: [`)
56
- field.options.forEach((option: { label: string; value: string }) => {
57
- fieldConfig.push(` { label: '${option.label}', value: '${option.value}' },`)
58
- })
59
- fieldConfig.push(` ],`)
60
- }
61
-
62
- fieldConfig.push(` },`)
63
- return fieldConfig.join('\n')
64
- }
65
-
66
- const fieldDefinitions = fields.map(generateFieldDefinition).join('\n')
38
+ const fieldDefinitions = fields.map(generateFieldDefinitionString).join('\n')
67
39
 
68
40
  // Generate collection file content
69
41
  const collectionContent = `import type { CollectionConfig } from 'payload'
@@ -4,27 +4,9 @@ import type { PayloadRequest } from 'payload'
4
4
  import { readFileSync, unlinkSync, writeFileSync } from 'fs'
5
5
  import { join } from 'path'
6
6
 
7
+ import { removeCollectionFromConfig } from '../../helpers/config.js'
7
8
  import { toolSchemas } from '../schemas.js'
8
9
 
9
- // Helper function for removing collection from config
10
- const removeCollectionFromConfig = (configContent: string, collectionName: string): string => {
11
- // Simple implementation - find and remove the collection import and reference
12
- let updatedContent = configContent
13
-
14
- // Remove import statement
15
- const importRegex = new RegExp(
16
- `import\\s*{\\s*${collectionName}\\s*}\\s*from\\s*['"]\\./collections/${collectionName}['"];?\\s*\\n?`,
17
- 'g',
18
- )
19
- updatedContent = updatedContent.replace(importRegex, '')
20
-
21
- // Remove from collections array
22
- const collectionsRegex = new RegExp(`\\s*${collectionName},?\\s*`, 'g')
23
- updatedContent = updatedContent.replace(collectionsRegex, '')
24
-
25
- return updatedContent
26
- }
27
-
28
10
  export const deleteCollection = (
29
11
  req: PayloadRequest,
30
12
  verboseLogs: boolean,
@@ -21,7 +21,6 @@ export const updateConfig = (
21
21
  adminConfig?: any,
22
22
  databaseConfig?: any,
23
23
  pluginUpdates?: any,
24
- generalConfig?: any,
25
24
  newContent?: string,
26
25
  ) => {
27
26
  const payload = req.payload
@@ -218,7 +217,6 @@ export const updateConfigTool = (
218
217
  adminConfig,
219
218
  collectionName,
220
219
  databaseConfig,
221
- generalConfig,
222
220
  newContent,
223
221
  pluginUpdates,
224
222
  updateType,
@@ -226,7 +224,6 @@ export const updateConfigTool = (
226
224
  adminConfig?: any
227
225
  collectionName?: string
228
226
  databaseConfig?: any
229
- generalConfig?: any
230
227
  newContent?: string
231
228
  pluginUpdates?: any
232
229
  updateType: string
@@ -247,7 +244,6 @@ export const updateConfigTool = (
247
244
  adminConfig,
248
245
  databaseConfig,
249
246
  pluginUpdates,
250
- generalConfig,
251
247
  newContent,
252
248
  )
253
249
 
@@ -7,6 +7,10 @@ import { z } from 'zod'
7
7
  import type { PluginMCPServerConfig } from '../../../types.js'
8
8
 
9
9
  import { toCamelCase } from '../../../utils/camelCase.js'
10
+ import {
11
+ getGlobalVirtualFieldNames,
12
+ stripVirtualFields,
13
+ } from '../../../utils/getVirtualFieldNames.js'
10
14
  import { convertCollectionSchemaToZod } from '../../../utils/schemaConversion/convertCollectionSchemaToZod.js'
11
15
  import { toolSchemas } from '../schemas.js'
12
16
 
@@ -45,6 +49,10 @@ export const updateGlobalTool = (
45
49
  let parsedData: Record<string, unknown>
46
50
  try {
47
51
  parsedData = JSON.parse(data)
52
+
53
+ const virtualFieldNames = getGlobalVirtualFieldNames(payload.config, globalSlug)
54
+ parsedData = stripVirtualFields(parsedData, virtualFieldNames)
55
+
48
56
  if (verboseLogs) {
49
57
  payload.logger.info(
50
58
  `[payload-mcp] Parsed data for ${globalSlug}: ${JSON.stringify(parsedData)}`,
@@ -4,6 +4,7 @@ import type { PayloadRequest } from 'payload'
4
4
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs'
5
5
  import { join } from 'path'
6
6
 
7
+ import { toCamelCase } from '../../../utils/camelCase.js'
7
8
  import { validatePayloadFile } from '../../helpers/fileValidation.js'
8
9
  import { toolSchemas } from '../schemas.js'
9
10
 
@@ -271,12 +272,12 @@ ${jobContent}
271
272
 
272
273
  // Helper function to generate task content
273
274
  function generateTaskContent(
274
- jobName: string,
275
+ _jobName: string,
275
276
  jobSlug: string,
276
277
  description: string,
277
278
  inputSchema: any,
278
279
  outputSchema: any,
279
- jobData: Record<string, any>,
280
+ _jobData: Record<string, any>,
280
281
  ): string {
281
282
  const camelCaseJobSlug = toCamelCase(jobSlug)
282
283
 
@@ -307,12 +308,12 @@ export const ${camelCaseJobSlug}Task: Task = {
307
308
 
308
309
  // Helper function to generate workflow content
309
310
  function generateWorkflowContent(
310
- jobName: string,
311
+ _jobName: string,
311
312
  jobSlug: string,
312
313
  description: string,
313
314
  inputSchema: any,
314
315
  outputSchema: any,
315
- jobData: Record<string, any>,
316
+ _jobData: Record<string, any>,
316
317
  ): string {
317
318
  const camelCaseJobSlug = toCamelCase(jobSlug)
318
319
 
@@ -339,13 +340,6 @@ export const ${camelCaseJobSlug}Workflow: Workflow = {
339
340
  `
340
341
  }
341
342
 
342
- // Helper function to convert to camel case
343
- function toCamelCase(str: string): string {
344
- return str
345
- .replace(/[-_\s]+(.)?/g, (_, chr) => (chr ? chr.toUpperCase() : ''))
346
- .replace(/^(.)/, (_, chr) => chr.toLowerCase())
347
- }
348
-
349
343
  export const createJobTool = (
350
344
  server: McpServer,
351
345
  req: PayloadRequest,
@@ -8,7 +8,7 @@ export const runJob = async (
8
8
  req: PayloadRequest,
9
9
  verboseLogs: boolean,
10
10
  jobSlug: string,
11
- input: Record<string, any>,
11
+ input: Record<string, unknown>,
12
12
  queue?: string,
13
13
  priority?: number,
14
14
  delay?: number,
@@ -143,49 +143,25 @@ ${JSON.stringify(input, null, 2)}
143
143
  }
144
144
 
145
145
  export const runJobTool = (server: McpServer, req: PayloadRequest, verboseLogs: boolean) => {
146
- const tool = async (
147
- jobSlug: string,
148
- input: Record<string, any>,
149
- queue?: string,
150
- priority?: number,
151
- delay?: number,
152
- ) => {
153
- if (verboseLogs) {
154
- req.payload.logger.info(`[payload-mcp] Run Job Tool called with: ${jobSlug}`)
155
- }
156
-
157
- try {
158
- const result = await runJob(req, verboseLogs, jobSlug, input, queue, priority, delay)
159
-
160
- if (verboseLogs) {
161
- req.payload.logger.info(`[payload-mcp] Run Job Tool completed successfully`)
162
- }
163
-
164
- return result
165
- } catch (error) {
166
- const errorMessage = error instanceof Error ? error.message : 'Unknown error'
167
- req.payload.logger.error(`[payload-mcp] Error in Run Job Tool: ${errorMessage}`)
168
-
169
- return {
170
- content: [
171
- {
172
- type: 'text' as const,
173
- text: `❌ **Error in Run Job Tool**: ${errorMessage}`,
174
- },
175
- ],
176
- }
177
- }
178
- }
179
-
180
146
  server.registerTool(
181
147
  'runJob',
182
148
  {
183
149
  description: 'Runs a Payload job with specified input data and queue options',
184
150
  inputSchema: toolSchemas.runJob.parameters.shape,
185
151
  },
186
- async (args) => {
187
- const { delay, input, jobSlug, priority, queue } = args
188
- return await tool(jobSlug, input, queue, priority, delay)
152
+ async ({ delay, input, jobSlug, priority, queue }) => {
153
+ if (verboseLogs) {
154
+ req.payload.logger.info(`[payload-mcp] Run Job Tool called with: ${jobSlug}`)
155
+ }
156
+ return runJob(
157
+ req,
158
+ verboseLogs,
159
+ jobSlug,
160
+ input as Record<string, unknown>,
161
+ queue,
162
+ priority,
163
+ delay,
164
+ )
189
165
  },
190
166
  )
191
167
  }