Docs Plugins

Plugins

Use a plugin when you want to add ready-made mocks, integrations, or other content to Mockarty. For example, a mock kit can give your team a payment provider’s test API without creating every mock by hand. Plugins are .zip bundles; some also contain sandboxed code or interface panels. Administrators can install them for the instance, while namespace owners can install selected no-code plugins for their own space.

You can install a bundle from a file in an offline environment. This guide covers installation and use. If you are writing a plugin, see Writing plugins; for cluster and security settings, see Plugin operations.

Installing a plugin

You need an administrator account.

Web UI: Admin panel → Plugins tab → Install plugin… → pick the .zip file, or Install from URL… → paste a link to a .zip (optionally its sha256 to pin the exact bytes). The plugin appears in the list disabled; press Enable to activate its contributions.

CLI:

mockarty-cli plugin install ./acme-kit.zip                    # from a local file
mockarty-cli plugin install https://example.com/acme-1.0.0.zip  # from a URL
mockarty-cli plugin install https://example.com/acme-1.0.0.zip --sha256 <hex>  # pin the bytes
mockarty-cli plugin enable acme.demo-kit
mockarty-cli plugin list

REST:

curl -X POST http://localhost:5770/api/v1/plugins \
  -H "X-API-Key: $TOKEN" \
  -F bundle=@acme-kit.zip
# or install from a URL (server downloads it; add "sha256" to pin the bytes):
curl -X POST http://localhost:5770/api/v1/plugins/install-url \
  -H "X-API-Key: $TOKEN" -H 'Content-Type: application/json' \
  -d '{"url":"https://example.com/acme-1.0.0.zip"}'
curl -X POST http://localhost:5770/api/v1/plugins/acme.demo-kit/enable \
  -H "X-API-Key: $TOKEN"

Once enabled, the plugin’s mock kits show up in the Mock Kits catalogue (UI, REST and the built-in AI tools) and can be instantiated like any built-in kit. Disabling a plugin removes its kits from the catalogue; mocks you already created from them stay and remain editable.

Installing into your own namespace

When an administrator has enabled it (Admin → Plugins), a namespace owner can install plugins without an administrator — from Settings → Extensions. Pick a marketplace visible to your namespace, find a plugin, press Install. Such a plugin:

  • works only inside your namespace — other teams never see its content;
  • must be pure no-code (mock kits, content packs, wiki macros, link types, connector presets). Bundles with WASM modules, interface panels, event types or task types are refused with a clear error — those still need an administrator;
  • can be removed by you at any time from the same tab (content already created from it stays), and administrators always see and can remove it too.

If you switch the namespace in Settings, the marketplace list and plugin catalogue reload for the newly selected namespace.

If no marketplace is configured, this tab says so and offers Add marketplace… to a namespace editor. Enter the name and the URL of that marketplace’s index.json. A system administrator can also open Administration → Plugins from the same empty state to upload a .zip bundle for the whole instance. The Built-in registry choice appears only when an administrator configured one for this instance; it is not an included online catalogue.

GET /api/v1/marketplace/sources?namespace=<namespace> returns the configured sources and the caller’s canManageNamespace and canManageGlobal permissions. An empty sources array means there is no source to browse. Adding a namespace source uses POST /api/v1/marketplace/sources with name, url and namespace; the server checks namespace write access and validates the registry URL before saving it.

The same flow is available to AI agents over MCP: marketplace_catalog (look for nsInstall: true), plugin_ns_install, plugin_ns_uninstall.

Asking an administrator for a plugin

Some plugins can only be installed by an administrator: they run code inside the shared instance, so they are installed once for everyone. In Settings → Extensions such a plugin is marked Admin install only, and next to it there is an Ask an administrator button.

  1. Press Ask an administrator.
  2. Say what you need the plugin for. This field is required — the administrator decides on what you write here, so be specific: which service you want to test and why the plugin helps.
  3. Press Send request.

Your requests then appear under Your requests on the same tab, with their state and the administrator’s answer:

State What it means
waiting for an answer the administrator has not answered yet; you can Withdraw the request
approved — installation pending the administrator agreed; the plugin appears once they install it
declined the answer next to the request says why
installed the plugin is installed
withdrawn you took the request back

A namespace can have one pending request per plugin. Asking again for the same plugin is refused until the first request is answered or withdrawn.

Only a namespace owner can send, see and withdraw requests.

