Skip to content

feat(plugin-mcp)!: mcp plugin refactor, add stdio mcp#16726

Open
AlessioGr wants to merge 50 commits into
mainfrom
feat/mcp-local
Open

feat(plugin-mcp)!: mcp plugin refactor, add stdio mcp#16726
AlessioGr wants to merge 50 commits into
mainfrom
feat/mcp-local

Conversation

@AlessioGr
Copy link
Copy Markdown
Member

@AlessioGr AlessioGr commented May 23, 2026

Fixes #16339

This PR refactors @payloadcms/plugin-mcp. The public API and main ideas stay mostly the same, but the config shape, access model, and internals all changed. The new architecture lands in one PR; follow-up improvements are planned separately.

Breaking changes

The plugin config API changed across the board, so most setups need updating.

Collections and globals are opt-out, not opt-in

Installing the plugin is now enough to get a working MCP server: every collection and global is exposed by default with the standard CRUD tools (find, create, update, delete). You opt OUT of what you don't want instead of opting IN to each piece.

After upgrading, collections you never listed before are reachable over MCP. Review what's exposed and disable anything that shouldn't be.

  mcpPlugin({
    collections: {
-     posts: { enabled: true },
-     users: { enabled: { find: true } },
+     // posts is exposed automatically, no entry needed
+     users: { tools: { create: false, update: false, delete: false } }, // find only
    },
  })

A consistent shape for tools, prompts and resources

Registering an MCP capability used to mean juggling three different API shapes:

  • collections.<slug>.enabled.<op>: built-in CRUD. Not keyed under tools.
  • mcp.tools[]: custom tools. Keyed under tools, but as an array.
  • experimental.tools.<kind>: auth and codegen. Keyed under tools again, but as a nested map per kind.

Now there's one shape everywhere: a tools / prompts / resources map, applied either nested under a collection or global (config.collections[slug].tools, config.globals[slug].tools) or at the top level (config.tools).

Before.

mcpPlugin({
  collections: {
    posts: { enabled: { find: true, create: true } },
  },
  mcp: {
    tools: [
      { name: 'diceRoll', parameters: z.object({ sides: z.number() }).shape, handler: (args, req) => ({...}) },
    ],
    prompts: [
      { name: 'echo', argsSchema: z.object({ msg: z.string() }), handler: (args, req) => ({...}) },
    ],
    resources: [
      { name: 'data', uri: 'data://app', handler: (uri, req) => ({...}) },
    ],
  },
  experimental: {
    tools: {
      auth:        { enabled: true },
      collections: { enabled: true, collectionsDirPath: './src/collections' },
      jobs:        { enabled: true, jobsDirPath: './src/jobs' },
    },
  },
})

After. One name: value map at two scopes. The same map holds built-in tools, overrides, opt-in auth tools, and custom tools side by side:

mcpPlugin({
  collections: {
    posts: {
      tools: {
        find: { description: 'Find published posts' }, // built-in override
        publish: defineCollectionTool({                  // custom collection tool
          input: z.object({ id: z.string() }),
        }).handler(async ({ input, req }) => ({...})),
      },
    },
    users: {
      tools: { login: true, verify: true }, // opt-in built-in auth tools
    },
  },

  tools:     { diceRoll: defineTool({ input: z.object({ sides: z.number() }) }).handler(({ input }) => ({...})) },
  prompts:   { echo:     definePrompt({ argsSchema: z.object({ msg: z.string() }) }).handler(({ input }) => ({...})) },
  resources: { data:     { uri: 'data://app', handler: ({ uri }) => ({...}) } },
})

Fully typed tool handlers

The schema you pass as input flows into the handler's argument:

defineTool({
  input: z.object({
    sides: z.number().int().min(2).max(100),
    label: z.string().optional(),
  }),
}).handler(({ input }) => {
  input.sides // number
  input.label // string | undefined
})

Same inference for all four builders (defineTool, defineCollectionTool, defineGlobalTool, definePrompt). Inputs accept any Standard Schema (Zod, Valibot, etc.) or a raw JSON Schema. The old parameters: ZodRawShape is gone, and handlers now take named arguments instead of positional ones.

Nested instead of hoisted

