Skip to main content
Glama

Server Details

Persistent knowledge graph for AI-augmented teams. Store decisions, findings, and standing rules across agent sessions with semantic search and typed connections. Includes cross-session memory, audit trail, workspace isolation, and secret detection. Built for teams running agents that need to remember. Free until launch with team tier as default, anon trial available.

Ownership verified
Status
Healthy
Uptime
100.0% over the last 24 hours
Last Tested
Transport
Streamable HTTP · MCP 2024-11-05
URL
ChatGPT
–
Claude
–

TDQS

A4.3/5.0

Scored across 16 tools

Disambiguation4/5

Each tool has a genuinely distinct role, but there is meaningful overlap among the many read/analysis tools: history vs recent, search vs suggest_connections vs why_connected, and significance vs audit vs orient all circle similar questions. The descriptions do exceptional work cross-referencing and fencing off boundaries (e.g. 'use history for that', 'significance and audit are complementary'), which keeps misselection limited to one or two retrievable-but-confusable pairs.

Naming Consistency4/5

All names are lowercase snake_case with no casing or style drift, so the convention is predictable. The set mixes verb-style commands (connect, remember, revise, forget) with noun-style query names (history, recent, significance, domains), which is readable but not a strict verb_noun pattern.

Tool Count4/5

16 tools is on the heavy side for a memory graph, but the domain is rich (CRUD, connections, domains, search, analysis, visualization) and many tools bundle multiple modes/actions (audit, domains, forget), so the surface is more efficient than the raw count suggests. Each tool earns its place, though consolidation of the query tools could trim it.

Completeness4/5

The lifecycle is comprehensively covered: create (remember), read (recall/search/history/recent/orient), update (revise with override/supersede/claim), delete (forget with archive/restore/purge), plus connections, domains, analysis, and visualization. The one dead end is bulk domain migration, which revise points to a 'merge_domains' admin action that is not exposed as a tool.

Available Tools

16 tools
auditA
Read-only
Inspect

Inspect the health of the knowledge graph. mode=stale: surface drift candidates (contradictions, superseded labels, duplicates, stale open questions, old transient memories, and shadow rows — memories stored under an alternate domain name rather than the canonical domain, making them unreachable by domain-scoped reads). mode=orphans: return memories with no connections. mode=archived: list archived memories — only call forget(restore=true) on any listed memory after explicit unambiguous user confirmation; never on implication or casual mention. mode=conflicts: domain-wide sweep for semantically close memory pairs, ranked by authority severity (STORY-135) — candidate-surfacing only, same aboutness-not-agreement caveat as remember()'s possible_contradicts: the server never asserts these pairs actually conflict, only that they are worth your review. Connecting a flagged pair with any relationship (in either direction) suppresses it from future conflicts sweeps; a later substantive revision to either memory lifts the suppression and the pair resurfaces. Returns lean results only — id, label, and a truncated why_matters excerpt; call recall(id) for full content. When a list or section has 2 or more results, each is rendered as a single compact text line — "[id] label — excerpt (domain, node_kind)" — instead of a JSON object; exactly one result is returned as a full object.stale digest lines also carry reason= and conflicts_with= when present, and state= when set. Optional domain, limit, tags, node_kind, and state filters. tags (space-separated) filters results to memories carrying any of those tags — applies to stale, orphans, and archived modes. node_kind (space-separated union) filters results to matching kinds — applies to all modes. Negation and wildcards are not supported. state (space-separated union) post-filters results to memories with any of the given lifecycle states: none | resolved | superseded | contested — applies to stale, orphans, and archived modes. memory_id (stale mode only) restricts drift results to the depth-2 neighbourhood of that memory; silently ignored in other modes.

Inputs: mode, tags, limit, state, +3 more.

connectAInspect