For administrators. Open the admin panel → Plugins tab. The Requests from namespaces section lists the requests that are waiting for an answer, oldest first: the plugin, its version, the namespace that asked and the reason it gave. Press Approve or Decline and write an answer — the namespace owner sees it. Declining requires a reason.

Approving only records your decision. It does not install anything: install the bundle yourself with the install buttons on the same tab (Install plugin…, Install from URL…, or the one-click install in Available from registry), then enable it.

REST. A namespace owner files a request (reason is required; version and source are optional):

curl -X POST http://localhost:5770/api/v1/namespaces/team-a/plugin-install-requests \
  -H "X-API-Key: $TOKEN" -H 'Content-Type: application/json' \
  -d '{"plugin_id":"acme.ru-fakers","version":"1.0.0","reason":"We need Russian INN and SNILS values in the payment mocks"}'

The answer contains the new request with its id and "state": "pending". GET on the same address lists the namespace’s requests, and POST .../plugin-install-requests/<id>/withdraw withdraws a pending one.

An administrator reads the queue with GET /api/v1/plugin-install-requests?state=pending and answers a request ($REQUEST_ID is the id from the queue):

curl -X POST "http://localhost:5770/api/v1/plugin-install-requests/$REQUEST_ID/decide" \
  -H "X-API-Key: $TOKEN" -H 'Content-Type: application/json' \
  -d '{"state":"rejected","note":"Not yet: this plugin runs code our security team has not reviewed. Ask again after the review."}'

state is approved, rejected or installed. A note is required for rejected. A request is answered once; installed is accepted only on a request that was approved, and marks it as done after you have installed the bundle.

AI agents drive the same flow over MCP: plugin_install_request_create, plugin_install_request_list and plugin_install_request_withdraw for a namespace owner; plugin_install_request_queue_list and plugin_install_request_decide for an administrator.

Ready-made packs

Five packs ship with the product as reference examples. Each one extends several
parts of Mockarty at once — which is the point: a package can prepare a whole
way of working, not just one mechanism.

Pack What it prepares Runs code?
GitLab dev/test kit a GitLab API v4 contour — projects, merge requests with approvals and conflicts, pipelines, jobs, issues, registry — including pagination, rate limits and the error codes integrations trip over no
Atlassian teamwork pack Jira and Confluence connections, a starter project, a team wiki space, migration acceptance cases, deep links back to the originals, an issue-badge macro no
Agent SDLC pack the knowledge an autonomous tester reads, a project shaped like the loop it follows, a smoke suite, two runnable task types, events for “asked for review” and “filed a defect” no
Community connectors (n8n import) nine pre-filled connections converted from n8n community nodes, with every credential held as a reference to your secret store no
Performance worker (runtime reference) source and a build manifest showing the managed-worker package contract; native task dispatch is not available yet not as a task handler

Each pack ships with a README that says what it does and what it does not
do
. Read that before installing: a pack prepares a shape, it does not migrate
your data for you.

The declarative packs install like any other bundle. The performance worker is
an authoring/runtime reference, not evidence of a working task-dispatch path.
It ships as source with a build script because a program’s identity is the
checksum of the bytes that were actually built — see the pack’s README.

Writing a plugin

Scaffold, edit, package, install:

mockarty-cli plugin create my-plugin
# edit my-plugin/plugin.json
cd my-plugin && zip -r my-plugin.zip plugin.json README.md
mockarty-cli plugin inspect my-plugin.zip   # offline validation
mockarty-cli plugin install my-plugin.zip

plugin.json describes the plugin and what it contributes:

{
  "id": "acme.demo-kit",
  "name": "ACME demo kit",
  "version": "1.0.0",
  "description": "Mocks for the ACME partner API.",
  "author": {"name": "ACME", "url": "https://acme.example"},
  "contributes": {
    "mock_kits": [
      {
        "key": "acme_partner",
        "name": "ACME partner API",
        "mocks": [
          {"route": "/partner/ping", "method": "GET", "status_code": 200, "body": {"ok": true}}
        ]
      }
    ]
  }
}

Rules worth knowing:

  • id is a lowercase slug (letters, digits, ., _, -) and is permanent — installing a bundle with the same id upgrades the plugin in place.
  • version is semver. Optional min_mockarty_version blocks installation on servers that are too old.
  • Kit keys must not clash with built-in kits or other enabled plugins — enabling reports a clear conflict error if they do.
  • Unknown contribution types are rejected at install time, so a typo never turns into a silent no-op.

Code extensions (WebAssembly)

