Coding Agent Installation

View as Markdown

Install a persistent integration when you want a coding agent to load NeMo Relay without a nemo-relay wrapper command.

Two different mechanisms live under this one command. Claude Code and Codex take a generated marketplace plugin whose MCP server carries the gateway; the sections below describe that path, and everything they say about marketplaces, MCP stdio, --install-dir, and version gating applies only to those two hosts. pi has an extension and package system of its own but no marketplace and no MCP client, so nemo-relay install pi writes an extension into pi’s auto-discovery directory and that extension talks to the gateway over plain HTTP. See pi for the whole of the pi path.

Each persistent integration forwards the lifecycle signals that its host exposes, including agent, subagent, tool, prompt, compaction, and stop events where available. Model-provider routing sends LLM traffic through the local NeMo Relay gateway. Hooks alone cannot capture complete LLM request and response spans.

Both integrations share the same lifecycle gateway. Provider traffic joins that gateway when routing is configured for the host:

Codex / Claude Code
|-> Relay MCP lifecycle client -------> shared Relay gateway
|-> generated lifecycle hooks --------> shared Relay gateway
\-> provider route (when configured) -> shared Relay gateway -> model provider

Each agent starts its own lightweight MCP stdio process. Those processes share one compatible gateway. Generated lifecycle hooks use hook-forward to deliver their canonical payloads to that same gateway.

Requirements

Install nemo-relay and ensure that it is available on PATH or %PATH%. The installer does not download a second Relay binary, install a daemon, or require an integration-local executable.

The selected coding-agent CLI must also be available at a supported version:

  • Claude Code 2.1.121 or newer through claude.
  • codex-cli 0.143.0 or newer through codex.
  • pi 0.84.x through pi.

For Claude Code and Codex, Relay checks the selected CLI version before modifying agent configuration. Prerelease, malformed, and older versions are rejected consistently by install, doctor, and transparent launch paths.

nemo-relay install pi does not check pi’s version, because it never runs pi: it writes a directory into pi’s auto-discovery location, which succeeds whether or not pi is present. It reports when pi is absent from PATH. Version checking for pi happens in nemo-relay doctor pi and at transparent launch.

Install a Persistent Integration

Run the command for the coding-agent integration that you want to install:

nemo-relay install claude-code
nemo-relay install codex
nemo-relay install pi

Install every supported host detected on the machine:

nemo-relay install all

install all selects only supported agents whose CLI is present. It fails if Claude Code, Codex and pi are all absent.

nemo-relay install pi differs from the other two: pi has no plugin marketplace, so Relay writes the extension into pi’s own auto-discovery directory rather than generating a marketplace plugin. --install-dir does not apply to it, and it does not require pi on PATH when installed by name. See pi.

Use --dry-run to preview the operation without changing host configuration. For Claude Code and Codex, the preview includes marketplace paths and host commands:

nemo-relay install codex --dry-run

For Claude Code and Codex, use --install-dir when you need a non-default marketplace location. The default plugin directory is platform-specific:

PlatformDefault Plugin Install Directory
macOS~/Library/Application Support/nemo-relay/plugins
Linux${XDG_DATA_HOME:-~/.local/share}/nemo-relay/plugins
Windows%LOCALAPPDATA%\nemo-relay\plugins

Relay serializes install, force-install, rollback, and uninstall operations for each user and host, even when two operations name different install directories. If another operation is still active after a short wait, Relay stops with a timeout instead of changing host-wide plugin state concurrently.

Recover a Deleted Codex Marketplace

If the generated Codex marketplace directory is deleted while Codex still has nemo-relay-local registered, Codex reports the marketplace as present but unloadable and cannot say whether nemo-relay-plugin is registered. Relay recognizes this exact dangling state when both the expected marketplace root and its generation marker are absent. Recovery is explicit:

nemo-relay install codex --force
nemo-relay uninstall codex --force

Use the first command to rebuild the integration or the second to finish removing it. The corresponding command without --force does not change the dangling state and tells you which forced command to run.

