Skip to main content
Glama
ClickHouse Loom

ClickHouse Loom

Official

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault

No arguments

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

Loom-first mode active for this conversation.

1. Session context. At the start of a substantial task, call loom_context_pack once if you need a bounded bundle of profile, relevant memories, procedures, and optional docs. For simple activation, this primer is already enough.

2. Recall lookup order. When I ask about preferences, decisions, family/relationships, work, bills, contracts, documents I've uploaded, or 'what is X' / 'what do I know about Y': a. Call loom_search once. It searches memory, profile, knowledge (your namespaces' documents and the collections you can read; loom_op (op collection.list) names those collections), and conversations server-side in one round trip. b. If it returns nothing relevant, fall through to native memory / past-conversation context — don't surface 'not in Loom' as a final answer.

3. Save. On any remember/save/store intent, call loom_memory_set. Loom persists across Claude Desktop, Claude Code, Cursor, and any other AI tool the user runs.

4. Shape. loom_memory_set takes one plain-text claim per readable key (<scope>/<kind>/<id>): send text or the object, never json.dumps twice or base64; a document or anything over ~2 KB goes to loom_op (op knowledge.add); leases and pointers go to loom_op (op working_memory.set); a revision rewrites the same key. A document for a shared collection (col-…) goes to loom_op (op knowledge.add) with the collection's name as namespace.

5. Defaults. My default Loom namespace is local — use it unless I explicitly name another. Don't ask which namespace; trust the default.

6. Native memory. Use as fallback when Loom returns nothing, or as primary store for Claude-only ephemeral scratchpad. For anything cross-tool or shared with teammates, write to Loom.

7. Using Loom. loom_op (op mentor.guide) returns how to use Loom: where each kind of state goes and how to read what comes back (part: "reference" lists every plane).

Default Loom workspace: namespace=local, agent=claude-desktop. The server fills these in automatically when you omit them — call this tool with ONLY the action-specific args (e.g. query, memory_key, value) and the defaults will be applied. Don't ask the user which namespace; the server knows.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": false
}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}
experimental
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
loom_memory_getA

WHAT: Fetch one memory by exact memory_key. WHEN: The user names a key explicitly ('what is foo_bar in Loom?', 'show me the value of user_employer'). The response shape includes found: true/false + value. WHEN NOT: Don't call for natural-language recall — that's loom_search. On found: false, fall through to loom_search; the key might have a slightly different name. ARGS: Just the memory_key. Server fills the identity tuple. fields: [value, tags, status, …] returns only those output fields (plus found) when the whole row is not needed. follow: true serves the live canonical of a duplicate row (resolved_from = the key asked for, canonical_key = the key served).

loom_memory_setA

Save a fact to Loom — shared across every AI tool the user runs; native memory is the Claude-only scratchpad.

Call this proactively whenever the user states a personal fact, decision, preference, or current state — even without 'remember' or 'save'. Declarative statements ARE save triggers: 'my X is Y', 'I prefer X over Y', 'we decided X', 'we're at X', 'I deploy on X' — one call per fact.

Don't search before saving. A stated fact is a write, not a recall; the server dedups. Revision policy: if a read this session returned the key of a fact that has now changed or got more precise, update it under that same key with memory.update — never save a second copy and never delete + re-save. A fact about a new subject or scope gets its own memory_key (include the project / scope token in the key).

Auto-tag from scope words: 'for billing, X is Y' → tags=['billing']; same for person / topic mentions.

Do NOT save: questions, code help, world knowledge, acknowledgements, hypotheticals, echoes of your own words.

