Skip to content

feat(cms): upgrade Payload to 3.78.0 and set up MCP plugin#12

Merged
jhb-dev merged 7 commits intomainfrom
copilot/setup-payload-mcp-plugin
Mar 15, 2026
Merged

feat(cms): upgrade Payload to 3.78.0 and set up MCP plugin#12
jhb-dev merged 7 commits intomainfrom
copilot/setup-payload-mcp-plugin

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 14, 2026

Upgrades Payload CMS to v3.78.0 (second latest stable) and wires up the @payloadcms/plugin-mcp plugin so AI coding assistants can read and edit CMS content via MCP.

Package upgrades

  • All @payloadcms/* packages: 3.74.03.78.0
  • @payloadcms/plugin-mcp@3.78.0 added
  • next: 16.2.0-canary.716.2.0-canary.98 (required by @payloadcms/next@3.78.0 peer dep)

MCP plugin configuration

All content collections and globals are enabled; system collections (users, redirects) are excluded:

mcpPlugin({
  collections: {
    'article-tags': { enabled: true },
    articles: { enabled: true },
    authors: { enabled: true },
    customers: { enabled: true },
    images: { enabled: true },
    pages: { enabled: true },
    projects: { enabled: true },
    testimonials: { enabled: true },
  },
  globals: {
    footer: { enabled: true },
    header: { enabled: true },
    labels: { enabled: true },
  },
})

Draft-only writes for MCP agents

For all collections with versions.drafts enabled (Articles, Pages, Authors, Projects, Testimonials), MCP API key requests are restricted to draft-only writes via a shared restrictMcpToDraft beforeChange hook. This prevents MCP agents from publishing content directly — any attempt to set _status: 'published' is silently coerced to 'draft'.

Type fix

The MCP plugin expands the user type to User | PayloadMcpApiKey. All role-based access functions now guard with user.collection === 'users' before accessing user.roles to satisfy the union type.

README

Added MCP setup instructions for both GitHub Copilot (VS Code) and Claude Code, covering API key creation and client configuration against both local and production CMS URLs.

Original prompt

This section details on the original issue you should resolve

<issue_title>set up Payload MCP plugin</issue_title>
<issue_description>- upgrade to second latest payload version

  • install the MCP plugin and configure so that all collections (except for system ones like users) become editable
  • add some instructions to the readme on how to set up the MCP in GitHub codepilot agents (GitHub Web) and Claude Code
  • type check, format and build the CMS to ensure everything works before committing</issue_description>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

@vercel
Copy link
Copy Markdown

vercel bot commented Mar 14, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

2 Skipped Deployments
Project Deployment Actions Updated (UTC)
website Ignored Ignored Mar 15, 2026 4:19pm
website-cms Ignored Ignored Mar 15, 2026 4:19pm

Request Review

- Upgrade all @payloadcms packages from 3.74.0 to 3.78.0 (second latest stable)
- Update Next.js from 16.2.0-canary.7 to 16.2.0-canary.98 for compatibility
- Install and configure @payloadcms/plugin-mcp@3.78.0 for all non-system collections and globals
- Fix type errors in access control files caused by PayloadMcpApiKey union type
- Add MCP setup instructions to README.md for GitHub Copilot and Claude Code

Co-authored-by: jhb-dev <20878653+jhb-dev@users.noreply.github.com>
Copilot AI changed the title [WIP] Set up Payload MCP plugin and configure collections feat(cms): upgrade Payload to 3.78.0 and set up MCP plugin Mar 14, 2026
Copilot AI requested a review from jhb-dev March 14, 2026 10:17
Copy link
Copy Markdown
Contributor

@jhb-dev jhb-dev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure hat for collections with drafts enabled. The agent is only able to create new drafts but not published versions. Use acces control to achieve this.

Add a shared restrictMcpToDraft beforeChange hook that forces _status
to 'draft' when the requesting user is an MCP API key. Apply it to all
five draft-enabled collections: Articles, Pages, Authors, Projects,
and Testimonials.

Co-authored-by: jhb-dev <20878653+jhb-dev@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 14, 2026

Ensure hat for collections with drafts enabled. The agent is only able to create new drafts but not published versions. Use acces control to achieve this.

Done in 571408e. Added a shared restrictMcpToDraft beforeChange hook (cms/src/shared/hooks/restrictMcpToDraft.ts) that forces _status: 'draft' whenever the requester is an MCP API key. The hook is applied to all five draft-enabled collections: Articles, Pages, Authors, Projects, and Testimonials.

Note: Payload's auto-generated _status field (added by versions.drafts) cannot be given field-level access overrides without conflicting with Payload's internal field generation. The beforeChange hook is the Payload-recommended mechanism for enforcing this kind of data constraint — it silently coerces the value rather than blocking the request, which gives the MCP client a clean result (a draft) rather than an error.

Copilot AI requested a review from jhb-dev March 14, 2026 12:47
@jhb-dev jhb-dev marked this pull request as ready for review March 15, 2026 16:18
@claude
Copy link
Copy Markdown

claude bot commented Mar 15, 2026

PR Review: feat(cms): upgrade Payload to 3.78.0 and set up MCP plugin

Overall the implementation is clean and well-structured. A few things to flag:


Potential Bugs

restrictMcpToDraft applied to Testimonials inconsistently

The hook is described as targeting "collections with versions.drafts enabled," but Testimonials uses CollectionConfig (not PageCollectionConfig) and doesn't appear to have versions.drafts configured. The hook is harmless on a non-draft collection (no _status field exists to coerce), but it's misleading and should either be removed from Testimonials.ts or the PR description should be updated.

Globals have no draft-restriction protection

footer, header, and labels are all enabled for MCP writes, but no equivalent of restrictMcpToDraft is applied to them. If these globals support drafts, MCP agents can publish changes to globals directly — bypassing the draft-only constraint applied to collections. Consider checking whether globals need a similar beforeChange global hook.

Silent status coercion

restrictMcpToDraft silently overwrites _status: 'published' with 'draft' without any error or warning. MCP agent users will have no feedback that their publish attempt was rejected. Consider returning an error or at least logging, so agents can understand the constraint rather than assuming the write succeeded as intended.


Security Concerns

customers and images collections enabled for full CRUD

Both collections are enabled with create/update/delete access for MCP agents:

  • customers likely contains sensitive PII — granting arbitrary MCP write (and delete) access is risky without additional field-level restrictions.
  • images allows uploading arbitrary files. Depending on how Payload handles file uploads via the MCP endpoint, this could be abused.

Consider either disabling write operations for these collections, or enabling read-only (find: true, others omitted/false).

Production MCP URL in README

The README documents https://cms.jhb.software/api/mcp publicly. While the endpoint requires an API key, publishing the URL increases the attack surface for credential stuffing or API key brute-forcing. Worth noting that the MCP plugin should enforce rate limiting on the auth endpoint.


Minor

  • The next-env.d.ts path change (.next/types/.next/dev/types/) is auto-generated by the Next.js canary bump — fine, but verify the production build path stays consistent post-deployment.
  • The next bump is a large canary jump (.7.98). It's required by Payload 3.78.0, but worth keeping an eye on any behavioral regressions in the admin UI.

@jhb-dev jhb-dev merged commit 70b8c01 into main Mar 15, 2026
7 of 8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

set up Payload MCP plugin

2 participants