Skip to main content
Glama

Mnemoverse Memory

Hosted long-term memory for AI agents over MCP. Two calls cover the basics: memory_write saves a memory, and memory_read finds it again by a natural-language query. Pass domain: "user:<id>" on both to keep each user's memories apart (a namespace inside your account, not a permission boundary). Rating a recalled memory as helpful or misleading re-ranks what comes back next (memory_feedback).

Free plan, no credit card: 1,000 queries a day (reads, writes and feedback combined), 10,000 atoms of storage, 60 requests a minute. Plans and limits: mnemoverse.com/pricing

Connect with an OAuth sign-in on the hosted endpoint https://mcp.mnemoverse.com/mcp, or run this package locally with an API key. Setup for Claude Code, Claude Desktop, Cursor, VS Code, Devin Desktop (formerly Windsurf), Zed, JetBrains, Cline, Gemini CLI and ChatGPT is below. Steps for other hosts: mnemoverse.com/docs/api/install-by-host

Shared rooms (beta) let several agents work from one memory.

@mnemoverse/mcp-memory-server is the MIT-licensed MCP server for the hosted Mnemoverse memory engine.

npm version npm downloads MCP Registry License: MIT Research: SLoD arXiv Glama quality

What is Mnemoverse Memory?

Mnemoverse is a hosted memory engine for AI agents, reached over the Model Context Protocol. It stores what your agents learn (decisions, preferences, lessons) and returns it in any connected tool, so one memory follows you across Claude Code, Cursor, VS Code and ChatGPT with one account: an API key in a local config, or an OAuth sign-in on the hosted endpoint.

What is open source here, and what is not. This repository, the MCP server, is MIT, and so is the Python SDK. The memory engine they talk to is a hosted service with a free tier. Self-hosting the engine is available on Enterprise plans by agreement, when security or compliance requirements call for it; by default we run it for you.

Related MCP server: memmd-mcp

How it compares

Most agent memory today lives in one of three places. Per-tool instruction files (CLAUDE.md, .cursorrules, AGENTS.md) are versioned and readable, each new session reads them again, and a committed file travels with its repository; but a file reaches only the tools that look for its name, so a rule written for Claude Code is not there in a ChatGPT chat. A vector store behind RAG retrieves by similarity, and similarity never changes because advice helped or misled. Local-first memory servers win on privacy and latency, and ask you to run and update the infrastructure yourself. Mnemoverse is the managed, cross-tool option in that landscape: nothing to deploy, one account everywhere, and rating a recalled memory as helpful or misleading re-ranks what comes back next. If you need memory inside your own perimeter, a local-first server is the better choice; this one is hosted by default, with Enterprise self-hosting by agreement.

⭐ If Mnemoverse saves you from re-explaining context to your agents, star the repo. It helps other builders find it.

Quick Start

No key: the hosted endpoint

If your client signs in over OAuth, you do not need a key at all. Create a free account at console.mnemoverse.com (no credit card), then connect the hosted endpoint.

Claude Code:

claude mcp add --scope user --transport http mnemoverse https://mcp.mnemoverse.com/mcp

Then start Claude Code, run /mcp, select mnemoverse and choose Authenticate. A session that was already running when the command ran does not load the new server: exit and start claude again first.

Cursor, in .cursor/mcp.json:

{ "mcpServers": { "mnemoverse": { "url": "https://mcp.mnemoverse.com/mcp" } } }

Claude Desktop, Devin Desktop (formerly Windsurf), VS Code and ChatGPT: Remote MCP setup. The local server below is the other path: it runs on your machine and reads an API key.

1. Get a free API key

Sign up at console.mnemoverse.com — takes 30 seconds, no credit card.

Check the key before you put it in a config. Both forms ask for the key at a masked prompt and never pass it as a command argument, so it lands neither in your shell history nor in the process list.

macOS, Linux, Git Bash:

printf 'Mnemoverse API key: '; read -rs KEY; echo
printf 'X-Api-Key: %s\n' "$KEY" | curl -s -H @- https://core.mnemoverse.com/api/v1/memory/stats; unset KEY

Windows PowerShell 5.1 and PowerShell 7:

$k = [Net.NetworkCredential]::new('', (Read-Host 'Mnemoverse API key' -AsSecureString)).Password
try { (Invoke-WebRequest https://core.mnemoverse.com/api/v1/memory/stats -Headers @{ 'X-Api-Key' = $k } -UseBasicParsing).Content }
catch { if ($_.ErrorDetails.Message) { $_.ErrorDetails.Message } else { (New-Object IO.StreamReader($_.Exception.Response.GetResponseStream())).ReadToEnd() } }; Remove-Variable k

The output contains

What it means

JSON that includes "total_atoms"

The key works.

"reason":"placeholder_key"

That is the example key from these docs. Create a real one at the console.

"reason":"malformed_key"

Not the shape of a key: cut short in the paste, wrapped in quotes, or a different token entirely.

"reason":"invalid_key"

The shape is right and no such key exists. Copy it again from the console.

"reason":"revoked_key"

The key was revoked and will not work again. Create a new one.

"reason":"missing_key"

No key reached the API: what you entered was empty.

In the JSON, reason sits inside the details object (details.reason), next to details.keys_url, the console page where keys are created.

2. Connect to your AI tool

The two canonical setups, Claude Code and Cursor. Each starts with the hosted server: a browser sign-in and no key. Their key-based setups write the key once, at user scope, covering every project; each client further down says where its own config lives. Avoid a per-project config file for a key: it lives inside the repository and can be committed with it, and a key belongs outside:

Claude Code — the hosted server, with a browser sign-in. No API key, nothing to install:

claude mcp add --scope user --transport http mnemoverse https://mcp.mnemoverse.com/mcp

Then start Claude Code, run /mcp, select mnemoverse and choose Authenticate. If the command ran inside a Claude Code session (yours, or Claude ran it for you), that session does not load the new server: exit and start claude again first.

To run the local server with an API key instead (Node.js 18 or later), put your own key in place of mk_live_YOUR_KEY. Use one or the other, not both: they share the name mnemoverse.

claude mcp add mnemoverse --scope user \
  -e MNEMOVERSE_API_KEY=mk_live_YOUR_KEY \
  -e MNEMOVERSE_API_URL=https://core.mnemoverse.com/api/v1 \
  -- npx -y @mnemoverse/mcp-memory-server@latest

On Windows (PowerShell), paste the same command as one line — PowerShell does not read the \ line continuations:

claude mcp add mnemoverse --scope user -e MNEMOVERSE_API_KEY=mk_live_YOUR_KEY -e MNEMOVERSE_API_URL=https://core.mnemoverse.com/api/v1 -- npx -y @mnemoverse/mcp-memory-server@latest

Cursor — click to add the hosted server. Cursor signs you in through the browser, so there is no key to paste:

Add to Cursor

The button writes {"url": "https://mcp.mnemoverse.com/mcp"} under mnemoverse in ~/.cursor/mcp.json, the global config that covers every project. Then click Connect next to mnemoverse in Cursor's MCP settings (Customize in the sidebar; Cursor Settings → Tools & MCPs in Cursor 3.21.16) and approve in the browser. Cursor runs the sign-in and keeps the token itself.

To run the local server with an API key instead, add the JSON below to ~/.cursor/mcp.json, merging it with any servers already there, and put your own key in place of mk_live_YOUR_KEY. Get one at console.mnemoverse.com. Do not put it in a project-level .cursor/mcp.json: that file lives inside the repository and is committed with it unless you exclude it, and this config holds your key. Use one entry or the other, not both: they share the name mnemoverse.

{
  "mcpServers": {
    "mnemoverse": {
      "command": "npx",
      "args": [
        "-y",
        "@mnemoverse/mcp-memory-server@latest"
      ],
      "env": {
        "MNEMOVERSE_API_KEY": "mk_live_YOUR_KEY",
        "MNEMOVERSE_API_URL": "https://core.mnemoverse.com/api/v1"
      }
    }
  }
}

VS Code — the VS Code extension signs in through the browser and needs no key; that's the default path. In VS Code's non-interactive Agent Host mode, servers that prompt for inputs like this one are not started; for unattended use there, put the key in the environment of the process that launches VS Code instead. To wire the MCP server directly instead, add this to .vscode/mcp.json (note: VS Code uses servers, not mcpServers). Never put a literal mk_live_ key in that file — it's committed with the repo. The inputs entry below prompts for the key instead: VS Code masks what you type and stores it in its own secret storage, not in the file:

{
  "inputs": [
    {
      "type": "promptString",
      "id": "mnemoverse-api-key",
      "description": "Mnemoverse API key (starts with mk_live_), for this local package only: the hosted server https://mcp.mnemoverse.com/mcp signs in with OAuth and takes no key. Optional to install and inspect — the server starts and lists its tools without a key; every actual tool call requires one. Get one free in ~30s at https://console.mnemoverse.com",
      "password": true
    }
  ],
  "servers": {
    "mnemoverse": {
      "type": "stdio",
      "command": "npx",
      "args": [
        "-y",
        "@mnemoverse/mcp-memory-server@latest"
      ],
      "env": {
        "MNEMOVERSE_API_KEY": "${input:mnemoverse-api-key}",
        "MNEMOVERSE_API_URL": "https://core.mnemoverse.com/api/v1"
      }
    }
  }
}

Devin Desktop (formerly Windsurf) — add to ~/.config/devin/mcp_config.json:

{
  "mcpServers": {
    "mnemoverse": {
      "command": "npx",
      "args": [
        "-y",
        "@mnemoverse/mcp-memory-server@latest"
      ],
      "env": {
        "MNEMOVERSE_API_KEY": "mk_live_YOUR_KEY",
        "MNEMOVERSE_API_URL": "https://core.mnemoverse.com/api/v1"
      }
    }
  }
}

More MCP clients — same server, different config file:

Zed — add to ~/.config/zed/settings.json (Zed uses context_servers, and "source": "custom" is required):

{
  "context_servers": {
    "mnemoverse": {
      "source": "custom",
      "command": "npx",
      "args": [
        "-y",
        "@mnemoverse/mcp-memory-server@latest"
      ],
      "env": {
        "MNEMOVERSE_API_KEY": "mk_live_YOUR_KEY",
        "MNEMOVERSE_API_URL": "https://core.mnemoverse.com/api/v1"
      }
    }
  }
}

JetBrains (AI Assistant) — Settings → Tools → AI Assistant → Model Context Protocol (MCP), then paste:

{
  "mcpServers": {
    "mnemoverse": {
      "command": "npx",
      "args": [
        "-y",
        "@mnemoverse/mcp-memory-server@latest"
      ],
      "env": {
        "MNEMOVERSE_API_KEY": "mk_live_YOUR_KEY",
        "MNEMOVERSE_API_URL": "https://core.mnemoverse.com/api/v1"
      }
    }
  }
}

Cline — MCP Servers → Configure (or edit cline_mcp_settings.json). Cline reads env values literally, so paste your real key — not a ${VAR} reference:

{
  "mcpServers": {
    "mnemoverse": {
      "command": "npx",
      "args": [
        "-y",
        "@mnemoverse/mcp-memory-server@latest"
      ],
      "env": {
        "MNEMOVERSE_API_KEY": "mk_live_YOUR_KEY",
        "MNEMOVERSE_API_URL": "https://core.mnemoverse.com/api/v1"
      }
    }
  }
}

Why @latest? Bare npx @mnemoverse/mcp-memory-server is cached indefinitely by npm and stops re-checking the registry. The @latest suffix forces a metadata lookup on every Claude Code / Cursor / VS Code session start (~100-300ms), so you always pick up new releases.

⚠️ Restart your AI client after editing the config. MCP servers are only picked up on client startup.

3. Try it — 30 seconds to verify it works

Paste this in your AI chat:

"Remember that my favourite TypeScript framework is Hono, and please call memory_write to save it."

Your agent should call memory_write and confirm the memory was stored.

Then open a new chat / new session (this is the whole point — memory survives restarts), and ask:

"What's my favourite TypeScript framework?"

Your agent should call memory_read, find the entry, and answer "Hono". If it does — you're wired up. Write whatever you want next.

If it doesn't remember: check that the client was fully restarted and the config has your real mk_live_... key, not the placeholder. On the hosted server there is no key to check; check that the browser sign-in finished (in Cursor, Connect next to mnemoverse).

⭐ If the second session remembered, star the repo. It helps other builders find it.

4. Make it a habit

The test above works because you asked the agent to call the tool. In normal work it will not, unless it has a standing instruction that says when to read memory and when to save. The setup_memory prompt writes those rules for Claude Code, Claude, Cursor or Codex, and Make Your Agent Use Memory explains where they go and how to confirm the tools work first.

Tools

Tool

What it does

memory_write

Store a memory — insight, preference, lesson learned

memory_read

Search memories by natural language query (optional recency ordering, time bounds, author exclusion)

memory_list_recent

List newest memories first — no query; since/until bounds (inclusive) + cursor paging

memory_feedback

Rate a recalled memory as helpful or misleading, which re-ranks what comes back next

memory_stats

Check how many memories stored, which domains exist

memory_create_room

Create a shared memory room; its address works as a domain on write/read

memory_invite_to_room

Mint an invite (code + link) for a room you own; single-use unless max_uses allows more

memory_join_room

Join a shared room with an invite code (mnvr_...)

memory_list_rooms

List rooms you own or joined, with each room's address to use as domain

memory_graph

Read the association edges around given concepts — weight, outcome valence, co-activation count

vault_list

List Vault secrets by alias and purpose — the secret value is never returned

Prompts

Four named prompts for clients that show MCP prompts as commands (Claude Code as /mcp__mnemoverse__<name>). None of them calls the API itself: three ask the model to use the tools above, and setup_memory hands you rules for your own agent.

Prompt

Arguments

What it asks for

recall

topic

Search memory for a topic with memory_read and summarize only what comes back

save_insight

insight, optional domain

Store an insight with memory_write and confirm what was stored

what_do_you_know

subject

A briefing from memory_read that flags what is not stored

setup_memory

optional host: claude-code, claude-ai, cursor or codex

Memory rules for CLAUDE.md, AGENTS.md, Cursor rules or your chat preferences, and where they go, so your assistant checks and saves memory without being reminded

Resources

memory://item/{memory_id} opens one saved memory by its id (the id: line of a memory_read result) for clients that attach MCP resources. It returns the memory's memory_id, content and domain as JSON. It reads your own store only: a memory read from a shared room cannot be opened by id.

Tool surface stability

tools/list is frozen per released version, so a client can save the list it saw and diff it against what the server serves today, by version.

  • Within a PATCH (x.y.Z): tool names, argument schemas and the annotations object of every tool (title, readOnlyHint, destructiveHint, idempotentHint, openWorldHint) do not change. Only text may: descriptions and what a tool returns, as the CHANGELOG rules state.

  • Within a MINOR (x.Y.0): tools and annotation fields may be added, never removed or renamed, and no declared annotation field disappears or flips silently. Every addition has a line in the CHANGELOG under that version. A MINOR may also add an output schema (outputSchema, with structuredContent returned alongside the same text) to a tool that did not have one; once declared, that schema's fields are add-only under this same rule. Where this server's output schema deliberately differs from the hosted connector's, the CHANGELOG entry says so; today that is memory_id in every output schema, a plain string here and a GUID-validated string there (this package's ids are opaque); memory_list_recent's next_cursor, optional here (absent when the service sent a continuation token this client will not pass on) and required there; memory_stats, which carries five optional fields (episodes, prototypes, hebbian_edges, avg_valence, avg_importance) the connector's schema does not declare; the room tools (memory_create_room, memory_invite_to_room, memory_join_room, memory_list_rooms), where several fields the connector marks required are optional here (name, scope, already_member, and the invite's code, scope, room_address and expires_at), because a value core did not send is an honest outcome here rather than a placeholder; and memory_list_rooms and vault_list, which drop a row with no usable identity (room_id, address, role; alias, context) from the data, reported once on stderr, instead of emitting empty strings into required fields; and memory_read and memory_list_recent, which carry an optional rooms_not_searched field (the shared rooms an unscoped call did not search) that the connector's schemas do not declare yet.

  • Removing or renaming a tool or a tool's input parameter, or dropping or renaming a declared annotation field, is announced one MINOR ahead: the tool (or parameter) stays, its description says deprecated since x.y, removed in x.z, and the change lands only in the announced version, with its CHANGELOG line. A renamed parameter is accepted under both names until then (0.11 renamed memory_feedback's atom_ids to memory_ids; the old name was removed in 0.13, as announced after 0.12 shipped sooner than the first announcement assumed). A rename is announced by naming both the old and the new name; the version pair alone does not say what a client should look for. Because a MINOR may add a field but not remove one, a renamed annotation field is declared under both names until the announced version.

  • Any difference between two servers of the same version is a bug. Report it with both tools/list outputs. One exception, by configuration: a server built on the /shared entry point may ask for its own noun in the three descriptions that name the server (wording.serverNoun, below), which changes those three description strings and nothing else; tool names, input and output schemas and annotations never vary by configuration.

Every inputSchema and outputSchema is JSON Schema 2020-12, the dialect MCP assumes when a schema names none, and names none (#189).

The list above is the current surface: eleven tools, each declaring all four hints. The hosted connector at mcp.mnemoverse.com/mcp serves the same surface, registered from this package at the version it pins. The list itself is published as tools.json, generated from the built server (name, title, description and annotations per tool); the test suite and the release workflow fail when it does not list what the server registers, and the .mcpb manifest's tool list is derived from it.

If the hosted connector stops answering in a session. A client can keep showing the connector as connected while every call in that session fails with "not connected". Reconnecting it on claude.ai does not revive a session that is already stuck; reconnect from inside the session instead (in Claude Code, /mcp, then sign in again). Meanwhile this local server, set up with an API key from the same account as in the Quick Start, reaches the same memory and does not depend on that session's sign-in.

Building a second MCP server on this package

@mnemoverse/mcp-memory-server/shared is the entry point another server registers these same tools from, instead of keeping its own copy (ADR-025, mnemoverse-core). It exports registerMemoryTools/registerMemoryPrompts/registerMemoryResources, the three typed error classes (ApiError, NetworkError, UnreadableBodyError), MAX_RESULT_CHARS/capResult, and two optional dependencies a hosted deployment injects to speak in its own voice: wording (its own server noun and error vocabulary, including an OAuth mode under which no 401 or 403 explanation names an API key) and writeAuthor (vouching for the end user behind a write). See docs/shared.md for the full contract.

Use cases

The pattern that pays off first is cross-tool continuity: a decision made while pairing in Claude Code is there when you open Cursor an hour later, and the preference you stated in VS Code holds in a ChatGPT session that evening. Teams use shared rooms the same way — one place where an agent's lessons about a codebase accumulate instead of being re-taught per seat. And rating a recalled memory as helpful or misleading re-ranks what comes back next, which matters once a store grows past what anyone curates by hand.

Concrete things worth writing:

  • User preferences: "I use dark mode", "I prefer Tailwind over CSS modules"

  • Project context: "This project uses PostgreSQL + Prisma", "Deploy to Railway"

  • Lessons learned: "Always run tests before push on this repo"

  • Decisions made: "We chose REST over GraphQL because of caching simplicity"

  • People & roles: "Alice is the designer, Bob owns the API"

  • Past mistakes: "Don't deploy on Fridays — learned this the hard way"

Universal Memory

The same API key works across all tools. Write a memory in Claude Code — read it in Cursor. Learn something in VS Code — your GPT Custom Action knows it too.

                    ┌── Claude Code (this MCP server)
                    ├── Cursor (this MCP server)
   Mnemoverse API ──├── VS Code (this MCP server)
   (one memory)     ├── GPT (Custom Actions)
                    ├── Python SDK (pip install mnemoverse)
                    └── REST API (curl)

Configuration

Env Variable

Required

Default

MNEMOVERSE_API_KEY

For every tool call — the server starts and lists its tools without one

—

MNEMOVERSE_API_URL

No

https://core.mnemoverse.com/api/v1

Research behind it

The retrieval model is published: arXiv:2603.08965, accepted at the GRAAI workshop at IEEE WCCI 2026 — it establishes the abstraction-discovery method the memory model builds on. No benchmark figures appear in this README, ours or anyone's: numbers will come with a reproducible run to stand behind, not before.

Setup and reference

Background reading

Other ways to install it

The same memory, packaged for hosts that prefer a plugin or an extension over an MCP config block. How each one connects and authenticates differs, so the line below says which is which rather than claiming one flow for all of them.

  • Claude Code plugin — remote endpoint over MCP with an OAuth sign-in, no key to paste. Bundles the agent-memory-discipline skill

    claude plugin marketplace add mnemoverse/claude-plugin
    claude plugin install mnemoverse@mnemoverse
  • Cursor plugin — same remote endpoint, same sign-in

  • Gemini CLI extension — same remote endpoint. gemini extensions install https://github.com/mnemoverse/gemini-extension

  • VS Code extension (VS Code Marketplace, Open VSX, source) — signs in through the browser, with pasting a key kept as a fallback command

  • Desktop extension: manifest.json in this repository is an MCPB manifest. This one is different from the four above: it runs the server as a local node process and reads MNEMOVERSE_API_KEY from the extension settings rather than calling the hosted endpoint. The packaged .mcpb ships with each release

Standing rules, separate from this server

  • agent-memory-discipline — when an agent should recall before acting and save afterward. CC0, backend-neutral, works against any memory store rather than this one. It carries its own marketplace manifest under .claude-plugin/.

  • awesome-agent-memory — a curated index of the category, CC0, including the servers this one competes with

Project

Privacy Policy

This server sends to the Mnemoverse API (core.mnemoverse.com), authenticated with your API key, what a tool call carries — and nothing else it can see. It does not read your AI client's conversation history, your local files, or anything you don't pass to a memory_* / vault_* tool. Stored memories live under your account; Mnemoverse never sells them and never shares them on its own. The one sharing path is the one you create yourself: inviting someone to a shared room grants their assistant access to that room's memories, bounded by the invite's scope.

What each tool sends:

Tool

Data sent

memory_write

the content, concepts, and domain you pass

memory_read

the query, plus any filters: domain, since/until, exclude_author, top_k, order_by

memory_list_recent

the feed filters: domain, since/until, exclude_author, limit, cursor

memory_feedback

the memory_ids being rated (sent to the API as atom_ids), the outcome score, and the domain when you pass one (a shared room's address)

memory_create_room

the room name and description

memory_invite_to_room

the room_id, invite scope, and expiry

memory_join_room

the invite code

memory_graph

the seeds, plus any of depth, domain, min_weight, limit you pass

memory_stats / memory_list_rooms / vault_list

no request body — authenticated GETs

One thing goes out that you did not explicitly request: since 0.8.1, when a search or feed comes back empty, the server sends one or two authenticated read-only GET probes (/memory/rooms and/or /memory/stats) so the empty answer can say what it did not cover. Since 0.16.0 a search or feed without domain that does return results also sends one, to /memory/rooms, so the answer can name the shared rooms it did not search. The probes carry your API key and nothing else, change no stored state, and are disclosed in the CHANGELOG.

Privacy Policy

https://mnemoverse.com/docs/legal/privacy-policy

Retention & deletion

correct a wrong or stale memory by writing a fresh one; deletion is an administrative operation on the REST API, not exposed through this MCP server

Contact

hello@mnemoverse.com

License

MIT © Mnemoverse

Available Tools

11 tools
memory_create_roomAInspect

Create a SHARED memory room — a space OTHER people's assistants can read, and write too when their invite granted read_write (the default scope), across Claude/ChatGPT/Cursor. Use when the user wants to share context or collaborate with someone else (e.g. 'make a room for me and my teammate'). Returns the room's address; pass that address as the domain on memory_write/memory_read to use it, and on memory_list_recent to catch up on what others added. People join through an invite minted with memory_invite_to_room.

NameRequiredDescriptionDefault
nameYesRoom name, unique within your account (e.g. 'launch-team').
descriptionNoOptional description of the room.

Output Schema

NameRequiredDescription
nameNoThe room name as stored.
addressYesDomain address (xroom:<id>); pass as `domain` on read/write.
room_idYesThe room's id (room_...); pass to memory_invite_to_room.

TDQS

A4.4/5.0
Behavior4/5

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

Annotations cover the safety profile (readOnly=false, destructive=false, idempotent=false), so the description only needs to add context — and it does: it discloses the shared/cross-platform nature, the default read_write invite scope, and what is returned. It stops short of stating error behavior (e.g. duplicate-name rejection) or any permission/rate constraints, but the added context is substantial.

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?

Three sentences, front-loaded with the core action and the usage trigger before the downstream instructions. The parentheticals (default scope, platform list, example phrase) are informative but make the middle slightly dense; nothing is redundant enough to remove outright.

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?

Although an output schema exists, the description still names the key return value (the room's address) and explains how to feed it into memory_write/memory_read/memory_list_recent, which is the critical integration knowledge an agent needs. Nothing required to invoke and then use the result is missing.

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 description coverage is 100%, so both parameters are already documented in the schema. The description's mention of `domain` refers to other tools' parameters, not this tool's inputs, so it adds no meaning to `name` or `description` beyond the schema. Baseline 3 applies.

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 ('Create a SHARED memory room') and immediately qualifies the resource as a cross-assistant shared space, which cleanly separates it from siblings like memory_join_room and memory_list_rooms. An agent can identify the operation without opening the 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 trigger ('Use when the user wants to share context or collaborate with someone else') with a concrete example utterance, and routes the complementary action to the named sibling memory_invite_to_room. The condition that selects this tool over its alternatives is stated rather than implied.

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

memory_feedbackAInspect

Rate memories returned by memory_read to help improve future retrieval ranking. Pass their IDs as memory_ids and an outcome from -1 (unhelpful) to 1 (helpful). Records feedback and updates ranking signals: positive feedback raises a memory's ranking; negative feedback lowers it so other memories out-rank it — nothing is erased. Saved text is not changed or deleted. For memories read from a shared room, pass that room's address as domain; your own memories need no domain. A read-only room member cannot rate the room's memories.

NameRequiredDescriptionDefault
domainNoOnly for memories read from a shared room: that room's address (xroom:...), exactly as you read it. Omit it for your own memories, which are rated by id alone.
outcomeYesHow helpful was this? 1.0 = very helpful, 0 = neutral, -1.0 = harmful/wrong
memory_idsYesIDs of the memories to rate, the `id:` line of each memory_read result.

Output Schema

NameRequiredDescription
avg_valenceNoAverage valence of the rated memories after the update. Reported as 0 in an asynchronous acknowledgement, where the real value is computed later — a 0 here is therefore not evidence of a neutral outcome.
updated_countYesHow many memories the service reports it applied the rating to. Processed synchronously this is the real count of memories that existed and were updated; processed asynchronously it is a best-effort ACCEPTED-count estimate — the number of IDs submitted — and the authoritative number is not known until the background worker runs. Zero means no submitted ID matched in the service's resolved request scope.
coactivation_edgesNoNumber of links between query concepts and result concepts that this rating changed. This server does not send query_concepts, so live calls through this tool report 0; asynchronous acknowledgements also report 0.

TDQS

A4.2/5.0
Behavior3/5

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

Adds real context beyond annotations: positive feedback raises ranking, negative lowers it so others out-rank it, and nothing is erased or edited. However, it never mentions that repeated calls accumulate rather than being idempotent (idempotentHint=false), nor does it address whether feedback can be revised or overwritten.

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 purpose and effect, then permissions. Slightly padded at the end: 'nothing is erased' and 'Saved text is not changed or deleted' are two near-identical reassurances that could collapse into one clause.

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?

For a 3-param mutation tool with full schema coverage and an output schema (so return values need no explanation), the description covers purpose, side effects, reversibility, domain requirement, and the permission gate. Nothing needed to call it correctly is missing.

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 100%, so the baseline is 3. The description restates the -1..1 outcome scale and the domain-for-shared-rooms rule, but both points are already spelled out in the property descriptions; it adds no format or edge-case detail the schema lacks.

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?

Opens with a specific verb+resource ('Rate memories returned by memory_read') and states the goal (improve future retrieval ranking). It is clearly distinguished from siblings like memory_write and memory_read, which store and fetch rather than score.

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 ties invocation to memories obtained from memory_read, states the domain-only condition for shared-room memories versus own memories, and names a hard exclusion: a read-only room member cannot rate the room's memories. That is when-to-use, when-not, and the gating prerequisite in one place.

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

memory_graphA
Read-onlyIdempotent
Inspect

Reads the association edges around given concepts: which concepts the memory has linked together, with each link's weight, outcome valence and co-activation count. Use to inspect what a memory store has learned or to explain why a read expanded to a concept. Reads your own graph, or a shared room's when its address is passed as domain; any other domain value has no effect. At depth 2 or 3 the engine drops edges below weight 0.05 unless min_weight is set. Read-only.

NameRequiredDescriptionDefault
depthNoHops to expand from the seeds (1-3, default 1). At depth 2 or 3, if min_weight is omitted the engine floors edge weight at 0.05 at EVERY hop — including the first — so a hub concept cannot fan out across the whole store before limit applies; pass min_weight explicitly (0 included) to see every edge anyway.
limitNoMax edges to return (1-500, default 100 — mirrors memory_read's top_k bounds).
seedsYesConcepts to center the graph on (1-20, each ≤200 chars, non-blank) — e.g. ['deploy', 'staging']. An unrecognised concept simply contributes no edges; it is not an error.
domainNoRead a shared room's graph instead of your own: pass that room's address (e.g. 'xroom:room_01ABC'). Find room addresses with memory_list_rooms. Unlike memory_read, any OTHER value has no effect here — the association store has no domain column, so a plain domain name behaves exactly like omitting this field.
min_weightNoOnly include edges at or above this weight (≥ 0). Omit for no floor at depth 1; at depth 2/3 the engine applies its own 0.05 floor when this is omitted (see depth) — pass 0 to see every edge at every depth.

Output Schema

NameRequiredDescription
edgesYesAssociation edges found within the requested depth.
nodesYesConcepts touched by edges below. A seed with no surviving edge (unrecognised concept, or every edge fell below the weight floor) is not listed.
truncatedYesTrue when a per-hop server cap or limit cut the walk short — the store may hold more edges than are reported here.
min_weight_appliedYesThe weight floor actually used at every hop: your min_weight when you set one (0 included); otherwise 0.05 from depth 2, or 0 at depth 1.

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already cover the safety profile (readOnlyHint, idempotentHint, destructiveHint=false), but the description adds non-obvious behavior: the 0.05 weight floor auto-applied at depth 2/3 unless min_weight is passed, that a non-address domain value is silently a no-op, and that an unrecognised seed is not an error. These are genuine surprises an agent would otherwise hit, though the trailing 'Read-only' merely restates the annotation.

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 tool returns, then usage, then the domain caveat, then the depth/min_weight caveat — a sensible ordering with no filler sentences. The final 'Read-only.' is redundant against the annotations, the only wasted token.

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-shape explanation is unnecessary, and the annotations carry the safety profile. What remains — when to use it, the domain constraint, and the min_weight floor interaction — is fully covered, leaving nothing an agent needs to call it 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 100%, so the baseline is 3, but the description adds cross-parameter semantics the schema states only locally: how depth and min_weight interact (0.05 floor at every hop including the first) and that domain must be a room address, unlike memory_read. It does not add anything for seeds or limit, which the schema already documents fully.

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 ('Reads the association edges around given concepts') and enumerates what each edge carries (weight, outcome valence, co-activation count). This clearly separates it from sibling memory_read, which retrieves memories rather than the link structure between them.

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 two concrete use cases: inspecting what a store has learned, and explaining why a read expanded to a concept — the latter implicitly points at memory_read as the upstream operation. It also scopes the domain parameter ('reads your own graph, or a shared room's when its address is passed'). No explicit when-not or named alternative tool, so it falls 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.

memory_invite_to_roomAInspect

Mint an invite for a room you own and get a ready-to-forward message. An invite is single-use by default; pass max_uses to let several people join with the same one. The user sends that message to the person they want to add (any messenger); the recipient opens the link or tells THEIR assistant the code to join. Use when the user asks to invite someone to a room they own, including one just created with memory_create_room.

NameRequiredDescriptionDefault
scopeNoRole the invitee gets — 'read' or 'read_write' (default read_write).
room_idYesThe room's id (room_...), from memory_create_room.
max_usesNoHow many people may join with this invite (default 1, single-use).
expires_in_daysNoDays until the invite expires (default 7).

Output Schema

NameRequiredDescription
codeNoThe invite code (mnvr_...). Single-use by default, with a configurable use limit. Shown once.
scopeNoRole the invitee will get.
join_urlNoLanding URL the invitee can open to join.
expires_atNoISO 8601 expiry, or null.
room_addressNoThe room's domain address (xroom:<id>).
share_messageYesReady-to-forward invite text.

TDQS

A4.5/5.0
Behavior5/5

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

Annotations only cover the safety flags (non-readonly, non-idempotent, non-destructive). The description adds substantial behavior beyond them: single-use default, max_uses for multi-recipient, the message flow (user forwards, recipient opens link or tells THEIR assistant the code). That workflow context is exactly what annotations cannot convey.

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 sentences, front-loaded with the action and artifact. Each sentence carries distinct information (what it mints, the single-use default, the forwarding flow, the trigger) with no filler.

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 values need no explanation. The description supplies the trigger, defaults, and end-to-end workflow an agent needs; nothing material is missing for correct 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 description coverage is 100%, so all four parameters are already documented with defaults and ranges. The description only reinforces max_uses' single-use default, adding no syntax or format detail beyond the schema. Baseline 3 is appropriate.

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+resource ('Mint an invite for a room') and immediately describes the concrete artifact produced (a ready-to-forward message). It is clearly distinguishable from siblings like memory_join_room or memory_create_room.

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?

Explicitly says when to use it: 'when the user asks to invite someone to a room they own, including one just created with memory_create_room,' naming a sibling. It lacks an explicit when-not or an alternative for the recipient side, but the trigger context is unambiguous.

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

memory_join_roomA
Idempotent
Inspect

Join a shared memory room using an invite code (starts with 'mnvr_'). Use when the user pastes an invite code or says something like 'join room with code ...'. The result gives the room's address, which is the domain for reading the shared room with memory_read, and tells you what you may do with it: memory_write to that address is only allowed when your membership scope is read_write; a read-only membership has that write refused; and when the server does not report a scope, whether memory_write would succeed is stated as unknown rather than promised either way.

NameRequiredDescriptionDefault
codeYesThe invite code (mnvr_...).

Output Schema

NameRequiredDescription
nameNoThe room name.
scopeNoYour role in the room ('read' | 'read_write').
addressYesDomain address (xroom:<id>); pass as `domain` on read/write.
room_idYesThe room's id (room_...).
next_stepsYesHow to use the room now.
already_memberNoTrue if you were already a member (no-op join).

TDQS

A4.4/5.0
Behavior4/5

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

With annotations declaring readOnlyHint=false, idempotentHint=true, destructiveHint=false and openWorldHint=false, the description still adds real content: the join returns a room address usable as `domain`, and write permission depends on membership scope, with read-only writes refused and unknown scopes reported as unknown rather than promised. This is unusually candid about permission outcomes, though it stops short of describing what happens on an invalid or expired code.

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?

Purpose and trigger are front-loaded in the first two sentences, and every sentence carries information about downstream use. The closing scope sentence is dense and slightly convoluted, but it is not padding.

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 structure need not be re-explained, yet the description covers the one fact an agent needs to chain correctly (the address is the `domain` for reads) plus the write-permission conditionality. Complete for a single-parameter join 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?

Only one parameter exists and schema coverage is 100%, so the schema already documents `code` and its 'mnvr_...' form. The description repeats the prefix convention without adding syntax, error behavior, or length/format nuance beyond the schema. Baseline 3 applies.

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 (join) and resource (shared memory room) plus the required input format 'mnvr_'. It is immediately distinguishable from siblings like memory_create_room and memory_invite_to_room, which are the adjacent operations in the same lifecycle.

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 trigger ('use when the user pastes an invite code or says something like "join room with code ..."') and routes onward: the returned address is the `domain` for memory_read, and memory_write is conditional on scope. Alternatives and conditions are named rather than inferred.

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

memory_list_recentA
Read-onlyIdempotent
Inspect

List the NEWEST memories first — no search query needed. Semantic search answers 'what do I know about X'; this answers 'what happened lately': resuming work after a break, catching up on a shared room ('any new messages?'), or reviewing what was saved recently. Pass since (your last-seen time) to get only what's new, and page through older entries with the returned cursor. Complete by construction WITHIN ONE SCOPE — nothing is skipped there, unlike a semantic search. A page is also bounded by SIZE, so a page of long entries comes back shorter than limit and hands you a cursor for the rest — nothing is dropped, and following the cursor is how you get it. To catch up on a shared room you MUST pass its address as domain: rooms are separate stores and an unscoped call never covers them, though it names the ones you have (rooms_not_searched).

NameRequiredDescriptionDefault
limitNoMost entries per page (default: 20). Newest first. ⚠️ A CEILING, not a promise: the page is ALSO bounded by size, so a page of long entries stops early and returns a cursor for the rest. In rooms whose entries run long, ask for 5–10 — a large `limit` there buys nothing the size budget will not take back, and costs round trips.
sinceNoOnly entries created at/after this ISO-8601 instant (naive = UTC) — your novelty watermark.
untilNoOnly entries created at/before this ISO-8601 instant (inclusive). Pair with `since` to read a closed window — 'what happened on Monday' — instead of paging back from now.
cursorNoOpaque cursor from a previous page's 'More older entries exist' line — continues the listing without skips or duplicates.
domainNoRestrict to one domain. REQUIRED to read a shared room — pass its address ('xroom:room_01ABC'), because rooms are separate stores that an unscoped feed does NOT cover. Omit only when you mean your own domains. Room addresses come from memory_list_rooms. Room entries are often long — a room feed usually reaches its size budget after a handful of them, so expect to page (see `limit`).
exclude_authorNoDrop entries written by this author PRINCIPAL. ⚠️ NOT USABLE FROM HERE YET — the principal is never shown in these results, so there is no value you can get through this tool; a guess like 'me' filters nothing, silently. Same caveat as on memory_read.

Output Schema

NameRequiredDescription
itemsYesEntries newest-first (creation time descending).
next_cursorNoPass back as cursor for the next (older) page; null = listing complete. Absent when the service sent a continuation token this client will not pass on; the text then says the token could not be displayed.
rooms_not_searchedNoPresent only on a call WITHOUT `domain`, when you have shared rooms or they could not be checked: rooms are separate stores that call did not search.

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already cover the safety profile (readOnly, idempotent, non-destructive), and the description adds real behavioral context beyond them: completeness-within-a-scope, the size budget that can truncate a page below `limit`, the guarantee of no skips/duplicates across pages, and the `rooms_not_searched` signal on unscoped calls. It also discloses a limitation not visible elsewhere ('nothing is skipped there, unlike a semantic search').

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 opening sentence is well front-loaded and the paragraph advances from purpose to paging to scope. However, the size-budget/cursor mechanic is explained twice (once in prose, again in the `limit` description) and the paragraph is dense enough to be mildly repetitive.

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?

With 6 optional parameters and an output schema present, the description supplies exactly what the schema cannot: which scope the call covers, why a page may be short, how to continue, and where the room-address list comes from. An agent has everything needed to call it correctly on the first try.

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 coverage is 100%, so the baseline is 3, but the description adds synthesis the schema cannot: `since` as a novelty watermark, `domain` as mandatory for room access, and the interaction between `limit` and the size budget that makes large limits wasteful in rooms. It largely restates the schema's per-parameter caveats rather than adding new semantics, which keeps it below a 5.

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 leads with a specific verb and ordering ('List the NEWEST memories first') and immediately contrasts itself with the sibling capability of semantic search ('what happened lately' vs 'what do I know about X'). An agent can pick between this and memory_read without opening either 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?

It names concrete use cases (resuming after a break, catching up on a room, reviewing recent saves), states when to pass `since` versus paging with the cursor, and gives an explicit MUST for the alternative store ('to catch up on a shared room you MUST pass its address as `domain`'). When-not guidance is present: unscoped calls never cover rooms.

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

memory_list_roomsA
Read-onlyIdempotent
Inspect

List the shared memory rooms you can use — the ones you OWN plus the ones you've JOINED — each with the address to pass as domain on memory_read, and on memory_write too where your membership scope is read_write; a read-only membership has that write refused. Use this to RE-FIND a room in a new session (e.g. 'what rooms do I have?', 'resume the room with my teammate') instead of having to create or re-join it.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
roomsYes

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already supply readOnly/idempotent/non-destructive, so the bar is lower, yet the description adds real behavioral context: the returned address is the value to pass as `domain` on memory_read and memory_write, and write is refused for read-only memberships. That permission nuance is not derivable from the schema or annotations.

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 and dense with useful content, but the middle clause nesting the `domain` usage for two other tools inside a dash-heavy sentence makes it harder to parse than a two-sentence split would be. Still, essentially every clause earns its place.

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?

With an output schema present, return values need no explanation, and rich annotations cover the safety profile. The description fills the remaining gaps: usage scenario, cross-tool handoff via `domain`, and membership-based write refusal. Nothing needed to call it correctly is missing.

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?

The tool takes zero parameters (schema coverage 100% trivially), so the baseline is 4. The description's mention of `domain` belongs to sibling tools, not this one, so there is no additional parameter meaning to add here.

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?

Specific verb + resource ('List the shared memory rooms') with scope made explicit: rooms you OWN plus rooms you've JOINED. It is unambiguously distinguishable from siblings memory_create_room and memory_join_room, which the description implicitly contrasts against.

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?

States the triggering scenario ('RE-FIND a room in a new session') with concrete user phrasings, and explicitly says to use this instead of creating or re-joining. Both the when and the not-this alternatives are named.

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

memory_readA
Read-onlyIdempotent
Inspect

Search long-term memory for user preferences, past decisions, project setup, people, or earlier context. The memory persists across sessions and across every AI tool the user has connected (Claude, ChatGPT, Cursor, VS Code). It applies when an answer may depend on something from an earlier session or another tool; it is not needed for general world knowledge. Returns matches ranked by relevance (or newest-first with order_by: 'recency'); each result carries an id; after the answer, memory_feedback takes these ids to record which memories helped. A wrong or stale memory is corrected by writing a fresh one with memory_write, not by deleting it.

NameRequiredDescriptionDefault
queryYesNatural-language description of what you're looking for, e.g. 'database choice for the API' or 'user's preferred testing framework'.
sinceNoOnly memories created at/after this ISO-8601 instant (naive = UTC) — e.g. your last-seen watermark in a shared room.
top_kNoRequested number of results (default: 5, what this server asks for when you omit it; the engine's own default of 10 never applies, because the field is always sent). ⚠️ Not a hard cap: association expansion can return MORE than this, and the relevance floor can return fewer — raising it does not reliably widen the result set. For a complete, exactly-bounded listing use memory_list_recent instead.
untilNoOnly memories created at/before this ISO-8601 instant.
domainNoRestrict the search to one domain namespace (e.g. 'project:acme'). Omitting it searches your OWN domains — it does NOT include shared rooms, which are separate stores: to search a room, pass its address here (e.g. 'xroom:room_01ABC'). Find room addresses with memory_list_rooms, or in `rooms_not_searched`, which an answer without `domain` carries when you have rooms.
order_byNo'relevance' (default) = ranking order. 'recency' = the matched set re-sorted newest-first. For a complete newest-first feed with no search at all, use memory_list_recent instead.
diversityNo0 (default) returns the matches as ranked. Above 0, a match that is a near-copy of one already picked gives its slot to the next distinct memory (maximal marginal relevance); 1 lets similarity alone decide after the first pick. It changes which memories come back, not their scores, and applies only when there are more matches than top_k and top_k is below 200.
exclude_authorNoDrop memories written by this author PRINCIPAL — the server-side identity. ⚠️ NOT USABLE FROM HERE YET: the principal is not shown in these results, so there is no value you can obtain through this tool, and a guess like 'me' silently matches nothing and filters nothing. Only pass it if your system knows the exact principal from elsewhere (e.g. the REST API).

Output Schema

NameRequiredDescription
itemsYesMatching memories, ordered per order_by.
rooms_not_searchedNoPresent only on a call WITHOUT `domain`, when you have shared rooms or they could not be checked: rooms are separate stores that call did not search.

TDQS

A4.5/5.0
Behavior5/5

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

Beyond readOnly/idempotent/non-destructive annotations, it discloses that memory persists across sessions and across other AI tools, that results are ranked with an alternative newest-first ordering, that each result carries an id consumed by memory_feedback, and that stale entries are superseded by writing rather than deleting. That is genuine behavioral context an agent cannot get from the annotations.

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 purpose and trigger, then workflow semantics; every sentence carries information. It is on the long side for a search tool, and the cross-tool enumeration (Claude, ChatGPT, Cursor, VS Code) is decorative rather than decision-relevant.

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?

Output schema exists, so return-shape explanation is unnecessary and the description correctly spends its words on when to call, the feedback loop, and correction semantics. The one behavior it omits is that a query without `domain` silently excludes shared rooms, which is a real usage trap, though the schema does cover it.

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 100% and the schema already documents query, domain, top_k caveats, since/until, diversity and exclude_author, so the baseline applies. The description only restates that order_by: 'recency' produces newest-first ordering, which the schema says too; it adds no parameter meaning the schema lacks.

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 (search) and resource (long-term memory) plus the content classes it covers (preferences, decisions, project setup, people, earlier context). It explicitly distinguishes itself from siblings, naming memory_list_recent for exhaustive listing and memory_write/memory_feedback for the other memory operations.

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 trigger ('applies when an answer may depend on something from an earlier session or another tool') and an explicit exclusion ('not needed for general world knowledge'). It also routes to alternatives for adjacent jobs: memory_feedback to record usefulness, memory_write to correct a stale memory, memory_list_recent for a complete bound.

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

memory_statsA
Read-onlyIdempotent
Inspect

Get an overview of the stored memory: total count, the number of learned concept associations, the list of domains, and average quality scores. This memory is shared across all AI tools the user has connected to Mnemoverse. Use it to orient yourself, to confirm the exact domain name before writing to it, or when the user asks what you remember. Read-only — changes nothing.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
domainsYesUser-defined memory domains.
episodesNoNumber of individual memories (not merged into a summary).
prototypesNoNumber of summary memories merged from several individual ones. Consolidation is not running on the hosted service, so this count does not currently grow.
avg_valenceNoAverage valence of stored memories: how well recalls turned out, on a scale from -1 to 1.
memory_countYesNumber of saved memories.
hebbian_edgesNoNumber of learned concept-to-concept associations; memory_graph reads them.
avg_importanceNoAverage importance of stored memories, on a scale from 0 to 1.

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already declare readOnlyHint/idempotentHint/destructiveHint, so the "Read-only — changes nothing" clause is redundant. The genuinely additive fact is that the memory is shared across all AI tools connected to Mnemoverse, which is scope information not available in the structured fields.

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?

Three sentences, front-loaded with the returned data, then sharing scope, then usage triggers — a sensible order with no filler. The final "Read-only — changes nothing" clause is redundant against the annotations and could be dropped.

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?

Zero parameters, an output schema (so returns need not be explained), and annotations covering the safety profile mean the description only needs context — which it supplies via the cross-tool sharing scope and usage triggers. Nothing an agent needs to call it correctly is missing.

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?

The tool takes zero parameters, so the schema-baseline of 4 applies and there is nothing for the description to compensate for. No parameter semantics are needed or missing.

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?

Specific verb ("Get an overview") plus resource (stored memory), with the exact contents enumerated: total count, learned concept associations, domain list, average quality scores. This makes the aggregate nature clear against siblings like memory_read and memory_list_recent. However, no sibling is named or explicitly contrasted, so it stops short of full differentiation.

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 three concrete when-to-use triggers: orienting yourself, confirming the exact domain name before writing, and answering "what do you remember." These are actionable contexts. No when-not condition or named alternative (e.g., memory_list_recent for recency) is provided, so it isn't a full 5.

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

memory_writeAInspect

Store a long-term memory that persists across sessions and across every AI tool the user has connected to Mnemoverse (Claude, ChatGPT, Cursor, VS Code). Suited to durable information: a stated preference, a decision, a fact about people, roles or project setup, a lesson learned; transient chatter that only matters this turn does not belong here. Never store passwords, API keys, payment data, MFA codes, government IDs, or health records. Behavior: outside shared rooms, a novelty gate refuses a write the embedder cannot tell apart from a memory already stored in the same domain, so the result tells you whether the memory was stored or refused. Write content as a self-contained statement that still makes sense when recalled out of context.

NameRequiredDescriptionDefault
domainNoNamespace to organize memories (e.g. 'engineering', 'user:alice', 'project:acme'). Matched byte-for-byte — a leading space, a different case, or an invisible character opens a SEPARATE, permanent store, so reuse an exact name from memory_stats rather than retyping one. To write into a shared room, pass its address here instead (e.g. 'xroom:room_01ABC'). Find room addresses with memory_list_rooms.
contentYesThe memory to store as a self-contained statement, e.g. 'User prefers TypeScript strict mode' or 'Decided to deploy the API on Cloudflare Workers (2026-06)'.
conceptsNoKey concepts for linking related memories (e.g. ['deploy', 'friday', 'staging'])

Output Schema

NameRequiredDescription
reasonNoThe memory service's own explanation of this outcome, quoted as sent — when stored is false this is the ONLY statement of WHY, e.g. "Below importance threshold (0.047 < 0.1)". Ordinary text is preserved exactly; only control, bidi, zero-width, and repeated-whitespace characters are normalized before display, and the value is capped at 400 characters. Absent when the service sent no explanation, or when nothing remains after that normalization.
storedYesWhether the memory passed the novelty gate and was stored.
memory_idYesIdentifier of the stored memory, or null when it was not stored.
importanceNoNovelty score for this write (0-1): how much it adds over the nearest memories already saved in the same domain. Outside shared rooms, a write that scores below the service's importance threshold is not stored, and `reason` says why when the service sends one. The score is approximate and can read lower for non-English text. It is not a verdict on whether the memory was worth keeping. Absent when the service sent no score.

TDQS

A4.6/5.0
Behavior5/5

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

Goes well beyond the annotations by disclosing the novelty gate that can refuse near-duplicate writes outside shared rooms, noting that the result reports stored vs refused, specifying that domain matching is byte-exact so a stray space opens a separate permanent store, and listing forbidden content classes. This is exactly the kind of behavior an agent cannot infer from destructiveHint=false or idempotentHint=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?

Front-loads purpose and durability scope, then usage criteria, then constraints, then behavior. Dense but each sentence earns its place, with only mild overlap between the closing sentence and the schema's own description of the content field.

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?

For a three-parameter write tool with an output schema and annotations, the description covers the remaining gaps an agent needs: durability semantics, privacy boundaries, refusal behavior, and content authoring rules. Return structure is correctly left to the output schema while its outcome meaning is still summarized.

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 coverage is 100%, so the baseline is 3, and the description adds real meaning on top: content must be a self-contained statement that still makes sense when recalled out of context, which the schema only demonstrates by example. Domain semantics are mostly delegated to the schema, so it lands at 4 rather than 5.

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 (store) and resource (long-term memory) plus scope: persists across sessions and across every connected AI tool. This clearly separates it from siblings like memory_read, memory_list_recent, and memory_create_room, which read or set up rather than persist content.

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 explicit inclusion criteria (stated preference, decision, fact, lesson learned) and exclusion criteria (transient chatter that only matters this turn does not belong here), plus a hard prohibition list. It stops short of naming sibling tools an agent should use instead for retrieval or routing, so it is strong but not a full 5.

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

vault_listA
Read-onlyIdempotent
Inspect

List the secrets stored in your Mnemoverse Vault — by ALIAS and purpose only; the secret VALUE is never returned or shown to you, and no tool on this server returns it. Use this to check WHICH secrets the user has stored and under what alias (e.g. the user says 'do I have a GitHub token saved?'). Only YOUR account's secrets are listed.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
secretsYes

TDQS

A4.6/5.0
Behavior5/5

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

Annotations already declare readOnly/idempotent/non-destructive safely, but the description adds non-obvious behavior: values are never returned or displayed, no tool on the server can retrieve them, and only the calling account's secrets are listed. That is meaningful disclosure beyond the structured hints.

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 the core action and result shape, and the example is compact and useful. The value-is-never-returned point is restated twice ('never returned or shown to you' and 'no tool on this server returns it'), a mild redundancy that costs a point.

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 formatting needs no explanation, and the description still covers the one thing an agent most needs to know: what is and isn't in the response. No gaps for a zero-parameter list operation.

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?

The tool takes zero parameters, so there is nothing for the description to disambiguate and the baseline of 4 applies. The description appropriately avoids inventing parameter guidance that doesn't exist.

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 (list secrets in the Mnemoverse Vault) plus the exact scope of the result (alias and purpose only). It also distinguishes itself from every sibling by asserting that no tool on this server returns the value, so memory_read can't be confused with it.

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 when-to-use rule ('Use this to check WHICH secrets the user has stored and under what alias') and a concrete trigger example ('do I have a GitHub token saved?'). It does not name an explicit alternative tool or a when-not condition, but the value-retrieval case is already ruled out.

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. 2 tool updatesv0.16.0
    • Changedmemory_list_recent1 field changed
      • addedOutput schema / properties / rooms_not_searched
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Present only on a call WITHOUT `domain`, when you have shared rooms or they could not be checked: rooms are separate stores that call did not search.",
        +  "properties": {
        +    "note": {
        +      "description": "The same disclosure the text ends with.",
        +      "type": "string"
        +    },
        +    "rooms": {
        +      "description": "The live rooms this call did not search; present only when state is 'live'. A row missing room_id, address or role is omitted here and still named in `note`.",
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "address": {
        +            "description": "Domain address (xroom:<id>); pass as `domain` on read/write.",
        +            "type": "string"
        +          },
        +          "archived": {
        +            "description": "True if archived (owned rooms only).",
        +            "type": "boolean"
        +          },
        +          "name": {
        +            "description": "The room name.",
        +            "type": "string"
        +          },
        +          "role": {
        +            "description": "'owner' or 'member'.",
        +            "type": "string"
        +          },
        +          "room_id": {
        +            "description": "The room's id (room_...).",
        +            "type": "string"
        +          },
        +          "scope": {
        +            "description": "'read' or 'read_write'.",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "room_id",
        +          "address",
        +          "role",
        +          "archived"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "state": {
        +      "description": "'live': the rooms listed can be read by passing an address as `domain`. 'archived-only': every room you have is archived and refuses reads. 'unknown': the room list could not be checked, so whether any room went unsearched is not known.",
        +      "enum": [
        +        "live",
        +        "archived-only",
        +        "unknown"
        +      ],
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "state",
        +    "note"
        +  ],
        +  "type": "object"
        +}
    • Changedmemory_read2 fields changed
      • changedInput schema / properties / domain / description
        Previous value: -"Restrict the search to one domain namespace (e.g. 'project:acme'). Omitting it searches your OWN domains — it does NOT include shared rooms, which are separate stores: to search a room, pass its address here (e.g. 'xroom:room_01ABC'). Find room addresses with memory_list_rooms."New value: +"Restrict the search to one domain namespace (e.g. 'project:acme'). Omitting it searches your OWN domains — it does NOT include shared rooms, which are separate stores: to search a room, pass its address here (e.g. 'xroom:room_01ABC'). Find room addresses with memory_list_rooms, or in `rooms_not_searched`, which an answer without `domain` carries when you have rooms."
      • addedOutput schema / properties / rooms_not_searched
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Present only on a call WITHOUT `domain`, when you have shared rooms or they could not be checked: rooms are separate stores that call did not search.",
        +  "properties": {
        +    "note": {
        +      "description": "The same disclosure the text ends with.",
        +      "type": "string"
        +    },
        +    "rooms": {
        +      "description": "The live rooms this call did not search; present only when state is 'live'. A row missing room_id, address or role is omitted here and still named in `note`.",
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "address": {
        +            "description": "Domain address (xroom:<id>); pass as `domain` on read/write.",
        +            "type": "string"
        +          },
        +          "archived": {
        +            "description": "True if archived (owned rooms only).",
        +            "type": "boolean"
        +          },
        +          "name": {
        +            "description": "The room name.",
        +            "type": "string"
        +          },
        +          "role": {
        +            "description": "'owner' or 'member'.",
        +            "type": "string"
        +          },
        +          "room_id": {
        +            "description": "The room's id (room_...).",
        +            "type": "string"
        +          },
        +          "scope": {
        +            "description": "'read' or 'read_write'.",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "room_id",
        +          "address",
        +          "role",
        +          "archived"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "state": {
        +      "description": "'live': the rooms listed can be read by passing an address as `domain`. 'archived-only': every room you have is archived and refuses reads. 'unknown': the room list could not be checked, so whether any room went unsearched is not known.",
        +      "enum": [
        +        "live",
        +        "archived-only",
        +        "unknown"
        +      ],
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "state",
        +    "note"
        +  ],
        +  "type": "object"
        +}
  2. 11 tool updatesv0.15.3
    • Changedmemory_create_room2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedOutput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
    • Changedmemory_feedback2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedOutput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
    • Changedmemory_graph2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedOutput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
    • Changedmemory_invite_to_room2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedOutput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
    • Changedmemory_join_room2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedOutput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
    • Changedmemory_list_recent2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedOutput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
    • Changedmemory_list_rooms2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedOutput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
    • Changedmemory_read2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedOutput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
    • Changedmemory_stats2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedOutput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
    • Changedmemory_write2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedOutput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
    • Changedvault_list2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedOutput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
  3. 1 tool updatev0.15.0
    • Changedmemory_read1 field changed
      • addedInput schema / properties / diversity
        Added value: +{
        +  "description": "0 (default) returns the matches as ranked. Above 0, a match that is a near-copy of one already picked gives its slot to the next distinct memory (maximal marginal relevance); 1 lets similarity alone decide after the first pick. It changes which memories come back, not their scores, and applies only when there are more matches than top_k and top_k is below 200.",
        +  "maximum": 1,
        +  "minimum": 0,
        +  "type": "number"
        +}
  4. 5 tool updatesv0.14.2
    • Changedmemory_create_room1 field changed
      • changedInput schema / properties / name / description
        Previous value: -"Room name, unique within your account (e.g. 'me-and-olya')."New value: +"Room name, unique within your account (e.g. 'launch-team')."
    • Changedmemory_feedback1 field changed
      • changedOutput schema / properties / coactivation_edges / description
        Previous value: -"Number of feedback-driven query/result concept co-activation edges changed by the service. This is separate from ordinary Hebbian strengthening among a memory's own concepts. This server does not send query_concepts, so live calls through this tool report 0; asynchronous acknowledgements also report 0."New value: +"Number of links between query concepts and result concepts that this rating changed. This server does not send query_concepts, so live calls through this tool report 0; asynchronous acknowledgements also report 0."
    • Changedmemory_read1 field changed
      • changedInput schema / properties / exclude_author / description
        Previous value: -"Drop memories written by this author PRINCIPAL — the server-side identity. ⚠️ NOT USABLE FROM HERE YET: the principal is not shown in these results, so there is no value you can obtain through this tool, and a guess like 'me' silently matches nothing and filters nothing. Only pass it if your system knows the exact principal from elsewhere (e.g. the REST API). A self-exclusion shortcut is planned."New value: +"Drop memories written by this author PRINCIPAL — the server-side identity. ⚠️ NOT USABLE FROM HERE YET: the principal is not shown in these results, so there is no value you can obtain through this tool, and a guess like 'me' silently matches nothing and filters nothing. Only pass it if your system knows the exact principal from elsewhere (e.g. the REST API)."
    • Changedmemory_stats3 fields changed
      • changedOutput schema / properties / episodes / description
        Previous value: -"Number of episodic (not yet consolidated) memories."New value: +"Number of individual memories (not merged into a summary)."
      • changedOutput schema / properties / hebbian_edges / description
        Previous value: -"Number of Hebbian concept-to-concept links, learned from concepts that occur together as memories are stored and used."New value: +"Number of learned concept-to-concept associations; memory_graph reads them."
      • changedOutput schema / properties / prototypes / description
        Previous value: -"Number of consolidated prototype memories."New value: +"Number of summary memories merged from several individual ones. Consolidation is not running on the hosted service, so this count does not currently grow."
    • Changedmemory_write1 field changed
      • changedOutput schema / properties / importance / description
        Previous value: -"Novelty score for this write (0-1): how much it adds over the nearest memories already saved in the same domain. A first-generation metric UNDER ACTIVE DEVELOPMENT and known to be unreliable — the same content has measured ~0.08 in Russian against ~0.55 in English, so it under-reads non-English text. It is not a verdict on whether the memory was worth keeping. Absent when the service sent no score."New value: +"Novelty score for this write (0-1): how much it adds over the nearest memories already saved in the same domain. Outside shared rooms, a write that scores below the service's importance threshold is not stored, and `reason` says why when the service sends one. The score is approximate and can read lower for non-English text. It is not a verdict on whether the memory was worth keeping. Absent when the service sent no score."
  5. 1 tool updatev0.13.0
    • Changedmemory_feedback3 fields changed
      • removedInput schema / properties / atom_ids
        Removed value: -{
        -  "description": "Deprecated since 0.11, removed in 0.13: atom_ids is the old name of memory_ids, still accepted on its own until then. Pass memory_ids instead.",
        -  "items": {
        -    "type": "string"
        -  },
        -  "minItems": 1,
        -  "type": "array"
        -}
      • changedInput schema / properties / memory_ids / description
        Previous value: -"Required: IDs of the memories to rate, the `id:` line of each memory_read result. (Optional in this schema only while the deprecated atom_ids is still accepted in its place.)"New value: +"IDs of the memories to rate, the `id:` line of each memory_read result."
      • changedInput schema / required
        Previous value: -[
        -  "outcome"
        -]New value: +[
        +  "memory_ids",
        +  "outcome"
        +]
  6. 4 tool updatesv0.12.1
    • Changedmemory_feedback1 field changed
      • changedInput schema / properties / atom_ids / description
        Previous value: -"Deprecated since 0.11, removed in 0.12: atom_ids is the old name of memory_ids, still accepted on its own until then. Pass memory_ids instead."New value: +"Deprecated since 0.11, removed in 0.13: atom_ids is the old name of memory_ids, still accepted on its own until then. Pass memory_ids instead."
    • Addedmemory_graph
    • Changedmemory_list_rooms1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "rooms": {
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "address": {
        +            "description": "Domain address (xroom:<id>); pass as `domain` on read/write.",
        +            "type": "string"
        +          },
        +          "archived": {
        +            "description": "True if archived (owned rooms only).",
        +            "type": "boolean"
        +          },
        +          "name": {
        +            "description": "The room name.",
        +            "type": "string"
        +          },
        +          "role": {
        +            "description": "'owner' or 'member'.",
        +            "type": "string"
        +          },
        +          "room_id": {
        +            "description": "The room's id (room_...).",
        +            "type": "string"
        +          },
        +          "scope": {
        +            "description": "'read' or 'read_write'.",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "room_id",
        +          "address",
        +          "role",
        +          "archived"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "rooms"
        +  ],
        +  "type": "object"
        +}
    • Changedvault_list1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "secrets": {
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "alias": {
        +            "description": "The secret's alias — the reference you use, never the value.",
        +            "type": "string"
        +          },
        +          "concepts": {
        +            "description": "Concept tags.",
        +            "items": {
        +              "type": "string"
        +            },
        +            "type": "array"
        +          },
        +          "context": {
        +            "description": "The secret's purpose/context — never the value.",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "alias",
        +          "context",
        +          "concepts"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "secrets"
        +  ],
        +  "type": "object"
        +}
  7. 8 tool updatesv0.11.0
    • Changedmemory_create_room1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "address": {
        +      "description": "Domain address (xroom:<id>); pass as `domain` on read/write.",
        +      "type": "string"
        +    },
        +    "name": {
        +      "description": "The room name as stored.",
        +      "type": "string"
        +    },
        +    "room_id": {
        +      "description": "The room's id (room_...); pass to memory_invite_to_room.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "room_id",
        +    "address"
        +  ],
        +  "type": "object"
        +}
    • Changedmemory_feedback1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "avg_valence": {
        +      "description": "Average valence of the rated memories after the update. Reported as 0 in an asynchronous acknowledgement, where the real value is computed later — a 0 here is therefore not evidence of a neutral outcome.",
        +      "type": "number"
        +    },
        +    "coactivation_edges": {
        +      "description": "Number of feedback-driven query/result concept co-activation edges changed by the service. This is separate from ordinary Hebbian strengthening among a memory's own concepts. This server does not send query_concepts, so live calls through this tool report 0; asynchronous acknowledgements also report 0.",
        +      "maximum": 9007199254740991,
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "updated_count": {
        +      "description": "How many memories the service reports it applied the rating to. Processed synchronously this is the real count of memories that existed and were updated; processed asynchronously it is a best-effort ACCEPTED-count estimate — the number of IDs submitted — and the authoritative number is not known until the background worker runs. Zero means no submitted ID matched in the service's resolved request scope.",
        +      "maximum": 9007199254740991,
        +      "minimum": 0,
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "updated_count"
        +  ],
        +  "type": "object"
        +}
    • Changedmemory_invite_to_room2 fields changed
      • changedInput schema / properties / max_uses / maximum
        Previous value: -9007199254740991New value: +1000
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "code": {
        +      "description": "The invite code (mnvr_...). Single-use by default, with a configurable use limit. Shown once.",
        +      "type": "string"
        +    },
        +    "expires_at": {
        +      "description": "ISO 8601 expiry, or null.",
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "join_url": {
        +      "description": "Landing URL the invitee can open to join.",
        +      "type": "string"
        +    },
        +    "room_address": {
        +      "description": "The room's domain address (xroom:<id>).",
        +      "type": "string"
        +    },
        +    "scope": {
        +      "description": "Role the invitee will get.",
        +      "type": "string"
        +    },
        +    "share_message": {
        +      "description": "Ready-to-forward invite text.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "share_message"
        +  ],
        +  "type": "object"
        +}
    • Changedmemory_join_room1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "address": {
        +      "description": "Domain address (xroom:<id>); pass as `domain` on read/write.",
        +      "type": "string"
        +    },
        +    "already_member": {
        +      "description": "True if you were already a member (no-op join).",
        +      "type": "boolean"
        +    },
        +    "name": {
        +      "description": "The room name.",
        +      "type": "string"
        +    },
        +    "next_steps": {
        +      "description": "How to use the room now.",
        +      "type": "string"
        +    },
        +    "room_id": {
        +      "description": "The room's id (room_...).",
        +      "type": "string"
        +    },
        +    "scope": {
        +      "description": "Your role in the room ('read' | 'read_write').",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "room_id",
        +    "address",
        +    "next_steps"
        +  ],
        +  "type": "object"
        +}
    • Changedmemory_list_recent1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "items": {
        +      "description": "Entries newest-first (creation time descending).",
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "author": {
        +            "description": "Sanitized AGENT identity of the writer (never the human principal) — attribution in shared rooms.",
        +            "type": "string"
        +          },
        +          "content": {
        +            "description": "Stored memory content.",
        +            "type": "string"
        +          },
        +          "created_at": {
        +            "description": "UTC creation instant, ISO-8601; absent on legacy memories without a timestamp.",
        +            "type": "string"
        +          },
        +          "domain": {
        +            "description": "User-defined memory namespace or domain.",
        +            "type": "string"
        +          },
        +          "memory_id": {
        +            "description": "Identifier needed to rate or manage this saved memory.",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "memory_id",
        +          "content",
        +          "domain"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "next_cursor": {
        +      "description": "Pass back as cursor for the next (older) page; null = listing complete. Absent when the service sent a continuation token this client will not pass on; the text then says the token could not be displayed.",
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    }
        +  },
        +  "required": [
        +    "items"
        +  ],
        +  "type": "object"
        +}
    • Changedmemory_read3 fields changed
      • changedInput schema / properties / top_k / description
        Previous value: -"Requested number of results (default: 5). ⚠️ Not a hard cap: association expansion can return MORE than this, and the relevance floor can return fewer — raising it does not reliably widen the result set. For a complete, exactly-bounded listing use memory_list_recent instead."New value: +"Requested number of results (default: 5, what this server asks for when you omit it; the engine's own default of 10 never applies, because the field is always sent). ⚠️ Not a hard cap: association expansion can return MORE than this, and the relevance floor can return fewer — raising it does not reliably widen the result set. For a complete, exactly-bounded listing use memory_list_recent instead."
      • changedInput schema / properties / top_k / maximum
        Previous value: -50New value: +500
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "items": {
        +      "description": "Matching memories, ordered per order_by.",
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "author": {
        +            "description": "Sanitized AGENT identity of the writer (never the human principal) — attribution in shared rooms.",
        +            "type": "string"
        +          },
        +          "content": {
        +            "description": "Stored memory content.",
        +            "type": "string"
        +          },
        +          "created_at": {
        +            "description": "UTC creation instant, ISO-8601; absent on legacy memories without a timestamp.",
        +            "type": "string"
        +          },
        +          "domain": {
        +            "description": "User-defined memory namespace or domain.",
        +            "type": "string"
        +          },
        +          "memory_id": {
        +            "description": "Identifier needed to rate or manage this saved memory.",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "memory_id",
        +          "content",
        +          "domain"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "items"
        +  ],
        +  "type": "object"
        +}
    • Changedmemory_stats1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "avg_importance": {
        +      "description": "Average importance of stored memories, on a scale from 0 to 1.",
        +      "type": "number"
        +    },
        +    "avg_valence": {
        +      "description": "Average valence of stored memories: how well recalls turned out, on a scale from -1 to 1.",
        +      "type": "number"
        +    },
        +    "domains": {
        +      "description": "User-defined memory domains.",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "episodes": {
        +      "description": "Number of episodic (not yet consolidated) memories.",
        +      "maximum": 9007199254740991,
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "hebbian_edges": {
        +      "description": "Number of Hebbian concept-to-concept links, learned from concepts that occur together as memories are stored and used.",
        +      "maximum": 9007199254740991,
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "memory_count": {
        +      "description": "Number of saved memories.",
        +      "maximum": 9007199254740991,
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "prototypes": {
        +      "description": "Number of consolidated prototype memories.",
        +      "maximum": 9007199254740991,
        +      "minimum": 0,
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "memory_count",
        +    "domains"
        +  ],
        +  "type": "object"
        +}
    • Changedmemory_write3 fields changed
      • addedInput schema / properties / concepts / maxItems
        Added value: +256
      • addedInput schema / properties / domain / maxLength
        Added value: +100
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "importance": {
        +      "description": "Novelty score for this write (0-1): how much it adds over the nearest memories already saved in the same domain. A first-generation metric UNDER ACTIVE DEVELOPMENT and known to be unreliable — the same content has measured ~0.08 in Russian against ~0.55 in English, so it under-reads non-English text. It is not a verdict on whether the memory was worth keeping. Absent when the service sent no score.",
        +      "type": "number"
        +    },
        +    "memory_id": {
        +      "description": "Identifier of the stored memory, or null when it was not stored.",
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "reason": {
        +      "description": "The memory service's own explanation of this outcome, quoted as sent — when stored is false this is the ONLY statement of WHY, e.g. \"Below importance threshold (0.047 < 0.1)\". Ordinary text is preserved exactly; only control, bidi, zero-width, and repeated-whitespace characters are normalized before display, and the value is capped at 400 characters. Absent when the service sent no explanation, or when nothing remains after that normalization.",
        +      "type": "string"
        +    },
        +    "stored": {
        +      "description": "Whether the memory passed the novelty gate and was stored.",
        +      "type": "boolean"
        +    }
        +  },
        +  "required": [
        +    "stored",
        +    "memory_id"
        +  ],
        +  "type": "object"
        +}
  8. 2 tool updatesv0.10.2
    • Changedmemory_feedback4 fields changed
      • changedInput schema / properties / atom_ids / description
        Previous value: -"IDs of memories to give feedback on (from memory_read results)"New value: +"Deprecated since 0.11, removed in 0.12: atom_ids is the old name of memory_ids, still accepted on its own until then. Pass memory_ids instead."
      • addedInput schema / properties / domain
        Added value: +{
        +  "description": "Only for memories read from a shared room: that room's address (xroom:...), exactly as you read it. Omit it for your own memories, which are rated by id alone.",
        +  "type": "string"
        +}
      • addedInput schema / properties / memory_ids
        Added value: +{
        +  "description": "Required: IDs of the memories to rate, the `id:` line of each memory_read result. (Optional in this schema only while the deprecated atom_ids is still accepted in its place.)",
        +  "items": {
        +    "type": "string"
        +  },
        +  "minItems": 1,
        +  "type": "array"
        +}
      • changedInput schema / required
        Previous value: -[
        -  "atom_ids",
        -  "outcome"
        -]New value: +[
        +  "outcome"
        +]
    • Changedmemory_invite_to_room1 field changed
      • addedInput schema / properties / max_uses
        Added value: +{
        +  "description": "How many people may join with this invite (default 1, single-use).",
        +  "maximum": 9007199254740991,
        +  "minimum": 1,
        +  "type": "integer"
        +}
  9. 2 tool updatesv0.10.0
    • Changedmemory_list_recent2 fields changed
      • changedInput schema / properties / domain / description
        Previous value: -"Restrict to one domain. REQUIRED to read a shared room — pass its address ('xroom:room_01ABC'), because rooms are separate stores that an unscoped feed does NOT cover. Omit only when you mean your own domains. Room addresses come from memory_list_rooms."New value: +"Restrict to one domain. REQUIRED to read a shared room — pass its address ('xroom:room_01ABC'), because rooms are separate stores that an unscoped feed does NOT cover. Omit only when you mean your own domains. Room addresses come from memory_list_rooms. Room entries are often long — a room feed usually reaches its size budget after a handful of them, so expect to page (see `limit`)."
      • changedInput schema / properties / limit / description
        Previous value: -"Page size (default: 20). Newest first."New value: +"Most entries per page (default: 20). Newest first. ⚠️ A CEILING, not a promise: the page is ALSO bounded by size, so a page of long entries stops early and returns a cursor for the rest. In rooms whose entries run long, ask for 5–10 — a large `limit` there buys nothing the size budget will not take back, and costs round trips."
    • Changedmemory_write1 field changed
      • changedInput schema / properties / domain / description
        Previous value: -"Namespace to organize memories (e.g. 'engineering', 'user:alice', 'project:acme')"New value: +"Namespace to organize memories (e.g. 'engineering', 'user:alice', 'project:acme'). Matched byte-for-byte — a leading space, a different case, or an invisible character opens a SEPARATE, permanent store, so reuse an exact name from memory_stats rather than retyping one. To write into a shared room, pass its address here instead (e.g. 'xroom:room_01ABC'). Find room addresses with memory_list_rooms."
  10. 2 tool updatesv0.9.0
    • Removedmemory_delete
    • Removedmemory_delete_domain
  11. 2 tool updatesv0.8.1
    • Changedmemory_list_recent3 fields changed
      • changedInput schema / properties / domain / description
        Previous value: -"Restrict to one domain (e.g. a shared room address 'xroom:...'); omit for all your domains."New value: +"Restrict to one domain. REQUIRED to read a shared room — pass its address ('xroom:room_01ABC'), because rooms are separate stores that an unscoped feed does NOT cover. Omit only when you mean your own domains. Room addresses come from memory_list_rooms."
      • addedInput schema / properties / exclude_author
        Added value: +{
        +  "description": "Drop entries written by this author PRINCIPAL. ⚠️ NOT USABLE FROM HERE YET — the principal is never shown in these results, so there is no value you can get through this tool; a guess like 'me' filters nothing, silently. Same caveat as on memory_read.",
        +  "maxLength": 200,
        +  "type": "string"
        +}
      • addedInput schema / properties / until
        Added value: +{
        +  "description": "Only entries created at/before this ISO-8601 instant (inclusive). Pair with `since` to read a closed window — 'what happened on Monday' — instead of paging back from now.",
        +  "type": "string"
        +}
    • Changedmemory_read3 fields changed
      • changedInput schema / properties / domain / description
        Previous value: -"Restrict the search to one domain namespace (e.g. 'project:acme'); omit to search across all domains."New value: +"Restrict the search to one domain namespace (e.g. 'project:acme'). Omitting it searches your OWN domains — it does NOT include shared rooms, which are separate stores: to search a room, pass its address here (e.g. 'xroom:room_01ABC'). Find room addresses with memory_list_rooms."
      • changedInput schema / properties / exclude_author / description
        Previous value: -"Drop memories written by this author PRINCIPAL (the server-side identity, not shown in these results). Useful when your system knows principals (e.g. via the REST API); a self-exclusion shortcut is planned server-side."New value: +"Drop memories written by this author PRINCIPAL — the server-side identity. ⚠️ NOT USABLE FROM HERE YET: the principal is not shown in these results, so there is no value you can obtain through this tool, and a guess like 'me' silently matches nothing and filters nothing. Only pass it if your system knows the exact principal from elsewhere (e.g. the REST API). A self-exclusion shortcut is planned."
      • changedInput schema / properties / top_k / description
        Previous value: -"Max results to return (default: 5)"New value: +"Requested number of results (default: 5). ⚠️ Not a hard cap: association expansion can return MORE than this, and the relevance floor can return fewer — raising it does not reliably widen the result set. For a complete, exactly-bounded listing use memory_list_recent instead."
  12. 4 tool updatesv0.7.0
    • Addedmemory_list_recent
    • Addedmemory_list_rooms
    • Changedmemory_read4 fields changed
      • addedInput schema / properties / exclude_author
        Added value: +{
        +  "description": "Drop memories written by this author PRINCIPAL (the server-side identity, not shown in these results). Useful when your system knows principals (e.g. via the REST API); a self-exclusion shortcut is planned server-side.",
        +  "maxLength": 200,
        +  "type": "string"
        +}
      • addedInput schema / properties / order_by
        Added value: +{
        +  "description": "'relevance' (default) = ranking order. 'recency' = the matched set re-sorted newest-first. For a complete newest-first feed with no search at all, use memory_list_recent instead.",
        +  "enum": [
        +    "relevance",
        +    "recency"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / since
        Added value: +{
        +  "description": "Only memories created at/after this ISO-8601 instant (naive = UTC) — e.g. your last-seen watermark in a shared room.",
        +  "maxLength": 40,
        +  "type": "string"
        +}
      • addedInput schema / properties / until
        Added value: +{
        +  "description": "Only memories created at/before this ISO-8601 instant.",
        +  "maxLength": 40,
        +  "type": "string"
        +}
    • Addedvault_list

TDQS

A4.3/5.0

Scored across 11 tools

Disambiguation4/5

memory_read (semantic search) and memory_list_recent (chronological catch-up) are the closest pair, but their descriptions explicitly draw the line ('what do I know about X' vs 'what happened lately'). memory_stats, memory_graph, and memory_feedback each target a distinct read/observe action, and the room tools (create/invite/join/list) are cleanly separated. vault_list is the one off-domain item, though its purpose is unmistakable.

Naming Consistency4/5

Ten of eleven tools follow a consistent snake_case memory_<verb>_<noun> pattern (memory_write, memory_read, memory_create_room, memory_join_room, etc.). The lone outlier, vault_list, breaks the prefix but is still readable and clearly scoped to a different resource.

Tool Count5/5

Eleven tools is well within a comfortable range and each maps to a real operation: core memory I/O, feedback/ranking, graph inspection, and a four-step room-sharing lifecycle. Nothing appears redundant or padding.

Completeness4/5

Core lifecycle is covered: write, search, list, rate, inspect stats/graph, plus full room create/invite/join/list. Deliberate omissions exist (no delete/update — corrections go through memory_write), but the vault surface is thin: only vault_list, with no way to store or manage secrets, and no room leave/revoke operation, which agents would have to work around.

Maintenance

ActivityActive
ResponsivenessSlow

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Persistent memory API for AI agents — store, recall, and inject semantically-searchable context across sessions. EU-hosted, GDPR-compliant. Supports Claude, Cursor, Cline, and any MCP-compatible client.
    4
    2
    MIT
  • A
    license
    B
    quality
    D
    maintenance
    A shared memory layer for AI agents — one memory.md synced across Claude Desktop, Cursor, Claude Code, OpenAI Codex, and any MCP client.
    4
    2
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Persistent memory for AI coding agents that stores and recalls preferences, decisions, and conventions via semantic similarity, with zero cloud dependencies and plug-and-play MCP integration for Claude Code.
    Apache 2.0