Agent Briefing¶
This page is written for an AI agent that plans a Manganese App Server, and for the person working with it. Read it whole before proposing anything. Each section links to the guide that details it.
Give this page to your agent
Paste its URL into the conversation, or the URL of its markdown:
https://docs.muppy.io/muppy_manganese/agent-briefing.md. The Manganese dashboard
shows it under your MCP URL, behind the Agent Briefing button.
What you are planning¶
An App Server — a mgx — hosts one application and what that application needs:
- the satellites its upstream ships with it: admin panel, API, exporters, webhook receivers;
- its single-consumer dependencies: Redis, a search engine, Mailpit, Adminer.
A service another mgx must reach goes on a mgx of its own. A commodity with a mature SaaS — email, object storage, analytics — goes to that SaaS. → Designing Your mgx
An App Server is created from an App Definition and owns a copy of its configuration. It comes with:
- an LXC container or a virtual machine, with your repository cloned in it;
- a dedicated PostgreSQL database, backed up every day;
- a public HTTPS URL, guarded by Sunray Zero Trust;
- a browser IDE (Code Server) where Claude Code runs.
The fixed constraints¶
Plan within these. Nothing installed on the server changes them.
- Two Internet-facing endpoints. The application at
https://<app-url>(Cloudflare → Sunray → Traefik →localhost:$APP_HTTP_PORT), and the IDE athttps://codr-<app-url>. No other port is reachable from the Internet. - Plain HTTP on
$APP_HTTP_PORT. TLS ends upstream. A service bound to another port (3000, 8080, an upstream default) runs, and is unreachable through the public URL. The value is in/etc/muppy.env. - No reverse proxy and no certificate on the server. Traefik is upstream.
- Path routing for several concerns on the main URL:
/api/*,/admin/*,/webhooks/stripe. Additional public sub-domains are not available. - Dev tools through the IDE proxy. The authenticated user reaches any local port
Nathttps://codr-<app-url>/proxy/<N>/. External clients — webhook providers, mobile apps — cannot. - PostgreSQL is provided. The
PG*variables are set;psqlandpg_dumpconnect with no arguments. Never install a second PostgreSQL server. - The OS is fixed at creation. A newer Ubuntu means a new App Server.
- A 503 Setup in Progress on the public URL for about ten seconds after a (re)provisioning is normal: Sunray is wiring the route.
→ How Muppy Exposes Your Application
The decisions to make¶
- The App Definition. A generic Ubuntu template for an application your repository
builds itself —
ubuntu26-v3-generic-template, orubuntu24-v3-generic-templatewhen a dependency is not packaged for 26.04. A stack template (Odoo, Muppy, Sunray) for that stack.mgx_list_app_definitionslists them. → Choosing an App Definition - The plan. Size for the workload, build peak included: it is often larger than the
run. Add about 4 GiB of RAM when Claude Code runs on the server. A container is the
default; a virtual machine is for kernel modules or nested virtualization. CPU and RAM
change later, the disk only grows, the machine type never changes.
mgx_get_available_planslists the plans. → Per-Stack Plan Selection - The qualifier, and so the lifetime. A Development or Test App Server is destroyed with its host on its Auto-Decommission Date: 30 days after creation by default, extendable up to a ceiling, 90 days by default. A Production App Server has no date. → App Server Lifetime
- The git credentials. The owner needs a git token that reads the repository. Ask
mpy.vault.can_serve_app_serverbefore creating: it says whether the creation will work and what is missing. It checks the repository you name, not the ones your build clones (sub-repositories, private dependencies): the token must read those too, or the build fails. → Git Tokens - One App Server or several. A build server and a run server can be split. The tiers of one application can share one database. → Sharing a Database
What the repository carries¶
Muppy clones the repository and runs what it finds in .muppy/. Nothing else builds the
application.
| File | Role |
|---|---|
.muppy/mpy_setup.sh |
The build. It runs twice at provisioning: MPY_SETUP_SH_STAGE=setup installs system packages and runtimes, then build installs dependencies and compiles. Each stage is idempotent, unattended, and leaves no process running. → mpy_setup.sh Setup Script Guide |
.muppy/services.yml |
The long-running processes — web, workers, timers — turned into systemd units. The HTTP service binds $APP_HTTP_PORT. → services.yml Service Definitions Guide |
Your own variables — API keys, SMTP settings, feature flags — go in a vault envfile on the
ENV Vars tab. Muppy writes them, with its own, to /etc/muppy.env.
→ Environment Variables
When you cannot commit to the repository (open source, a third party's), both files live on
the App Server record and the MCP pushes them to the server. Before writing a
mpy_setup.sh, look for an existing template: search mpy.template on
source_repository_url.
Driving the App Server through the MCP¶
Connect your client — Claude Desktop, claude.ai, Claude Code — to the MCP URL shown on your Manganese dashboard. It signs you in through Muppy.
- Create with
mgx_create_app_server; it is reserved to Manganese admins. Passai_llm_managed=Trueto let the agent redeploy and deprovision that server without a human approving each call. - Most calls run in the background. They return an
imq_message_id: follow it withget_task_statusonimq.message(domainimq) untildoneorfailed. A provisioning takes about ten minutes. - A held call returns
pending_approvaland apermission_request_id. Ask the user to approve it in Muppy, then pollget_status(domainmcp-permissions). Never work around it by another route. - Shell commands:
mgx_execfor a one-liner.mgx_exec_b64for a command holding|,;,&&,$(…)or several lines: Cloudflare's firewall blocks those in plain text and answers with an HTML page carrying a Ray ID. Files:mgx_read_file,mgx_write_file,mgx_edit_file. - The build runs through
mgx_run_mpy_setup_sh(stage=…).mgx_execrefuses any command that namesmpy_setup.sh. - Services:
mgx_configure_systemd_units_from_definitionsdeploysservices.yml;mgx_journalctlreads a unit's logs. - Later:
mgx_deploy_app_serverdeploys a branch,mgx_resize_serverchanges the plan,mgx_deprovision_app_serverdestroys the server.
Claude Code refuses a call before it leaves your machine
In auto mode, Claude Code may refuse an MCP call with a rule in brackets —
[Data Exfiltration] — and no Ray ID. Base64 changes nothing there. Allow the server in
~/.claude/settings.json on that machine:
{"permissions": {"allow": ["mcp__<server name>__*"]}}, with the server name /mcp
shows.
Inside the App Server¶
The agent that works inside the App Server — Claude Code in its IDE — reads
~/.claude/CLAUDE.md, which Muppy writes at provisioning: the same constraints, with the
server's own URLs and values. mgx_repair_user_claude_md writes it again when it is missing
or damaged.
That agent leaves to the user what changes the infrastructure: resize, on-demand backup, restore, deprovision.
Related¶
- Using This Doc with an AI Agent —
llms.txt, and every page as markdown - Accessing Your App Server — the application, the IDE, SSH