MyronCMS Developers Hub Docs sandbox review

Start Here

Verify Your Extension

Use three layers of verification for a new extension:

  1. CLI substrate verification.
  2. Direct API action verification.
  3. MCP tool discovery and call verification.

The CLI check proves the extension system foundation. API and MCP checks prove the extension is usable inside a running install after registration, enablement, scope grants, and exposure.

Human Path

Run the local smoke test first:

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

For a hello-world extension, register the extension from the Extensions admin surface and grant content.read. Then call the action over /api/v1/x/{vendor}/... with a caller that holds content.read.

AI Path

An AI coding agent can run the CLI test from the repository and report failures against the local files. It can also prepare API or MCP requests for an operator-supplied local install.

An installed MCP client can verify only runtime-visible behavior. It can list and call tools exposed by registered actions, but it cannot author extension PHP files or grant itself scopes.

Verification

Complete verification in this order:

  1. Run the CLI smoke test locally.
  2. Confirm the extension is registered, enabled, and granted the required scope.
  3. Call the extension action through /api/v1/x/{vendor}/....
  4. Confirm the action appears in MCP tools/list for a scoped caller.
  5. Call the action through MCP tools/call.

If an earlier layer fails, fix that layer before interpreting later API or MCP results.

Scopes

The hello-world guide uses content.read. Verification needs that scope in two places:

  • the extension's granted scopes must include content.read,
  • the API or MCP caller must hold content.read.

If either gate is missing, the action should not be callable.

Artifacts

The main local verification artifact is:

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

That test creates an isolated SQLite database in the system temp directory, configures a local dev bearer token, boots MyronCMS, and verifies the extension foundation.

What The CLI Test Proves

verify-extension-system-foundation.php checks:

  • extension grant and load-error tables exist,
  • the sample manifest parses,
  • vendor mismatches are rejected,
  • unknown manifest scopes are rejected,
  • valid extension actions resolve,
  • invalid URI/domain/schema actions are rejected,
  • the sample extension can be registered and granted,
  • the loader mounts the sample admin route,
  • sample migrations create prefixed tables,
  • the sample action dispatches with a content.read token,
  • non-prefixed migration SQL is rejected,
  • bootstrap exceptions are recorded as load errors,
  • the Extensions rail section appears for administrators and is hidden from non-administrators.

The expected output is:

Extension system foundation verification passed.

API Verification

Use the direct API path after the extension is registered, enabled, and granted:

curl -sS \
  -H "Authorization: Bearer ${MYRON_TOKEN}" \
  "https://example.test/api/v1/x/my_vendor/hello"

The token must resolve to a caller with content.read. In local development, MyronCMS can accept MYRON_AI_DEV_BEARER_TOKEN when not in production mode; production installs should use an AI integration token or another supported authenticated caller path.

A successful response uses the action envelope:

{
  "ok": true,
  "result": {
    "message": "Hello from my_vendor extension",
    "siteType": "BIZ"
  },
  "error": null
}

Additional envelope fields such as actionId and auditEventId may also be present.

MCP Verification

Use MCP after the same runtime conditions are true:

  • extension is registered,
  • extension is enabled,
  • extension is granted required scopes,
  • action metadata has exposeToMcp: true,
  • MCP caller holds content.read.

Send tools/list to /mcp with the caller's Authorization header. For the hello-world tutorial, the default normalized tool name is:

x_my_vendor_hello_hello_get

Then call it with an empty argument object:

{
  "jsonrpc": "2.0",
  "id": "hello-1",
  "method": "tools/call",
  "params": {
    "name": "x_my_vendor_hello_hello_get",
    "arguments": {}
  }
}

The MCP server delegates the call through the same action dispatcher used by /api/v1/....

Failure Modes

SymptomLikely causeCheck
auth_requiredMissing bearer token or session caller.Send Authorization: Bearer ... or use an authenticated session path.
auth_invalidToken does not match an active integration, deployment token, or local dev token.Verify token source and environment mode.
scope_insufficientCaller lacks the action's required scope.Grant or use a caller with content.read.
action_not_foundNo registered action matches method and URI.Check extension registration, enablement, loader status, URI, and method.
Tool missing from tools/listAction is not exposed or caller lacks scope.Check exposeToMcp:true and caller scopes.
Manifest rejectedInvalid JSON, vendor mismatch, missing name/version, or unknown scope.Check manifest.json against ExtensionManifest.php.
Loader skips extensionExtension is unregistered or disabled.Check the Extensions admin surface.
Load error recordedBootstrap, migration, or manifest failure.Check Installed Extensions load error details.
Migration rejectedSQL touched a non-{vendor}_* table.Keep extension storage isolated.
Empty schema rejectedAction metadata used [] for input or output schema.Use object schemas, even for no-input actions.

Safety Boundary

Do not weaken verification to make a failing extension pass. If the failure requires new runtime behavior, stop and route the work through Evaluate and Contract before expanding the SDK.