MyronCMS Developers Hub Docs sandbox review

Core Concepts

Scopes And Grants

Scopes are the permission vocabulary shared by human/admin workflows, AI bearer callers, API dispatch, MCP discovery, and extension loading.

An extension must pass two layers of scope control:

  1. The extension must be registered, enabled, and granted the scopes declared in its manifest.
  2. The API or MCP caller must hold the action's required scope at call time.

Base Extension Scopes

Extension manifests can request only these six base scopes:

ScopeUse
design.readRead design surfaces.
design.writeMutate design surfaces.
content.readRead content surfaces.
content.writeMutate content surfaces.
administration.readRead administration surfaces.
administration.writeMutate administration surfaces.

Scopes.php also contains scopes used by other platform areas, but ExtensionManifest.php and ExtensionScopeGrantRepository.php restrict extension manifests and extension grants to the six base scopes above.

Human Path

An operator registers a locally installed extension from the Extensions admin surface:

/extensions/register

The operator provides:

  • vendor,
  • name,
  • version,
  • granted scopes.

Installed extensions are reviewed from:

/extensions

That surface shows enabled/disabled state, granted scopes, load health, and latest load errors. It also lets an administrator enable, disable, or revoke individual scopes.

AI Path

The grant workflow is human-admin-only in extension v1. An installed MCP client cannot grant itself scopes, enable an extension, or revoke the trust gate that controls it.

An AI coding agent working locally can author the manifest and action metadata. After the operator grants scopes and enables the extension, an installed API or MCP client can call exposed actions only when its caller context also holds the action's required scope.

The Scope Gates

GateSourceEffect
Manifest requiredScopesmanifest.jsonDeclares what the extension needs to load safely.
Operator grant rowextension_scope_grantsRecords allowed scopes and enabled state for a vendor.
Loader grant checkExtensionLoader::isGranted()Skips unregistered or disabled extensions and rejects under-granted extensions.
Action requiredScopeMyronActionMetadataDeclares the caller scope needed for one action.
API dispatcher caller scopeActionDispatcher through caller contextRejects calls when the caller lacks the action scope.
MCP tools/list filterServer.phpLists only exposed tools the caller scope can invoke.

The gates are additive. Passing one does not bypass the others.

MCP Discovery

MCP tool listing is filtered by:

  • exposeToMcp: true,
  • the caller's held scopes.

If an action is valid and API-callable but exposeToMcp is false, it should not appear in MCP tools/list. If the caller lacks the required scope, the tool should also be omitted for that caller.

Failure Modes

SymptomLikely cause
Extension is absent from runtime actionsVendor was not registered, extension is disabled, or loader skipped it.
Load error mentions ungranted scopeManifest requested a scope that the operator did not grant.
API returns auth_requiredRequest has no valid session or bearer caller.
API returns auth_invalidBearer token or session caller is invalid.
API returns scope_insufficientCaller lacks the action's required scope.
MCP tool missingAction is not loaded, exposeToMcp is false, or caller lacks scope.
Scope revoke makes a previously working extension failThe manifest still requires a scope no longer granted.

Safety Boundary

Do not document trust-granting as MCP self-service. Grant creation, enable/disable, and revocation are operator/admin workflows. If a future contract introduces an API or MCP route for privileged administration, it must be evaluated as a separate safety decision.

Verification

Run the foundation test:

php app/tests/verify-extension-system-foundation.php

For runtime verification, call an extension action with a caller that holds the action scope, then repeat with a caller that lacks it. The scoped caller should succeed; the under-scoped caller should fail or see no MCP tool.