Beyond ready-made content, a plugin can contribute small pieces of logic as a
WebAssembly (.wasm) module. The module runs in a strict sandbox: it cannot
touch the filesystem, the network or the clock, and every call is bounded by a
time and memory budget. This is what a bank or government security officer needs
to hear — a code plugin can do nothing the host did not explicitly allow.

The first extension point is custom faker providers. A module implements a
function that receives {"name":"<faker>"} and returns {"value":"<string>"},
and the manifest binds it to the faker names it provides:

{
  "id": "acme.ru-fakers",
  "name": "Russian data fakers",
  "version": "1.0.0",
  "contributes": {
    "wasm": [
      {
        "point": "faker-provider",
        "module": "fakers.wasm",
        "fn": "faker",
        "exports": ["ru_inn", "ru_snils", "ru_ogrn"]
      }
    ]
  }
}

Once the plugin is enabled, a mock response template can use the new faker like
any built-in one:

{ "inn": "$.fake.ru_inn" }

Package the .wasm file alongside plugin.json in the bundle. The module must
export memory, mk_alloc(size) and your function; any language that compiles
to WebAssembly (Rust, Go/TinyGo, AssemblyScript, C) can produce one.

Programs a plugin brings with it

WebAssembly covers small pieces of logic. Some things need more: a native
library, a protocol stack, a scanner, a load-testing extension. For those a
plugin package can carry its own program — a managed worker.

The current release provides the local lifecycle foundation: on Desktop and an
explicit local/single-node placement, Mockarty picks the build for the host,
checks its declared checksum, starts it, health-checks it, bounds crash restarts,
and stops it on disable, rollback, revocation or uninstall.

Mockarty gives the program its own worker credential and connection settings.
Removing, disabling or rolling back the plugin withdraws that credential.
A managed worker can be started and supervised, but plugin task dispatch is
not available yet.
Installing one does not make its declared task types
executable; queue and in-flight counters on its card stay at zero.

On a multi-node cluster this is refused instead: see
Where a program is allowed to run below.
Declarative and sandboxed WASM plugins are unaffected by that limit.

Because this is the most powerful thing a package can ask for, it is also the
most visible:

  • the manifest must request the runtime:managed-worker permission — a package
    that ships a program without asking is refused;
  • the install preview shows a managed worker badge, the platforms the
    package ships, and the limits the worker will run under;
  • if your server has no build for its platform, or your instance is configured
    not to run these at all, the preview says so before anything is written —
    you never end up with something installed that could never start.

The package contract reserves the task types and resource envelope a future
dispatch path will use:

{
  "contributes": {
    "task_types": [
      { "type": "plugin-acme-scan", "name": "ACME scan", "description": "Runs the ACME scanner" }
    ],
    "workers": [
      {
        "key": "scanner",
        "name": "ACME scanner",
        "task_types": ["plugin-acme-scan"],
        "limits": { "max_concurrent": 4, "memory_mb": 1024, "queue_depth": 50 },
        "health": { "path": "/healthz", "timeout_seconds": 30 },
        "artifacts": [
          { "os": "linux",  "arch": "amd64", "path": "bin/scanner-linux-amd64",  "sha256": "…" },
          { "os": "darwin", "arch": "arm64", "path": "bin/scanner-darwin-arm64", "sha256": "…" }
        ]
      }
    ]
  },
  "permissions": ["runtime:managed-worker"]
}

A worker may only name task types the same package declares. If you leave the
limits out, Mockarty records conservative values rather than “unlimited”.
Mockarty passes the concurrency limit to the program. Task dispatch is not yet
available for managed workers; the queue depth is recorded for future use. The
memory figure is handed to the program as its budget — Mockarty does not impose
an operating-system ceiling on it, so treat it as the contract your program is
expected to keep, and the preview you see before installing says so.

The program starts in its own folder — the one its build was unpacked into — and
receives only the settings Mockarty gives it, never the server’s own
environment. Use absolute paths for anything outside that folder.

What happens when a worker misbehaves

A program from outside will eventually crash, and a plugin that cannot start
must not be able to cost you a server. Mockarty bounds it:

  • a failed start waits before the next attempt, and each further failure waits
    longer, so a broken worker never spins;
  • after several failures in a row it is marked stopped after repeated
    failures
    and left alone until a cooldown passes, with the reason on the card
    in Admin → Plugins;
  • an upgrade whose worker never becomes ready is rolled back to the version you
    were running.