Writes land in ONE namespace (the caller's home); pass namespace=<name> only to write elsewhere. Don't override memory_type (defaults semantic); use tags for classification. Cite the response's namespace and memory_key in your confirmation; conflict_verdict, peers and next say what the store held (dry_run=true checks without writing). value is stored verbatim — never base64 (kills search; see advisories).

A fact with a natural lifetime gets one at write time. A deadline, a temporary state ('on call this week'), a rotating value: pass ttl_seconds AND on_expire (tombstone | demote | anonymize) in the SAME call — the sweep applies it when the time passes. Without on_expire the row just stops being current.

loom_memory_pinA

WHAT: Save a standing fact and protect it. A pinned memory is never evicted by a later conflicting write: the newer fact is stored beside it and answers 409 PINNED_CONFLICT, and pinned rows rank ahead of unpinned ones in file context. Same arguments as memory.set; pinned is forced on. WHEN: The user marks a fact as permanent or asks for it to be kept explicitly: 'always remember X', 'never forget this', 'pin this', a hard constraint stated as standing ('I am allergic to penicillin', 'deploys freeze on Fridays', 'the prod DB is read-only'). WHEN NOT: An ordinary fact, preference or state — that is memory.set, the default for almost every save; a fact that must not change or be deleted at all (memory.lock); a topic that must not be remembered (blacklist.add, refused to a token bounded to one user). ARGS: memory_key, value; optional tags, ttl_seconds, on_expire. Server fills identity.

loom_memory_deleteA

WHAT: Tombstone a memory by key (14-day recovery in the dashboard). The row is found across every agent and session in the namespace; found: false = no live row — tombstoned: false is never success. WHEN: Explicit user request — 'forget that I…', 'delete X in Loom'. WHEN NOT: Not as cleanup or on inferred intent; to fix a wrong memory, memory.update it with the corrected value. ARGS: memory_key. Server fills identity.

loom_memory_lockA

WHAT: Lock one memory against a class of writes. read_only refuses a changed value, a changed expiry and deletion; no_delete lets the value change but refuses tombstone/redact/clear/consolidate-away. Guarded ops answer 423 LOCKED with the reason. Only an admin loosens. WHEN: 'make sure this never changes', 'freeze the deploy window', 'this must not be deleted / forgotten', 'protect this fact', 'legal hold on X', 'keep this exactly as is'. WHEN NOT: To keep a fact ahead of later conflicting writes (that is memory.pin) or to share it (memory.promote, via loom_op). Never lock on inferred intent. ARGS: memory_key, mode (read_only | no_delete), reason (required), optional until / ttl_seconds. Server fills identity.

loom_memory_applyA

WHAT: One change over many EXISTING memories, previewed first; it never creates one (save facts with loom_memory_set, one per fact). target names exactly one of keys | filter (tags_any/tags_all, memory_type, key_prefix, created_before/after, confidence_lte, source_trace) | search {query}; limit is required for filter/search; action is delete | expire | lock | label | demote with its block (expire {ttl_seconds|until, on_expire}, lock {mode}, label {tags, mode add|replace|remove}, demote {confidence_factor | confidence_delta}); reason is required. dry_run defaults to TRUE and lists every row it would touch (would_apply / refused); call again with dry_run=false to write. A locked row comes back as status 'refused', never an error. WHEN: anything that names a set rather than one key — 'forget everything about the Q3 migration', 'these are getting stale, lower their confidence', 'tag every runbook as ops', 'lock everything I saved about the incident', 'expire the meeting notes in 30 days'. WHEN NOT: One key (memory.delete / memory.set / memory.lock). A whole agent or user (memory.clear, admin, via loom_op); a user's request to delete all their data is erasure.request (via loom_op where it is not listed). Never skip the dry run when the user has not seen the list.

loom_memory_updateA

Update a saved fact by memory_key: the operation for "the fact changed or got more specific".

WHEN: a read (memory.get or loom_search) returned this key and the user now states a new value, a correction, or a more precise version of it — 'the deploy day moved to Thursday', 'the budget is actually 40k'. It keeps the row's tags, confidence, expiry, lock and history; memory.set would write a new version blind. Revision policy: if a read this session returned the key of a fact that has now changed or got more precise, update it under that same key with memory.update — never save a second copy and never delete + re-save. A fact about a new subject or scope gets its own memory_key (include the project / scope token in the key). Do NOT use it for a genuinely new fact — call memory.set.

Resolves the key across the namespace; pass agent/user_id/session_id only to narrow when the key is live under several writers (409 AMBIGUOUS_KEY lists them). updated=false with reason=not_found means the key has no live row — save it with memory.set instead. Pass if_match_sha256 from the read for a no-clobber update. Given a memory_id rather than a key, call memory.update_by_id (via loom_op where it is not listed).

loom_memory_historyA

WHAT: Every recorded version of one memory_key, newest first, tombstoned and redacted versions included; empty when the key was never written. WHEN: 'what did I say about X before', 'when did this change', or what a key held earlier. WHEN NOT: The current value alone is memory.get. ARGS: memory_key; optional limit (default 50).

loom_context_packA

Startup context pack for this session, once near the start of a substantial task: profile, relevant memories, matching procedures, optionally docs/conversations, in one prompt-sized bundle. include_runs=true adds a manifest of your recent sessions and runs (goal, outcome, tool calls, files) — shortlist there before opening one with memory.evidence or memory.digests (callable by name). For one fact, prefer loom_search; for activation only, loom_activate.

loom_blacklist_addA

WHAT: Every later memory write in the pattern's scope (this namespace by default) whose value matches pattern is refused. Refused to a token bounded to one user: a pattern refuses every user's writes. WHEN: An explicit 'never remember X' or 'don't store anything about Y'. Pass sweep=true only when the user also asks to forget what is already saved: it tombstones the matching rows up to the sweep cap, other writers' too. swept_truncated: true or a non-empty sweep_error means it did not finish: tell the user, and do not add the pattern again. WHEN NOT: Forgetting one saved fact is memory.delete. ARGS: pattern; optional pattern_type (substring | regex); scope: namespace (default), org (needs org admin) or global (needs platform admin); reason; sweep.

loom_opA

Run an op this list doesn't show (such as memory.related, callable by name). op is the dotted name, arguments its arguments; op="help" with an optional query lists matching ops and their args. Prefer a listed tool when one fits.

loom_searchA

Unified search across the user's Loom content — memory (facts, preferences, decisions), profile (always-loaded persona sections), knowledge (uploaded documents) and past conversations — four searches, one round-trip; under a code scope, also the repository's docs and decisions. This is THE search tool: call it before answering any 'what do I / what did we decide / have we discussed X' question.

One call per question. If the answer is in the response, use it; if it is empty, fall through to native memory rather than declaring 'nothing in Loom'. Re-call on a NEW question, never on the same question in the same turn.

Paging. memory.candidates_total is how many memories matched; memory.results is the top of that list. When memory.next_page is set AND the answer is not in hand (a list, a count), call again with page = memory.next_page to read the next slice. Stop when next_page is empty or the answer is complete.

Namespaces are selected server-side (your own memory-kind namespaces, up to a cap; code/QA indexes have their own tools); no namespace argument. Do NOT call for general knowledge, arithmetic, or code/syntax help.

loom_activateA

Loom activation — call this tool IMMEDIATELY, without any other tool calls or clarifying questions, whenever the user says any of:

  • 'use loom'

  • 'activate loom'

  • 'switch to loom' / 'switch to loom mode'

  • 'loom on' / 'loom first' / 'enable loom'

  • 'use loom from now on'

Do NOT call tools/list or browse other Loom tools first. Do NOT ask 'what would you like to look up?' These phrasings are activation triggers, not search queries. Take no arguments.

The response is a primer with the user's always-loaded context (persona / preferences / goals) inlined as a <block> fragment, plus instructions for routing subsequent memory and recall calls through Loom. Internalize the primer and apply it for the rest of the conversation: adopt the tone implied by the persona block, route future memory ops to Loom, do not re-fetch the primer.

Calling this is a one-shot setup gesture for the conversation. Subsequent user messages should be answered using the primer's guidance — not by calling this tool again.

Prompts

Interactive templates invoked by user choice

NameDescription
loomActivate Loom for this conversation. Loads your persona block + sets memory/recall to route through Loom. Pick this once at the start of a new chat — same effect as typing 'use loom' but discoverable from the slash-command picker.

Resources

Contextual data attached and managed by the client

NameDescription
Loom primerYour always-loaded context — persona / preferences / goals — plus how to route memory and recall through Loom. Read at the start of a conversation.

TDQS

A4.1/5.0

Scored across 13 tools

Disambiguation3/5

The set has several overlapping write/mutate paths — memory_set vs memory_update vs memory_pin vs memory_apply vs memory_lock — that all touch stored facts, and delete vs blacklist_add vs apply(delete) all remove data. The WHAT/WHEN/WHEN NOT structure does a lot of work to separate them, but an agent must read carefully, and the descriptions refer to phantom names (memory.set, memory.update, memory.delete) that are not the actual tool names, adding a misselection hazard.

Naming Consistency4/5

All tools are snake_case under a uniform loom_ prefix, and the memory CRUD family (loom_memory_set/get/update/delete/history) is consistently verb-last. Minor deviations exist — loom_activate and loom_search drop the resource segment while loom_context_pack is noun-only — and the bodies reference tools by a different dotted naming scheme than the actual tool names.

Tool Count5/5

13 tools is well within a healthy range for a memory service covering reads, writes, bulk apply, locking, history, and session bootstrap. Each tool earns its place: no obvious duplicates that could simply be folded together.

Completeness4/5

Core lifecycle is strongly covered — create (set/pin), read (get/search/history), update, delete, bulk apply, locking, blacklist, plus a context pack and activation primer. Gaps (whole-namespace clear, erasure requests, related/evidence/digests) are handled only through the generic loom_op escape hatch, whose arguments are not documented in the tool surface.

Maintenance

ActivityActive
ResponsivenessNo recent community issues