shared-agent-memory-mcp
This server provides a shared, human-auditable memory service for MCP-compatible coding agents, backed by Notion with local SQLite caching and optional Obsidian mirroring.
Search memories:
memory_searchperforms keyword, semantic, or hybrid search across the shared Notion memory, filtering by agent, category, tag, and project, with options for compact/full responses.List recent memories:
memory_recentretrieves the latest updated memories, optionally filtered by agent or project.Fetch a single memory:
memory_getretrieves a full memory by its Notion page ID.Add new memories:
memory_addsaves durable facts, preferences, decisions, conventions, bug fixes, or project context, with metadata like category, importance, and tags, and supports idempotency keys.Update memories:
memory_updatemodifies existing memories (title, content, tags, category, importance, status) to avoid duplicates when knowledge changes.Delete memories:
memory_deletearchives a memory by default or moves it to trash withhard=true.CLI tools: The server also includes a CLI for setup, CRUD, cache management, diagnostics, sync/watch to Obsidian, and conflict resolution.
Cache and sync: Maintains a local SQLite FTS5 cache for fast keyword searches, supports semantic/vector search with a multilingual model, and can sync Notion records to Obsidian with conflict handling.
Notion as source of truth: All writes go to Notion; Obsidian is a read-only mirror. The server ensures data consistency across multiple agents and clients.
Shared Agent Memory MCP
A shared, human-auditable memory service for MCP-compatible coding agents. Notion holds the authoritative records; a local SQLite FTS5 cache handles eligible keyword searches; an optional multilingual embedding model enables semantic and hybrid search; an Obsidian vault can mirror records as Markdown.
What works today
Six MCP tools:
memory_search,memory_recent,memory_get,memory_add,memory_update, andmemory_delete.One Notion database shared by Cline, OpenCode, Claude Code, Copilot, Hermes, and other MCP clients.
Project, agent, category, tag, importance, and provenance metadata. Optional Notion properties are used when present in the database schema.
A CLI for setup, CRUD, export, cache maintenance, diagnostics, conflict inspection, and Notion-to-Obsidian sync or watch.
Conflict copies preserve manually edited Obsidian files during sync. Git commit and push for the vault are best-effort operations.
Search and sync boundaries
memory_search and CLI search default to keyword mode. A fresh SQLite FTS5 cache handles eligible active-memory keyword queries; requests with unsupported cache filters or a stale cache query Notion instead. After writes, the cache is invalidated until the next sync or cache rebuild.
Set mode to semantic or hybrid in memory_search, or use CLI search --mode semantic|hybrid, to search a fresh local cache with the multilingual MiniLM model. Semantic mode ranks by embedding similarity; hybrid mode combines those results with FTS5 keyword results. The first such query downloads model files to the local model cache and embeds matching cached records, so it can take longer. Later queries reuse persisted record vectors and calculate cosine distance with the installed sqlite-vec extension; a changed title or content is re-embedded. Long memories are split into overlapping 1,200-character chunks, and the best matching chunk determines each memory's semantic rank. Semantic results and hybrid results with a vector match include match.excerpt, match.start, and match.end; offsets count Unicode characters in content and the excerpt spans at most 1,200 characters. Hybrid results found only by keyword have no match. The full content remains available. Existing cached vectors are re-embedded once after this upgrade. Memory text is processed locally, while downloading model files requires network access. Run cache rebuild or sync against the same installation and cache path as the MCP server before using these modes. If the cache is stale or incomplete, they report an error instead of silently returning keyword-only results.
The match object is visible in MCP responses and CLI search --json output. The normal CLI summary displays the matched excerpt and its character offsets for vector hits; keyword-only results still display the content prefix.
MCP memory_search and memory_recent accept response: "compact" to omit full content from their results. Compact results include excerpt: the best matching semantic chunk in search (up to 1,200 Unicode characters), a 240-character window around the matching text for keyword-only search, or the first 240 Unicode characters for recent items. If a search term appears only in the title, the keyword excerpt falls back to the content prefix. Vector hits also retain match.start and match.end; match.excerpt is represented by the top-level excerpt in compact mode. The default response: "full" preserves the existing result shape. Call memory_get with a result ID when you need the complete memory.
MCP memory_recent also accepts project or currentProject: true to list only memories from one project. An explicit project takes precedence over automatic detection; omitting both retains the global recent list. Project filtering requires a Project property in the Notion database.
The older tiered-memory, incremental-index, ranking, hybrid-search.ts, and vector-search.ts modules remain experimental and are not used by the active search path. The older vector module still uses hash-based mock embeddings; the active semantic implementation is in semantic-search.ts.
Notion is the source of truth. sync and watch copy Notion records to Obsidian. Changes edited in Obsidian are not written back to Notion.
If a Markdown file was edited after its last sync, the next sync leaves it intact and writes the latest Notion version to a .conflict.md copy. Use conflicts to list these files and resolve <path> --accept-notion to apply the Notion version with a backup of the manual file. --keep-obsidian keeps the manual file; because Notion remains authoritative, a later sync can report the same conflict until the records agree. Git commits include the sync manifest and Markdown files with a Notion ID in their frontmatter; unrelated vault notes are left out. CLI warnings and the obsidian.error, cache.error, and git fields in MCP write results report mirror, cache, commit, or push failures. These local failures do not undo a completed Notion write; repair the local state and run sync rather than repeating add.
Related MCP server: obsidian-mcp
Requirements
Node.js 22 or newer
A Notion integration token and a database shared with that integration
Optional: an Obsidian vault backed by Git for Markdown mirroring
Quick start
git clone https://github.com/Chaerulcp/shared-agent-memory-mcp.git
cd shared-agent-memory-mcp
npm ci
npm run build
Copy-Item .env.example .env
# Set NOTION_TOKEN and NOTION_DATABASE_ID in .env
# Set NOTION_DATA_SOURCE_ID too when the database has multiple data sources
node dist/cli.js doctorCreate a Notion integration at My Integrations, then share the target database with it. To create a new memory database from an existing Notion parent page, set NOTION_TOKEN and run npm run init-db -- <parent-page-url>. See Getting Started for setup details.
The doctor command checks credentials and Notion connectivity. doctor --sync also checks the optional vault, watcher, and cache and shows the effective cache path; a missing watcher is healthy because polling is optional, while a stale lock is reported as a failure. An unconfigured vault or stale cache can make that extended check report unhealthy.
CLI examples
node dist/cli.js add --title "Use TypeScript for API" --content "The API uses TypeScript." --agent shared --category decision --project backend-service
node dist/cli.js add --title "Retry-safe memory" --content "A durable fact" --idempotency-key task-2026-09-14-001
node dist/cli.js search "TypeScript API" --project backend-service
node dist/cli.js recent --limit 5
node dist/cli.js get YOUR_NOTION_PAGE_ID
node dist/cli.js update YOUR_NOTION_PAGE_ID --title "Use TypeScript for backend API"
node dist/cli.js delete YOUR_NOTION_PAGE_ID
node dist/cli.js cache rebuild
node dist/cli.js cache search "TypeScript"
node dist/cli.js search "cara memperbaiki mobil" --mode semantic --project backend-service
node dist/cli.js search "TypeScript API" --mode hybrid --project backend-service
node dist/cli.js sync --dry-rundelete archives by default; --hard moves the Notion page to trash. cache rebuild and sync read all Notion records. sync --dry-run only reads Notion and does not write the cache, vault, or Git.
For a write that may be retried, give memory_add an idempotencyKey or CLI add an --idempotency-key (8–128 letters, digits, ., _, :, or -). Reuse that key only for the same logical write. The first keyed write adds a rich-text Operation Key property to an older Notion database if the integration can edit its schema; databases created by init include it. A retry finds the existing page and returns replayed: true. When a write may have reached Notion but the page cannot yet be found, the local operation journal blocks another create with that key. Keep the key and check Notion before deciding how to resolve the uncertain write. The journal lives beside the configured cache file and survives cache clear; clients must share MEMORY_CACHE_PATH to coordinate pending writes. Notion does not enforce uniqueness for this property, so simultaneous keyed writes from separate installations with separate journals are not atomic.
For all commands and accepted values, run node dist/cli.js --help.
MCP client setup
Use node dist/index.js as a stdio MCP server and pass NOTION_TOKEN and NOTION_DATABASE_ID through your client's environment or the local .env file. The server automatically discovers the target when the database has one data source. For a multi-source database, also set NOTION_DATA_SOURCE_ID; the server refuses an ambiguous target instead of writing to the wrong source. This release uses Notion API 2025-09-03 and @notionhq/client v5. Never commit .env or put credentials in memory content.
The SQLite cache defaults to .cache/memory.sqlite under this installation, regardless of a client's working directory. Set MEMORY_CACHE_PATH to an absolute path in .env or each client's environment when the installation directory is read-only or several installations should share one cache. Existing caches created under other working directories are disposable; run node dist/cli.js cache rebuild after switching paths.
Setup guides: Claude Code, Codex CLI, OpenCode, Copilot CLI, Cline, Gemini CLI, and other clients. Example configurations are in examples/mcp-configs.
Architecture
src/index.ts exposes the MCP tools. src/store.ts reads and writes Notion. src/cache.ts maintains the disposable SQLite FTS5 and embedding cache at the installation's .cache/memory.sqlite by default; src/semantic-search.ts runs the local model and ranks cached records. src/obsidian.ts writes the optional Markdown mirror and handles Git. See ARCHITECTURE.md for the data flows and cache policy.
Validation
npm testThe test script builds TypeScript and runs the repository's automated tests. Local model inference and MCP retrieval were also checked manually with an Indonesian-to-English paraphrase. The automated tests do not prove live Notion sync, production latency, or quality on a large memory collection; those require separate integration checks and benchmarks. CI also runs a production-dependency audit.
Run the reproducible retrieval benchmark with npm run benchmark:retrieval -- --sizes 100,1000,10000 --modes keyword,semantic,hybrid --repeats 3. The vector comparison, long-memory evaluation, and matched-excerpt check document later search changes. These benchmarks use labeled synthetic bilingual fixtures and temporary SQLite databases, without calling Notion. Semantic and hybrid runs require the local MiniLM model files to have been cached beforehand; downloads are disabled. The reported figures are measurements for these fixtures and machine, not a production performance claim.
v1.5.0 release notes summarize the current release. The v1.4.0 development notes are historical and contain unverified performance claims.
Contributing and support
See CONTRIBUTING.md, SECURITY.md, and GitHub Issues.
Licensed under the MIT License.
Available Tools
6 toolsmemory_addA
Save a new durable memory into the shared Notion memory. USE THIS when: the user states a preference, a project decision is made, a convention is established, a non-obvious bug is fixed (root cause + fix), or important project/environment context is learned. Do NOT store secrets, tokens, or throwaway information.
| Name | Required | Description | Default |
|---|---|---|---|
| tags | No | Lowercase tags, e.g. ['typescript','ui','deploy'] | |
| agent | Yes | Which agent is saving this; use 'shared' for universal rules | |
| title | Yes | Short, searchable, imperative title (<= 80 chars recommended) | |
| source | No | Origin: agent, user, notion, import, or system | |
| content | Yes | Full memory content: concise but complete, with examples when helpful | |
| project | No | Project/repository scope; optional for legacy databases | |
| category | No | other | |
| confidence | No | ||
| importance | No | medium | |
| supersedes | No | ID of an older memory replaced by this one | |
| verifiedAt | No | ISO timestamp when this memory was last verified | |
| freshnessDays | No | Days before this memory is considered stale | |
| allowDuplicate | No | Explicitly allow a similar memory to be saved | |
| idempotencyKey | No | Reuse the same key when retrying one memory_add operation |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden and does disclose the core write behavior ('durable', 'shared Notion memory'). However, it omits behavioral details like duplicate rejection (despite allowDuplicate), idempotency retry semantics, and what the operation returns or confirms.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is structured with an action sentence, a 'USE THIS when' list, and an exclusion clause. Every phrase earns its place and the core purpose is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 14-parameter tool with no output schema, the description covers when to use it and content policy well, while the schema documents the parameters. A minor gap is the lack of any statement about return behavior or duplicate handling, though the schema's allowDuplicate and idempotencyKey fields hint at it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 79% and individual fields like title, content, agent, and tags already have meaningful descriptions. The tool description adds no per-parameter detail, which is acceptable given the schema's heavy lifting; the coverage baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource: 'Save a new durable memory into the shared Notion memory.' This clearly identifies an add/create operation and sets it apart from sibling tools like memory_update and memory_delete without needing to inspect schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit 'USE THIS when' triggers (preferences, decisions, conventions, bug fixes, context) and a 'Do NOT' exclusion for secrets and throwaway info. It does not name alternative tools, such as memory_update for editing existing memories, so it stops short of the full when/when-not/alternatives pattern.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
memory_deleteA
Archive a memory (default) or move it to Notion trash (hard=true). Use when a memory is wrong or obsolete.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Notion page id of the memory | |
| hard | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It explains the behavior of the hard parameter (archive vs. trash) and the default action, which is useful. However, it does not disclose potential side effects like reversibility or permission requirements, leaving some behavioral details unstated. This is adequate but not exhaustive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no wasted words. The primary action and default behavior are front-loaded, followed by a concise usage guideline. Every word earns its place, making it efficient and easy to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple deletion tool with no output schema, the description covers the essential behavior and the when-to-use scenario. It clarifies the two operational modes and the parameter semantics. Minor gaps like explicit side effects or prerequisites are not critical given the tool's simplicity, so it feels largely complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 50%: the id parameter is described in the schema, but the hard parameter is not. The description adds meaningful semantic detail for hard by explaining that hard=true moves to Notion trash, and it clarifies the default archive behavior. This compensates for the missing schema description and goes beyond a bare boolean.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action: archive a memory by default, or move it to Notion trash with hard=true. It identifies the resource (memory) and the two operational modes, making the tool's purpose unambiguous and distinct from siblings like memory_update or memory_add.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit when-to-use guidance: 'Use when a memory is wrong or obsolete.' This gives a clear context for selecting this tool, though it does not mention when not to use it or alternative tools. It stops short of naming siblings or exclusion scenarios, so a 4 is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
memory_getA
Fetch a single memory by its id (full content).
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Notion page id of the memory |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure. It communicates that the operation is a read ('Fetch') and that the returned content is complete rather than truncated ('full content'). However, it does not describe what happens for a missing or invalid id, permission requirements, or any response format details.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with no wasted words. The core action, target, selector, and output qualifier are all front-loaded, making it easy for an agent to quickly grasp the tool's purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter get-by-id operation, the description is nearly complete: it states the input, the action, and the nature of the output ('full content'). The only meaningful omission is behavior for missing or invalid ids, but given the low complexity and fully covered schema, the description is adequately contextual.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the schema already documents the id as 'Notion page id of the memory.' The description merely refers to 'its id' and adds no new semantic detail beyond what the input schema already provides, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Fetch'), a specific resource ('a single memory'), and a precise selection mechanism ('by its id'), plus the notable qualifier 'full content.' This clearly differentiates memory_get from siblings like memory_search, memory_recent, and the mutation tools without requiring an agent to open their schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'by its id' implies the tool should be used when an agent already knows the memory's id, but it does not explicitly contrast this with memory_search, memory_recent, or the mutation tools. Usage context is implied rather than stated, so no clear when-not or alternative guidance is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
memory_recentA
List the most recently updated memories from the shared Notion memory. Set response to compact to return excerpts without full content. Use to get context about what was learned/saved lately.
| Name | Required | Description | Default |
|---|---|---|---|
| agent | No | ||
| limit | No | ||
| project | No | Only memories for this project/repository | |
| response | No | Compact omits full content; full preserves the existing response | full |
| currentProject | No | Use the current Git repository as project scope when project is omitted |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
There are no annotations, so the description must carry behavior. It states the response-mode behavior (compact returns excerpts) and 'List' implies a read-only operation, but it does not explicitly confirm no side effects, mention auth/access needs, or describe ordering guarantees beyond 'recently updated.'
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with the main operation; each adds some value. The compact-mode tip and use-case sentence are useful but mildly redundant with the first sentence and schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a no-output-schema tool with 5 optional params, the description gives the core list behavior and response modes, but omits what an actual result item looks like, default agent scope, and the meaning of 'full' vs 'compact' beyond omission. It is adequate for a simple list but not fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 60% schema coverage, the schema documents project, response, and currentProject, but not agent or limit. The description only adds a usage tip for response ('compact... without full content'), which largely repeats the schema, and does not explain the agent scope or default limit.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence names a specific verb ('List') and resource ('most recently updated memories from the shared Notion memory'), so an agent immediately knows the operation and scope. The recency qualifier separates it from sibling search/get tools, even though no sibling is named.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The last sentence gives a concrete use case: 'Use to get context about what was learned/saved lately.' That is clear context for when to call it, but it does not explicitly contrast with memory_search or memory_get or mention any exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
memory_searchA
Search the shared long-term memory stored in Notion (used by Cline, OpenCode, Claude Code, GitHub Copilot, Hermes). Returns matching memories with id, title, content, agent, category, tags. Semantic and hybrid vector matches also include match.excerpt with Unicode start/end offsets. Set response to compact to omit full content and return an excerpt; use memory_get for full content. USE THIS at the start of a task with relevant keywords, and before making decisions, to reuse saved preferences, conventions, and past decisions.
| Name | Required | Description | Default |
|---|---|---|---|
| tag | No | Exact tag name to filter by | |
| mode | No | Semantic and hybrid modes require a fresh local cache | keyword |
| agent | No | Only memories saved by this agent | |
| limit | No | ||
| query | Yes | Search text; semantic and hybrid modes also match related meaning | |
| project | No | Only memories for this project/repository | |
| category | No | ||
| response | No | Compact omits full content; full preserves the existing response | full |
| currentProject | No | Use the current Git repository as project scope when project is omitted |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It discloses return format, the presence of match.excerpt with Unicode offsets for semantic/hybrid modes, and the behavior of the response parameter. It does not mention side effects (though search implies read-only) or authentication/rate limits, but it covers the essential behavioral traits for correct invocation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, front-loaded with purpose, and flows logically from what it returns to usage guidance. It avoids redundancy with the schema. It could be slightly more structured with separate sections, but it remains efficient and easy to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 9 parameters, multiple modes, and alternatives, the description covers the key behavioral aspects: return contents, compact vs full, and when to use. It does not delve into parameter interactions (e.g., currentProject vs project), but the schema covers those. Given the output schema is absent and annotations are missing, the description adequately covers what 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.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is high (78%), so most parameters are already documented. The description adds value by clarifying the response parameter's purpose ('compact to omit full content') and referencing the mode requirement ('require a fresh local cache'), but these are also in the schema. The baseline of 3 applies because the schema does most of the work.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb (search), the resource (shared long-term memory in Notion), and the exact return fields (id, title, content, agent, category, tags). It also distinguishes itself from siblings by noting that memory_get provides full content, making it unambiguous what this tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly instructs to use this tool at the start of a task and before decisions, with relevant keywords. It also references an alternative (memory_get) for full content. However, it does not explicitly state when not to use it relative to memory_recent or memory_delete, so it stops short of 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_updateA
Update an existing memory by id. Prefer updating over creating duplicates when knowledge changes or gets corrected.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Notion page id of the memory | |
| tags | No | ||
| agent | No | ||
| title | No | ||
| source | No | ||
| status | No | ||
| content | No | ||
| project | No | ||
| category | No | ||
| confidence | No | ||
| importance | No | ||
| supersedes | No | ||
| verifiedAt | No | ||
| freshnessDays | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
There are no annotations, so the description carries the full burden of behavioral disclosure. It says 'update' but does not explain whether this is a PATCH-style partial update or a full replacement, whether omitted fields are preserved, or what side effects occur when updating an archived or superseded memory.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler; the core action is front-loaded and the usage preference adds meaningful guidance without redundancy. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool with 14 optional parameters, no annotations, and no output schema, the description is too thin. An agent still lacks critical context about update semantics, field preservation, and what constitutes a successful update.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 7%, yet the description only references 'id' and gives no meaning for the other 13 parameters. It does not compensate for the missing schema descriptions, though it at least identifies id as the lookup key.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Update') with a specific resource ('existing memory by id'), clearly distinguishing it from siblings like memory_add, memory_delete, and memory_search. The intent is immediately unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states when to prefer this tool: 'when knowledge changes or gets corrected,' and contrasts it with creating duplicates. This directly guides the agent away from memory_add in the main scenario where duplication would be inappropriate.
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.
4 tool updates
v1.6.0- Changed
memory_add8 fields changed- added
Input schema / properties / allowDuplicateAdded value: +{ + "default": false, + "description": "Explicitly allow a similar memory to be saved", + "type": "boolean" +} - added
Input schema / properties / confidenceAdded value: +{ + "enum": [ + "high", + "medium", + "low" + ], + "type": "string" +} - added
Input schema / properties / freshnessDaysAdded value: +{ + "description": "Days before this memory is considered stale", + "maximum": 3650, + "minimum": 0, + "type": "integer" +} - added
Input schema / properties / idempotencyKeyAdded value: +{ + "description": "Reuse the same key when retrying one memory_add operation", + "maxLength": 128, + "minLength": 8, + "pattern": "^[A-Za-z0-9._:-]+$", + "type": "string" +} - added
Input schema / properties / projectAdded value: +{ + "description": "Project/repository scope; optional for legacy databases", + "maxLength": 120, + "type": "string" +} - added
Input schema / properties / sourceAdded value: +{ + "description": "Origin: agent, user, notion, import, or system", + "maxLength": 40, + "type": "string" +} - added
Input schema / properties / supersedesAdded value: +{ + "description": "ID of an older memory replaced by this one", + "type": "string" +} - added
Input schema / properties / verifiedAtAdded value: +{ + "description": "ISO timestamp when this memory was last verified", + "format": "date-time", + "type": "string" +}
- Changed
memory_recent3 fields changed- added
Input schema / properties / currentProjectAdded value: +{ + "default": false, + "description": "Use the current Git repository as project scope when project is omitted", + "type": "boolean" +} - added
Input schema / properties / projectAdded value: +{ + "description": "Only memories for this project/repository", + "maxLength": 120, + "type": "string" +} - added
Input schema / properties / responseAdded value: +{ + "default": "full", + "description": "Compact omits full content; full preserves the existing response", + "enum": [ + "full", + "compact" + ], + "type": "string" +}
- Changed
memory_search5 fields changed- added
Input schema / properties / currentProjectAdded value: +{ + "default": false, + "description": "Use the current Git repository as project scope when project is omitted", + "type": "boolean" +} - added
Input schema / properties / modeAdded value: +{ + "default": "keyword", + "description": "Semantic and hybrid modes require a fresh local cache", + "enum": [ + "keyword", + "semantic", + "hybrid" + ], + "type": "string" +} - added
Input schema / properties / projectAdded value: +{ + "description": "Only memories for this project/repository", + "maxLength": 120, + "type": "string" +} - changed
Input schema / properties / query / descriptionPrevious value: -"Keywords/phrase to match in title, content, and tags"New value: +"Search text; semantic and hybrid modes also match related meaning" - added
Input schema / properties / responseAdded value: +{ + "default": "full", + "description": "Compact omits full content; full preserves the existing response", + "enum": [ + "full", + "compact" + ], + "type": "string" +}
- Changed
memory_update6 fields changed- added
Input schema / properties / confidenceAdded value: +{ + "enum": [ + "high", + "medium", + "low" + ], + "type": "string" +} - added
Input schema / properties / freshnessDaysAdded value: +{ + "maximum": 3650, + "minimum": 0, + "type": "integer" +} - added
Input schema / properties / projectAdded value: +{ + "maxLength": 120, + "type": "string" +} - added
Input schema / properties / sourceAdded value: +{ + "maxLength": 40, + "type": "string" +} - added
Input schema / properties / supersedesAdded value: +{ + "type": "string" +} - added
Input schema / properties / verifiedAtAdded value: +{ + "format": "date-time", + "type": "string" +}
6 tool updates
v1.0.0- First observed
memory_add - First observed
memory_delete - First observed
memory_get - First observed
memory_recent - First observed
memory_search - First observed
memory_update
TDQS
Scored across 6 tools
Each tool targets a distinct operation: search, recent, add, get, update, delete. There is no overlap in purpose, and the descriptions clarify when to use each, minimizing selection ambiguity.
All tools follow a consistent 'memory_' prefix followed by an action verb (search, recent, delete, add, update, get). Even 'recent' is a clear descriptor, and the pattern is uniform and predictable.
With 6 tools, the server covers the full lifecycle of memory operations—create, read, update, delete, plus search and recent listing—without being bloated or sparse. The count is well-scoped for its purpose.
The surface provides complete CRUD coverage (add, get, update, delete) and includes discovery mechanisms (search, recent). No obvious gaps exist; it fully supports the stated purpose of a shared memory store.
Maintenance
Related MCP Connectors
Shared memory for coding agents. Stop re-explaining your codebase every session.
Agent-native notes, tasks, dev-docs, vaults, sync & handoffs. MCP + OpenAPI dual surface.
Personal wiki and memory layer for AI assistants. Persistent, structured memory across sessions.
Persistent docs and memory for AI agents — read, write, organize & search a shared workspace.
Related MCP Servers
- AlicenseAqualityCmaintenanceEnables AI agents to store and retrieve project context, bugs, decisions, and session logs by reading and appending markdown files in a local Obsidian vault, without requiring any cloud services.6MIT
- AlicenseAqualityCmaintenanceEnables AI coding agents to read, write, search, and organize notes in an Obsidian vault directly via the filesystem.132,509 npmMIT
- AlicenseAqualityBmaintenanceProvides AI coding assistants persistent engineering memory stored as Markdown files in an Obsidian vault, enabling project context retrieval, session capture, decision recording, and memory search without requiring Obsidian to be running.7MIT
- AlicenseAqualityBmaintenanceEnables coding agents to use an Obsidian vault as long-term memory, with search, reading, and writing of notes, plus automatic capture of learnings that are propagated to MOCs, daily notes, and the knowledge index with git commits.932 npmMIT