Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.modelcode.ai/llms.txt

Use this file to discover all available pages before exploring further.

uses a Self-hosted Daemon (also called the ModelDaemon) to execute build, run, and test commands on your own infrastructure. This is necessary when your project depends on private services - such as internal APIs, databases, or package registries - that are not accessible from the public internet.
The Self-hosted Daemon is for projects that need access to private infrastructure. If your project uses publicly accessible dependencies, use the cloud build environment instead - will auto-discover your lifecycle setup with no manual configuration needed.

ModelDaemon - Designed for Real Environments

The ModelDaemon runs directly inside your existing application environment - the same machine, the same runtime, the same network context your application already uses. There is no environment recreation, no containerization requirement, and no need to replicate your infrastructure elsewhere. This is intentional design. Enterprise applications depend on internal services, private registries, and runtime configurations that are difficult or impossible to faithfully reproduce elsewhere. ModelDaemon sidesteps that problem entirely by operating in-place, against your real environment. For teams with a working, stable application environment, ModelDaemon is the fastest and most reliable path to getting ModelCode running.

When to Use a Self-hosted Daemon

  • Your app already builds and runs - no environment setup required
  • Dependencies are already in place - language runtimes, package managers, internal tools
  • You don’t need portability - the environment is stable and not going away
  • Speed matters - you want ModelCode operational with minimal infrastructure changes
If your application works today, ModelDaemon can operate on it immediately. There is no migration, no container configuration, and no environment parity problem to solve.

How It Works

The ModelDaemon is a lightweight binary (mcode) that runs on a machine within your network. Once started, it:
  1. Registers with and begins sending periodic heartbeats
  2. Polls for pending jobs (build, test, validation tasks)
  3. Executes commands on the host machine’s shell
  4. Reports results and logs back to

Command Execution Model

The daemon executes each command in a new shell process on the host machine. There is no persistent shell session between commands - each step (install, build, run, test) starts a fresh shell -c "command" invocation. All lifecycle commands are executed in a POSIX shell environment. Windows CMD or PowerShell syntax is not supported.
The ModelDaemon executes lifecycle commands in a POSIX-compliant shell environment. Linux and macOS are fully supported.
What this means in practice:
  • Environment variables - Configure environment variables in the Modelcode UI, not via lifecycle commands.
  • Working directory - The daemon manages the working directory and keeps it consistent across all commands within a single job. You don’t need to cd into the project directory unless a command should run in a nested directory.
  • Concatenated commands - When multiple commands must run in the same shell context, join them with &&.
  • Private repositories - The daemon executes lifecycle commands exactly as defined. If Composer requires authentication for private repositories, those credentials must be present on the daemon host or supplied via encrypted environment variables.
The daemon runs commands with the same permissions as the user that started the mcode process. Make sure the user has access to the tools and services your project needs (e.g., language runtimes, network access to private registries).

Setting Up the Daemon

Install the ModelDaemon on the same machine or environment where your application runs. This is what gives it access to your internal services, private registries, and runtime dependencies. Installing it elsewhere - even a similar machine - may result in build or test failures that are difficult to diagnose.The environment must remain stable for the duration of your project work.
One daemon per project. Each project supports a single active ModelDaemon. If your team has multiple seats, only one person should set up the daemon for a given project - typically whoever owns or has access to the target environment. Other team members connect to the same project and share that daemon automatically. Setting up multiple daemons for the same project is not supported and will cause conflicts.

Prerequisites

  • A machine on your network that can reach your private services
  • A Modelcode account with an active project
  • Network connectivity from the machine to *.modelcode.ai
  • All dependencies of the migration project should be available to the Daemon
  • POSIX-compliant operating system (Linux or macOS)
The ModelDaemon currently supports POSIX environments only.

Language-Specific Requirements (PHP)

If your project uses PHP and Composer:
  • PHP must be installed on the daemon host
  • Composer must be installed and available in PATH
  • Any required PHP extensions must be installed
Verify PHP and Composer are available:
php -v
composer -v

Supported Operating Systems

  • Linux (x86_64, ARM64)
  • macOS (Intel & Apple Silicon)
Windows native execution is not supported at this time.
To set up the daemon, open your project in Modelcode and navigate to the Build Environment section. Select Self Hosted as your environment type. The UI walks you through each step with platform-specific commands and input fields. At a high level, the onboarding flow covers:
  1. Generate an API key - Creates credentials for the daemon to authenticate with
  2. Install the daemon - Download and install the mcode binary on your target machine
  3. Set up encryption - Generate a key pair so the daemon can securely handle secrets
  4. Start the daemon - Run the daemon process and connect it to
  5. Verify the connection - Confirm the daemon is registered and online
  6. Configure lifecycle commands - Define the install, build, run, health check, and test commands for your project
  7. Configure environment variables - Add any variables your application needs at build or runtime, with optional secret encryption
  8. Validate the setup - Run an end-to-end validation that executes each lifecycle command in sequence
With a Self-hosted Daemon, lifecycle commands are configured at the project level during this onboarding flow. For the cloud environment, lifecycle configuration is also project-level but is auto-discovered - with separate origin and target entries, each containing scripts, variables, and a lifecycle document.
For production use, run mcode install-service followed by mcode start to run as a background service (e.g., using systemd, launchd, or a process manager like pm2). This ensures the daemon restarts automatically after reboots.

