Usage Guide
This guide covers all the core operations in Kore Memory: saving memories, searching, managing tags and relations, batch operations, timeline queries, and data export/import.
Starting the Server
# Default: localhost:8765
kore
# Custom port
KORE_PORT=9000 kore
# With verbose logging
KORE_LOG_LEVEL=debug kore
The web dashboard is immediately available at http://localhost:8765/dashboard.
Saving Memories
Basic Save
Save a memory with automatic importance scoring:
from kore_memory import KoreClient
with KoreClient("http://localhost:8765", agent_id="my-agent") as kore:
result = kore.save("User prefers dark mode for all interfaces")
print(result.id, result.importance) # e.g., 42, 3
Via curl:
curl -X POST http://localhost:8765/save \
-H "Content-Type: application/json" \
-H "X-Agent-Id: my-agent" \
-d '{"content": "User prefers dark mode for all interfaces"}'
With Category and Importance
Override auto-scoring by specifying importance explicitly:
kore.save(
"Never deploy on Fridays - production incident in Q3",
category="decision",
importance=5
)
curl -X POST http://localhost:8765/save \
-H "Content-Type: application/json" \
-H "X-Agent-Id: my-agent" \
-d '{
"content": "Never deploy on Fridays - production incident in Q3",
"category": "decision",
"importance": 5
}'
Set importance to 1 (or omit it) to let Kore auto-score. Values 2--5 are treated as explicit overrides. Critical memories (importance 5) have a decay half-life of 365 days.
With TTL (Auto-Expiration)
Memories can auto-expire after a set number of hours:
kore.save(
"Deploy scheduled for Friday at 14:00 UTC",
category="task",
ttl_hours=48
)
After 48 hours, this memory is automatically removed during the next cleanup cycle.
TTL range is 1 to 8760 hours (1 hour to 1 year). Set ttl_hours to null or omit it for memories that never expire.
Searching Memories
Full-Text Search (FTS5)
Always available, even without the semantic extra:
results = kore.search("dark mode", limit=5)
for memory in results:
print(f"[{memory.decay_score:.2f}] {memory.content}")
curl "http://localhost:8765/search?q=dark+mode&limit=5" \
-H "X-Agent-Id: my-agent"
Semantic Search
Requires the semantic extra. Finds conceptually similar memories across languages:
# This will find "User prefers dark mode" even with different wording
results = kore.search("interface color preferences", limit=5, semantic=True)
curl "http://localhost:8765/search?q=interface+color+preferences&limit=5&semantic=true" \
-H "X-Agent-Id: my-agent"
Semantic search uses cosine similarity between embeddings. Results are ranked by effective score: similarity * decay * importance. This means fresh, important, and relevant memories always rank highest.
Filtering by Category
curl "http://localhost:8765/search?q=deploy&category=decision&limit=10" \
-H "X-Agent-Id: my-agent"
Pagination
curl "http://localhost:8765/search?q=project&limit=10&offset=20" \
-H "X-Agent-Id: my-agent"
Timeline API
Retrieve the chronological history of a subject:
timeline = kore.timeline(subject="project alpha")
for entry in timeline:
print(f"{entry.created_at}: {entry.content}")
curl "http://localhost:8765/timeline?subject=project+alpha" \
-H "X-Agent-Id: my-agent"
The timeline API returns memories sorted by creation date, giving you a narrative view of how knowledge about a subject evolved over time.
Tags
Tags let you organize and cross-reference memories beyond categories.
Adding Tags
kore.add_tags(memory_id=42, tags=["ui", "preference", "dark-theme"])
curl -X POST http://localhost:8765/memories/42/tags \
-H "Content-Type: application/json" \
-d '{"tags": ["ui", "preference", "dark-theme"]}'
Listing Tags on a Memory
tags = kore.get_tags(memory_id=42)
print(tags) # ["ui", "preference", "dark-theme"]
curl http://localhost:8765/memories/42/tags
Searching by Tag
Find all memories with a specific tag:
results = kore.search_by_tag("dark-theme")
curl "http://localhost:8765/tags/dark-theme/memories" \
-H "X-Agent-Id: my-agent"
Removing Tags
curl -X DELETE http://localhost:8765/memories/42/tags \
-H "Content-Type: application/json" \
-d '{"tags": ["dark-theme"]}'
Relations
Relations create bidirectional links between memories, forming a knowledge graph.
Creating a Relation
kore.add_relation(source_id=42, target_id=58, relation="depends_on")
curl -X POST http://localhost:8765/memories/42/relations \
-H "Content-Type: application/json" \
-d '{"target_id": 58, "relation": "depends_on"}'
Listing Relations
relations = kore.get_relations(memory_id=42)
for rel in relations:
print(f"{rel.relation}: memory #{rel.target_id}")
curl http://localhost:8765/memories/42/relations
Relations are bidirectional -- querying from either side returns the connection.
Batch Operations
Save up to 100 memories in a single request:
memories = [
{"content": "React 19 supports server components", "category": "project"},
{"content": "Always use parameterized queries", "category": "decision", "importance": 5},
{"content": "Team standup at 09:30 CET", "category": "task", "ttl_hours": 168},
]
results = kore.save_batch(memories)
print(f"Saved {len(results)} memories")
curl -X POST http://localhost:8765/save/batch \
-H "Content-Type: application/json" \
-H "X-Agent-Id: my-agent" \
-d '{"memories": [
{"content": "React 19 supports server components", "category": "project"},
{"content": "Always use parameterized queries", "category": "decision", "importance": 5}
]}'
Batch saves are significantly faster than individual saves because they share a single database transaction and embedding batch.
Updating Memories
Update the content, category, or importance of an existing memory:
kore.update(memory_id=42, content="User prefers dark mode (confirmed)", importance=4)
curl -X PUT http://localhost:8765/memories/42 \
-H "Content-Type: application/json" \
-d '{"content": "User prefers dark mode (confirmed)", "importance": 4}'
Deleting Memories
Hard Delete
kore.delete(memory_id=42)
curl -X DELETE http://localhost:8765/memories/42
Soft Delete (Archive)
Archive preserves the memory but hides it from search results:
curl -X POST http://localhost:8765/memories/42/archive
Restore an archived memory:
curl -X POST http://localhost:8765/memories/42/restore
List all archived memories:
curl http://localhost:8765/archive
Export and Import
Export All Memories
backup = kore.export_memories()
# Returns JSON with all active memories
curl http://localhost:8765/export > backup.json
Import from Backup
kore.import_memories(backup)
curl -X POST http://localhost:8765/import \
-H "Content-Type: application/json" \
-d @backup.json
Import does not overwrite existing memories. Duplicate content may result in similar entries. Run compression after import to merge near-duplicates.
Maintenance Operations
Run Decay Pass
Recalculate decay scores for all memories and clean up fully decayed ones:
kore.decay_run()
curl -X POST http://localhost:8765/decay/run
Compress Similar Memories
Merge memories with cosine similarity above 0.88 (configurable via KORE_SIMILARITY_THRESHOLD):
kore.compress()
curl -X POST http://localhost:8765/compress
Clean Up Expired Memories
Remove memories that have exceeded their TTL:
curl -X POST http://localhost:8765/cleanup
Run maintenance periodically -- for example via a cron job or the MCP memory_decay_run tool. The web dashboard also has one-click buttons for all maintenance operations.
Async Python Usage
For async applications (FastAPI, aiohttp, etc.):
from kore_memory import AsyncKoreClient
async with AsyncKoreClient("http://localhost:8765", agent_id="my-agent") as kore:
result = await kore.save("Async memory example")
results = await kore.search("async", limit=5)
await kore.add_tags(result.id, ["async", "example"])
await kore.decay_run()
Error Handling
The Python SDK raises typed exceptions:
from kore_memory import KoreClient, KoreValidationError, KoreNotFoundError
with KoreClient("http://localhost:8765") as kore:
try:
kore.save("") # Too short
except KoreValidationError as e:
print(f"Validation failed: {e}")
try:
kore.delete(99999)
except KoreNotFoundError:
print("Memory not found")
Exception hierarchy:
| Exception | HTTP Status | When |
|---|---|---|
KoreValidationError | 422 | Invalid input (too short, bad category, etc.) |
KoreNotFoundError | 404 | Memory ID does not exist |
KoreAuthError | 401 / 403 | Invalid or missing API key |
KoreRateLimitError | 429 | Too many requests |
KoreServerError | 500 | Internal server error |
All exceptions inherit from KoreError.