# Kevy

> kevy — a pure-Rust, zero-dependency, Redis-compatible serving engine: declared indexes, CJK full-text + vector search, views, CDC feeds, replication & failover, MCP

- **Type:** MCP server
- **Install:** `agentstack add mcp-goliajp-kevy`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [goliajp](https://agentstack.voostack.com/s/goliajp)
- **Installs:** 0
- **Category:** [Databases](https://agentstack.voostack.com/c/databases)
- **Latest version:** 0.1.0
- **License:** Apache-2.0
- **Upstream author:** [goliajp](https://github.com/goliajp)
- **Source:** https://github.com/goliajp/kevy
- **Website:** https://github.com/goliajp/kevy

## Install

```sh
agentstack add mcp-goliajp-kevy
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# kevy

**English** · [简体中文](README.zh-CN.md) · [日本語](README.ja.md)

[](https://github.com/goliajp/kevy/actions/workflows/ci.yml?query=branch%3Adevelop)
[](#license)

A pure-Rust, zero-dependency, Redis-compatible key–value store. Use it as
a standalone server, an in-process library, or both — every form speaks
RESP2, so `redis-cli` and every Redis client library work unchanged.

```sh
cargo install kevy
kevy --port 6379 &
redis-cli -p 6379 SET hello world
redis-cli -p 6379 GET hello
```

## What kevy is

kevy ships in three forms, all built from the same engine:

- **Server** — a Redis-wire-compatible daemon. Speaks RESP2, replies are
  reply-checked byte-for-byte against valkey 9.1 for 94 commands.
- **Embedded library** — `kevy-embedded` is the same engine without the
  network. Drop it into a Rust binary and call `Store` directly. Pure
  Rust, zero dependencies, feature-tiered from a bare `core` KV up to
  the full index/replication surface — and it reaches both extremes:
  the browser ([`@goliapkg/kevy`](docs/wasm.md) on npm) and 655 KB IoT
  builds ([docs/iot.md](docs/iot.md)).
- **Clients** — `kevy-client` (blocking) and `kevy-client-async` (one
  feature flag per runtime: tokio / smol / async-std). Both accept a
  URL so the same code targets a TCP server (`kevy://host:port`) or an
  in-process bus (`mem://name`).

## kevy 4 — a serving engine, set in stone

3.x declared kevy a **serving engine**: the primary store for
applications that would otherwise run an RDS with a cache in front.
On top of full Redis parity you get declared secondary indexes
(range / unique / CJK full-text / vector ANN, with server-side hybrid
BM25 + KNN fusion) with one-hop hydration, composable views (virtual
and materialized top-K), a CDC feed with exact recovery points (the
built-in outbox), and a migration toolchain with checksummed
verification — all derived-by-construction (maintained in the write
path, never drifting, rebuilt from data). The 3.x mainline adds the
machine faces — a self-describing verb contract (`COMMAND DOCS`,
generated references, an official MCP server in `kevy-mcp`) — and the
availability arc: streaming replication with heartbeat/ACK lag truth,
planned zero-loss handover (`FAILOVER`) plus quorum crash elections,
and an opt-in consistency ladder (`WAIT`, read-your-writes tokens,
bounded staleness, quorum-fenced writes) — see
[docs/availability.md](docs/availability.md).
4.0 sets it in stone: the public Rust API was consolidated once —
one error type (`KevyError`), one builder, borrowed write faces
([docs/UPGRADING.md](docs/UPGRADING.md)) — and is frozen add-only;
the runtime is instance-scoped, so one process can run several
independent kevys; and the same engine now ships to the browser and
to the edge (the two sections below).
4.0 also raises the capacity ceiling: your dataset no longer has to
fit in RAM. **Transparent tiering** gives the store a RAM budget —
cold values spill to a disposable on-disk value log and page back on
access, every command keeps its exact semantics on a cold key, and
the AOF durability contract is untouched, so RAM bounds your keys
and disk bounds your data. The **TABLE layer** compiles relational
declarations — typed columns, secondary indexes, composite `ORDER BY`
paths, even a PG/MySQL schema file via `kevy-sql` — into named
indexes at declare time, so the single-table read path stays a
lookup and index-only queries answer from RAM even when every row is
cold. See [docs/tiering.md](docs/tiering.md) and
[docs/tables.md](docs/tables.md).
Every headline number is gated and re-measured on every train:
hydrated row-list pages p99                                      
  jp.goliakevy6.4.0

```

The Go module is the remote client; its embedded engine is cgo against
a static library, which a Go module cannot carry, so that half builds
from this tree with `-tags kevy_embedded` (see
[bindings/go](bindings/go)). Swift has no registry to be on: SwiftPM
resolves `KevyKit` from this repository's tags (see
[bindings/apple/KevyKit](bindings/apple/KevyKit)).

The Rust surface is on crates.io:

```sh
# Server
cargo install kevy
# …or without a Rust toolchain (Linux x86_64 / aarch64, macOS Apple Silicon)
npm install -g @goliapkg/kevy-bin

# Embedded library
cargo add kevy-embedded

# Blocking client
cargo add kevy-client

# Async client (pick one runtime feature)
cargo add kevy-client-async --features tokio
```

Pre-built server binaries are attached to every [GitHub Release](https://github.com/goliajp/kevy/releases)
for Linux x86_64, Linux aarch64, and macOS Apple Silicon. A multi-arch
Docker image is published to both [Docker Hub](https://hub.docker.com/r/goliakk/kevy)
and [GitHub Container Registry](https://github.com/goliajp/kevy/pkgs/container/kevy):

```sh
docker run --rm -p 6379:6379 goliakk/kevy:latest
```

## Quick start

### Server

```sh
kevy --port 6379 &
redis-cli -p 6379 SET foo bar
redis-cli -p 6379 GET foo
```

Configuration precedence is CLI flags → environment variables → TOML
file → built-in defaults. The full annotated schema lives in
[`crates/kevy/kevy.toml.example`](crates/kevy/kevy.toml.example).

### Embedded library

```rust
use kevy_embedded::{Config, Store};

let store = Store::open(Config::default().without_aof())?;
store.set(b"key", b"value")?;
assert_eq!(store.get(b"key")?, Some(b"value".to_vec()));
# Ok::(())
```

`Store` is `Clone` and every method takes `&self`, so a clone can move
between threads freely. For a file-backed store use
`Config::default().with_persist("/var/lib/myapp")`.

### Blocking client

```rust
use kevy_client::Connection;

let mut conn = Connection::connect("tcp://127.0.0.1:6379")?;
conn.set(b"k", b"v")?;
let v = conn.get(b"k")?;
assert_eq!(v.as_deref(), Some(&b"v"[..]));
# Ok::(())
```

The same URL surface accepts `mem://app` for an in-process backend, so
the same code paths run against an embedded store in tests and a
networked server in production.

### Async client

```rust,no_run
use kevy_client_async::AsyncConnection;

# async fn run() -> std::io::Result {
let mut conn = AsyncConnection::connect("tcp://127.0.0.1:6379").await?;
conn.set(b"k", b"v").await?;
let v = conn.get(b"k").await?;
# Ok(())
# }
```

Pick exactly one of `tokio`, `smol`, or `async-std` as a Cargo feature;
the crate refuses to compile on zero or more than one.

## In the browser

kevy runs in the browser as a real store: the npm package
[`@goliapkg/kevy`](https://www.npmjs.com/package/@goliapkg/kevy) ships
the engine compiled to `wasm32-unknown-unknown` behind a hand-written
ES-module loader — no wasm-bindgen, zero dependencies on either side
of the boundary; six files, 496 KB packed (481 KB gzipped over the wire).

```sh
npm install @goliapkg/kevy
```

```js
import { open } from "@goliapkg/kevy";

const db = await open({ persist: { name: "app" } });
db.set("session", "abc123", { ttlMs: 60_000 });
db.subscribe("events", (payload) => { /* fires from any tab */ });
```

- **Durable**: writes stream to OPFS (IndexedDB fallback) as a kevy
  append-only log, byte-compatible with native kevy — a log written
  in the browser replays on a server.
- **Cross-tab pub/sub** over a BroadcastChannel bridge, with the same
  at-most-once contract as the server.
- **Fast where a store needs to be**: 77–86× IndexedDB on point reads,
  166–189× on point writes, and 12.6–17.4× its durable-write rate
  ([`bench/WASM-BENCH.md`](bench/WASM-BENCH.md)).

[docs/wasm.md](docs/wasm.md) has the loader API and the ABI contract;
[kevy.golia.jp/demo](https://kevy.golia.jp/demo/) is the whole thing
live — a browser REPL with persistence and cross-tab pub/sub, no
backend.

## On the edge (IoT)

The same embedded library scales down. `kevy-embedded` is
feature-tiered (`core` / `persist` / `index` / `text` / `vector` /
`replicate` / `listener`; the default is everything), and the `core`
tier compiles to a **655 KB** binary (budget ≤ 700 KB) that opens an
empty store in under 2 MB of RSS — both lines enforced as a ratchet
by [`bench/iotgate.sh`](bench/iotgate.sh).

- Static musl cross-builds for `aarch64` and `armv7` are gated in CI.
- Below Linux entirely: five foundation crates (`kevy-store`,
  `kevy-hash`, `kevy-bytes`, `kevy-map`, `kevy-madvise`) build
  `no_std` + `alloc`, proven on a Cortex-M target
  (`thumbv7em-none-eabihf`).

See [docs/iot.md](docs/iot.md) for the tier table, the budgets, and a
sensor-cache example.

## Performance

A representative slice from the bare-metal benchmark suite (16-core
Linux box, server and client pinned to disjoint cores, TCP loopback).
The KV rows below are `bench/arena.sh`, re-measured 2026-07-19:
median-of-5, throughput read from each server's own command counter
over a timed window. Full method, every workload, and the caveats live
in [`bench/REPORT.md`](bench/REPORT.md); every figure is reproducible
from a script in [`bench/`](bench/).

| Workload | kevy | valkey 9.1 | Ratio |
|---|---:|---:|---:|
| `GET -c 50 -P 16` | 7.49 M/s | 2.98 M/s | **2.51×** |
| `SET -c 50 -P 16` | 6.82 M/s | 1.68 M/s | **4.05×** |
| Pub/sub fan-out (50 subs) | 23.1 M/s | 5.1 M/s | **4.52×** |
| Embedded `get` (hit) | 9.0 M/s | — | (no in-process Redis) |

The same `GET -c 50 -P 16` face, four engines on one box — kevy at 7.49 M/s against each (median-of-5; method and per-engine cycle
accounting in
[`bench/REPORT.md`](bench/REPORT.md)):

| Engine | kevy's lead |
|---|---:|
| valkey 9.1.2 | **2.34×** |
| redis 8.10.1 | **1.26×** |
| dragonfly 1.40.2 | **2.62×** |

These ratios are **lower than the ones published before 2026-07-19**,
and the reason is the ruler, not the engines. The earlier figures read
`redis-benchmark`'s own reported rate, which under `--threads` is
quantized to multiples of its 250 ms sampling timer and therefore
understated — unevenly, so the ratio moved too. Counting server-side
removes the quantization; kevy's own number went UP (6.39 → 7.24 M/s)
and every competitor's went up more.

The pub/sub and embedded rows are from their own harnesses and were
not part of this re-measurement.

And the serving face vs redis-stack 7.4.7 (RediSearch), same seeded
corpora, recall-aligned ([`bench/PERF-LEDGER.md`](bench/PERF-LEDGER.md)):

| Query class | kevy | RediSearch | Verdict |
|---|---:|---:|---|
| Full-text (BM25 top-10) | 330 qps | 273 qps | **+21% qps**, p95 tie |
| ANN KNN @ recall 1.000 | 0.48 ms | 0.79 ms | **1.64× ahead** |
| GROUP BY top-100 | 1.9 ms | 202.9 ms | **110×** (write-time aggregates) |
| Numeric range + hydrate | 0.19 ms | 0.43 ms | **2.3×** |

A complete server is a 768 KB stripped binary that boots into under
5 MB of RSS.

**Upgrading?** [docs/upgrading-6.3-to-6.4.md](docs/upgrading-6.3-to-6.4.md)
is the current hop: nothing to change in code and nothing on disk moves,
but five answers that were wrong are now right — `GEOSEARCH` near the
poles, `used_memory` for `APPEND`-grown strings, overflowing month and year
bounds, a `regexp_*` alternation, and io_uring disconnects — each measured
against 6.3.0. The hop before it is
[docs/upgrading-6.2-to-6.3.md](docs/upgrading-6.2-to-6.3.md).
[docs/UPGRADING.md](docs/UPGRADING.md) covers the
older majors — 3.x → 4.0 (wire and disk carry over; the Rust
API changed once, with a table and a rule for every rename) and
2.x → 3.x (binary swap + dependency bump). Snapshots and AOF load
as-is across majors in the upgrade direction.

## Compatibility

94 commands are reply-checked byte-for-byte against valkey 9.1,
covering all five Redis data types (String, Hash, List, Set, Sorted
Set) plus Streams, Pub/Sub (channel + pattern), Transactions (`MULTI` /
`EXEC` / `WATCH` / `UNWATCH`), Blocking pops, and the standard
operations and persistence verbs. The full command list is in
[`MIGRATION-FROM-VALKEY.md`](MIGRATION-FROM-VALKEY.md).

Client libraries verified end-to-end against kevy:

| Language | Library | Version |
|---|---|---|
| Java | [Jedis](https://github.com/redis/jedis) | 5.x |
| .NET | [StackExchange.Redis](https://stackexchange.github.io/StackExchange.Redis/) | 2.x |
| Go | [go-redis](https://github.com/redis/go-redis) | v9 |
| Python | [redis-py](https://github.com/redis/redis-py) | 5.x |
| Python | [Celery](https://docs.celeryq.dev/) | 5.6 |
| Ruby | [Sidekiq](https://sidekiq.org/) | 6.5 |
| Node.js | [ioredis](https://github.com/redis/ioredis) | 5.7 |
| Node.js | [BullMQ](https://github.com/taskforcesh/bullmq) | 5.79 |
| Node.js | [Bee Queue](https://github.com/bee-queue/bee-queue) | 1.7 |
| Node.js | [node-redlock](https://github.com/mike-marcacci/node-redlock) | 5 |

All run unmodified against a default `kevy --port 6379` instance.

## Crates

| Crate | Role |
|---|---|
| [`kevy`](crates/kevy) | The server binary and library entry-point |
| [`kevy-embedded`](crates/kevy-embedded) | In-process KV with the Redis-shaped Rust API |
| [`kevy-client`](crates/kevy-client) | Blocking RESP client; URL facade for server or in-process backend — **carries the workspace version since 6.2.1** (was a 2.x line of its own; see [docs/upgrading-6.2.0-to-6.2.1.md](docs/upgrading-6.2.0-to-6.2.1.md)) |
| [`kevy-client-async`](crates/kevy-client-async) | Async mirror of `kevy-client` for tokio / smol / async-std — **workspace version since 6.2.1**, like `kevy-client` |
| [`kevy-cluster-rw`](crates/kevy-cluster-rw) | Primary-write / replica-read client wrapper |
| [`kevy-cli`](crates/kevy-cli) | Operator CLI: backup, restore, smoke tests |
| [`kevy-config`](crates/kevy-config) | TOML config schema with CLI/env/file precedence |
| [`kevy-resp-client`](crates/kevy-resp-client) | Low-level RESP2 client primitive |
| [`kevy-bytes`](crates/kevy-bytes) | Owned byte string with inline-or-heap small-string optimization |
| [`kevy-hash`](crates/kevy-hash) | Fast non-cryptographic hash for single-trust-domain keyspaces |
| [`kevy-map`](crates/kevy-map) | Swiss-table hashmap with SIMD group scan |
| [`kevy-resp`](crates/kevy-resp) | Zero-allocation RESP2 / 3 parser |
| [`kevy-ring`](crates/kevy-ring) | Bounded lock-free SPSC queue |
| [`kevy-madvise`](crates/kevy-madvise) | Linux `MADV_HUGEPAGE` wrapper; no-op elsewhere |
| [`kevy-uring`](crates/kevy-uring) | Pure-Rust io_uring bindings — no liburing linked |
| [`kevy-geo`](crates/kevy-geo) | Geospatial command primitives |
| [`kevy-wasm`](crates/kevy-wasm) | The browser build: hand-written C ABI + the `@goliapkg/kevy` loader |
| [`kevy-lua`](crates/kevy-lua) | Lua scripting bridge (backed by the [luna](https://github.com/goliajp/luna) runtime) |

The remaining crates (`kevy-store`, `kevy-rt`, `kevy-persist`,
`kevy-sys`, `kevy-elect`, `kevy-replicate`, `kevy-scope`,
`kevy-lua-host`, `kevy-chaos`, `kevy-bench`, `kevy-pubsub-bench`) are
internal infrastructure for the server and embedded library — they are
published so the workspace builds reproducibly, but end users typically
reach for the surfaces above.

**For AI agents & tools**: [`llms.txt`](llms.txt) (machine-first index) ·
[verb reference](docs/verb-reference.md) (all 189 verbs, generated from the
server's own metadata — the same rows `COMMAND DOCS` serves).

## Topic guides

| Topic | Doc |
|---|---|
| RDS workload mapping (SQL → kevy) | [`docs/rds-workloads.md`](docs/rds-workloads.md) |
| Migration playbook & toolchain | [`docs/migration.md`](docs/migration.md) |
| Configuration tuning | [`docs/tuning.md`](docs/tuning.md) |
| Persistence (AOF + RDB) | [`docs/persistence.md`](docs/persistence.md) |
| Pub/Sub | [`docs/pubsub.md`](docs/pubsub.md) |
| Replication | [`docs/replication.md`](docs/replication.md) |
| Cluster mode | [`docs/cluster.md`](docs/cluster.md) |
| Deploying behind a proxy (TLS) | [`docs/deploy-behind-a-proxy.md`](docs/deploy-behind-a-proxy.md) |
| Lua scripting | [`docs/lua.md`](docs/lua.md) |
| Unix-domain socket | [`docs/uds.md`](docs/uds.md) |
| Async client | [`docs/async.md`](docs/async.md) |
| Browser / WASM | [`docs/wasm.md`](docs/wasm.md) |
| Electron apps | [`docs/electron.md`](docs/electron.md) |
| Tauri apps | [`docs/tauri.md`](docs/tauri.md) |
| IoT & feature tiers | [`docs/iot.md`](do

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [goliajp](https://github.com/goliajp)
- **Source:** [goliajp/kevy](https://github.com/goliajp/kevy)
- **License:** Apache-2.0
- **Homepage:** https://github.com/goliajp/kevy

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** yes
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-goliajp-kevy
- Seller: https://agentstack.voostack.com/s/goliajp
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
