@payloadcms/plugin-mcp 4.0.0-internal.c2b57ce → 4.0.0-internal.c6494b5
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 +75 -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 +98 -18
- package/dist/endpoint/index.js.map +1 -1
- 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 +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -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 -74
- 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 -64
- 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 -133
- 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 -58
- 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 +124 -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 +123 -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 +14 -21
- package/src/defaultAccess.ts +3 -0
- package/src/endpoint/access.ts +80 -101
- package/src/endpoint/index.ts +88 -16
- package/src/exports/client.ts +2 -1
- package/src/exports/internal.ts +1 -0
- package/src/index.ts +12 -20
- package/src/mcp/buildMcpServer.ts +180 -110
- 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 -138
- 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 -77
- package/src/mcp/builtinTools.ts +118 -41
- package/src/mcp/sanitizeMCPConfig.ts +120 -78
- package/src/stdio.ts +80 -47
- package/src/types.ts +141 -120
- package/src/utils/getPluginConfig.ts +1 -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 -59
- 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/prepareCollectionSchema.d.ts +0 -7
- package/dist/utils/schemaConversion/prepareCollectionSchema.d.ts.map +0 -1
- package/dist/utils/schemaConversion/prepareCollectionSchema.js +0 -37
- package/dist/utils/schemaConversion/prepareCollectionSchema.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/sanitizeJsonSchema.d.ts +0 -13
- package/dist/utils/schemaConversion/sanitizeJsonSchema.d.ts.map +0 -1
- package/dist/utils/schemaConversion/sanitizeJsonSchema.js +0 -56
- package/dist/utils/schemaConversion/sanitizeJsonSchema.js.map +0 -1
- package/dist/utils/schemaConversion/simplifyRelationshipFields.d.ts +0 -20
- package/dist/utils/schemaConversion/simplifyRelationshipFields.d.ts.map +0 -1
- package/dist/utils/schemaConversion/simplifyRelationshipFields.js +0 -56
- package/dist/utils/schemaConversion/simplifyRelationshipFields.js.map +0 -1
- package/dist/utils/schemaConversion/transformPointFields.d.ts +0 -3
- package/dist/utils/schemaConversion/transformPointFields.d.ts.map +0 -1
- package/dist/utils/schemaConversion/transformPointFields.js +0 -57
- package/dist/utils/schemaConversion/transformPointFields.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/collection/getAccessField.ts +0 -64
- package/src/collection/index.ts +0 -63
- 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/prepareCollectionSchema.ts +0 -39
- package/src/utils/schemaConversion/removeVirtualFieldsFromSchema.ts +0 -27
- package/src/utils/schemaConversion/sanitizeJsonSchema.ts +0 -62
- package/src/utils/schemaConversion/simplifyRelationshipFields.ts +0 -70
- package/src/utils/schemaConversion/transformPointFields.ts +0 -56
- 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,105 +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
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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
|
+
}
|
|
73
141
|
|
|
74
142
|
try {
|
|
143
|
+
const registeredEntityTools = new Set<string>()
|
|
144
|
+
|
|
75
145
|
for (const item of authorizedMCP.items) {
|
|
76
146
|
switch (item.type) {
|
|
77
|
-
case 'collectionTool':
|
|
78
|
-
const tool = item.tool
|
|
79
|
-
const name = wireName(item.key, item.collectionSlug)
|
|
80
|
-
let inputSchema = tool.input
|
|
81
|
-
if (typeof inputSchema === 'function') {
|
|
82
|
-
const raw = configSchema.definitions?.[item.collectionSlug]
|
|
83
|
-
if (!raw) {
|
|
84
|
-
throw new APIError(
|
|
85
|
-
`Collection schema not found for slug: ${item.collectionSlug}`,
|
|
86
|
-
500,
|
|
87
|
-
)
|
|
88
|
-
}
|
|
89
|
-
const collectionSchema = removeVirtualFieldsFromSchema(
|
|
90
|
-
JSON.parse(JSON.stringify(raw)) as JsonSchemaType,
|
|
91
|
-
getCollectionVirtualFieldNames(req.payload.config, item.collectionSlug),
|
|
92
|
-
)
|
|
93
|
-
inputSchema = inputSchema({ collectionSchema })
|
|
94
|
-
}
|
|
95
|
-
server.registerTool(
|
|
96
|
-
name,
|
|
97
|
-
{
|
|
98
|
-
description: tool.description,
|
|
99
|
-
inputSchema: inputSchema ? toStandardSchema(inputSchema) : undefined,
|
|
100
|
-
},
|
|
101
|
-
async (input: unknown, ctx: ServerContext) =>
|
|
102
|
-
finalizeToolResponse(
|
|
103
|
-
await tool.handler({
|
|
104
|
-
authorizedMCP,
|
|
105
|
-
collectionSlug: item.collectionSlug,
|
|
106
|
-
input: (input ?? {}) as Record<string, unknown>,
|
|
107
|
-
req,
|
|
108
|
-
serverContext: ctx,
|
|
109
|
-
}),
|
|
110
|
-
tool.overrideResponse,
|
|
111
|
-
),
|
|
112
|
-
)
|
|
113
|
-
logger.info(`✅ Tool: ${name} Registered.`)
|
|
114
|
-
break
|
|
115
|
-
}
|
|
147
|
+
case 'collectionTool':
|
|
116
148
|
case 'globalTool': {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
let inputSchema = tool.input
|
|
120
|
-
if (typeof inputSchema === 'function') {
|
|
121
|
-
const raw = configSchema.definitions?.[item.globalSlug]
|
|
122
|
-
if (!raw) {
|
|
123
|
-
throw new APIError(`Global schema not found for slug: ${item.globalSlug}`, 500)
|
|
124
|
-
}
|
|
125
|
-
const globalSchema = removeVirtualFieldsFromSchema(
|
|
126
|
-
JSON.parse(JSON.stringify(raw)) as JsonSchemaType,
|
|
127
|
-
getGlobalVirtualFieldNames(req.payload.config, item.globalSlug),
|
|
128
|
-
)
|
|
129
|
-
|
|
130
|
-
inputSchema = inputSchema({ globalSchema })
|
|
149
|
+
if (registeredEntityTools.has(item.mcpName)) {
|
|
150
|
+
break
|
|
131
151
|
}
|
|
152
|
+
registeredEntityTools.add(item.mcpName)
|
|
153
|
+
|
|
154
|
+
const inputSchema = withSlugInput({ input: item.tool.input })
|
|
155
|
+
|
|
132
156
|
server.registerTool(
|
|
133
|
-
|
|
157
|
+
item.mcpName,
|
|
134
158
|
{
|
|
135
|
-
|
|
136
|
-
|
|
159
|
+
annotations: item.tool.annotations,
|
|
160
|
+
description: item.tool.description,
|
|
161
|
+
inputSchema: toStandardSchema(inputSchema),
|
|
137
162
|
},
|
|
138
163
|
async (input: unknown, ctx: ServerContext) =>
|
|
139
|
-
|
|
140
|
-
await tool.handler({
|
|
141
|
-
authorizedMCP,
|
|
142
|
-
globalSlug: item.globalSlug,
|
|
143
|
-
input: (input ?? {}) as Record<string, unknown>,
|
|
144
|
-
req,
|
|
145
|
-
serverContext: ctx,
|
|
146
|
-
}),
|
|
147
|
-
tool.overrideResponse,
|
|
148
|
-
),
|
|
164
|
+
callEntityTool({ input, item, serverContext: ctx }),
|
|
149
165
|
)
|
|
150
|
-
logger.info(`✅ Tool: ${
|
|
166
|
+
logger.info(`✅ Tool: ${item.mcpName} Registered.`)
|
|
151
167
|
break
|
|
152
168
|
}
|
|
153
169
|
case 'prompt': {
|
|
154
170
|
const prompt = item.prompt
|
|
155
171
|
server.registerPrompt(
|
|
156
|
-
item.
|
|
172
|
+
item.mcpName,
|
|
157
173
|
{
|
|
158
174
|
argsSchema: prompt.argsSchema ? toStandardSchema(prompt.argsSchema) : undefined,
|
|
159
175
|
description: prompt.description,
|
|
@@ -172,7 +188,7 @@ export const buildMcpServer = ({
|
|
|
172
188
|
case 'resource': {
|
|
173
189
|
const resource = item.resource
|
|
174
190
|
server.registerResource(
|
|
175
|
-
item.
|
|
191
|
+
item.mcpName,
|
|
176
192
|
// @ts-expect-error - Overload type ambiguity (string OR ResourceTemplate is valid)
|
|
177
193
|
resource.uri,
|
|
178
194
|
{
|
|
@@ -195,23 +211,29 @@ export const buildMcpServer = ({
|
|
|
195
211
|
case 'tool': {
|
|
196
212
|
const tool = item.tool
|
|
197
213
|
server.registerTool(
|
|
198
|
-
item.
|
|
214
|
+
item.mcpName,
|
|
199
215
|
{
|
|
216
|
+
annotations: tool.annotations,
|
|
200
217
|
description: tool.description,
|
|
201
218
|
inputSchema: tool.input ? toStandardSchema(tool.input) : undefined,
|
|
202
219
|
},
|
|
203
|
-
async (input: unknown, ctx: ServerContext) =>
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
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
|
+
},
|
|
213
235
|
)
|
|
214
|
-
logger.info(`✅ Tool: ${item.
|
|
236
|
+
logger.info(`✅ Tool: ${item.mcpName} Registered.`)
|
|
215
237
|
break
|
|
216
238
|
}
|
|
217
239
|
}
|
|
@@ -222,3 +244,51 @@ export const buildMcpServer = ({
|
|
|
222
244
|
|
|
223
245
|
return server
|
|
224
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
|
+
}
|