![RushDB Logo](https://raw.githubusercontent.com/rush-db/rushdb/main/rushdb-logo.svg) # RushDB ### The memory layer for AI agents and apps. Push any JSON. Your agent gets a live, queryable schema, graph relationships, and semantic search β€” inferred automatically. No pipeline. No separate stores. No schema to design. [![GitHub Stars](https://img.shields.io/github/stars/rush-db/rushdb?style=social)](https://github.com/rush-db/rushdb) [![Follow on X](https://img.shields.io/twitter/follow/rushdb?style=social)](https://x.com/RushDatabase) [![NPM Version](https://img.shields.io/npm/v/%40rushdb%2Fjavascript-sdk?label=npm)](https://www.npmjs.com/package/@rushdb/javascript-sdk) [![PyPI Version](https://img.shields.io/pypi/v/rushdb?label=pypi)](https://pypi.org/project/rushdb/) [![License](https://img.shields.io/badge/license-Apache%202.0-blue)](packages/javascript-sdk/LICENSE) [![CI](https://img.shields.io/github/actions/workflow/status/rush-db/rushdb/ci.yml?label=tests)](https://github.com/rush-db/rushdb/actions) [🌐 Website](https://rushdb.com) β€’ [πŸ“– Documentation](https://docs.rushdb.com) β€’ [☁️ Cloud](https://app.rushdb.com) β€’ [πŸ” Examples](https://github.com/rush-db/examples) **English** β€’ [δΈ­ζ–‡](README_ZH.md) β€’ [ζ—₯本θͺž](README_JA.md) β€’ [ν•œκ΅­μ–΄](README_KO.md) β€’ [Deutsch](README_DE.md) β€’ [FranΓ§ais](README_FR.md) β€’ [PortuguΓͺs](README_PT.md) β€’ [EspaΓ±ol](README_ES.md) β€’ [ΰ€Ήΰ€Ώΰ€¨ΰ₯ΰ€¦ΰ₯€](README_HI.md) β€’ [Ψ§Ω„ΨΉΨ±Ψ¨ΩŠΨ©](README_AR.md) β€’ [Bahasa Indonesia](README_ID.md) β€’ [ΰΉ„ΰΈ—ΰΈ’](README_TH.md)
--- ## The problem Your agent needs memory. The standard answer is three databases: Redis for key-value, a vector store for semantic search, a graph DB for relationships β€” plus glue code to keep them in sync. RushDB replaces all three. Push JSON once. Query it with graph traversal, semantic search, or both β€” in one call. | Without RushDB | With RushDB | | ----------------------------------------- | -------------------------------------- | | Redis + Pinecone + Neo4j + glue code | One API | | Design schema β†’ write migrations β†’ repeat | Push any shape, no schema required | | Separate embedding pipeline | Managed embeddings, server-side | | Hand-craft relationship edges | Auto-detected from your data structure | --- ## Quick start Two paths depending on your setup: - **Cloud** β€” Managed, free tier, running in 30 seconds. [Get API key β†’](https://app.rushdb.com) - **Self-host** β€” Docker + your own Neo4j instance. [Jump to Self-hosting β†’](#self-hosting) ### Cloud path ```bash npm install @rushdb/javascript-sdk # or pip install rushdb ``` ### Store and recall agent memory ```typescript import RushDB from '@rushdb/javascript-sdk' const db = new RushDB('RUSHDB_API_KEY') // One-time: tell RushDB to auto-embed 'output' on every write await db.ai.indexes.create({ label: 'MEMORY', propertyName: 'output' }) // Store an agent action β€” no embedder, no vectors array await db.records.create({ label: 'MEMORY', data: { agent_id: 'agent-42', session_id: 'sess-001', action: 'summarized', topic: 'Q4 results', output: summaryText } }) // Recall by meaning β€” graph filter + semantic search in one call const memories = await db.records.vectorSearch({ labels: ['MEMORY'], propertyName: 'output', query: 'what did we decide about Q4?', where: { agent_id: 'agent-42' }, limit: 10 }) ``` ```python from rushdb import RushDB db = RushDB('RUSHDB_API_KEY') # Store β€” graph links sessions, actions, and context automatically db.records.create( label='MEMORY', data={ 'agent_id': 'agent-42', 'action': 'summarized', 'topic': 'Q4 results', 'output': summary_text, }, ) # Recall β€” traverse relationships and filter by meaning results = db.records.find({ 'labels': ['MEMORY'], 'where': { 'agent_id': 'agent-42', 'topic': {'$contains': 'Q4'}, }, 'limit': 10, }) ``` --- ## Working with your data ### Import nested JSON Push any JSON shape. Nested objects and arrays of objects become linked records β€” labels, types, and relationships are inferred on write. No schema, no migration step. ```typescript await db.records.importJson({ label: 'COMPANY', data: { name: 'Acme Corp', DEPARTMENT: [ { name: 'Engineering', budget: 2_000_000, EMPLOYEE: [ { name: 'Alice', role: 'Staff Engineer', salary: 210_000 }, { name: 'Bob', role: 'Engineer', salary: 160_000 } ] } ] } }) ``` Each nested key (`DEPARTMENT`, `EMPLOYEE`) becomes a label, each object a record, and containment a relationship β€” all created automatically. ### Import CSV ```typescript const csv = `name,email,department Alice,alice@acme.co,Engineering Bob,bob@acme.co,Sales` await db.records.importCsv({ label: 'EMPLOYEE', data: csv, options: { suggestTypes: true, skipEmptyValues: true }, parseConfig: { header: true } }) ``` `suggestTypes` infers numbers, booleans, and dates from strings; `skipEmptyValues` treats blank cells as unset instead of storing empty values (`0` and `false` are kept). ### Traverse the graph Filter root records by conditions on their _related_ records β€” arbitrarily deep β€” in a single query. Related labels go **inside** `where`, not in `labels`: ```typescript // Engineers in Acme's Engineering department const engineers = await db.records.find({ labels: ['EMPLOYEE'], where: { role: { $contains: 'Engineer' }, DEPARTMENT: { name: 'Engineering', COMPANY: { name: 'Acme Corp' } } } }) ``` ### Analytical queries (aggregate & group by) `select` shapes the output with aggregations (`$sum`, `$avg`, `$count`, `$min`, `$max`); `groupBy` controls the dimensions. Don't add `limit` to an aggregation β€” it would scan only the first N records and skew the totals. ```typescript // Portfolio KPIs across ALL projects β†’ one row const kpis = await db.records.find({ labels: ['PROJECT'], select: { totalBudget: { $sum: '$record.budget' }, avgBudget: { $avg: '$record.budget', $precision: 2 }, projectCount: { $count: '*' } }, groupBy: ['totalBudget', 'avgBudget', 'projectCount'], orderBy: { totalBudget: 'asc' } // late-ordering β†’ aggregates the full dataset }) // β†’ [{ totalBudget: 18_750_000, avgBudget: 568181.82, projectCount: 33 }] // Breakdown by dimension β†’ one row per status const byStatus = await db.records.find({ labels: ['PROJECT'], select: { count: { $count: '*' }, avgBudget: { $avg: '$record.budget', $precision: 2 } }, groupBy: ['$record.status'], orderBy: { count: 'desc' } }) // β†’ [{ status: 'active', count: 18, avgBudget: 612000 }, { status: 'paused', count: 9, ... }] ``` Aggregations compose with traversal β€” e.g. headcount and payroll per department: ```typescript const payroll = await db.records.find({ labels: ['DEPARTMENT'], where: { EMPLOYEE: { $alias: '$emp' } }, // alias the related node for use in select select: { headcount: { $count: '*' }, payroll: { $sum: '$emp.salary' } }, groupBy: ['$record.name'], orderBy: { payroll: 'desc' } }) // β†’ [{ name: 'Engineering', headcount: 2, payroll: 370000 }, ...] ``` --- ## Connect to Claude, Cursor, or any MCP client RushDB ships an MCP server. Your agent gets persistent, structured memory β€” out of the box. ```json { "mcpServers": { "rushdb": { "command": "npx", "args": ["@rushdb/mcp-server"], "env": { "RUSHDB_API_KEY": "your-api-key-here" } } } } ``` Place this in your Claude Desktop, Cursor, or Windsurf MCP config. The agent can now create records, search by meaning, traverse relationships, and introspect the schema β€” all via natural language. --- ## What's in the box | Capability | What it means | | ------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | | **Managed embeddings** | Index any string property once β€” every write is auto-embedded server-side | | **Graph + vector in one query** | Semantic similarity and relationship traversal compose in a single call | | **Zero schema** | Push any JSON shape. RushDB infers types, creates properties, links records | | **Inferred schema** | Properties become first-class nodes β€” types, labels, and relationships are discovered on write, so a queryable schema builds itself as data arrives | | **ACID transactions** | Concurrent agents don't corrupt shared memory. Neo4j under the hood | | **Self-describing** | Agents introspect the inferred schema β€” labels, properties, value ranges β€” to know what they can safely query | | **MCP-native** | Full MCP server with discovery-first query prompt built in | | **Agent Skills** | Installable `@rushdb/skills` package β€” teach any skills-compatible agent to query, model, and remember with RushDB in one command | | **Unified query API** | One JSON shape for graph, vector, aggregation, and introspection | | **Self-host or cloud** | Docker + your Neo4j, or managed cloud. Full data ownership | --- ## Use cases | Use case | What RushDB replaces | Key API | | --------------------------- | ------------------------------- | ------------------------------------------------------------- | | **Agent memory** | Redis + vector store + graph DB | `db.records.vectorSearch({ query, where: { agent_id } })` | | **RAG with context** | Flat vector store | `db.records.find({ where, labels })` + relationship traversal | | **Schema-free apps** | Postgres + migrations + ETL | `db.records.importJson(nestedJson)` | | **Connected data products** | Multiple joined services | `db.records.find({ labels, where: { SOME_LABEL: { ... } } })` | --- ## Self-hosting > **Self-host path** β€” run RushDB on your own infrastructure. Requires Neo4j 2026.01.4+ with APOC plugin. ```yaml # docker-compose.yml version: '3.8' services: rushdb: image: rushdb/platform ports: - '3000:3000' environment: - NEO4J_URL=neo4j+s://your-instance.neo4j.io - NEO4J_USERNAME=neo4j - NEO4J_PASSWORD=password - RUSHDB_AES_256_ENCRYPTION_KEY=32-char-key-here - RUSHDB_LOGIN=admin - RUSHDB_PASSWORD=secure-password # Optional: managed continuous-sync connectors via synx - RUSHDB_BASE_URL=https://rushdb.example.com - RUSHDB_SYNX_CONTROL_TOKEN=long-random-shared-token - RUSHDB_SYNX_DESTINATION_API_KEY=internal-write-api-key ```
Full environment variables | Name | Description | Required | Default | | --------------------------------- | ---------------------------------------------- | ---------- | -------- | | `NEO4J_URL` | Neo4j connection URL | yes | β€” | | `NEO4J_USERNAME` | Neo4j username | yes | neo4j | | `NEO4J_PASSWORD` | Neo4j password | yes | β€” | | `RUSHDB_AES_256_ENCRYPTION_KEY` | 32-char key for API token encryption | yes (prod) | β€” | | `RUSHDB_PORT` | HTTP port | no | 3000 | | `RUSHDB_LOGIN` | Admin login | no | admin | | `RUSHDB_PASSWORD` | Admin password | no | password | | `RUSHDB_BASE_URL` | Public/base API URL for synx assignments | no | β€” | | `RUSHDB_SYNX_CONTROL_TOKEN` | Internal token for managed synx workers | no | β€” | | `RUSHDB_SYNX_DESTINATION_API_KEY` | Internal write key for synx destination writes | no | β€” | Managed synx workers run as daemons. They poll for runnable connectors, renew connector leases, release leases on graceful shutdown, and let platform/core reclaim expired leases after crashes.
Local development (bundled Neo4j) ```yaml version: '3.8' services: rushdb: image: rushdb/platform depends_on: neo4j: condition: service_healthy ports: - '3000:3000' environment: - NEO4J_URL=bolt://neo4j - NEO4J_USERNAME=neo4j - NEO4J_PASSWORD=password neo4j: image: neo4j:2026.01.4 healthcheck: test: ['CMD-SHELL', 'wget --no-verbose --tries=1 --spider localhost:7474 || exit 1'] interval: 5s retries: 30 start_period: 10s ports: - '7474:7474' - '7687:7687' environment: - NEO4J_ACCEPT_LICENSE_AGREEMENT=yes - NEO4J_AUTH=neo4j/password volumes: - ./neo4j-plugins:/var/lib/neo4j/plugins ```
```bash # Manage users via CLI rushdb create-user admin@example.com securepassword123 rushdb update-password admin@example.com newsecurepassword456 ```
Architecture: how RushDB structures data (LMPG) RushDB uses a **Labeled Meta Property Graph (LMPG)** model. Properties are elevated to first-class graph nodes ("HyperProperties") β€” not just key-value pairs attached to records. This means: - **Schema without upfront design** β€” because properties are graph nodes, the schema is _inferred from your data, not designed_: labels, types, value ranges, and relationship topology are discovered on write and queryable immediately β€” no manual schema modeling, no RDF/OWL toolchain - **Auto-detected relationships** β€” records sharing properties get linked without hand-crafting edges - **Schema introspection** β€” agents can enumerate labels, property types, value ranges, and relationship topology in one query - **Soft constraints** β€” type cohesion scoring, cardinality tracking, and vector dimension enforcement without rigid upfront schemas - **Unified query surface** β€” the same filter expression works across records, labels, properties, and relationships One SearchQuery retrieves multiple perspectives simultaneously (records + property stats + aggregations), avoiding the N+1 inspection pattern common in separate-system architectures. [Read the full LMPG architecture post β†’](https://rushdb.com/blog/labeled-meta-property-graphs-rushdb-s-revolutionary-approach-to-graph-database-architecture)
--- ## Documentation | Topic | Link | | ------------------------ | -------------------------------------------------------------- | | Quick Tutorial | https://docs.rushdb.com/get-started/quick-tutorial | | Vector / Semantic Search | https://docs.rushdb.com/concepts/search/where#vector-operators | | Filtering & Traversal | https://docs.rushdb.com/concepts/search/where | | Grouping & Aggregations | https://docs.rushdb.com/concepts/search/group-by | | TypeScript SDK | https://docs.rushdb.com/typescript-sdk/introduction | | Python SDK | https://docs.rushdb.com/python-sdk/introduction | | REST API | https://docs.rushdb.com/rest-api/introduction | | MCP Server | packages/mcp-server/README.md | | Agent Skills | packages/skills/README.md | --- ## When not to use RushDB - You need sub-millisecond latency at very high write throughput β€” RushDB is built on Neo4j, which prioritises consistency and query expressiveness over raw write speed. - You only need flat key-value storage with no relationships or semantic search β€” a simpler store will be lighter. - You need a rigid relational schema enforced at the database level β€” RushDB is deliberately schema-free. --- ## Contributing ```bash git clone https://github.com/rush-db/rushdb.git cd rushdb pnpm install pnpm test ``` See [CONTRIBUTING.md](CONTRIBUTING.md) for full guidelines. Issues and PRs welcome. --- ## License | Path | License | | ----------------------- | ------------------- | | platform/core | Elastic License 2.0 | | platform/dashboard | Elastic License 2.0 | | docs | Apache 2.0 | | website | Apache 2.0 | | packages/javascript-sdk | Apache 2.0 | | packages/mcp-server | Apache 2.0 | --- Need something not supported yet? Open an issue β€” design discussions are welcome.