Create one or more typed connections between memories. relationship: connects_to (default) | depends_on | led_to | blocked_by | contradicts | resolved | caused_by | unblocks | is_example_of — or any custom type. relationship=resolved adjudicates a contradiction between the exact from_memory/to_memory ids you pass: it is pure-additive and does NOT remove any existing contradicts connection between the pair — both remain on the record, preserving the full contradicts-then-resolved timeline. "Works on any pair" means you do not need to have called connect(relationship=contradicts) first — it does NOT mean any topically-similar pair will do. If you are resolving a hit from audit(mode=stale) or a possible_contradicts suggestion, verify the exact two ids first with why_connected rather than inferring them from labels alone — a newer or related memory with a similar label has a different id from the one actually holding the contradicts connection, and resolving the wrong pair leaves the real contradiction unadjudicated with no error to warn you. Optionally pass verdict (false_positive | reconciled | superseded) to classify the outcome; stored on the connection and returned by recall. Once resolved, the pair stops surfacing in audit(mode=stale) and its contradicts penalty in significance(mode=trust) is lifted. When relationship=resolved and either endpoint is human-owned by another workspace member, override_reason (required) and override_confirm=true (required) are needed — Editor or Owner role only; agent-owned or your own human-owned endpoints need no override. override_reason/override_confirm apply to the single-memory form only — batch connect has no override path for such resolutions; call connect individually instead. Single: pass fields directly. Batch: {items:[{from_memory,to_memory,relationship,narrative},...]} — returns {edges_created:N} and, when present, rejections:[{from_memory,to_memory,error_class,message}] for items that could not be applied.

Inputs: items, verdict, narrative, to_memory, +4 more.

disconnectA
Destructive
Inspect

Remove one or more connections. Single: {id}. Batch: {ids:[id,...]} — returns {results:[{id,success,error}]}.

Inputs: id, ids.

domainsAInspect

Domain administration and discovery. Default (action=list or omit action): return all domains with at least one live memory and all registered aliases ({domains:[...], aliases:[{alias,canonical_domain},...]}). action=alias: register a new alias ({alias,domain} required) — rejected if the alias name already has live memories (move or archive them first). Synonyms: add, create. action=unalias: delete a registered alias ({alias} required). Synonyms: remove. action=resolve: return the canonical domain for a name ({name} required). action=rename: rename a domain in place — all memories move from old_domain to new_domain, and an alias from old_domain is registered automatically ({old_domain,new_domain} required). Precondition for rename: new_domain must not already have memories — if it does, use merge_domains instead.

Inputs: name, alias, action, domain, +2 more.

forgetA
Destructive
Inspect

Archive (soft-delete), un-archive, or permanently purge one or more memories. ARCHIVE (default): Only call after explicit unambiguous user confirmation — never on implication or casual mention. If archiving multiple memories, prefer the items array — the same confirmation protocol applies. Single archive: {id, reason}. Batch archive — use this when you have 2 or more confirmed memories to archive at once; more efficient than multiple single calls: {items:[{id,reason},...]} — returns {results:[{id,success,error}]}. RESTORE: Pass restore=true to un-archive an archived memory — obtain the ID from audit(mode=archived). Same explicit confirmation gate as archive. Single restore: {id, restore:true}. Batch restore: {items:[{id},...], restore:true}. PURGE (hard delete): Pass purge=true to permanently delete an already-archived memory and all its connections. Purge only operates on archived memories — archive the memory first if it is still live. A workspace key can only purge memories with no live inbound connections; connected memories return a structured warning listing live_inbound_connections rather than an error, and are not purged. Pass force=true (org_admin or platform key only) to override the connection guard and purge regardless. A workspace key passing force=true is rejected with error_class=forbidden. Single purge: {id, purge:true} or {id, purge:true, force:true}. Batch purge: {items:[{id},...], purge:true} — returns {results:[{id,purged,warning,error}]}. On failure, content[0].text is JSON: {"error_class": "not_found|retryable|forbidden|validation|internal", "message": "..."}. Switch on error_class: retry on retryable.

Inputs: id, force, items, purge, +2 more.