Environment Variables and Registry Access

Private Registry Access (Artifactory)

If your dependencies are hosted in a private Artifactory instance:
  • The daemon host must have network access to Artifactory
  • Composer must be configured to authenticate against Artifactory
  • Required credentials (tokens, username/password, or auth.json) must be available at runtime
Authentication options include:
  • Composer auth.json
  • Environment variables
If credentials are configured via environment variables, they should be stored as encrypted variables in the Morph UI.

Why This Approach Works

Recreating an enterprise application environment from scratch is harder than it looks. Internal services have specific versions, configurations, and network paths that are rarely fully documented. Private registries require credentials that may be tied to specific machines or users. Runtime behavior often depends on system-level configuration that isn’t captured in source control. ModelDaemon avoids this entirely. It runs in your real environment - not a simulated one. The commands it executes are the same commands your developers run. The network paths it uses are the same ones your application uses in production. The credentials and config files are already in place. This is why it works reliably: it inherits correctness from your existing setup rather than trying to reproduce it.

Environment Stability

ModelDaemon is designed to run on a stable host. The environment where the daemon is installed should:
  • Remain accessible for the duration of the project
  • Maintain consistent build and runtime behavior across sessions
  • Not be decommissioned, re-imaged, or significantly reconfigured mid-project
This is a strength, not a constraint. The daemon’s reliability comes directly from the stability of the environment it runs in. Teams that treat their build environment as a managed, long-lived resource get the most consistent results.

Example: Running ModelDaemon in an Existing Application

A typical self-hosted daemon deployment looks like this:
  1. The daemon binary is installed on the same server or VM where the application is already running
  2. The daemon is configured with an API key and pointed at the Modelcode platform
  3. Lifecycle commands - install, build, run, test - are defined in the Modelcode UI using the same commands the team already uses
  4. No infrastructure changes are made: no new VMs, no containers, no network modifications
  5. ModelCode begins executing build and test workflows immediately, using the existing environment
This setup is in production use across applications with complex dependency chains, private Artifactory registries, and internal service dependencies. The common thread: the environment was already working, and ModelDaemon leveraged that directly.

Troubleshooting

Daemon Shows as Offline

The daemon appears offline when has not received a heartbeat within the last 60 seconds. Check if the daemon process is running:
ps aux | grep mcode
If the process is not running, start it again with mcode run/start. Check network connectivity: The daemon must be able to reach Morph server over HTTPS. Verify with:
curl -I https://<SERVER_URL>
If this fails, check your firewall rules, proxy settings, or VPN configuration. Check the daemon logs: Run mcode logs to show the last log lines. Alternatively the logs are written to the logs/ directory next to the mcode binary. Look for connection errors or authentication failures. Common causes:
  • The mcode run process was killed or the machine rebooted without a service manager configured
  • A network change (VPN disconnect, firewall rule update) is blocking outbound HTTPS traffic

Command Not Found

The daemon inherits the PATH from the shell that started it. When installed as a system service, it takes a snapshot of the current PATH and stores it in its config file. If you install new tools after the daemon is already running as a service, update the stored path with mcode refresh-path and restart the daemon.

Test Generation Failed

Test generation failures occur when cannot generate tests for your project. This typically relates to the build or run steps. Application failed to build: Check the install and build command output in the validation logs. Common causes:
  • Missing dependencies that are only available on your private network
  • Incorrect build command - verify it works when run manually on the same machine
  • Environment variables missing - add them in the Modelcode UI
Application failed to start: If the build succeeds but the run command fails:
  • Check that the port your application listens on is not already in use
  • Verify that required services (databases, APIs) are reachable from the host machine
  • Review the run command output for startup errors
Health check timed out: If the application starts but the health check never succeeds:
  • Confirm the health check URL and port match your application’s configuration
  • Check that the application is binding to 0.0.0.0 or localhost, not a specific interface
  • Increase the health check timeout if your application has a long startup sequence

Functional Testing Failed

Functional test failures mean the test suite ran but one or more tests did not pass. Review the test output: The validation logs show the full test command output, including individual test failures. Read the error messages to determine whether the failure is:
  • A test that depends on external state (e.g., seeded database records, specific API responses)
  • A test environment issue (missing env var, wrong service URL)
  • An actual bug surfaced by the generated tests
Tests depend on unavailable services: If tests require services that are not running on the daemon host:
  • Start those services before running mcode run
  • Add their connection details as environment variables in the Modelcode UI
Tests time out:
  • Check the command_timeout configuration (default is 10 minutes)
  • If your test suite takes longer, consider splitting it or increasing the timeout

API Key Issues

“Unauthorized” or “Authentication failed”:
  • Verify the API key in your daemon configuration matches the one shown in the Modelcode UI

Encryption Key Mismatch

Secrets fail to decrypt: If the daemon cannot decrypt secret environment variables:
  • Re-run mcode encryption generate and update the public key in the Modelcode UI
  • Restart the daemon with mcode run
  • Re-save your environment variables in the UI to re-encrypt them with the new key

FAQ

Does the ModelDaemon Support Windows?

The daemon supports POSIX-compliant environments (Linux/macOS).

Next Steps