Agent memory storage API with SSH-simulated interface, backed by S3. Inspired by MemPalace principles.
The memory system is organized like a palace:
- Wings - Top-level directories (e.g.,
/projects,/conversations,/knowledge) - Rooms - Subdirectories within wings
- Drawers - Files containing actual memories
npm install
npm run build
npm run dev:onceThis starts:
- HTTP API on
http://localhost:3456 - SSH Server on
localhost:2222
ssh -p 2222 localhostYou get an interactive shell with all memory commands.
# Create structure
curl -X POST http://localhost:3456/memory/exec \
-H "Content-Type: application/json" \
-d '{"command": "mkdir /projects/myapp", "path": "/"}'
# Write content
curl -X POST http://localhost:3456/memory/exec \
-H "Content-Type: application/json" \
-d '{"command": "write /projects/myapp/README.md "# My Project"", "path": "/"}'
# Read content
curl -X POST http://localhost:3456/memory/exec \
-H "Content-Type: application/json" \
-d '{"command": "cat /projects/myapp/README.md", "path": "/"}'Your AI can use Berget Memory as persistent storage without any additional tools or MCP servers. Just use standard SSH or HTTP calls.
Connect once, keep the session open. The server gives you an interactive shell.
# Connect to your memory palace
ssh ssh.memory.stage.berget.ai
# Inside the SSH session, use these commands:
mkdir /projects/myapp # Create project directory
write /projects/myapp/spec.md "# Spec" # Store requirements
cat /projects/myapp/spec.md # Read them back
grep "TODO" /projects -r # Search for TODOs
tree /projects -L2 # View structureFor autonomous agents: Execute commands directly:
ssh ssh.memory.stage.berget.ai "mkdir /conversations/client-acme"
ssh ssh.memory.stage.berget.ai "write /conversations/client-acme/2024-01-15.md 'Meeting notes...'"
ssh ssh.memory.stage.berget.ai "cat /conversations/client-acme/2024-01-15.md"Use standard HTTP POST requests. No special libraries needed.
# Store a memory
curl -X POST https://memory.stage.berget.ai/memory/exec \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <token>" \
-d '{
"command": "write /projects/myapp/decision.md '# We chose PostgreSQL'",
"path": "/"
}'
# Retrieve it
curl -X POST https://memory.stage.berget.ai/memory/exec \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <token>" \
-d '{
"command": "cat /projects/myapp/decision.md",
"path": "/"
}'
# Batch operations (multiple commands in one request)
curl -X POST https://memory.stage.berget.ai/memory/batch \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <token>" \
-d '{
"commands": [
"mkdir /projects/myapp",
"cd /projects/myapp",
"write README.md '# My Project'",
"write todo.md '## Tasks\n- [ ] Setup CI'",
"ls -l"
],
"path": "/"
}'/conversations/ # One directory per conversation thread
/projects/ # One directory per project
/myapp/
README.md # Project overview
decisions.md # Architecture decisions
context.md # Current session context
todo.md # Active tasks
/knowledge/ # Research, patterns, references
/tasks/ # Global task list
/people/ # Contacts, preferences
# Start every session by reading context
context=$(ssh ssh.memory.stage.berget.ai "cat /projects/myapp/context.md")
# After each interaction, update context
ssh ssh.memory.stage.berget.ai "write /projects/myapp/context.md 'Last action: ...'"
# Search for relevant memories
ssh ssh.memory.stage.berget.ai "grep 'database' /projects -r"
# Use tags for organization
ssh ssh.memory.stage.berget.ai "tag /projects/myapp/decision.md backend urgent"All protected endpoints require a Keycloak Bearer token from keycloak.berget.ai realm berget.
Authorization: Bearer <token>
In dev mode, any token (or no token) is accepted.
Execute a single SSH-like command.
{
"command": "ls -l /projects",
"path": "/"
}Response includes tips field with contextual guidance for agents:
{
"stdout": "file listing...",
"stderr": "",
"exitCode": 0,
"currentPath": "/",
"tips": ["TIP: Organize your memory palace with top-level 'wings'..."]
}Execute multiple commands in sequence.
{
"commands": [
"mkdir /projects/myapp",
"cd /projects/myapp",
"write README.md \"# My Project\"",
"ls -l"
],
"path": "/"
}SSE endpoint for real-time memory events. Subscribe to changes as they happen.
curl -N "http://localhost:3456/events/stream?types=node.created,node.updated&pathPrefix=/projects"Query Parameters:
types- Filter by event types (comma-separated):node.created,node.updated,node.deleted,node.tagged,node.indexedpathPrefix- Only events under this pathnodeType-fileordirectorytags- Only events matching these tags (comma-separated)
Event Format:
event: node.created
data: {"id":"evt-123","type":"node.created","userId":"user-123","path":"/projects/app","nodeType":"directory","timestamp":"2024-01-15T10:00:00Z","metadata":{"action":"mkdir"}}
Check active SSE subscriptions for the authenticated user.
Check memory status for authenticated user.
| Command | Description |
|---|---|
ls [path] [-l] |
List directory contents |
cat <path> |
Display file contents |
grep <pattern> [path] [-r] [--include='*.md'] |
Search for pattern in files. Use --include to filter by file type |
mkdir <path> |
Create a directory |
touch <path> |
Create or update a file |
rm <path> [-r] |
Remove a file or directory |
write <path> <content> |
Write content to a file |
cd <path> |
Change directory |
pwd |
Print working directory |
tree [path] [-L<n>] |
Display directory tree |
find <pattern> [path] |
Find files by name pattern |
meta <path> [key] [value] |
View or edit metadata |
tag <path> <tags...> [-d] |
Add or remove tags |
search <query> [path] [-n<N>] |
Full-text search with ranking |
vsearch <query> [path] |
Semantic/vector search |
index [path] |
Rebuild search index |
stats |
Display memory statistics |
help |
Show help message |
Chain commands with pipes:
ls /projects | grep api
find /docs | grep setup
cat /README.md | grep TODO/ <- Root
├── projects/ <- Wing: Active projects
│ ├── myapp/ <- Room: Specific project
│ │ ├── README.md
│ │ ├── docs/
│ │ └── src/
│ └── other-project/
├── conversations/ <- Wing: Meeting notes & decisions
│ ├── client-acme/
│ │ ├── context.md
│ │ └── 2024-01-15-meeting.md
│ └── team-syncs/
├── knowledge/ <- Wing: Research & architecture
│ ├── architecture/
│ ├── patterns/
│ └── decisions/
├── people/ <- Wing: Contacts & relationships
└── tasks/ <- Wing: TODOs & deadlines
- kebab-case for files:
api-gateway-design.md - Dates for chronological items:
2024-01-15-meeting.md - Be descriptive: bad="notes.md" good="graphql-vs-rest-decision.md"
Tag everything immediately after creation:
tag /projects/myapp/README.md backend api v1Use consistent tags: backend, frontend, urgent, decision, research
# Exact text search (fast)
grep "pattern" / -r
# Full-text with ranking
search "microservices benefits" /knowledge
# Semantic similarity (find related ideas)
vsearch "container orchestration"
# Find by filename
find "micro" /knowledge
# Filter by file type
grep "pattern" /projects -r --include='*.md'
grep "pattern" /projects -r --include='*.yaml'Store session context for continuity:
write /conversations/client-acme/context.md "# Context
Client: ACME Corp
Budget: $50k
Timeline: 3 months
Stakeholders: John (CTO), Sarah (PM)"| Variable | Description |
|---|---|
PORT |
Server port (default: 3000) |
SSH_PORT |
SSH server port (default: 2222) |
S3_BUCKET |
S3 bucket name |
S3_ENDPOINT |
S3 endpoint URL (optional, for MinIO) |
AWS_REGION |
AWS region |
AWS_ACCESS_KEY_ID |
AWS access key |
AWS_SECRET_ACCESS_KEY |
AWS secret key |
KEYCLOAK_URL |
Keycloak URL (default: https://keycloak.berget.ai) |
KEYCLOAK_REALM |
Keycloak realm (default: berget) |
# Install dependencies
npm install
# Run tests
npm test
# Start dev server (API + SSH)
npm run dev:once
# Build
npm run buildsrc/
├── domain/ # Domain models, errors, events
├── ports/ # Interface definitions (ports)
├── adapters/ # External system adapters (S3, Keycloak, Vector Store)
├── services/ # Business logic (commands, paths, search, events)
├── middleware/ # Koa middleware (auth, error handling)
├── routes/ # API routes (memory, events, health)
└── index.ts # Application entry point