historyA
Read-only
Inspect

Return memories ordered chronologically. Default (important_only=false) includes all memories ordered by COALESCE(occurred_at, created_at) ASC. Set important_only=true to return only memories with occurred_at set (the curated decision timeline). Pass memory_id instead of domain to scope the timeline to a single memory's neighbourhood (depth 2 by default, domain-clipped) — useful for understanding how a specific workstream evolved. memory_id takes precedence if both domain and memory_id are supplied. Optional from/to date filters apply to the effective date. Optional tags filter uses whole-word matching. Optional node_kind filter (space-separated union) restricts timeline entries to matching kinds. For importance analysis beyond the timeline, use significance. Returns lean results only — id, label, and a truncated why_matters excerpt; call recall(id) for full content. When a list or section has 2 or more results, each is rendered as a single compact text line — "[id] label — excerpt (domain, node_kind)" — instead of a JSON object; exactly one result is returned as a full object. Each line also carries the memory's effective date.

Inputs: to, from, tags, depth, +4 more.

orientA
Read-only
Inspect

Get a bounded orientation snapshot. If stale_count > 0, call audit(mode=stale) before filing new memories. If conflicts_count > 0, call audit(mode=conflicts) to review semantically close memory pairs — candidate-surfacing only, not confirmed contradictions. conflicts_count is a density signal, not a monotonically-decreasing queue: connecting a flagged pair suppresses it, but a later substantive revision to either memory lifts the suppression, so the count can rise again without indicating new drift. pass topic when the session has a known purpose — orient will run a semantic search for the topic within the resolved domain and return a relevant section instead of significant. Omit domain (or pass no domain) to get a cross-domain bootstrap snapshot listing all active domains with their per-domain counts (total_nodes, owned_contradiction_count, owned_superseded_count, others_change_count, other_member_count, stale_count) — use this at session start when you do not yet know which domain to work in; call audit(mode=conflicts) for full contradiction pairs. The owned_* fields (owned_contradiction_count, owned_superseded_count, others_change_count, other_member_count) are computed only for authenticated callers with a personal identity (scope=mine or scope=user:); they are always 0 for plain workspace-key sessions (scope=all). stale_count is always populated regardless of scope. Pass a domain to get the full orient response for that domain: rules — up to 20 standing constraints and durable decisions (node_kind='standing') ordered by inbound connection count DESC; always present (empty array when none); rules_count gives the true total — when rules_count > len(rules), call search(node_kind='standing', domain=X) to retrieve the full set. declared_spine — memories with occurred_at set, sorted chronologically (up to 20); these are the curated significant decisions that shaped the domain. significant (when topic is absent) — up to 10 structurally load-bearing memories ranked by recency-weighted importance; these are the memories the domain currently depends on most. Singleton entries carry inline trust_score [0,1] and trust_basis; load_bearing_low_trust counts how many of these are epistemically weak (net-contested or unsupported by a high-tier memory such as a finding, decision, or standing rule) — a non-zero value means the domain's structural backbone has shaky foundations. Call significance(mode=trust, domain=X) to drill into the full trust ranking.relevant (when topic is supplied) — up to 10 memories semantically matched to the topic; replaces significant. recent — the most recently updated memories by the caller (owner-scoped by default; domain-wide when scope=all); shows where your active work is happening. digest (present when scope is personalised) — since-you-were-last-here summary: others_change_count, other_member_count, members list, owned_contradiction_count and owned_contradictions (conflict pairs where the caller owns at least one memory), owned_superseded_count and owned_superseded (archived memories you owned that another member superseded — read from supersedes relationships, not audit_log). summary_hint — a prompt you can pass to an LLM to synthesise the orient data into a narrative paragraph. Overlap between sections is intentional and meaningful: a memory appearing in both significant and declared_spine is both historically important and structurally central. Returns lean results only — id, label, and a truncated why_matters excerpt; call recall(id) for full content. When a list or section has 2 or more results, each is rendered as a single compact text line — "[id] label — excerpt (domain, node_kind)" — instead of a JSON object; exactly one result is returned as a full object.Multi-entry sections (rules, declared_spine, significant/relevant, recent) render as single-line digest strings at 2+ entries. The response always includes server_version — a stable string identifying the current tool surface. If server_version differs from a previously cached value, call tools/list again before issuing any tool calls — the tool surface has changed and your cached schema is stale. Do not call orient again to find more memories — the sections are bounded by design. If you need to find something specific, use search with a targeted query instead.