Admin → Plugins shows each worker’s state (ready, starting, restarting, stopped)
next to its plugin.

Storage

The programs a package ships are kept once per distinct build, so two versions
that produce the same binary do not store it twice, and the version you can roll
back to keeps its own. When an extension is uninstalled its programs become
reclaimable; Admin → Plugins can free them.

Where a program is allowed to run

Mockarty decides this from what the installation IS, not per package, and it
decides conservatively — a package declares a program, an operator decides
whether this machine runs one at all:

Installation Default What an operator sees
Desktop, or a single server the program runs as a child process of Mockarty installs and starts normally
A multi-node cluster no program is run an extension that ships one is refused at install, with that reason

The cluster default is deliberate: Mockarty nodes are replaceable, so a
long-lived program started inside one of them would live and die with whichever
node happened to host it. If your cluster genuinely should run one, say so
explicitly with the setting below — Mockarty then starts exactly one copy,
on the node currently leading, rather than one per node.

Three settings are available to an operator:

  • MOCKARTY_EXTENSION_WORKER_PLACEMENT — local runs programs on this machine,
    disabled never runs one. Anything else is rejected and treated as
    disabled, so a typo can never widen what runs. Extensions that ship a
    program are refused at install with the exact reason; everything else keeps
    working.
  • MOCKARTY_EXTENSION_WORKER_CACHE_DIR — where verified programs are kept
    (default: extension-workers inside your data directory). The directory must
    be writable and executable by Mockarty.
  • MOCKARTY_EXTENSION_ARTIFACT_QUOTA_MB — the total these programs may occupy
    (default 4096). Past it, an install is refused with what is used and what was
    asked for.

Whose program is allowed to run

Where a program runs and who wrote it are two separate questions. A bundle can
be signed by a publisher whose key you imported, or by nobody at all — and until
you say otherwise, both are treated the same way.

MOCKARTY_EXTENSION_NATIVE_TRUST is the answer for programs specifically. It
does not affect extensions that only add data (mock kits, link types, content
packs) — those run no program of their own, so tightening this setting never
takes them away.

Value What happens to an extension that ships a program
unset, or warn it runs, and Mockarty tells you — in the install preview and in the log — that it cannot say who wrote it
signed-only it runs only if the bundle was signed by a publisher you trust when it was installed; otherwise it is refused, at install and again on every restart
explicit-unsafe it runs with no warning: you have recorded that this machine accepts programs it cannot attribute

Anything else is rejected and treated as signed-only, so a typo can never
widen what runs. signed-only also stops a program that was installed before
you tightened the setting — the check runs every time Mockarty decides what
should be running, not only at install. It judges who signed the package when
it was installed
: retiring a publisher’s key stops new installs from that
publisher, and does not stop a package you are already running. To stop a
package you already run, use a security advisory.

To trust a publisher, import their trust bundle:

mockarty-cli plugin trust import acme-publisher.json
mockarty-cli plugin trust list

The install preview then names the publisher instead of warning that the
package is unattributed.

Interface panels

A plugin can add its own screen to Mockarty. Declare a sidebar item that opens
a panel; the panel is an HTML page shipped inside the bundle and shown in a
sandboxed frame — it runs its own markup but cannot reach the host page or your
session.

{
  "id": "acme.dashboard",
  "name": "ACME dashboard",
  "version": "1.0.0",
  "contributes": {
    "ui": [
      {
        "point": "sidebar",
        "id": "acme-dash",
        "title": "ACME Dashboard",
        "icon": "chart-bar",
        "panel": "dashboard.html"
      }
    ]
  }
}

icon is a Heroicon id (without the hi- prefix); panel is a bundle-relative
HTML file. Ship the HTML plus any CSS, JS or images it needs (as bundle assets).
When the plugin is enabled, the sidebar shows the item for every user; clicking
it opens the panel.

Permissions

Capabilities that go beyond what the bundle itself ships must be declared in
the manifest’s permissions list, so the administrator reviews them before
installing. The rules are strict:

  • an unknown permission key is refused at install — a capability this Mockarty
    does not understand can never be silently “approved”;
  • a contribution that needs a permission installs only when the manifest
    declares it.

Currently enforced permission:

Key What it allows
ui:external-panel Load a panel from your own external https origin (panel_url instead of a bundled panel) and receive the plugin’s namespace settings values in it.

Example — an externally hosted panel:

