Skip to main content
Glama

โœจ Features

  • ๐Ÿ” Hybrid search โ€” BM25 (full-text) + vector KNN (pgvector) fused via Reciprocal Rank Fusion

  • ๐Ÿ“‚ Multi-user โ€” each user sees only their own memories; workspaces for shared team knowledge

  • ๐Ÿ› ๏ธ 10 MCP tools โ€” store, retrieve, recall, list, search by tag, get, update, delete, move, list workspaces

  • ๐ŸŒ Web UI โ€” browse, search, edit and delete memories in the browser; export/import JSON

  • ๐Ÿ”’ OAuth 2.1 โ€” full in-process authorization server, always enabled

  • ๐Ÿ˜ PostgreSQL โ€” pgvector for embeddings, tsvector for full-text search

  • ๐Ÿ“Š Progressive disclosure โ€” search returns compact snippets by default; call get_memory(id) only for what you need, reducing token usage

  • ๐Ÿ” Deduplication โ€” automatically detects near-identical memories before saving, preventing noise accumulation


Related MCP server: Memory MCP Server

๐Ÿ†š How Memlord compares

Memlord

OpenMemory

mcp-memory-service

basic-memory

Search

BM25 + vector + RRF

Vector only (Qdrant)

BM25 + vector + RRF

BM25 + vector

Embeddings

Local ONNX, zero config

OpenAI default; Ollama optional

Local ONNX, zero config

Local FastEmbed

Storage

PostgreSQL + pgvector

PostgreSQL + Qdrant

SQLite-vec / Cloudflare Vectorize

SQLite + Markdown files

Multi-user

โœ…

โŒ single-user in practice

โš ๏ธ agent-ID scoping, no isolation

โŒ

Workspaces

โœ… shared + personal, invite links

โš ๏ธ "Apps" namespace

โš ๏ธ tags + conversation_id

โœ… per-project flag

Authentication

โœ… OAuth 2.1

โŒ none (self-hosted)

โœ… OAuth 2.0 + PKCE

โŒ

Web UI

โœ… browse, edit, export

โœ… Next.js dashboard

โœ… rich UI, graph viz, quality scores

โŒ local; cloud only

MCP tools

10

5

15+

~20

Self-hosted

โœ… single process

โœ… Docker (3 containers)

โœ…

โœ…

Memory input

Manual (explicit store)

Auto-extracted by LLM

Manual

Manual (Markdown notes)

Memory types

fact / preference / instruction / feedback

auto-extracted facts

โ€”

observations + wiki links

Time-aware search

โœ… natural language dates

โš ๏ธ REST only, not in MCP tools

โ€”

โœ… recent_activity

Token efficiency

โœ… progressive disclosure

โŒ

โ€”

โœ… build_context traversal

Import / Export

โœ… JSON

โœ… ZIP (JSON + JSONL)

โ€”

โœ… Markdown (human-readable)

License

AGPL-3.0 / Commercial

Apache 2.0

Apache 2.0

AGPL-3.0

Where competitors have a real edge:

  • OpenMemory โ€” auto-extracts memories from raw conversation text; no need to decide what to store manually; good import/export

  • mcp-memory-service โ€” richer web UI (graph visualization, quality scoring, 8 tabs); more permissive license (Apache 2.0); multiple transport options (stdio, SSE, HTTP)

  • basic-memory โ€” memories are human-readable Markdown files you can edit, version-control, and read without any server; wiki-style entity links form a local knowledge graph; ~20 MCP tools

When to pick Memlord:

  • You want zero-config local embeddings โ€” ONNX model ships with the server, no Ollama or external API needed

  • You run a multi-user team server with proper OAuth 2.1 auth and invite-based workspaces

  • You want a production-grade database (PostgreSQL) that scales beyond a single machine's SQLite

  • You manage memories explicitly โ€” store exactly what matters, typed and tagged, not everything the LLM decides to extract

  • You want a self-hosted Web UI with full CRUD and JSON export, without a cloud subscription


๐Ÿš€ Quickstart

๐Ÿณ Docker

cp .env.example .env
docker compose up

HTTP server (multi-user, Web UI, OAuth)

# Install dependencies
uv sync --dev

# Download ONNX model (~23 MB)
uv run python scripts/download_model.py

# Run migrations
alembic upgrade head

# Start the server
memlord

Open http://localhost:8000 for the Web UI. The MCP endpoint is at /mcp.

STDIO (local single-user, no OAuth)

STDIO mode runs the MCP server over stdin/stdout โ€” no HTTP port, no OAuth. Ideal for local use with Claude Desktop or Claude Code.

Set MEMLORD_STDIO_USER_ID to your user ID (created after first HTTP login, or 1 for a fresh DB) so all memories are scoped to your account.

pip install memlord

Create .mcp.json and adjust the paths and env vars:

{
  "mcpServers": {
    "memlord-local": {
      "command": "python",
      "args": [
        "memlord",
        "--stdio"
      ],
      "env": {
        "MEMLORD_DB_URL": "postgresql+asyncpg://postgres:postgres@localhost/memlord",
        "MEMLORD_STDIO_USER_ID": "1"
      }
    }
  }
}

๐Ÿ” How It Works

Each search request runs BM25 and vector KNN in parallel, then merges results via Reciprocal Rank Fusion:

flowchart TD
    Q([query]) --> BM25["BM25\nsearch_vector @@ websearch_to_tsquery"]
    Q --> EMB["ONNX embed\nall-MiniLM-L6-v2 ยท 384d ยท local"]
    EMB --> KNN["KNN\nembedding <=> query_vector\ncosine distance"]
    BM25 --> RRF["RRF fusion\nscore = 1/(k+rank_bm25) + 1/(k+rank_vec)\nk=60"]
    KNN --> RRF
    RRF --> R([top-N results])

โš™๏ธ Configuration

All settings use the MEMLORD_ prefix. See .env.example for the full list.