Two places in the old plugin packed unrelated concepts into the same top-level namespace, which made name conflicts easy. Both are now nested by kind.

Tool inputs. The built-in create and update tools used to place document fields right next to option fields like depth, draft, locale and select. A field literally called draft or depth would collide with the option of the same name. Document fields now live under their own data key:

// arguments to a `createPosts` tool call

// before
{ title: 'Hello', _status: 'draft', draft: true, depth: 2 }

// after
{ data: { title: 'Hello' }, draft: true, depth: 2 }

_status, id, createdAt and updatedAt are also stripped from data since Payload manages them.

API key access document. The old document hung every collection, global, tool, prompt and resource off the root, with custom items wedged under awkward payload-mcp-tool / payload-mcp-resource / payload-mcp-prompt keys. Everything now goes into one access JSON field, nested by kind:

// before (excerpt of the api key doc)
{
  posts:            { create: true, find: true },
  'site-settings':  { find: true, update: false },
  'payload-mcp-tool':     { diceRoll: true },
  'payload-mcp-resource': { data: true },
  'payload-mcp-prompt':   { echo: true },
  // Properties unrelated to access
  user: 123,
  description: 'Test',
}

// after
{
  access: {
    collections: { posts: { create: true } },
    globals:     { 'site-settings': { update: false } },
    tools:       { diceRoll: true },
    resources:   { data: true },
    prompts:     { echo: true },
  },
  // Properties unrelated to access
  user: 123,
  description: 'Test',
}

Auth tools are scoped and opt-in

The auth tools (login, verify, forgotPassword, resetPassword, unlock, auth) used to be flat, development-only tools that took a collection argument. They're now per-collection and bound to it:

- mcpPlugin({ experimental: { tools: { auth: { enabled: true } } } })
- // wire name: `login`, called with { collection: 'users', email, password }
+ mcpPlugin({ collections: { users: { tools: { login: true } } } })
+ // wire name: `loginUsers`, called with { email, password }

A leaner public surface

A handful of options got removed:

  • mcp.handlerOptions is gone. verboseLogs survived as mcp.verboseLogs; onEvent, maxDuration, disableSse, redisUrl and basePath were dropped (the new server has no SSE/Redis path).
  • experimental.tools (the tools that scaffolded and edited collection, job and config files on disk) was removed entirely, with no replacement.
  • The GET /api/mcp route was dropped; only POST remains.

API keys must be recreated

The payload-mcp-api-keys collection keeps its slug, but its fields changed completely. Access used to be defined via multiple group and checkbox fields. Now, the whole tree now lives in a single access JSON field with a custom checkbox UI in the admin panel.

The old layout meant that on a postgres/drizzle db, adding or removing a collection, tool, prompt or resource changed the schema, requiring a migration. With the access tree kept as JSON, the table schema stays stable and no migrations are required.

To migrate, delete your existing API keys after upgrading and create fresh ones.

Dependencies

Bundling plugin-mcp/src/index.ts with esbuild (externalizing payload, @payloadcms/ui, react):

Branch Bundled src/index.ts (minified)
origin/main 4,781 KB
feat/mcp-local 537 KB

About a 9x smaller bundle, ~4.3 MB shaved off. The biggest single contributor was the runtime use of convertCollectionSchemaToZod, which called import * as ts from 'typescript'. We were shipping the entire TypeScript package so we could transpile a generated source-code string at runtime and new Function()-eval it into a zod schema - now, z.fromJSONSchema() from zod v4 can now do this cleanly in a single call.

The rest came from swapping the SDK. @modelcontextprotocol/sdk@1.x was a bloated kitchen sink: Express 5, Hono, @hono/node-server, cors, express-rate-limit, jose, ajv + ajv-formats, pkce-challenge. 29 MB unpacked with dependencies, plus mcp-handler (which added Redis). @modelcontextprotocol/server@2.0.0-alpha.2 is one runtime dependency (zod) and one optional peer (@cfworker/json-schema). 6 MB unpacked with dependencies.

In the next 2.0 alpha release, we'll be able to get rid of @cfworker/json-schema to further cut bundle size.

@modelcontextprotocol/sdk@1.:

screenshot 2026-05-22 at 18 45 23@2x

@modelcontextprotocol/server@2 alpha:

