Skip to content

moru-ai/maru

Repository files navigation

Maru

A research assistant built with Moru sandbox and Claude Agent SDK.

demo-hq.mp4

Features

🤖 Multi-Agent Sessions

Run multiple Claude in parallel. Each agent gets its own dedicated Linux VM.

💬 Native Message Format

Renders Claude Code's native message format. Not restricted message subset of Claude Agent SDK.

⚡ Real-time Streaming

See tool executions, thinking, and results in real-time

🔄 Session Resume

Agents maintain session history. Resume sessions anytime

💾 Workspace Persistence

Workspaces are saved to storage and restored on session resume. Files and Claude session persist across sessions.

📁 File Explorer & Editor

Browse and view files in the agent's workspace. Download files that the agent writes or edits.

Detail

  • Claude Code stores each chat session locally as newline-delimited JSON.
  • I reverse-engineered those JSONL message formats and turned them into JSON Schemas for reuse (see agent-schemas)
  • When a user sends a message, we boot a fresh Moru VM with a clean workspace; if it’s a resume, we restore the previous workspace and session JSONL into the VM
  • Inside the VM, the agent reads the message from stdin and calls the Claude Agent SDK query() function.
  • The backend tails the session JSONL file for new records and streams them to the frontend in near real time.
  • When the run completes, we sync the workspace to Google Cloud Storage (GCS) so it can be restored next time.

Try It

Cloud: maru.moru.io - Maru is BYOK (Bring Your Own Key), but your API key is not saved on our server.

Self-hosted: Follow the setup instructions below.

Getting Started (Self-hosted)

Prerequisites

  • Node.js 22+
  • PostgreSQL
  • Moru API Key (for sandbox execution)
  • GitHub OAuth App (for authentication)

Installation

  1. Clone and install dependencies:
git clone https://github.com/moru-ai/maru.git
cd maru
npm install
  1. Set up environment files:
cp apps/server/.env.example apps/server/.env
cp apps/frontend/.env.example apps/frontend/.env
cp packages/db/.env.template packages/db/.env
  1. Configure environment variables:

packages/db/.env

DATABASE_URL="postgresql://postgres:@127.0.0.1:5432/maru_dev"
DIRECT_URL="postgresql://postgres:@127.0.0.1:5432/maru_dev"

apps/server/.env

# Database
DATABASE_URL="postgresql://postgres:@127.0.0.1:5432/maru_dev"

# GitHub OAuth
GITHUB_CLIENT_ID=your_github_client_id
GITHUB_CLIENT_SECRET=your_github_client_secret

# Moru Sandbox (required)
MORU_API_KEY=your_moru_api_key
MORU_TEMPLATE_ID=maru-agent
MORU_SANDBOX_TIMEOUT_MS=3600000

# GCS Storage (optional, for workspace persistence)
GCS_BUCKET_NAME=your-bucket-name
GCS_KEY_FILE=./gcs-key.json

apps/frontend/.env

NEXT_PUBLIC_SERVER_URL="http://localhost:4000"
BETTER_AUTH_SECRET=your_secret_here
GITHUB_CLIENT_ID=your_github_client_id
GITHUB_CLIENT_SECRET=your_github_client_secret
DATABASE_URL="postgresql://postgres:@127.0.0.1:5432/maru_dev"
  1. Set up the database:
# Create database
psql -U postgres -c "CREATE DATABASE maru_dev;"

# Generate Prisma client and push schema
npm run generate
npm run db:push
  1. Build the agent template:
cd apps/agent
cp .env.example .env
# Add your MORU_API_KEY to .env

# Build and register the template
.venv/bin/python template.py
  1. Start development servers:
npm run dev

Development Commands

# Start dev servers (frontend + backend)
npm run dev

# Type checking
npm run check-types

# Linting
npm run lint

# Database operations
npm run db:push        # Push schema changes
npm run generate       # Generate Prisma client
npm run db:studio      # Open Prisma Studio

Rebuilding the Agent Template

After modifying any files in apps/agent/ (including Dockerfile, src/, or INSTRUCTIONS.md), you must rebuild the template:

cd apps/agent
.venv/bin/python template.py

This builds a new Docker image and registers it with Moru. The next sandbox will use the updated template.

License

MIT License

About

A research assistant built with Moru sandbox and Claude Agent SDK

Resources

License

Stars

Watchers

Forks

Contributors