Variable

Default

Description

MEMLORD_DB_URL

postgresql+asyncpg://postgres:postgres@localhost/memlord

PostgreSQL connection URL

MEMLORD_PORT

8000

Server port

MEMLORD_BASE_URL

http://localhost:8000

Public URL for OAuth (HTTP mode)

MEMLORD_OAUTH_JWT_SECRET

memlord-dev-secret-please-change

JWT signing secret (HTTP mode)

MEMLORD_STDIO_USER_ID

โ€”

User ID to use in STDIO mode (required for stdio)

In HTTP mode, set MEMLORD_BASE_URL to your public URL and change MEMLORD_OAUTH_JWT_SECRET before deploying. In STDIO mode, OAuth is skipped โ€” set MEMLORD_STDIO_USER_ID to your numeric user ID instead.


๐Ÿ› ๏ธ MCP Tools

Tool

Description

store_memory

Save a memory (idempotent by content); raises on near-duplicates

retrieve_memory

Hybrid semantic + full-text search; returns snippets by default

recall_memory

Search by natural-language time expression; returns snippets by default

list_memories

Paginated list with type/tag filters

search_by_tag

AND/OR tag search

get_memory

Fetch a single memory by ID with full content

update_memory

Update content, type, tags, or metadata by ID

delete_memory

Delete by ID

move_memory

Move a memory to a different workspace

list_workspaces

List workspaces you are a member of (including personal)

Workspace management (create, invite, join, leave) is handled via the Web UI.


๐Ÿ’ป System Requirements

  • Python 3.12

  • PostgreSQL โ‰ฅ 15 with pgvector extension

  • uv โ€” Python package manager


๐Ÿ‘จโ€๐Ÿ’ป Development

pyright src/           # type check
ruff format .          # format
pytest                 # run tests
alembic-autogen-check  # verify migrations are up to date

๐Ÿ“„ License

Memlord is dual-licensed:

Available Tools

11 tools
delete_memoryA
Destructive

Delete a memory by name. Pass workspace to disambiguate if the name exists in multiple workspaces.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYes
workspaceNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
nameYes
successYes

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate destructiveHint=true, so description does not need to repeat destructiveness. It adds useful disambiguation context, but no further behavioral traits beyond what annotations provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, no filler. First sentence states primary action, second adds optional guidance. Ideal conciseness for a simple tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given simple tool with 2 params and output schema present, description covers core operation and disambiguation. Missing details like permissions or confirmation, but adequate for invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema has 0% description coverage for parameters. Description adds the purpose of workspace (disambiguation), but does not describe name parameter type or constraints, leaving gaps.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly states 'Delete a memory by name', specifying verb and resource. Sibling tools (get_memory, list_memories, etc.) have different purposes, so no ambiguity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Description explains when to use workspace parameter for disambiguation, but does not explicitly state when not to use this tool or suggest alternatives like update_memory if deletion is not intended.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

dream_reportA
Read-only

Candidates for memory consolidation: similar pairs, expired and expiring memories.

Read-only. The report only proposes candidates โ€” reviewing and acting on them (merge, supersede, extend, delete) is done via the regular memory tools. Similar pairs are always within a single workspace, ordered by similarity. Use the dream prompt for the full guided consolidation procedure.

ParametersJSON Schema
NameRequiredDescriptionDefault
max_pairsNo
workspaceNoLimit the report to one workspace (must have write access). Omit to cover all write-accessible workspaces.
similarity_thresholdNoMinimum cosine similarity for a pair of memories to be reported.

Output Schema

ParametersJSON Schema
NameRequiredDescription
expiredNoAlready-expired memories, hidden from reads but not yet purged.
expiring_soonNoMemories expiring within the next 7 days; extend expires_at if still valuable.
similar_pairsNoPairs of semantically close memories within one workspace, candidates for merge/supersession review.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, and the description reinforces the non-mutating nature by stating it only proposes candidates. It also adds a behavioral detail annotations cannot convey: similar pairs are always within a single workspace and ordered by similarity. It stops short of describing result volume or what the report body contains.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with what the report contains, then the read-only constraint, then routing guidance โ€” a sensible order. Every sentence carries information, though the fragment-style opening sentence is slightly compressed for the amount of detail it introduces.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value documentation is unnecessary, and annotations cover the safety profile. Combined with the description's coverage of scope, ordering, read-only behavior, and follow-up routing, an agent has everything needed to call this correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 67% โ€” `workspace` and `similarity_threshold` are documented in the schema, but `max_pairs` has no description. The description's note that pairs are single-workspace and similarity-ordered adds context relevant to two of the three parameters, but it does not compensate for the undocumented `max_pairs` or clarify threshold/limit semantics beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific resource and scope: a report of consolidation candidates consisting of similar pairs plus expired/expiring memories. It clearly distinguishes itself from the sibling memory tools by stating it only proposes candidates while merge/supersede/extend/delete happen elsewhere.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly routes the agent: this tool is for reviewing candidates, acting on them uses the regular memory tools, and the full guided procedure lives in the `dream` prompt. Both the alternative and the escalation path are named, not inferred.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_memoryA
Read-only

Fetch full content of a single memory by name.

