{"_id":"@arevo/payload-mcp","_rev":"2-83714572471eee7271c831ab3449181d","name":"@arevo/payload-mcp","dist-tags":{"latest":"1.0.1"},"versions":{"1.0.0":{"name":"@arevo/payload-mcp","version":"1.0.0","license":"MIT","_id":"@arevo/payload-mcp@1.0.0","maintainers":[{"name":"skxv","email":"skov@skxv.dev"}],"homepage":"https://github.com/Arevo-Digital/payload-mcp#readme","bugs":{"url":"https://github.com/Arevo-Digital/payload-mcp/issues"},"dist":{"shasum":"5002f6cd1f36dc29de6bd371be75858ed77eecb0","tarball":"https://registry.npmjs.org/@arevo/payload-mcp/-/payload-mcp-1.0.0.tgz","fileCount":33,"integrity":"sha512-dzK/9yAaFJpglAlCUkrtJP061/An81Vgwdrod2vju3fp7XeEbzHG64CoZLCFa94KUeTo6kk370eHFuBMt2Ynng==","signatures":[{"sig":"MEQCIFEfjnt8Z2ezfO3fmK3ZspsMo2G2jYpgNudcuUNPHNzOAiBgNKGhwJU56DEFU5f08Zsb0uzv/mscfqRxPb0mCRXo5Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":104845},"main":"./dist/index.js","type":"module","_from":"file:arevo-payload-mcp-1.0.0.tgz","types":"./dist/index.d.ts","engines":{"node":"^18.20.2 || >=20.9.0","pnpm":"^9 || ^10"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"},"./rsc":{"types":"./dist/exports/rsc.d.ts","import":"./dist/exports/rsc.js","default":"./dist/exports/rsc.js"}},"scripts":{"dev":"next dev dev --turbo","lint":"eslint","test":"pnpm test:int && pnpm test:e2e","build":"pnpm copyfiles && pnpm build:types && pnpm build:swc","clean":"rimraf {dist,*.tsbuildinfo}","lint:fix":"eslint ./src --fix","test:e2e":"playwright test","test:int":"vitest","build:swc":"swc ./src -d ./dist --config-file .swcrc --strip-leading-paths","copyfiles":"copyfiles -u 1 \"src/**/*.{html,css,scss,ttf,woff,woff2,eot,svg,jpg,png,json}\" dist/","build:types":"tsc --outDir dist --rootDir ./src","dev:payload":"cross-env PAYLOAD_CONFIG_PATH=./dev/payload.config.ts payload","generate:types":"pnpm dev:generate-types","dev:generate-types":"pnpm dev:payload generate:types","generate:importmap":"pnpm dev:generate-importmap","dev:generate-importmap":"pnpm dev:payload generate:importmap"},"_npmUser":{"name":"skxv","email":"skov@skxv.dev"},"registry":"https://registry.npmjs.org/","_resolved":"/private/var/folders/ng/26vz_x2j5x35q1qp1jzfv4tm0000gn/T/2aba0f8a636f33e4f9b006417746903b/arevo-payload-mcp-1.0.0.tgz","_integrity":"sha512-dzK/9yAaFJpglAlCUkrtJP061/An81Vgwdrod2vju3fp7XeEbzHG64CoZLCFa94KUeTo6kk370eHFuBMt2Ynng==","repository":{"url":"git+https://github.com/Arevo-Digital/payload-mcp.git","type":"git"},"_npmVersion":"10.8.2","description":"A Payload CMS plugin that exposes a site-local MCP server over streamable HTTP.","directories":{},"_nodeVersion":"20.19.5","dependencies":{"zod":"^4.3.6","@modelcontextprotocol/sdk":"^1.29.0"},"_hasShrinkwrap":false,"devDependencies":{"next":"16.2.3","open":"^10.1.0","react":"19.2.4","sharp":"0.34.2","eslint":"^9.23.0","qs-esm":"8.0.1","rimraf":"3.0.2","vitest":"4.0.18","graphql":"^16.8.1","payload":"3.82.1","@swc/cli":"0.6.0","prettier":"^3.4.2","copyfiles":"2.4.1","cross-env":"^7.0.3","react-dom":"19.2.4","typescript":"5.7.3","@types/node":"22.19.9","@types/react":"19.2.14","@payloadcms/ui":"3.82.1","@eslint/eslintrc":"^3.2.0","@payloadcms/next":"3.82.1","@playwright/test":"1.58.2","@types/react-dom":"19.2.3","sort-package-json":"^2.10.0","@swc-node/register":"1.10.9","eslint-config-next":"16.2.3","vite-tsconfig-paths":"6.0.5","@payloadcms/db-sqlite":"3.82.1","@payloadcms/db-postgres":"3.82.1","@payloadcms/eslint-config":"3.9.0","@payloadcms/richtext-lexical":"3.82.1"},"peerDependencies":{"payload":"^3.37.0"},"_npmOperationalInternal":{"tmp":"tmp/payload-mcp_1.0.0_1775923580701_0.12452419607657639","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@arevo/payload-mcp","version":"1.0.1","description":"A Payload CMS plugin that exposes a site-local MCP server over streamable HTTP.","repository":{"type":"git","url":"git+https://github.com/Arevo-Digital/payload-mcp.git"},"homepage":"https://github.com/Arevo-Digital/payload-mcp#readme","bugs":{"url":"https://github.com/Arevo-Digital/payload-mcp/issues"},"license":"MIT","type":"module","exports":{".":{"import":"./dist/index.js","types":"./dist/index.d.ts","default":"./dist/index.js"}},"main":"./dist/index.js","types":"./dist/index.d.ts","devDependencies":{"@eslint/eslintrc":"^3.2.0","@payloadcms/db-postgres":"3.82.1","@payloadcms/db-sqlite":"3.82.1","@payloadcms/eslint-config":"3.9.0","@payloadcms/next":"3.82.1","@payloadcms/richtext-lexical":"3.82.1","@payloadcms/ui":"3.82.1","@playwright/test":"1.58.2","@swc-node/register":"1.10.9","@swc/cli":"0.6.0","@types/node":"22.19.9","@types/react":"19.2.14","@types/react-dom":"19.2.3","copyfiles":"2.4.1","cross-env":"^7.0.3","eslint":"^9.23.0","eslint-config-next":"16.2.3","graphql":"^16.8.1","next":"16.2.3","open":"^10.1.0","payload":"3.82.1","prettier":"^3.4.2","qs-esm":"8.0.1","react":"19.2.4","react-dom":"19.2.4","rimraf":"3.0.2","sharp":"0.34.2","sort-package-json":"^2.10.0","typescript":"5.7.3","vite-tsconfig-paths":"6.0.5","vitest":"4.0.18"},"peerDependencies":{"payload":"^3.37.0"},"engines":{"node":"^18.20.2 || >=20.9.0","pnpm":"^9 || ^10"},"publishConfig":{"access":"public"},"registry":"https://registry.npmjs.org/","dependencies":{"@modelcontextprotocol/sdk":"^1.29.0","zod":"^4.3.6"},"scripts":{"build":"pnpm copyfiles && pnpm build:types && pnpm build:swc","build:swc":"swc ./src -d ./dist --config-file .swcrc --strip-leading-paths","build:types":"tsc --outDir dist --rootDir ./src","clean":"rimraf {dist,*.tsbuildinfo}","copyfiles":"copyfiles -u 1 \"src/**/*.{html,css,scss,ttf,woff,woff2,eot,svg,jpg,png,json}\" dist/","dev":"next dev dev --turbo","dev:generate-importmap":"pnpm dev:payload generate:importmap","dev:generate-types":"pnpm dev:payload generate:types","dev:payload":"cross-env PAYLOAD_CONFIG_PATH=./dev/payload.config.ts payload","generate:importmap":"pnpm dev:generate-importmap","generate:types":"pnpm dev:generate-types","lint":"eslint","lint:fix":"eslint ./src --fix","test":"pnpm test:int && pnpm test:e2e","test:e2e":"playwright test","test:int":"vitest"},"_id":"@arevo/payload-mcp@1.0.1","_integrity":"sha512-JlI7k4H0ZJ16M5LlLDRQYjmb49T6N4wR3sQpCvIi2AeWdkIzqLAsSxOHstABk7MpPYnftLoANWcTNMRRaIMcMQ==","_resolved":"/private/var/folders/ng/26vz_x2j5x35q1qp1jzfv4tm0000gn/T/1070bbf4d9185336ec17cc8af4aed805/arevo-payload-mcp-1.0.1.tgz","_from":"file:arevo-payload-mcp-1.0.1.tgz","_nodeVersion":"20.19.5","_npmVersion":"10.8.2","dist":{"integrity":"sha512-JlI7k4H0ZJ16M5LlLDRQYjmb49T6N4wR3sQpCvIi2AeWdkIzqLAsSxOHstABk7MpPYnftLoANWcTNMRRaIMcMQ==","shasum":"24ed7d6f30470e017f6ced5eeab11aed445d17eb","tarball":"https://registry.npmjs.org/@arevo/payload-mcp/-/payload-mcp-1.0.1.tgz","fileCount":33,"unpackedSize":103613,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDacmOkkOsnisDYPoCbyGM0gEa5KuJdGIJg/iQ+IYH/+AIgFjgDqSpOHIKl4QePxy5v/wi7YkrVHGebppgIwVIJSG8="}]},"_npmUser":{"name":"skxv","email":"skov@skxv.dev"},"directories":{},"maintainers":[{"name":"skxv","email":"skov@skxv.dev"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/payload-mcp_1.0.1_1775924984972_0.9229551889735133"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-11T16:06:20.585Z","modified":"2026-04-11T16:29:45.273Z","1.0.0":"2026-04-11T16:06:20.823Z","1.0.1":"2026-04-11T16:29:45.134Z"},"bugs":{"url":"https://github.com/Arevo-Digital/payload-mcp/issues"},"license":"MIT","homepage":"https://github.com/Arevo-Digital/payload-mcp#readme","repository":{"type":"git","url":"git+https://github.com/Arevo-Digital/payload-mcp.git"},"description":"A Payload CMS plugin that exposes a site-local MCP server over streamable HTTP.","maintainers":[{"name":"skxv","email":"skov@skxv.dev"}],"readme":"# payloadcms-mcp-server\n\nA Payload CMS plugin that exposes a site-local MCP server over streamable HTTP.\n\nInstall the plugin in any Payload app, give it a shared bearer token, and connect your MCP client directly to that Payload instance. There is no browser auth flow. The MCP client talks to `https://your-site.com/api/mcp` and the plugin uses Payload's Local API to read and mutate content.\n\n## What it does\n\n- Exposes a streamable HTTP MCP endpoint from the Payload app itself\n- Secures the endpoint with a shared bearer token\n- Lets MCP clients inspect the Payload schema before making changes\n- Supports generic collection CRUD, global CRUD, duplication, counts, and uploads\n- Runs entirely inside the Payload server, so there is no separate MCP process to host\n\n## Security model\n\nThis plugin is designed for direct server-to-client MCP connections.\n\n- The endpoint is protected by a static bearer token that you configure in Payload.\n- By default, the plugin runs Local API operations with `overrideAccess: true`.\n- That means the MCP connection acts like a trusted service account with full access to the exposed collections and globals.\n- If you want stricter scope, limit the exposed collections/globals and set `overrideAccess: false`.\n\nIf you expose this on a public site, use a strong random token and keep it in environment variables on both sides.\n\n## Installation\n\n```bash\npnpm add payloadcms-mcp-server\n```\n\nThen add it to your `payload.config.ts`:\n\n```ts\nimport { buildConfig } from 'payload'\nimport { payloadMCP } from 'payloadcms-mcp-server'\n\nexport default buildConfig({\n  collections: [\n    // your collections\n  ],\n  globals: [\n    // your globals\n  ],\n  plugins: [\n    payloadMCP({\n      endpoint: '/mcp',\n      serverName: 'my-payload-site',\n      token: process.env.PAYLOAD_MCP_TOKEN,\n    }),\n  ],\n})\n```\n\n## Required environment variables\n\nAdd a shared token to your Payload app:\n\n```bash\nPAYLOAD_MCP_TOKEN=replace-this-with-a-long-random-secret\n```\n\nYour MCP client should use the same token as a bearer token.\n\n## Connecting from an MCP client\n\nUse these settings in clients that support remote streamable HTTP MCP servers:\n\n- Name: anything you want\n- Transport: `Streamable HTTP`\n- URL: `https://your-site.com/api/mcp`\n- Bearer token env var: whatever env var your client uses locally, for example `PAYLOAD_MCP_TOKEN`\n\nExample local client env:\n\n```bash\nexport PAYLOAD_MCP_TOKEN=replace-this-with-a-long-random-secret\n```\n\n## Plugin options\n\n```ts\ntype PayloadMCPPluginConfig = {\n  allowUnauthenticated?: boolean\n  collections?: true | string[]\n  corsOrigins?: '*' | string[]\n  defaultDepth?: number\n  enabled?: boolean\n  endpoint?: `/${string}`\n  globals?: true | string[]\n  maxBase64UploadSizeMB?: number\n  maxFindLimit?: number\n  overrideAccess?: boolean\n  serverName?: string\n  token?: string\n  tokens?: string[]\n}\n```\n\n### Common options\n\n- `token`: the shared bearer token for the MCP endpoint\n- `tokens`: multiple valid bearer tokens if you want rotation or per-client tokens\n- `endpoint`: endpoint path relative to Payload's API route, defaults to `/mcp`\n- `serverName`: the MCP server name reported to clients\n- `collections`: `true` for all collections or an allowlist like `['pages', 'posts', 'media']`\n- `globals`: `true` for all globals or an allowlist\n- `overrideAccess`: defaults to `true`\n- `allowUnauthenticated`: only use this if you explicitly want an open MCP endpoint\n- `corsOrigins`: optional CORS allowlist for browser-based callers\n\n## Recommended production config\n\n```ts\npayloadMCP({\n  collections: ['pages', 'posts', 'media'],\n  endpoint: '/mcp',\n  globals: ['site-settings'],\n  maxBase64UploadSizeMB: 5,\n  maxFindLimit: 25,\n  overrideAccess: true,\n  serverName: 'marketing-site',\n  token: process.env.PAYLOAD_MCP_TOKEN,\n})\n```\n\n## Exposed tools\n\nThe plugin currently registers these MCP tools:\n\n- `payload_server_info`\n- `payload_schema`\n- `payload_find`\n- `payload_find_by_id`\n- `payload_count`\n- `payload_create`\n- `payload_update`\n- `payload_delete`\n- `payload_duplicate`\n- `payload_get_global`\n- `payload_update_global`\n- `payload_create_upload_from_url`\n- `payload_create_upload_from_base64`\n\nIt also exposes:\n\n- Resource: `payload://schema`\n- Prompt: `payload-editor-guide`\n\n## Typical workflow\n\nMost MCP clients will work best if the model follows this order:\n\n1. Call `payload_schema`\n2. Inspect available collections, globals, and fields\n3. Read the target document with `payload_find` or `payload_find_by_id`\n4. Apply changes with `payload_create`, `payload_update`, or `payload_update_global`\n\n## Uploads\n\nTwo upload helpers are included:\n\n- `payload_create_upload_from_url`: download a remote file and create an upload document\n- `payload_create_upload_from_base64`: create an upload document from base64 file contents\n\nBase64 uploads are limited by `maxBase64UploadSizeMB`, which defaults to `10`.\n\n## Development\n\nThis repo includes a working Payload app in [`dev`](./dev) that uses the plugin locally.\n\n### Start the dev app\n\n```bash\npnpm install\npnpm dev\n```\n\nDefault local credentials:\n\n- Email: `dev@payloadcms.com`\n- Password: `test`\n\nDefault local MCP token:\n\n- `payload-mcp-dev-token`\n\nLocal MCP URL:\n\n- `http://localhost:3000/api/mcp`\n\n### Run tests\n\n```bash\npnpm test:int\npnpm build\n```\n\n## Publishing to npm\n\nBefore publishing:\n\n1. Update `package.json` metadata if you want a different package name, author, or repository URL.\n2. Run `pnpm test:int`\n3. Run `pnpm build`\n4. Publish with your preferred registry workflow\n\nExample:\n\n```bash\nnpm publish --access public\n```\n\n## Notes\n\n- The plugin uses Payload's custom endpoints, so the final URL is your Payload API route plus the configured `endpoint`.\n- With a standard Payload setup, `/mcp` becomes `/api/mcp`.\n- The plugin intentionally does not implement an OAuth or browser auth flow.\n- The current design is best for trusted internal tooling and direct editor/agent connections.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}