Skip to main content
Glama
John-CEO-HQ

John CEO Agentic Memory

by John-CEO-HQ
README.md
# John CEO Agentic Memory

**John CEO Agentic Memory** is the open-source memory layer for [John CEO](https://john.ceo) - a private AI coworker with a dedicated workspace per customer. This repo is our [CockroachDB x AWS hackathon](https://cockroachdb-x-aws.devpost.com/) submission: MCP tools, CockroachDB native vector indexing, and Amazon Bedrock on AWS Lambda.

Long-term memory for AI agents, backed by **CockroachDB** (native `VECTOR` +
distributed vector index) and **Amazon Bedrock**, exposed over the
[Model Context Protocol (MCP)](https://modelcontextprotocol.io).

> Hackathon: **CockroachDB x AWS - Build with Agentic Memory**. Product: **https://john.ceo**. License: MIT.

Agents feel sharp inside one conversation and amnesiac across sessions. John CEO needs memory that **accumulates**, **retrieves** within
a limited context window, and **forgets** what is outdated - with production-grade
persistence on CockroachDB Cloud and serverless execution on AWS Lambda.

## Architecture

```mermaid
flowchart LR
  agent["MCP client / agent"] -->|"POST /mcp Bearer"| lambda["AWS Lambda Function URL"]
  lambda --> svc["MemoryService"]
  svc -->|"embed + analyze"| bedrock["Amazon Bedrock"]
  svc -->|"VECTOR + hybrid SQL"| crdb["CockroachDB Cloud"]
  cursor["Cursor / Claude Code"] -->|"read-only audit"| managedMcp["Cockroach Managed MCP"]
  managedMcp --> crdb
  ccloud["ccloud CLI"] -.->|"provision + schema"| crdb
```

See also [`docs/architecture.mmd`](docs/architecture.mmd).

## CockroachDB tools used

| Tool | How this project uses it |
|---|---|
| **Distributed Vector Indexing** | `memories.embedding VECTOR(1024)` + `VECTOR INDEX (user_id, status, embedding vector_cosine_ops)`. Every semantic search is an ANN scan through this index, pre-filtered by the `(user_id, status)` prefix so one deployment serves many tenants. Verified with `EXPLAIN` - see [Vector index verification](#vector-index-verification). |
| **Cloud Managed MCP Server** | Read-only audit path from Cursor/Claude Code via `https://cockroachlabs.cloud/mcp`. See [`docs/managed-mcp.md`](docs/managed-mcp.md). |
| **ccloud CLI** | [`scripts/ccloud-bootstrap.sh`](scripts/ccloud-bootstrap.sh) provisions/attaches the cluster, creates DB/user, applies `schema.sql`, then grants least privilege. |
| **Agent Skills** | Four skills from [`cockroachlabs/cockroachdb-skills`](https://github.com/cockroachlabs/cockroachdb-skills) changed this code: retry backoff/jitter and idempotent session counters, statistics-aware index validation, least-privilege grants, and schema/type design. Each change is traced in [`docs/skills-used.md`](docs/skills-used.md). |

## AWS services used

| Service | How |
|---|---|
| **AWS Lambda** | Stateless MCP HTTP handler + Function URL (`POST /mcp`, `GET /` landing). |
| **Amazon Bedrock** | Titan Text Embeddings V2 (1024-d) + Amazon Nova Lite (analyze/consolidate). Optional Claude via inference profile after Anthropic use-case form. |
| **AWS Secrets Manager** | Bearer token + bound `userId` for ACL (see deploy script). |

## Quick start (local, offline)

```bash
npm install
npm run demo          # no cloud credentials needed
npm test
npm run typecheck
npm run seed:demo     # populate demo-user for EXPLAIN / video (needs DATABASE_URL)
```

Copy `.env.example` to `.env`. With `USE_FAKE_BEDROCK=1` the server uses a
deterministic local intelligence (still 1024-d vectors to match the schema).

```bash
npm run build
MCP_TRANSPORT=stdio npm start
```

HTTP mode:

```bash
MCP_TRANSPORT=http PORT=8080 USE_FAKE_BEDROCK=1 npm start
curl -s http://localhost:8080/ | jq .
```

## MCP tools

| Tool | Purpose |
|---|---|
| `memory_write` | Persist a durable memory (Bedrock summary/tags/salience/kind) |
| `memory_search` | Top-k semantic recall (Cockroach vector index when configured) |
| `memory_recall_context` | Pack critical memories into a token budget |
| `memory_forget` | Consolidate related memories + decay stale ones |

All memories are namespaced by `userId`. When `MCP_AUTH_TOKEN` is set, the
server forces `MCP_AUTH_USER_ID` (token-bound ACL).

## Storage

- `MEMORY_STORE=memory` - ephemeral (tests/demo)
- `MEMORY_STORE=file` - JSON file (local default)
- `MEMORY_STORE=cockroach` - CockroachDB Cloud via `DATABASE_URL`

Schema: [`schema.sql`](schema.sql). Embedding dimension is locked at **1024**
(Amazon Titan Text Embeddings V2 default).

### Vector index verification

Two details decide whether the vector index is actually used, and both are easy
to get wrong silently.

**Opclass must match the distance operator.** The index is declared with
`vector_cosine_ops` because search orders by cosine distance (`<=>`). With the
default `vector_l2_ops`, CockroachDB accelerates only `<->`, and the same query
falls back to a full primary-key scan. Measured on v26.2.5 over 2000 rows:

```
-- vector_cosine_ops (current schema), ORDER BY embedding <=> $2
-- plan excerpt, ASCII-rendered:
  vector search
    table: memories@idx_memories_user_embedding
    prefix spans: [/'u1'/'active' - /'u1'/'active']

-- default vector_l2_ops, same cosine query:
  top-k
    scan
      table: memories_l2@memories_l2_pkey     <-- index unused
```

**Only prefix columns may be filtered.** Adding a non-prefix predicate such as a
`created_at_ms >= x` recency bound disqualifies the index: CockroachDB raises
`SQLSTATE 42809` if you hint it, and otherwise silently plans a full scan. The
recency window is therefore applied in `MemoryService` after retrieval, which
keeps ANN acceleration on every search path and makes `recencyDays` behave
identically for the file and in-memory stores.

Note that a vector index will not appear in query plans on an empty or
unanalyzed table - the optimizer picks a plain scan until statistics exist. Test
index behavior against representative data, not an empty schema.

## Cloud setup

1. **CockroachDB** - reuse an existing cluster or run `bash scripts/ccloud-bootstrap.sh`
   (set `CRDB_CLUSTER_NAME` if not using the default `agentic-memory`). For password-based
   non-interactive SQL, install the `cockroach` CLI and set `CRDB_ADMIN_USER` /
   `CRDB_ADMIN_PASSWORD` before running the script.
2. **Managed MCP** - enable in Cloud Console for your cluster; follow [`docs/managed-mcp.md`](docs/managed-mcp.md).
3. **AWS Lambda** - `bash deploy/deploy-lambda.sh` (see [`deploy/README.md`](deploy/README.md)).

### Live demo (staging)

| Item | Value |
|---|---|
| Demo URL | `https://l4ohjmgz52.execute-api.eu-central-1.amazonaws.com/` |
| Judge credentials | [`docs/DEMO-CREDENTIALS.md`](docs/DEMO-CREDENTIALS.md) (shared Bearer token, scoped to `demo-user`) |
| MCP path | `POST /mcp` with Bearer token |
| Cockroach cluster | existing Serverless cluster (`aws-eu-west-1`) |
| Lambda region | `eu-central-1` |

### Amazon Bedrock in `eu-central-1`

| Model | Role | Setup |
|---|---|---|
| `amazon.titan-embed-text-v2:0` | Embeddings (1024-d) | Works out of the box |
| `eu.amazon.nova-lite-v1:0` | Analyze / consolidate (default chat) | Works out of the box |
| `eu.anthropic.claude-haiku-4-5-20251001-v1:0` | Optional chat upgrade | Requires the one-time Anthropic use-case form in the Bedrock console (Model access) |

You do **not** need Claude 3.5 Haiku specifically - it is not offered as a direct on-demand model in Frankfurt. The defaults above are sufficient for the hackathon demo.

## Security

- Bearer auth on HTTP/Lambda (`MCP_AUTH_TOKEN` or Secrets Manager).
- Token-bound `userId` - clients cannot query another tenant's rows.
- Least-privilege SQL user (DML only on `memories` / `sessions`).
- Managed MCP kept read-only for operator audit.
- TLS everywhere (`sslmode=verify-full` on CockroachDB Cloud).
- Structured JSON logs include request id / tool / latency / row counts - **never** memory content.

## What happens when things go wrong

- **Serialization failure (SQLSTATE 40001):** retried up to 3 times with exponential backoff plus jitter, so colliding writers do not retry in lockstep. A `40001` means CockroachDB already aborted the transaction, so replaying the unit of work is always safe.
- **Connection loss / ambiguous commit (`08xxx`, `57P01`):** also retried. This is safe only because every statement is idempotent - memory rows upsert on a client-generated primary key, and `sessions.memory_count` is derived with `COUNT(*)` rather than incremented, so a replay cannot double-count.
- **Unmigrated database:** startup fails fast with the missing table names instead of erroring inside the first tool call.
- **Lambda timeout:** keep tool work bounded; Function timeout defaults to 60s in the deploy script.
- **Bedrock / network errors:** surfaced as MCP tool errors; fake mode available for offline demos.

## Example MCP client config (local stdio)

```json
{
  "mcpServers": {
    "agentic-memory": {
      "command": "node",
      "args": ["dist/index.js"],
      "env": {
        "USE_FAKE_BEDROCK": "1",
        "MEMORY_STORE": "file"
      }
    }
  }
}
```

## Hackathon evidence

- [`docs/SUBMISSION.md`](docs/SUBMISSION.md) - project summary for Devpost
- [`docs/RESULTS.md`](docs/RESULTS.md) - benchmarks and EXPLAIN evidence
- [`docs/DEMO-CREDENTIALS.md`](docs/DEMO-CREDENTIALS.md) - live demo Bearer token and curl examples

## License

MIT - see [`LICENSE`](LICENSE).

TDQS

A3.9/5.0

Scored across 4 tools

Disambiguation5/5

Each tool serves a clearly distinct purpose: write persists, search retrieves, recall_context packs, forget maintains. There is no overlap in functionality, reducing risk of misselection.

Naming Consistency5/5

All tools follow a consistent memory_verb pattern (memory_write, memory_search, memory_recall_context, memory_forget). The naming is predictable and uniform, simplifying agent tool selection.

Tool Count5/5

Four tools is a tightly scoped set that covers the core memory operations without redundancy. Each tool earns its place, fitting the recommended 3-15 range.

Completeness5/5

The set covers the full memory lifecycle: create/write, retrieve/search, recall context for injection, and forget/maintenance for updates and deletions. No obvious gaps for the stated purpose of persistent user memory.

Maintenance

ActivitySlowing
ResponsivenessNo issues