@payloadcms/plugin-mcp 4.0.0-internal.4cbdd50 → 4.0.0-internal.4e1f822
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/LICENSE.md +1 -1
- package/bin.js +7 -0
- package/dist/defaultAccess.d.ts.map +1 -1
- package/dist/defineTool.d.ts +8 -8
- package/dist/defineTool.d.ts.map +1 -1
- package/dist/endpoint/access.d.ts +2 -7
- package/dist/endpoint/access.d.ts.map +1 -1
- package/dist/endpoint/access.js +6 -13
- package/dist/endpoint/access.js.map +1 -1
- package/dist/endpoint/index.d.ts +1 -1
- package/dist/endpoint/index.d.ts.map +1 -1
- package/dist/endpoint/index.js +57 -17
- package/dist/endpoint/index.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/mcp/buildMcpServer.d.ts +5 -5
- package/dist/mcp/buildMcpServer.d.ts.map +1 -1
- package/dist/mcp/buildMcpServer.js +67 -33
- 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 +10 -16
- 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 +10 -15
- 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 -54
- 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 +41 -45
- 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 +27 -38
- package/dist/mcp/builtin/collections/duplicateTool.js.map +1 -1
- package/dist/mcp/builtin/collections/fileInput.d.ts +28 -0
- package/dist/mcp/builtin/collections/fileInput.d.ts.map +1 -0
- package/dist/mcp/builtin/collections/fileInput.js +123 -0
- package/dist/mcp/builtin/collections/fileInput.js.map +1 -0
- package/dist/mcp/builtin/collections/fileInput.spec.js +86 -0
- package/dist/mcp/builtin/collections/fileInput.spec.js.map +1 -0
- package/dist/mcp/builtin/collections/findDistinctTool.d.ts.map +1 -1
- package/dist/mcp/builtin/collections/findDistinctTool.js +12 -28
- 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 +23 -46
- 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 +18 -28
- 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 +17 -32
- 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 +51 -11
- 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 +15 -28
- 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 +62 -86
- 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 +5 -7
- 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 +10 -15
- 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 +12 -18
- 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 +14 -26
- 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 +14 -31
- 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 +28 -10
- 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 +16 -24
- 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 +28 -37
- 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.d.ts.map +1 -1
- package/dist/mcp/sanitizeMCPConfig.js +5 -1
- package/dist/mcp/sanitizeMCPConfig.js.map +1 -1
- package/dist/stdio.d.ts +3 -4
- package/dist/stdio.d.ts.map +1 -1
- package/dist/stdio.js +61 -42
- package/dist/stdio.js.map +1 -1
- package/dist/types.d.ts +61 -13
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +2 -4
- package/dist/types.js.map +1 -1
- package/dist/utils/camelCase.d.ts.map +1 -1
- package/dist/utils/resolveProjectRoot.d.ts.map +1 -1
- package/dist/utils/toStandardSchema.d.ts.map +1 -1
- package/package.json +8 -12
- package/src/endpoint/access.ts +5 -13
- package/src/endpoint/index.ts +45 -16
- package/src/index.ts +4 -4
- package/src/mcp/buildMcpServer.ts +79 -49
- package/src/mcp/builtin/collections/authTools.ts +77 -69
- package/src/mcp/builtin/collections/countTool.ts +10 -23
- package/src/mcp/builtin/collections/countVersionsTool.ts +10 -20
- package/src/mcp/builtin/collections/createTool.ts +110 -77
- package/src/mcp/builtin/collections/deleteTool.ts +36 -65
- package/src/mcp/builtin/collections/duplicateTool.ts +34 -86
- package/src/mcp/builtin/collections/fileInput.spec.ts +93 -0
- package/src/mcp/builtin/collections/fileInput.ts +169 -0
- package/src/mcp/builtin/collections/findDistinctTool.ts +12 -65
- package/src/mcp/builtin/collections/findTool.ts +23 -106
- package/src/mcp/builtin/collections/findVersionByIDTool.ts +16 -60
- package/src/mcp/builtin/collections/findVersionsTool.ts +15 -87
- package/src/mcp/builtin/collections/getCollectionSchemaTool.ts +48 -14
- package/src/mcp/builtin/collections/restoreVersionTool.ts +15 -58
- package/src/mcp/builtin/collections/updateTool.ts +61 -100
- package/src/mcp/builtin/collections/uploadInstructionsTool.ts +64 -0
- package/src/mcp/builtin/formatEntityError.ts +77 -0
- package/src/mcp/builtin/getConfigInfoTool.ts +4 -5
- package/src/mcp/builtin/globals/countVersionsTool.ts +10 -19
- package/src/mcp/builtin/globals/findTool.ts +14 -53
- package/src/mcp/builtin/globals/findVersionByIDTool.ts +14 -54
- package/src/mcp/builtin/globals/findVersionsTool.ts +15 -94
- package/src/mcp/builtin/globals/getGlobalSchemaTool.ts +30 -8
- package/src/mcp/builtin/globals/restoreVersionTool.ts +15 -47
- package/src/mcp/builtin/globals/updateTool.ts +39 -62
- package/src/mcp/builtinTools.ts +9 -2
- package/src/mcp/sanitizeMCPConfig.ts +5 -1
- package/src/stdio.ts +61 -43
- package/src/types.ts +61 -13
- package/dist/@types/assets.d.js +0 -2
- package/dist/@types/assets.d.js.map +0 -1
- 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/localAPIDefaults.d.ts +0 -20
- package/dist/utils/localAPIDefaults.d.ts.map +0 -1
- package/dist/utils/localAPIDefaults.js +0 -19
- package/dist/utils/localAPIDefaults.js.map +0 -1
- package/dist/utils/schemaConversion/getEntityInputSchema.d.ts +0 -11
- package/dist/utils/schemaConversion/getEntityInputSchema.d.ts.map +0 -1
- package/dist/utils/schemaConversion/getEntityInputSchema.js +0 -34
- package/dist/utils/schemaConversion/getEntityInputSchema.js.map +0 -1
- package/dist/utils/schemaConversion/removeVirtualFieldsFromSchema.d.ts +0 -7
- package/dist/utils/schemaConversion/removeVirtualFieldsFromSchema.d.ts.map +0 -1
- package/dist/utils/schemaConversion/removeVirtualFieldsFromSchema.js +0 -20
- package/dist/utils/schemaConversion/removeVirtualFieldsFromSchema.js.map +0 -1
- package/dist/utils/schemaConversion/sanitizeEntitySchema.d.ts +0 -15
- package/dist/utils/schemaConversion/sanitizeEntitySchema.d.ts.map +0 -1
- package/dist/utils/schemaConversion/sanitizeEntitySchema.js +0 -464
- package/dist/utils/schemaConversion/sanitizeEntitySchema.js.map +0 -1
- package/dist/utils/schemaConversion/sanitizeEntitySchema.spec.js +0 -158
- 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/@types/assets.d.ts +0 -3
- 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/localAPIDefaults.ts +0 -22
- package/src/utils/schemaConversion/getEntityInputSchema.ts +0 -78
- package/src/utils/schemaConversion/removeVirtualFieldsFromSchema.ts +0 -27
- package/src/utils/schemaConversion/sanitizeEntitySchema.spec.ts +0 -103
- package/src/utils/schemaConversion/sanitizeEntitySchema.ts +0 -529
- package/src/utils/transformPointDataToPayload.ts +0 -40
- package/src/utils/whereSchema.ts +0 -24
|
@@ -1,18 +1,15 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
import { z } from 'zod'
|
|
1
|
+
import { restoreVersionInputSchema } from 'payload'
|
|
4
2
|
|
|
5
3
|
import { defaultAccess } from '../../../defaultAccess.js'
|
|
6
4
|
import { defineCollectionTool } from '../../../defineTool.js'
|
|
7
5
|
import { getLogger } from '../../../utils/getLogger.js'
|
|
8
|
-
import { localAPIDefaults } from '../../../utils/localAPIDefaults.js'
|
|
9
6
|
|
|
10
7
|
const DEFAULT_DESCRIPTION =
|
|
11
8
|
'Restore a document from a previous version in any version-enabled collection.'
|
|
12
9
|
|
|
13
10
|
export const restoreVersionTool = defineCollectionTool({
|
|
14
11
|
access: (args) =>
|
|
15
|
-
defaultAccess(args) && Boolean(args.permissions?.collections?.[args.
|
|
12
|
+
defaultAccess(args) && Boolean(args.permissions?.collections?.[args.slug]?.update),
|
|
16
13
|
annotations: {
|
|
17
14
|
destructiveHint: true,
|
|
18
15
|
idempotentHint: false,
|
|
@@ -21,85 +18,45 @@ export const restoreVersionTool = defineCollectionTool({
|
|
|
21
18
|
title: 'Restore Version',
|
|
22
19
|
},
|
|
23
20
|
description: DEFAULT_DESCRIPTION,
|
|
24
|
-
input:
|
|
25
|
-
|
|
26
|
-
depth: z
|
|
27
|
-
.number()
|
|
28
|
-
.int()
|
|
29
|
-
.min(0)
|
|
30
|
-
.max(10)
|
|
31
|
-
.describe('How many levels deep to populate relationships in response')
|
|
32
|
-
.optional()
|
|
33
|
-
.default(0),
|
|
34
|
-
draft: z
|
|
35
|
-
.boolean()
|
|
36
|
-
.describe('Whether to restore the version as a draft')
|
|
37
|
-
.optional()
|
|
38
|
-
.default(false),
|
|
39
|
-
fallbackLocale: z
|
|
40
|
-
.string()
|
|
41
|
-
.describe('Optional: fallback locale code to use when requested locale is not available')
|
|
42
|
-
.optional(),
|
|
43
|
-
locale: z
|
|
44
|
-
.string()
|
|
45
|
-
.describe('Optional: locale code to restore in (e.g., "en", "es")')
|
|
46
|
-
.optional(),
|
|
47
|
-
populate: z
|
|
48
|
-
.record(z.string(), z.unknown())
|
|
49
|
-
.describe(
|
|
50
|
-
'Optional: control which fields to include from populated relationship or upload documents.',
|
|
51
|
-
)
|
|
52
|
-
.optional(),
|
|
53
|
-
select: z
|
|
54
|
-
.record(z.string(), z.unknown())
|
|
55
|
-
.describe(
|
|
56
|
-
'Optional: define exactly which fields you\'d like to return in the response, e.g., {"title": true}',
|
|
57
|
-
)
|
|
58
|
-
.optional(),
|
|
59
|
-
showHiddenFields: z
|
|
60
|
-
.boolean()
|
|
61
|
-
.describe('Optional: include hidden fields in the restored document response')
|
|
62
|
-
.optional(),
|
|
63
|
-
}),
|
|
64
|
-
}).handler(async ({ authorizedMCP, collectionSlug, input, req }) => {
|
|
21
|
+
input: restoreVersionInputSchema,
|
|
22
|
+
}).handler(async ({ slug, authorizedMCP, input, req }) => {
|
|
65
23
|
const payload = req.payload
|
|
66
24
|
const logger = getLogger({ payload })
|
|
67
|
-
const { id, depth, draft, fallbackLocale, locale, populate, select
|
|
25
|
+
const { id, depth, draft, fallbackLocale, locale, populate, select } = input
|
|
68
26
|
|
|
69
|
-
logger.info(`Restoring version in collection: ${
|
|
27
|
+
logger.info(`Restoring version in collection: ${slug} with ID: ${id}`)
|
|
70
28
|
|
|
71
29
|
try {
|
|
72
30
|
const result = await payload.restoreVersion({
|
|
73
|
-
id,
|
|
74
|
-
collection:
|
|
31
|
+
id: String(id),
|
|
32
|
+
collection: slug,
|
|
75
33
|
depth,
|
|
76
34
|
draft,
|
|
35
|
+
overrideAccess: authorizedMCP.overrideAccess,
|
|
77
36
|
req,
|
|
78
|
-
...
|
|
79
|
-
...(fallbackLocale ? { fallbackLocale } : {}),
|
|
37
|
+
...(fallbackLocale !== undefined ? { fallbackLocale } : {}),
|
|
80
38
|
...(locale ? { locale } : {}),
|
|
81
|
-
...(populate ? { populate
|
|
82
|
-
...(select ? { select
|
|
83
|
-
...(showHiddenFields !== undefined ? { showHiddenFields } : {}),
|
|
39
|
+
...(populate ? { populate } : {}),
|
|
40
|
+
...(select ? { select } : {}),
|
|
84
41
|
})
|
|
85
42
|
|
|
86
43
|
return {
|
|
87
44
|
content: [
|
|
88
45
|
{
|
|
89
46
|
type: 'text',
|
|
90
|
-
text: `Version "${id}" restored successfully in collection "${
|
|
47
|
+
text: `Version "${id}" restored successfully in collection "${slug}"!\nRestored document:\n\`\`\`json\n${JSON.stringify(result)}\n\`\`\``,
|
|
91
48
|
},
|
|
92
49
|
],
|
|
93
50
|
doc: result as Record<string, unknown>,
|
|
94
51
|
}
|
|
95
52
|
} catch (error) {
|
|
96
53
|
const errorMessage = error instanceof Error ? error.message : 'Unknown error'
|
|
97
|
-
logger.error(`Error restoring version ${id} in ${
|
|
54
|
+
logger.error(`Error restoring version ${id} in ${slug}: ${errorMessage}`)
|
|
98
55
|
return {
|
|
99
56
|
content: [
|
|
100
57
|
{
|
|
101
58
|
type: 'text',
|
|
102
|
-
text: `❌ **Error restoring version "${id}" in collection "${
|
|
59
|
+
text: `❌ **Error restoring version "${id}" in collection "${slug}":** ${errorMessage}`,
|
|
103
60
|
},
|
|
104
61
|
],
|
|
105
62
|
isError: true,
|
|
@@ -1,27 +1,26 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Where } from 'payload'
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
getCollectionInputSchema,
|
|
5
|
+
getCollectionVirtualFieldNames,
|
|
6
|
+
stripVirtualFields,
|
|
7
|
+
transformPointDataToPayload,
|
|
8
|
+
updateDocumentInputSchema,
|
|
9
|
+
validateCollectionData,
|
|
10
|
+
} from 'payload'
|
|
4
11
|
|
|
5
12
|
import { defaultAccess } from '../../../defaultAccess.js'
|
|
6
13
|
import { defineCollectionTool } from '../../../defineTool.js'
|
|
7
14
|
import { getLogger } from '../../../utils/getLogger.js'
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
stripVirtualFields,
|
|
11
|
-
} from '../../../utils/getVirtualFieldNames.js'
|
|
12
|
-
import { localAPIDefaults } from '../../../utils/localAPIDefaults.js'
|
|
13
|
-
import { getCollectionInputSchema } from '../../../utils/schemaConversion/getEntityInputSchema.js'
|
|
14
|
-
import { transformPointDataToPayload } from '../../../utils/transformPointDataToPayload.js'
|
|
15
|
-
import { whereSchema } from '../../../utils/whereSchema.js'
|
|
16
|
-
import { validateCollectionData } from '../validateEntityData.js'
|
|
17
|
-
import { formatCollectionError } from './formatCollectionError.js'
|
|
15
|
+
import { formatEntityError } from '../formatEntityError.js'
|
|
16
|
+
import { fileInputSchema, resolveFile } from './fileInput.js'
|
|
18
17
|
|
|
19
18
|
const DEFAULT_DESCRIPTION =
|
|
20
|
-
'Update documents
|
|
19
|
+
'Update documents. Prefer uploadReference after upload, externalURL for URLs, or base64 for small local files.'
|
|
21
20
|
|
|
22
21
|
export const updateDocumentTool = defineCollectionTool({
|
|
23
22
|
access: (args) =>
|
|
24
|
-
defaultAccess(args) && Boolean(args.permissions?.collections?.[args.
|
|
23
|
+
defaultAccess(args) && Boolean(args.permissions?.collections?.[args.slug]?.update),
|
|
25
24
|
annotations: {
|
|
26
25
|
destructiveHint: true,
|
|
27
26
|
idempotentHint: false,
|
|
@@ -30,53 +29,8 @@ export const updateDocumentTool = defineCollectionTool({
|
|
|
30
29
|
title: 'Update Document',
|
|
31
30
|
},
|
|
32
31
|
description: DEFAULT_DESCRIPTION,
|
|
33
|
-
input:
|
|
34
|
-
|
|
35
|
-
data: z.record(z.string(), z.unknown()).describe('The fields to update'),
|
|
36
|
-
depth: z
|
|
37
|
-
.number()
|
|
38
|
-
.describe('How many levels deep to populate relationships')
|
|
39
|
-
.optional()
|
|
40
|
-
.default(0),
|
|
41
|
-
draft: z
|
|
42
|
-
.boolean()
|
|
43
|
-
.describe('Whether to update the document as a draft')
|
|
44
|
-
.optional()
|
|
45
|
-
.default(false),
|
|
46
|
-
fallbackLocale: z
|
|
47
|
-
.string()
|
|
48
|
-
.describe('Optional: fallback locale code to use when requested locale is not available')
|
|
49
|
-
.optional(),
|
|
50
|
-
filePath: z.string().describe('File path for file uploads').optional(),
|
|
51
|
-
locale: z
|
|
52
|
-
.string()
|
|
53
|
-
.describe(
|
|
54
|
-
'Optional: locale code to update the document in (e.g., "en", "es"). Defaults to the default locale',
|
|
55
|
-
)
|
|
56
|
-
.optional(),
|
|
57
|
-
overrideLock: z
|
|
58
|
-
.boolean()
|
|
59
|
-
.describe('Whether to override document locks')
|
|
60
|
-
.optional()
|
|
61
|
-
.default(true),
|
|
62
|
-
overwriteExistingFiles: z
|
|
63
|
-
.boolean()
|
|
64
|
-
.describe('Whether to overwrite existing files')
|
|
65
|
-
.optional()
|
|
66
|
-
.default(false),
|
|
67
|
-
select: z
|
|
68
|
-
.record(z.string(), z.unknown())
|
|
69
|
-
.describe(
|
|
70
|
-
'Optional: define exactly which fields you\'d like to return in the response, e.g., {"title": true}',
|
|
71
|
-
)
|
|
72
|
-
.optional(),
|
|
73
|
-
where: whereSchema
|
|
74
|
-
.describe(
|
|
75
|
-
'Where clause to update multiple documents. Use field names with Payload operators, and/or arrays for grouping. Example: {"title":{"contains":"test"}}',
|
|
76
|
-
)
|
|
77
|
-
.optional(),
|
|
78
|
-
}),
|
|
79
|
-
}).handler(async ({ authorizedMCP, collectionSlug, input, req }) => {
|
|
32
|
+
input: updateDocumentInputSchema({ file: fileInputSchema }),
|
|
33
|
+
}).handler(async ({ slug, authorizedMCP, input, req }) => {
|
|
80
34
|
const payload = req.payload
|
|
81
35
|
const logger = getLogger({ payload })
|
|
82
36
|
|
|
@@ -86,97 +40,104 @@ export const updateDocumentTool = defineCollectionTool({
|
|
|
86
40
|
depth,
|
|
87
41
|
draft,
|
|
88
42
|
fallbackLocale,
|
|
89
|
-
|
|
43
|
+
file: fileInput,
|
|
44
|
+
limit,
|
|
90
45
|
locale,
|
|
91
46
|
overrideLock,
|
|
92
|
-
|
|
47
|
+
populate,
|
|
48
|
+
publishAllLocales,
|
|
49
|
+
returning,
|
|
93
50
|
select,
|
|
51
|
+
sort,
|
|
52
|
+
trash,
|
|
53
|
+
unpublishAllLocales,
|
|
94
54
|
where,
|
|
95
55
|
} = input
|
|
96
56
|
|
|
97
57
|
logger.info(
|
|
98
|
-
`Updating document in collection: ${
|
|
58
|
+
`Updating document in collection: ${slug}${id ? ` with ID: ${id}` : ' with where clause'}, draft: ${draft}${locale ? `, locale: ${locale}` : ''}`,
|
|
99
59
|
)
|
|
100
60
|
|
|
101
61
|
try {
|
|
102
|
-
|
|
103
|
-
return {
|
|
104
|
-
content: [{ type: 'text', text: 'Error: Either id or where clause must be provided' }],
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
const virtualFieldNames = getCollectionVirtualFieldNames(payload.config, collectionSlug)
|
|
62
|
+
const virtualFieldNames = getCollectionVirtualFieldNames(payload.config, slug)
|
|
109
63
|
const inputData = stripVirtualFields(data, virtualFieldNames)
|
|
110
|
-
|
|
111
|
-
|
|
64
|
+
validateCollectionData({
|
|
65
|
+
slug,
|
|
112
66
|
data: inputData,
|
|
113
67
|
partial: true,
|
|
114
68
|
req,
|
|
115
69
|
})
|
|
116
70
|
|
|
117
|
-
if (validationError) {
|
|
118
|
-
return validationError
|
|
119
|
-
}
|
|
120
|
-
|
|
121
71
|
const parsedData = transformPointDataToPayload(inputData)
|
|
72
|
+
const file = await resolveFile({ slug, input: fileInput, req })
|
|
122
73
|
|
|
123
74
|
const whereClause: Where = where ?? {}
|
|
124
75
|
|
|
125
|
-
if (id) {
|
|
76
|
+
if (id !== undefined) {
|
|
126
77
|
const result = await payload.update({
|
|
127
78
|
id,
|
|
128
|
-
collection:
|
|
79
|
+
collection: slug,
|
|
129
80
|
data: parsedData,
|
|
130
81
|
depth,
|
|
131
82
|
draft,
|
|
83
|
+
fallbackLocale,
|
|
84
|
+
locale,
|
|
85
|
+
overrideAccess: authorizedMCP.overrideAccess,
|
|
132
86
|
overrideLock,
|
|
87
|
+
populate,
|
|
88
|
+
publishAllLocales,
|
|
133
89
|
req,
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
...(
|
|
138
|
-
...(fallbackLocale ? { fallbackLocale } : {}),
|
|
139
|
-
...(select ? { select: select as SelectType } : {}),
|
|
90
|
+
select: returning ? select : { id: true },
|
|
91
|
+
trash,
|
|
92
|
+
unpublishAllLocales,
|
|
93
|
+
...(file ? { file } : {}),
|
|
140
94
|
})
|
|
141
95
|
|
|
96
|
+
const responseResult = returning ? result : { id: result.id }
|
|
97
|
+
|
|
142
98
|
return {
|
|
143
99
|
content: [
|
|
144
100
|
{
|
|
145
101
|
type: 'text',
|
|
146
|
-
text: `Document updated successfully in collection "${
|
|
102
|
+
text: `Document updated successfully in collection "${slug}"!\nResult:\n\`\`\`json\n${JSON.stringify(responseResult)}\n\`\`\``,
|
|
147
103
|
},
|
|
148
104
|
],
|
|
149
|
-
doc:
|
|
105
|
+
doc: responseResult as Record<string, unknown>,
|
|
150
106
|
}
|
|
151
107
|
}
|
|
152
108
|
|
|
153
109
|
const result = await payload.update({
|
|
154
|
-
collection:
|
|
110
|
+
collection: slug,
|
|
155
111
|
data: parsedData,
|
|
156
112
|
depth,
|
|
157
113
|
draft,
|
|
114
|
+
fallbackLocale,
|
|
115
|
+
limit,
|
|
116
|
+
locale,
|
|
117
|
+
overrideAccess: authorizedMCP.overrideAccess,
|
|
158
118
|
overrideLock,
|
|
119
|
+
populate,
|
|
120
|
+
publishAllLocales,
|
|
159
121
|
req,
|
|
122
|
+
select: returning ? select : { id: true },
|
|
123
|
+
sort,
|
|
124
|
+
trash,
|
|
125
|
+
unpublishAllLocales,
|
|
160
126
|
where: whereClause,
|
|
161
|
-
...
|
|
162
|
-
...(filePath ? { filePath } : {}),
|
|
163
|
-
...(overwriteExistingFiles ? { overwriteExistingFiles } : {}),
|
|
164
|
-
...(locale ? { locale } : {}),
|
|
165
|
-
...(fallbackLocale ? { fallbackLocale } : {}),
|
|
166
|
-
...(select ? { select: select as SelectType } : {}),
|
|
127
|
+
...(file ? { file } : {}),
|
|
167
128
|
})
|
|
168
129
|
|
|
169
|
-
const docs = result.docs
|
|
130
|
+
const docs = returning ? result.docs : result.docs.map(({ id }) => ({ id }))
|
|
170
131
|
const errors = result.errors || []
|
|
171
132
|
|
|
172
|
-
let responseText = `Multiple documents updated in collection "${
|
|
133
|
+
let responseText = `Multiple documents updated in collection "${slug}"!\nUpdated: ${docs.length} documents\nErrors: ${errors.length}\n---`
|
|
173
134
|
if (docs.length > 0) {
|
|
174
135
|
responseText += `\n\nUpdated documents:\n\`\`\`json\n${JSON.stringify(docs)}\n\`\`\``
|
|
175
136
|
}
|
|
176
137
|
if (errors.length > 0) {
|
|
177
138
|
responseText += `\n\nErrors:\n\`\`\`json\n${JSON.stringify(errors)}\n\`\`\``
|
|
178
139
|
|
|
179
|
-
const errorSchema = getCollectionInputSchema({ collectionSlug, req })
|
|
140
|
+
const errorSchema = getCollectionInputSchema({ collectionSlug: slug, req })
|
|
180
141
|
|
|
181
142
|
if (errorSchema) {
|
|
182
143
|
responseText += `\n\nUse this schema for data:\n\`\`\`json\n${JSON.stringify(errorSchema)}\n\`\`\``
|
|
@@ -189,7 +150,7 @@ export const updateDocumentTool = defineCollectionTool({
|
|
|
189
150
|
...(errorSchema
|
|
190
151
|
? {
|
|
191
152
|
structuredContent: {
|
|
192
|
-
|
|
153
|
+
slug,
|
|
193
154
|
docs,
|
|
194
155
|
errors,
|
|
195
156
|
schema: errorSchema,
|
|
@@ -205,7 +166,7 @@ export const updateDocumentTool = defineCollectionTool({
|
|
|
205
166
|
}
|
|
206
167
|
} catch (error) {
|
|
207
168
|
const errorMessage = error instanceof Error ? error.message : 'Unknown error'
|
|
208
|
-
logger.error(`Error updating document in ${
|
|
209
|
-
return
|
|
169
|
+
logger.error(`Error updating document in ${slug}: ${errorMessage}`)
|
|
170
|
+
return formatEntityError({ slug, action: 'updating', entity: 'collection', error, req })
|
|
210
171
|
}
|
|
211
172
|
})
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { strictObject, z } from 'payload'
|
|
2
|
+
import { getUploadInstructions as getPayloadUploadInstructions } from 'payload/internal'
|
|
3
|
+
|
|
4
|
+
import { defaultAccess } from '../../../defaultAccess.js'
|
|
5
|
+
import { defineCollectionTool } from '../../../defineTool.js'
|
|
6
|
+
|
|
7
|
+
export const getUploadInstructionsTool = defineCollectionTool({
|
|
8
|
+
access: (args) =>
|
|
9
|
+
defaultAccess(args) &&
|
|
10
|
+
Boolean(
|
|
11
|
+
args.permissions?.collections?.[args.slug]?.create ||
|
|
12
|
+
args.permissions?.collections?.[args.slug]?.update,
|
|
13
|
+
),
|
|
14
|
+
annotations: {
|
|
15
|
+
destructiveHint: false,
|
|
16
|
+
idempotentHint: false,
|
|
17
|
+
openWorldHint: true,
|
|
18
|
+
readOnlyHint: false,
|
|
19
|
+
title: 'Get Upload Instructions',
|
|
20
|
+
},
|
|
21
|
+
description:
|
|
22
|
+
'Prepare uploads for createDocuments or updateDocument. This does not upload bytes; finish the returned action before use.',
|
|
23
|
+
input: strictObject({
|
|
24
|
+
docPrefix: z.optional(z.string()).check(z.describe('Document folder or prefix.')),
|
|
25
|
+
filename: z.string().check(z.describe('The original file name.')),
|
|
26
|
+
filesize: z.int().check(z.nonnegative(), z.describe('The file size in bytes.')),
|
|
27
|
+
mimeType: z.string().check(z.describe('The file MIME type.')),
|
|
28
|
+
}),
|
|
29
|
+
}).handler(async ({ slug, authorizedMCP, input, req }) => {
|
|
30
|
+
try {
|
|
31
|
+
const instructions = await getPayloadUploadInstructions({
|
|
32
|
+
...input,
|
|
33
|
+
collectionSlug: slug,
|
|
34
|
+
overrideAccess: authorizedMCP.overrideAccess,
|
|
35
|
+
req,
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
const nextStep =
|
|
39
|
+
instructions.type === 'http'
|
|
40
|
+
? 'Upload bytes with instructions.request. After success, pass { source: "uploadReference", file: instructions.file }.'
|
|
41
|
+
: `Call "${instructions.name}" with file and data. After success, pass { source: "uploadReference", file: instructions.file }.`
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
content: [
|
|
45
|
+
{
|
|
46
|
+
type: 'text',
|
|
47
|
+
text: `Upload instructions for collection "${slug}":\n\`\`\`json\n${JSON.stringify(instructions)}\n\`\`\`\n${nextStep}`,
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
structuredContent: { instructions },
|
|
51
|
+
}
|
|
52
|
+
} catch (error) {
|
|
53
|
+
const message = error instanceof Error ? error.message : 'Unknown error'
|
|
54
|
+
return {
|
|
55
|
+
content: [
|
|
56
|
+
{
|
|
57
|
+
type: 'text',
|
|
58
|
+
text: `Error getting upload instructions for collection "${slug}": ${message}`,
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
isError: true,
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
})
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { CollectionSlug, GlobalSlug, PayloadRequest } from 'payload'
|
|
2
|
+
|
|
3
|
+
import { getCollectionInputSchema, getGlobalInputSchema, ValidationError } from 'payload'
|
|
4
|
+
|
|
5
|
+
import type { MCPToolResponse } from '../../types.js'
|
|
6
|
+
|
|
7
|
+
export const formatEntityError = ({
|
|
8
|
+
slug,
|
|
9
|
+
action,
|
|
10
|
+
entity,
|
|
11
|
+
error,
|
|
12
|
+
req,
|
|
13
|
+
}:
|
|
14
|
+
| {
|
|
15
|
+
action: 'creating' | 'duplicating' | 'updating'
|
|
16
|
+
entity: 'collection'
|
|
17
|
+
error: unknown
|
|
18
|
+
req: PayloadRequest
|
|
19
|
+
slug: CollectionSlug
|
|
20
|
+
}
|
|
21
|
+
| {
|
|
22
|
+
action: 'updating'
|
|
23
|
+
entity: 'global'
|
|
24
|
+
error: unknown
|
|
25
|
+
req: PayloadRequest
|
|
26
|
+
slug: GlobalSlug
|
|
27
|
+
}): MCPToolResponse => {
|
|
28
|
+
const message = error instanceof Error ? error.message : 'Unknown error'
|
|
29
|
+
const target = entity === 'collection' ? `document in collection "${slug}"` : `global "${slug}"`
|
|
30
|
+
|
|
31
|
+
if (!isValidationError(error, message)) {
|
|
32
|
+
return {
|
|
33
|
+
content: [{ type: 'text', text: `Error ${action} ${target}: ${message}` }],
|
|
34
|
+
isError: true,
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const schema =
|
|
39
|
+
entity === 'collection'
|
|
40
|
+
? getCollectionInputSchema({ collectionSlug: slug, req })
|
|
41
|
+
: getGlobalInputSchema({ globalSlug: slug, req })
|
|
42
|
+
const errors = error instanceof ValidationError ? error.data.errors : [{ message }]
|
|
43
|
+
const validationMessage = errors
|
|
44
|
+
.map((issue) => `${'path' in issue ? `${issue.path}: ` : ''}${issue.message}`)
|
|
45
|
+
.join('\n')
|
|
46
|
+
const schemaText = schema
|
|
47
|
+
? `\n\nUse this schema for data:\n\`\`\`json\n${JSON.stringify(schema)}\n\`\`\``
|
|
48
|
+
: ''
|
|
49
|
+
|
|
50
|
+
return {
|
|
51
|
+
content: [
|
|
52
|
+
{ type: 'text', text: `Error ${action} ${target}: ${validationMessage}${schemaText}` },
|
|
53
|
+
],
|
|
54
|
+
isError: true,
|
|
55
|
+
...(schema
|
|
56
|
+
? {
|
|
57
|
+
structuredContent: {
|
|
58
|
+
slug,
|
|
59
|
+
errors,
|
|
60
|
+
schema,
|
|
61
|
+
},
|
|
62
|
+
}
|
|
63
|
+
: {}),
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const isValidationError = (error: unknown, message: string): boolean => {
|
|
68
|
+
if (error instanceof ValidationError) {
|
|
69
|
+
return true
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const name = error && typeof error === 'object' && 'name' in error ? error.name : undefined
|
|
73
|
+
|
|
74
|
+
return (
|
|
75
|
+
name === 'CastError' || message.includes('Cast to ') || message.includes('validation failed')
|
|
76
|
+
)
|
|
77
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getAccessResults, isEntityHidden } from 'payload'
|
|
1
|
+
import { getAccessResults, getConfigInfoInputSchema, isEntityHidden } from 'payload'
|
|
2
2
|
|
|
3
3
|
import { defineTool } from '../../defineTool.js'
|
|
4
4
|
|
|
@@ -11,11 +11,10 @@ export const getConfigInfoTool = defineTool({
|
|
|
11
11
|
title: 'Config Info',
|
|
12
12
|
},
|
|
13
13
|
description: 'List the Payload collection and global slugs visible to this MCP client.',
|
|
14
|
+
input: getConfigInfoInputSchema,
|
|
14
15
|
}).handler(async ({ authorizedMCP, req }) => {
|
|
15
|
-
const user =
|
|
16
|
-
const permissions = authorizedMCP.overrideAccess
|
|
17
|
-
? null
|
|
18
|
-
: await getAccessResults({ req: { ...req, user } })
|
|
16
|
+
const user = req.user
|
|
17
|
+
const permissions = authorizedMCP.overrideAccess ? null : await getAccessResults({ req })
|
|
19
18
|
const authorizedCollectionSlugs = new Set<string>()
|
|
20
19
|
const authorizedGlobalSlugs = new Set<string>()
|
|
21
20
|
|
|
@@ -1,17 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { countGlobalVersionsInputSchema } from 'payload'
|
|
2
2
|
|
|
3
3
|
import { defaultAccess } from '../../../defaultAccess.js'
|
|
4
4
|
import { defineGlobalTool } from '../../../defineTool.js'
|
|
5
5
|
import { getLogger } from '../../../utils/getLogger.js'
|
|
6
|
-
import { localAPIDefaults } from '../../../utils/localAPIDefaults.js'
|
|
7
|
-
import { whereSchema } from '../../../utils/whereSchema.js'
|
|
8
6
|
|
|
9
7
|
const DEFAULT_DESCRIPTION =
|
|
10
8
|
'Count global versions in any version-enabled global by passing the global slug and optional where clause.'
|
|
11
9
|
|
|
12
10
|
export const countGlobalVersionsTool = defineGlobalTool({
|
|
13
11
|
access: (args) =>
|
|
14
|
-
defaultAccess(args) && Boolean(args.permissions?.globals?.[args.
|
|
12
|
+
defaultAccess(args) && Boolean(args.permissions?.globals?.[args.slug]?.readVersions),
|
|
15
13
|
annotations: {
|
|
16
14
|
destructiveHint: false,
|
|
17
15
|
idempotentHint: true,
|
|
@@ -20,26 +18,19 @@ export const countGlobalVersionsTool = defineGlobalTool({
|
|
|
20
18
|
title: 'Count Global Versions',
|
|
21
19
|
},
|
|
22
20
|
description: DEFAULT_DESCRIPTION,
|
|
23
|
-
input:
|
|
24
|
-
|
|
25
|
-
where: whereSchema
|
|
26
|
-
.describe(
|
|
27
|
-
'Optional: where clause for filtering versions. Version document fields are usually under "version". Example: {"version.siteName":{"contains":"test"}}',
|
|
28
|
-
)
|
|
29
|
-
.optional(),
|
|
30
|
-
}),
|
|
31
|
-
}).handler(async ({ authorizedMCP, globalSlug, input, req }) => {
|
|
21
|
+
input: countGlobalVersionsInputSchema,
|
|
22
|
+
}).handler(async ({ slug, authorizedMCP, input, req }) => {
|
|
32
23
|
const payload = req.payload
|
|
33
24
|
const logger = getLogger({ payload })
|
|
34
25
|
const { locale, where } = input
|
|
35
26
|
|
|
36
|
-
logger.info(`Counting versions for global: ${
|
|
27
|
+
logger.info(`Counting versions for global: ${slug}`)
|
|
37
28
|
|
|
38
29
|
try {
|
|
39
30
|
const result = await payload.countGlobalVersions({
|
|
40
|
-
global:
|
|
31
|
+
global: slug,
|
|
32
|
+
overrideAccess: authorizedMCP.overrideAccess,
|
|
41
33
|
req,
|
|
42
|
-
...localAPIDefaults(authorizedMCP),
|
|
43
34
|
...(locale ? { locale } : {}),
|
|
44
35
|
...(where ? { where } : {}),
|
|
45
36
|
})
|
|
@@ -48,19 +39,19 @@ export const countGlobalVersionsTool = defineGlobalTool({
|
|
|
48
39
|
content: [
|
|
49
40
|
{
|
|
50
41
|
type: 'text',
|
|
51
|
-
text: `Global "${
|
|
42
|
+
text: `Global "${slug}" contains ${result.totalDocs} matching versions.\n\`\`\`json\n${JSON.stringify(result)}\n\`\`\``,
|
|
52
43
|
},
|
|
53
44
|
],
|
|
54
45
|
doc: result,
|
|
55
46
|
}
|
|
56
47
|
} catch (error) {
|
|
57
48
|
const errorMessage = error instanceof Error ? error.message : 'Unknown error'
|
|
58
|
-
logger.error(`Error counting versions for global ${
|
|
49
|
+
logger.error(`Error counting versions for global ${slug}: ${errorMessage}`)
|
|
59
50
|
return {
|
|
60
51
|
content: [
|
|
61
52
|
{
|
|
62
53
|
type: 'text',
|
|
63
|
-
text: `❌ **Error counting versions for global "${
|
|
54
|
+
text: `❌ **Error counting versions for global "${slug}":** ${errorMessage}`,
|
|
64
55
|
},
|
|
65
56
|
],
|
|
66
57
|
isError: true,
|