Use only when you already know the name โ€” e.g. after retrieve_memory() or recall_memory() which return names in their results alongside compact snippets. Do NOT use for search โ€” use retrieve_memory() for semantic/text search or recall_memory() for time-based queries like 'last week'. Unlike search, this also returns expired memories (expires_at in the past) โ€” check expires_at to tell; extend it via update_memory to bring one back.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYes
workspaceNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
nameYes
tagsYes
contentYes
metadataNo
workspaceNo
created_atYes
expires_atNo
memory_typeYesfact: established fact about user, project, or system. preference: user's likes, dislikes, habits. instruction: persistent rule Claude must follow. feedback: evaluation of Claude's output. decision: a choice made with reasoning ('chose X over Y because Z'). insight: consolidated conclusion distilled from several existing memories.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish the safe read profile (readOnlyHint=true, destructiveHint=false), but the description adds a genuinely non-obvious behavior: this lookup returns expired memories that search hides, and tells the agent how to detect (expires_at) and remedy (update_memory) that state. It does not cover permissions, pagination, or duplicate-name behavior, so it falls short of a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action, then usage, then exclusions in short scannable clauses. Every sentence carries actionable content โ€” positive precondition, negative routing, and the expired-memory caveat โ€” with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value explanation is unnecessary, and the description covers selection criteria, alternatives, and the expired-memory edge case. The only real gap is the unexplained 'workspace' parameter, which prevents a 5.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage, the description carries the full burden, and it does clarify that 'name' is a memory identifier sourced from retrieve_memory/recall_memory results. However, the optional 'workspace' parameter is never mentioned in the description or the schema, leaving its scope and default semantics unexplained.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Fetch full content of a single memory by name') and immediately contrasts itself with the two nearest siblings, retrieve_memory() and recall_memory(). An agent can distinguish this tool from search-style siblings without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit precondition ('Use only when you already know the name'), names where names come from ('after retrieve_memory() or recall_memory()'), and states an explicit when-not with the correct alternatives for both semantic/text search and time-based queries. Nothing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_memoriesA
Read-only

Browse all memories ordered by creation date (newest first). Returns full content (not snippets). Use to enumerate or audit without a specific query.

ParametersJSON Schema
NameRequiredDescriptionDefault
tagNoCase-insensitive exact match on a single tag name
pageNo
page_sizeNo
memory_typeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
pageNo
itemsNo
totalNo
page_sizeNo

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds useful behavior beyond that: result ordering (newest first) and that full content is returned rather than snippets. It says nothing about pagination limits or result volume, which would have been the last piece.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, zero filler. Ordering and return format come first, and the intended use case is stated last in a single compact clause.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be re-explained, and the description still helpfully characterizes them as full content. For a read-only list tool with annotations covering safety, the only real omission is pagination guidance for the otherwise-undocumented page/page_size parameters.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 25%: tag and memory_type are documented in the schema, but page and page_size carry no descriptions. The description adds no parameter information at all โ€” notably it never mentions that results are paginated or how page/page_size interact โ€” so it fails to compensate for the documented coverage gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (browse/enumerate) and resource (memories), plus concrete scope details: ordered by creation date newest-first and full content rather than snippets. The phrase 'without a specific query' implicitly separates it from query-driven siblings like search_by_tag or recall_memory, though no sibling is named.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a clear use case ('Use to enumerate or audit without a specific query'), which tells the agent when this tool is appropriate versus retrieval/search tools. It stops short of naming specific alternatives or explicit when-not conditions, so it falls just short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_workspacesA
Read-only

List all workspaces you are a member of (personal + shared).

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide readOnlyHint=true and destructiveHint=false. Description adds that it lists workspaces the user is a member of (personal + shared), providing context beyond annotations. No contradictions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Single sentence, front-loaded, no wasted words. Perfectly concise.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Tool has no parameters, has output schema, annotations cover safety, description covers purpose and scope. Complete for a simple read-only list tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

No parameters; schema description coverage is 100%. Baseline score of 4 for 0 parameters, as description adds no parameter info but none is needed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly states the tool lists all workspaces the user is a member of, specifying personal and shared. Verb 'List' and resource 'workspaces' are precise. Sibling tools are all memory-related, so no confusion.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Description indicates when to use: to list workspaces. No explicit exclusion or alternatives, but given the tool's self-contained nature and distinct sibling set, the guidance is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

move_memoryA

Move a memory to a different to_workspace.

name: name of the memory to move. workspace: name of the target workspace (must be a member with write access). from_workspace: disambiguate source if the name exists in multiple workspaces.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYes
to_workspaceYes
from_workspaceNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
nameYes
createdYes

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations indicate non-destructive, but 'move' typically removes from source. The description adds workspace access requirement but does not clarify if memory is removed from source, potential side effects, or atomicity. There is a mild contradiction with destructiveHint=false.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise with four lines covering the action and parameters. However, parameter descriptions are listed separately rather than integrated, slightly reducing flow.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

While the description covers parameters and basic action, it does not explain return values (despite output schema existing), error cases, or behavior on name conflict. For a 3-parameter tool, this is adequate but not comprehensive.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description explains each parameter with purpose and constraints (e.g., 'to_workspace: must be a member with write access', 'from_workspace: disambiguate source'). This adds significant value beyond the bare schema, especially with 0% schema description coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Move a memory') and the target ('to a different to_workspace'). It distinguishes this tool from siblings like delete_memory or store_memory by focusing on relocation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for moving a memory between workspaces but does not provide explicit guidance on when to use vs. not use this tool, nor does it mention alternatives like update_memory for changing properties.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

recall_memoryA
Read-only

Search memories by time expression + semantics. Returns names + metadata only.

Examples: "last week", "yesterday", "about Python last month". Use get_memory(name=...) to fetch full content of a specific result. Pass workspace= to search only within a specific workspace.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYesQuery string
n_resultsNo
workspaceNo
memory_typeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
itemsNo

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds one useful behavioral fact โ€“ results are truncated to names and metadata rather than full records. It says nothing about result counts, ranking, or pagination beyond that, and an output schema already exists, so a 3 is appropriate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four tight lines: capability plus output contract first, then examples, then the escape hatch to get_memory, then the workspace scoping note. Every sentence carries distinct information and nothing is repeated from the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present and annotations covering the safety profile, the description only needs to cover invocation semantics, which it largely does via query format examples, the result-truncation contract, and the get_memory follow-up. The unexplained n_results parameter is the one remaining gap for a search tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is only 25%, so the description must compensate, and it partially does: it explains the query accepts time expressions plus semantics and gives three concrete examples, and it explains the workspace scope parameter. It says nothing about n_results or memory_type, leaving two of four parameters to the schema alone.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb and resource (search memories) and narrows scope to time expression + semantics, plus an explicit output boundary (names + metadata only). That output boundary meaningfully separates it from get_memory, which fetches full content. It does not clearly separate itself from the sibling retrieve_memory, which keeps it short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives a concrete follow-up path (use get_memory(name=...) for full content) and a scoping rule (pass workspace=<name> to restrict the search), which tells the agent when to reach for this tool. It lacks explicit exclusions relative to retrieve_memory and list_memories, so it is clear context rather than full when/when-not guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

