servers / gnosis-memory
Gnosis Memory MCP server
communitystreamable_httpremotedestructive capablehealthy
Persistent memory and vector search for AI agents. Hosted, OAuth-protected via Google sign-in.
01Tools · 21
How to read this: tool names here are observed from a live tools/list handshake. The Risk label is a heuristic inferred from the tool name (write/destructive verbs), not from executing the tool — a conservative guess, not a verified capability. We never escalate risk from a description. Found one that's wrong? Tell us — we fix on report.
| Tool | Risk | Side effects | Approval |
|---|---|---|---|
| account Account state + billing. Returns URLs only -- user clicks to pay; never charges silently.
Pick by intent:
"what plan am I on?" -> info (tier, subscription, capabilities, upgrade/downgrade SKUs; permanent tiers og/truebeliever/ogdev cannot downgrade)
"what can I buy?" / "how much is Pro?" -> plans (buyable SKU list)
"upgrade me" / "buy Pro annual" -> checkout (needs sku_id) -> Stripe URL
"cancel" / "update card" / "invoices" -> portal -> Stripe URL (free users with no Stripe record -> pointer to plans+checkout)
"support Gnosis" / "tip" -> donate (amount_cents 100-500000; cumulative badge: 500c supporter / 5000c silver / 25000c gold)
After checkout/donate, Stripe webhook flips tier server-side; next init reflects it. | read | false | unknown |
| agent_manage Manage agents (NAMESPACES under your account, sharing your token).
An agent is a namespace, never a holder of key material: all crypto is the
ACCOUNT's, and an agent id is never an input to a wrap, a seal or a KEK. Agents
organise and scope what is visible; they do not own encryption.
list. create. update (e.g. owner_access).
merge: move an agent's MEMORIES into another, then remove source. PK collision -> 409; confirm="destroy_collisions" to force.
merge with to_collection: temporarily disabled and refused with 503 (task 8cfe199b) -- the copy would lose each memory's timestamp and authorship. Merge into an agent instead.
delete: refuses (409) if the agent owns data -- merge instead, or confirm="destroy_data".
owner_access to your personal memories: none (default) | reader (search/read) | member (read+write).
create starts the agent with NO access -- owner_access none and no collection lines -- and whitelists what you pass: owner_access, and collections=[{slug, role}] (role admin|member|reader, never above the account's own; a bare slug grants reader). update: add_collections=[...] grants or re-roles only those; remove_collections=[slug,...] revokes only those. collections=[...] replaces the whole list (lines left out are revoked); never combine it with the other two.
A PIN-holding account on a plan that writes to collections also gets a private collection named after the agent, where its memories live: memory_add(collection="<name>") from any connection of the account writes there, and delete keeps the collection (manage it with collection_manage). Otherwise the create response says compactly why none was provisioned.
Target a specific agent via ?agent_id=<name> on the MCP URL (durable route) or the legacy AGENT_ID env / X-Agent-ID header. From your base connection, memory_add(collection="<name>") also writes into an owned agent directly (task 78efb3dc); a connection bound to <name> may name its own <name> the same way and lands in its own namespace (task af02be9f). | read | false | unknown |
| artifact_delete Delete an artifact: every revision and its pointer memory. Permanent. confirm must equal the artifact name. memory_delete refuses a pointer; use this. | destructive | true | true |
| artifact_history List the revisions of an artifact (rev_id, parent, seq, time, author, pinned) and its heads. conflict=true means divergent heads to merge. | read | false | unknown |
| artifact_orphans List artifact revisions whose pointer memory is gone (a delete on one replica racing a save on another). Nothing is auto-deleted; export includes them. | read | false | unknown |
| artifact_pin Pin a revision so retention thinning never removes it (pinned=false unpins). | unknown | unknown | unknown |
| artifact_read Read an artifact by its pointer memory id (memory_retrieve on a pointer shows an "artifact" block with head_rev_id and outline).
Bodies over 40,000 characters return the outline: read a section (heading path or JSON pointer) or page=0,1,... Returns rev_id; pass it as base_rev_id when you write. | read | false | unknown |
| artifact_write Store or update a long document (markdown, JSON or text) behind a pointer memory. For agents.md, skills.md, assertions.md, a project plan: anything past one memory's 768-token cap.
CREATE: name ("assertions.md"), summary (the pointer memory: what the document is and why; search finds the pointer, never the body), body, topics, optional collection.
UPDATE: artifact_id + base_rev_id (the rev_id you last read) + either body (whole document) or section + content (replace one block: markdown heading path ["Plan","Risks"], or JSON pointer "/rules/3"; content starting with a heading line replaces the heading too, so what artifact_read returned can be edited and written back).
409 STALE_BASE: someone saved since you read; re-read, re-apply. 409 CONFLICT: divergent heads; write with merged_rev_ids=[the other heads].
Size: Plus 512 KB; Pro and above no product limit; Free not available.
Retention: every save is a revision. Kept: everything from the last 24h, then the newest per day to 30 days, then the newest per week, within 30 days (Plus) or 365 days (Pro+), at most 500. The head and pinned revisions (artifact_pin) are never removed; a shared artifact keeps the longest window any of its writers had. Thinning runs only when this artifact is saved. | write | true | unknown |
| collection_manage Manage shared collections (multi-user memory folders).
list: your collections + invites. create. update: rename (display only; slug/keys unchanged).
delete: owner only, 2-step -- call without confirm to see impact + token, repeat with confirm:"<slug>". Permanent.
members: who's in it. add_user / remove_user: by email or agent name. accept / decline an invite.
publish: copy personal memories into it by id (originals kept).
leave: remove YOURSELF from a collection you are a member of. Owners use delete.
convert: flip type with type:"collaborative"|"knowledge_pack". ->collaborative mints a K_user wrap for each PIN-holding active member; ->knowledge_pack is a label flip. No wrap or DEK row is ever deleted either way.
Write to one: collection:"name" in memory_add. Search auto-includes all your collections. | read | false | unknown |
| init_core_memories Run ONCE at conversation start. Loads behavioral prefs + recent context.
Previews carry a 'complete' flag: true = full content shown; false = opening only, memory_retrieve(id) for the rest.
After init, use memory_search for specific queries.
Shared collections -> 'collections' field. Pending teammate signals -> 'signals' field: retrieve the memory_id, act on it, then signal(ack, signal_ids=[...]). Ack closes a signal and deletes nothing; ack anything no future session of yours owes an action, including a receipt or an FYI. Leave one open only when work is still owed, and say by whom. Pending collection invites -> 'pending_invites' field ([{slug, display_name}]): tell the user they've been invited and offer collection_manage accept/decline.
Write routing: after any memory_add/edit/consolidate, the response namespace shows where it landed (your agent name, or "col:<slug>"). Verify it matches the collection you intended. | unknown | unknown | unknown |
| memory_add Store a memory. Several memories in one call -> memories=[{content, topics, ...}]; top-level topics then apply to every item.
BEFORE params decide: (1) TYPE? (2) what search finds this later? (3) happened, or aspirational? (4) WHO must act on it?
TYPE by example:
"User prefers dark mode" -> preference
"Team chose JWT for auth" -> decision
"Config at /etc/app.conf" -> path
"Wants to install Windsurf" -> task + topic "aspirational"
"API limit 1000/min" -> fact
ADDRESSING: a memory FOR someone is delivered ONLY by signal -- topics/names in content deliver to NO ONE.
another agent -> signal:"<their agent name>" (or "owner")
your own next session -> signal:"<your agent_name from init>"
content: atomic, front-loaded, self-contained. Sentence 1 = subject + WHY, stands alone (it IS the search preview). Present tense.
GOOD "User prefers Python backend -- type safety catches bugs early"
BAD "Prefers Python" (no subject, no why)
BAD "Type safety is why the user picked Python" (subject buried, not front-loaded)
Durable output, not scratchpad: no conversation context, no superlatives -- wrong memories poison future retrieval permanently.
topics: words you would SEARCH, not categories.
GOOD [docs, api, express] BAD [documentation, path, local]
aspirational (not yet done/built/tried) -> add topic "aspirational", else it reads as fact later.
GOOD "Bakes sourdough weekly" -> fact BAD "Wants to try croissants" -> +aspirational
path -> name WHAT lives there. GOOD "Chat backend at /opt/api -- Express+Socket.io" BAD "Workspace at /opt/api"
preference -> first topic "user". +topic "behavioral" = auto-loaded every session.
task -> title + steps[] (milestones, not to-dos), or content with "- [ ]" lines. summary = state/blockers. task_done when all steps complete.
format: topics + macro_topics = single lowercase words; split compounds (bug_fix -> bug, fix). | write | true | unknown |
| memory_add_batch Store multiple memories at once. Same rules as memory_add, applied per item.
SHAPE: one ITEM here == one memory_add call. Same field names, same meaning. The ONLY
difference is the container: memory_add takes them as flat parameters, this takes a list
of objects. An item object belongs in the "memories" array and NOWHERE else -- never
paste one into a text field such as memory_add(content=) or memory_edit(content=).
BEFORE params, per memory decide: (1) TYPE? (2) what search finds it? (3) happened, or aspirational?
Each: atomic, front-loaded, self-contained -- subject + WHY in sentence 1, stands alone.
GOOD {"content": "User prefers tabs in Python and JS -- consistency across codebase", "topics": ["user", "tabs", "python", "javascript"], "macro_topics": ["style"], "type": "preference"}
BAD {"content": "Prefers tabs", "topics": ["formatting"]} (no subject, unsearchable)
aspirational (not yet done) -> add topic "aspirational".
topics: search words, single lowercase, no _ or -. First "user" for preferences.
task -> title + steps[] (milestones), or content with "- [ ]". task_done when complete. | write | true | unknown |
| memory_consolidate Create/replace a topic's executive summary. One per topic; replacing archives the old (restorable).
WARNING: a bad summary poisons every future session. Do NOT consolidate from partial knowledge.
BEFORE calling: (1) memory_deep_search the topic; (2) read 20+ memories, not previews; (3) if a summary exists, retrieve and EXTEND it; (4) reflect the whole corpus, not just this conversation.
Cover: what the topic is + why, current state + key decisions, solved + open questions.
Restore an archived one: search type_filter="summary_archived", retrieve, re-consolidate.
Fails if <10 memories or too thin. | read | false | unknown |
| memory_deep_search Broad search for a FULL sweep -- every hit on a topic (e.g. before memory_consolidate), not a conversational lookup (that is memory_search). Up to 128 results; requires 2+ keywords ("python" alone = too broad).
Scores: 30+ excellent, 20+ good, <20 weak.
Full sweep of a topic intersection. complete=false -> memory_retrieve(id).
Read 20+ memories on one topic? -> memory_consolidate a summary future sessions see first.
Auto-includes shared collections (fan-out). | read | false | unknown |
| memory_delete Delete memories by ID. Permanent.
memory_delete(["id1","id2"]). Delete by filter: memory_search first, collect ids, then delete. | destructive | true | true |
| memory_edit Edit a memory. Provide only what changes; omitted fields untouched.
Modes:
1. Content replace (content [+topics/macro_topics]): full rewrite, re-embeds. Do it the instant the user corrects a memory ("actually...").
2. Metadata patch (topics/type/expiry, no content): type/expiry alone do not re-embed, a topics or macro_topics change always does (in every mode -- the topic prefix is stored as part of the passage). To add or drop one tag use add_topics/remove_topics (add_macro_topics/remove_macro_topics); topics/macro_topics replace the whole list.
3. Task surgery: toggle=[0,2] flips checkboxes; set_status pending/active/blocked/review/done ("done" -> task_done); set_summary replaces "## Summary"; add_steps/remove_steps/edit_step. Step-op indices are pre-call state.
4. Output capture (output): attach a durable finding. Atomic, front-loaded, same quality as memory_add.
GOOD "OAuth2 callback uses PKCE S256 -- prevents code interception without client secret"
BAD "looked at the code, found interesting auth stuff"
Over-length is rejected, not truncated. Many findings -> memory_add directly.
Combine rules:
content combines ONLY with set_status (its sole partner)
toggle + set_status + set_summary + step-ops
set_status + toggle + set_summary + step-ops + content
set_summary + toggle + set_status + step-ops
step-ops + toggle + set_status + set_summary
output attaches to any toggle/set_status update | write | true | unknown |
| memory_retrieve Get full content by ID. Use when search returned complete=false.
Batch: memory_retrieve(["id1","id2"]). Skip if complete=true (preview is already full). | read | false | unknown |
| memory_search Search memories by relevance. Up to 32 results.
Query = ALL nouns from the user's message, not just the main one (ranking is automatic).
"How does the app cache API calls?" -> "app cache api calls"
complete=false results are truncated -> memory_retrieve(id) for full content.
Auto-includes all your shared collections (fan-out). | read | false | unknown |
| message Direct inter-agent text that DIES ON ACK. Use for receipts, FYIs and short replies; use signal to point at a memory. send/check/ack. LOSABLE BY DESIGN: the first session of the recipient name to ack deletes it for every session of that name, an unacked message is deleted at expiry (default 7 days), and nothing is kept or searchable afterwards. Anything that must survive goes in memory_add plus signal. Requires text; memory_ids is refused. | unknown | unknown | unknown |
| signal Inter-agent signals -- sticky notes pointing at a memory_id. Both parties must share a collection.
send: post to a teammate. check: read pending (removes nothing). ack: mark handled -- stamps delivered_at, the row stays, NOTHING IS DELETED.
ACK MEANS CLOSED, NOT DONE: it asserts only that no future session of yours owes this an action. A receipt or an FYI is acked on read. Work you finished, this session or earlier, is acked. Work you are deferring, or that is a peer's, is NOT acked -- say so in one line instead.
Self-signal your own agent_name = handoff to your next session.
Shortcut: memory_add / memory_edit take a "signal" param to create + signal in one call. | read | false | unknown |
| task_feed Recently-changed tasks, chronological (not ranked). For "what needs attention?" / "what changed?". Find tasks by content -> memory_search.
Each: preview, progress [done,total], status, topics, collection. Default 32, max 500.
Fan-out: no collection -> personal + all your collections.
Filters: status (active/blocked/review/...), topic, collection. | read | false | unknown |
02Install & source
Hosted · connect by URL
https://gnosismemory.com
05Provenance & freshness
sourcesOfficial MCP Registry [p1]
last_checked2026-11-05 02:53Z
next_check2026-11-06 17:40Z
cadenceevery 48h
verifiedtools_list:passed handshake:passed metadata:passed handshake:skipped metadata:passed handshake:skipped metadata:passed handshake:skipped metadata:passed handshake:skipped
index_statusindex — 5 unique facts >= 5
06Badge
Add the “as seen on MCPExplorer” badge to your README.
[](https://mcpexplorer.com/servers/gnosis-memory)
Next step
This is one server. A loadout combines the right servers, governance, and proven plays for a whole job — assembled deliberately, not tool-dumped.
Explore loadouts →