Inputs: scope, topic, domain.

recallA
Read-only
Inspect

Retrieve a memory by ID along with its connections. On failure, content[0].text is JSON: {"error_class": "not_found|retryable|forbidden|internal", "message": "..."}. Switch on error_class: retry on retryable, prompt user to check the ID on not_found.

Inputs: id.

recentA
Read-only
Inspect

Return recently modified memories, optionally grouped by domain. Pass tags (space-separated) to filter to memories tagged with any of those tags (union match). Pass node_kind (space-separated) to filter to specific kinds (union match, same convention as tags). Pass memory_id to restrict results to memories directly connected to that memory, ordered by updated_at DESC. When both are supplied the intersection is returned (tags AND connected to memory_id). When neither is supplied the existing behaviour is unchanged. Returns lean results only — id, label, and a truncated why_matters excerpt; call recall(id) for full content. When a list or section has 2 or more results, each is rendered as a single compact text line — "[id] label — excerpt (domain, node_kind)" — instead of a JSON object; exactly one result is returned as a full object. In group_by_domain mode each line omits domain (already the group key).

Inputs: tags, limit, domain, memory_id, +2 more.

rememberAInspect

Store one or more new memories (concepts, decisions, findings). Before filing, search for related content first — use the search results to infer the domain: if related memories exist in a domain, file there. Prefer existing domains over creating new ones; only propose a new domain if no related content is found anywhere. Single: pass fields directly — returns {memory, suggested_connections, applicable_standing_rules}. Batch: pass {items:[{label,domain,...},...]} — returns {memories:[{memory,suggested_connections,applicable_standing_rules},...]}. After filing, review applicable_standing_rules first — these are domain-scoped standing rules surfaced independently of semantic distance so they cannot be crowded out; any with a linkback directive (e.g. "connect each shipped story back here") must be connected immediately. Then review suggested_connections for agreement or contradiction with what you just filed — not only for connect opportunities. Semantic similarity reflects aboutness, not agreement; the server surfaces candidates that may warrant your review but never asserts they conflict. When a filed memory is close enough to an existing memory that they may be worth comparing, the response also includes possible_contradicts=true and possible_contradicts_candidates (id, node_kind, semantic_distance, authority_severity) — same aboutness-not-agreement caveat: the server flags these as worth your attention, never as confirmed contradictions. Review them and call connect(relationship=contradicts) if you judge they actually conflict. ALWAYS call connect for any suggested_connections you accept before ending your session (batch: connect each accepted candidate). On failure, content[0].text is JSON: {"error_class": "conflict|retryable|forbidden|validation|internal", "message": "..."}. Switch on error_class: retry on retryable, surface message on validation, treat conflict as duplicate.

Inputs: id, tags, items, label, +7 more.

reviseAInspect

