John CEO Agentic Memory
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@John CEO Agentic MemorySearch my memories for notes about the board meeting."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
John CEO Agentic Memory
John CEO Agentic Memory is the open-source memory layer for John CEO - a private AI coworker with a dedicated workspace per customer. This repo is our CockroachDB x AWS hackathon 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).
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
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"| crdbSee also docs/architecture.mmd.
Related MCP server: brain-mcp
CockroachDB tools used
Tool | How this project uses it |
Distributed Vector Indexing |
|
Cloud Managed MCP Server | Read-only audit path from Cursor/Claude Code via |
ccloud CLI |
|
Agent Skills | Four skills from |
AWS services used
Service | How |
AWS Lambda | Stateless MCP HTTP handler + Function URL ( |
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 |
Quick start (local, offline)
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).
npm run build
MCP_TRANSPORT=stdio npm startHTTP mode:
MCP_TRANSPORT=http PORT=8080 USE_FAKE_BEDROCK=1 npm start
curl -s http://localhost:8080/ | jq .MCP tools
Tool | Purpose |
| Persist a durable memory (Bedrock summary/tags/salience/kind) |
| Top-k semantic recall (Cockroach vector index when configured) |
| Pack critical memories into a token budget |
| 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 viaDATABASE_URL
Schema: 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 unusedOnly 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
CockroachDB - reuse an existing cluster or run
bash scripts/ccloud-bootstrap.sh(setCRDB_CLUSTER_NAMEif not using the defaultagentic-memory). For password-based non-interactive SQL, install thecockroachCLI and setCRDB_ADMIN_USER/CRDB_ADMIN_PASSWORDbefore running the script.Managed MCP - enable in Cloud Console for your cluster; follow
docs/managed-mcp.md.AWS Lambda -
bash deploy/deploy-lambda.sh(seedeploy/README.md).
Live demo (staging)
Item | Value |
Demo URL |
|
Judge credentials |
|
MCP path |
|
Cockroach cluster | existing Serverless cluster ( |
Lambda region |
|
Amazon Bedrock in eu-central-1
Model | Role | Setup |
| Embeddings (1024-d) | Works out of the box |
| Analyze / consolidate (default chat) | Works out of the box |
| 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_TOKENor 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-fullon 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
40001means 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, andsessions.memory_countis derived withCOUNT(*)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)
{
"mcpServers": {
"agentic-memory": {
"command": "node",
"args": ["dist/index.js"],
"env": {
"USE_FAKE_BEDROCK": "1",
"MEMORY_STORE": "file"
}
}
}
}Hackathon evidence
docs/SUBMISSION.md- project summary for Devpostdocs/RESULTS.md- benchmarks and EXPLAIN evidencedocs/DEMO-CREDENTIALS.md- live demo Bearer token and curl examples
License
MIT - see LICENSE.
Available Tools
4 toolsmemory_forgetConsolidate and forgetA
Runs the maintenance pass: related memories are merged by Bedrock into one canonical memory, contradicted items are forgotten, and stale low-importance memories decay away.
| Name | Required | Description | Default |
|---|---|---|---|
| userId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses the key behaviors: merging, forgetting contradicted items, and decaying stale memories, which are meaningful side effects. However, it does not explicitly state irreversibility or whether a summary is returned, though the maintenance nature is clear.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, information-dense sentence that front-loads the core action ('Runs the maintenance pass') before elaborating on the effects. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a maintenance tool with one parameter and no output schema, the description covers the main operations well, but omits any return value or post-condition details (e.g., whether the operation is atomic, how success is reported). Given the lack of annotations, this is a moderate gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description does not mention the userId parameter at all, and the schema provides no description for it (0% coverage). Since userId is self-explanatory, the parameter is understandable, but the tool description adds no guidance on how this parameter scopes the maintenance (e.g., per-user memory isolation).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool runs a maintenance pass with specific effects: merging related memories, discarding contradicted items, and decaying stale low-importance memories. It distinguishes from siblings (write/search/recall) by focusing on consolidation and forgetting. The verb 'runs' plus resource 'memories' makes the purpose explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit 'when to use' vs alternatives is provided. The description implies this is the maintenance action, and the title/name suggest forgetting, but it doesn't compare against memory_write or memory_search. Users must infer from the tool name that this is for cleanup.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
memory_recall_contextRecall context within a token budgetB
Returns the most critical memories for a query, greedily packed to fit a token budget, as a ready-to-inject context block.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | ||
| userId | Yes | ||
| tokenBudget | Yes | Approximate max tokens the returned context may use. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds behavioral detail not present in the schema: it uses a greedy packing algorithm to fit the token budget and produces a ready-to-inject context block. However, it does not disclose other behavioral traits like ordering of memories, behavior with no results, or whether the output is plain text or structured, leaving some burden unaddressed given no annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, dense sentence that front-loads the core action (returns most critical memories) and packs in the budget constraint and output format. No filler or redundancy, making it highly efficient for an agent to parse quickly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema and no annotations, the description is the only source for understanding return values and edge cases. It fails to specify what a 'context block' looks like, how memories are ordered, or what happens if no memories are found, leaving significant ambiguity for a tool that is meant to produce injectable context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 33%, with only tokenBudget having a description. The tool description does not clarify the semantics of query or userId beyond calling it a 'query', leaving these parameters under-documented. The greedy/token-budget wording reinforces tokenBudget but does not compensate for the missing explanations of the other two parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it returns the most critical memories for a query, with a token budget constraint and a ready-to-inject context block output. This distinguishes it from sibling tools like memory_search by emphasizing the context-injection purpose and budget optimization, though it doesn't explicitly name a sibling comparator.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance is given on when to use this tool versus memory_search, memory_write, or memory_forget. The description implies a use case for budget-constrained context injection, but it does not state exclusions or alternatives, leaving the selection decision to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
memory_searchSearch memoriesA
Semantic search over a user's memories via CockroachDB vector indexing, re-ranked by similarity, importance, recency, and reinforcement. Recalled memories are reinforced.
| Name | Required | Description | Default |
|---|---|---|---|
| k | No | Max results (default 5). | |
| query | Yes | What you want to recall. | |
| userId | Yes | ||
| recencyDays | No | Optional filter: only memories newer than N days. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry the behavioral transparency burden. It does so effectively by disclosing that memories are re-ranked by similarity, importance, recency, and reinforcement, and that recalled memories are reinforced—a non-obvious side effect. It does not mention return format or error behavior, but the disclosed ranking and reinforcement are strong behavioral details.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The entire description is one focused sentence that packs in the key purpose, technical approach, ranking factors, and side-effect without filler. It is front-loaded and every element contributes to understanding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has 4 parameters, no annotations, and no output schema, so the description must serve as the primary context source. It covers purpose, ranking behavior, and the reinforcement side-effect, but it does not explain what the search returns or how this relates to memory_recall_context. This leaves some gaps given the absence of other structured context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already covers 75% of parameters with descriptions (k and recencyDays). The overall description mentions "recency," which loosely connects to the recencyDays parameter, but it does not add meaningful detail beyond the schema. Baseline 3 is appropriate given the high schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the tool as performing semantic search over a user's memories, with specific details about the ranking mechanism (similarity, importance, recency, and reinforcement). This distinguishes it from siblings like memory_write or memory_forget, which are clearly write/delete operations, and from memory_recall_context, which is likely a different retrieval approach.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies that this tool is for semantic search scenarios but does not explicitly state when to use it versus the sibling memory_recall_context. There is no mention of alternatives or exclusions, so the usage guidance is only implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
memory_writeWrite memoryA
Persist something worth remembering about a user (a preference, fact, commitment, or event). Bedrock derives a short summary, tags, importance (salience), and kind. Call this whenever the user reveals durable information you should recall in future sessions.
| Name | Required | Description | Default |
|---|---|---|---|
| userId | Yes | Stable id namespacing this user's memories. | |
| content | Yes | The information to remember, in plain language. | |
| salience | No | Optional importance override in [0,1]; otherwise Bedrock decides. | |
| sourceSession | No | Optional originating session/conversation id. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden. It does add useful context by explaining that Bedrock automatically derives a summary, tags, salience, and kind. However, it does not disclose whether the write is idempotent, how duplicates are handled, or what the return value is, leaving gaps in behavioral transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with the core action, and every clause adds value. No repetition or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and no annotations, the description covers the what, when, and how of usage well. It lacks return value and error handling details, but for a straightforward write tool with clear usage guidance, it is reasonably complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds meaningful guidance by giving examples of content (preference, fact, commitment, event) and clarifying that salience is derived by default unless overridden. This enriches understanding beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool persists something worth remembering about a user, with a specific verb ('persist') and resource ('memory'). It lists content types (preference, fact, commitment, event), which distinguishes it from siblings like memory_search and memory_forget.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives an explicit trigger: 'Call this whenever the user reveals durable information you should recall in future sessions.' This is clear context, though it does not mention alternatives or when not to use it, so it falls short of a full 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
4 tool updates
v0.1.0- First observed
memory_forget - First observed
memory_recall_context - First observed
memory_search - First observed
memory_write
TDQS
Scored across 4 tools
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.
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.
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.
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
Related MCP Connectors
Cloud-hosted MCP server for durable AI memory
An MCP memory server. One memory your agents share — across models, devices and apps.
Shared cross-LLM long-term memory over MCP: semantic recall, sessions, and media (pgvector).
Analytical memory for AI agents: a real Postgres queried in plain English over MCP. One command.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceAn MCP server providing semantic memory storage and retrieval using vector embeddings powered by LanceDB and Google Gemini. It supports multi-tenant isolation and bucket-based organization for managing structured memories through natural language queries.MIT
- AlicenseNot gradedqualityDmaintenanceAn MCP server that provides persistent semantic memory backed by PostgreSQL and pgvector for storing and searching thoughts via vector embeddings. It enables dimensional organization, conflict detection, and historical tracking of facts, decisions, and observations.1 npmAGPL 3.0
- AlicenseNot gradedqualityDmaintenanceMulti-tenant memory system MCP server with vector search, relationships, and trust-based access control for AI assistants.157 npm1MIT
- AlicenseAqualityDmaintenanceMCP server for semantic code indexing using vector embeddings, enabling AI agents to maintain persistent memory of codebases through natural language queries and intelligent chunking.193 npm4MIT