PMA is more than the sum of its open-source parts. This essay covers the emergent properties — what becomes possible once 15+ services are wired together as a coherent platform, with manifests, atomic releases, machine-readable runbooks, and an AI-friendly operator surface. Written for evaluators and operators who want to understand why PMA is qualitatively different from "I installed Docker containers and hope for the best".
PMA is often pitched as a cost-cutting SaaS replacement:
"ASD-PMA integreert zes best-in-class open source platforms tot
één naadloze business suite. Waar grote bedrijven tienduizenden
euro's per maand betalen aan Salesforce, Jira en SAP, draait u
dezelfde functionaliteit op uw eigen infrastructuur — voor een
fractie van de kosten."
That positioning works for one buyer (the cost-conscious MKB owner)
but misses the magic. The €21.600/year SaaS-savings table is
true, but it's a feature any open-source stack offers. PMA's actual
magic is operational — what becomes possible after the cost
argument has done its job.
This essay collects the magic that doesn't fit on a sales sheet.
PMA's killer trick is that adding a service is adding a YAML
file. The framework reads it and the rest happens.
packages/<svc>/manifest.yaml declares: container, ports, DB,packages/<svc>/net.manifest.yaml declares the route.tpl.env declares the env-var template.The wow moment: look at the framework code — if service == "redmine" does not exist anywhere. Adding a 16th service does not
mean editing any framework code. The framework is a generic
machine; packages are interchangeable parts.
Hook: "Add a service by writing one YAML file. There is no
step two."
just release-run TICKET is the only operator entry point. Behind
it: prepare (git fetch + ff-pull + BASE_SHA capture + per-service
backup) → migrate (regenerate compose + run migrate.sh) → ticket-
script (per-ticket migrations) → verify (drift check + health
gate). Halt-on-failure between every phase.
If any phase fails, just release-revert TICKET restores the
backups taken in phase 1 and reverts the merge commit. Single
command rollback, no per-deploy snapshot to remember.
The wow moment: there is no "I broke prod and now I'm
manually un-doing migrations" story in PMA's incident log. The
revert is mechanical.
Hook: "release-run and release-revert are the only deploy
verbs. Everything else is a sub-script."
recovery/playbooks/*.yaml files map: symptom → detection commands
→ root cause → fix script → verify command. Structured so a
Haiku-class AI agent can read a JSONL failure log, look up the
matching playbook, execute the fix, and verify.
The pattern: every bootstrap fix MUST come with a playbook entry.
The playbook is committed alongside the fix in the same PR. Three
days from now nobody has to remember why the fix was needed —
it's encoded.
The wow moment: "we know how to recover from this" is itself
a file in the repo. Tribal knowledge doesn't exist in PMA.
Hook: "Every incident leaves a playbook. The next incident is
shorter."
Adding a service with sso.type: oauth (or oidc, saml,
proxy, wikijs, frappe) in its manifest gets it Authentik
integration with no per-service config. The bootstrap reads
manifest → discovers SSO type → calls the right generic flow → the
service joins the SSO realm.
The wow moment: log in to Redmine, click over to Mattermost,
already logged in. Click to ERPNext, logged in. Wiki.js, logged
in. Each service was a separate auth nightmare last year; this
year it's a manifest field.
Hook: "One Authentik login. Fifteen services. Zero per-service
SSO config."
PMA ships an MCP server (claude_ai_PMA) that exposes:
A Claude / GPT / agent can run mcp__claude_ai_PMA__redmine_create_ticket
and it's a real ticket in real Redmine, with proper attribution to
the AI agent via X-Redmine-Switch-User.
The wow moment: the AI agent participating in the team's
ticket flow isn't a hack — it's a first-class operator with its own
identity, audit trail, and permission scope.
Hook: "Your AI agent gets a Redmine login, a Zammad seat, and
write access to your services — through the same gateway your
humans use."
ASD_ENV=dev and ASD_ENV=prod can coexist on the same machine.
Container names get an env-suffix (asd-dev-redmine, asd-prod-redmine),
ports are isolated, Caddy serves both. just bootstrap-local minimal vs43 clones a fresh /opt/pma-vs43 and bootstraps it without
touching /opt/pma-vs42.
The wow moment: a single beefy laptop runs five separate
PMA installations simultaneously — for testing migrations, validating
new packages, demoing customer-specific configs, all without
docker-compose port-juggling.
Hook: "Five PMA environments on one laptop. Five different
demos. One copy of the framework."
A profile is a named subset of services:
development — n8n, mattermost, redmine, wikijsenterprise — development + erpnext, zammad, superset, redashsupport — n8n, mattermost, zammad, espocrmdata — n8n, redash, supersetfull — all non-experimentaldocker-compose.yml is generated from the active profile, so
small projects pay no Docker overhead for services they don't use.
The wow moment: customers running PMA-data (BI-only) and PMA-
support (CRM-only) get clean, minimal stacks. Same codebase, same
release pipeline, completely different service set.
Hook: "Same codebase, ten profiles, ten different products."
backup.enabled: true + backup.type: database + backup.database.name
in a manifest, and the service is included in the standard backup
flow. Restore reads the same manifest. restore_service.py walks
through fixes.post_restore.functions to handle service-specific
quirks (unlocking migration tables, regenerating session keys,
chowning the data volume).
The wow moment: "we need to back up the new service" is a
checkbox in the manifest, not a script that someone has to remember
to write.
Hook: "Backup and restore are properties of the service, not
the operator."
just contract-generate produces an in-memory snapshot of every
command and every package. Pre-commit hooks fail if your change
broke the contract. Pre-push verifies consistency. CI runs the
full bootstrap E2E. The contract is what the MCP server exposes
to AI agents.
The wow moment: you can't accidentally rename a just recipe
without the framework noticing and stopping you.
Hook: "The contract is enforced at three layers — pre-commit,
pre-push, CI. Drift dies in code review."
Every package's health.endpoint is checked by
dynamic-service-checks.ts. The check code knows nothing about
the service — it reads the manifest and probes. Adding a 16th
service adds zero lines to the health-check code; the manifest is
enough.
The wow moment: the framework's testing code is less code
than the services it tests, because the services describe
themselves.
Hook: "The service describes how to test it. The framework
does the testing."
PMA has 200+ just recipes. The naming is consistent
(<service>-status, <service>-restart, <service>-logs,
<service>-create-user, <service>-list-users). The pattern is so
predictable that an AI agent can guess the right recipe without
help text — and if it guesses wrong, just symbols "keyword" finds
the right one.
The wow moment: the documentation of every service is the
service's recipe list. No separate "operations manual" lives in
Confluence.
Hook: "Type just. Tab. Read. Choose. Run. The whole operator
surface is one tab-complete away."
PMA has a formal protocol (/install-service) that an AI agent
follows to add a service. It enforces:
The wow moment: adding a service is a protocol, not a
freeform task. Two different developers (or one developer and one
AI agent) produce structurally identical packages.
Hook: "The framework adds services by reading; the install
skill ensures the package was written right in the first place."
Three stories cut across all the magic above:
Manifests + idempotent applies + recovery playbooks + atomic
release-run + automated health checks → the operator's job becomes
reviewing what the framework decided, not deciding everything
from scratch. Most days, the framework runs PMA. The operator
intervenes on exceptions.
This is the story for: tired DevOps engineers, small IT teams,
solo operators of a self-hosted stack.
The MCP gateway, structured logs, JSON output everywhere, the
contract system, the install skill — every part of PMA is built
so that an AI agent can drive it as well as a human can. The agent
isn't simulating a human at a terminal; it's operating against the
same APIs the framework uses internally.
This is the story for: teams adopting AI-driven development,
agency operators running PMA for clients via AI, anyone building
agent-mediated workflows.
PMA gives you the SaaS-replacement story (the existing pitch) but
the bonus is that the operational story is also sovereign:
recovery/playbooks/.You don't trade vendor lock-in for "ok now we manage 15 services
by hand". You trade it for a coherent platform that handles the
15 services.
This is the story for: compliance officers, legal/healthcare
practices, government, EU companies feeling geopolitical pressure
to move off US SaaS, cooperatives, NGOs.
| Persona | The magic that lands first |
|---|---|
| MKB owner / CFO | Cost (existing pitch). Then: "and the IT team can self-recover from incidents without a vendor support ticket." |
| IT manager (5+ SaaS today) | SSO across services + the integration story. n8n connecting them in dataflows they used to coordinate by hand. |
| DevOps engineer | release-run atomicity + recovery playbooks + asd's just doctor style. "Mondays stop being the day everyone's tunnel is broken." |
| Compliance officer / DPO | Data sovereignty + audit trail in git + Authentik holds all identity, not a third party. |
| Compliance officer (GDPR / DSGVO) | "Your dev workflow doesn't ship your code to a third party anymore" + on-prem deployment + Authentik + audit log. |
| Founder of a digital agency | Run PMA for clients. Each client gets a profile. One framework, many client stacks. |
| AI agent operator (running Claude / GPT agents) | MCP gateway gives the agent a real seat. Structured outputs everywhere. Contract system means the agent knows what it can call. |
| Developer joining a PMA team | just bootstrap-local, productive in hours, not days. Symbol index for "where does X live?". |
| Open-source contributor | Add a new service by writing a manifest. Framework picks it up. Get the SSO + backup + health checks for free. |
| Educator (teaching enterprise software integration) | A real, working, multi-service stack students can run on their laptops. Free, complete, with real Authentik / Superset / n8n. |
| Healthcare practice / law firm | On-prem + GDPR + integrated stack. No "your patient data went through Salesforce". |
| Local government / cooperative / NGO | The cost story matters. The sovereignty story matters more. "Our community owns its tools." |
| Researcher / scientific group | Project tracking (Redmine) + wiki (Wiki.js) + chat (Mattermost) + data (Superset) + workflow (n8n) — all integrated, all locally hosted, all free. |
| Solo consultant | Their own PMA = their own ticket system + their own knowledge base + their own automation. Personal CRM that actually feels like theirs. |
just release-run and just release-revert are the only deploy verbs. Everything else is a sub-script."just. Tab. Read. Choose. Run."Most of the magic above can be approximated with enough effort by
combining other tools. But a few items are genuinely PMA-only as
far as we can tell:
Manifest-driven SSO across 15+ services with one config field.
Other self-hosted stacks (Cloudron, Yunohost) ship multi-service
bundles but require per-service SSO setup. PMA's sso.type: slot
automates the whole flow.
Recovery playbooks as machine-readable artefacts. Most
projects have runbooks in Confluence / wiki. PMA's are YAML in
git, structured for AI-agent consumption.
The MCP gateway with per-service tool surface. Other
platforms have admin APIs; PMA has an MCP server that exposes
them all as agent-callable tools with structured contracts.
The atomic release orchestrator with backup+migrate+verify in
one halt-on-failure pipeline. Most self-hosted stacks have
"run docker-compose pull and pray" as the deploy mechanism.
The contract system that fails CI on framework drift. New;
nobody else seems to have this for self-hosted enterprise stacks.
The install skill as a formal protocol. Other projects have
"how to add a service" docs; PMA has a step-by-step skill that
an agent (or human) follows mechanically.
These five together make PMA qualitatively different from "I
installed 15 Docker containers and hope for the best".
The existing pitch hasn't caught up to where PMA actually stands
in the AI-driven-ops landscape. Specifically:
just recipe → AI agents can call them.--json) → AI agentsPMA is in 2026 what a lot of teams will be reaching for in 2027.
The pitch should say that out loud.
Hook: "PMA was built so AI agents could operate it as
first-class peers. The AI era didn't catch us by surprise — we
designed for it."