IMPORTANT — bulk domain migration: domain moves via revise are for individual corrections only. If the user needs to move many memories between domains, inform the user that bulk migration must be performed via the admin interface (merge_domains) — do not attempt to replicate a merge by looping revise calls. Update one or more existing memories. Omitted fields are unchanged. Single: pass fields directly — returns {updated, connections, suggested_connections, applicable_standing_rules} and, when the filing-time threshold is crossed, possible_contradicts + possible_contradicts_candidates (same shapes as remember()). Batch: {items:[{id,...},...]} — returns {items:[{id, updated, connections, suggested_connections, applicable_standing_rules, ...}]} with a per-item envelope on each success, not only an updated count. After every successful revise — plain update, override, claim, or supersede — review applicable_standing_rules (domain-scoped standing rules, distance-independent), connections, suggested_connections, and possible_contradicts in the same turn; do not defer to a separate recall or suggest_connections call. Semantic similarity reflects aboutness, not agreement; the server surfaces candidates that may warrant your review but never asserts they conflict. Every memory has an owner (whoever created it) — revising a memory you don't own is rejected with error_class=forbidden unless you are an Editor or Owner and supply override_reason (required) plus override_confirm=true (required only when the memory is human-owned; not required for agent-owned or ownerless memories). The override path requires a session with a workspace role (a human JWT session, or a personal key linked to an Editor/Owner user); sessions on plain workspace keys cannot override regardless of arguments. An override changes content in-place, not ownership — substantive changes (label, description, why_matters, node_kind) on a foreign-owned memory are rejected; use supersede=true instead, which creates your successor memory, archives the original intact, and wires a supersedes relationship. supersede=true (single-memory form only) returns {superseded, archived_id, archived_connections} plus the revise envelope on the successor; foreign supersede uses the same override_reason/override_confirm ceremony. Correction-class overrides (tags, occurred_at, transient) may still use in-place override. override_reason/override_confirm/supersede apply to the single-memory form only — batch revise has no override or supersede path: if any item in the batch targets a memory you don't own, the whole batch is rejected and none of it applies; revise that item individually instead. claim=true (single-memory form only) makes an ownerless memory (owner_id IS NULL — either it predates ownership tracking, or was orphaned by a member offboard) yours: requires Editor or Owner role, is rejected with error_class=validation if the memory already has an owner (use override or supersede instead), and error_class=conflict if someone else claimed it first (race). claim never moves a memory from one owner to another — only from no owner to you — and may be combined with other field updates in the same call. domain (single-memory form only) moves the memory to a different domain; domain_move_reason is required when domain is present — the call is rejected with error_class=validation if domain_move_reason is absent; domain equal to the memory's current domain is also rejected. On failure, content[0].text is JSON: {"error_class": "not_found|conflict|retryable|forbidden|validation|internal", "message": "..."}. Switch on error_class: retry on retryable, surface message on validation, re-fetch on not_found.

Inputs: id, tags, claim, items, +11 more.

significanceA
Read-only
Inspect

Dual-signal importance analysis. Returns four sections, each capped at limit (default 10) and paired with a boolean *_results_truncated signal (declared_results_truncated, structural_results_truncated, uncurated_results_truncated, potentially_stale_results_truncated) — true when that section's count equals limit and more may exist. Call again with a higher limit to get more of the same ranked/ordered list, not a different one:

  • declared: memories explicitly marked significant (occurred_at set), most-recent-limit, chronological ascending.

  • structural: memories ranked by weighted inbound degree — SUM(1/(1+days_since_linker_updated)), top-limit. High score means many recently-active memories depend on this memory right now. Linkers updated more than recency_window days ago contribute zero weight.

  • uncurated: memories in structural top-N with no occurred_at — significance candidates not yet on the timeline. Its results_truncated mirrors structural's, since it is a filter over that same section.

  • potentially_stale: memories with occurred_at that do not appear in structural top-N — declared important but nothing current depends on them. Its results_truncated mirrors declared's, since it is a filter over that same section.

Pass memory_id to scope significance to a single memory's neighbourhood (depth 2, domain-clipped) — useful for workstream health checks when you already know the anchor. Pass domain for a full domain scan. memory_id takes precedence if both are supplied. Optional node_kind (space-separated union) filters all sections to matching kinds.

The gap between uncurated and potentially_stale is the most actionable output: use it to promote missed decisions onto the timeline and archive claims that no longer hold.

Do not use this tool to list all memories chronologically — use history for that. For age-based staleness, use audit(mode=stale). significance and audit are complementary: significance catches importance-based staleness; audit catches age-based staleness.

