@payloadcms/plugin-mcp 4.0.0-internal.fa183d3 → 4.0.0-internal.fec2230
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.
- package/dist/endpoint/access.js +2 -2
- package/dist/endpoint/access.js.map +1 -1
- package/dist/mcp/buildMcpServer.d.ts +1 -1
- package/dist/mcp/buildMcpServer.d.ts.map +1 -1
- package/dist/mcp/buildMcpServer.js +35 -23
- package/dist/mcp/buildMcpServer.js.map +1 -1
- package/dist/mcp/builtin/collections/authTools.d.ts.map +1 -1
- package/dist/mcp/builtin/collections/authTools.js +79 -56
- package/dist/mcp/builtin/collections/authTools.js.map +1 -1
- package/dist/mcp/builtin/collections/countTool.d.ts.map +1 -1
- package/dist/mcp/builtin/collections/countTool.js +9 -14
- package/dist/mcp/builtin/collections/countTool.js.map +1 -1
- package/dist/mcp/builtin/collections/countVersionsTool.d.ts.map +1 -1
- package/dist/mcp/builtin/collections/countVersionsTool.js +9 -13
- package/dist/mcp/builtin/collections/countVersionsTool.js.map +1 -1
- package/dist/mcp/builtin/collections/createTool.d.ts +1 -1
- package/dist/mcp/builtin/collections/createTool.d.ts.map +1 -1
- package/dist/mcp/builtin/collections/createTool.js +104 -63
- package/dist/mcp/builtin/collections/createTool.js.map +1 -1
- package/dist/mcp/builtin/collections/deleteTool.d.ts.map +1 -1
- package/dist/mcp/builtin/collections/deleteTool.js +44 -43
- package/dist/mcp/builtin/collections/deleteTool.js.map +1 -1
- package/dist/mcp/builtin/collections/duplicateTool.d.ts.map +1 -1
- package/dist/mcp/builtin/collections/duplicateTool.js +31 -37
- package/dist/mcp/builtin/collections/duplicateTool.js.map +1 -1
- package/dist/mcp/builtin/collections/fileInput.d.ts +21 -13
- package/dist/mcp/builtin/collections/fileInput.d.ts.map +1 -1
- package/dist/mcp/builtin/collections/fileInput.js +52 -64
- package/dist/mcp/builtin/collections/fileInput.js.map +1 -1
- package/dist/mcp/builtin/collections/fileInput.spec.js +20 -6
- package/dist/mcp/builtin/collections/fileInput.spec.js.map +1 -1
- package/dist/mcp/builtin/collections/findDistinctTool.d.ts.map +1 -1
- package/dist/mcp/builtin/collections/findDistinctTool.js +11 -26
- package/dist/mcp/builtin/collections/findDistinctTool.js.map +1 -1
- package/dist/mcp/builtin/collections/findTool.d.ts.map +1 -1
- package/dist/mcp/builtin/collections/findTool.js +27 -45
- package/dist/mcp/builtin/collections/findTool.js.map +1 -1
- package/dist/mcp/builtin/collections/findVersionByIDTool.d.ts.map +1 -1
- package/dist/mcp/builtin/collections/findVersionByIDTool.js +17 -26
- package/dist/mcp/builtin/collections/findVersionByIDTool.js.map +1 -1
- package/dist/mcp/builtin/collections/findVersionsTool.d.ts.map +1 -1
- package/dist/mcp/builtin/collections/findVersionsTool.js +16 -30
- package/dist/mcp/builtin/collections/findVersionsTool.js.map +1 -1
- package/dist/mcp/builtin/collections/getCollectionSchemaTool.d.ts.map +1 -1
- package/dist/mcp/builtin/collections/getCollectionSchemaTool.js +15 -14
- package/dist/mcp/builtin/collections/getCollectionSchemaTool.js.map +1 -1
- package/dist/mcp/builtin/collections/restoreVersionTool.d.ts.map +1 -1
- package/dist/mcp/builtin/collections/restoreVersionTool.js +14 -26
- package/dist/mcp/builtin/collections/restoreVersionTool.js.map +1 -1
- package/dist/mcp/builtin/collections/updateTool.d.ts.map +1 -1
- package/dist/mcp/builtin/collections/updateTool.js +58 -90
- package/dist/mcp/builtin/collections/updateTool.js.map +1 -1
- package/dist/mcp/builtin/collections/uploadInstructionsTool.d.ts +2 -0
- package/dist/mcp/builtin/collections/uploadInstructionsTool.d.ts.map +1 -0
- package/dist/mcp/builtin/collections/uploadInstructionsTool.js +55 -0
- package/dist/mcp/builtin/collections/uploadInstructionsTool.js.map +1 -0
- package/dist/mcp/builtin/formatEntityError.d.ts +16 -0
- package/dist/mcp/builtin/formatEntityError.d.ts.map +1 -0
- package/dist/mcp/builtin/formatEntityError.js +55 -0
- package/dist/mcp/builtin/formatEntityError.js.map +1 -0
- package/dist/mcp/builtin/getConfigInfoTool.d.ts.map +1 -1
- package/dist/mcp/builtin/getConfigInfoTool.js +3 -2
- package/dist/mcp/builtin/getConfigInfoTool.js.map +1 -1
- package/dist/mcp/builtin/globals/countVersionsTool.d.ts.map +1 -1
- package/dist/mcp/builtin/globals/countVersionsTool.js +9 -13
- package/dist/mcp/builtin/globals/countVersionsTool.js.map +1 -1
- package/dist/mcp/builtin/globals/findTool.d.ts.map +1 -1
- package/dist/mcp/builtin/globals/findTool.js +10 -16
- package/dist/mcp/builtin/globals/findTool.js.map +1 -1
- package/dist/mcp/builtin/globals/findVersionByIDTool.d.ts.map +1 -1
- package/dist/mcp/builtin/globals/findVersionByIDTool.js +13 -24
- package/dist/mcp/builtin/globals/findVersionByIDTool.js.map +1 -1
- package/dist/mcp/builtin/globals/findVersionsTool.d.ts.map +1 -1
- package/dist/mcp/builtin/globals/findVersionsTool.js +13 -29
- package/dist/mcp/builtin/globals/findVersionsTool.js.map +1 -1
- package/dist/mcp/builtin/globals/getGlobalSchemaTool.d.ts.map +1 -1
- package/dist/mcp/builtin/globals/getGlobalSchemaTool.js +11 -11
- package/dist/mcp/builtin/globals/getGlobalSchemaTool.js.map +1 -1
- package/dist/mcp/builtin/globals/restoreVersionTool.d.ts.map +1 -1
- package/dist/mcp/builtin/globals/restoreVersionTool.js +15 -22
- package/dist/mcp/builtin/globals/restoreVersionTool.js.map +1 -1
- package/dist/mcp/builtin/globals/updateTool.d.ts.map +1 -1
- package/dist/mcp/builtin/globals/updateTool.js +27 -36
- package/dist/mcp/builtin/globals/updateTool.js.map +1 -1
- package/dist/mcp/builtinTools.d.ts +6 -0
- package/dist/mcp/builtinTools.d.ts.map +1 -1
- package/dist/mcp/builtinTools.js +9 -3
- package/dist/mcp/builtinTools.js.map +1 -1
- package/dist/mcp/sanitizeMCPConfig.js +4 -1
- package/dist/mcp/sanitizeMCPConfig.js.map +1 -1
- package/dist/stdio.d.ts.map +1 -1
- package/dist/stdio.js +2 -1
- package/dist/stdio.js.map +1 -1
- package/dist/types.d.ts +4 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +5 -7
- package/src/endpoint/access.ts +2 -3
- package/src/mcp/buildMcpServer.ts +39 -29
- package/src/mcp/builtin/collections/authTools.ts +77 -69
- package/src/mcp/builtin/collections/countTool.ts +9 -21
- package/src/mcp/builtin/collections/countVersionsTool.ts +9 -18
- package/src/mcp/builtin/collections/createTool.ts +110 -86
- package/src/mcp/builtin/collections/deleteTool.ts +36 -64
- package/src/mcp/builtin/collections/duplicateTool.ts +35 -85
- package/src/mcp/builtin/collections/fileInput.spec.ts +20 -6
- package/src/mcp/builtin/collections/fileInput.ts +64 -76
- package/src/mcp/builtin/collections/findDistinctTool.ts +11 -63
- package/src/mcp/builtin/collections/findTool.ts +23 -105
- package/src/mcp/builtin/collections/findVersionByIDTool.ts +15 -58
- package/src/mcp/builtin/collections/findVersionsTool.ts +14 -85
- package/src/mcp/builtin/collections/getCollectionSchemaTool.ts +16 -12
- package/src/mcp/builtin/collections/restoreVersionTool.ts +14 -56
- package/src/mcp/builtin/collections/updateTool.ts +57 -111
- package/src/mcp/builtin/collections/uploadInstructionsTool.ts +64 -0
- package/src/mcp/builtin/formatEntityError.ts +77 -0
- package/src/mcp/builtin/getConfigInfoTool.ts +2 -1
- package/src/mcp/builtin/globals/countVersionsTool.ts +9 -17
- package/src/mcp/builtin/globals/findTool.ts +12 -51
- package/src/mcp/builtin/globals/findVersionByIDTool.ts +13 -52
- package/src/mcp/builtin/globals/findVersionsTool.ts +14 -92
- package/src/mcp/builtin/globals/getGlobalSchemaTool.ts +10 -10
- package/src/mcp/builtin/globals/restoreVersionTool.ts +14 -45
- package/src/mcp/builtin/globals/updateTool.ts +37 -60
- package/src/mcp/builtinTools.ts +9 -2
- package/src/mcp/sanitizeMCPConfig.ts +4 -1
- package/src/stdio.ts +2 -1
- package/src/types.ts +4 -4
- package/dist/mcp/builtin/collections/formatCollectionError.d.ts +0 -9
- package/dist/mcp/builtin/collections/formatCollectionError.d.ts.map +0 -1
- package/dist/mcp/builtin/collections/formatCollectionError.js +0 -60
- package/dist/mcp/builtin/collections/formatCollectionError.js.map +0 -1
- package/dist/mcp/builtin/validateEntityData.d.ts +0 -14
- package/dist/mcp/builtin/validateEntityData.d.ts.map +0 -1
- package/dist/mcp/builtin/validateEntityData.js +0 -82
- package/dist/mcp/builtin/validateEntityData.js.map +0 -1
- package/dist/utils/getVirtualFieldNames.d.ts +0 -14
- package/dist/utils/getVirtualFieldNames.d.ts.map +0 -1
- package/dist/utils/getVirtualFieldNames.js +0 -35
- package/dist/utils/getVirtualFieldNames.js.map +0 -1
- package/dist/utils/schemaConversion/filterFieldsByAccess.d.ts +0 -28
- package/dist/utils/schemaConversion/filterFieldsByAccess.d.ts.map +0 -1
- package/dist/utils/schemaConversion/filterFieldsByAccess.js +0 -71
- package/dist/utils/schemaConversion/filterFieldsByAccess.js.map +0 -1
- package/dist/utils/schemaConversion/getEntityInputSchema.d.ts +0 -13
- package/dist/utils/schemaConversion/getEntityInputSchema.d.ts.map +0 -1
- package/dist/utils/schemaConversion/getEntityInputSchema.js +0 -66
- package/dist/utils/schemaConversion/getEntityInputSchema.js.map +0 -1
- package/dist/utils/schemaConversion/sanitizeEntitySchema.d.ts +0 -10
- package/dist/utils/schemaConversion/sanitizeEntitySchema.d.ts.map +0 -1
- package/dist/utils/schemaConversion/sanitizeEntitySchema.js +0 -384
- package/dist/utils/schemaConversion/sanitizeEntitySchema.js.map +0 -1
- package/dist/utils/schemaConversion/sanitizeEntitySchema.spec.js +0 -133
- package/dist/utils/schemaConversion/sanitizeEntitySchema.spec.js.map +0 -1
- package/dist/utils/transformPointDataToPayload.d.ts +0 -7
- package/dist/utils/transformPointDataToPayload.d.ts.map +0 -1
- package/dist/utils/transformPointDataToPayload.js +0 -28
- package/dist/utils/transformPointDataToPayload.js.map +0 -1
- package/dist/utils/whereSchema.d.ts +0 -9
- package/dist/utils/whereSchema.d.ts.map +0 -1
- package/dist/utils/whereSchema.js +0 -13
- package/dist/utils/whereSchema.js.map +0 -1
- package/src/mcp/builtin/collections/formatCollectionError.ts +0 -84
- package/src/mcp/builtin/validateEntityData.ts +0 -132
- package/src/utils/getVirtualFieldNames.ts +0 -53
- package/src/utils/schemaConversion/filterFieldsByAccess.ts +0 -123
- package/src/utils/schemaConversion/getEntityInputSchema.ts +0 -96
- package/src/utils/schemaConversion/sanitizeEntitySchema.spec.ts +0 -96
- package/src/utils/schemaConversion/sanitizeEntitySchema.ts +0 -432
- package/src/utils/transformPointDataToPayload.ts +0 -40
- package/src/utils/whereSchema.ts +0 -24
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
import { z } from 'zod'
|
|
1
|
+
import { restoreGlobalVersionInputSchema } from 'payload'
|
|
4
2
|
|
|
5
3
|
import { defaultAccess } from '../../../defaultAccess.js'
|
|
6
4
|
import { defineGlobalTool } from '../../../defineTool.js'
|
|
@@ -10,8 +8,7 @@ const DEFAULT_DESCRIPTION =
|
|
|
10
8
|
'Restore a global from a previous version in any version-enabled global.'
|
|
11
9
|
|
|
12
10
|
export const restoreGlobalVersionTool = defineGlobalTool({
|
|
13
|
-
access: (args) =>
|
|
14
|
-
defaultAccess(args) && Boolean(args.permissions?.globals?.[args.globalSlug]?.update),
|
|
11
|
+
access: (args) => defaultAccess(args) && Boolean(args.permissions?.globals?.[args.slug]?.update),
|
|
15
12
|
annotations: {
|
|
16
13
|
destructiveHint: true,
|
|
17
14
|
idempotentHint: false,
|
|
@@ -20,53 +17,25 @@ export const restoreGlobalVersionTool = defineGlobalTool({
|
|
|
20
17
|
title: 'Restore Global Version',
|
|
21
18
|
},
|
|
22
19
|
description: DEFAULT_DESCRIPTION,
|
|
23
|
-
input:
|
|
24
|
-
|
|
25
|
-
depth: z
|
|
26
|
-
.number()
|
|
27
|
-
.int()
|
|
28
|
-
.min(0)
|
|
29
|
-
.max(10)
|
|
30
|
-
.describe('How many levels deep to populate relationships in response')
|
|
31
|
-
.optional()
|
|
32
|
-
.default(0),
|
|
33
|
-
fallbackLocale: z
|
|
34
|
-
.string()
|
|
35
|
-
.describe('Optional: fallback locale code to use when requested locale is not available')
|
|
36
|
-
.optional(),
|
|
37
|
-
locale: z
|
|
38
|
-
.string()
|
|
39
|
-
.describe('Optional: locale code to restore in (e.g., "en", "es")')
|
|
40
|
-
.optional(),
|
|
41
|
-
populate: z
|
|
42
|
-
.record(z.string(), z.unknown())
|
|
43
|
-
.describe(
|
|
44
|
-
'Optional: control which fields to include from populated relationship or upload documents.',
|
|
45
|
-
)
|
|
46
|
-
.optional(),
|
|
47
|
-
showHiddenFields: z
|
|
48
|
-
.boolean()
|
|
49
|
-
.describe('Optional: include hidden fields in the restored global response')
|
|
50
|
-
.optional(),
|
|
51
|
-
}),
|
|
52
|
-
}).handler(async ({ authorizedMCP, globalSlug, input, req }) => {
|
|
20
|
+
input: restoreGlobalVersionInputSchema,
|
|
21
|
+
}).handler(async ({ slug, authorizedMCP, input, req }) => {
|
|
53
22
|
const payload = req.payload
|
|
54
23
|
const logger = getLogger({ payload })
|
|
55
|
-
const { id, depth, fallbackLocale, locale, populate,
|
|
24
|
+
const { id, depth, fallbackLocale, locale, populate, select } = input
|
|
56
25
|
|
|
57
|
-
logger.info(`Restoring version for global: ${
|
|
26
|
+
logger.info(`Restoring version for global: ${slug} with ID: ${id}`)
|
|
58
27
|
|
|
59
28
|
try {
|
|
60
29
|
const result = await payload.restoreGlobalVersion({
|
|
61
|
-
id,
|
|
62
|
-
slug
|
|
30
|
+
id: String(id),
|
|
31
|
+
slug,
|
|
63
32
|
depth,
|
|
64
33
|
overrideAccess: authorizedMCP.overrideAccess,
|
|
65
34
|
req,
|
|
66
|
-
...(fallbackLocale ? { fallbackLocale } : {}),
|
|
35
|
+
...(fallbackLocale !== undefined ? { fallbackLocale } : {}),
|
|
67
36
|
...(locale ? { locale } : {}),
|
|
68
|
-
...(populate ? { populate
|
|
69
|
-
...(
|
|
37
|
+
...(populate ? { populate } : {}),
|
|
38
|
+
...(select ? { select } : {}),
|
|
70
39
|
})
|
|
71
40
|
const resultObject = result as Record<string, unknown>
|
|
72
41
|
const restoredGlobal =
|
|
@@ -78,19 +47,19 @@ export const restoreGlobalVersionTool = defineGlobalTool({
|
|
|
78
47
|
content: [
|
|
79
48
|
{
|
|
80
49
|
type: 'text',
|
|
81
|
-
text: `Version "${id}" restored successfully for global "${
|
|
50
|
+
text: `Version "${id}" restored successfully for global "${slug}"!\nRestored global:\n\`\`\`json\n${JSON.stringify(restoredGlobal)}\n\`\`\``,
|
|
82
51
|
},
|
|
83
52
|
],
|
|
84
53
|
doc: restoredGlobal,
|
|
85
54
|
}
|
|
86
55
|
} catch (error) {
|
|
87
56
|
const errorMessage = error instanceof Error ? error.message : 'Unknown error'
|
|
88
|
-
logger.error(`Error restoring version ${id} for global ${
|
|
57
|
+
logger.error(`Error restoring version ${id} for global ${slug}: ${errorMessage}`)
|
|
89
58
|
return {
|
|
90
59
|
content: [
|
|
91
60
|
{
|
|
92
61
|
type: 'text',
|
|
93
|
-
text: `❌ **Error restoring version "${id}" for global "${
|
|
62
|
+
text: `❌ **Error restoring version "${id}" for global "${slug}":** ${errorMessage}`,
|
|
94
63
|
},
|
|
95
64
|
],
|
|
96
65
|
isError: true,
|
|
@@ -1,22 +1,20 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import {
|
|
2
|
+
getGlobalVirtualFieldNames,
|
|
3
|
+
stripVirtualFields,
|
|
4
|
+
transformPointDataToPayload,
|
|
5
|
+
updateGlobalInputSchema,
|
|
6
|
+
validateGlobalData,
|
|
7
|
+
} from 'payload'
|
|
4
8
|
|
|
5
9
|
import { defaultAccess } from '../../../defaultAccess.js'
|
|
6
10
|
import { defineGlobalTool } from '../../../defineTool.js'
|
|
7
11
|
import { getLogger } from '../../../utils/getLogger.js'
|
|
8
|
-
import {
|
|
9
|
-
getGlobalVirtualFieldNames,
|
|
10
|
-
stripVirtualFields,
|
|
11
|
-
} from '../../../utils/getVirtualFieldNames.js'
|
|
12
|
-
import { transformPointDataToPayload } from '../../../utils/transformPointDataToPayload.js'
|
|
13
|
-
import { validateGlobalData } from '../validateEntityData.js'
|
|
12
|
+
import { formatEntityError } from '../formatEntityError.js'
|
|
14
13
|
|
|
15
14
|
const DEFAULT_DESCRIPTION = 'Update any Payload global by passing the global slug and data.'
|
|
16
15
|
|
|
17
16
|
export const updateGlobalTool = defineGlobalTool({
|
|
18
|
-
access: (args) =>
|
|
19
|
-
defaultAccess(args) && Boolean(args.permissions?.globals?.[args.globalSlug]?.update),
|
|
17
|
+
access: (args) => defaultAccess(args) && Boolean(args.permissions?.globals?.[args.slug]?.update),
|
|
20
18
|
annotations: {
|
|
21
19
|
destructiveHint: true,
|
|
22
20
|
idempotentHint: false,
|
|
@@ -25,73 +23,54 @@ export const updateGlobalTool = defineGlobalTool({
|
|
|
25
23
|
title: 'Update Global',
|
|
26
24
|
},
|
|
27
25
|
description: DEFAULT_DESCRIPTION,
|
|
28
|
-
input:
|
|
29
|
-
|
|
30
|
-
depth: z
|
|
31
|
-
.number()
|
|
32
|
-
.describe('Optional: Depth of relationships to populate')
|
|
33
|
-
.optional()
|
|
34
|
-
.default(0),
|
|
35
|
-
draft: z
|
|
36
|
-
.boolean()
|
|
37
|
-
.describe('Optional: Whether to save as draft (default: false)')
|
|
38
|
-
.optional()
|
|
39
|
-
.default(false),
|
|
40
|
-
fallbackLocale: z
|
|
41
|
-
.string()
|
|
42
|
-
.describe('Optional: fallback locale code to use when requested locale is not available')
|
|
43
|
-
.optional(),
|
|
44
|
-
locale: z
|
|
45
|
-
.string()
|
|
46
|
-
.describe(
|
|
47
|
-
'Optional: locale code to update data in (e.g., "en", "es"). Use "all" to update all locales for localized fields',
|
|
48
|
-
)
|
|
49
|
-
.optional(),
|
|
50
|
-
select: z
|
|
51
|
-
.record(z.string(), z.unknown())
|
|
52
|
-
.describe(
|
|
53
|
-
'Optional: define exactly which fields you\'d like to return in the response, e.g., {"siteName": true}',
|
|
54
|
-
)
|
|
55
|
-
.optional(),
|
|
56
|
-
}),
|
|
57
|
-
}).handler(async ({ authorizedMCP, globalSlug, input, req }) => {
|
|
26
|
+
input: updateGlobalInputSchema,
|
|
27
|
+
}).handler(async ({ slug, authorizedMCP, input, req }) => {
|
|
58
28
|
const payload = req.payload
|
|
59
29
|
const logger = getLogger({ payload })
|
|
60
30
|
|
|
61
|
-
const {
|
|
31
|
+
const {
|
|
32
|
+
data,
|
|
33
|
+
depth,
|
|
34
|
+
draft,
|
|
35
|
+
fallbackLocale,
|
|
36
|
+
locale,
|
|
37
|
+
overrideLock,
|
|
38
|
+
populate,
|
|
39
|
+
publishAllLocales,
|
|
40
|
+
select,
|
|
41
|
+
unpublishAllLocales,
|
|
42
|
+
} = input
|
|
62
43
|
|
|
63
|
-
logger.info(
|
|
64
|
-
`Updating global: ${globalSlug}, draft: ${draft}${locale ? `, locale: ${locale}` : ''}`,
|
|
65
|
-
)
|
|
44
|
+
logger.info(`Updating global: ${slug}, draft: ${draft}${locale ? `, locale: ${locale}` : ''}`)
|
|
66
45
|
|
|
67
46
|
try {
|
|
68
|
-
const virtualFieldNames = getGlobalVirtualFieldNames(payload.config,
|
|
47
|
+
const virtualFieldNames = getGlobalVirtualFieldNames(payload.config, slug)
|
|
69
48
|
const inputData = stripVirtualFields(data, virtualFieldNames)
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
if (validationError) {
|
|
73
|
-
return validationError
|
|
74
|
-
}
|
|
49
|
+
validateGlobalData({ slug, data: inputData, req })
|
|
75
50
|
|
|
76
51
|
const parsedData = transformPointDataToPayload(inputData)
|
|
77
52
|
|
|
78
53
|
const updateOptions: Parameters<typeof payload.updateGlobal>[0] = {
|
|
79
|
-
slug
|
|
54
|
+
slug,
|
|
80
55
|
data: parsedData,
|
|
81
56
|
depth,
|
|
82
57
|
draft,
|
|
83
58
|
overrideAccess: authorizedMCP.overrideAccess,
|
|
59
|
+
overrideLock,
|
|
60
|
+
populate,
|
|
61
|
+
publishAllLocales,
|
|
84
62
|
req,
|
|
63
|
+
unpublishAllLocales,
|
|
85
64
|
}
|
|
86
65
|
|
|
87
66
|
if (locale) {
|
|
88
67
|
updateOptions.locale = locale
|
|
89
68
|
}
|
|
90
|
-
if (fallbackLocale) {
|
|
69
|
+
if (fallbackLocale !== undefined) {
|
|
91
70
|
updateOptions.fallbackLocale = fallbackLocale
|
|
92
71
|
}
|
|
93
72
|
if (select) {
|
|
94
|
-
updateOptions.select = select
|
|
73
|
+
updateOptions.select = select
|
|
95
74
|
}
|
|
96
75
|
|
|
97
76
|
const result = await payload.updateGlobal(updateOptions)
|
|
@@ -100,16 +79,14 @@ export const updateGlobalTool = defineGlobalTool({
|
|
|
100
79
|
content: [
|
|
101
80
|
{
|
|
102
81
|
type: 'text',
|
|
103
|
-
text: `Global "${
|
|
82
|
+
text: `Global "${slug}" updated successfully!\n\`\`\`json\n${JSON.stringify(result)}\n\`\`\``,
|
|
104
83
|
},
|
|
105
84
|
],
|
|
106
85
|
doc: result as Record<string, unknown>,
|
|
107
86
|
}
|
|
108
87
|
} catch (error) {
|
|
109
|
-
const
|
|
110
|
-
logger.error(`Error updating global ${
|
|
111
|
-
return {
|
|
112
|
-
content: [{ type: 'text', text: `Error updating global "${globalSlug}": ${errorMessage}` }],
|
|
113
|
-
}
|
|
88
|
+
const message = error instanceof Error ? error.message : 'Unknown error'
|
|
89
|
+
logger.error(`Error updating global ${slug}: ${message}`)
|
|
90
|
+
return formatEntityError({ slug, action: 'updating', entity: 'global', error, req })
|
|
114
91
|
}
|
|
115
92
|
})
|
package/src/mcp/builtinTools.ts
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
} from './builtin/collections/authTools.js'
|
|
11
11
|
import { countDocumentsTool } from './builtin/collections/countTool.js'
|
|
12
12
|
import { countVersionsTool } from './builtin/collections/countVersionsTool.js'
|
|
13
|
-
import {
|
|
13
|
+
import { createDocumentsTool } from './builtin/collections/createTool.js'
|
|
14
14
|
import { deleteDocumentsTool } from './builtin/collections/deleteTool.js'
|
|
15
15
|
import { duplicateDocumentTool } from './builtin/collections/duplicateTool.js'
|
|
16
16
|
import { findDistinctTool } from './builtin/collections/findDistinctTool.js'
|
|
@@ -20,6 +20,7 @@ import { findVersionsTool } from './builtin/collections/findVersionsTool.js'
|
|
|
20
20
|
import { getCollectionSchemaTool } from './builtin/collections/getCollectionSchemaTool.js'
|
|
21
21
|
import { restoreVersionTool } from './builtin/collections/restoreVersionTool.js'
|
|
22
22
|
import { updateDocumentTool } from './builtin/collections/updateTool.js'
|
|
23
|
+
import { getUploadInstructionsTool } from './builtin/collections/uploadInstructionsTool.js'
|
|
23
24
|
import { getConfigInfoTool } from './builtin/getConfigInfoTool.js'
|
|
24
25
|
import { countGlobalVersionsTool } from './builtin/globals/countVersionsTool.js'
|
|
25
26
|
import { findGlobalTool } from './builtin/globals/findTool.js'
|
|
@@ -32,6 +33,7 @@ import { updateGlobalTool } from './builtin/globals/updateTool.js'
|
|
|
32
33
|
type CollectionBuiltin = {
|
|
33
34
|
mcpName: string
|
|
34
35
|
requiresDuplicateEnabled?: boolean
|
|
36
|
+
requiresUpload?: boolean
|
|
35
37
|
requiresVersions?: boolean
|
|
36
38
|
tool: CollectionTool
|
|
37
39
|
}
|
|
@@ -54,7 +56,7 @@ export const TOOL_BUILTINS = {
|
|
|
54
56
|
export const COLLECTION_BUILTINS = {
|
|
55
57
|
count: { mcpName: 'countDocuments', tool: countDocumentsTool },
|
|
56
58
|
countVersions: { mcpName: 'countVersions', requiresVersions: true, tool: countVersionsTool },
|
|
57
|
-
create: { mcpName: '
|
|
59
|
+
create: { mcpName: 'createDocuments', tool: createDocumentsTool },
|
|
58
60
|
delete: { mcpName: 'deleteDocuments', tool: deleteDocumentsTool },
|
|
59
61
|
duplicate: {
|
|
60
62
|
mcpName: 'duplicateDocument',
|
|
@@ -70,6 +72,11 @@ export const COLLECTION_BUILTINS = {
|
|
|
70
72
|
},
|
|
71
73
|
findVersions: { mcpName: 'findVersions', requiresVersions: true, tool: findVersionsTool },
|
|
72
74
|
getCollectionSchema: { mcpName: 'getCollectionSchema', tool: getCollectionSchemaTool },
|
|
75
|
+
getUploadInstructions: {
|
|
76
|
+
mcpName: 'getUploadInstructions',
|
|
77
|
+
requiresUpload: true,
|
|
78
|
+
tool: getUploadInstructionsTool,
|
|
79
|
+
},
|
|
73
80
|
restoreVersion: { mcpName: 'restoreVersion', requiresVersions: true, tool: restoreVersionTool },
|
|
74
81
|
update: { mcpName: 'updateDocument', tool: updateDocumentTool },
|
|
75
82
|
} satisfies Record<string, CollectionBuiltin>
|
|
@@ -127,7 +127,7 @@ const sanitizeCollectionConfig = ({
|
|
|
127
127
|
|
|
128
128
|
for (const [
|
|
129
129
|
toolKey,
|
|
130
|
-
{ mcpName, requiresDuplicateEnabled, requiresVersions, tool },
|
|
130
|
+
{ mcpName, requiresDuplicateEnabled, requiresUpload, requiresVersions, tool },
|
|
131
131
|
] of COLLECTION_BUILTIN_ENTRIES) {
|
|
132
132
|
if (requiresVersions && !collection.versions) {
|
|
133
133
|
continue
|
|
@@ -135,6 +135,9 @@ const sanitizeCollectionConfig = ({
|
|
|
135
135
|
if (requiresDuplicateEnabled && isDuplicateDisabled) {
|
|
136
136
|
continue
|
|
137
137
|
}
|
|
138
|
+
if (requiresUpload && !collection.upload) {
|
|
139
|
+
continue
|
|
140
|
+
}
|
|
138
141
|
const matchedConfigEntry = collectionPluginConfig?.tools?.[toolKey]
|
|
139
142
|
if (matchedConfigEntry === false) {
|
|
140
143
|
continue
|
package/src/stdio.ts
CHANGED
|
@@ -4,7 +4,7 @@ import type { Config, Plugin, SanitizedConfig } from 'payload'
|
|
|
4
4
|
import { serveStdio } from '@modelcontextprotocol/server/stdio'
|
|
5
5
|
import { fileURLToPath, pathToFileURL } from 'node:url'
|
|
6
6
|
import { createLocalReq, getPayload } from 'payload'
|
|
7
|
-
import { findConfig } from 'payload/node'
|
|
7
|
+
import { findConfig, loadEnv } from 'payload/node'
|
|
8
8
|
|
|
9
9
|
import type { SanitizedMCPPluginConfig } from './types.js'
|
|
10
10
|
|
|
@@ -28,6 +28,7 @@ export const runMcpStdio = async (): Promise<void> => {
|
|
|
28
28
|
process.chdir(projectRoot)
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
loadEnv()
|
|
31
32
|
const configPath = findConfig()
|
|
32
33
|
const configModule = await import(pathToFileURL(configPath).toString())
|
|
33
34
|
const config = (await (configModule.default ?? configModule)) as SanitizedConfig
|
package/src/types.ts
CHANGED
|
@@ -75,11 +75,11 @@ export type MCPAccessArgs = {
|
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
export type CollectionMCPAccessArgs = {
|
|
78
|
-
|
|
78
|
+
slug: CollectionSlug
|
|
79
79
|
} & MCPAccessArgs
|
|
80
80
|
|
|
81
81
|
export type GlobalMCPAccessArgs = {
|
|
82
|
-
|
|
82
|
+
slug: GlobalSlug
|
|
83
83
|
} & MCPAccessArgs
|
|
84
84
|
|
|
85
85
|
export type ToolHandlerArgs<TSchema = undefined> = {
|
|
@@ -90,11 +90,11 @@ export type ToolHandlerArgs<TSchema = undefined> = {
|
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
export type CollectionToolHandlerArgs<TSchema = undefined> = {
|
|
93
|
-
|
|
93
|
+
slug: CollectionSlug
|
|
94
94
|
} & ToolHandlerArgs<TSchema>
|
|
95
95
|
|
|
96
96
|
export type GlobalToolHandlerArgs<TSchema = undefined> = {
|
|
97
|
-
|
|
97
|
+
slug: GlobalSlug
|
|
98
98
|
} & ToolHandlerArgs<TSchema>
|
|
99
99
|
|
|
100
100
|
export type Tool<TSchema extends ToolInputSchema | undefined = ToolInputSchema | undefined> = {
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { CollectionSlug, PayloadRequest } from 'payload';
|
|
2
|
-
import type { MCPToolResponse } from '../../../types.js';
|
|
3
|
-
export declare const formatCollectionError: ({ action, collectionSlug, error, req, }: {
|
|
4
|
-
action: 'creating' | 'duplicating' | 'updating';
|
|
5
|
-
collectionSlug: CollectionSlug;
|
|
6
|
-
error: unknown;
|
|
7
|
-
req: PayloadRequest;
|
|
8
|
-
}) => MCPToolResponse;
|
|
9
|
-
//# sourceMappingURL=formatCollectionError.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"formatCollectionError.d.ts","sourceRoot":"","sources":["../../../../src/mcp/builtin/collections/formatCollectionError.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAE7D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAgCxD,eAAO,MAAM,qBAAqB,4CAK/B;IACD,MAAM,EAAE,UAAU,GAAG,aAAa,GAAG,UAAU,CAAA;IAC/C,cAAc,EAAE,cAAc,CAAA;IAC9B,KAAK,EAAE,OAAO,CAAA;IACd,GAAG,EAAE,cAAc,CAAA;CACpB,KAAG,eAuCH,CAAA"}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { getCollectionInputSchema } from '../../../utils/schemaConversion/getEntityInputSchema.js';
|
|
2
|
-
const getValidationErrors = (error)=>{
|
|
3
|
-
if (!error || typeof error !== 'object') {
|
|
4
|
-
return undefined;
|
|
5
|
-
}
|
|
6
|
-
const data = 'data' in error ? error.data : undefined;
|
|
7
|
-
if (!data || typeof data !== 'object' || !('errors' in data) || !Array.isArray(data.errors)) {
|
|
8
|
-
return undefined;
|
|
9
|
-
}
|
|
10
|
-
return data.errors;
|
|
11
|
-
};
|
|
12
|
-
const isSchemaError = (error, message)=>{
|
|
13
|
-
if (getValidationErrors(error)) {
|
|
14
|
-
return true;
|
|
15
|
-
}
|
|
16
|
-
const name = error && typeof error === 'object' && 'name' in error ? error.name : undefined;
|
|
17
|
-
return name === 'CastError' || name === 'ValidationError' || message.includes('Cast to ') || message.includes('validation failed');
|
|
18
|
-
};
|
|
19
|
-
export const formatCollectionError = ({ action, collectionSlug, error, req })=>{
|
|
20
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
21
|
-
const errors = getValidationErrors(error) ?? [
|
|
22
|
-
{
|
|
23
|
-
message: errorMessage
|
|
24
|
-
}
|
|
25
|
-
];
|
|
26
|
-
if (!isSchemaError(error, errorMessage)) {
|
|
27
|
-
return {
|
|
28
|
-
content: [
|
|
29
|
-
{
|
|
30
|
-
type: 'text',
|
|
31
|
-
text: `Error ${action} document in collection "${collectionSlug}": ${errorMessage}`
|
|
32
|
-
}
|
|
33
|
-
],
|
|
34
|
-
isError: true
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
const schema = getCollectionInputSchema({
|
|
38
|
-
collectionSlug,
|
|
39
|
-
req
|
|
40
|
-
});
|
|
41
|
-
const schemaText = schema ? `\n\nUse this schema for data:\n\`\`\`json\n${JSON.stringify(schema)}\n\`\`\`` : '';
|
|
42
|
-
return {
|
|
43
|
-
content: [
|
|
44
|
-
{
|
|
45
|
-
type: 'text',
|
|
46
|
-
text: `Error ${action} document in collection "${collectionSlug}": ${errorMessage}${schemaText}`
|
|
47
|
-
}
|
|
48
|
-
],
|
|
49
|
-
isError: true,
|
|
50
|
-
...schema ? {
|
|
51
|
-
structuredContent: {
|
|
52
|
-
collectionSlug,
|
|
53
|
-
errors,
|
|
54
|
-
schema
|
|
55
|
-
}
|
|
56
|
-
} : {}
|
|
57
|
-
};
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
//# sourceMappingURL=formatCollectionError.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/mcp/builtin/collections/formatCollectionError.ts"],"sourcesContent":["import type { CollectionSlug, PayloadRequest } from 'payload'\n\nimport type { MCPToolResponse } from '../../../types.js'\n\nimport { getCollectionInputSchema } from '../../../utils/schemaConversion/getEntityInputSchema.js'\n\nconst getValidationErrors = (error: unknown): undefined | unknown[] => {\n if (!error || typeof error !== 'object') {\n return undefined\n }\n\n const data = 'data' in error ? error.data : undefined\n if (!data || typeof data !== 'object' || !('errors' in data) || !Array.isArray(data.errors)) {\n return undefined\n }\n\n return data.errors\n}\n\nconst isSchemaError = (error: unknown, message: string): boolean => {\n if (getValidationErrors(error)) {\n return true\n }\n\n const name = error && typeof error === 'object' && 'name' in error ? error.name : undefined\n\n return (\n name === 'CastError' ||\n name === 'ValidationError' ||\n message.includes('Cast to ') ||\n message.includes('validation failed')\n )\n}\n\nexport const formatCollectionError = ({\n action,\n collectionSlug,\n error,\n req,\n}: {\n action: 'creating' | 'duplicating' | 'updating'\n collectionSlug: CollectionSlug\n error: unknown\n req: PayloadRequest\n}): MCPToolResponse => {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error'\n const errors = getValidationErrors(error) ?? [{ message: errorMessage }]\n\n if (!isSchemaError(error, errorMessage)) {\n return {\n content: [\n {\n type: 'text',\n text: `Error ${action} document in collection \"${collectionSlug}\": ${errorMessage}`,\n },\n ],\n isError: true,\n }\n }\n\n const schema = getCollectionInputSchema({ collectionSlug, req })\n const schemaText = schema\n ? `\\n\\nUse this schema for data:\\n\\`\\`\\`json\\n${JSON.stringify(schema)}\\n\\`\\`\\``\n : ''\n\n return {\n content: [\n {\n type: 'text',\n text: `Error ${action} document in collection \"${collectionSlug}\": ${errorMessage}${schemaText}`,\n },\n ],\n isError: true,\n ...(schema\n ? {\n structuredContent: {\n collectionSlug,\n errors,\n schema,\n },\n }\n : {}),\n }\n}\n"],"names":["getCollectionInputSchema","getValidationErrors","error","undefined","data","Array","isArray","errors","isSchemaError","message","name","includes","formatCollectionError","action","collectionSlug","req","errorMessage","Error","content","type","text","isError","schema","schemaText","JSON","stringify","structuredContent"],"mappings":"AAIA,SAASA,wBAAwB,QAAQ,0DAAyD;AAElG,MAAMC,sBAAsB,CAACC;IAC3B,IAAI,CAACA,SAAS,OAAOA,UAAU,UAAU;QACvC,OAAOC;IACT;IAEA,MAAMC,OAAO,UAAUF,QAAQA,MAAME,IAAI,GAAGD;IAC5C,IAAI,CAACC,QAAQ,OAAOA,SAAS,YAAY,CAAE,CAAA,YAAYA,IAAG,KAAM,CAACC,MAAMC,OAAO,CAACF,KAAKG,MAAM,GAAG;QAC3F,OAAOJ;IACT;IAEA,OAAOC,KAAKG,MAAM;AACpB;AAEA,MAAMC,gBAAgB,CAACN,OAAgBO;IACrC,IAAIR,oBAAoBC,QAAQ;QAC9B,OAAO;IACT;IAEA,MAAMQ,OAAOR,SAAS,OAAOA,UAAU,YAAY,UAAUA,QAAQA,MAAMQ,IAAI,GAAGP;IAElF,OACEO,SAAS,eACTA,SAAS,qBACTD,QAAQE,QAAQ,CAAC,eACjBF,QAAQE,QAAQ,CAAC;AAErB;AAEA,OAAO,MAAMC,wBAAwB,CAAC,EACpCC,MAAM,EACNC,cAAc,EACdZ,KAAK,EACLa,GAAG,EAMJ;IACC,MAAMC,eAAed,iBAAiBe,QAAQf,MAAMO,OAAO,GAAG;IAC9D,MAAMF,SAASN,oBAAoBC,UAAU;QAAC;YAAEO,SAASO;QAAa;KAAE;IAExE,IAAI,CAACR,cAAcN,OAAOc,eAAe;QACvC,OAAO;YACLE,SAAS;gBACP;oBACEC,MAAM;oBACNC,MAAM,CAAC,MAAM,EAAEP,OAAO,yBAAyB,EAAEC,eAAe,GAAG,EAAEE,cAAc;gBACrF;aACD;YACDK,SAAS;QACX;IACF;IAEA,MAAMC,SAAStB,yBAAyB;QAAEc;QAAgBC;IAAI;IAC9D,MAAMQ,aAAaD,SACf,CAAC,2CAA2C,EAAEE,KAAKC,SAAS,CAACH,QAAQ,QAAQ,CAAC,GAC9E;IAEJ,OAAO;QACLJ,SAAS;YACP;gBACEC,MAAM;gBACNC,MAAM,CAAC,MAAM,EAAEP,OAAO,yBAAyB,EAAEC,eAAe,GAAG,EAAEE,eAAeO,YAAY;YAClG;SACD;QACDF,SAAS;QACT,GAAIC,SACA;YACEI,mBAAmB;gBACjBZ;gBACAP;gBACAe;YACF;QACF,IACA,CAAC,CAAC;IACR;AACF,EAAC"}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import type { CollectionSlug, GlobalSlug, PayloadRequest } from 'payload';
|
|
2
|
-
import type { MCPToolResponse } from '../../types.js';
|
|
3
|
-
export declare const validateCollectionData: ({ collectionSlug, data, partial, req, }: {
|
|
4
|
-
collectionSlug: CollectionSlug;
|
|
5
|
-
data: Record<string, unknown>;
|
|
6
|
-
partial?: boolean;
|
|
7
|
-
req: PayloadRequest;
|
|
8
|
-
}) => MCPToolResponse | null;
|
|
9
|
-
export declare const validateGlobalData: ({ data, globalSlug, req, }: {
|
|
10
|
-
data: Record<string, unknown>;
|
|
11
|
-
globalSlug: GlobalSlug;
|
|
12
|
-
req: PayloadRequest;
|
|
13
|
-
}) => MCPToolResponse | null;
|
|
14
|
-
//# sourceMappingURL=validateEntityData.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"validateEntityData.d.ts","sourceRoot":"","sources":["../../../src/mcp/builtin/validateEntityData.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,cAAc,EAAmB,MAAM,SAAS,CAAA;AAI1F,OAAO,KAAK,EAAkB,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAuBrE,eAAO,MAAM,sBAAsB,4CAKhC;IACD,cAAc,EAAE,cAAc,CAAA;IAC9B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,GAAG,EAAE,cAAc,CAAA;CACpB,KAAG,eAAe,GAAG,IAQlB,CAAA;AAEJ,eAAO,MAAM,kBAAkB,+BAI5B;IACD,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC7B,UAAU,EAAE,UAAU,CAAA;IACtB,GAAG,EAAE,cAAc,CAAA;CACpB,KAAG,eAAe,GAAG,IAQlB,CAAA"}
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { CfWorkerJsonSchemaValidator } from '@modelcontextprotocol/server/validators/cf-worker';
|
|
2
|
-
import { getCollectionInputSchema, getGlobalInputSchema } from '../../utils/schemaConversion/getEntityInputSchema.js';
|
|
3
|
-
/**
|
|
4
|
-
* Keep the default `shortcircuit: true` - `false` makes validating nested rich text exponentially slow.
|
|
5
|
-
*/ const validator = new CfWorkerJsonSchemaValidator({
|
|
6
|
-
shortcircuit: true
|
|
7
|
-
});
|
|
8
|
-
/**
|
|
9
|
-
* - Caches each entity's schema and validator, so both are only built on the first request.
|
|
10
|
-
* - Keyed by payload config, then by entity type, slug, partial and language.
|
|
11
|
-
*/ const validatorCache = new WeakMap();
|
|
12
|
-
export const validateCollectionData = ({ collectionSlug, data, partial, req })=>validateData({
|
|
13
|
-
slug: collectionSlug,
|
|
14
|
-
buildSchema: ()=>getCollectionInputSchema({
|
|
15
|
-
collectionSlug,
|
|
16
|
-
req
|
|
17
|
-
}),
|
|
18
|
-
data,
|
|
19
|
-
entity: 'collection',
|
|
20
|
-
partial,
|
|
21
|
-
req
|
|
22
|
-
});
|
|
23
|
-
export const validateGlobalData = ({ data, globalSlug, req })=>validateData({
|
|
24
|
-
slug: globalSlug,
|
|
25
|
-
buildSchema: ()=>getGlobalInputSchema({
|
|
26
|
-
globalSlug,
|
|
27
|
-
req
|
|
28
|
-
}),
|
|
29
|
-
data,
|
|
30
|
-
entity: 'global',
|
|
31
|
-
partial: true,
|
|
32
|
-
req
|
|
33
|
-
});
|
|
34
|
-
const validateData = ({ slug, buildSchema, data, entity, partial, req })=>{
|
|
35
|
-
let cache = validatorCache.get(req.payload.config);
|
|
36
|
-
if (!cache) {
|
|
37
|
-
cache = new Map();
|
|
38
|
-
validatorCache.set(req.payload.config, cache);
|
|
39
|
-
}
|
|
40
|
-
const cacheKey = `${entity}:${slug}:${partial ? 'partial' : 'full'}:${req.i18n.language}`;
|
|
41
|
-
let entityValidator = cache.get(cacheKey);
|
|
42
|
-
if (!entityValidator) {
|
|
43
|
-
const schema = buildSchema();
|
|
44
|
-
if (!schema) {
|
|
45
|
-
return null;
|
|
46
|
-
}
|
|
47
|
-
entityValidator = {
|
|
48
|
-
schema,
|
|
49
|
-
validate: validator.getValidator(partial ? withoutRequired(schema) : schema)
|
|
50
|
-
};
|
|
51
|
-
cache.set(cacheKey, entityValidator);
|
|
52
|
-
}
|
|
53
|
-
const result = entityValidator.validate(data);
|
|
54
|
-
if (result.valid) {
|
|
55
|
-
return null;
|
|
56
|
-
}
|
|
57
|
-
const { schema } = entityValidator;
|
|
58
|
-
return {
|
|
59
|
-
content: [
|
|
60
|
-
{
|
|
61
|
-
type: 'text',
|
|
62
|
-
text: `Invalid data for ${entity} "${slug}": ${result.errorMessage}\n\nUse this schema for data:\n\`\`\`json\n${JSON.stringify(schema)}\n\`\`\``
|
|
63
|
-
}
|
|
64
|
-
],
|
|
65
|
-
isError: true,
|
|
66
|
-
structuredContent: {
|
|
67
|
-
[`${entity}Slug`]: slug,
|
|
68
|
-
errors: [
|
|
69
|
-
{
|
|
70
|
-
message: result.errorMessage
|
|
71
|
-
}
|
|
72
|
-
],
|
|
73
|
-
schema
|
|
74
|
-
}
|
|
75
|
-
};
|
|
76
|
-
};
|
|
77
|
-
/** Updates are partial — drop the schema's top-level `required` before validating. */ const withoutRequired = (schema)=>{
|
|
78
|
-
const { required: _required, ...rest } = schema;
|
|
79
|
-
return rest;
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
//# sourceMappingURL=validateEntityData.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/mcp/builtin/validateEntityData.ts"],"sourcesContent":["import type { CollectionSlug, GlobalSlug, PayloadRequest, SanitizedConfig } from 'payload'\n\nimport { CfWorkerJsonSchemaValidator } from '@modelcontextprotocol/server/validators/cf-worker'\n\nimport type { JsonSchemaType, MCPToolResponse } from '../../types.js'\n\nimport {\n getCollectionInputSchema,\n getGlobalInputSchema,\n} from '../../utils/schemaConversion/getEntityInputSchema.js'\n\n/**\n * Keep the default `shortcircuit: true` - `false` makes validating nested rich text exponentially slow.\n */\nconst validator = new CfWorkerJsonSchemaValidator({ shortcircuit: true })\n\ntype EntityValidator = {\n schema: JsonSchemaType\n validate: ReturnType<(typeof validator)['getValidator']>\n}\n\n/**\n * - Caches each entity's schema and validator, so both are only built on the first request.\n * - Keyed by payload config, then by entity type, slug, partial and language.\n */\nconst validatorCache = new WeakMap<SanitizedConfig, Map<string, EntityValidator>>()\n\nexport const validateCollectionData = ({\n collectionSlug,\n data,\n partial,\n req,\n}: {\n collectionSlug: CollectionSlug\n data: Record<string, unknown>\n partial?: boolean\n req: PayloadRequest\n}): MCPToolResponse | null =>\n validateData({\n slug: collectionSlug,\n buildSchema: () => getCollectionInputSchema({ collectionSlug, req }),\n data,\n entity: 'collection',\n partial,\n req,\n })\n\nexport const validateGlobalData = ({\n data,\n globalSlug,\n req,\n}: {\n data: Record<string, unknown>\n globalSlug: GlobalSlug\n req: PayloadRequest\n}): MCPToolResponse | null =>\n validateData({\n slug: globalSlug,\n buildSchema: () => getGlobalInputSchema({ globalSlug, req }),\n data,\n entity: 'global',\n partial: true,\n req,\n })\n\nconst validateData = ({\n slug,\n buildSchema,\n data,\n entity,\n partial,\n req,\n}: {\n buildSchema: () => JsonSchemaType | null\n data: Record<string, unknown>\n entity: 'collection' | 'global'\n partial?: boolean\n req: PayloadRequest\n slug: string\n}): MCPToolResponse | null => {\n let cache = validatorCache.get(req.payload.config)\n if (!cache) {\n cache = new Map()\n validatorCache.set(req.payload.config, cache)\n }\n\n const cacheKey = `${entity}:${slug}:${partial ? 'partial' : 'full'}:${req.i18n.language}`\n let entityValidator = cache.get(cacheKey)\n\n if (!entityValidator) {\n const schema = buildSchema()\n\n if (!schema) {\n return null\n }\n\n entityValidator = {\n schema,\n validate: validator.getValidator(partial ? withoutRequired(schema) : schema),\n }\n cache.set(cacheKey, entityValidator)\n }\n\n const result = entityValidator.validate(data)\n\n if (result.valid) {\n return null\n }\n\n const { schema } = entityValidator\n\n return {\n content: [\n {\n type: 'text',\n text: `Invalid data for ${entity} \"${slug}\": ${result.errorMessage}\\n\\nUse this schema for data:\\n\\`\\`\\`json\\n${JSON.stringify(schema)}\\n\\`\\`\\``,\n },\n ],\n isError: true,\n structuredContent: {\n [`${entity}Slug`]: slug,\n errors: [{ message: result.errorMessage }],\n schema,\n },\n }\n}\n\n/** Updates are partial — drop the schema's top-level `required` before validating. */\nconst withoutRequired = (schema: JsonSchemaType): JsonSchemaType => {\n const { required: _required, ...rest } = schema\n return rest\n}\n"],"names":["CfWorkerJsonSchemaValidator","getCollectionInputSchema","getGlobalInputSchema","validator","shortcircuit","validatorCache","WeakMap","validateCollectionData","collectionSlug","data","partial","req","validateData","slug","buildSchema","entity","validateGlobalData","globalSlug","cache","get","payload","config","Map","set","cacheKey","i18n","language","entityValidator","schema","validate","getValidator","withoutRequired","result","valid","content","type","text","errorMessage","JSON","stringify","isError","structuredContent","errors","message","required","_required","rest"],"mappings":"AAEA,SAASA,2BAA2B,QAAQ,oDAAmD;AAI/F,SACEC,wBAAwB,EACxBC,oBAAoB,QACf,uDAAsD;AAE7D;;CAEC,GACD,MAAMC,YAAY,IAAIH,4BAA4B;IAAEI,cAAc;AAAK;AAOvE;;;CAGC,GACD,MAAMC,iBAAiB,IAAIC;AAE3B,OAAO,MAAMC,yBAAyB,CAAC,EACrCC,cAAc,EACdC,IAAI,EACJC,OAAO,EACPC,GAAG,EAMJ,GACCC,aAAa;QACXC,MAAML;QACNM,aAAa,IAAMb,yBAAyB;gBAAEO;gBAAgBG;YAAI;QAClEF;QACAM,QAAQ;QACRL;QACAC;IACF,GAAE;AAEJ,OAAO,MAAMK,qBAAqB,CAAC,EACjCP,IAAI,EACJQ,UAAU,EACVN,GAAG,EAKJ,GACCC,aAAa;QACXC,MAAMI;QACNH,aAAa,IAAMZ,qBAAqB;gBAAEe;gBAAYN;YAAI;QAC1DF;QACAM,QAAQ;QACRL,SAAS;QACTC;IACF,GAAE;AAEJ,MAAMC,eAAe,CAAC,EACpBC,IAAI,EACJC,WAAW,EACXL,IAAI,EACJM,MAAM,EACNL,OAAO,EACPC,GAAG,EAQJ;IACC,IAAIO,QAAQb,eAAec,GAAG,CAACR,IAAIS,OAAO,CAACC,MAAM;IACjD,IAAI,CAACH,OAAO;QACVA,QAAQ,IAAII;QACZjB,eAAekB,GAAG,CAACZ,IAAIS,OAAO,CAACC,MAAM,EAAEH;IACzC;IAEA,MAAMM,WAAW,GAAGT,OAAO,CAAC,EAAEF,KAAK,CAAC,EAAEH,UAAU,YAAY,OAAO,CAAC,EAAEC,IAAIc,IAAI,CAACC,QAAQ,EAAE;IACzF,IAAIC,kBAAkBT,MAAMC,GAAG,CAACK;IAEhC,IAAI,CAACG,iBAAiB;QACpB,MAAMC,SAASd;QAEf,IAAI,CAACc,QAAQ;YACX,OAAO;QACT;QAEAD,kBAAkB;YAChBC;YACAC,UAAU1B,UAAU2B,YAAY,CAACpB,UAAUqB,gBAAgBH,UAAUA;QACvE;QACAV,MAAMK,GAAG,CAACC,UAAUG;IACtB;IAEA,MAAMK,SAASL,gBAAgBE,QAAQ,CAACpB;IAExC,IAAIuB,OAAOC,KAAK,EAAE;QAChB,OAAO;IACT;IAEA,MAAM,EAAEL,MAAM,EAAE,GAAGD;IAEnB,OAAO;QACLO,SAAS;YACP;gBACEC,MAAM;gBACNC,MAAM,CAAC,iBAAiB,EAAErB,OAAO,EAAE,EAAEF,KAAK,GAAG,EAAEmB,OAAOK,YAAY,CAAC,2CAA2C,EAAEC,KAAKC,SAAS,CAACX,QAAQ,QAAQ,CAAC;YAClJ;SACD;QACDY,SAAS;QACTC,mBAAmB;YACjB,CAAC,GAAG1B,OAAO,IAAI,CAAC,CAAC,EAAEF;YACnB6B,QAAQ;gBAAC;oBAAEC,SAASX,OAAOK,YAAY;gBAAC;aAAE;YAC1CT;QACF;IACF;AACF;AAEA,oFAAoF,GACpF,MAAMG,kBAAkB,CAACH;IACvB,MAAM,EAAEgB,UAAUC,SAAS,EAAE,GAAGC,MAAM,GAAGlB;IACzC,OAAOkB;AACT"}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import type { SanitizedConfig } from 'payload';
|
|
2
|
-
/**
|
|
3
|
-
* Returns the names of all top-level virtual fields for a given collection slug.
|
|
4
|
-
*/
|
|
5
|
-
export declare function getCollectionVirtualFieldNames(config: SanitizedConfig, slug: string): string[];
|
|
6
|
-
/**
|
|
7
|
-
* Returns the names of all top-level virtual fields for a given global slug.
|
|
8
|
-
*/
|
|
9
|
-
export declare function getGlobalVirtualFieldNames(config: SanitizedConfig, slug: string): string[];
|
|
10
|
-
/**
|
|
11
|
-
* Strips virtual field values from a data object given a list of virtual field names.
|
|
12
|
-
*/
|
|
13
|
-
export declare function stripVirtualFields(data: Record<string, unknown>, virtualFieldNames: string[]): Record<string, unknown>;
|
|
14
|
-
//# sourceMappingURL=getVirtualFieldNames.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"getVirtualFieldNames.d.ts","sourceRoot":"","sources":["../../src/utils/getVirtualFieldNames.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAI9C;;GAEG;AACH,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAU9F;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAU1F;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,iBAAiB,EAAE,MAAM,EAAE,GAC1B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAYzB"}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { fieldIsVirtual } from 'payload/shared';
|
|
2
|
-
/**
|
|
3
|
-
* Returns the names of all top-level virtual fields for a given collection slug.
|
|
4
|
-
*/ export function getCollectionVirtualFieldNames(config, slug) {
|
|
5
|
-
const collection = config.collections.find((c)=>c.slug === slug);
|
|
6
|
-
if (!collection) {
|
|
7
|
-
return [];
|
|
8
|
-
}
|
|
9
|
-
return collection.flattenedFields.filter((field)=>'name' in field && fieldIsVirtual(field)).map((field)=>field.name);
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
* Returns the names of all top-level virtual fields for a given global slug.
|
|
13
|
-
*/ export function getGlobalVirtualFieldNames(config, slug) {
|
|
14
|
-
const global = config.globals.find((g)=>g.slug === slug);
|
|
15
|
-
if (!global) {
|
|
16
|
-
return [];
|
|
17
|
-
}
|
|
18
|
-
return global.flattenedFields.filter((field)=>'name' in field && fieldIsVirtual(field)).map((field)=>field.name);
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Strips virtual field values from a data object given a list of virtual field names.
|
|
22
|
-
*/ export function stripVirtualFields(data, virtualFieldNames) {
|
|
23
|
-
if (virtualFieldNames.length === 0) {
|
|
24
|
-
return data;
|
|
25
|
-
}
|
|
26
|
-
const stripped = {
|
|
27
|
-
...data
|
|
28
|
-
};
|
|
29
|
-
for (const name of virtualFieldNames){
|
|
30
|
-
delete stripped[name];
|
|
31
|
-
}
|
|
32
|
-
return stripped;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
//# sourceMappingURL=getVirtualFieldNames.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/getVirtualFieldNames.ts"],"sourcesContent":["import type { SanitizedConfig } from 'payload'\n\nimport { fieldIsVirtual } from 'payload/shared'\n\n/**\n * Returns the names of all top-level virtual fields for a given collection slug.\n */\nexport function getCollectionVirtualFieldNames(config: SanitizedConfig, slug: string): string[] {\n const collection = config.collections.find((c) => c.slug === slug)\n\n if (!collection) {\n return []\n }\n\n return collection.flattenedFields\n .filter((field) => 'name' in field && fieldIsVirtual(field))\n .map((field) => (field as { name: string }).name)\n}\n\n/**\n * Returns the names of all top-level virtual fields for a given global slug.\n */\nexport function getGlobalVirtualFieldNames(config: SanitizedConfig, slug: string): string[] {\n const global = config.globals.find((g) => g.slug === slug)\n\n if (!global) {\n return []\n }\n\n return global.flattenedFields\n .filter((field) => 'name' in field && fieldIsVirtual(field))\n .map((field) => (field as { name: string }).name)\n}\n\n/**\n * Strips virtual field values from a data object given a list of virtual field names.\n */\nexport function stripVirtualFields(\n data: Record<string, unknown>,\n virtualFieldNames: string[],\n): Record<string, unknown> {\n if (virtualFieldNames.length === 0) {\n return data\n }\n\n const stripped = { ...data }\n\n for (const name of virtualFieldNames) {\n delete stripped[name]\n }\n\n return stripped\n}\n"],"names":["fieldIsVirtual","getCollectionVirtualFieldNames","config","slug","collection","collections","find","c","flattenedFields","filter","field","map","name","getGlobalVirtualFieldNames","global","globals","g","stripVirtualFields","data","virtualFieldNames","length","stripped"],"mappings":"AAEA,SAASA,cAAc,QAAQ,iBAAgB;AAE/C;;CAEC,GACD,OAAO,SAASC,+BAA+BC,MAAuB,EAAEC,IAAY;IAClF,MAAMC,aAAaF,OAAOG,WAAW,CAACC,IAAI,CAAC,CAACC,IAAMA,EAAEJ,IAAI,KAAKA;IAE7D,IAAI,CAACC,YAAY;QACf,OAAO,EAAE;IACX;IAEA,OAAOA,WAAWI,eAAe,CAC9BC,MAAM,CAAC,CAACC,QAAU,UAAUA,SAASV,eAAeU,QACpDC,GAAG,CAAC,CAACD,QAAU,AAACA,MAA2BE,IAAI;AACpD;AAEA;;CAEC,GACD,OAAO,SAASC,2BAA2BX,MAAuB,EAAEC,IAAY;IAC9E,MAAMW,SAASZ,OAAOa,OAAO,CAACT,IAAI,CAAC,CAACU,IAAMA,EAAEb,IAAI,KAAKA;IAErD,IAAI,CAACW,QAAQ;QACX,OAAO,EAAE;IACX;IAEA,OAAOA,OAAON,eAAe,CAC1BC,MAAM,CAAC,CAACC,QAAU,UAAUA,SAASV,eAAeU,QACpDC,GAAG,CAAC,CAACD,QAAU,AAACA,MAA2BE,IAAI;AACpD;AAEA;;CAEC,GACD,OAAO,SAASK,mBACdC,IAA6B,EAC7BC,iBAA2B;IAE3B,IAAIA,kBAAkBC,MAAM,KAAK,GAAG;QAClC,OAAOF;IACT;IAEA,MAAMG,WAAW;QAAE,GAAGH,IAAI;IAAC;IAE3B,KAAK,MAAMN,QAAQO,kBAAmB;QACpC,OAAOE,QAAQ,CAACT,KAAK;IACvB;IAEA,OAAOS;AACT"}
|