Skip to main content
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 on the public internet. ModelDaemon sidesteps that problem by sitting inside your network, where those services and credentials are already reachable — and it does so without polluting that environment with project-specific runtimes, because the agent and its dependencies live inside per-job isolated workspaces (see How It Works below). For teams with a stable internal network and a machine that can reach their private dependencies, ModelDaemon is the fastest and most reliable path to getting 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
V2 is a substantial rework of how the self-hosted daemon executes work. The biggest change is architectural — the AI morph-agent now runs on your daemon host instead of in our cloud — and that change is what makes the simpler onboarding possible: The net result is that V2 onboarding is just three steps: name your daemon, run an install command, confirm it’s connected. Everything else is handled by the agent on first use.

How It Works

The ModelDaemon is a binary (mcode) that runs on a machine within your network. Once started, it:
  1. Registers with and begins sending periodic heartbeats
  2. Receives jobs from over an authenticated outbound connection — lifecycle discovery, spec extraction, milestone execution, code-review chat
  3. Spawns the morph-agent in an isolated workspace for each job — a fresh per-job scratch directory with its own pinned dependency environment
  4. Streams results, logs, and AI traffic back to through the same outbound connection
All communication is initiated by the daemon, so you do not need to open any inbound ports. 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 invocation. In V2, the AI morph-agent that drives migration work runs as a process on your daemon host. The daemon is responsible for setting up a clean, reproducible environment for it, executing it, and tearing everything down when the job finishes.

Per-job isolated workspaces

When dispatches a job, the daemon creates a fresh scratch directory under its working tree (<workdir>/jobs/<job-id>/) and starts a morph-agent HTTP server inside it. The agent operates on the repository clone in that directory, so jobs cannot see or interfere with each other’s files. When the job completes, the workspace and every process spawned inside it are cleaned up. The shell used for lifecycle scripts depends on your project’s target operating system:
  • 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 - On Linux/macOS, join commands with &&. On Windows, join with ; or use separate lines in a multi-line PowerShell script.
  • 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 process itself runs commands with the same permissions as the user that started mcode. The agent runs inside its own pixi environment, so it does not inherit your host’s runtimes, but it does inherit network access, file-system permissions, and any credentials available to that user (SSH keys, kubeconfig, cloud-CLI tokens, etc.). Run the daemon as a user that has the network and credential access your project needs to reach private resources, and nothing more.

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 user. Each team member who actively works with (approving milestones, running code review chat, using knowledge chat) should have their own ModelDaemon. The daemon handles that user’s work and runs one active job at a time. If your daemon is busy (already running a job), new requests queue until the current job finishes. If your daemon is offline, cannot dispatch work for you until it reconnects.Multiple team members can work on the same project simultaneously — each using their own daemon — without conflicts.

Prerequisites

  • A machine on your network that can reach your private services
  • A account with an active project
  • Network connectivity from the machine to *.modelcode.ai over HTTPS (outbound only — no inbound ports required)
  • A supported host OS (see below)
You do not need to preinstall language runtimes (Python, Node, Java, Ruby, Go, etc.) or package managers (pip, npm, maven, gem, etc.). The agent declares what each project needs and the daemon installs it inside an isolated pixi environment.

Supported Operating Systems

  • Linux (amd64 or arm64) — Ubuntu, Debian, RHEL, Amazon Linux, SUSE, Alpine, and other POSIX-compatible distributions
  • macOS (Apple Silicon or Intel)
  • Windows (amd64 or arm64) — Windows 10/11 or Windows Server 2019+
Install the daemon on the same OS family as your application.

Onboarding Flow

UI walks you through the full setup and generates the exact install command for your platform with your API key already filled in — follow the on-screen instructions. The flow boils down to three steps: name the daemon, run the generated install command on the daemon host, and click Verify & Continue so the platform confirms the daemon’s heartbeat.
Once installed, you can sanity-check the daemon from the host: mcode version confirms the binary is present, and mcode logs tails the most recent log lines. Run mcode install-service followed by mcode start (the UI will remind you of this) so the daemon comes back up automatically after reboots. On Windows, install-service requires an elevated (Run as administrator) PowerShell session; if you cannot run as administrator, use mcode run in foreground mode instead.

Windows Setup Notes

onboarding UI provides a PowerShell one-liner that downloads and runs install.ps1. After installation:
  1. Open a new PowerShell window so the updated PATH is picked up (the installer adds mcode to your user PATH).
  2. Run mcode version to verify the binary is available.
  3. Return to the UI and click Verify & Continue.
For a background daemon, run mcode install-service and mcode start from an elevated PowerShell prompt. Service logs appear in Event Viewer → Windows Logs → Application (filter by source ModelDaemon), or run mcode logs for the local log file.

After Onboarding

Once the daemon is connected, dispatches a first job that does the following on your daemon host:
  1. Materializes an isolated pixi environment based on the agent’s analysis of your codebase (manifests, lockfiles, framework conventions). On the very first project this also installs a shared pixi base layer; subsequent projects reuse it.
  2. Discovers the lifecycle configuration — install, build, run, health-check, and test scripts plus any environment variables — by reading the codebase and trying things in the isolated workspace. This is the same auto-discovery used for cloud projects.
  3. Surfaces the result in the UI. You can review and edit everything on the Lifecycle Setup page at any time.
Secret environment variables are encrypted in transit and at rest; the encryption keys are managed by the daemon itself, with no manual key exchange.

Overriding npm and PyPI registries