Recovery reuses the surviving generation lock and fails before changing anything if that lock cannot be proved safe—for example, if it is missing, malformed, replaced, symlinked, not a regular file, or held by another process, or if the marketplace root or marker reappears while Relay acquires it. In that case, follow the manual-remediation instructions in the error instead of replacing the lock.

During a forced reinstall, removal of the old provider and hooks, plugin registration, and marketplace registration is one cleanup phase. Until all three areas have been cleaned, a failure restores only prior state Relay can prove existed. Marketplace removal is durable progress because the generated tree is already gone, so a later probe failure records that removal and retries forward. After all three are clean, cleanup is committed: a later install failure does not recreate the dangling Codex registration. Relay keeps the validated lock and records the clean progress so another nemo-relay install codex --force or nemo-relay integrations refresh can retry safely. A partially failed forced uninstall is likewise retryable with nemo-relay uninstall codex --force; Relay removes the retained lock and state only after cleanup succeeds completely.

What Install Changes

For Claude Code and Codex, nemo-relay install writes a local marketplace named nemo-relay-local, then registers the generated nemo-relay-plugin package with the selected host.

For Claude Code, nemo-relay install claude-code registers the local marketplace, installs nemo-relay-plugin@nemo-relay-local at user scope, and enables provider routing through the local NeMo Relay sidecar. Relay preserves existing Claude authentication and model settings and backs them up only when it adds the provider route. The plugin also declares the native nemo-relay mcp lifecycle client.

For Codex, nemo-relay install codex registers the local marketplace, installs nemo-relay-plugin@nemo-relay-local, enables Codex hooks, and configures the nemo-relay-openai provider alias at http://127.0.0.1:47632/v1. The plugin’s hooks/hooks.json is the sole persistent Relay hook source. The installer uses the Codex app-server API to select hooks by plugin ID, exact canonical command, and event definition. It never trusts unrelated user, project, or plugin hooks. If Codex does not discover exactly one enabled and trusted handler for every generated event—SessionStart, UserPromptSubmit, PreToolUse, PostToolUse, PermissionRequest, SubagentStart, SubagentStop, Stop, PreCompact, and PostCompact—installation restores the previous Codex config, legacy hooks, Relay backup files, and every original targeted trust entry. These 10 events are the complete supported Codex 0.143 plugin hook schema; Relay does not generate undiscoverable PostToolUseFailure, Notification, or SessionEnd handlers. Upgrade removes legacy Relay groups from ~/.codex/hooks.json while preserving unrelated hooks.

After upgrading to a release with file-backed hook configuration, uninstall and reinstall the Relay plugin so the coding-agent host refreshes its stored hook commands and trust hashes.

Generated hooks invoke the native Relay binary with a short private --hook-config path. The private Relay-owned file contains the gateway URL, generation fence, and hook lifecycle settings, so host-managed hook configuration does not expose those values or exceed Windows command-length limits. Both install and doctor verify the generated command and event ownership.

Start a new Codex CLI process after installation. Restart the Codex desktop app if it was already running so it reloads the provider and hook configuration.

Shared Gateway Lifecycle

Claude Code and Codex processes use the same nemo-relay mcp lifecycle client. Before reading MCP protocol frames, it starts or reuses a detached native sidecar on 127.0.0.1:47632. The client authenticates Relay with a per-user bootstrap proof and confirms its version and protocol readiness. It binds the effective user-level configuration fingerprint into that proof without requiring it to match the running gateway’s fingerprint. Therefore, a configuration-only difference does not reject or replace a healthy gateway: clients that share the same user bootstrap state can reuse it. The fingerprint does not expose credentials or configuration secrets, and it is not the gateway ownership boundary.

The client heartbeats the sidecar every 3 seconds by default. Relay shortens the default automatically when necessary to keep it below the gateway idle timeout. Set NEMO_RELAY_PLUGIN_HEARTBEAT_INTERVAL_SECS to a positive integer shorter than the idle timeout to override it. Concurrent Claude Code and Codex MCP clients that share the bootstrap state reuse the gateway. After the final MCP client closes, the sidecar exits after 300 idle seconds by default. If the gateway exits while MCP stdio is open, the client performs one coordinated restart and fails if recovery does not succeed. Relay reports a port conflict for a foreign process instead of accepting it merely because it returned HTTP 200.

