@payloadcms/plugin-mcp 4.0.0-internal.bc5cf8c → 4.0.0-internal.bf4bcce
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/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 +17 -14
- 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 +91 -16
- package/dist/endpoint/index.js.map +1 -1
- package/dist/endpoint/oauth.d.ts +27 -0
- package/dist/endpoint/oauth.d.ts.map +1 -0
- package/dist/endpoint/oauth.js +61 -0
- package/dist/endpoint/oauth.js.map +1 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -2
- package/dist/index.js.map +1 -1
- package/dist/mcp/buildMcpServer.d.ts +6 -6
- package/dist/mcp/buildMcpServer.d.ts.map +1 -1
- package/dist/mcp/buildMcpServer.js +68 -34
- 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 +80 -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 +45 -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 +32 -39
- 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 +88 -0
- package/dist/mcp/builtin/collections/fileInput.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 +29 -48
- 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 +68 -12
- 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 +67 -87
- 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 +46 -12
- 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 +6 -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 +65 -45
- package/dist/stdio.js.map +1 -1
- package/dist/types.d.ts +94 -16
- 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 +9 -13
- package/src/endpoint/access.ts +14 -14
- package/src/endpoint/index.ts +79 -14
- package/src/endpoint/oauth.ts +72 -0
- package/src/index.ts +11 -4
- package/src/mcp/buildMcpServer.ts +80 -50
- package/src/mcp/builtin/collections/authTools.ts +80 -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 +36 -87
- package/src/mcp/builtin/collections/fileInput.spec.ts +93 -0
- package/src/mcp/builtin/collections/fileInput.ts +127 -0
- package/src/mcp/builtin/collections/findDistinctTool.ts +12 -65
- package/src/mcp/builtin/collections/findTool.ts +25 -108
- 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 +60 -15
- package/src/mcp/builtin/collections/restoreVersionTool.ts +15 -58
- package/src/mcp/builtin/collections/updateTool.ts +63 -101
- 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 +41 -9
- 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 +6 -1
- package/src/stdio.ts +63 -45
- package/src/types.ts +95 -16
- 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
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import type { CollectionSlug, File, PayloadRequest } from 'payload'
|
|
2
|
+
|
|
3
|
+
import { APIError, z } from 'payload'
|
|
4
|
+
import {
|
|
5
|
+
externalURLInputSchema,
|
|
6
|
+
getFileFromUploadInstructions,
|
|
7
|
+
resolveURLUploadInput,
|
|
8
|
+
} from 'payload/internal'
|
|
9
|
+
import { sanitizeFilename } from 'payload/shared'
|
|
10
|
+
|
|
11
|
+
const mimeTypeSchema = z
|
|
12
|
+
.string()
|
|
13
|
+
.check(
|
|
14
|
+
z.regex(
|
|
15
|
+
/^[!#$%&'*+.^`|~\w-]+\/[!#$%&'*+.^`|~\w-]+$/,
|
|
16
|
+
'MIME type must use the type/subtype format',
|
|
17
|
+
),
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
const uploadFileSchema = z.strictObject({
|
|
21
|
+
filename: z.string(),
|
|
22
|
+
mimeType: z.string(),
|
|
23
|
+
size: z.int().check(z.nonnegative()),
|
|
24
|
+
uploadReference: z.record(z.string(), z.unknown()),
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
export const fileInputSchema = z
|
|
28
|
+
.discriminatedUnion('source', [
|
|
29
|
+
z.strictObject({
|
|
30
|
+
name: z.string().check(z.minLength(1), z.describe('The file name, including its extension.')),
|
|
31
|
+
data: z
|
|
32
|
+
.string()
|
|
33
|
+
.check(z.describe('The base64-encoded file bytes, without a data URL prefix.')),
|
|
34
|
+
mimeType: mimeTypeSchema.check(z.describe('The file MIME type, for example image/png.')),
|
|
35
|
+
source: z.literal('base64'),
|
|
36
|
+
}),
|
|
37
|
+
externalURLInputSchema,
|
|
38
|
+
z.strictObject({
|
|
39
|
+
file: uploadFileSchema.check(z.describe('getUploadInstructions file field post-upload.')),
|
|
40
|
+
source: z.literal('uploadReference'),
|
|
41
|
+
}),
|
|
42
|
+
])
|
|
43
|
+
.check(
|
|
44
|
+
z.describe(
|
|
45
|
+
'A file for an upload collection. Prefer uploadReference after its upload succeeds; use base64 only for small local files or externalURL for an online file.',
|
|
46
|
+
),
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
type FileInput = z.infer<typeof fileInputSchema>
|
|
50
|
+
|
|
51
|
+
export async function resolveFile({
|
|
52
|
+
slug,
|
|
53
|
+
input,
|
|
54
|
+
req,
|
|
55
|
+
}: {
|
|
56
|
+
input?: FileInput
|
|
57
|
+
req: PayloadRequest
|
|
58
|
+
slug: CollectionSlug
|
|
59
|
+
}): Promise<File | undefined> {
|
|
60
|
+
if (!input) {
|
|
61
|
+
return undefined
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (input.source === 'uploadReference') {
|
|
65
|
+
try {
|
|
66
|
+
return await getFileFromUploadInstructions({ collectionSlug: slug, file: input.file, req })
|
|
67
|
+
} catch (error) {
|
|
68
|
+
if (error instanceof Error && error.message === 'Staged upload was not found.') {
|
|
69
|
+
throw new APIError(
|
|
70
|
+
'Staged upload not found. Complete the upload action first, or use base64 for small local files.',
|
|
71
|
+
400,
|
|
72
|
+
)
|
|
73
|
+
}
|
|
74
|
+
throw error
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (input.source === 'externalURL') {
|
|
79
|
+
return resolveURLUploadInput({ slug, input, req })
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const uploadConfig = req.payload.collections[slug]?.config.upload
|
|
83
|
+
|
|
84
|
+
if (!uploadConfig) {
|
|
85
|
+
throw new APIError(`Collection "${slug}" does not support file uploads.`, 400)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const maxFileSize = req.payload.config.upload.limits?.fileSize
|
|
89
|
+
const data = decodeBase64({ maxFileSize, value: input.data })
|
|
90
|
+
const file: File = {
|
|
91
|
+
name: sanitizeFilename(input.name),
|
|
92
|
+
data,
|
|
93
|
+
mimetype: input.mimeType,
|
|
94
|
+
size: data.length,
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (maxFileSize !== undefined && Number.isFinite(maxFileSize) && file.size > maxFileSize) {
|
|
98
|
+
throw new APIError(`File exceeds the ${maxFileSize} byte upload limit.`, 400)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return file
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function decodeBase64({ maxFileSize, value }: { maxFileSize?: number; value: string }): Buffer {
|
|
105
|
+
const normalized = value.replace(/\s/g, '')
|
|
106
|
+
|
|
107
|
+
if (!/^[a-z0-9+/]*={0,2}$/i.test(normalized) || normalized.length % 4 === 1) {
|
|
108
|
+
throw new APIError('File data must be valid base64.', 400)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (maxFileSize !== undefined && Number.isFinite(maxFileSize)) {
|
|
112
|
+
const paddingLength = normalized.endsWith('==') ? 2 : normalized.endsWith('=') ? 1 : 0
|
|
113
|
+
const decodedSize = Math.floor((normalized.length * 3) / 4) - paddingLength
|
|
114
|
+
|
|
115
|
+
if (decodedSize > maxFileSize) {
|
|
116
|
+
throw new APIError(`File exceeds the ${maxFileSize} byte upload limit.`, 400)
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const data = Buffer.from(normalized, 'base64')
|
|
121
|
+
|
|
122
|
+
if (data.toString('base64').replace(/=+$/, '') !== normalized.replace(/=+$/, '')) {
|
|
123
|
+
throw new APIError('File data must be valid base64.', 400)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return data
|
|
127
|
+
}
|
|
@@ -1,19 +1,15 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
import { z } from 'zod'
|
|
1
|
+
import { findDistinctInputSchema } 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
|
-
import { whereSchema } from '../../../utils/whereSchema.js'
|
|
10
6
|
|
|
11
7
|
const DEFAULT_DESCRIPTION =
|
|
12
8
|
'Find distinct values for a field in any collection by passing the collection slug and field path.'
|
|
13
9
|
|
|
14
10
|
export const findDistinctTool = defineCollectionTool({
|
|
15
11
|
access: (args) =>
|
|
16
|
-
defaultAccess(args) && Boolean(args.permissions?.collections?.[args.
|
|
12
|
+
defaultAccess(args) && Boolean(args.permissions?.collections?.[args.slug]?.read),
|
|
17
13
|
annotations: {
|
|
18
14
|
destructiveHint: false,
|
|
19
15
|
idempotentHint: true,
|
|
@@ -22,74 +18,25 @@ export const findDistinctTool = defineCollectionTool({
|
|
|
22
18
|
title: 'Find Distinct',
|
|
23
19
|
},
|
|
24
20
|
description: DEFAULT_DESCRIPTION,
|
|
25
|
-
input:
|
|
26
|
-
|
|
27
|
-
.number()
|
|
28
|
-
.int()
|
|
29
|
-
.min(0)
|
|
30
|
-
.max(10)
|
|
31
|
-
.describe('How many levels deep to populate relationships in distinct values')
|
|
32
|
-
.optional()
|
|
33
|
-
.default(0),
|
|
34
|
-
field: z.string().describe('The field path to get distinct values for'),
|
|
35
|
-
limit: z
|
|
36
|
-
.number()
|
|
37
|
-
.int()
|
|
38
|
-
.min(1)
|
|
39
|
-
.max(100)
|
|
40
|
-
.describe('Maximum number of distinct values to return (max: 100)')
|
|
41
|
-
.optional(),
|
|
42
|
-
locale: z
|
|
43
|
-
.string()
|
|
44
|
-
.describe(
|
|
45
|
-
'Optional: locale code to retrieve data in (e.g., "en", "es"). Use "all" to retrieve all locales for localized fields',
|
|
46
|
-
)
|
|
47
|
-
.optional(),
|
|
48
|
-
page: z.number().int().min(1).describe('Page number for pagination').optional(),
|
|
49
|
-
populate: z
|
|
50
|
-
.record(z.string(), z.unknown())
|
|
51
|
-
.describe(
|
|
52
|
-
'Optional: control which fields to include from populated relationship or upload documents.',
|
|
53
|
-
)
|
|
54
|
-
.optional(),
|
|
55
|
-
showHiddenFields: z
|
|
56
|
-
.boolean()
|
|
57
|
-
.describe('Optional: include hidden fields in the distinct query')
|
|
58
|
-
.optional(),
|
|
59
|
-
sort: z
|
|
60
|
-
.string()
|
|
61
|
-
.describe('Field to sort by (e.g., "createdAt", "-updatedAt" for descending)')
|
|
62
|
-
.optional(),
|
|
63
|
-
trash: z
|
|
64
|
-
.boolean()
|
|
65
|
-
.describe('Optional: include soft-deleted documents when trash is enabled on the collection')
|
|
66
|
-
.optional(),
|
|
67
|
-
where: whereSchema
|
|
68
|
-
.describe(
|
|
69
|
-
'Optional: where clause for filtering. Use field names with Payload operators, and/or arrays for grouping. Example: {"title":{"contains":"test"}}',
|
|
70
|
-
)
|
|
71
|
-
.optional(),
|
|
72
|
-
}),
|
|
73
|
-
}).handler(async ({ authorizedMCP, collectionSlug, input, req }) => {
|
|
21
|
+
input: findDistinctInputSchema,
|
|
22
|
+
}).handler(async ({ slug, authorizedMCP, input, req }) => {
|
|
74
23
|
const payload = req.payload
|
|
75
24
|
const logger = getLogger({ payload })
|
|
76
|
-
const { depth, field, limit, locale, page, populate,
|
|
77
|
-
input
|
|
25
|
+
const { depth, field, limit, locale, page, populate, sort, trash, where } = input
|
|
78
26
|
|
|
79
|
-
logger.info(`Finding distinct values in collection: ${
|
|
27
|
+
logger.info(`Finding distinct values in collection: ${slug}, field: ${field}`)
|
|
80
28
|
|
|
81
29
|
try {
|
|
82
30
|
const result = await payload.findDistinct({
|
|
83
|
-
collection:
|
|
31
|
+
collection: slug,
|
|
84
32
|
depth,
|
|
85
33
|
field,
|
|
34
|
+
overrideAccess: authorizedMCP.overrideAccess,
|
|
86
35
|
req,
|
|
87
|
-
...localAPIDefaults(authorizedMCP),
|
|
88
36
|
...(limit ? { limit } : {}),
|
|
89
37
|
...(locale ? { locale } : {}),
|
|
90
38
|
...(page ? { page } : {}),
|
|
91
|
-
...(populate ? { populate
|
|
92
|
-
...(showHiddenFields !== undefined ? { showHiddenFields } : {}),
|
|
39
|
+
...(populate ? { populate } : {}),
|
|
93
40
|
...(sort ? { sort } : {}),
|
|
94
41
|
...(trash !== undefined ? { trash } : {}),
|
|
95
42
|
...(where ? { where } : {}),
|
|
@@ -99,19 +46,19 @@ export const findDistinctTool = defineCollectionTool({
|
|
|
99
46
|
content: [
|
|
100
47
|
{
|
|
101
48
|
type: 'text',
|
|
102
|
-
text: `Distinct values for "${field}" in collection "${
|
|
49
|
+
text: `Distinct values for "${field}" in collection "${slug}":\n\`\`\`json\n${JSON.stringify(result)}\n\`\`\``,
|
|
103
50
|
},
|
|
104
51
|
],
|
|
105
52
|
doc: result as unknown as Record<string, unknown>,
|
|
106
53
|
}
|
|
107
54
|
} catch (error) {
|
|
108
55
|
const errorMessage = error instanceof Error ? error.message : 'Unknown error'
|
|
109
|
-
logger.error(`Error finding distinct values in ${
|
|
56
|
+
logger.error(`Error finding distinct values in ${slug}: ${errorMessage}`)
|
|
110
57
|
return {
|
|
111
58
|
content: [
|
|
112
59
|
{
|
|
113
60
|
type: 'text',
|
|
114
|
-
text: `❌ **Error finding distinct values in collection "${
|
|
61
|
+
text: `❌ **Error finding distinct values in collection "${slug}":** ${errorMessage}`,
|
|
115
62
|
},
|
|
116
63
|
],
|
|
117
64
|
isError: true,
|
|
@@ -1,19 +1,15 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
import { z } from 'zod'
|
|
1
|
+
import { findDocumentsInputSchema, parseDocumentID } 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
|
-
import { whereSchema } from '../../../utils/whereSchema.js'
|
|
10
6
|
|
|
11
7
|
const DEFAULT_DESCRIPTION =
|
|
12
8
|
'Find documents in any collection by passing the collection slug and optional ID or where clause.'
|
|
13
9
|
|
|
14
10
|
export const findDocumentsTool = defineCollectionTool({
|
|
15
11
|
access: (args) =>
|
|
16
|
-
defaultAccess(args) && Boolean(args.permissions?.collections?.[args.
|
|
12
|
+
defaultAccess(args) && Boolean(args.permissions?.collections?.[args.slug]?.read),
|
|
17
13
|
annotations: {
|
|
18
14
|
destructiveHint: false,
|
|
19
15
|
idempotentHint: true,
|
|
@@ -22,87 +18,8 @@ export const findDocumentsTool = defineCollectionTool({
|
|
|
22
18
|
title: 'Find Documents',
|
|
23
19
|
},
|
|
24
20
|
description: DEFAULT_DESCRIPTION,
|
|
25
|
-
input:
|
|
26
|
-
|
|
27
|
-
.union([z.string(), z.number()])
|
|
28
|
-
.describe(
|
|
29
|
-
'Optional: specific document ID to retrieve. If not provided, returns all documents',
|
|
30
|
-
)
|
|
31
|
-
.optional(),
|
|
32
|
-
depth: z
|
|
33
|
-
.number()
|
|
34
|
-
.int()
|
|
35
|
-
.min(0)
|
|
36
|
-
.max(10)
|
|
37
|
-
.describe('How many levels deep to populate relationships (default: 0)')
|
|
38
|
-
.optional()
|
|
39
|
-
.default(0),
|
|
40
|
-
draft: z
|
|
41
|
-
.boolean()
|
|
42
|
-
.describe(
|
|
43
|
-
'Optional: whether the document should be queried from the versions table/collection or not.',
|
|
44
|
-
)
|
|
45
|
-
.optional(),
|
|
46
|
-
fallbackLocale: z
|
|
47
|
-
.string()
|
|
48
|
-
.describe('Optional: fallback locale code to use when requested locale is not available')
|
|
49
|
-
.optional(),
|
|
50
|
-
joins: z
|
|
51
|
-
.union([z.record(z.string(), z.unknown()), z.literal(false)])
|
|
52
|
-
.describe('Optional: configure join field queries, or pass false to disable all join fields.')
|
|
53
|
-
.optional(),
|
|
54
|
-
limit: z
|
|
55
|
-
.number()
|
|
56
|
-
.int()
|
|
57
|
-
.min(1)
|
|
58
|
-
.max(100)
|
|
59
|
-
.describe('Maximum number of documents to return (default: 10, max: 100)')
|
|
60
|
-
.optional()
|
|
61
|
-
.default(10),
|
|
62
|
-
locale: z
|
|
63
|
-
.string()
|
|
64
|
-
.describe(
|
|
65
|
-
'Optional: locale code to retrieve data in (e.g., "en", "es"). Use "all" to retrieve all locales for localized fields',
|
|
66
|
-
)
|
|
67
|
-
.optional(),
|
|
68
|
-
page: z
|
|
69
|
-
.number()
|
|
70
|
-
.int()
|
|
71
|
-
.min(1)
|
|
72
|
-
.describe('Page number for pagination (default: 1)')
|
|
73
|
-
.optional()
|
|
74
|
-
.default(1),
|
|
75
|
-
pagination: z
|
|
76
|
-
.boolean()
|
|
77
|
-
.describe('Optional: set to false to skip the count query overhead')
|
|
78
|
-
.optional(),
|
|
79
|
-
populate: z
|
|
80
|
-
.record(z.string(), z.unknown())
|
|
81
|
-
.describe(
|
|
82
|
-
'Optional: control which fields to include from populated relationship or upload documents.',
|
|
83
|
-
)
|
|
84
|
-
.optional(),
|
|
85
|
-
select: z
|
|
86
|
-
.record(z.string(), z.unknown())
|
|
87
|
-
.describe(
|
|
88
|
-
'Optional: define exactly which fields you\'d like to return in the response, e.g., {"title": true}',
|
|
89
|
-
)
|
|
90
|
-
.optional(),
|
|
91
|
-
sort: z
|
|
92
|
-
.string()
|
|
93
|
-
.describe('Field to sort by (e.g., "createdAt", "-updatedAt" for descending)')
|
|
94
|
-
.optional(),
|
|
95
|
-
trash: z
|
|
96
|
-
.boolean()
|
|
97
|
-
.describe('Optional: include soft-deleted documents when trash is enabled on the collection')
|
|
98
|
-
.optional(),
|
|
99
|
-
where: whereSchema
|
|
100
|
-
.describe(
|
|
101
|
-
'Optional: where clause for filtering. Use field names with Payload operators, and/or arrays for grouping. Example: {"title":{"contains":"test"}}',
|
|
102
|
-
)
|
|
103
|
-
.optional(),
|
|
104
|
-
}),
|
|
105
|
-
}).handler(async ({ authorizedMCP, collectionSlug, input, req }) => {
|
|
21
|
+
input: findDocumentsInputSchema,
|
|
22
|
+
}).handler(async ({ slug, authorizedMCP, input, req }) => {
|
|
106
23
|
const payload = req.payload
|
|
107
24
|
const logger = getLogger({ payload })
|
|
108
25
|
|
|
@@ -124,23 +41,23 @@ export const findDocumentsTool = defineCollectionTool({
|
|
|
124
41
|
} = input
|
|
125
42
|
|
|
126
43
|
logger.info(
|
|
127
|
-
`Reading document from collection: ${
|
|
44
|
+
`Reading document from collection: ${slug}${id ? ` with ID: ${id}` : ''}, limit: ${limit}, page: ${page}${locale ? `, locale: ${locale}` : ''}`,
|
|
128
45
|
)
|
|
129
46
|
|
|
130
47
|
try {
|
|
131
|
-
if (id) {
|
|
48
|
+
if (id !== undefined) {
|
|
132
49
|
try {
|
|
133
50
|
const doc = await payload.findByID({
|
|
134
|
-
id,
|
|
135
|
-
collection:
|
|
51
|
+
id: parseDocumentID({ id, collectionSlug: slug, payload }),
|
|
52
|
+
collection: slug,
|
|
136
53
|
depth,
|
|
54
|
+
overrideAccess: authorizedMCP.overrideAccess,
|
|
137
55
|
req,
|
|
138
|
-
...
|
|
139
|
-
...(
|
|
140
|
-
...(
|
|
141
|
-
...(joins !== undefined && { joins: joins as JoinQuery }),
|
|
56
|
+
...(select && { select }),
|
|
57
|
+
...(populate && { populate }),
|
|
58
|
+
...(joins !== undefined && { joins }),
|
|
142
59
|
...(locale && { locale }),
|
|
143
|
-
...(fallbackLocale && { fallbackLocale }),
|
|
60
|
+
...(fallbackLocale !== undefined && { fallbackLocale }),
|
|
144
61
|
...(draft !== undefined && { draft }),
|
|
145
62
|
...(trash !== undefined && { trash }),
|
|
146
63
|
})
|
|
@@ -149,18 +66,18 @@ export const findDocumentsTool = defineCollectionTool({
|
|
|
149
66
|
content: [
|
|
150
67
|
{
|
|
151
68
|
type: 'text',
|
|
152
|
-
text: `Document from collection "${
|
|
69
|
+
text: `Document from collection "${slug}":\n${JSON.stringify(doc)}`,
|
|
153
70
|
},
|
|
154
71
|
],
|
|
155
72
|
doc: doc as Record<string, unknown>,
|
|
156
73
|
}
|
|
157
74
|
} catch {
|
|
158
|
-
logger.warn(`Document not found with ID: ${id} in collection: ${
|
|
75
|
+
logger.warn(`Document not found with ID: ${id} in collection: ${slug}`)
|
|
159
76
|
return {
|
|
160
77
|
content: [
|
|
161
78
|
{
|
|
162
79
|
type: 'text',
|
|
163
|
-
text: `Error: Document with ID "${id}" not found in collection "${
|
|
80
|
+
text: `Error: Document with ID "${id}" not found in collection "${slug}"`,
|
|
164
81
|
},
|
|
165
82
|
],
|
|
166
83
|
}
|
|
@@ -168,17 +85,17 @@ export const findDocumentsTool = defineCollectionTool({
|
|
|
168
85
|
}
|
|
169
86
|
|
|
170
87
|
const findOptions: Parameters<typeof payload.find>[0] = {
|
|
171
|
-
collection:
|
|
88
|
+
collection: slug,
|
|
172
89
|
depth,
|
|
173
90
|
limit,
|
|
91
|
+
overrideAccess: authorizedMCP.overrideAccess,
|
|
174
92
|
page,
|
|
175
93
|
req,
|
|
176
|
-
...
|
|
177
|
-
...(
|
|
178
|
-
...(
|
|
179
|
-
...(joins !== undefined && { joins: joins as JoinQuery }),
|
|
94
|
+
...(select && { select }),
|
|
95
|
+
...(populate && { populate }),
|
|
96
|
+
...(joins !== undefined && { joins }),
|
|
180
97
|
...(locale && { locale }),
|
|
181
|
-
...(fallbackLocale && { fallbackLocale }),
|
|
98
|
+
...(fallbackLocale !== undefined && { fallbackLocale }),
|
|
182
99
|
...(draft !== undefined && { draft }),
|
|
183
100
|
...(pagination !== undefined && { pagination }),
|
|
184
101
|
...(trash !== undefined && { trash }),
|
|
@@ -193,7 +110,7 @@ export const findDocumentsTool = defineCollectionTool({
|
|
|
193
110
|
|
|
194
111
|
const result = await payload.find(findOptions)
|
|
195
112
|
|
|
196
|
-
let responseText = `Collection: "${
|
|
113
|
+
let responseText = `Collection: "${slug}"\nTotal: ${result.totalDocs} documents\nPage: ${result.page} of ${result.totalPages}\n`
|
|
197
114
|
for (const doc of result.docs) {
|
|
198
115
|
responseText += `\n\`\`\`json\n${JSON.stringify(doc)}\n\`\`\``
|
|
199
116
|
}
|
|
@@ -204,12 +121,12 @@ export const findDocumentsTool = defineCollectionTool({
|
|
|
204
121
|
}
|
|
205
122
|
} catch (error) {
|
|
206
123
|
const errorMessage = error instanceof Error ? error.message : 'Unknown error'
|
|
207
|
-
logger.error(`Error reading documents from collection ${
|
|
124
|
+
logger.error(`Error reading documents from collection ${slug}: ${errorMessage}`)
|
|
208
125
|
return {
|
|
209
126
|
content: [
|
|
210
127
|
{
|
|
211
128
|
type: 'text',
|
|
212
|
-
text: `❌ **Error reading documents from collection "${
|
|
129
|
+
text: `❌ **Error reading documents from collection "${slug}":** ${errorMessage}`,
|
|
213
130
|
},
|
|
214
131
|
],
|
|
215
132
|
}
|
|
@@ -1,19 +1,15 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
import { z } from 'zod'
|
|
1
|
+
import { findVersionByIDInputSchema } 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
|
'Find a specific document version in any version-enabled collection by passing the collection slug and version ID.'
|
|
12
9
|
|
|
13
10
|
export const findVersionByIDTool = defineCollectionTool({
|
|
14
11
|
access: (args) =>
|
|
15
|
-
defaultAccess(args) &&
|
|
16
|
-
Boolean(args.permissions?.collections?.[args.collectionSlug]?.readVersions),
|
|
12
|
+
defaultAccess(args) && Boolean(args.permissions?.collections?.[args.slug]?.readVersions),
|
|
17
13
|
annotations: {
|
|
18
14
|
destructiveHint: false,
|
|
19
15
|
idempotentHint: true,
|
|
@@ -22,66 +18,26 @@ export const findVersionByIDTool = defineCollectionTool({
|
|
|
22
18
|
title: 'Find Version By ID',
|
|
23
19
|
},
|
|
24
20
|
description: DEFAULT_DESCRIPTION,
|
|
25
|
-
input:
|
|
26
|
-
|
|
27
|
-
depth: z
|
|
28
|
-
.number()
|
|
29
|
-
.int()
|
|
30
|
-
.min(0)
|
|
31
|
-
.max(10)
|
|
32
|
-
.describe('How many levels deep to populate relationships in the version document')
|
|
33
|
-
.optional()
|
|
34
|
-
.default(0),
|
|
35
|
-
fallbackLocale: z
|
|
36
|
-
.string()
|
|
37
|
-
.describe('Optional: fallback locale code to use when requested locale is not available')
|
|
38
|
-
.optional(),
|
|
39
|
-
locale: z
|
|
40
|
-
.string()
|
|
41
|
-
.describe(
|
|
42
|
-
'Optional: locale code to retrieve data in (e.g., "en", "es"). Use "all" to retrieve all locales for localized fields',
|
|
43
|
-
)
|
|
44
|
-
.optional(),
|
|
45
|
-
populate: z
|
|
46
|
-
.record(z.string(), z.unknown())
|
|
47
|
-
.describe(
|
|
48
|
-
'Optional: control which fields to include from populated relationship or upload documents.',
|
|
49
|
-
)
|
|
50
|
-
.optional(),
|
|
51
|
-
select: z
|
|
52
|
-
.record(z.string(), z.unknown())
|
|
53
|
-
.describe(
|
|
54
|
-
'Optional: define exactly which fields you\'d like to return in the response, e.g., {"version.title": true}',
|
|
55
|
-
)
|
|
56
|
-
.optional(),
|
|
57
|
-
showHiddenFields: z
|
|
58
|
-
.boolean()
|
|
59
|
-
.describe('Optional: include hidden fields in the returned version document')
|
|
60
|
-
.optional(),
|
|
61
|
-
trash: z
|
|
62
|
-
.boolean()
|
|
63
|
-
.describe('Optional: include soft-deleted version documents when trash is enabled')
|
|
64
|
-
.optional(),
|
|
65
|
-
}),
|
|
66
|
-
}).handler(async ({ authorizedMCP, collectionSlug, input, req }) => {
|
|
21
|
+
input: findVersionByIDInputSchema,
|
|
22
|
+
}).handler(async ({ slug, authorizedMCP, input, req }) => {
|
|
67
23
|
const payload = req.payload
|
|
68
24
|
const logger = getLogger({ payload })
|
|
69
|
-
const { id, depth, fallbackLocale, locale, populate, select,
|
|
25
|
+
const { id, depth, draft, fallbackLocale, locale, populate, select, trash } = input
|
|
70
26
|
|
|
71
|
-
logger.info(`Finding version in collection: ${
|
|
27
|
+
logger.info(`Finding version in collection: ${slug} with ID: ${id}`)
|
|
72
28
|
|
|
73
29
|
try {
|
|
74
30
|
const result = await payload.findVersionByID({
|
|
75
|
-
id,
|
|
76
|
-
collection:
|
|
31
|
+
id: String(id),
|
|
32
|
+
collection: slug,
|
|
77
33
|
depth,
|
|
34
|
+
overrideAccess: authorizedMCP.overrideAccess,
|
|
78
35
|
req,
|
|
79
|
-
...
|
|
80
|
-
...(fallbackLocale ? { fallbackLocale } : {}),
|
|
36
|
+
...(draft !== undefined ? { draft } : {}),
|
|
37
|
+
...(fallbackLocale !== undefined ? { fallbackLocale } : {}),
|
|
81
38
|
...(locale ? { locale } : {}),
|
|
82
|
-
...(populate ? { populate
|
|
83
|
-
...(select ? { select
|
|
84
|
-
...(showHiddenFields !== undefined ? { showHiddenFields } : {}),
|
|
39
|
+
...(populate ? { populate } : {}),
|
|
40
|
+
...(select ? { select } : {}),
|
|
85
41
|
...(trash !== undefined ? { trash } : {}),
|
|
86
42
|
})
|
|
87
43
|
|
|
@@ -89,19 +45,19 @@ export const findVersionByIDTool = defineCollectionTool({
|
|
|
89
45
|
content: [
|
|
90
46
|
{
|
|
91
47
|
type: 'text',
|
|
92
|
-
text: `Version "${id}" from collection "${
|
|
48
|
+
text: `Version "${id}" from collection "${slug}":\n\`\`\`json\n${JSON.stringify(result)}\n\`\`\``,
|
|
93
49
|
},
|
|
94
50
|
],
|
|
95
51
|
doc: result as unknown as Record<string, unknown>,
|
|
96
52
|
}
|
|
97
53
|
} catch (error) {
|
|
98
54
|
const errorMessage = error instanceof Error ? error.message : 'Unknown error'
|
|
99
|
-
logger.error(`Error finding version ${id} in ${
|
|
55
|
+
logger.error(`Error finding version ${id} in ${slug}: ${errorMessage}`)
|
|
100
56
|
return {
|
|
101
57
|
content: [
|
|
102
58
|
{
|
|
103
59
|
type: 'text',
|
|
104
|
-
text: `❌ **Error finding version "${id}" in collection "${
|
|
60
|
+
text: `❌ **Error finding version "${id}" in collection "${slug}":** ${errorMessage}`,
|
|
105
61
|
},
|
|
106
62
|
],
|
|
107
63
|
isError: true,
|