screenshot 2026-05-22 at 18 45 50@2x

What else is new

  • A stdio transport with near-zero setup. Install the plugin and point a local AI client at npx payload-mcp. No plugins array entry, HTTP server, or API key required.

The internal refactor

The biggest internal wins are that the public API is now used internally, an improved, simpler folder structure, and the up-front sanitization into a flat items array that's much easier to work with.

That collapses several parallel flows that used to coexist: a 545-line getMcpHandler.ts that hand-registered every kind, a tools/resource/* family that ran new Function('z', ...) per request, three filesystem-codegen families (tools/collection/*, tools/config/*, tools/job/*, now gone), and inline auth checks scattered across tool files. Now the plugin runs through:

  1. Init: sanitizeMCPConfig walks the user config and the builtinTools.ts registry, producing a flat items: MCPItem[].
  2. Request: mcpEndpoint calls getAuthorizedMCP to resolve the API key (or dev-mode session) and filter items against the access document, then buildMcpServer iterates and registers each on mcp item. Auth lives in one single file (endpoint/access.ts).
  3. stdio: same as 2, but stdio.ts synthesizes a full-access AuthorizedMCP and connects a StdioServerTransport.

Per-request work, old vs new

The single biggest reduction is how tools get registered: the old plugin had a separate iteration and code branch for every kind of thing it could expose; the new one sanitizes all of them into one flat array at boot and walks it once.

Old: everything happens per request. Each config source resolves to its own bespoke tool file, and mcpAccessSettings (a flat per-slug permissions object) is consulted at every register site to decide whether to expose that specific tool.

flowchart TB
    subgraph perReqOld["Per request"]
      req[POST /api/mcp]
      req --> auth["getDefaultMcpAccessSettings<br/>Bearer + API key lookup"]
      auth --> mas["mcpAccessSettings<br/>(flat per-slug permissions)"]
      mas --> setup["mcp-handler invokes setup callback"]

      setup --> col["collections.&lt;slug&gt;.enabled.&lt;op&gt;"]
      setup --> glb["globals.&lt;slug&gt;.enabled.&lt;op&gt;"]
      setup --> exp["experimental.tools.{auth, collections, config, jobs}"]
      setup --> mct["mcp.tools[]"]
      setup --> mcpP["mcp.prompts[]"]
      setup --> mcr["mcp.resources[]"]

      col --> tr["tools/resource/{create,find,update,delete}.ts<br/>+ convertCollectionSchemaToZod (eval)"]
      glb --> tg["tools/global/{find,update}.ts"]
      exp --> texp["tools/auth/* &nbsp;·&nbsp; tools/collection/* (codegen)<br/>tools/config/* (codegen) &nbsp;·&nbsp; tools/job/* (codegen)"]
      mct --> uh1["user handler"]
      mcpP --> uh2["user handler"]
      mcr --> uh3["user handler"]

      mas -. access check .-> tr
      mas -. access check .-> tg
      mas -. access check .-> texp
      mas -. access check .-> uh1
      mas -. access check .-> uh2
      mas -. access check .-> uh3

      tr --> RT[server.registerTool]
      tg --> RT
      texp --> RT
      uh1 --> RT
      uh2 --> RP[server.registerPrompt]
      uh3 --> RR[server.registerResource]
    end
Loading

New: sanitization during boot.

flowchart TB
    subgraph bootNew["Once at boot"]
      cfg[plugin config + builtinTools registry] --> san[sanitizeMCPConfig]
      san --> items["items: MCPItem[]"]
    end

    subgraph perReqNew["Per request"]
      req[POST /api/mcp] --> auth["getAuthorizedMCP<br/>fetch API key document, filter flat items[] array"]
      access["api-key.access JSON field"] --> auth
      auth --> build["buildMcpServer<br/>one switch on item.type"]
      build --> RT[server.registerTool]
      build --> RP[server.registerPrompt]
      build --> RR[server.registerResource]
    end

    items --> auth
Loading

The MCP plugin is now also enabled across the monorepo test suites, so we exercise it internally.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 23, 2026

📦 esbuild Bundle Analysis for payload

This analysis was generated by esbuild-bundle-analyzer. 🤖

Meta File Out File Size (raw) Note
packages/next/meta_index.json esbuild/index.js 988.74 KB 🆕 Added
packages/payload/meta_index.json esbuild/index.js 1.41 MB 🆕 Added
packages/payload/meta_shared.json esbuild/exports/shared.js 192.51 KB 🆕 Added
packages/richtext-lexical/meta_client.json esbuild/exports/client_optimized/index.js 304.12 KB 🆕 Added
packages/ui/meta_client.json esbuild/exports/client_optimized/index.js 1.25 MB 🆕 Added
packages/ui/meta_shared.json esbuild/exports/shared_optimized/index.js 18.56 KB 🆕 Added
Largest paths These visualization shows top 20 largest paths in the bundle.

Meta file: packages/next/meta_index.json, Out file: esbuild/index.js

Path Size
../../node_modules ${{\color{Goldenrod}{ ████████████████████▌ }}}$ 82.1%, 807.52 KB
dist/views/Version ${{\color{Goldenrod}{ █▎ }}}$ 5.2%, 51.48 KB
dist/views/Dashboard ${{\color{Goldenrod}{ ▌ }}}$ 2.2%, 21.71 KB
dist/views/Document ${{\color{Goldenrod}{ ▍ }}}$ 1.7%, 16.68 KB
dist/views/List ${{\color{Goldenrod}{ ▍ }}}$ 1.6%, 15.44 KB
dist/elements/Nav ${{\color{Goldenrod}{ ▎ }}}$ 1.0%, 10.24 KB
dist/views/Root ${{\color{Goldenrod}{ ▎ }}}$ 1.0%, 9.90 KB
dist/views/API ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 6.13 KB
dist/views/Account ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 6.06 KB
dist/views/Versions ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 5.70 KB
dist/elements/DocumentHeader ${{\color{Goldenrod}{ ▏ }}}$ 0.5%, 4.71 KB
dist/views/Login ${{\color{Goldenrod}{ ▏ }}}$ 0.5%, 4.53 KB
dist/layouts/Root ${{\color{Goldenrod}{ }}}$ 0.4%, 3.53 KB
dist/views/ForgotPassword ${{\color{Goldenrod}{ }}}$ 0.3%, 3.13 KB
dist/views/CreateFirstUser ${{\color{Goldenrod}{ }}}$ 0.3%, 3.02 KB
dist/views/ResetPassword ${{\color{Goldenrod}{ }}}$ 0.2%, 2.40 KB
dist/templates/Default ${{\color{Goldenrod}{ }}}$ 0.2%, 2.02 KB
dist/views/Logout ${{\color{Goldenrod}{ }}}$ 0.2%, 1.94 KB
dist/views/Verify ${{\color{Goldenrod}{ }}}$ 0.1%, 1.29 KB
dist/utilities/initReq.js ${{\color{Goldenrod}{ }}}$ 0.1%, 1.14 KB
(other) ${{\color{Goldenrod}{ ████▍ }}}$ 17.9%, 176.54 KB

Meta file: packages/payload/meta_index.json, Out file: esbuild/index.js

Path Size
../../node_modules ${{\color{Goldenrod}{ █████████████████ }}}$ 68.4%, 959.51 KB
dist/fields/hooks ${{\color{Goldenrod}{ ▊ }}}$ 3.1%, 44.07 KB
dist/collections/operations ${{\color{Goldenrod}{ ▋ }}}$ 2.9%, 40.23 KB
dist/versions/migrations ${{\color{Goldenrod}{ ▎ }}}$ 1.3%, 18.50 KB
dist/auth/operations ${{\color{Goldenrod}{ ▎ }}}$ 1.1%, 15.63 KB
dist/fields/config ${{\color{Goldenrod}{ ▎ }}}$ 1.0%, 13.41 KB
dist/globals/operations ${{\color{Goldenrod}{ ▎ }}}$ 1.0%, 13.40 KB
dist/utilities/configToJSONSchema.js ${{\color{Goldenrod}{ ▏ }}}$ 0.9%, 13.13 KB
dist/queues/operations ${{\color{Goldenrod}{ ▏ }}}$ 0.9%, 12.63 KB
dist/fields/validations.js ${{\color{Goldenrod}{ ▏ }}}$ 0.8%, 10.57 KB
dist/collections/config ${{\color{Goldenrod}{ ▏ }}}$ 0.7%, 9.53 KB
dist/bin/generateImportMap ${{\color{Goldenrod}{ ▏ }}}$ 0.7%, 9.44 KB
dist/config/orderable ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 7.92 KB
dist/uploads/fetchAPI-multipart ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 7.80 KB
dist/index.js ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 7.77 KB
dist/hierarchy/utils ${{\color{Goldenrod}{ ▏ }}}$ 0.5%, 7.65 KB
dist/database/migrations ${{\color{Goldenrod}{ ▏ }}}$ 0.5%, 7.54 KB
dist/collections/endpoints ${{\color{Goldenrod}{ }}}$ 0.4%, 6.23 KB
dist/auth/strategies ${{\color{Goldenrod}{ }}}$ 0.4%, 5.43 KB
dist/queues/config ${{\color{Goldenrod}{ }}}$ 0.4%, 5.31 KB
(other) ${{\color{Goldenrod}{ ███████▉ }}}$ 31.6%, 443.37 KB

Meta file: packages/payload/meta_shared.json, Out file: esbuild/exports/shared.js

Path Size
../../node_modules ${{\color{Goldenrod}{ ███████████████████▉ }}}$ 79.5%, 150.12 KB
dist/fields/validations.js ${{\color{Goldenrod}{ █▍ }}}$ 5.6%, 10.57 KB
dist/config/orderable ${{\color{Goldenrod}{ ▍ }}}$ 1.7%, 3.13 KB
dist/fields/baseFields ${{\color{Goldenrod}{ ▍ }}}$ 1.5%, 2.79 KB
dist/utilities/deepCopyObject.js ${{\color{Goldenrod}{ ▎ }}}$ 1.3%, 2.54 KB
dist/auth/cookies.js ${{\color{Goldenrod}{ ▏ }}}$ 0.8%, 1.55 KB
dist/utilities/flattenTopLevelFields.js ${{\color{Goldenrod}{ ▏ }}}$ 0.8%, 1.42 KB
dist/fields/config ${{\color{Goldenrod}{ ▏ }}}$ 0.7%, 1.29 KB
dist/utilities/getVersionsConfig.js ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 1.04 KB
dist/utilities/flattenAllFields.js ${{\color{Goldenrod}{ ▏ }}}$ 0.5%, 943 B
dist/utilities/unflatten.js ${{\color{Goldenrod}{ }}}$ 0.4%, 779 B
dist/utilities/sanitizeUserDataForEmail.js ${{\color{Goldenrod}{ }}}$ 0.4%, 713 B
dist/utilities/getFieldPermissions.js ${{\color{Goldenrod}{ }}}$ 0.3%, 651 B
dist/collections/config ${{\color{Goldenrod}{ }}}$ 0.3%, 570 B
dist/bin/generateImportMap ${{\color{Goldenrod}{ }}}$ 0.3%, 561 B
dist/auth/sessions.js ${{\color{Goldenrod}{ }}}$ 0.3%, 525 B
dist/fields/getFieldPaths.js ${{\color{Goldenrod}{ }}}$ 0.3%, 485 B
dist/utilities/appendDateTimezoneSelectFields.js ${{\color{Goldenrod}{ }}}$ 0.2%, 451 B
dist/utilities/getSafeRedirect.js ${{\color{Goldenrod}{ }}}$ 0.2%, 423 B
dist/utilities/deepMerge.js ${{\color{Goldenrod}{ }}}$ 0.2%, 413 B
(other) ${{\color{Goldenrod}{ █████▏ }}}$ 20.5%, 38.61 KB

Meta file: packages/richtext-lexical/meta_client.json, Out file: esbuild/exports/client_optimized/index.js

Path Size
dist/features/blocks ${{\color{Goldenrod}{ ███ }}}$ 12.4%, 37.36 KB
dist/lexical/ui ${{\color{Goldenrod}{ ██▊ }}}$ 11.4%, 34.16 KB
dist/lexical/plugins ${{\color{Goldenrod}{ ██▋ }}}$ 10.9%, 32.88 KB
dist/features/experimental_table ${{\color{Goldenrod}{ ██▎ }}}$ 9.0%, 27.16 KB
dist/packages/@lexical ${{\color{Goldenrod}{ █▌ }}}$ 6.3%, 18.99 KB
dist/features/link ${{\color{Goldenrod}{ █▌ }}}$ 6.3%, 18.81 KB
dist/features/toolbars ${{\color{Goldenrod}{ █▍ }}}$ 5.5%, 16.58 KB
dist/features/upload ${{\color{Goldenrod}{ █▏ }}}$ 4.7%, 14.09 KB
dist/features/textState ${{\color{Goldenrod}{ ▉ }}}$ 3.7%, 11.08 KB
dist/features/relationship ${{\color{Goldenrod}{ ▊ }}}$ 3.1%, 9.39 KB
dist/lexical/utils ${{\color{Goldenrod}{ ▋ }}}$ 2.9%, 8.79 KB
dist/features/converters ${{\color{Goldenrod}{ ▋ }}}$ 2.8%, 8.36 KB
dist/features/debug ${{\color{Goldenrod}{ ▋ }}}$ 2.5%, 7.40 KB
dist/utilities/fieldsDrawer ${{\color{Goldenrod}{ ▌ }}}$ 2.4%, 7.29 KB
dist/lexical/config ${{\color{Goldenrod}{ ▍ }}}$ 1.7%, 5.08 KB
dist/features/lists ${{\color{Goldenrod}{ ▍ }}}$ 1.7%, 5.00 KB
dist/features/format ${{\color{Goldenrod}{ ▎ }}}$ 1.2%, 3.46 KB
dist/lexical/LexicalEditor.js ${{\color{Goldenrod}{ ▎ }}}$ 1.1%, 3.23 KB
dist/features/horizontalRule ${{\color{Goldenrod}{ ▎ }}}$ 1.1%, 3.18 KB
dist/field/Field.js ${{\color{Goldenrod}{ ▏ }}}$ 0.9%, 2.84 KB
(other) ${{\color{Goldenrod}{ █████████████████████▉ }}}$ 87.6%, 263.53 KB

Meta file: packages/ui/meta_client.json, Out file: esbuild/exports/client_optimized/index.js

Path Size
../../node_modules ${{\color{Goldenrod}{ ███████████▋ }}}$ 46.7%, 579.57 KB
dist/elements/Hierarchy ${{\color{Goldenrod}{ ▉ }}}$ 3.5%, 43.77 KB
dist/elements/BulkUpload ${{\color{Goldenrod}{ ▌ }}}$ 2.3%, 28.06 KB
dist/views/HierarchyList ${{\color{Goldenrod}{ ▍ }}}$ 1.6%, 19.33 KB
dist/elements/Table ${{\color{Goldenrod}{ ▍ }}}$ 1.5%, 19.25 KB
dist/views/Edit ${{\color{Goldenrod}{ ▎ }}}$ 1.4%, 17.35 KB
dist/elements/WhereBuilder ${{\color{Goldenrod}{ ▎ }}}$ 1.4%, 17.27 KB
dist/forms/Form ${{\color{Goldenrod}{ ▎ }}}$ 1.3%, 15.92 KB
dist/fields/Relationship ${{\color{Goldenrod}{ ▎ }}}$ 1.2%, 15.48 KB
dist/fields/Blocks ${{\color{Goldenrod}{ ▎ }}}$ 1.2%, 15.12 KB
dist/fields/Upload ${{\color{Goldenrod}{ ▎ }}}$ 1.2%, 14.39 KB
dist/elements/QueryPresets ${{\color{Goldenrod}{ ▏ }}}$ 0.8%, 10.25 KB
dist/elements/PublishButton ${{\color{Goldenrod}{ ▏ }}}$ 0.7%, 9.01 KB
dist/elements/HTMLDiff ${{\color{Goldenrod}{ ▏ }}}$ 0.7%, 8.38 KB
dist/elements/LivePreview ${{\color{Goldenrod}{ ▏ }}}$ 0.7%, 8.21 KB
dist/views/List ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 8.02 KB
dist/elements/ReactSelect ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 7.84 KB
dist/fields/Array ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 7.76 KB
dist/elements/RelationshipTable ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 6.88 KB
dist/elements/Upload ${{\color{Goldenrod}{ ▏ }}}$ 0.5%, 6.61 KB
(other) ${{\color{Goldenrod}{ █████████████▎ }}}$ 53.3%, 662.55 KB

Meta file: packages/ui/meta_shared.json, Out file: esbuild/exports/shared_optimized/index.js

Path Size
dist/graphics/Logo ${{\color{Goldenrod}{ ███████▊ }}}$ 31.1%, 5.57 KB
../../node_modules ${{\color{Goldenrod}{ ███▋ }}}$ 14.8%, 2.65 KB
dist/graphics/Icon ${{\color{Goldenrod}{ ██▏ }}}$ 8.5%, 1.52 KB
dist/utilities/formatDocTitle ${{\color{Goldenrod}{ █▊ }}}$ 7.4%, 1.32 KB
dist/providers/TableColumns ${{\color{Goldenrod}{ █▏ }}}$ 4.8%, 866 B
dist/utilities/getGlobalData.js ${{\color{Goldenrod}{ █ }}}$ 4.2%, 762 B
dist/utilities/api.js ${{\color{Goldenrod}{ █ }}}$ 4.2%, 756 B
dist/utilities/groupNavItems.js ${{\color{Goldenrod}{ █ }}}$ 4.1%, 734 B
dist/elements/Translation ${{\color{Goldenrod}{ ▋ }}}$ 2.7%, 493 B
dist/utilities/handleTakeOver.js ${{\color{Goldenrod}{ ▋ }}}$ 2.5%, 440 B
dist/utilities/traverseForLocalizedFields.js ${{\color{Goldenrod}{ ▌ }}}$ 2.2%, 399 B
dist/elements/withMergedProps ${{\color{Goldenrod}{ ▍ }}}$ 1.9%, 339 B
dist/utilities/getNavGroups.js ${{\color{Goldenrod}{ ▍ }}}$ 1.9%, 338 B
dist/utilities/getVisibleEntities.js ${{\color{Goldenrod}{ ▍ }}}$ 1.8%, 329 B
dist/elements/WithServerSideProps ${{\color{Goldenrod}{ ▎ }}}$ 1.3%, 232 B
dist/utilities/handleGoBack.js ${{\color{Goldenrod}{ ▎ }}}$ 1.0%, 180 B
dist/fields/mergeFieldStyles.js ${{\color{Goldenrod}{ ▏ }}}$ 0.9%, 159 B
dist/utilities/handleBackToDashboard.js ${{\color{Goldenrod}{ ▏ }}}$ 0.8%, 152 B
dist/forms/Form ${{\color{Goldenrod}{ ▏ }}}$ 0.8%, 147 B
dist/utilities/abortAndIgnore.js ${{\color{Goldenrod}{ ▏ }}}$ 0.8%, 146 B
(other) ${{\color{Goldenrod}{ █████████████████▏ }}}$ 68.9%, 12.36 KB
Details

Next to the size is how much the size has increased or decreased compared with the base branch of this PR.

  • ‼️: Size increased by 20% or more. Special attention should be given to this.
  • ⚠️: Size increased in acceptable range (lower than 20%).
  • ✅: No change or even downsized.
  • 🗑️: The out file is deleted: not found in base branch.
  • 🆕: The out file is newly found: will be added to base branch.

@@ -0,0 +1,344 @@
'use client'
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Basic custom field. This is not the final design. Since access is now a json field instead of a group field, we just need something to replace the old ui.

@AlessioGr AlessioGr marked this pull request as ready for review May 23, 2026 04:13
@AlessioGr AlessioGr enabled auto-merge (squash) May 23, 2026 04:43
@jhb-dev
Copy link
Copy Markdown
Contributor

jhb-dev commented May 23, 2026

Great changes @AlessioGr!

I guess adding the missing parameters to the find tool is out of scope of this PR? #15880

@AlessioGr
Copy link
Copy Markdown
Member Author

Great changes @AlessioGr!

I guess adding the missing parameters to the find tool is out of scope of this PR? #15880

Yep! The remaining planned improvements + all open MCP issues like this one are on my radar and will be done as individual PRs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

plugin-mcp: schema eval returns "use strict" → convertedFields.partial is not a function when registering update tools

2 participants