Everything as code
Keep a complete AI setup in a repository and import it into a clean environment.
Every example in this section was built from pieces - credentials, groups, gateways, connections, services, skills. The setup below puts all of them into files a repository can hold and a clean environment can import, so recreating production in staging is a checkout and an import, not an afternoon of clicking.
The pieces
Everything is a file, but not the same kind of file:
| Piece | Form | How it deploys |
|---|---|---|
| Security, groups, gateways, LLM connections | One enmasse YAML | Imported - on demand or on startup |
| Services | Python files | Hot-deployed |
| Skills | A SKILL.md per directory under config/repo/skills | Files - copied or checked out in place |
| Secrets | Environment variables | Never in the repository |
The YAML names services and skills that arrive as files - enmasse brings the configuration, the files bring the content, and the names are the joint between them.
The YAML
The complete configuration of a support setup - an agent credential, its group, a gateway with two tools and a prompt, and the LLM connection the tools use:
security:
- name: agent.support
type: apikey
username: support-agent
password: Zato_Enmasse_Env.Support_Agent_Key
groups:
- name: support-agents
members:
- agent.support
llm:
- name: Support LLM
model: gpt-4o-mini
address: https://api.openai.com/v1
secret: Zato_Enmasse_Env.Support_LLM_Key
timeout: 15
max_tokens: 2048
mcp_gateway:
- name: support
url_path: /mcp/support
services:
- example.support.get-ticket
- example.support.summarize-ticket
security_groups:
- support-agents
skills:
- ticket-triage
validate_input: true
is_audit_log_active: true
max_response_size: 2000
Two properties matter:
- No secrets - the
Zato_Enmasse_Env.prefix reads each secret from an environment variable where the import runs, so this file is safe in git and each environment brings its own keys. - Importing the gateway also creates the REST channel that makes it reachable - the YAML above is complete.
The repository
support-ai/
├── enmasse.yaml
├── services/
│ └── support.py # the two services the gateway names
└── skills/
└── ticket-triage/
└── SKILL.md # the prompt the gateway serves
Import into a clean environment
With a fresh environment and the two environment variables set, the files go in first and the configuration follows:
# Services hot-deploy by being placed in the pickup directory
cp services/support.py ~/env/qs-1/server1/pickup/incoming/services/
# Skills are files under the server's config
cp -r skills/ticket-triage ~/env/qs-1/server1/config/repo/skills/
Then the YAML imports as one unit - in the Dashboard through System > Config > Import enmasse, or, in containers, as a mount point: enmasse.yaml under /opt/hot-deploy/enmasse/ imports on startup, as the DevOps guide describes. Either way the environment now serves /mcp/support, the agent's key works, the prompt is listed and the audit log is on - nothing was configured by hand.
Running the import again is safe - it creates what does not exist and updates what does, matching by name. That makes the YAML the reviewable unit of change: raising max_response_size is a one-line diff, a pull request and a re-import.
Failure behavior
The joints are names, and names can dangle:
- A service in the gateway's list that is not deployed yet is not an error - the gateway imports, and the tool appears the moment the service hot-deploys. The export marks such services with a
Not deployednote, as sharing with clients shows. - A skill named in
skillsthat has no directory yet is not served until the files arrive -prompts/listshows what is there. - A missing environment variable does not stop the import - the value becomes a placeholder that names the missing variable, so the first call that needs the secret fails and the placeholder in the error points straight at which variable was not set.
See also
| Feature | What it does |
|---|---|
| GitOps | The llm and mcp_gateway enmasse sections in full |
| Multi-agent isolation | The same layout grown to several agents and gateways |
| Self-hosted models | Per-environment YAML that swaps the model backends |