Conversation Memory
Conversation memory is a subsystem that provides durable, append-only, per-conversation logs. It offers a structured way for agents to store and retrieve working memory, allowing conversations to persist and evolve over time. It supports appending new items and offers various read access patterns, including recalling recent history (recall_memory), replaying full conversations (replay_memory), and listing available conversations (list_conversations).
Authentication
Section titled “Authentication”All conversation memory operations require Basic authentication. Clients using Bearer tokens will be rejected at the tool layer.
Data Models
Section titled “Data Models”The core data structures in the conversation memory subsystem define how data is stored and accessed.
ConversationId
Section titled “ConversationId”An opaque, pseudonymous handle for a conversation, validated at construction. It must be:
- An opaque string of 8–64 characters from
[A-Za-z0-9_-]. - Client-chosen and stable for the duration of a single conversation.
- Never derived from personal data.
Invalid input is a hard error, ensuring that malformed IDs do not silently lead to orphaned data.
A per-conversation sequence number, assigned in strict append order. Sequence numbers are 0-based and gapless within a single conversation.
MemoryItem
Section titled “MemoryItem”Represents a single appended record in a conversation’s memory log:
seq: The sequence number assigned to this item.recorded_at: The server-side commit time for the item. All items within the same batch share the samerecorded_attimestamp.payload: The stored value, always a JSON object. Its keys make the item self-describing. Contents are stored verbatim and are not interpreted by the system, allowing for flexible data structures.
McpMemoryItem
Section titled “McpMemoryItem”The public API representation of a MemoryItem, as returned by recall_memory and replay_memory. For its full schema, refer to McpMemoryItem in MCP Data Types.
SeqRange
Section titled “SeqRange”A witness of a committed append operation, representing an inclusive contiguous sequence range [first, last] for a batch of items. This range is non-empty by construction, as empty batches are rejected.
ReadSelector
Section titled “ReadSelector”Defines how items are selected from a conversation’s log during a read operation:
Tail { count }: Selects the lastcountitems in ascending sequence order. Returns fewer items if the log contains less thancount.Range { start, limit }: Selects up tolimititems starting from the specifiedstartsequence number. Returns fewer items at the end of the log, or an empty list ifstartis past the end.
ListCursor
Section titled “ListCursor”An opaque keyset position used to paginate conversation listings. It captures the last_appended_at timestamp and conversation_id of the last conversation in a previous page.
ListSelector
Section titled “ListSelector”Defines how a listing selects one bounded read of a site’s conversations:
cursor: An optionalListCursorto resume the listing strictly after this position.Nonestarts the listing from the most recently active conversation.limit: The maximum number of conversation summaries to return in one page.
ConversationListing
Section titled “ConversationListing”One bounded read of a site’s conversation listing, containing:
summaries: A list ofConversationSummaryobjects, ordered bylast_appended_atdescending, with ties broken by ascendingconversation_id.next_cursor: An optionalListCursorto continue the listing;Noneonce the listing is exhausted.
ConversationSummary
Section titled “ConversationSummary”Provides metadata about a conversation without retrieving its full content:
conversation_id: The ID of the conversation.created_at: Therecorded_attimestamp of the first item in the conversation.last_appended_at: Therecorded_attimestamp of the last item in the conversation.
McpConversationSummary
Section titled “McpConversationSummary”The public API representation of a ConversationSummary, as returned by list_conversations. For its full schema, refer to McpConversationSummary in MCP Data Types.
Capacity Limits
Section titled “Capacity Limits”To prevent resource exhaustion and ensure predictable performance, conversation memory enforces several capacity limits:
- Per-item payload: Individual item payloads are capped at 256 KiB.
- Per-batch total payload: The sum of all item payloads in a single append batch is capped at 1 MiB.
- Per-conversation item count: A single conversation can store a maximum of 100,000 items.
Attempts to exceed these limits are rejected with specific errors (see Error Handling).
MCP Tool: append_memory
Section titled “MCP Tool: append_memory”The append_memory tool allows agents to append batches of items to a conversation’s durable memory log.
Description
Section titled “Description”Append a batch of items to a conversation’s durable, ordered memory log and receive the assigned sequence range (first_seq to last_seq, inclusive) as the durability acknowledgment. Each item is one self-describing JSON object, stored verbatim; the batch commits atomically and in order. The conversation_id is a pseudonymous handle the client mints itself: an opaque string of 8-64 characters from [A-Za-z0-9_-] (UUIDs and nanoids fit), stable for one conversation, and never derived from personal data such as names, e-mail addresses, or account ids. This tool requires Basic authentication. The maximum size for a single item payload is 256 KiB, and the total payload size for a batch is 1 MiB. A conversation can hold a maximum of 100,000 items. Memory must never block the conversation: the append acknowledgment is a durability signal, not flow control. Validation errors are permanent; any other failure is safe to retry after buffering the batch, and duplicates from retries are tolerated.
AppendMemoryRequest Schema
Section titled “AppendMemoryRequest Schema”{ "properties": { "conversation_id": { "description": "The pseudonymous handle of the conversation to append to, minted by the client: 8-64 characters from `[A-Za-z0-9_-]`, stable for one conversation, never derived from personal data. A malformed id is rejected outright — it never falls back to a fresh conversation.", "type": "string" }, "items": { "description": "The items to remember, in order. Each item is one JSON object whose keys make it self-describing; contents are stored verbatim, never interpreted. The batch commits atomically — all items or none — and must not be empty.", "items": { "additionalProperties": true, "type": "object" }, "maxItems": 250, "minItems": 1, "type": "array" } }, "required": [ "conversation_id", "items" ], "title": "AppendMemoryRequest", "type": "object"}AppendMemoryResponse Schema
Section titled “AppendMemoryResponse Schema”{ "properties": { "first_seq": { "description": "Sequence number assigned to the first item of the batch. Sequence numbers are per conversation, 0-based, gapless, in append order.", "format": "uint64", "minimum": 0, "type": "integer" }, "last_seq": { "description": "Sequence number assigned to the last item of the batch; the batch occupies the inclusive range `[first_seq, last_seq]`.", "format": "uint64", "minimum": 0, "type": "integer" } }, "required": [ "first_seq", "last_seq" ], "title": "AppendMemoryResponse", "type": "object"}MCP Tool: recall_memory
Section titled “MCP Tool: recall_memory”The recall_memory tool allows agents to retrieve the most recent items from a conversation’s memory log.
Description
Section titled “Description”Return the most recent items of a conversation’s durable, ordered memory log — the everyday way a client rehydrates recent context at the start of a session or after a gap. The response carries the last count items in ascending sequence order, so the oldest of the returned tail comes first; count defaults to 50 (max 1000), and a log holding fewer items returns them all. A conversation with no items — including one never appended to — reads as an empty list, not an error, so a fresh conversation id needs no special-casing. To read the log from a chosen position, or rebuild a conversation from the start, use replay_memory; to discover which conversations exist for your site, use list_conversations. The conversation_id is a pseudonymous handle the client mints itself: an opaque string of 8-64 characters from [A-Za-z0-9_-] (UUIDs and nanoids fit), stable for one conversation, and never derived from personal data such as names, e-mail addresses, or account ids. This tool requires Basic authentication. Memory must never block the conversation: the append acknowledgment is a durability signal, not flow control. Validation errors are permanent; any other failure is safe to retry after buffering the batch, and duplicates from retries are tolerated.
RecallMemoryRequest Schema
Section titled “RecallMemoryRequest Schema”{ "properties": { "conversation_id": { "description": "The pseudonymous handle of the conversation to read, minted by the\nclient: 8-64 characters from `[A-Za-z0-9_-]`, stable for one\nconversation, never derived from personal data. A malformed id is\nrejected outright; an unknown one reads as an empty list.", "type": "string" }, "count": { "default": 50, "description": "How many items to return, counted from the end of the log: the last\n`count` items in ascending sequence order, fewer if the log holds\nfewer, none for `0`. Defaults to 50.", "format": "uint64", "maximum": 1000, "minimum": 0, "type": "integer" } }, "required": [ "conversation_id" ], "title": "RecallMemoryRequest", "type": "object"}RecallMemoryResponse Schema
Section titled “RecallMemoryResponse Schema”{ "$defs": { "McpMemoryItem": { "properties": { "payload": { "additionalProperties": true, "description": "The remembered JSON object, exactly as it was appended — contents are\nstored verbatim, never interpreted.", "type": "object" }, "recorded_at": { "description": "Server-side commit time of the item's batch, as an RFC3339 timestamp;\nall items appended in one batch share it.", "type": "string" }, "seq": { "description": "Sequence number of the item: per conversation, 0-based, gapless, in\nappend order.", "format": "uint64", "minimum": 0, "type": "integer" } }, "required": [ "seq", "recorded_at", "payload" ], "type": "object" } }, "properties": { "items": { "description": "The recalled items in ascending sequence order. Empty when the\nconversation holds no items — including one never appended to.", "items": { "$ref": "#/$defs/McpMemoryItem" }, "type": "array" } }, "required": [ "items" ], "title": "RecallMemoryResponse", "type": "object"}MCP Tool: replay_memory
Section titled “MCP Tool: replay_memory”The replay_memory tool allows agents to rebuild a conversation’s state from a known position.
Description
Section titled “Description”Return a conversation’s durable, ordered memory log from a given position onward, in ascending sequence order — the read that rebuilds conversation state from the record, for example restoring a conversation after a restart. The response carries up to limit items starting at sequence number offset; offset defaults to 0. Fewer than limit items come back at the end of the log (max 1000), and a page shorter than limit — including an empty one — means the end was reached; an offset past the end reads as an empty list. To restore a whole conversation, start at offset 0, after each page continue at the last returned item’s sequence number plus one, and stop at the first page shorter than limit. Sequence numbers are per conversation, 0-based, and gapless, so the sequence number doubles as the offset — there is no cursor token. A conversation with no items — including one never appended to — reads as an empty list, not an error. For the everyday read of the most recent items, to rehydrate recent context, use recall_memory; to discover which conversations exist for your site, use list_conversations. The conversation_id is a pseudonymous handle the client mints itself: an opaque string of 8-64 characters from [A-Za-z0-9_-] (UUIDs and nanoids fit), stable for one conversation, and never derived from personal data such as names, e-mail addresses, or account ids. This tool requires Basic authentication. Memory must never block the conversation: the append acknowledgment is a durability signal, not flow control. Validation errors are permanent; any other failure is safe to retry after buffering the batch, and duplicates from retries are tolerated.
ReplayMemoryRequest Schema
Section titled “ReplayMemoryRequest Schema”{ "properties": { "conversation_id": { "description": "The pseudonymous handle of the conversation to read, minted by the\nclient: 8-64 characters from `[A-Za-z0-9_-]`, stable for one\nconversation, never derived from personal data. A malformed id is\nrejected outright; an unknown one reads as an empty list.", "type": "string" }, "limit": { "description": "Maximum number of items to return, in ascending sequence order\nstarting at `offset`. A page shorter than `limit` — including an\nempty one — signals that the end of the log was reached.", "format": "uint64", "maximum": 1000, "minimum": 0, "type": "integer" }, "offset": { "default": 0, "description": "Sequence number to start reading from; sequence numbers are per\nconversation, 0-based, and gapless, so this is also the position in\nthe log. Defaults to 0.", "format": "uint64", "minimum": 0, "type": "integer" } }, "required": [ "conversation_id", "limit" ], "title": "ReplayMemoryRequest", "type": "object"}ReplayMemoryResponse Schema
Section titled “ReplayMemoryResponse Schema”{ "$defs": { "McpMemoryItem": { "properties": { "payload": { "additionalProperties": true, "description": "The remembered JSON object, exactly as it was appended — contents are\nstored verbatim, never interpreted.", "type": "object" }, "recorded_at": { "description": "Server-side commit time of the item's batch, as an RFC3339 timestamp;\nall items appended in one batch share it.", "type": "string" }, "seq": { "description": "Sequence number of the item: per conversation, 0-based, gapless, in\nappend order.", "format": "uint64", "minimum": 0, "type": "integer" } }, "required": [ "seq", "recorded_at", "payload" ], "type": "object" } }, "properties": { "items": { "description": "The items from `offset` onward, in ascending sequence order. Fewer\nthan `limit` items means the end of the log was reached. An unknown\nconversation or an `offset` past the end yields an empty list.", "items": { "$ref": "#/$defs/McpMemoryItem" }, "type": "array" } }, "required": [ "items" ], "title": "ReplayMemoryResponse", "type": "object"}MCP Tool: list_conversations
Section titled “MCP Tool: list_conversations”The list_conversations tool allows agents to discover which conversations exist for their site.
Description
Section titled “Description”List the conversations stored for the authenticated site: each with its id and its created and last-appended timestamps, ordered most-recently-active first. It returns no item contents — to read a conversation’s contents use recall_memory (recent items) or replay_memory (from a chosen position); to check whether a specific already-known conversation has anything stored, a non-empty recall_memory is the existence check. This tool is for discovering which conversations exist, not for probing one you already know. Results are bounded: limit caps one call and defaults to 50 (max 1000); when more remain, next_cursor is returned — pass it back as cursor to continue, and a null next_cursor marks the end of the listing. This lists only your authenticated site’s conversations; there is no hard isolation below the site — to keep two sets of conversations hard-separated, use separate sites. The conversation_id is a pseudonymous handle the client mints itself: an opaque string of 8-64 characters from [A-Za-z0-9_-] (UUIDs and nanoids fit), stable for one conversation, and never derived from personal data such as names, e-mail addresses, or account ids. This tool requires Basic authentication. Memory must never block the conversation: the append acknowledgment is a durability signal, not flow control. Validation errors are permanent; any other failure is safe to retry after buffering the batch, and duplicates from retries are tolerated.
ListConversationsRequest Schema
Section titled “ListConversationsRequest Schema”{ "properties": { "cursor": { "default": null, "description": "An opaque continuation token from a previous response's next_cursor;\nomit to start from the most recently active conversation.", "type": [ "string", "null" ] }, "limit": { "default": 50, "description": "Maximum number of conversations to return in one call. Defaults to\n50.", "format": "uint64", "maximum": 1000, "minimum": 0, "type": "integer" } }, "title": "ListConversationsRequest", "type": "object"}ListConversationsResponse Schema
Section titled “ListConversationsResponse Schema”{ "$defs": { "McpConversationSummary": { "properties": { "conversation_id": { "description": "The pseudonymous conversation id, exactly as minted by the client.", "type": "string" }, "created_at": { "description": "When the conversation's first item was recorded, as an RFC3339\ntimestamp.", "type": "string" }, "last_appended_at": { "description": "When the conversation's most recent item was recorded, as an RFC3339\ntimestamp — the field the list is ordered by, most recent first.", "type": "string" } }, "required": [ "conversation_id", "created_at", "last_appended_at" ], "type": "object" } }, "properties": { "conversations": { "description": "The next conversations of your site's listing, ordered\nmost-recently-active first. Each entry carries only its id and\ntimestamps, never stored items.", "items": { "$ref": "#/$defs/McpConversationSummary" }, "type": "array" }, "next_cursor": { "description": "Opaque token to pass back as `cursor` to continue the listing; `null`\nonce the listing is exhausted.", "type": [ "string", "null" ] } }, "required": [ "conversations" ], "title": "ListConversationsResponse", "type": "object"}Error Handling
Section titled “Error Handling”Operations on conversation memory can result in specific errors, categorized for client handling:
MemoryError
Section titled “MemoryError”InvalidConversationId: Indicates a malformedConversationId. This is a client fault and a permanent error.EmptyBatch: Occurs when an append batch contains zero payloads. This is a client fault and a permanent error.PayloadTooLarge: An individual item payload exceeds the 256 KiB limit. This is a client fault and a permanent error.BatchTooLarge: The total payload size of an append batch exceeds the 1 MiB limit. This is a client fault and a permanent error.ConversationFull: Appending items would cause the conversation to exceed its 100,000 item limit. This is a client fault and a permanent error.Unavailable: Signifies that the memory storage backend is currently unavailable. This is a retryable error.Timeout: An append operation timed out while waiting for conversation access. This is a retryable error.Io: Represents an I/O error during memory storage operations. This is a retryable error.Corrupted: Indicates that the conversation log is corrupted at a specific byte offset. This is a permanent error.
ConversationIdError
Section titled “ConversationIdError”Detailed reasons for an InvalidConversationId:
TooShort: The ID length is below the minimum requirement.TooLong: The ID length exceeds the maximum allowed.InvalidCharacters: The ID contains characters outside the allowed charset[A-Za-z0-9_-].