When the daemon needs to install its base dependencies, it uses public registries: Many enterprise deployments cannot use those defaults. Common reasons include:
  • Air-gapped networks — the daemon host has no route to the public internet, so packages must come from an internal mirror.
  • Security policy — all third-party artifacts must be vetted and served from an approved internal registry (Artifactory, Nexus, Azure Artifacts, etc.) rather than pulled directly from the public npm or PyPI indexes.
You can point the daemon at your own npm and PyPI mirrors by adding a [registries] table to the daemon’s config.toml (in the same directory as the mcode binary — ~/.local/share/modelcode/ on Linux/macOS, or the equivalent under %LOCALAPPDATA% on Windows). Values you set here override ‘s defaults for that package manager. The daemon appends --registry (npm) or --index-url (pip) to the relevant install commands so base installs target your mirror even when the host has different package-manager defaults.
Registry overrides apply only to npm and pip installs during base dependency setup. It will not affect any downloads of your application.
If your mirror requires authentication, configure credentials on the daemon host the same way you would for manual npm or pip usage (for example .npmrc, pip.conf, or network policies that allow unauthenticated access from the daemon’s subnet).

Migrating from V1

V1 daemons are deprecated, but they have not been switched off:
  • Existing V1 projects keep working. If a project is already connected to a V1 daemon, that pairing continues to run jobs as before. There is no forced migration and no deadline you need to meet.
  • New projects require V2. Any project created from now on can only connect to a V2 daemon. If you try to attach a new project to a V1 daemon, the connection will be rejected.
V1 and V2 cannot run side by side on the same machine. Both versions install the mcode binary and config to the same location (~/.local/share/modelcode/ on Linux/macOS, or the equivalent under %LOCALAPPDATA% on Windows), so running the V2 installer on a host that already has V1 will replace the V1 daemon — your existing V1 projects will lose their daemon and stop running jobs.If you still have active V1 projects and want to onboard new V2 projects, install the V2 daemon on a different machine (any host with the same network and credential reach to your private services — see How It Works). Once your V1 projects are complete, you can replace V1 with V2 on the original host.
For reference on the V1 onboarding flow (encryption key generation, manual lifecycle commands, environment variables in the UI, validation wizard), see Self-hosted Daemon V1 (deprecated).

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. You get the correctness of an in-environment setup (real network, real credentials, real registries) without the operational cost of treating the host as part of the project’s runtime stack.

Daemon Status

Your daemon reports its status to in real time. You can see the current status in the UI: Since each user has their own daemon, your daemon being busy does not block other team members — they use their own daemons independently.

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. The agent auto-discovers lifecycle commands from the codebase on first use; the team reviews and edits them on the Lifecycle Setup page
  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 few minutes. Check if the daemon process is running:
If the process is not running, start it again with mcode run (foreground) or mcode start (installed service). Check network connectivity: The daemon must be able to reach server over HTTPS.
If this fails, check your firewall rules, proxy settings, or VPN configuration. Check the daemon logs: Run mcode logs to show the most recent log lines. Logs are also written to the logs/ directory next to the mcode binary. Look for connection errors or authentication failures. Common causes:
  • The host rebooted and mcode install-service was never run, so there is no service manager keeping the daemon up
  • A network change (VPN disconnect, firewall rule update) is blocking outbound HTTPS traffic
  • The API key was rotated in the UI but not updated in the daemon’s config.toml

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.

API Key Issues

“Unauthorized” or “Authentication failed”:
  • Verify the API key in the daemon’s config.toml matches the one shown in UI
  • If the key was rotated, update config.toml and run mcode start again

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

FAQ

Does the ModelDaemon Support Windows?

Yes. The ModelDaemon runs on Windows 10/11 and Windows Server 2019+ (amd64 or arm64). Installation and service setup are done from PowerShell; the UI provides platform-specific commands for each step.

Do I need to install Python, Node, Java, or other runtimes on the host?

No. The agent declares each project’s dependencies in a manifest and the daemon installs them inside an isolated pixi environment under the daemon’s data directory. Your host only needs to be able to reach the network locations your application reaches.

Where does the AI agent actually run?

On your daemon host, inside a per-job pixi-managed workspace. The daemon spawns one morph-agent process per job, gives it an isolated working directory and pinned dependencies, and tears everything down when the job finishes. cloud orchestrates the work but does not execute it.

Do you store my code or my LLM provider keys in the cloud?

Source code is read by the agent on your daemon host and never copied off it as part of normal job execution. The daemon proxies the agent’s LLM calls through using your daemon’s API key, so there are no provider API keys (Anthropic, OpenAI, etc.) on the host.

Can I run multiple daemons on the same machine?

No. The installer always writes to the same data directory for the current user, so running it a second time on the same host replaces whatever daemon is already installed there — whether it’s a V1, an older V2, or a V2 registered under a different name. To run more than one daemon at the same time, install each on a separate machine.

Do I still need to configure lifecycle commands manually?

No. With a V2 daemon, the agent auto-discovers your lifecycle the same way it does for cloud projects. You can review and edit the discovered scripts and environment variables on the Lifecycle Setup page at any time.

Do I still need to upload an encryption public key?

No. V2 daemons manage their encryption keys internally. There is no mcode encryption generate step and no public key field in the UI.

How much disk space does the daemon need?

Plan for ~5 GB in the daemon’s data directory for the binary, pixi, and a small project’s environments. Larger monorepos or projects with many declared environments (e.g. one per service) will use more — pixi caches conda packages on disk, and the daemon keeps prior environment versions around as long as some workspace still pins them.

Next Steps