For a cold start, the lifecycle client allows up to 20 seconds from spawning a sidecar until authenticated readiness. This window includes persistent configuration resolution, listener binding, and readiness publication. If the window expires, the MCP session fails and the coding agent cannot send requests through Relay. Restart the coding agent to make a new startup attempt. If the failure recurs, inspect the gateway_acquisition_failed event with failure_kind = "gateway_readiness_timeout" in Relay’s operational log before collecting support diagnostics.

Health and readiness responses include a per-process instance ID. A per-user startup lock serializes launch and recovery, while a small recovery record lets overlapping MCP clients share the same restart attempt. The gateway tracks its own activity, idle shutdown, and authenticated ownership-record cleanup.

When a newly launched MCP client detects a verified Relay-owned gateway from a different Relay version, it stops that old sidecar and starts a matching one. This intentionally interrupts MCP clients still attached to the old gateway.

Codex marks the MCP server as required, so the captured turn waits for verified gateway readiness. Claude Code 2.1.121 or newer uses alwaysLoad, which blocks session startup until the MCP connection is ready. Installed MCP entries and hook-forward commands carry both the generation-file path and the immutable identity expected at that path. This prevents a host process with cached plugin configuration from adopting a replacement installation after --force. Persistent hooks wait for the MCP-owned gateway, verify it on the same connection used for delivery, and send the canonical payload once. They never start or recover the gateway, and Relay does not retry after payload transmission begins. The MCP server advertises no tools in any host.

Refresh Installed Integrations

After upgrading the nemo-relay binary, refresh every Relay-managed Codex and Claude Code installation with:

nemo-relay integrations refresh

Refresh retires each old MCP generation, stops the authenticated Relay-owned sidecar, and republishes the integration from the current binary. Restart the affected host clients afterward. To bring a legacy custom-directory installation under Relay management, reinstall the appropriate host before refreshing it:

nemo-relay install codex --install-dir <path-to-plugins> --force
nemo-relay integrations refresh

Refresh preflight validates installed targets and retires their active MCP generations. A preflight failure stops the refresh before any target is attempted. A deleted Codex marketplace has no generation to retire, so its recovery remains in the per-target forced-install loop. If its surviving lock is unsafe, Relay reports that target, continues refreshing the others, and returns an error after every target has been attempted.

Manual MCP configurations are not changed; reinstall them through Relay if you want Relay to manage future refreshes.

To explicitly stop the managed shared gateway, first close active MCP clients, then run:

nemo-relay --bind 127.0.0.1:47632 gateway stop

The command resolves the process listening at that exact loopback address, verifies that its executable is named nemo-relay, and stops it. It can only stop a gateway running on the local machine; remote gateway processes are not supported. An open MCP client can restart the managed gateway as part of its one allowed recovery.

nemo-relay gateway start starts the gateway with the same server configuration as a bare daemon invocation. nemo-relay gateway stop stops that gateway at the default daemon endpoint, 127.0.0.1:4040. Pass the same --bind value to both commands for a custom endpoint. On Unix, add --force to terminate the process immediately instead of requesting a graceful shutdown. Windows always terminates the gateway process tree.

Hook Delivery and Upgrade Safety

Before contacting the gateway, Relay rejects a fixed-endpoint hook-forward command that lacks a valid installer-owned generation fence. Generated persistent hook commands reference a private Relay-owned configuration file; that file contains the generation-file path and immutable generation identity. Relay uses the configured hook failure policy. This prevents a legacy hook retained by a host process from reviving a retired installation. If install or uninstall reports a missing or invalid generation marker, follow the error’s cleanup instructions. If the generated Codex marketplace was deleted but its registration remains, see Recover a Deleted Codex Marketplace. For other missing or invalid generation markers, or when forced recovery cannot validate the surviving lock, follow the error’s manual cleanup instructions: close the host and standalone nemo-relay mcp processes, remove the stale registration and state it identifies, and then run the requested --force command.