retrieve_memoryA
Read-only

Hybrid semantic + full-text search. Returns names + metadata only.

Use get_memory(name=...) to fetch full content of a specific result. Pass workspace= to search only within a specific workspace.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
queryYesQuery string
workspaceNo
memory_typeNo
similarity_thresholdNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish readOnlyHint=true and destructiveHint=false, so safety is covered. The description adds a genuinely useful behavioral trait beyond the annotations: results are truncated to "names + metadata only," which tells the agent why a follow-up call is needed. It omits pagination/limit behavior and any rate or auth context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short lines, zero filler, and the core mechanism and the "metadata only" caveat are front-loaded before the pointers to the alternative tool. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be described, and the description correctly focuses on routing and scoping. The remaining gap is the undocumented tuning parameters (limit, similarity_threshold), which is the one thing an agent needs before calling this search tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 20%, so the description carries the burden for the other parameters. It explains workspace scoping semantics, but says nothing about limit (result count/pagination), similarity_threshold (what it controls or how the default 0.25 behaves), while memory_type is documented only inside the schema enum text. Two of five parameters remain undocumented anywhere.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names the retrieval mechanism precisely ("Hybrid semantic + full-text search") and, together with the tool name retrieve_memory, makes the resource unambiguous. It also distinguishes itself from get_memory, so an agent can separate the two siblings without opening schemas. It stops just short of 5 because it never restates the resource explicitly (memories).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives an explicit alternative and the condition for choosing it: "Use get_memory(name=...) to fetch full content of a specific result," plus a scoping condition for workspace. It does not address other plausible siblings (recall_memory, search_by_tag, list_memories), so coverage is good but not exhaustive.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_by_tagA
Read-only

Find memories by exact tag match. Returns all results (no pagination).

operation="AND" (default): memory must have ALL specified tags. operation="OR": memory must have AT LEAST ONE of the specified tags. Tags are case-insensitive. Use retrieve_memory() for semantic/text search or list_memories(tag=...) to browse a single tag with pagination.

ParametersJSON Schema
NameRequiredDescriptionDefault
tagsYes
operationNoAND

Output Schema

ParametersJSON Schema
NameRequiredDescription
pageNo
itemsNo
totalNo
page_sizeNo

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnlyHint=true, destructiveHint=false), but the description adds real behavioral context: no pagination (all results returned) and case-insensitive tag matching. It does not discuss result ordering or limits, but for a read-only search tool this is solid added value.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core purpose and the non-pagination caveat, then the operation semantics, then routing to alternatives. Four short sentences, each earning its place with no repetition of the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value explanation is unnecessary, and the description still notes the all-results/no-pagination behavior. Combined with explicit sibling routing and enum semantics, an agent has everything needed to invoke this correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry the load, and it does: it defines operation='AND' (default, all tags required) vs 'OR' (at least one tag), and clarifies tags are exact and case-insensitive. Only minor gaps remain, such as the uniqueItems constraint in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Find memories by exact tag match') and immediately narrows scope with 'exact tag match' plus 'Returns all results (no pagination)'. It is clearly distinguishable from retrieve_memory and list_memories, both of which are named explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes the agent: use retrieve_memory() for semantic/text search and list_memories(tag=...) to browse a single tag with pagination, implying this tool for multi-tag exact matching without pagination. The when-to-use and when-to-use-something-else conditions are both stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

store_memoryA
Idempotent

Save a new memory. Idempotent: returns existing if content already stored.

name: human-readable name, unique within the workspace. workspace: name of the workspace to store into. Omit to store as a personal memory. force: skip near-duplicate check and store unconditionally. expires_at: optional UTC expiry; after it passes the memory is hidden from reads.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYes
tagsNo
forceNoSkip near-duplicate check and store unconditionally.
contentYes
metadataNo
workspaceNoName of the workspace to store into (must be a member). Omit or pass None to store as a personal memory.
expires_atNoUTC timestamp after which the memory is hidden from search and list results (still retrievable by exact name via get_memory). Expired memories are purged via the profile 'clean up expired' button. None = never expires.
memory_typeYesfact: established fact about user, project, or system. preference: user's likes, dislikes, habits. instruction: persistent rule Claude must follow. feedback: evaluation of Claude's output. decision: a choice made with reasoning ('chose X over Y because Z'). insight: consolidated conclusion distilled from several existing memories.

Output Schema

ParametersJSON Schema
NameRequiredDescription
nameYes
createdYes

TDQS

A3.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare idempotentHint=true and destructiveHint=false, so the baseline is set. The description adds real value beyond them: a near-duplicate check runs by default and is skipped only with force, expired memories remain retrievable by exact name via get_memory, and purging happens through a profile clean-up action. It does not describe return shape, but that is defensible given the idempotency note.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded one-line purpose followed by compact per-parameter bullets; nothing is wasted. The only blemish is that the workspace and force blurbs are near-verbatim duplicates of the schema descriptions, which is mild redundancy rather than bloat.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need no explanation, and the description covers creation semantics, dedup behavior, workspace scoping, and expiry. It is adequate for an 8-parameter write tool, though it could say more about what content or memory_type should contain and where the sibling update_memory takes over.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With only 50% schema description coverage across 8 parameters, the description must compensate, and it does for the four most ambiguous ones: name uniqueness, workspace membership vs personal-memory default, force semantics, and the expiry lifecycle. content, tags, and metadata are left unexplained, but those are largely self-evident and memory_type carries a detailed enum in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence gives a specific verb+resource ("Save a new memory") and the word "new" implicitly distinguishes it from the update_memory sibling. However, it never explicitly names or contrasts with update_memory, recall_memory, or retrieve_memory, so an agent must infer the boundary itself.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description states the tool is idempotent and returns existing content, which implies the caller need not pre-check for duplicates, but it never states when to use this over update_memory for existing memories or why not to use it for retrieval. No prerequisites, exclusions, or alternative routing are given despite ten siblings covering overlapping memory operations.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_memoryB