{
  "id": "acme.board",
  "name": "ACME board",
  "version": "1.0.0",
  "permissions": ["ui:external-panel"],
  "contributes": {
    "ui": [
      { "point": "sidebar", "id": "board", "title": "Board", "panel_url": "https://plugins.acme.com/board" }
    ]
  }
}

Without the permission the install is refused with a message naming exactly
what to add. Bundled panels need no permission — the reviewed bundle is the
consent.

Keys with the connect: prefix (for example connect:read) come from imported
Atlassian Connect descriptors. They are informational provenance — they show
what the original app requested and grant nothing in Mockarty.

Where a package came from

A manifest may declare how the bundle was built and what went into it:

{
  "provenance": {
    "source_url": "https://github.com/acme/mockarty-plugins",
    "source_revision": "9f2c1ab",
    "built_at": "2026-08-24T10:00:00Z",
    "builder": "GitHub Actions",
    "build_command": "mockarty-cli plugin pack ./acme-kit"
  },
  "sbom": [
    { "name": "leftpad", "version": "1.2.3", "license": "MIT" }
  ]
}

Both blocks are shown wherever the package is reviewed, and both are what the
author says
— Mockarty checks that the fields are usable (a source link opens,
a timestamp parses, a component has a version) but does not verify the claims
themselves. What is verified sits right next to them: the signature and the
publisher it belongs to. Read together, they answer “who says this, and is it
really them”.

Publishers and signing keys

Mockarty verifies a signed bundle against the publisher keys it trusts, and
records which key signed each installed plugin — so the Plugins list can
show a publisher name, not just “signed”.

Trust anchors arrive as a file, the same way advisories do:

mockarty-cli plugin trust import acme-trust.json            # unsigned
mockarty-cli plugin trust import acme-trust.json acme.sig   # signed by a key you already trust
mockarty-cli plugin trust list
mockarty-cli plugin trust retire <key-id>

The bundle looks like this:

{
  "kind": "mockarty/plugin-trust",
  "version": 1,
  "publishers": [
    { "name": "ACME", "keys": [ { "publicKey": "<base64 ed25519 public key>" } ] }
  ]
}

Things worth knowing:

  • a key’s id is derived from the key itself, so a bundle can never label
    someone else’s key with a well-known publisher’s id;
  • retiring a key is forward-blocking: new installs signed by it stop being
    trusted, while plugins already installed keep running untouched. To stop
    something that is already running, import a revocation (below);
  • a trust bundle signed by a key you already trust is accepted — that is
    how a publisher rotates keys without you hand-carrying the new one;
  • keys from MOCKARTY_PLUGINS_TRUSTED_KEYS keep working and appear in the list
    under the publisher name environment.

Security advisories and revocations

Mockarty can hold a list of known-bad plugin versions. The list is a JSON
file you import — an air-gapped instance uses exactly the same path as a
connected one, so there is no online-only security story:

mockarty-cli plugin advisories import advisories.json           # unsigned
mockarty-cli plugin advisories import advisories.json advisories.json.sig
mockarty-cli plugin advisories list

Each entry names a plugin, the affected versions, a severity and a summary:

{
  "kind": "mockarty/plugin-advisories",
  "version": 1,
  "advisories": [
    { "id": "ACME-2026-001", "pluginId": "acme.kit", "severity": "high",
      "summary": "What is wrong and what to do about it.", "revoked": true,
      "affected": { "versions": ["1.0.0", "1.0.1"] } }
  ]
}

An entry must say which versions it affects — list them in versions, give
minVersion/maxVersion bounds, or say "affected": {"allVersions": true} when
the whole plugin is affected. A file that names nothing is refused on import,
so a truncated or half-generated feed cannot quietly block every release of a
plugin — including the fixed one you were about to install.

Two kinds:

  • revocation ("revoked": true) — the matching versions can no longer be
    installed or enabled, and an already-enabled match is shown as unhealthy with
    the advisory text, so you decide what to do with it;
  • advisory (the default) — informational only; it never blocks work.

If the instance requires signed plugins, an unsigned advisory file is refused:
the list that decides what to block may not arrive through a weaker channel
than the plugins it judges.

Updating and rolling back

Installing a bundle with the same id updates the plugin in place, keeping its
enabled state and settings. Two safeguards come with that:

  • Downgrade protection. A bundle whose version is older than the
    installed one is refused, so a stale file re-uploaded by accident cannot
    quietly replace a newer plugin. Repeat the install with “allow downgrade”
    (UI), --allow-downgrade (CLI) or "allow_downgrade": true (API) when you
    mean it.
  • Roll back. Every update stores the bundle it replaced. Administration →
    Plugins shows Roll back for a plugin that has one, and
    mockarty-cli plugin rollback <plugin-id> does the same from a terminal.
    The stored bundle is validated exactly like a fresh install, so a rollback
    that would break another plugin depending on it is refused with the reason.