Transparent hooks reference a temporary private configuration file containing their process-private gateway URL and never recover a persistent gateway, so they do not need this fence. Source plugins and custom automation can use --forward-only to contact an existing gateway without a fence. That mode waits for an authenticated, configuration-compatible Relay gateway and rejects foreign or incompatible listeners before it sends the payload. Authentication and delivery use the same TCP connection, so a process that replaces the listener after a health probe cannot receive lifecycle data. The mode never launches or recovers Relay.

Relay cannot guarantee exactly-once delivery if the gateway fails after it accepts a request. It does not keep a durable hook outbox or deduplication journal. The opt-in end-to-end tests verify exactly-once lifecycle output for the healthy and cold-start paths they exercise, not for arbitrary crashes between request acceptance and response delivery.

On Windows, Relay requests Job Object breakaway when the host job permits it. When breakaway is unavailable and the host permits nested assignment, the gateway remains scoped to the host job and can exit before the normal idle reuse window. If the host rejects nested assignment, persistent bootstrap stops and explains the conflict instead of running without process-tree cleanup guarantees.

The compatibility fingerprint covers resolved provider, exporter, dynamic plugin, and relevant environment settings without exposing their values in the health response. For Claude Code and Codex, nemo-relay install <host> --force rotates the immutable MCP and hook generation identity, then uses a private ownership token to stop the shared fixed-endpoint gateway as one serialized operation. Ownership is keyed by endpoint rather than host, so an upgrade from any installed host can retire a gateway that another host originally started.

Relay leaves custom managed endpoints untouched and never sends its shutdown token to an unrelated listener.

Configuration and Credentials

Persistent mode resolves only system and user Relay configuration and starts in the user configuration directory. Project .nemo-relay layers remain available through transparent nemo-relay run invocations. Each host passes environment settings to MCP differently:

  • Codex stores variable names—not values—for provider credentials, Relay runtime, OpenTelemetry, AWS, proxies, certificates, approved prefixes, and credential variables referenced by user observability configuration.
  • Claude Code supplies its normal plugin MCP environment.

The long-lived managed sidecar injects a forwarded provider credential only when a request carries provider authorization or Relay’s private per-user client proof. The Codex installer writes a domain-separated HMAC proof into the managed provider’s http_headers; Relay stores the resulting Codex config with an owner-only mode on Unix or protected owner/System DACL on Windows before the temporary file becomes visible. Relay validates and removes that header before middleware, observability, or upstream forwarding. The underlying HMAC key remains in Relay’s owner-only bootstrap state. Claude Code sends its normal provider authorization. A foreign loopback caller cannot spend the sidecar’s forwarded credentials. Foreground nemo-relay --bind use retains environment-key injection for explicit local proxy workflows.

Diagnose

Run the command for the installed integration that you want to diagnose:

nemo-relay doctor --plugin claude-code
nemo-relay doctor --plugin codex
nemo-relay doctor --plugin all

--plugin asks about marketplace plugin state, so it does not accept pi — there is no pi plugin to diagnose, and --plugin all covers the marketplace hosts only. Diagnose a pi install with its own command, which reports the extension’s load path, whether pi will trust it, and whether it is up to date:

nemo-relay doctor pi

nemo-relay doctor includes every persistent integration it finds. It checks generated marketplace and plugin files where applicable, the Relay binary and hook support, agent version, registration, provider routing, hooks, and sidecar readiness assumptions. For Codex, doctor also asks the Codex app-server whether each exact Relay-generated hook is trusted and enabled. JSON output includes checks.codex_hooks_trusted and a codex_hook_trust object that groups trusted, untrusted, modified, disabled, missing, or duplicated required hooks. A stopped Codex sidecar is informational; the required plugin MCP starts it before the captured turn. Doctor also reports newly required forwarded environment names and recommends nemo-relay install codex --force.

In nemo-relay doctor --json output, a configured but unloadable Codex marketplace is reported with host_marketplace_unloadable: true under the integration’s host_registration object. In that state, host_plugin_registered is null because Codex could not determine whether the plugin is registered.

For Claude Code, doctor also validates version 2.1.121 or newer, the generated alwaysLoad MCP server, and its generation marker. A stopped sidecar remains informational because the next MCP process starts it. Persistent hooks wait for that MCP-owned gateway instead of starting it themselves.

