@payloadcms/plugin-mcp 4.0.0-internal.293e026 → 4.0.0-internal.2a3c3bc
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 +3 -0
- package/dist/defaultAccess.d.ts.map +1 -0
- package/dist/defaultAccess.js +3 -0
- package/dist/defaultAccess.js.map +1 -0
- package/dist/defineTool.d.ts +8 -8
- package/dist/defineTool.d.ts.map +1 -1
- package/dist/endpoint/access.d.ts +12 -5
- package/dist/endpoint/access.d.ts.map +1 -1
- package/dist/endpoint/access.js +76 -88
- 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 +102 -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/exports/client.d.ts +1 -1
- package/dist/exports/client.d.ts.map +1 -1
- package/dist/exports/client.js +1 -1
- package/dist/exports/client.js.map +1 -1
- package/dist/exports/internal.d.ts +2 -0
- package/dist/exports/internal.d.ts.map +1 -0
- package/dist/exports/internal.js +3 -0
- package/dist/exports/internal.js.map +1 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -20
- 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 +146 -81
- 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 +123 -61
- package/dist/mcp/builtin/collections/authTools.js.map +1 -1
- package/dist/mcp/builtin/collections/countTool.d.ts +2 -0
- package/dist/mcp/builtin/collections/countTool.d.ts.map +1 -0
- package/dist/mcp/builtin/collections/countTool.js +63 -0
- package/dist/mcp/builtin/collections/countTool.js.map +1 -0
- package/dist/mcp/builtin/collections/countVersionsTool.d.ts +2 -0
- package/dist/mcp/builtin/collections/countVersionsTool.d.ts.map +1 -0
- package/dist/mcp/builtin/collections/countVersionsTool.js +60 -0
- package/dist/mcp/builtin/collections/countVersionsTool.js.map +1 -0
- 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 +114 -68
- package/dist/mcp/builtin/collections/createTool.js.map +1 -1
- package/dist/mcp/builtin/collections/deleteTool.d.ts +1 -1
- package/dist/mcp/builtin/collections/deleteTool.d.ts.map +1 -1
- package/dist/mcp/builtin/collections/deleteTool.js +55 -61
- package/dist/mcp/builtin/collections/deleteTool.js.map +1 -1
- package/dist/mcp/builtin/collections/duplicateTool.d.ts +2 -0
- package/dist/mcp/builtin/collections/duplicateTool.d.ts.map +1 -0
- package/dist/mcp/builtin/collections/duplicateTool.js +90 -0
- package/dist/mcp/builtin/collections/duplicateTool.js.map +1 -0
- 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 +2 -0
- package/dist/mcp/builtin/collections/findDistinctTool.d.ts.map +1 -0
- package/dist/mcp/builtin/collections/findDistinctTool.js +77 -0
- package/dist/mcp/builtin/collections/findDistinctTool.js.map +1 -0
- package/dist/mcp/builtin/collections/findTool.d.ts +1 -1
- package/dist/mcp/builtin/collections/findTool.d.ts.map +1 -1
- package/dist/mcp/builtin/collections/findTool.js +61 -74
- package/dist/mcp/builtin/collections/findTool.js.map +1 -1
- package/dist/mcp/builtin/collections/findVersionByIDTool.d.ts +2 -0
- package/dist/mcp/builtin/collections/findVersionByIDTool.d.ts.map +1 -0
- package/dist/mcp/builtin/collections/findVersionByIDTool.js +74 -0
- package/dist/mcp/builtin/collections/findVersionByIDTool.js.map +1 -0
- package/dist/mcp/builtin/collections/findVersionsTool.d.ts +2 -0
- package/dist/mcp/builtin/collections/findVersionsTool.d.ts.map +1 -0
- package/dist/mcp/builtin/collections/findVersionsTool.js +84 -0
- package/dist/mcp/builtin/collections/findVersionsTool.js.map +1 -0
- package/dist/mcp/builtin/collections/getCollectionSchemaTool.d.ts +2 -0
- package/dist/mcp/builtin/collections/getCollectionSchemaTool.d.ts.map +1 -0
- package/dist/mcp/builtin/collections/getCollectionSchemaTool.js +103 -0
- package/dist/mcp/builtin/collections/getCollectionSchemaTool.js.map +1 -0
- package/dist/mcp/builtin/collections/restoreVersionTool.d.ts +2 -0
- package/dist/mcp/builtin/collections/restoreVersionTool.d.ts.map +1 -0
- package/dist/mcp/builtin/collections/restoreVersionTool.js +69 -0
- package/dist/mcp/builtin/collections/restoreVersionTool.js.map +1 -0
- package/dist/mcp/builtin/collections/updateTool.d.ts +1 -1
- package/dist/mcp/builtin/collections/updateTool.d.ts.map +1 -1
- package/dist/mcp/builtin/collections/updateTool.js +118 -137
- 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 +2 -0
- package/dist/mcp/builtin/getConfigInfoTool.d.ts.map +1 -0
- package/dist/mcp/builtin/getConfigInfoTool.js +69 -0
- package/dist/mcp/builtin/getConfigInfoTool.js.map +1 -0
- package/dist/mcp/builtin/globals/countVersionsTool.d.ts +2 -0
- package/dist/mcp/builtin/globals/countVersionsTool.d.ts.map +1 -0
- package/dist/mcp/builtin/globals/countVersionsTool.js +60 -0
- package/dist/mcp/builtin/globals/countVersionsTool.js.map +1 -0
- package/dist/mcp/builtin/globals/findTool.d.ts.map +1 -1
- package/dist/mcp/builtin/globals/findTool.js +27 -36
- package/dist/mcp/builtin/globals/findTool.js.map +1 -1
- package/dist/mcp/builtin/globals/findVersionByIDTool.d.ts +2 -0
- package/dist/mcp/builtin/globals/findVersionByIDTool.d.ts.map +1 -0
- package/dist/mcp/builtin/globals/findVersionByIDTool.js +68 -0
- package/dist/mcp/builtin/globals/findVersionByIDTool.js.map +1 -0
- package/dist/mcp/builtin/globals/findVersionsTool.d.ts +2 -0
- package/dist/mcp/builtin/globals/findVersionsTool.d.ts.map +1 -0
- package/dist/mcp/builtin/globals/findVersionsTool.js +78 -0
- package/dist/mcp/builtin/globals/findVersionsTool.js.map +1 -0
- package/dist/mcp/builtin/globals/getGlobalSchemaTool.d.ts +2 -0
- package/dist/mcp/builtin/globals/getGlobalSchemaTool.d.ts.map +1 -0
- package/dist/mcp/builtin/globals/getGlobalSchemaTool.js +81 -0
- package/dist/mcp/builtin/globals/getGlobalSchemaTool.js.map +1 -0
- package/dist/mcp/builtin/globals/restoreVersionTool.d.ts +2 -0
- package/dist/mcp/builtin/globals/restoreVersionTool.d.ts.map +1 -0
- package/dist/mcp/builtin/globals/restoreVersionTool.js +70 -0
- package/dist/mcp/builtin/globals/restoreVersionTool.js.map +1 -0
- package/dist/mcp/builtin/globals/updateTool.d.ts.map +1 -1
- package/dist/mcp/builtin/globals/updateTool.js +44 -62
- package/dist/mcp/builtin/globals/updateTool.js.map +1 -1
- package/dist/mcp/builtinTools.d.ts +150 -19
- package/dist/mcp/builtinTools.d.ts.map +1 -1
- package/dist/mcp/builtinTools.js +125 -20
- package/dist/mcp/builtinTools.js.map +1 -1
- package/dist/mcp/sanitizeMCPConfig.d.ts +0 -1
- package/dist/mcp/sanitizeMCPConfig.d.ts.map +1 -1
- package/dist/mcp/sanitizeMCPConfig.js +125 -58
- package/dist/mcp/sanitizeMCPConfig.js.map +1 -1
- package/dist/stdio.d.ts +3 -3
- package/dist/stdio.d.ts.map +1 -1
- package/dist/stdio.js +86 -47
- package/dist/stdio.js.map +1 -1
- package/dist/types.d.ts +138 -114
- 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/getPluginConfig.d.ts +1 -1
- package/dist/utils/getPluginConfig.js +1 -1
- package/dist/utils/getPluginConfig.js.map +1 -1
- package/dist/utils/resolveProjectRoot.d.ts.map +1 -1
- package/dist/utils/toStandardSchema.d.ts.map +1 -1
- package/package.json +11 -18
- package/src/defaultAccess.ts +3 -0
- package/src/endpoint/access.ts +81 -101
- package/src/endpoint/index.ts +93 -15
- package/src/endpoint/oauth.ts +72 -0
- package/src/exports/client.ts +2 -1
- package/src/exports/internal.ts +1 -0
- package/src/index.ts +19 -20
- package/src/mcp/buildMcpServer.ts +181 -116
- package/src/mcp/builtin/collections/authTools.ts +122 -75
- package/src/mcp/builtin/collections/countTool.ts +61 -0
- package/src/mcp/builtin/collections/countVersionsTool.ts +60 -0
- package/src/mcp/builtin/collections/createTool.ts +117 -88
- package/src/mcp/builtin/collections/deleteTool.ts +48 -74
- package/src/mcp/builtin/collections/duplicateTool.ts +84 -0
- 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 +67 -0
- package/src/mcp/builtin/collections/findTool.ts +57 -110
- package/src/mcp/builtin/collections/findVersionByIDTool.ts +66 -0
- package/src/mcp/builtin/collections/findVersionsTool.ts +83 -0
- package/src/mcp/builtin/collections/getCollectionSchemaTool.ts +91 -0
- package/src/mcp/builtin/collections/restoreVersionTool.ts +65 -0
- package/src/mcp/builtin/collections/updateTool.ts +106 -143
- package/src/mcp/builtin/collections/uploadInstructionsTool.ts +64 -0
- package/src/mcp/builtin/formatEntityError.ts +77 -0
- package/src/mcp/builtin/getConfigInfoTool.ts +68 -0
- package/src/mcp/builtin/globals/countVersionsTool.ts +60 -0
- package/src/mcp/builtin/globals/findTool.ts +27 -57
- package/src/mcp/builtin/globals/findVersionByIDTool.ts +64 -0
- package/src/mcp/builtin/globals/findVersionsTool.ts +69 -0
- package/src/mcp/builtin/globals/getGlobalSchemaTool.ts +73 -0
- package/src/mcp/builtin/globals/restoreVersionTool.ts +68 -0
- package/src/mcp/builtin/globals/updateTool.ts +51 -79
- package/src/mcp/builtinTools.ts +118 -41
- package/src/mcp/sanitizeMCPConfig.ts +121 -78
- package/src/stdio.ts +80 -47
- package/src/types.ts +156 -120
- package/src/utils/getPluginConfig.ts +1 -1
- package/dist/@types/assets.d.js +0 -2
- package/dist/@types/assets.d.js.map +0 -1
- package/dist/collection/getAccessField.d.ts +0 -12
- package/dist/collection/getAccessField.d.ts.map +0 -1
- package/dist/collection/getAccessField.js +0 -57
- package/dist/collection/getAccessField.js.map +0 -1
- package/dist/collection/index.d.ts +0 -6
- package/dist/collection/index.d.ts.map +0 -1
- package/dist/collection/index.js +0 -60
- package/dist/collection/index.js.map +0 -1
- package/dist/components/AccessField/index.client.d.ts +0 -10
- package/dist/components/AccessField/index.client.d.ts.map +0 -1
- package/dist/components/AccessField/index.client.js +0 -305
- package/dist/components/AccessField/index.client.js.map +0 -1
- package/dist/components/AccessField/index.css +0 -93
- 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/buildToolInput.d.ts +0 -29
- package/dist/utils/schemaConversion/buildToolInput.d.ts.map +0 -1
- package/dist/utils/schemaConversion/buildToolInput.js +0 -51
- package/dist/utils/schemaConversion/buildToolInput.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/src/@types/assets.d.ts +0 -3
- package/src/collection/getAccessField.ts +0 -64
- package/src/collection/index.ts +0 -64
- package/src/components/AccessField/index.client.tsx +0 -344
- package/src/components/AccessField/index.css +0 -93
- package/src/utils/getVirtualFieldNames.ts +0 -53
- package/src/utils/localAPIDefaults.ts +0 -22
- package/src/utils/schemaConversion/buildToolInput.ts +0 -68
- 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
|
@@ -1,38 +1,31 @@
|
|
|
1
|
+
import type { PayloadRequest } from 'payload'
|
|
2
|
+
|
|
1
3
|
import { McpServer, type ServerContext } from '@modelcontextprotocol/server'
|
|
2
|
-
import { APIError,
|
|
4
|
+
import { APIError, strictObject, z } from 'payload'
|
|
3
5
|
|
|
4
6
|
import type {
|
|
5
7
|
AuthorizedMCP,
|
|
8
|
+
CollectionMCPItem,
|
|
9
|
+
GlobalMCPItem,
|
|
6
10
|
JsonSchemaType,
|
|
7
11
|
MCPResponseOverride,
|
|
8
12
|
MCPToolResponse,
|
|
9
13
|
SanitizedMCPPluginConfig,
|
|
14
|
+
ToolInputSchema,
|
|
10
15
|
} from '../types.js'
|
|
11
16
|
|
|
12
|
-
import { toCamelCase } from '../utils/camelCase.js'
|
|
13
17
|
import { getLogger } from '../utils/getLogger.js'
|
|
14
|
-
import {
|
|
15
|
-
getCollectionVirtualFieldNames,
|
|
16
|
-
getGlobalVirtualFieldNames,
|
|
17
|
-
} from '../utils/getVirtualFieldNames.js'
|
|
18
|
-
import { removeVirtualFieldsFromSchema } from '../utils/schemaConversion/removeVirtualFieldsFromSchema.js'
|
|
19
18
|
import { toStandardSchema } from '../utils/toStandardSchema.js'
|
|
20
19
|
|
|
21
|
-
/** `findPosts`, `updateSiteSettings` — auto-prefixed wire name for collection/global tools. */
|
|
22
|
-
const wireName = (key: string, slug: string): string => {
|
|
23
|
-
const camel = toCamelCase(slug)
|
|
24
|
-
return `${key}${camel.charAt(0).toUpperCase()}${camel.slice(1)}`
|
|
25
|
-
}
|
|
26
|
-
|
|
27
20
|
/**
|
|
28
|
-
*
|
|
29
|
-
* `McpServer` and returns it. The
|
|
30
|
-
*
|
|
31
|
-
*
|
|
21
|
+
* Serving-entry-agnostic core: registers every authorized MCP item onto a fresh
|
|
22
|
+
* `McpServer` and returns it. The HTTP and stdio entry point callers provide fresh
|
|
23
|
+
* instances from this builder while they own the transport and protocol-era
|
|
24
|
+
* decision.
|
|
32
25
|
*
|
|
33
26
|
* `req` is the request context handlers see. For HTTP it's the live
|
|
34
27
|
* `PayloadRequest` derived from the incoming HTTP request; for stdio it's a
|
|
35
|
-
* synthesized one built via `
|
|
28
|
+
* synthesized one built via `createPayloadRequest`.
|
|
36
29
|
*/
|
|
37
30
|
export const buildMcpServer = ({
|
|
38
31
|
authorizedMCP,
|
|
@@ -43,6 +36,8 @@ export const buildMcpServer = ({
|
|
|
43
36
|
pluginConfig: SanitizedMCPPluginConfig
|
|
44
37
|
req: PayloadRequest
|
|
45
38
|
}): McpServer => {
|
|
39
|
+
z.config(z.locales.en())
|
|
40
|
+
|
|
46
41
|
const serverOptions = pluginConfig.mcp?.serverOptions || {}
|
|
47
42
|
const server = new McpServer(
|
|
48
43
|
{ name: 'Payload MCP Server', version: '1.0.0', ...serverOptions.serverInfo },
|
|
@@ -55,110 +50,126 @@ export const buildMcpServer = ({
|
|
|
55
50
|
* Wrap a tool handler's response with the tool's `overrideResponse`, then
|
|
56
51
|
* strip the internal `doc` field so it doesn't leak onto the wire.
|
|
57
52
|
*/
|
|
58
|
-
const finalizeToolResponse = (
|
|
59
|
-
|
|
60
|
-
overrideResponse
|
|
61
|
-
|
|
62
|
-
|
|
53
|
+
const finalizeToolResponse = async ({
|
|
54
|
+
input,
|
|
55
|
+
overrideResponse,
|
|
56
|
+
response,
|
|
57
|
+
toolName,
|
|
58
|
+
}: {
|
|
59
|
+
input: unknown
|
|
60
|
+
overrideResponse?: MCPResponseOverride
|
|
61
|
+
response: MCPToolResponse
|
|
62
|
+
toolName: string
|
|
63
|
+
}): Promise<MCPToolResponse> => {
|
|
64
|
+
let overridden = overrideResponse?.(response, response.doc ?? {}, req) ?? response
|
|
65
|
+
for (const hook of pluginConfig.hooks?.afterToolCall ?? []) {
|
|
66
|
+
overridden = await hook({ input, req, response: overridden, toolName })
|
|
67
|
+
}
|
|
63
68
|
const { doc: _doc, ...rest } = overridden
|
|
64
69
|
return rest
|
|
65
70
|
}
|
|
66
71
|
|
|
72
|
+
/**
|
|
73
|
+
* Runs a collection/global tool call:
|
|
74
|
+
* - reads `slug` from the input
|
|
75
|
+
* - runs access control: errors if `authorizedMCP.items` has no entry for this tool + slug
|
|
76
|
+
* - runs the tool handler and finalizes its response
|
|
77
|
+
*/
|
|
78
|
+
const callEntityTool = async ({
|
|
79
|
+
input,
|
|
80
|
+
item,
|
|
81
|
+
serverContext,
|
|
82
|
+
}: {
|
|
83
|
+
input: unknown
|
|
84
|
+
item: CollectionMCPItem | GlobalMCPItem
|
|
85
|
+
serverContext: ServerContext
|
|
86
|
+
}): Promise<MCPToolResponse> => {
|
|
87
|
+
const entity = item.type === 'collectionTool' ? 'collection' : 'global'
|
|
88
|
+
const toolInput = (input ?? {}) as Record<string, unknown>
|
|
89
|
+
const slug = toolInput.slug as string | undefined
|
|
90
|
+
|
|
91
|
+
if (!slug) {
|
|
92
|
+
return {
|
|
93
|
+
content: [
|
|
94
|
+
{
|
|
95
|
+
type: 'text',
|
|
96
|
+
text: `Error: "${item.mcpName}" requires slug. Use getConfigInfo to inspect ${entity} slugs.`,
|
|
97
|
+
},
|
|
98
|
+
],
|
|
99
|
+
isError: true,
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const match = authorizedMCP.items.find(
|
|
104
|
+
(candidate): candidate is CollectionMCPItem | GlobalMCPItem =>
|
|
105
|
+
candidate.type === item.type &&
|
|
106
|
+
candidate.mcpName === item.mcpName &&
|
|
107
|
+
(candidate.type === 'collectionTool'
|
|
108
|
+
? candidate.collectionSlug === slug
|
|
109
|
+
: candidate.type === 'globalTool' && candidate.globalSlug === slug),
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
if (!match) {
|
|
113
|
+
return {
|
|
114
|
+
content: [
|
|
115
|
+
{
|
|
116
|
+
type: 'text',
|
|
117
|
+
text: `Error: MCP access to "${item.mcpName}" is not enabled for ${entity} "${slug}"`,
|
|
118
|
+
},
|
|
119
|
+
],
|
|
120
|
+
isError: true,
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const handlerArgs = {
|
|
125
|
+
authorizedMCP,
|
|
126
|
+
input: toolInput,
|
|
127
|
+
req,
|
|
128
|
+
serverContext,
|
|
129
|
+
}
|
|
130
|
+
const response = await (match.type === 'collectionTool'
|
|
131
|
+
? match.tool.handler({ ...handlerArgs, slug })
|
|
132
|
+
: match.tool.handler({ ...handlerArgs, slug }))
|
|
133
|
+
|
|
134
|
+
return finalizeToolResponse({
|
|
135
|
+
input: toolInput,
|
|
136
|
+
overrideResponse: match.tool.overrideResponse,
|
|
137
|
+
response,
|
|
138
|
+
toolName: match.mcpName,
|
|
139
|
+
})
|
|
140
|
+
}
|
|
141
|
+
|
|
67
142
|
try {
|
|
143
|
+
const registeredEntityTools = new Set<string>()
|
|
144
|
+
|
|
68
145
|
for (const item of authorizedMCP.items) {
|
|
69
146
|
switch (item.type) {
|
|
70
|
-
case 'collectionTool':
|
|
71
|
-
const tool = item.tool
|
|
72
|
-
const name = wireName(item.key, item.collectionSlug)
|
|
73
|
-
let inputSchema = tool.input
|
|
74
|
-
if (typeof inputSchema === 'function') {
|
|
75
|
-
const collection = req.payload.collections[item.collectionSlug]?.config
|
|
76
|
-
if (!collection) {
|
|
77
|
-
throw new APIError(
|
|
78
|
-
`Collection schema not found for slug: ${item.collectionSlug}`,
|
|
79
|
-
500,
|
|
80
|
-
)
|
|
81
|
-
}
|
|
82
|
-
const collectionSchema = removeVirtualFieldsFromSchema(
|
|
83
|
-
entityToStandaloneJSONSchema({
|
|
84
|
-
config: req.payload.config,
|
|
85
|
-
defaultIDType: req.payload.db.defaultIDType,
|
|
86
|
-
entity: collection,
|
|
87
|
-
i18n: req.i18n,
|
|
88
|
-
}) as unknown as JsonSchemaType,
|
|
89
|
-
getCollectionVirtualFieldNames(req.payload.config, item.collectionSlug),
|
|
90
|
-
)
|
|
91
|
-
inputSchema = inputSchema({ collectionSchema })
|
|
92
|
-
}
|
|
93
|
-
server.registerTool(
|
|
94
|
-
name,
|
|
95
|
-
{
|
|
96
|
-
description: tool.description,
|
|
97
|
-
inputSchema: inputSchema ? toStandardSchema(inputSchema) : undefined,
|
|
98
|
-
},
|
|
99
|
-
async (input: unknown, ctx: ServerContext) =>
|
|
100
|
-
finalizeToolResponse(
|
|
101
|
-
await tool.handler({
|
|
102
|
-
authorizedMCP,
|
|
103
|
-
collectionSlug: item.collectionSlug,
|
|
104
|
-
input: (input ?? {}) as Record<string, unknown>,
|
|
105
|
-
req,
|
|
106
|
-
serverContext: ctx,
|
|
107
|
-
}),
|
|
108
|
-
tool.overrideResponse,
|
|
109
|
-
),
|
|
110
|
-
)
|
|
111
|
-
logger.info(`✅ Tool: ${name} Registered.`)
|
|
112
|
-
break
|
|
113
|
-
}
|
|
147
|
+
case 'collectionTool':
|
|
114
148
|
case 'globalTool': {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
let inputSchema = tool.input
|
|
118
|
-
if (typeof inputSchema === 'function') {
|
|
119
|
-
const globalEntity = req.payload.config.globals.find(
|
|
120
|
-
(globalConfig) => globalConfig.slug === item.globalSlug,
|
|
121
|
-
)
|
|
122
|
-
if (!globalEntity) {
|
|
123
|
-
throw new APIError(`Global schema not found for slug: ${item.globalSlug}`, 500)
|
|
124
|
-
}
|
|
125
|
-
const globalSchema = removeVirtualFieldsFromSchema(
|
|
126
|
-
entityToStandaloneJSONSchema({
|
|
127
|
-
config: req.payload.config,
|
|
128
|
-
defaultIDType: req.payload.db.defaultIDType,
|
|
129
|
-
entity: globalEntity,
|
|
130
|
-
i18n: req.i18n,
|
|
131
|
-
}) as unknown as JsonSchemaType,
|
|
132
|
-
getGlobalVirtualFieldNames(req.payload.config, item.globalSlug),
|
|
133
|
-
)
|
|
134
|
-
|
|
135
|
-
inputSchema = inputSchema({ globalSchema })
|
|
149
|
+
if (registeredEntityTools.has(item.mcpName)) {
|
|
150
|
+
break
|
|
136
151
|
}
|
|
152
|
+
registeredEntityTools.add(item.mcpName)
|
|
153
|
+
|
|
154
|
+
const inputSchema = withSlugInput({ input: item.tool.input })
|
|
155
|
+
|
|
137
156
|
server.registerTool(
|
|
138
|
-
|
|
157
|
+
item.mcpName,
|
|
139
158
|
{
|
|
140
|
-
|
|
141
|
-
|
|
159
|
+
annotations: item.tool.annotations,
|
|
160
|
+
description: item.tool.description,
|
|
161
|
+
inputSchema: toStandardSchema(inputSchema),
|
|
142
162
|
},
|
|
143
163
|
async (input: unknown, ctx: ServerContext) =>
|
|
144
|
-
|
|
145
|
-
await tool.handler({
|
|
146
|
-
authorizedMCP,
|
|
147
|
-
globalSlug: item.globalSlug,
|
|
148
|
-
input: (input ?? {}) as Record<string, unknown>,
|
|
149
|
-
req,
|
|
150
|
-
serverContext: ctx,
|
|
151
|
-
}),
|
|
152
|
-
tool.overrideResponse,
|
|
153
|
-
),
|
|
164
|
+
callEntityTool({ input, item, serverContext: ctx }),
|
|
154
165
|
)
|
|
155
|
-
logger.info(`✅ Tool: ${
|
|
166
|
+
logger.info(`✅ Tool: ${item.mcpName} Registered.`)
|
|
156
167
|
break
|
|
157
168
|
}
|
|
158
169
|
case 'prompt': {
|
|
159
170
|
const prompt = item.prompt
|
|
160
171
|
server.registerPrompt(
|
|
161
|
-
item.
|
|
172
|
+
item.mcpName,
|
|
162
173
|
{
|
|
163
174
|
argsSchema: prompt.argsSchema ? toStandardSchema(prompt.argsSchema) : undefined,
|
|
164
175
|
description: prompt.description,
|
|
@@ -177,7 +188,7 @@ export const buildMcpServer = ({
|
|
|
177
188
|
case 'resource': {
|
|
178
189
|
const resource = item.resource
|
|
179
190
|
server.registerResource(
|
|
180
|
-
item.
|
|
191
|
+
item.mcpName,
|
|
181
192
|
// @ts-expect-error - Overload type ambiguity (string OR ResourceTemplate is valid)
|
|
182
193
|
resource.uri,
|
|
183
194
|
{
|
|
@@ -200,23 +211,29 @@ export const buildMcpServer = ({
|
|
|
200
211
|
case 'tool': {
|
|
201
212
|
const tool = item.tool
|
|
202
213
|
server.registerTool(
|
|
203
|
-
item.
|
|
214
|
+
item.mcpName,
|
|
204
215
|
{
|
|
216
|
+
annotations: tool.annotations,
|
|
205
217
|
description: tool.description,
|
|
206
218
|
inputSchema: tool.input ? toStandardSchema(tool.input) : undefined,
|
|
207
219
|
},
|
|
208
|
-
async (input: unknown, ctx: ServerContext) =>
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
220
|
+
async (input: unknown, ctx: ServerContext) => {
|
|
221
|
+
const toolInput = (input ?? {}) as Record<string, unknown>
|
|
222
|
+
const response = await tool.handler({
|
|
223
|
+
authorizedMCP,
|
|
224
|
+
input: toolInput,
|
|
225
|
+
req,
|
|
226
|
+
serverContext: ctx,
|
|
227
|
+
})
|
|
228
|
+
return finalizeToolResponse({
|
|
229
|
+
input: toolInput,
|
|
230
|
+
overrideResponse: tool.overrideResponse,
|
|
231
|
+
response,
|
|
232
|
+
toolName: item.mcpName,
|
|
233
|
+
})
|
|
234
|
+
},
|
|
218
235
|
)
|
|
219
|
-
logger.info(`✅ Tool: ${item.
|
|
236
|
+
logger.info(`✅ Tool: ${item.mcpName} Registered.`)
|
|
220
237
|
break
|
|
221
238
|
}
|
|
222
239
|
}
|
|
@@ -227,3 +244,51 @@ export const buildMcpServer = ({
|
|
|
227
244
|
|
|
228
245
|
return server
|
|
229
246
|
}
|
|
247
|
+
|
|
248
|
+
const withSlugInput = ({ input }: { input?: ToolInputSchema }): ToolInputSchema => {
|
|
249
|
+
const description = 'The target slug.'
|
|
250
|
+
const slugSchema = z.string().check(z.describe(description))
|
|
251
|
+
|
|
252
|
+
if (!input) {
|
|
253
|
+
return strictObject({ slug: slugSchema }) as unknown as ToolInputSchema
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
if (typeof input === 'object' && input !== null && '~standard' in input) {
|
|
257
|
+
const schema = input['~standard'].jsonSchema.input({ target: 'draft-2020-12' })
|
|
258
|
+
const properties = schema.properties as Record<string, unknown> | undefined
|
|
259
|
+
|
|
260
|
+
if (properties?.slug) {
|
|
261
|
+
return input
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
return addSlugToJSONSchema({ description, schema: schema as JsonSchemaType })
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
return addSlugToJSONSchema({ description, schema: input })
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
const addSlugToJSONSchema = ({
|
|
271
|
+
description,
|
|
272
|
+
schema,
|
|
273
|
+
}: {
|
|
274
|
+
description: string
|
|
275
|
+
schema: JsonSchemaType
|
|
276
|
+
}): JsonSchemaType => {
|
|
277
|
+
const objectSchema = schema as {
|
|
278
|
+
properties?: Record<string, JsonSchemaType>
|
|
279
|
+
required?: string[]
|
|
280
|
+
} & JsonSchemaType
|
|
281
|
+
|
|
282
|
+
return {
|
|
283
|
+
...objectSchema,
|
|
284
|
+
type: 'object',
|
|
285
|
+
properties: {
|
|
286
|
+
...objectSchema.properties,
|
|
287
|
+
slug: {
|
|
288
|
+
type: 'string',
|
|
289
|
+
description,
|
|
290
|
+
},
|
|
291
|
+
},
|
|
292
|
+
required: Array.from(new Set(['slug', ...(objectSchema.required ?? [])])),
|
|
293
|
+
}
|
|
294
|
+
}
|