After a rollback the slot holds the version you rolled back from, so rolling
forward again is one more click. Uninstalling a plugin clears its slot.

Catalogues mark update available only when the published version is
genuinely newer by semantic versioning — a differing version string alone is
never presented as an update.

Dependencies and compatibility

A plugin may require other plugins and bound the Mockarty versions it
supports:

{
  "id": "acme.reports",
  "name": "ACME reports",
  "version": "1.0.0",
  "min_mockarty_version": "2.0.0",
  "max_mockarty_version": "3.0.0",
  "dependencies": [
    { "id": "acme.base-kit", "min_version": "1.2.0" }
  ]
}

Rules:

  • a dependency must already be installed (and visible to the installing
    namespace) at the required version — the install error names exactly what to
    install first; nothing is downloaded automatically;
  • a plugin that others depend on refuses to uninstall until the dependents are
    removed (disabling it is still allowed);
  • a host newer than max_mockarty_version refuses the install — publish an
    updated build instead of letting it break at runtime. Hosts older than the
    version that introduced these fields ignore them, so pair dependencies
    with a matching min_mockarty_version.

Secrets and connections in settings

Plugin settings are configuration, never credentials. When your plugin needs a
secret or an existing integration, declare the field as a typed reference in
settings_schema:

{
  "type": "object",
  "properties": {
    "api_token": { "type": "string", "format": "mockarty-secret-ref", "title": "API token" },
    "tracker":  { "type": "string", "format": "mockarty-connection-ref", "title": "Tracker connection" }
  }
}

The stored value is then a pointer — secret://<store>/<entry> (an entry
created in Stores → Secrets) or connection://<integration-id> (an
integration from Settings → Integrations). A raw credential does not fit the
shape and is refused on save, so a secret can never be persisted in plugin
settings. Panels and the settings API only ever see the reference.

Signing plugins

Signing is optional by default and can be made mandatory for hardened environments.

mockarty-cli plugin keygen --out orgkey          # orgkey (private) + orgkey.pub
mockarty-cli plugin sign my-plugin.zip --key orgkey
mockarty-cli plugin inspect my-plugin.zip        # prints signature status

On the server:

  • MOCKARTY_PLUGINS_TRUSTED_KEYS — comma-separated base64 public keys the server trusts (for example, your security team’s key).
  • MOCKARTY_PLUGINS_REQUIRE_SIGNATURE=true — refuse to install any bundle that is unsigned or signed by an untrusted key.

The signature covers the bundle’s content, and the verification result (unsigned / trusted / untrusted) is stored with the plugin and written to the audit log.

Plugin registry

A registry is a published index.json that lists installable plugins (for example, a GitHub repository with the bundles attached to releases). Mockarty does not contact an external registry by default. Configure one explicitly when you want the Plugins tab to offer remote packages; local bundle installation remains available without it.

Enable a public or internal registry:

export MOCKARTY_PLUGINS_REGISTRY_URL=https://raw.githubusercontent.com/your-org/mockarty-plugins/main/index.json

To disable a registry value supplied by the surrounding deployment:

export MOCKARTY_PLUGINS_REGISTRY_URL=off

With a registry configured:

  • the Plugins tab shows an Available from registry section with one-click install;
  • mockarty-cli plugin search [query] lists what is published;
  • mockarty-cli plugin install <plugin-id> installs by name;
  • downloads are verified against the sha256 recorded in the index before anything is installed.

To publish your plugin, prepare its index entry and open a pull request to the registry repository:

mockarty-cli plugin publish my-plugin.zip \
  --download-url https://github.com/your-org/mockarty-plugins/releases/download/my-plugin-v1.0.0/my-plugin.zip

The generated entry includes namespace_installable — whether a namespace
owner may self-install the bundle (pure no-code content) or an administrator
must install it (it carries WASM modules, UI panels, event types or task
types). Catalogues use it to show the correct action up front instead of
failing after the Install click.

Turning plugins off completely

MOCKARTY_PLUGINS_ENABLED=false removes the whole mechanism: no plugin API routes, no Plugins tab, no AI tools for plugins. Use it in environments where third-party content is not allowed.