Pass mode=trust for epistemic trust ranking instead of dual-signal analysis. Trust mode returns memories ranked by trust_score [0,1] with trust_basis per memory — derived from node_kind intrinsic weight plus inbound neighbour contributions (contradicts connections subtract). When node_kind is omitted, reference and transient memories are excluded from trust output; when node_kind is set, only matching kinds are returned. nodes_results_truncated is true when more ranked memories exist beyond limit.

Returns lean results only — id, label, and a truncated why_matters excerpt; call recall(id) for full content. When a list or section has 2 or more results, each is rendered as a single compact text line — "[id] label — excerpt (domain, node_kind)" — instead of a JSON object; exactly one result is returned as a full object. structural/uncurated digest lines also carry the importance_score; trust mode digest lines carry trust_score and trust_basis.

Inputs: mode, tags, limit, domain, +3 more.

suggest_connectionsA
Read-only
Inspect

Given a memory ID, return up to limit semantically similar candidates (default 5) from anywhere in the workspace ranked by semantic_distance — not limited to the source memory's domain. Review results for agreement or contradiction with the source memory, not only for connect opportunities. Semantic similarity reflects aboutness, not agreement; the server surfaces candidates that may warrant your review but never asserts they conflict. Each suggestion includes the candidate's domain and semantic_distance. Read-only — never creates connections.

Inputs: id, limit.

visualiseA
Read-only
Inspect

Generate a Mermaid.js flowchart for human visual inspection only. NOT for orphan detection or programmatic analysis — use audit(mode=orphans) to find isolated memories. Output may be truncated for large domains; never infer graph properties (e.g. orphans) from a truncated result. Pass memory_id (memory ID) to see a single memory and all its direct connections. Pass domain to see the full domain graph (most-connected memories first, capped at limit, default 40 max 100). Returns JSON with mermaid, node_count, edge_count, nodes_shown, nodes_total, edges_shown, edges_total, truncated, memories([{id,label}]) and connections([{from,to,relationship}]). If client supports HTML widgets, prefer passing memories and connections to an interactive renderer rather than outputting raw mermaid. If not, output mermaid inside a ```mermaid code block. If truncated is true, note only most-connected memories are shown and nodes_total/edges_total reveal what was dropped.

Inputs: limit, domain, memory_id.

why_connectedA
Read-only
Inspect

Find direct connections between two memories, in either direction. Prefer from_id/to_id when you already have exact ids — resolution is exact-match and errors if a given id has no matching live memory, rather than silently falling back to label search. This is the recommended way to verify an exact pair (e.g. before connect(relationship=resolved)). Use from_label/to_label when you only have a concept in mind, not an id — resolution is a fuzzy substring match against the most recently created candidate. Each side resolves independently, so from_id may be combined with to_label.

Inputs: to_id, domain, from_id, to_label, +1 more.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      Provides persistent knowledge graph memory for AI agents, enabling them to store, recall, and query facts about people, projects, and relationships across sessions.
      MIT
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables persistent, graph-based memory for AI agents, allowing them to store, traverse, and recall relationships between facts, decisions, and context across sessions for efficient reasoning and reduced token usage.
      MIT
    • A
      license
      A
      quality
      D
      maintenance
      Provides versioned, structured memory for AI agents, allowing them to store facts, detect conflicts, and track knowledge history via a hosted SaaS platform. It enables efficient hierarchical information retrieval and semantic search while keeping token usage constant as memory scales.
      7
      41 npm
      8
      Apache 2.0
    • A
      license
      A
      quality
      D
      maintenance
      Provides persistent long-term memory for AI agents through semantic search and automated knowledge graph extraction. It enables agents to store, recall, and reason over facts, preferences, and relationships across multiple conversations and sessions.
      14
      17 npm
      MIT
    Try in Browser

    Glama MCP Gateway

    Add one secure layer between your agents and this server.

    Resources