Use the focused plugin doctor when diagnosing one host or an installation that uses a custom directory:

nemo-relay doctor --plugin codex --install-dir /path/to/plugins

If an installed integration is incomplete, doctor reports the failed check and suggests nemo-relay install <host> --force. Agents without a persistent installation remain informational, so transparent-run setup does not require one.

Uninstall

Run the command for the installed integration that you want to remove:

nemo-relay uninstall claude-code
nemo-relay uninstall codex
nemo-relay uninstall pi
nemo-relay uninstall all

nemo-relay uninstall pi removes only the files its install recorded, and only while they still match what was written; anything you edited is kept, and a directory Relay did not write is never touched. uninstall all includes it. --install-dir addresses the marketplace root, so it is ignored for pi under all and rejected when you name pi explicitly.

Uninstall removes Codex provider configuration and trust for the exact plugin hooks before unregistering the plugin, while Codex can still report its hook metadata. It then removes the host registration and marketplace. Claude Code provider routing is restored from the Relay backup. Unrelated user hooks and configuration remain unchanged.

Compatibility and Migration

These integrations require Codex 0.143.0 or Claude Code 2.1.121 at minimum. Relay rejects prerelease or malformed version output. If you configured an opaque wrapper, its --version output must identify the selected host.

The MCP bootstrap is host-neutral. Generated Codex and Claude Code configuration invokes nemo-relay mcp; Hermes-specific --agent hermes selections no longer parse. The --agent option remains supported for Claude Code and Codex run flows. Existing fenced installations can be refreshed with nemo-relay install <host> --force. Relay refuses to replace an older MCP installation without a valid generation marker because a cached host process might still be running. The exact deleted-Codex-marketplace state can be recovered through Recover a Deleted Codex Marketplace when its surviving lock is safe. For other missing-marker states, follow the manual cleanup steps in the error before you retry the forced install.

This release removes the internal nemo-relay plugin-shim command. Refresh a fenced generated installation with nemo-relay install <host> --force; use Recover a Deleted Codex Marketplace for that exact Codex state, and use manual cleanup for other missing-marker states. For custom automation, use these supported replacements:

Removed Internal CommandSupported Replacement
nemo-relay plugin-shim hook <agent>nemo-relay hook-forward <agent> --forward-only with the canonical lifecycle payload on standard input and an existing gateway
nemo-relay plugin-shim servenemo-relay mcp for host-managed lifecycle, or nemo-relay --bind <address> to run a gateway directly
nemo-relay plugin-shim install <agent>nemo-relay install <host>
nemo-relay plugin-shim uninstall <agent>nemo-relay uninstall <host>
nemo-relay plugin-shim provider claude enablenemo-relay install claude-code
nemo-relay plugin-shim provider claude restorenemo-relay uninstall claude-code
nemo-relay plugin-shim provider claude statusnemo-relay doctor --plugin claude-code
nemo-relay plugin-shim doctor <agent>nemo-relay doctor --plugin <host>

Persistent and transparent generated hook commands reference a private Relay hook configuration instead of embedding gateway details. The process environment lets an installed plugin MCP authenticate, borrow, and monitor that exact gateway. Transparent hook delivery authenticates the wrapper gateway before writing its lifecycle payload. When a transparent run uses a recognizable wrapper command, such as npx codex, Relay checks the host version through that wrapper. Opaque custom wrappers remain supported when the configured command emits the selected host’s canonical version output in response to --version. Install and doctor enforce the same minimum-version policy.

Source Marketplace Discovery

This repository also contains source marketplace manifests for development and validation:

  • .claude-plugin/marketplace.json
  • .agents/plugins/marketplace.json

Those manifests are useful when validating host plugin metadata from a source checkout. For end-user setup, use nemo-relay install <host>. For Claude Code and Codex, the command generates the local marketplace, registers the host plugin, and performs the required provider and hook setup. Source manifests do not provide Codex’s complete provider, environment-forwarding, and verified-trust workflow.

Do not keep a source-installed plugin and the generated plugin active for the same host. Both can forward the same lifecycle payload and produce duplicate events. Remove the source-installed plugin before you use the generated install.