Skip to main content

Architecture

Nexus is an Agent Operating System: a control plane that turns runtime-defined agent documents into isolated, observable executions. There are five substrates, each with exactly one job.

Nexus UI (React)
create agents · edit skills · manage
memory · view board · approve · logs
│ REST + SSE

┌───────────────────────────────────────────────────────────┐
│ Nexus Core (Rust, axum) │
│ │
│ orchestration engine · scheduler · agent registry · │
│ skill registry · memory service · board sync · auth · │
│ permissions · approvals · Kubernetes job launcher │
└───────┬───────────────┬───────────────┬───────────────┬────┘
│ │ │ │
(state) │ (events)│ (board) │ (isolation)│
▼ ▼ ▼ ▼
┌────────────┐ ┌────────────┐ ┌────────────┐ ┌──────────────────┐
│ MongoDB │ │ NATS │ │ Plane │ │ Kubernetes │
│ │ │ JetStream │ │ (adapter) │ │ │
│ source of │ │ durable │ │ external │ │ one Job per run │
│ truth for │ │ event bus │ │ projection │ │ generic runner │
│ agents, │ │ replay, │ │ of the │ │ image becomes │
│ skills, │ │ crash │ │ internal │ │ any agent from a │
│ memory, │ │ recovery │ │ board │ │ config payload │
│ tasks,runs │ └────────────┘ └────────────┘ └────────┬─────────┘
└────────────┘ │

┌──────────────────────────────┐
│ nexus-agent-runner (pod) │
│ loads skills + memory + │
│ tools, clones repo, calls │
│ the LLM, runs tools, commits,│
│ reports events back to Core │
└──────────────────────────────┘

Substrates and responsibilities

SubstrateOwnsNotes
Nexus CoreOrchestration authorityThe only component that mutates the source of truth. Everything routes through it.
MongoDBStateAgents, skills, memory, tasks, runs, approvals, board links. Dynamic configuration store.
NATS JetStreamEventsDurable, replayable stream messaging. Crash recovery for autonomous agents.
KubernetesIsolationEach agent run is an isolated Job. Resource limits, mounted secrets, scoped RBAC.
PlaneExternal projectionThe internal board is authoritative; Plane is a synced view. Jira later.

Components

ComponentTechResponsibility
nexus-coreRust, axum, tokio, tower, MongoDB driverAdmin/agent/board/skill/memory/webhook APIs, auth, approvals, orchestration.
nexus-workerRust, tokio, async-nats, MongoDBScheduling, agent dispatch, retries, Plane sync, memory indexing, reconciliation.
nexus-agent-runnerRust, reqwest, tokio, ductGeneric container: load config, run skills/tools, report events. One image, many agents.
nexus-telegramRust, teloxideHigh-level command gateway: create goals, approve tasks, status, alerts.
nexus-uiNext.js 16, React 19, Tailwind v4, TanStackAdmin dashboard (separate repo): agents, skills, memory, board, runs, approvals.
Shared cratesRustnexus-domain, nexus-db, nexus-events, nexus-board(-plane), nexus-agent-runtime, nexus-ai-runtime, nexus-k8s, nexus-skills, nexus-memory, nexus-llm, nexus-git, nexus-auth, nexus-observability.

See Repositories for the full per-project library list and Technical overview for the per-component deep dives.

Why agents are data

A traditional design encodes each agent role as a compiled type. Nexus rejects that. An agent is:

agent = MongoDB document (config) + attached skills + memory policy + permissions

When a task is assigned to an agent, Core assembles a run config and hands it to the runtime. The pod does not branch on role. This means:

  • You add a new agent from the UI, with no deploy.
  • The same nexus-agent-runner image serves every role.
  • Skills, memory, and permissions are composed at dispatch time.
{
"run_id": "run_123",
"agent_id": "agent_backend_implementer",
"task_id": "task_456",
"system_prompt": "...",
"skills": ["...skill markdown..."],
"memory": ["...relevant memory..."],
"tools": ["git", "shell", "cargo"],
"permissions": { "can_commit": true, "can_merge": false }
}

Trait seams

Nexus uses traits for dynamic providers, not for fixed agent roles:

#[async_trait::async_trait]
pub trait AgentRuntime {
async fn start_run(&self, run: AgentRunRequest) -> anyhow::Result<AgentRunHandle>;
async fn cancel_run(&self, run_id: &str) -> anyhow::Result<()>;
async fn get_logs(&self, run_id: &str) -> anyhow::Result<Vec<String>>;
}

#[async_trait::async_trait]
pub trait BoardProvider {
async fn create_item(&self, item: BoardItemCreate) -> anyhow::Result<BoardItem>;
async fn update_status(&self, item_id: &str, status: BoardStatus) -> anyhow::Result<()>;
async fn add_comment(&self, item_id: &str, comment: &str) -> anyhow::Result<()>;
}

Implementations: KubernetesAgentRuntime; PlaneBoardProvider, JiraBoardProvider, NexusInternalBoardProvider. Start with Plane — but Plane is just an adapter.

Deployment shape

ProcessPortsHosting
nexus-core8080 (REST + SSE), 9100 (Prometheus)Kubernetes deployment behind ingress.
nexus-worker9100 (Prometheus)Kubernetes deployment; consumes NATS.
nexus-telegramKubernetes deployment; long-polls or webhook.
nexus-ui3000Next.js server behind ingress; proxies REST to nexus-core.
agent runsEphemeral Kubernetes Jobs in a dedicated namespace.
MongoDB27017Replica set (3 nodes).
NATS JetStream4222Clustered, with file storage for durability.

Nexus Core's service account can create Jobs only in the agent namespace, with a tightly scoped RBAC role. See Security & permissions.

Per-component deep dives

The Technical overview is the entry point.