integration guide
How agents integrate with Mnemos
Mnemos is a schemaover Arkiv, not a service. Any agent that follows the attribute convention can read and write a user's memory store. The user holds the key, so the user controls the data.
1. The schema
Every Mnemos entity carries the project attribute and a kind discriminator:
{
attributes: [
{ key: "app", value: "mnemos:v1" }, // project namespace
{ key: "kind", value: "memory" | "conversation" },
...
],
payload: <JSON>,
contentType: "application/json",
expiresIn: <seconds>,
}A memorystores its parent conversation's entity key under the conversation attribute. Arkiv has no JOINs; shared attributes are the only relationship mechanism.
2. Reading memories
Reads are anonymous. Filter on app = mnemos:v1and the user's address to scope a query to their data.
import { createPublicClient, http } from "@arkiv-network/sdk";
import { braga } from "@arkiv-network/sdk/chains";
import { eq, gte } from "@arkiv-network/sdk/query";
const client = createPublicClient({ chain: braga, transport: http() });
const result = await client
.buildQuery()
.where([
eq("app", "mnemos:v1"),
eq("kind", "memory"),
eq("topic", "preferences"),
gte("importance", 50),
])
.ownedBy(userAddress) // the user's wallet
.withAttributes(true)
.withPayload(true)
.orderBy("createdAt", "number", "desc")
.limit(20)
.fetch();
for (const entity of result.entities) {
const memory = entity.toJson();
console.log(memory.content);
}3. Writing a memory
Writes are signed by the user's wallet. The default UI generates the key in the browser and holds it in localStorage. An agent integration would hold a delegated session key (not in v1).
import { createWalletClient, http, jsonToPayload, ExpirationTime } from "@arkiv-network/sdk";
import { braga } from "@arkiv-network/sdk/chains";
import { privateKeyToAccount } from "@arkiv-network/sdk/accounts";
const client = createWalletClient({
chain: braga,
transport: http(),
account: privateKeyToAccount(userPrivateKey),
});
const { entityKey, txHash } = await client.createEntity({
payload: jsonToPayload({
content: "User prefers TypeScript over Python for backend work.",
tags: ["typescript", "backend"],
source: "claude-sonnet-4-6",
}),
attributes: [
{ key: "app", value: "mnemos:v1" },
{ key: "kind", value: "memory" },
{ key: "agent", value: "claude" },
{ key: "topic", value: "preferences" },
{ key: "importance", value: 80 }, // numeric → range-queryable
{ key: "createdAt", value: Date.now() }, // numeric → range-queryable
{ key: "conversation", value: conversationKey },
],
contentType: "application/json",
expiresIn: ExpirationTime.fromDays(30),
});Numeric attributes (importance, createdAt, messageCount) get range queries; strings get equality only. Pick the type up front.
4. Recall before generating
Agent loop: recall before sampling, splice the results into the prompt, write new memories after. Importance + topic + recency is enough retrieval for v1; no embeddings.
// Pseudocode for an agent's "recall before generating" step
async function recall(userAddress: `0x${string}`, topic: string) {
const result = await mnemos
.buildQuery()
.where([
eq("app", "mnemos:v1"),
eq("kind", "memory"),
eq("topic", topic),
])
.ownedBy(userAddress)
.withPayload(true)
.orderBy("importance", "number", "desc")
.limit(10)
.fetch();
return result.entities.map((e) => e.toJson().content);
}
// In the agent loop:
const userContext = await recall(userAddress, "preferences");
const prompt = `User preferences from prior sessions:
${userContext.join("
")}`;5. What you get
- Memories are not in a vendor database. Anything that knows the schema can read them.
$creatoris immutable, so you can always prove which agent wrote a memory.$owneris mutable. A memory can be transferred to another wallet or burned.- Use a short
expiresInfor sensitive context, longer for stable preferences. Arkiv garbage-collects when the time is up.
Network details
- chain: Braga (testnet, id 60138453102)
- rpc: https://braga.hoodi.arkiv.network/rpc
- faucet: https://braga.hoodi.arkiv.network/faucet/
- explorer: https://explorer.braga.hoodi.arkiv.network
- sdk: @arkiv-network/sdk (viem-based)