@payloadcms/plugin-mcp 3.70.0 → 3.71.0-internal-debug.80dab4c

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.
Files changed (52) hide show
  1. package/dist/collections/createApiKeysCollection.d.ts +1 -1
  2. package/dist/collections/createApiKeysCollection.d.ts.map +1 -1
  3. package/dist/collections/createApiKeysCollection.js +10 -75
  4. package/dist/collections/createApiKeysCollection.js.map +1 -1
  5. package/dist/endpoints/mcp.d.ts.map +1 -1
  6. package/dist/endpoints/mcp.js +1 -0
  7. package/dist/endpoints/mcp.js.map +1 -1
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +4 -1
  10. package/dist/index.js.map +1 -1
  11. package/dist/mcp/getMcpHandler.d.ts.map +1 -1
  12. package/dist/mcp/getMcpHandler.js +24 -10
  13. package/dist/mcp/getMcpHandler.js.map +1 -1
  14. package/dist/mcp/tools/global/find.d.ts +5 -0
  15. package/dist/mcp/tools/global/find.d.ts.map +1 -0
  16. package/dist/mcp/tools/global/find.js +59 -0
  17. package/dist/mcp/tools/global/find.js.map +1 -0
  18. package/dist/mcp/tools/global/update.d.ts +6 -0
  19. package/dist/mcp/tools/global/update.d.ts.map +1 -0
  20. package/dist/mcp/tools/global/update.js +97 -0
  21. package/dist/mcp/tools/global/update.js.map +1 -0
  22. package/dist/mcp/tools/schemas.d.ts +55 -17
  23. package/dist/mcp/tools/schemas.d.ts.map +1 -1
  24. package/dist/mcp/tools/schemas.js +18 -0
  25. package/dist/mcp/tools/schemas.js.map +1 -1
  26. package/dist/types.d.ts +40 -1
  27. package/dist/types.d.ts.map +1 -1
  28. package/dist/types.js.map +1 -1
  29. package/dist/utils/adminEntitySettings.d.ts +17 -0
  30. package/dist/utils/adminEntitySettings.d.ts.map +1 -0
  31. package/dist/utils/adminEntitySettings.js +41 -0
  32. package/dist/utils/adminEntitySettings.js.map +1 -0
  33. package/dist/utils/createApiKeyFields.d.ts +15 -0
  34. package/dist/utils/createApiKeyFields.d.ts.map +1 -0
  35. package/dist/utils/createApiKeyFields.js +57 -0
  36. package/dist/utils/createApiKeyFields.js.map +1 -0
  37. package/dist/utils/getEnabledSlugs.d.ts +13 -0
  38. package/dist/utils/getEnabledSlugs.d.ts.map +1 -0
  39. package/dist/utils/getEnabledSlugs.js +32 -0
  40. package/dist/utils/getEnabledSlugs.js.map +1 -0
  41. package/package.json +3 -3
  42. package/src/collections/createApiKeysCollection.ts +11 -111
  43. package/src/endpoints/mcp.ts +1 -0
  44. package/src/index.ts +4 -0
  45. package/src/mcp/getMcpHandler.ts +62 -26
  46. package/src/mcp/tools/global/find.ts +104 -0
  47. package/src/mcp/tools/global/update.ts +168 -0
  48. package/src/mcp/tools/schemas.ts +50 -0
  49. package/src/types.ts +59 -1
  50. package/src/utils/adminEntitySettings.ts +40 -0
  51. package/src/utils/createApiKeyFields.ts +72 -0
  52. package/src/utils/getEnabledSlugs.ts +42 -0
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type { CollectionConfig, CollectionSlug, PayloadRequest, TypedUser } from 'payload'\nimport type { z } from 'zod'\n\nimport { type ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js'\n\nexport type PluginMCPServerConfig = {\n /**\n * Set the collections that should be available as resources via MCP.\n */\n collections?: Partial<\n Record<\n CollectionSlug,\n {\n /**\n * Set the description of the collection. This is used by MCP clients to determine when to use the collecton as a resource.\n */\n description?: string\n /**\n * Set the enabled capabilities of the collection. Admins can then allow or disallow the use of the capability by MCP clients.\n */\n enabled:\n | {\n create?: boolean\n delete?: boolean\n find?: boolean\n update?: boolean\n }\n | boolean\n\n /**\n * Override the response generated by the MCP client. This allows you to modify the response that is sent to the MCP client. This is useful for adding additional data to the response, data normalization, or verifying data.\n */\n overrideResponse?: (\n response: {\n content: Array<{\n text: string\n type: string\n }>\n },\n doc: Record<string, unknown>,\n req: PayloadRequest,\n ) => {\n content: Array<{\n text: string\n type: string\n }>\n }\n }\n >\n >\n /**\n * Disable the MCP plugin.\n */\n disabled?: boolean\n /**\n * Experimental features\n * **These features are for experimental purposes -- They are Disabled in Production by Default**\n */\n experimental?: {\n /**\n * These are MCP tools that can be used by a client to modify Payload.\n */\n tools: {\n /**\n * **Experimental** -- Auth MCP tools allow a client to change authentication priviliages for users. This is for developing ideas that help Admins with authentication tasks.\n */\n auth?: {\n /**\n * Enable the auth MCP tools. This allows Admins to enable or disable the auth capabilities.\n * @default false\n */\n enabled: boolean\n }\n /**\n * **Experimental** -- Collection MCP tools allow for the creation, modification, and deletion of Payload collections. This is for developing ideas that help Developers with collection tasks.\n */\n collections?: {\n /**\n * Set the directory path to the collections directory. This can be a directory outside of your default directory, or another Payload project.\n */\n collectionsDirPath: string\n /**\n * Enable the collection MCP tools. This allows Admins to enable or disable the Collection modification capabilities.\n * @default false\n */\n enabled: boolean\n }\n /**\n * **Experimental** -- Config MCP tools allow for the modification of a Payload Config. This is for developing ideas that help Developers with config tasks.\n */\n config?: {\n /**\n * Set the directory path to the config directory. This can be a directory outside of your default directory, or another Payload project.\n */\n configFilePath: string\n /**\n * Enable the config MCP tools. This allows Admins to enable or disable the Payload Config modification capabilities.\n * @default false\n */\n enabled: boolean\n }\n /**\n * **Experimental** -- Jobs MCP tools allow for the modification of Payload jobs. This is for developing ideas that help Developers with job tasks.\n */\n jobs?: {\n /**\n * Enable the jobs MCP tools. This allows Admins to enable or disable the Job modification capabilities.\n * @default false\n */\n enabled: boolean\n /**\n * Set the directory path to the jobs directory. This can be a directory outside of your default directory, or another Payload project.\n */\n jobsDirPath: string\n }\n }\n }\n /**\n * MCP Server options.\n */\n mcp?: {\n handlerOptions?: MCPHandlerOptions\n /**\n * Add custom MCP Prompts.\n */\n prompts?: {\n /**\n * Set the args schema of the prompt. This is the args schema that will be passed to the prompt. This is used by MCP clients to determine the arguments that will be passed to the prompt.\n */\n argsSchema: z.ZodRawShape\n /**\n * Set the description of the prompt. This is used by MCP clients to determine when to use the prompt.\n */\n description: string\n /**\n * Set the handler of the prompt. This is the function that will be called when the prompt is used.\n */\n handler: (\n args: Record<string, unknown>,\n req: PayloadRequest,\n _extra: unknown,\n ) =>\n | {\n messages: Array<{\n content: {\n text: string\n type: 'text'\n }\n role: 'assistant' | 'user'\n }>\n }\n | Promise<{\n messages: Array<{\n content: {\n text: string\n type: 'text'\n }\n role: 'assistant' | 'user'\n }>\n }>\n /**\n * Set the function name of the prompt.\n */\n name: string\n /**\n * Set the title of the prompt. LLMs will interperate the title to determine when to use the prompt.\n */\n title: string\n }[]\n\n /**\n * Add custom MCP Resource.\n */\n resources?: {\n /**\n * Set the description of the resource. This is used by MCP clients to determine when to use the resource.\n * example: 'Data is a resource that contains special data.'\n */\n description: string\n /**\n * Set the handler of the resource. This is the function that will be called when the resource is used.\n * The handler can have either 3 arguments (when no args are passed) or 4 arguments (when args are passed).\n */\n handler: (...args: any[]) =>\n | {\n contents: Array<{\n text: string\n uri: string\n }>\n }\n | Promise<{\n contents: Array<{\n text: string\n uri: string\n }>\n }>\n /**\n * Set the mime type of the resource.\n * example: 'text/plain'\n */\n mimeType: string\n /**\n * Set the function name of the resource.\n * example: 'data'\n */\n name: string\n /**\n * Set the title of the resource. LLMs will interperate the title to determine when to use the resource.\n * example: 'Data'\n */\n title: string\n /**\n * Set the uri of the resource.\n * example: 'data://app'\n */\n uri: ResourceTemplate | string\n }[]\n serverOptions?: MCPServerOptions\n /**\n * Add custom MCP Tools.\n */\n tools?: {\n /**\n * Set the description of the tool. This is used by MCP clients to determine when to use the tool.\n */\n description: string\n /**\n * Set the handler of the tool. This is the function that will be called when the tool is used.\n */\n handler: (\n args: Record<string, unknown>,\n req: PayloadRequest,\n _extra: unknown,\n ) =>\n | {\n content: Array<{\n text: string\n type: 'text'\n }>\n role?: string\n }\n | Promise<{\n content: Array<{\n text: string\n type: 'text'\n }>\n role?: string\n }>\n /**\n * Set the name of the tool. This is the name that will be used to identify the tool. LLMs will interperate the name to determine when to use the tool.\n */\n name: string\n /**\n * Set the parameters of the tool. This is the parameters that will be passed to the tool.\n */\n parameters: z.ZodRawShape\n }[]\n }\n\n /**\n * Override the API key collection.\n * This allows you to add fields to the API key collection or modify the collection in any way you want.\n * @param collection - The API key collection.\n * @returns The modified API key collection.\n */\n overrideApiKeyCollection?: (collection: CollectionConfig) => CollectionConfig\n\n /**\n * Override the authentication method.\n * This allows you to use a custom authentication method instead of the default API key authentication.\n * @param req - The request object.\n * @returns The MCP access settings.\n */\n overrideAuth?: (\n req: PayloadRequest,\n getDefaultMcpAccessSettings: (overrideApiKey?: null | string) => Promise<MCPAccessSettings>,\n ) => MCPAccessSettings | Promise<MCPAccessSettings>\n\n /**\n * Set the users collection that API keys should be associated with.\n */\n userCollection?: CollectionConfig | string\n}\n\n/**\n * MCP Handler options.\n */\nexport type MCPHandlerOptions = {\n /**\n * Set the base path of the MCP handler. This is the path that will be used to access the MCP handler.\n * @default /api\n */\n basePath?: string\n /**\n * Set the maximum duration of the MCP handler. This is the maximum duration that the MCP handler will run for.\n * @default 60\n */\n maxDuration?: number\n /**\n * Set the Redis URL for the MCP handler. This is the URL that will be used to access the Redis server.\n * @default process.env.REDIS_URL\n * INFO: Disabled until developer clarity is reached for server side streaming and we have an auth pattern for all SSE patterns\n */\n // redisUrl?: string\n /**\n * Set verbose logging.\n * @default false\n */\n verboseLogs?: boolean\n}\n\n/**\n * MCP Server options.\n */\nexport type MCPServerOptions = {\n /**\n * Set the server info of the MCP server.\n */\n serverInfo?: {\n /**\n * Set the name of the MCP server.\n * @default 'Payload MCP Server'\n */\n name: string\n /**\n * Set the version of the MCP server.\n * @default '1.0.0'\n */\n version: string\n }\n}\n\nexport type MCPAccessSettings = {\n auth?: {\n auth?: boolean\n forgotPassword?: boolean\n login?: boolean\n resetPassword?: boolean\n unlock?: boolean\n verify?: boolean\n }\n collections?: {\n create?: boolean\n delete?: boolean\n find?: boolean\n update?: boolean\n }\n config?: {\n find?: boolean\n update?: boolean\n }\n jobs?: {\n create?: boolean\n run?: boolean\n update?: boolean\n }\n 'payload-mcp-prompt'?: Record<string, boolean>\n 'payload-mcp-resource'?: Record<string, boolean>\n 'payload-mcp-tool'?: Record<string, boolean>\n user: TypedUser\n} & Record<string, unknown>\n\nexport type FieldDefinition = {\n description?: string\n name: string\n options?: { label: string; value: string }[]\n position?: 'main' | 'sidebar'\n required?: boolean\n type: string\n}\n\nexport type FieldModification = {\n changes: {\n description?: string\n options?: { label: string; value: string }[]\n position?: 'main' | 'sidebar'\n required?: boolean\n type?: string\n }\n fieldName: string\n}\n\nexport type CollectionConfigUpdates = {\n access?: {\n create?: string\n delete?: string\n read?: string\n update?: string\n }\n description?: string\n slug?: string\n timestamps?: boolean\n versioning?: boolean\n}\n\nexport type AdminConfig = {\n avatar?: string\n css?: string\n dateFormat?: string\n inactivityRoute?: string\n livePreview?: {\n breakpoints?: Array<{\n height: number\n label: string\n name: string\n width: number\n }>\n }\n logoutRoute?: string\n meta?: {\n favicon?: string\n ogImage?: string\n titleSuffix?: string\n }\n user?: string\n}\n\nexport type DatabaseConfig = {\n connectOptions?: string\n type?: 'mongodb' | 'postgres'\n url?: string\n}\n\nexport type PluginUpdates = {\n add?: string[]\n remove?: string[]\n}\n\nexport type GeneralConfig = {\n cookiePrefix?: string\n cors?: string\n csrf?: string\n graphQL?: {\n disable?: boolean\n schemaOutputFile?: string\n }\n rateLimit?: {\n max?: number\n skip?: string\n window?: number\n }\n secret?: string\n serverURL?: string\n typescript?: {\n declare?: boolean\n outputFile?: string\n }\n}\n\nexport interface SchemaField {\n description?: string\n name: string\n options?: string[]\n required?: boolean\n type: string\n}\n\nexport interface TaskSequenceItem {\n description?: string\n retries?: number\n taskId: string\n taskSlug: string\n timeout?: number\n}\n\nexport interface JobConfigUpdate {\n description?: string\n queue?: string\n retries?: number\n timeout?: number\n}\n"],"names":[],"mappings":"AAidA,WAKC"}
1
+ {"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type {\n CollectionConfig,\n CollectionSlug,\n GlobalSlug,\n PayloadRequest,\n TypedUser,\n} from 'payload'\nimport type { z } from 'zod'\n\nimport { type ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js'\n\nexport type PluginMCPServerConfig = {\n /**\n * Set the collections that should be available as resources via MCP.\n */\n collections?: Partial<\n Record<\n CollectionSlug,\n {\n /**\n * Set the description of the collection. This is used by MCP clients to determine when to use the collecton as a resource.\n */\n description?: string\n /**\n * Set the enabled capabilities of the collection. Admins can then allow or disallow the use of the capability by MCP clients.\n */\n enabled:\n | {\n create?: boolean\n delete?: boolean\n find?: boolean\n update?: boolean\n }\n | boolean\n\n /**\n * Override the response generated by the MCP client. This allows you to modify the response that is sent to the MCP client. This is useful for adding additional data to the response, data normalization, or verifying data.\n */\n overrideResponse?: (\n response: {\n content: Array<{\n text: string\n type: string\n }>\n },\n doc: Record<string, unknown>,\n req: PayloadRequest,\n ) => {\n content: Array<{\n text: string\n type: string\n }>\n }\n }\n >\n >\n /**\n * Disable the MCP plugin.\n */\n disabled?: boolean\n /**\n * Experimental features\n * **These features are for experimental purposes -- They are Disabled in Production by Default**\n */\n experimental?: {\n /**\n * These are MCP tools that can be used by a client to modify Payload.\n */\n tools: {\n /**\n * **Experimental** -- Auth MCP tools allow a client to change authentication priviliages for users. This is for developing ideas that help Admins with authentication tasks.\n */\n auth?: {\n /**\n * Enable the auth MCP tools. This allows Admins to enable or disable the auth capabilities.\n * @default false\n */\n enabled: boolean\n }\n /**\n * **Experimental** -- Collection MCP tools allow for the creation, modification, and deletion of Payload collections. This is for developing ideas that help Developers with collection tasks.\n */\n collections?: {\n /**\n * Set the directory path to the collections directory. This can be a directory outside of your default directory, or another Payload project.\n */\n collectionsDirPath: string\n /**\n * Enable the collection MCP tools. This allows Admins to enable or disable the Collection modification capabilities.\n * @default false\n */\n enabled: boolean\n }\n /**\n * **Experimental** -- Config MCP tools allow for the modification of a Payload Config. This is for developing ideas that help Developers with config tasks.\n */\n config?: {\n /**\n * Set the directory path to the config directory. This can be a directory outside of your default directory, or another Payload project.\n */\n configFilePath: string\n /**\n * Enable the config MCP tools. This allows Admins to enable or disable the Payload Config modification capabilities.\n * @default false\n */\n enabled: boolean\n }\n /**\n * **Experimental** -- Jobs MCP tools allow for the modification of Payload jobs. This is for developing ideas that help Developers with job tasks.\n */\n jobs?: {\n /**\n * Enable the jobs MCP tools. This allows Admins to enable or disable the Job modification capabilities.\n * @default false\n */\n enabled: boolean\n /**\n * Set the directory path to the jobs directory. This can be a directory outside of your default directory, or another Payload project.\n */\n jobsDirPath: string\n }\n }\n }\n /**\n * Set the globals that should be available as resources via MCP.\n * Globals are singleton configuration objects (e.g., site settings, navigation).\n * Note: Globals only support find and update operations.\n */\n globals?: Partial<\n Record<\n GlobalSlug,\n {\n /**\n * Set the description of the global. This is used by MCP clients to determine when to use the global as a resource.\n */\n description?: string\n /**\n * Set the enabled capabilities of the global. Admins can then allow or disallow the use of the capability by MCP clients.\n * Note: Globals only support find and update operations as they are singletons.\n */\n enabled:\n | {\n find?: boolean\n update?: boolean\n }\n | boolean\n\n /**\n * Override the response generated by the MCP client. This allows you to modify the response that is sent to the MCP client. This is useful for adding additional data to the response, data normalization, or verifying data.\n */\n overrideResponse?: (\n response: {\n content: Array<{\n text: string\n type: string\n }>\n },\n doc: Record<string, unknown>,\n req: PayloadRequest,\n ) => {\n content: Array<{\n text: string\n type: string\n }>\n }\n }\n >\n >\n /**\n * MCP Server options.\n */\n mcp?: {\n handlerOptions?: MCPHandlerOptions\n /**\n * Add custom MCP Prompts.\n */\n prompts?: {\n /**\n * Set the args schema of the prompt. This is the args schema that will be passed to the prompt. This is used by MCP clients to determine the arguments that will be passed to the prompt.\n */\n argsSchema: z.ZodRawShape\n /**\n * Set the description of the prompt. This is used by MCP clients to determine when to use the prompt.\n */\n description: string\n /**\n * Set the handler of the prompt. This is the function that will be called when the prompt is used.\n */\n handler: (\n args: Record<string, unknown>,\n req: PayloadRequest,\n _extra: unknown,\n ) =>\n | {\n messages: Array<{\n content: {\n text: string\n type: 'text'\n }\n role: 'assistant' | 'user'\n }>\n }\n | Promise<{\n messages: Array<{\n content: {\n text: string\n type: 'text'\n }\n role: 'assistant' | 'user'\n }>\n }>\n /**\n * Set the function name of the prompt.\n */\n name: string\n /**\n * Set the title of the prompt. LLMs will interperate the title to determine when to use the prompt.\n */\n title: string\n }[]\n\n /**\n * Add custom MCP Resource.\n */\n resources?: {\n /**\n * Set the description of the resource. This is used by MCP clients to determine when to use the resource.\n * example: 'Data is a resource that contains special data.'\n */\n description: string\n /**\n * Set the handler of the resource. This is the function that will be called when the resource is used.\n * The handler can have either 3 arguments (when no args are passed) or 4 arguments (when args are passed).\n */\n handler: (...args: any[]) =>\n | {\n contents: Array<{\n text: string\n uri: string\n }>\n }\n | Promise<{\n contents: Array<{\n text: string\n uri: string\n }>\n }>\n /**\n * Set the mime type of the resource.\n * example: 'text/plain'\n */\n mimeType: string\n /**\n * Set the function name of the resource.\n * example: 'data'\n */\n name: string\n /**\n * Set the title of the resource. LLMs will interperate the title to determine when to use the resource.\n * example: 'Data'\n */\n title: string\n /**\n * Set the uri of the resource.\n * example: 'data://app'\n */\n uri: ResourceTemplate | string\n }[]\n serverOptions?: MCPServerOptions\n /**\n * Add custom MCP Tools.\n */\n tools?: {\n /**\n * Set the description of the tool. This is used by MCP clients to determine when to use the tool.\n */\n description: string\n /**\n * Set the handler of the tool. This is the function that will be called when the tool is used.\n */\n handler: (\n args: Record<string, unknown>,\n req: PayloadRequest,\n _extra: unknown,\n ) =>\n | {\n content: Array<{\n text: string\n type: 'text'\n }>\n role?: string\n }\n | Promise<{\n content: Array<{\n text: string\n type: 'text'\n }>\n role?: string\n }>\n /**\n * Set the name of the tool. This is the name that will be used to identify the tool. LLMs will interperate the name to determine when to use the tool.\n */\n name: string\n /**\n * Set the parameters of the tool. This is the parameters that will be passed to the tool.\n */\n parameters: z.ZodRawShape\n }[]\n }\n\n /**\n * Override the API key collection.\n * This allows you to add fields to the API key collection or modify the collection in any way you want.\n * @param collection - The API key collection.\n * @returns The modified API key collection.\n */\n overrideApiKeyCollection?: (collection: CollectionConfig) => CollectionConfig\n\n /**\n * Override the authentication method.\n * This allows you to use a custom authentication method instead of the default API key authentication.\n * @param req - The request object.\n * @returns The MCP access settings.\n */\n overrideAuth?: (\n req: PayloadRequest,\n getDefaultMcpAccessSettings: (overrideApiKey?: null | string) => Promise<MCPAccessSettings>,\n ) => MCPAccessSettings | Promise<MCPAccessSettings>\n\n /**\n * Set the users collection that API keys should be associated with.\n */\n userCollection?: CollectionConfig | string\n}\n\n/**\n * MCP Handler options.\n */\nexport type MCPHandlerOptions = {\n /**\n * Set the base path of the MCP handler. This is the path that will be used to access the MCP handler.\n * @default /api\n */\n basePath?: string\n /**\n * Set the maximum duration of the MCP handler. This is the maximum duration that the MCP handler will run for.\n * @default 60\n */\n maxDuration?: number\n /**\n * Set the Redis URL for the MCP handler. This is the URL that will be used to access the Redis server.\n * @default process.env.REDIS_URL\n * INFO: Disabled until developer clarity is reached for server side streaming and we have an auth pattern for all SSE patterns\n */\n // redisUrl?: string\n /**\n * Set verbose logging.\n * @default false\n */\n verboseLogs?: boolean\n}\n\n/**\n * MCP Server options.\n */\nexport type MCPServerOptions = {\n /**\n * Set the server info of the MCP server.\n */\n serverInfo?: {\n /**\n * Set the name of the MCP server.\n * @default 'Payload MCP Server'\n */\n name: string\n /**\n * Set the version of the MCP server.\n * @default '1.0.0'\n */\n version: string\n }\n}\n\nexport type MCPAccessSettings = {\n auth?: {\n auth?: boolean\n forgotPassword?: boolean\n login?: boolean\n resetPassword?: boolean\n unlock?: boolean\n verify?: boolean\n }\n collections?: {\n create?: boolean\n delete?: boolean\n find?: boolean\n update?: boolean\n }\n config?: {\n find?: boolean\n update?: boolean\n }\n custom?: Record<string, boolean>\n globals?: {\n find?: boolean\n update?: boolean\n }\n jobs?: {\n create?: boolean\n run?: boolean\n update?: boolean\n }\n 'payload-mcp-prompt'?: Record<string, boolean>\n 'payload-mcp-resource'?: Record<string, boolean>\n 'payload-mcp-tool'?: Record<string, boolean>\n user: TypedUser\n} & Record<string, unknown>\n\nexport type EntityConfig = PluginMCPServerConfig['collections'] | PluginMCPServerConfig['globals']\n\nexport type FieldDefinition = {\n description?: string\n name: string\n options?: { label: string; value: string }[]\n position?: 'main' | 'sidebar'\n required?: boolean\n type: string\n}\n\nexport type FieldModification = {\n changes: {\n description?: string\n options?: { label: string; value: string }[]\n position?: 'main' | 'sidebar'\n required?: boolean\n type?: string\n }\n fieldName: string\n}\n\nexport type CollectionConfigUpdates = {\n access?: {\n create?: string\n delete?: string\n read?: string\n update?: string\n }\n description?: string\n slug?: string\n timestamps?: boolean\n versioning?: boolean\n}\n\nexport type AdminConfig = {\n avatar?: string\n css?: string\n dateFormat?: string\n inactivityRoute?: string\n livePreview?: {\n breakpoints?: Array<{\n height: number\n label: string\n name: string\n width: number\n }>\n }\n logoutRoute?: string\n meta?: {\n favicon?: string\n ogImage?: string\n titleSuffix?: string\n }\n user?: string\n}\n\nexport type DatabaseConfig = {\n connectOptions?: string\n type?: 'mongodb' | 'postgres'\n url?: string\n}\n\nexport type PluginUpdates = {\n add?: string[]\n remove?: string[]\n}\n\nexport type GeneralConfig = {\n cookiePrefix?: string\n cors?: string\n csrf?: string\n graphQL?: {\n disable?: boolean\n schemaOutputFile?: string\n }\n rateLimit?: {\n max?: number\n skip?: string\n window?: number\n }\n secret?: string\n serverURL?: string\n typescript?: {\n declare?: boolean\n outputFile?: string\n }\n}\n\nexport interface SchemaField {\n description?: string\n name: string\n options?: string[]\n required?: boolean\n type: string\n}\n\nexport interface TaskSequenceItem {\n description?: string\n retries?: number\n taskId: string\n taskSlug: string\n timeout?: number\n}\n\nexport interface JobConfigUpdate {\n description?: string\n queue?: string\n retries?: number\n timeout?: number\n}\n"],"names":[],"mappings":"AA2gBA,WAKC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Defines the default admin entity settings for Collections and Globals.
3
+ * This is used to create the MCP API key permission fields for the API Keys collection.
4
+ */
5
+ export declare const adminEntitySettings: {
6
+ collection: {
7
+ name: string;
8
+ description: (slug: string) => string;
9
+ label: string;
10
+ }[];
11
+ global: {
12
+ name: string;
13
+ description: (slug: string) => string;
14
+ label: string;
15
+ }[];
16
+ };
17
+ //# sourceMappingURL=adminEntitySettings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adminEntitySettings.d.ts","sourceRoot":"","sources":["../../src/utils/adminEntitySettings.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,mBAAmB;;;4BAIN,MAAM;;;;;4BAsBN,MAAM;;;CAS/B,CAAA"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Defines the default admin entity settings for Collections and Globals.
3
+ * This is used to create the MCP API key permission fields for the API Keys collection.
4
+ */ export const adminEntitySettings = {
5
+ collection: [
6
+ {
7
+ name: 'find',
8
+ description: (slug)=>`Allow clients to find ${slug}.`,
9
+ label: 'Find'
10
+ },
11
+ {
12
+ name: 'create',
13
+ description: (slug)=>`Allow clients to create ${slug}.`,
14
+ label: 'Create'
15
+ },
16
+ {
17
+ name: 'update',
18
+ description: (slug)=>`Allow clients to update ${slug}.`,
19
+ label: 'Update'
20
+ },
21
+ {
22
+ name: 'delete',
23
+ description: (slug)=>`Allow clients to delete ${slug}.`,
24
+ label: 'Delete'
25
+ }
26
+ ],
27
+ global: [
28
+ {
29
+ name: 'find',
30
+ description: (slug)=>`Allow clients to find ${slug} global.`,
31
+ label: 'Find'
32
+ },
33
+ {
34
+ name: 'update',
35
+ description: (slug)=>`Allow clients to update ${slug} global.`,
36
+ label: 'Update'
37
+ }
38
+ ]
39
+ };
40
+
41
+ //# sourceMappingURL=adminEntitySettings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/adminEntitySettings.ts"],"sourcesContent":["/**\n * Defines the default admin entity settings for Collections and Globals.\n * This is used to create the MCP API key permission fields for the API Keys collection.\n */\nexport const adminEntitySettings = {\n collection: [\n {\n name: 'find',\n description: (slug: string) => `Allow clients to find ${slug}.`,\n label: 'Find',\n },\n {\n name: 'create',\n description: (slug: string) => `Allow clients to create ${slug}.`,\n label: 'Create',\n },\n {\n name: 'update',\n description: (slug: string) => `Allow clients to update ${slug}.`,\n label: 'Update',\n },\n {\n name: 'delete',\n description: (slug: string) => `Allow clients to delete ${slug}.`,\n label: 'Delete',\n },\n ],\n global: [\n {\n name: 'find',\n description: (slug: string) => `Allow clients to find ${slug} global.`,\n label: 'Find',\n },\n {\n name: 'update',\n description: (slug: string) => `Allow clients to update ${slug} global.`,\n label: 'Update',\n },\n ],\n}\n"],"names":["adminEntitySettings","collection","name","description","slug","label","global"],"mappings":"AAAA;;;CAGC,GACD,OAAO,MAAMA,sBAAsB;IACjCC,YAAY;QACV;YACEC,MAAM;YACNC,aAAa,CAACC,OAAiB,CAAC,sBAAsB,EAAEA,KAAK,CAAC,CAAC;YAC/DC,OAAO;QACT;QACA;YACEH,MAAM;YACNC,aAAa,CAACC,OAAiB,CAAC,wBAAwB,EAAEA,KAAK,CAAC,CAAC;YACjEC,OAAO;QACT;QACA;YACEH,MAAM;YACNC,aAAa,CAACC,OAAiB,CAAC,wBAAwB,EAAEA,KAAK,CAAC,CAAC;YACjEC,OAAO;QACT;QACA;YACEH,MAAM;YACNC,aAAa,CAACC,OAAiB,CAAC,wBAAwB,EAAEA,KAAK,CAAC,CAAC;YACjEC,OAAO;QACT;KACD;IACDC,QAAQ;QACN;YACEJ,MAAM;YACNC,aAAa,CAACC,OAAiB,CAAC,sBAAsB,EAAEA,KAAK,QAAQ,CAAC;YACtEC,OAAO;QACT;QACA;YACEH,MAAM;YACNC,aAAa,CAACC,OAAiB,CAAC,wBAAwB,EAAEA,KAAK,QAAQ,CAAC;YACxEC,OAAO;QACT;KACD;AACH,EAAC"}
@@ -0,0 +1,15 @@
1
+ import type { Field } from 'payload';
2
+ import type { EntityConfig } from '../types.js';
3
+ /**
4
+ * Creates MCP API key permission fields using collections or globals.
5
+ * Generates collapsible field groups with checkboxes for each enabled operation.
6
+ *
7
+ * @param config - The collections or globals configuration object
8
+ * @param configType - The type of configuration ('collection' or 'global')
9
+ * @returns Array of fields for the MCP API Keys collection
10
+ */
11
+ export declare const createApiKeyFields: ({ config, configType, }: {
12
+ config: EntityConfig | undefined;
13
+ configType: "collection" | "global";
14
+ }) => Field[];
15
+ //# sourceMappingURL=createApiKeyFields.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createApiKeyFields.d.ts","sourceRoot":"","sources":["../../src/utils/createApiKeyFields.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAEpC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAK/C;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,4BAG5B;IACD,MAAM,EAAE,YAAY,GAAG,SAAS,CAAA;IAChC,UAAU,EAAE,YAAY,GAAG,QAAQ,CAAA;CACpC,KAAG,KAAK,EAkDR,CAAA"}
@@ -0,0 +1,57 @@
1
+ import { adminEntitySettings } from './adminEntitySettings.js';
2
+ import { toCamelCase } from './camelCase.js';
3
+ import { getEnabledSlugs } from './getEnabledSlugs.js';
4
+ /**
5
+ * Creates MCP API key permission fields using collections or globals.
6
+ * Generates collapsible field groups with checkboxes for each enabled operation.
7
+ *
8
+ * @param config - The collections or globals configuration object
9
+ * @param configType - The type of configuration ('collection' or 'global')
10
+ * @returns Array of fields for the MCP API Keys collection
11
+ */ export const createApiKeyFields = ({ config, configType })=>{
12
+ const operations = adminEntitySettings[configType];
13
+ const enabledSlugs = getEnabledSlugs(config, configType);
14
+ return enabledSlugs.map((slug)=>{
15
+ const entityConfig = config?.[slug];
16
+ const enabledOperations = operations.filter((operation)=>{
17
+ // If fully enabled, all operations are available
18
+ if (entityConfig?.enabled === true) {
19
+ return true;
20
+ }
21
+ // If partially enabled, check if this specific operation is enabled
22
+ const enabled = entityConfig?.enabled;
23
+ if (typeof enabled !== 'boolean' && enabled) {
24
+ const operationEnabled = enabled[operation.name];
25
+ return typeof operationEnabled === 'boolean' && operationEnabled === true;
26
+ }
27
+ return false;
28
+ });
29
+ // Generate checkbox fields for each enabled operation
30
+ const operationFields = enabledOperations.map((operation)=>({
31
+ name: operation.name,
32
+ type: 'checkbox',
33
+ admin: {
34
+ description: operation.description(slug)
35
+ },
36
+ defaultValue: false,
37
+ label: operation.label
38
+ }));
39
+ return {
40
+ type: 'collapsible',
41
+ admin: {
42
+ position: 'sidebar'
43
+ },
44
+ fields: [
45
+ {
46
+ name: toCamelCase(slug),
47
+ type: 'group',
48
+ fields: operationFields,
49
+ label: configType
50
+ }
51
+ ],
52
+ label: `${slug.charAt(0).toUpperCase() + toCamelCase(slug).slice(1)}`
53
+ };
54
+ });
55
+ };
56
+
57
+ //# sourceMappingURL=createApiKeyFields.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/createApiKeyFields.ts"],"sourcesContent":["import type { Field } from 'payload'\n\nimport type { EntityConfig } from '../types.js'\n\nimport { adminEntitySettings } from './adminEntitySettings.js'\nimport { toCamelCase } from './camelCase.js'\nimport { getEnabledSlugs } from './getEnabledSlugs.js'\n/**\n * Creates MCP API key permission fields using collections or globals.\n * Generates collapsible field groups with checkboxes for each enabled operation.\n *\n * @param config - The collections or globals configuration object\n * @param configType - The type of configuration ('collection' or 'global')\n * @returns Array of fields for the MCP API Keys collection\n */\nexport const createApiKeyFields = ({\n config,\n configType,\n}: {\n config: EntityConfig | undefined\n configType: 'collection' | 'global'\n}): Field[] => {\n const operations = adminEntitySettings[configType]\n const enabledSlugs = getEnabledSlugs(config, configType)\n\n return enabledSlugs.map((slug) => {\n const entityConfig = config?.[slug]\n\n const enabledOperations = operations.filter((operation) => {\n // If fully enabled, all operations are available\n if (entityConfig?.enabled === true) {\n return true\n }\n\n // If partially enabled, check if this specific operation is enabled\n const enabled = entityConfig?.enabled\n if (typeof enabled !== 'boolean' && enabled) {\n const operationEnabled = enabled[operation.name as keyof typeof enabled]\n return typeof operationEnabled === 'boolean' && operationEnabled === true\n }\n\n return false\n })\n\n // Generate checkbox fields for each enabled operation\n const operationFields = enabledOperations.map((operation) => ({\n name: operation.name,\n type: 'checkbox' as const,\n admin: {\n description: operation.description(slug),\n },\n defaultValue: false,\n label: operation.label,\n }))\n\n return {\n type: 'collapsible' as const,\n admin: {\n position: 'sidebar' as const,\n },\n fields: [\n {\n name: toCamelCase(slug),\n type: 'group' as const,\n fields: operationFields,\n label: configType,\n },\n ],\n label: `${slug.charAt(0).toUpperCase() + toCamelCase(slug).slice(1)}`,\n }\n })\n}\n"],"names":["adminEntitySettings","toCamelCase","getEnabledSlugs","createApiKeyFields","config","configType","operations","enabledSlugs","map","slug","entityConfig","enabledOperations","filter","operation","enabled","operationEnabled","name","operationFields","type","admin","description","defaultValue","label","position","fields","charAt","toUpperCase","slice"],"mappings":"AAIA,SAASA,mBAAmB,QAAQ,2BAA0B;AAC9D,SAASC,WAAW,QAAQ,iBAAgB;AAC5C,SAASC,eAAe,QAAQ,uBAAsB;AACtD;;;;;;;CAOC,GACD,OAAO,MAAMC,qBAAqB,CAAC,EACjCC,MAAM,EACNC,UAAU,EAIX;IACC,MAAMC,aAAaN,mBAAmB,CAACK,WAAW;IAClD,MAAME,eAAeL,gBAAgBE,QAAQC;IAE7C,OAAOE,aAAaC,GAAG,CAAC,CAACC;QACvB,MAAMC,eAAeN,QAAQ,CAACK,KAAK;QAEnC,MAAME,oBAAoBL,WAAWM,MAAM,CAAC,CAACC;YAC3C,iDAAiD;YACjD,IAAIH,cAAcI,YAAY,MAAM;gBAClC,OAAO;YACT;YAEA,oEAAoE;YACpE,MAAMA,UAAUJ,cAAcI;YAC9B,IAAI,OAAOA,YAAY,aAAaA,SAAS;gBAC3C,MAAMC,mBAAmBD,OAAO,CAACD,UAAUG,IAAI,CAAyB;gBACxE,OAAO,OAAOD,qBAAqB,aAAaA,qBAAqB;YACvE;YAEA,OAAO;QACT;QAEA,sDAAsD;QACtD,MAAME,kBAAkBN,kBAAkBH,GAAG,CAAC,CAACK,YAAe,CAAA;gBAC5DG,MAAMH,UAAUG,IAAI;gBACpBE,MAAM;gBACNC,OAAO;oBACLC,aAAaP,UAAUO,WAAW,CAACX;gBACrC;gBACAY,cAAc;gBACdC,OAAOT,UAAUS,KAAK;YACxB,CAAA;QAEA,OAAO;YACLJ,MAAM;YACNC,OAAO;gBACLI,UAAU;YACZ;YACAC,QAAQ;gBACN;oBACER,MAAMf,YAAYQ;oBAClBS,MAAM;oBACNM,QAAQP;oBACRK,OAAOjB;gBACT;aACD;YACDiB,OAAO,GAAGb,KAAKgB,MAAM,CAAC,GAAGC,WAAW,KAAKzB,YAAYQ,MAAMkB,KAAK,CAAC,IAAI;QACvE;IACF;AACF,EAAC"}
@@ -0,0 +1,13 @@
1
+ import type { EntityConfig } from '../types.js';
2
+ /**
3
+ * Extracts enabled slugs from collections or globals configuration.
4
+ * A slug is considered enabled if:
5
+ * 1. enabled is set to true (fully enabled)
6
+ * 2. enabled is an object with at least one operation set to true
7
+ *
8
+ * @param config - The collections or globals configuration object
9
+ * @param configType - The type of configuration ('collection' or 'global')
10
+ * @returns Array of enabled slugs
11
+ */
12
+ export declare const getEnabledSlugs: (config: EntityConfig | undefined, configType: "collection" | "global") => string[];
13
+ //# sourceMappingURL=getEnabledSlugs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getEnabledSlugs.d.ts","sourceRoot":"","sources":["../../src/utils/getEnabledSlugs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAI/C;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe,WAClB,YAAY,GAAG,SAAS,cACpB,YAAY,GAAG,QAAQ,KAClC,MAAM,EAwBR,CAAA"}
@@ -0,0 +1,32 @@
1
+ import { adminEntitySettings } from './adminEntitySettings.js';
2
+ /**
3
+ * Extracts enabled slugs from collections or globals configuration.
4
+ * A slug is considered enabled if:
5
+ * 1. enabled is set to true (fully enabled)
6
+ * 2. enabled is an object with at least one operation set to true
7
+ *
8
+ * @param config - The collections or globals configuration object
9
+ * @param configType - The type of configuration ('collection' or 'global')
10
+ * @returns Array of enabled slugs
11
+ */ export const getEnabledSlugs = (config, configType)=>{
12
+ return Object.keys(config || {}).filter((slug)=>{
13
+ const entityConfig = config?.[slug];
14
+ const operations = adminEntitySettings[configType];
15
+ // Check if fully enabled (boolean true)
16
+ const fullyEnabled = typeof entityConfig?.enabled === 'boolean' && entityConfig?.enabled === true;
17
+ if (fullyEnabled) {
18
+ return true;
19
+ }
20
+ // Check if partially enabled (at least one operation is enabled)
21
+ const enabled = entityConfig?.enabled;
22
+ if (typeof enabled !== 'boolean' && enabled) {
23
+ return operations.some((operation)=>{
24
+ const operationEnabled = enabled[operation.name];
25
+ return typeof operationEnabled === 'boolean' && operationEnabled === true;
26
+ });
27
+ }
28
+ return false;
29
+ });
30
+ };
31
+
32
+ //# sourceMappingURL=getEnabledSlugs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/getEnabledSlugs.ts"],"sourcesContent":["import type { EntityConfig } from '../types.js'\n\nimport { adminEntitySettings } from './adminEntitySettings.js'\n\n/**\n * Extracts enabled slugs from collections or globals configuration.\n * A slug is considered enabled if:\n * 1. enabled is set to true (fully enabled)\n * 2. enabled is an object with at least one operation set to true\n *\n * @param config - The collections or globals configuration object\n * @param configType - The type of configuration ('collection' or 'global')\n * @returns Array of enabled slugs\n */\nexport const getEnabledSlugs = (\n config: EntityConfig | undefined,\n configType: 'collection' | 'global',\n): string[] => {\n return Object.keys(config || {}).filter((slug) => {\n const entityConfig = config?.[slug]\n const operations = adminEntitySettings[configType]\n\n // Check if fully enabled (boolean true)\n const fullyEnabled =\n typeof entityConfig?.enabled === 'boolean' && entityConfig?.enabled === true\n\n if (fullyEnabled) {\n return true\n }\n\n // Check if partially enabled (at least one operation is enabled)\n const enabled = entityConfig?.enabled\n if (typeof enabled !== 'boolean' && enabled) {\n return operations.some((operation) => {\n const operationEnabled = enabled[operation.name as keyof typeof enabled]\n return typeof operationEnabled === 'boolean' && operationEnabled === true\n })\n }\n\n return false\n })\n}\n"],"names":["adminEntitySettings","getEnabledSlugs","config","configType","Object","keys","filter","slug","entityConfig","operations","fullyEnabled","enabled","some","operation","operationEnabled","name"],"mappings":"AAEA,SAASA,mBAAmB,QAAQ,2BAA0B;AAE9D;;;;;;;;;CASC,GACD,OAAO,MAAMC,kBAAkB,CAC7BC,QACAC;IAEA,OAAOC,OAAOC,IAAI,CAACH,UAAU,CAAC,GAAGI,MAAM,CAAC,CAACC;QACvC,MAAMC,eAAeN,QAAQ,CAACK,KAAK;QACnC,MAAME,aAAaT,mBAAmB,CAACG,WAAW;QAElD,wCAAwC;QACxC,MAAMO,eACJ,OAAOF,cAAcG,YAAY,aAAaH,cAAcG,YAAY;QAE1E,IAAID,cAAc;YAChB,OAAO;QACT;QAEA,iEAAiE;QACjE,MAAMC,UAAUH,cAAcG;QAC9B,IAAI,OAAOA,YAAY,aAAaA,SAAS;YAC3C,OAAOF,WAAWG,IAAI,CAAC,CAACC;gBACtB,MAAMC,mBAAmBH,OAAO,CAACE,UAAUE,IAAI,CAAyB;gBACxE,OAAO,OAAOD,qBAAqB,aAAaA,qBAAqB;YACvE;QACF;QAEA,OAAO;IACT;AACF,EAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@payloadcms/plugin-mcp",
3
- "version": "3.70.0",
3
+ "version": "3.71.0-internal-debug.80dab4c",
4
4
  "description": "MCP (Model Context Protocol) capabilities with Payload",
5
5
  "keywords": [
6
6
  "plugin",
@@ -45,10 +45,10 @@
45
45
  },
46
46
  "devDependencies": {
47
47
  "@payloadcms/eslint-config": "3.28.0",
48
- "payload": "3.70.0"
48
+ "payload": "3.71.0-internal-debug.80dab4c"
49
49
  },
50
50
  "peerDependencies": {
51
- "payload": "3.70.0"
51
+ "payload": "3.71.0-internal-debug.80dab4c"
52
52
  },
53
53
  "homepage:": "https://payloadcms.com",
54
54
  "scripts": {
@@ -3,119 +3,11 @@ import type { CollectionConfig } from 'payload'
3
3
  import type { PluginMCPServerConfig } from '../types.js'
4
4
 
5
5
  import { toCamelCase } from '../utils/camelCase.js'
6
-
7
- const addEnabledCollectionTools = (collections: PluginMCPServerConfig['collections']) => {
8
- const enabledCollectionSlugs = Object.keys(collections || {}).filter((collection) => {
9
- const fullyEnabled =
10
- typeof collections?.[collection]?.enabled === 'boolean' && collections?.[collection]?.enabled
11
-
12
- if (fullyEnabled) {
13
- return true
14
- }
15
-
16
- const partiallyEnabled =
17
- typeof collections?.[collection]?.enabled !== 'boolean' &&
18
- ((typeof collections?.[collection]?.enabled?.find === 'boolean' &&
19
- collections?.[collection]?.enabled?.find === true) ||
20
- (typeof collections?.[collection]?.enabled?.create === 'boolean' &&
21
- collections?.[collection]?.enabled?.create === true) ||
22
- (typeof collections?.[collection]?.enabled?.update === 'boolean' &&
23
- collections?.[collection]?.enabled?.update === true) ||
24
- (typeof collections?.[collection]?.enabled?.delete === 'boolean' &&
25
- collections?.[collection]?.enabled?.delete === true))
26
-
27
- if (partiallyEnabled) {
28
- return true
29
- }
30
- })
31
- return enabledCollectionSlugs.map((enabledCollectionSlug) => ({
32
- type: 'collapsible' as const,
33
- admin: {
34
- description: `Manage client access to ${enabledCollectionSlug}`,
35
- position: 'sidebar' as const,
36
- },
37
- fields: [
38
- {
39
- name: `${toCamelCase(enabledCollectionSlug)}`,
40
- type: 'group' as const,
41
- fields: [
42
- ...(collections?.[enabledCollectionSlug]?.enabled === true ||
43
- (typeof collections?.[enabledCollectionSlug]?.enabled !== 'boolean' &&
44
- typeof collections?.[enabledCollectionSlug]?.enabled?.find === 'boolean' &&
45
- collections?.[enabledCollectionSlug]?.enabled?.find === true)
46
- ? [
47
- {
48
- name: `find`,
49
- type: 'checkbox' as const,
50
- admin: {
51
- description: `Allow clients to find ${enabledCollectionSlug}.`,
52
- },
53
- defaultValue: false,
54
- label: 'Find',
55
- },
56
- ]
57
- : []),
58
-
59
- ...(collections?.[enabledCollectionSlug]?.enabled === true ||
60
- (typeof collections?.[enabledCollectionSlug]?.enabled !== 'boolean' &&
61
- typeof collections?.[enabledCollectionSlug]?.enabled?.create === 'boolean' &&
62
- collections?.[enabledCollectionSlug]?.enabled?.create === true)
63
- ? [
64
- {
65
- name: `create`,
66
- type: 'checkbox' as const,
67
- admin: {
68
- description: `Allow clients to create ${enabledCollectionSlug}.`,
69
- },
70
- defaultValue: false,
71
- label: 'Create',
72
- },
73
- ]
74
- : []),
75
-
76
- ...(collections?.[enabledCollectionSlug]?.enabled === true ||
77
- (typeof collections?.[enabledCollectionSlug]?.enabled !== 'boolean' &&
78
- typeof collections?.[enabledCollectionSlug]?.enabled?.update === 'boolean' &&
79
- collections?.[enabledCollectionSlug]?.enabled?.update === true)
80
- ? [
81
- {
82
- name: `update`,
83
- type: 'checkbox' as const,
84
- admin: {
85
- description: `Allow clients to update ${enabledCollectionSlug}.`,
86
- },
87
- defaultValue: false,
88
- label: 'Update',
89
- },
90
- ]
91
- : []),
92
-
93
- ...(collections?.[enabledCollectionSlug]?.enabled === true ||
94
- (typeof collections?.[enabledCollectionSlug]?.enabled !== 'boolean' &&
95
- typeof collections?.[enabledCollectionSlug]?.enabled?.delete === 'boolean' &&
96
- collections?.[enabledCollectionSlug]?.enabled?.delete === true)
97
- ? [
98
- {
99
- name: `delete`,
100
- type: 'checkbox' as const,
101
- admin: {
102
- description: `Allow clients to delete ${enabledCollectionSlug}.`,
103
- },
104
- defaultValue: false,
105
- label: 'Delete',
106
- },
107
- ]
108
- : []),
109
- ],
110
- label: false as const,
111
- },
112
- ],
113
- label: `${enabledCollectionSlug.charAt(0).toUpperCase() + toCamelCase(enabledCollectionSlug).slice(1)}`,
114
- }))
115
- }
6
+ import { createApiKeyFields } from '../utils/createApiKeyFields.js'
116
7
 
117
8
  export const createAPIKeysCollection = (
118
9
  collections: PluginMCPServerConfig['collections'],
10
+ globals: PluginMCPServerConfig['globals'],
119
11
  customTools: Array<{ description: string; name: string }> = [],
120
12
  experimentalTools: NonNullable<PluginMCPServerConfig['experimental']>['tools'] = {},
121
13
  pluginOptions: PluginMCPServerConfig,
@@ -204,7 +96,15 @@ export const createAPIKeysCollection = (
204
96
  },
205
97
  },
206
98
 
207
- ...addEnabledCollectionTools(collections),
99
+ ...createApiKeyFields({
100
+ config: collections,
101
+ configType: 'collection',
102
+ }),
103
+
104
+ ...createApiKeyFields({
105
+ config: globals,
106
+ configType: 'global',
107
+ }),
208
108
 
209
109
  ...(customTools.length > 0
210
110
  ? [
@@ -44,6 +44,7 @@ export const initializeMCPHandler = (pluginOptions: PluginMCPServerConfig) => {
44
44
 
45
45
  const { docs } = await payload.find({
46
46
  collection: 'payload-mcp-api-keys',
47
+ depth: 1,
47
48
  limit: 1,
48
49
  pagination: false,
49
50
  where,
package/src/index.ts CHANGED
@@ -27,6 +27,8 @@ export const mcpPlugin =
27
27
 
28
28
  // Collections
29
29
  const collections = pluginOptions.collections || {}
30
+ // Globals
31
+ const globals = pluginOptions.globals || {}
30
32
  // Extract custom tools for the global config
31
33
  const customTools =
32
34
  pluginOptions.mcp?.tools?.map((tool) => ({
@@ -46,11 +48,13 @@ export const mcpPlugin =
46
48
  * For example:
47
49
  * - If a collection has all of its capabilities enabled, admins can allow or disallow the create, update, delete, and find capabilities on that collection.
48
50
  * - If a collection only has the find capability enabled, admins can only allow or disallow the find capability on that collection.
51
+ * - If a global has all of its capabilities enabled, admins can allow or disallow the find and update capabilities on that global.
49
52
  * - If a custom tool has gone haywire, admins can disallow that tool.
50
53
  *
51
54
  */
52
55
  const apiKeyCollection = createAPIKeysCollection(
53
56
  collections,
57
+ globals,
54
58
  customTools,
55
59
  experimentalTools,
56
60
  pluginOptions,
@@ -7,9 +7,12 @@ import { APIError, configToJSONSchema, type PayloadRequest, type TypedUser } fro
7
7
  import type { MCPAccessSettings, PluginMCPServerConfig } from '../types.js'
8
8
 
9
9
  import { toCamelCase } from '../utils/camelCase.js'
10
+ import { getEnabledSlugs } from '../utils/getEnabledSlugs.js'
10
11
  import { registerTool } from './registerTool.js'
11
12
 
12
13
  // Tools
14
+ import { findGlobalTool } from './tools/global/find.js'
15
+ import { updateGlobalTool } from './tools/global/update.js'
13
16
  import { createResourceTool } from './tools/resource/create.js'
14
17
  import { deleteResourceTool } from './tools/resource/delete.js'
15
18
  import { findResourceTool } from './tools/resource/find.js'
@@ -81,6 +84,7 @@ export const getMCPHandler = (
81
84
  const experimentalTools: NonNullable<PluginMCPServerConfig['experimental']>['tools'] =
82
85
  pluginOptions?.experimental?.tools || {}
83
86
  const collectionsPluginConfig = pluginOptions.collections || {}
87
+ const globalsPluginConfig = pluginOptions.globals || {}
84
88
  const collectionsDirPath =
85
89
  experimentalTools && experimentalTools.collections?.collectionsDirPath
86
90
  ? experimentalTools.collections.collectionsDirPath
@@ -97,32 +101,8 @@ export const getMCPHandler = (
97
101
  try {
98
102
  return createMcpHandler(
99
103
  (server) => {
100
- const enabledCollectionSlugs = Object.keys(collectionsPluginConfig || {}).filter(
101
- (collection) => {
102
- const fullyEnabled =
103
- typeof collectionsPluginConfig?.[collection]?.enabled === 'boolean' &&
104
- collectionsPluginConfig?.[collection]?.enabled
105
-
106
- if (fullyEnabled) {
107
- return true
108
- }
109
-
110
- const partiallyEnabled =
111
- typeof collectionsPluginConfig?.[collection]?.enabled !== 'boolean' &&
112
- ((typeof collectionsPluginConfig?.[collection]?.enabled?.find === 'boolean' &&
113
- collectionsPluginConfig?.[collection]?.enabled?.find === true) ||
114
- (typeof collectionsPluginConfig?.[collection]?.enabled?.create === 'boolean' &&
115
- collectionsPluginConfig?.[collection]?.enabled?.create === true) ||
116
- (typeof collectionsPluginConfig?.[collection]?.enabled?.update === 'boolean' &&
117
- collectionsPluginConfig?.[collection]?.enabled?.update === true) ||
118
- (typeof collectionsPluginConfig?.[collection]?.enabled?.delete === 'boolean' &&
119
- collectionsPluginConfig?.[collection]?.enabled?.delete === true))
120
-
121
- if (partiallyEnabled) {
122
- return true
123
- }
124
- },
125
- )
104
+ // Get enabled collections
105
+ const enabledCollectionSlugs = getEnabledSlugs(collectionsPluginConfig, 'collection')
126
106
 
127
107
  // Collection Operation Tools
128
108
  enabledCollectionSlugs.forEach((enabledCollectionSlug) => {
@@ -215,6 +195,62 @@ export const getMCPHandler = (
215
195
  }
216
196
  })
217
197
 
198
+ // Global Operation Tools
199
+ const enabledGlobalSlugs = getEnabledSlugs(globalsPluginConfig, 'global')
200
+
201
+ enabledGlobalSlugs.forEach((enabledGlobalSlug) => {
202
+ try {
203
+ const schema = configSchema.definitions?.[enabledGlobalSlug] as JSONSchema4
204
+
205
+ const toolCapabilities = mcpAccessSettings?.[
206
+ `${toCamelCase(enabledGlobalSlug)}`
207
+ ] as Record<string, unknown>
208
+ const allowFind: boolean | undefined = toolCapabilities?.['find'] as boolean
209
+ const allowUpdate: boolean | undefined = toolCapabilities?.['update'] as boolean
210
+
211
+ if (allowFind) {
212
+ registerTool(
213
+ allowFind,
214
+ `Find ${enabledGlobalSlug}`,
215
+ () =>
216
+ findGlobalTool(
217
+ server,
218
+ req,
219
+ user,
220
+ useVerboseLogs,
221
+ enabledGlobalSlug,
222
+ globalsPluginConfig,
223
+ ),
224
+ payload,
225
+ useVerboseLogs,
226
+ )
227
+ }
228
+ if (allowUpdate) {
229
+ registerTool(
230
+ allowUpdate,
231
+ `Update ${enabledGlobalSlug}`,
232
+ () =>
233
+ updateGlobalTool(
234
+ server,
235
+ req,
236
+ user,
237
+ useVerboseLogs,
238
+ enabledGlobalSlug,
239
+ globalsPluginConfig,
240
+ schema,
241
+ ),
242
+ payload,
243
+ useVerboseLogs,
244
+ )
245
+ }
246
+ } catch (error) {
247
+ throw new APIError(
248
+ `Error registering tools for global ${enabledGlobalSlug}: ${String(error)}`,
249
+ 500,
250
+ )
251
+ }
252
+ })
253
+
218
254
  // Custom tools
219
255
  customMCPTools.forEach((tool) => {
220
256
  const camelCasedToolName = toCamelCase(tool.name)