Update an existing memory identified by name. Only provided fields are changed.

new_name: rename the memory to this name. workspace: disambiguate if the name exists in multiple workspaces. expires_at: set or extend the UTC expiry; omit to leave it unchanged.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYes
tagsNo
contentNo
metadataNo
new_nameNo
workspaceNo
expires_atNoSet or extend the UTC expiry. Omit to leave unchanged.
memory_typeYesfact: established fact about user, project, or system. preference: user's likes, dislikes, habits. instruction: persistent rule Claude must follow. feedback: evaluation of Claude's output. decision: a choice made with reasoning ('chose X over Y because Z'). insight: consolidated conclusion distilled from several existing memories.

Output Schema

ParametersJSON Schema
NameRequiredDescription
nameYes
createdYes

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare idempotentHint=false and destructiveHint=false; the description usefully adds that unspecified fields are preserved, which is not in the annotations. It still omits what happens on name collision, whether renames are reversible, and why the call is non-idempotent, so it adds partial rather than rich behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four short lines, front-loaded with the core action and then one line per non-obvious field. The per-field list is efficient, though the expires_at line is a verbatim restatement of the schema description and earns no new information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value explanation is unnecessary, and the partial-update rule is stated. For an 8-parameter mutation tool with non-idempotent behavior, the description is still thin on collision/rename semantics and on how content, tags, and metadata interact with existing values.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is only 25%, so the description carries extra burden. It explains new_name, workspace, and expires_at, and duplicates the schema's expires_at wording, but says nothing about tags, content, or metadata โ€” including whether they replace or merge with existing values, which is the most consequential ambiguity for a 8-parameter tool.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Update an existing memory') and adds the partial-update semantic ('Only provided fields are changed'), which is a meaningful differentiator from store_memory or delete_memory. It does not, however, distinguish itself from move_memory, which appears to be the natural alternative for changing workspace.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied through the field explanations: workspace is described as a disambiguator and expires_at as an extend-or-set action. There is no explicit when-to-use framing, and the workspace note potentially conflicts with the existence of move_memory, leaving the agent to infer which tool performs workspace changes.

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.

  1. 8 tool updatesv0.2.9
    • Addeddream_report
    • Changedget_memory3 fields changed
      • addedOutput schema / properties / expires_at
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ]
        +}
      • changedOutput schema / properties / memory_type / description
        Previous value: -"fact: established fact about user, project, or system.\npreference: user's likes, dislikes, habits.\ninstruction: persistent rule Claude must follow.\nfeedback: evaluation of Claude's output.\ndecision: a choice made with reasoning ('chose X over Y because Z')."New value: +"fact: established fact about user, project, or system.\npreference: user's likes, dislikes, habits.\ninstruction: persistent rule Claude must follow.\nfeedback: evaluation of Claude's output.\ndecision: a choice made with reasoning ('chose X over Y because Z').\ninsight: consolidated conclusion distilled from several existing memories."
      • changedOutput schema / properties / memory_type / enum
        Previous value: -[
        -  "fact",
        -  "preference",
        -  "instruction",
        -  "feedback",
        -  "decision"
        -]New value: +[
        +  "fact",
        +  "preference",
        +  "instruction",
        +  "feedback",
        +  "decision",
        +  "insight"
        +]
    • Changedlist_memories4 fields changed
      • changedInput schema / properties / memory_type / anyOf
        Previous value: -[
        -  {
        -    "description": "fact: established fact about user, project, or system.\npreference: user's likes, dislikes, habits.\ninstruction: persistent rule Claude must follow.\nfeedback: evaluation of Claude's output.\ndecision: a choice made with reasoning ('chose X over Y because Z').",
        -    "enum": [
        -      "fact",
        -      "preference",
        -      "instruction",
        -      "feedback",
        -      "decision"
        -    ],
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "description": "fact: established fact about user, project, or system.\npreference: user's likes, dislikes, habits.\ninstruction: persistent rule Claude must follow.\nfeedback: evaluation of Claude's output.\ndecision: a choice made with reasoning ('chose X over Y because Z').\ninsight: consolidated conclusion distilled from several existing memories.",
        +    "enum": [
        +      "fact",
        +      "preference",
        +      "instruction",
        +      "feedback",
        +      "decision",
        +      "insight"
        +    ],
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • addedOutput schema / properties / items / items / properties / expires_at
        Added value: +{
        +  "anyOf": [
        +    {
        +      "format": "date-time",
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Expires At"
        +}
      • changedOutput schema / properties / items / items / properties / memory_type / description
        Previous value: -"fact: established fact about user, project, or system.\npreference: user's likes, dislikes, habits.\ninstruction: persistent rule Claude must follow.\nfeedback: evaluation of Claude's output.\ndecision: a choice made with reasoning ('chose X over Y because Z')."New value: +"fact: established fact about user, project, or system.\npreference: user's likes, dislikes, habits.\ninstruction: persistent rule Claude must follow.\nfeedback: evaluation of Claude's output.\ndecision: a choice made with reasoning ('chose X over Y because Z').\ninsight: consolidated conclusion distilled from several existing memories."
      • changedOutput schema / properties / items / items / properties / memory_type / enum
        Previous value: -[
        -  "fact",
        -  "preference",
        -  "instruction",
        -  "feedback",
        -  "decision"
        -]New value: +[
        +  "fact",
        +  "preference",
        +  "instruction",
        +  "feedback",
        +  "decision",
        +  "insight"
        +]
    • Changedrecall_memory2 fields changed
      • changedInput schema / properties / memory_type / anyOf
        Previous value: -[
        -  {
        -    "description": "fact: established fact about user, project, or system.\npreference: user's likes, dislikes, habits.\ninstruction: persistent rule Claude must follow.\nfeedback: evaluation of Claude's output.\ndecision: a choice made with reasoning ('chose X over Y because Z').",
        -    "enum": [
        -      "fact",
        -      "preference",
        -      "instruction",
        -      "feedback",
        -      "decision"
        -    ],
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "description": "fact: established fact about user, project, or system.\npreference: user's likes, dislikes, habits.\ninstruction: persistent rule Claude must follow.\nfeedback: evaluation of Claude's output.\ndecision: a choice made with reasoning ('chose X over Y because Z').\ninsight: consolidated conclusion distilled from several existing memories.",
        +    "enum": [
        +      "fact",
        +      "preference",
        +      "instruction",
        +      "feedback",
        +      "decision",
        +      "insight"
        +    ],
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedOutput schema / properties / items / items / properties / memory_type / anyOf
        Previous value: -[
        -  {
        -    "description": "fact: established fact about user, project, or system.\npreference: user's likes, dislikes, habits.\ninstruction: persistent rule Claude must follow.\nfeedback: evaluation of Claude's output.\ndecision: a choice made with reasoning ('chose X over Y because Z').",
        -    "enum": [
        -      "fact",
        -      "preference",
        -      "instruction",
        -      "feedback",
        -      "decision"
        -    ],
        -    "title": "MemoryType",
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "description": "fact: established fact about user, project, or system.\npreference: user's likes, dislikes, habits.\ninstruction: persistent rule Claude must follow.\nfeedback: evaluation of Claude's output.\ndecision: a choice made with reasoning ('chose X over Y because Z').\ninsight: consolidated conclusion distilled from several existing memories.",
        +    "enum": [
        +      "fact",
        +      "preference",
        +      "instruction",
        +      "feedback",
        +      "decision",
        +      "insight"
        +    ],
        +    "title": "MemoryType",
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
    • Changedretrieve_memory3 fields changed
      • changedInput schema / properties / memory_type / anyOf
        Previous value: -[
        -  {
        -    "description": "fact: established fact about user, project, or system.\npreference: user's likes, dislikes, habits.\ninstruction: persistent rule Claude must follow.\nfeedback: evaluation of Claude's output.\ndecision: a choice made with reasoning ('chose X over Y because Z').",
        -    "enum": [
        -      "fact",
        -      "preference",
        -      "instruction",
        -      "feedback",
        -      "decision"
        -    ],
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "description": "fact: established fact about user, project, or system.\npreference: user's likes, dislikes, habits.\ninstruction: persistent rule Claude must follow.\nfeedback: evaluation of Claude's output.\ndecision: a choice made with reasoning ('chose X over Y because Z').\ninsight: consolidated conclusion distilled from several existing memories.",
        +    "enum": [
        +      "fact",
        +      "preference",
        +      "instruction",
        +      "feedback",
        +      "decision",
        +      "insight"
        +    ],
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedOutput schema / properties / result / items / properties / memory_type / description
        Previous value: -"fact: established fact about user, project, or system.\npreference: user's likes, dislikes, habits.\ninstruction: persistent rule Claude must follow.\nfeedback: evaluation of Claude's output.\ndecision: a choice made with reasoning ('chose X over Y because Z')."New value: +"fact: established fact about user, project, or system.\npreference: user's likes, dislikes, habits.\ninstruction: persistent rule Claude must follow.\nfeedback: evaluation of Claude's output.\ndecision: a choice made with reasoning ('chose X over Y because Z').\ninsight: consolidated conclusion distilled from several existing memories."
      • changedOutput schema / properties / result / items / properties / memory_type / enum
        Previous value: -[
        -  "fact",
        -  "preference",
        -  "instruction",
        -  "feedback",
        -  "decision"
        -]New value: +[
        +  "fact",
        +  "preference",
        +  "instruction",
        +  "feedback",
        +  "decision",
        +  "insight"
        +]
    • Changedsearch_by_tag3 fields changed
      • addedOutput schema / properties / items / items / properties / expires_at
        Added value: +{
        +  "anyOf": [
        +    {
        +      "format": "date-time",
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Expires At"
        +}
      • changedOutput schema / properties / items / items / properties / memory_type / description
        Previous value: -"fact: established fact about user, project, or system.\npreference: user's likes, dislikes, habits.\ninstruction: persistent rule Claude must follow.\nfeedback: evaluation of Claude's output.\ndecision: a choice made with reasoning ('chose X over Y because Z')."New value: +"fact: established fact about user, project, or system.\npreference: user's likes, dislikes, habits.\ninstruction: persistent rule Claude must follow.\nfeedback: evaluation of Claude's output.\ndecision: a choice made with reasoning ('chose X over Y because Z').\ninsight: consolidated conclusion distilled from several existing memories."
      • changedOutput schema / properties / items / items / properties / memory_type / enum
        Previous value: -[
        -  "fact",
        -  "preference",
        -  "instruction",
        -  "feedback",
        -  "decision"
        -]New value: +[
        +  "fact",
        +  "preference",
        +  "instruction",
        +  "feedback",
        +  "decision",
        +  "insight"
        +]
    • Changedstore_memory3 fields changed
      • addedInput schema / properties / expires_at
        Added value: +{
        +  "anyOf": [
        +    {
        +      "format": "date-time",
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "UTC timestamp after which the memory is hidden from search and list results (still retrievable by exact name via get_memory). Expired memories are purged via the profile 'clean up expired' button. None = never expires."
        +}
      • changedInput schema / properties / memory_type / description
        Previous value: -"fact: established fact about user, project, or system.\npreference: user's likes, dislikes, habits.\ninstruction: persistent rule Claude must follow.\nfeedback: evaluation of Claude's output.\ndecision: a choice made with reasoning ('chose X over Y because Z')."New value: +"fact: established fact about user, project, or system.\npreference: user's likes, dislikes, habits.\ninstruction: persistent rule Claude must follow.\nfeedback: evaluation of Claude's output.\ndecision: a choice made with reasoning ('chose X over Y because Z').\ninsight: consolidated conclusion distilled from several existing memories."
      • changedInput schema / properties / memory_type / enum
        Previous value: -[
        -  "fact",
        -  "preference",
        -  "instruction",
        -  "feedback",
        -  "decision"
        -]New value: +[
        +  "fact",
        +  "preference",
        +  "instruction",
        +  "feedback",
        +  "decision",
        +  "insight"
        +]
    • Changedupdate_memory3 fields changed
      • addedInput schema / properties / expires_at
        Added value: +{
        +  "anyOf": [
        +    {
        +      "format": "date-time",
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Set or extend the UTC expiry. Omit to leave unchanged."
        +}
      • changedInput schema / properties / memory_type / description
        Previous value: -"fact: established fact about user, project, or system.\npreference: user's likes, dislikes, habits.\ninstruction: persistent rule Claude must follow.\nfeedback: evaluation of Claude's output.\ndecision: a choice made with reasoning ('chose X over Y because Z')."New value: +"fact: established fact about user, project, or system.\npreference: user's likes, dislikes, habits.\ninstruction: persistent rule Claude must follow.\nfeedback: evaluation of Claude's output.\ndecision: a choice made with reasoning ('chose X over Y because Z').\ninsight: consolidated conclusion distilled from several existing memories."
      • changedInput schema / properties / memory_type / enum
        Previous value: -[
        -  "fact",
        -  "preference",
        -  "instruction",
        -  "feedback",
        -  "decision"
        -]New value: +[
        +  "fact",
        +  "preference",
        +  "instruction",
        +  "feedback",
        +  "decision",
        +  "insight"
        +]
  2. 10 tool updates
    • Addeddelete_memory
    • Addedget_memory
    • Addedlist_memories
    • Addedlist_workspaces
    • Addedmove_memory
    • Addedrecall_memory
    • Addedretrieve_memory
    • Addedsearch_by_tag
    • Addedstore_memory
    • Addedupdate_memory
  3. 10 tool updatesv0.2.8
    • Removeddelete_memory
    • Removedget_memory
    • Removedlist_memories
    • Removedlist_workspaces
    • Removedmove_memory
    • Removedrecall_memory
    • Removedretrieve_memory
    • Removedsearch_by_tag
    • Removedstore_memory
    • Removedupdate_memory
  4. 5 tool updatesv0.2.7
    • Changedget_memory1 field changed
      • removedOutput schema / properties / created_at / format
        Removed value: -"date-time"
    • Changedlist_memories5 fields changed
      • addedOutput schema / properties / page / default
        Added value: +1
      • addedOutput schema / properties / page_size / default
        Added value: +0
      • addedOutput schema / properties / total / default
        Added value: +0
      • addedOutput schema / properties / total_pages / default
        Added value: +0
      • removedOutput schema / required
        Removed value: -[
        -  "items",
        -  "total",
        -  "page",
        -  "page_size",
        -  "total_pages"
        -]
    • Changedrecall_memory5 fields changed
      • addedOutput schema / properties / items
        Added value: +{
        +  "items": {
        +    "properties": {
        +      "content": {
        +        "title": "Content",
        +        "type": "string"
        +      },
        +      "created_at": {
        +        "format": "date-time",
        +        "title": "Created At",
        +        "type": "string"
        +      },
        +      "id": {
        +        "title": "Id",
        +        "type": "integer"
        +      },
        +      "memory_type": {
        +        "anyOf": [
        +          {
        +            "enum": [
        +              "fact",
        +              "preference",
        +              "instruction",
        +              "feedback"
        +            ],
        +            "title": "MemoryType",
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      },
        +      "tags": {
        +        "items": {
        +          "type": "string"
        +        },
        +        "title": "Tags",
        +        "type": "array",
        +        "uniqueItems": true
        +      },
        +      "workspace_id": {
        +        "anyOf": [
        +          {
        +            "type": "integer"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "title": "Workspace Id"
        +      }
        +    },
        +    "required": [
        +      "id",
        +      "content",
        +      "memory_type",
        +      "tags",
        +      "created_at"
        +    ],
        +    "title": "RecallResult",
        +    "type": "object"
        +  },
        +  "title": "Items",
        +  "type": "array"
        +}
      • removedOutput schema / properties / result
        Removed value: -{
        -  "items": {
        -    "properties": {
        -      "content": {
        -        "type": "string"
        -      },
        -      "created_at": {
        -        "format": "date-time",
        -        "type": "string"
        -      },
        -      "id": {
        -        "type": "integer"
        -      },
        -      "memory_type": {
        -        "anyOf": [
        -          {
        -            "enum": [
        -              "fact",
        -              "preference",
        -              "instruction",
        -              "feedback"
        -            ],
        -            "type": "string"
        -          },
        -          {
        -            "type": "null"
        -          }
        -        ]
        -      },
        -      "tags": {
        -        "items": {
        -          "type": "string"
        -        },
        -        "type": "array",
        -        "uniqueItems": true
        -      },
        -      "workspace_id": {
        -        "anyOf": [
        -          {
        -            "type": "integer"
        -          },
        -          {
        -            "type": "null"
        -          }
        -        ],
        -        "default": null
        -      }
        -    },
        -    "required": [
        -      "id",
        -      "content",
        -      "memory_type",
        -      "tags",
        -      "created_at"
        -    ],
        -    "type": "object"
        -  },
        -  "type": "array"
        -}
      • removedOutput schema / required
        Removed value: -[
        -  "result"
        -]
      • addedOutput schema / title
        Added value: +"RecallPage"
      • removedOutput schema / x-fastmcp-wrap-result
        Removed value: -true
    • Changedretrieve_memory1 field changed
      • removedOutput schema / properties / result / items / properties / created_at / format
        Removed value: -"date-time"
    • Changedsearch_by_tag9 fields changed
      • addedOutput schema / properties / items
        Added value: +{
        +  "items": {
        +    "properties": {
        +      "content": {
        +        "title": "Content",
        +        "type": "string"
        +      },
        +      "created_at": {
        +        "format": "date-time",
        +        "title": "Created At",
        +        "type": "string"
        +      },
        +      "id": {
        +        "title": "Id",
        +        "type": "integer"
        +      },
        +      "memory_type": {
        +        "enum": [
        +          "fact",
        +          "preference",
        +          "instruction",
        +          "feedback"
        +        ],
        +        "title": "MemoryType",
        +        "type": "string"
        +      },
        +      "metadata": {
        +        "additionalProperties": true,
        +        "title": "Metadata",
        +        "type": "object"
        +      },
        +      "tags": {
        +        "items": {
        +          "type": "string"
        +        },
        +        "title": "Tags",
        +        "type": "array",
        +        "uniqueItems": true
        +      },
        +      "workspace_id": {
        +        "anyOf": [
        +          {
        +            "type": "integer"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "title": "Workspace Id"
        +      }
        +    },
        +    "required": [
        +      "id",
        +      "content",
        +      "memory_type",
        +      "tags",
        +      "created_at"
        +    ],
        +    "title": "MemoryListItem",
        +    "type": "object"
        +  },
        +  "title": "Items",
        +  "type": "array"
        +}
      • addedOutput schema / properties / page
        Added value: +{
        +  "default": 1,
        +  "title": "Page",
        +  "type": "integer"
        +}
      • addedOutput schema / properties / page_size
        Added value: +{
        +  "default": 0,
        +  "title": "Page Size",
        +  "type": "integer"
        +}
      • removedOutput schema / properties / result
        Removed value: -{
        -  "items": {
        -    "properties": {
        -      "content": {
        -        "type": "string"
        -      },
        -      "created_at": {
        -        "format": "date-time",
        -        "type": "string"
        -      },
        -      "id": {
        -        "type": "integer"
        -      },
        -      "memory_type": {
        -        "enum": [
        -          "fact",
        -          "preference",
        -          "instruction",
        -          "feedback"
        -        ],
        -        "type": "string"
        -      },
        -      "metadata": {
        -        "additionalProperties": true,
        -        "type": "object"
        -      },
        -      "tags": {
        -        "items": {
        -          "type": "string"
        -        },
        -        "type": "array",
        -        "uniqueItems": true
        -      },
        -      "workspace_id": {
        -        "anyOf": [
        -          {
        -            "type": "integer"
        -          },
        -          {
        -            "type": "null"
        -          }
        -        ],
        -        "default": null
        -      }
        -    },
        -    "required": [
        -      "id",
        -      "content",
        -      "memory_type",
        -      "tags",
        -      "created_at"
        -    ],
        -    "type": "object"
        -  },
        -  "type": "array"
        -}
      • addedOutput schema / properties / total
        Added value: +{
        +  "default": 0,
        +  "title": "Total",
        +  "type": "integer"
        +}
      • addedOutput schema / properties / total_pages
        Added value: +{
        +  "default": 0,
        +  "title": "Total Pages",
        +  "type": "integer"
        +}
      • removedOutput schema / required
        Removed value: -[
        -  "result"
        -]
      • addedOutput schema / title
        Added value: +"MemoryPage"
      • removedOutput schema / x-fastmcp-wrap-result
        Removed value: -true
  5. 10 tool updatesv0.2.4
    • First observeddelete_memory
    • First observedget_memory
    • First observedlist_memories
    • First observedlist_workspaces
    • First observedmove_memory
    • First observedrecall_memory
    • First observedretrieve_memory
    • First observedsearch_by_tag
    • First observedstore_memory
    • First observedupdate_memory

TDQS

A3.9/5.0

Scored across 11 tools

Disambiguation4/5

Retrieval tools (retrieve_memory, recall_memory, get_memory, list_memories, search_by_tag) overlap in purpose, but descriptions clearly distinguish semantic/text search, time-based search, direct name lookup, browsing, and exact tag search. CRUD, workspace, and consolidation tools are clearly separate.

Naming Consistency4/5

Almost all tools follow a consistent snake_case verb_noun pattern (store_memory, update_memory, retrieve_memory, etc.). The one outlier is dream_report, which is noun-based rather than verb-based, but the set remains predictable overall.

Tool Count5/5

11 tools is well-scoped for a memory management server. Each tool appears to cover a distinct operation, and the count sits comfortably within the typical 3-15 range without obvious bloat.

Completeness3/5

Core memory lifecycle is covered: store, get, update, delete, move, search, list, and expiry handling. Notable gaps remain: there is no create/delete workspace tool despite list_workspaces, and no tool to add or remove tags despite search_by_tag, which could leave agents unable to set up tag-based searches.

Maintenance

ActivityMaintained
ResponsivenessSlow

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Persistent memory and handoff intelligence layer for MCP agents. Most memory servers retrieve text โ€” Memory Nexus compounds operational context, learning from usage and progressively synthesizing observations into higher-order intelligence across sessions and tools.
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Provides persistent AI agent memory using a local vector database for long-term semantic storage and short-term session scratchpads. It enables low-latency memory operations including search, storage, and bulk management without external cloud dependencies.
    -