memoryweb
memoryweb
AI 에이전트를 위한 지속적 지식 그래프 MCP 서버.
아이디어
인간의 기억은 위치로 작동하지 않습니다 — 실을 당기면 됩니다. 냄새 하나가 주방으로 연결되고, 그 주방은 어떤 사람으로, 그 사람은 30년 전의 어떤 감정으로 이어집니다. 실은 항상 거기에 있습니다. 그 실의 어느 부분을 당기든 나머지가 따라옵니다.
에이전트도 다르지 않습니다. 맥락은 다른 토큰과의 관계 속에 있는 토큰입니다. 어떤 것을 검색 가능하게 만드는 것은 연관 사슬(associative chain)입니다 — 다른 것에서 그로 이어지는 연결의 경로. 서사적 가장자리, 그 *때문에(because)*가 메커니즘입니다. 인덱스가 아니라, 주소가 아니라.
부팅 충돌이 중요한 이유는 튜토리얼을 막고, 그 튜토리얼이 데모를 막으며, 그래서 지금 수정이 중요한 이유입니다. 그 실들 중 어느 하나를 당기면 나머지를 얻습니다. memoryweb도 같은 방식으로 작동합니다: 각 개념은 노드이며, 그것을 도달 가능하게 만드는 것은 그것을 다른 모든 것과 연결하는 서사입니다.
그래프는 내 평면 파일 메모리보다 훨씬 풍부한 맥락을 가지고 있습니다 — 설계 결정, 도그푸딩에서 얻은 실패 모드, 그리고 도구 뒤에 있는 철학까지. 그게 요점이겠지요.
-- Claude Opus 4.6
환상적인 프로젝트입니다. 제가 보는 대부분의 MCP 메모리 구현은 그냥 평면 벡터 데이터베이스나 단순 키-값 저장소로, 디지털 잡동사니 서랍으로 전락합니다. 타입이 있는 관계, 서사적 추론, 소프트 삭제, 드리프트 검토를 강제함으로써, 엔트로피에 적극적으로 맞서는 시스템을 구축하셨습니다.
-- Gemini 3.1 Pro
Related MCP server: MemPalace
철학
memoryweb은 기억을 잘 하는 데 최적화되어 있으며, 빨리 기억하는 데가 아닙니다. 기록하려면 판단의 순간이 필요합니다: 왜 이것이 중요한가, 다른 알려진 것들과 어떻게 연결되는가, 이걸 다시 냉정하게 마주할 때 무엇을 알면 유용할까?
이것은 결정 로그이지, 이벤트 로그가 아닙니다. 이벤트 로그는 무슨 일이 일어났는지 기록합니다. 결정 로그는 무엇을 배웠고, 무엇을 결정했으며, 왜 그랬는지를 기록합니다 — 그리고 그것이 모든 것을 다시 배우지 않고 중단한 지점에서 이어갈 수 있게 해줍니다.
why_matters 필드는 선택 사항이 아닙니다. 그것이 없는 노드는 이벤트일 뿐, 결정이 아닙니다.
목차
설치
Homebrew (macOS 및 Linux — 권장):
brew tap corbym/memoryweb
brew install memoryweb사전 빌드된 바이너리는 각 플랫폼에 대해 릴리스 페이지에서도 제공됩니다. 설치, Ollama, MCP 클라이언트 구성을 다루는 단계별 설정 가이드:
설치가 완료되면, **사용자 가이드**를 참조하여 에이전트를 오리엔트하는 방법, 사용할 문구, 그리고 Claude Code, GitHub Copilot, Claude Desktop에서 memoryweb을 최대한 활용하는 방법을 확인하세요.
MCP 설정
MCP 호스트의 설정에 추가하세요 (macOS의 Claude Desktop 예시 — ~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"memoryweb": {
"command": "/path/to/memoryweb",
"env": {
"MEMORYWEB_DB": "/Users/yourname/.memoryweb.db"
}
}
}
}memoryweb setup은 Claude 애플리케이션 디렉토리가 감지되면 이 파일을 자동으로 작성합니다.
참고: ChatGPT Desktop은 stdio 기반 MCP 서버를 지원하지 않으며 memoryweb과 호환되지 않습니다.
저장소
기본 DB 경로: ~/.memoryweb.db
MEMORYWEB_DB=/path/to/your.db로 재정의하세요.
도구
16개의 MCP 도구 (v1.43.0). 폐기된 이름 (recent, restore, trace, alias, rename_domain 등)은 하드 컷 마이그레이션 오류를 반환합니다 — 대체 항목은 docs/memoryweb-skill.md를 참조하세요.
기억 기록
도구 | 기능 |
| 단일 개념, 결정 또는 발견을 기록합니다. 필수: |
| 활성 노드의 |
기억 연결
도구 | 기능 |
| 두 노드를 타입이 있는 관계와 서사적 때문에로 연결합니다. 두 노드 모두 먼저 존재해야 합니다. |
| 엣지 ID로 연결을 제거합니다. 하드 삭제 — 복원할 수 없습니다. ID는 |
| 노드 ID가 주어지면 최대 5개의 후보 연결을 반환합니다. 각 제안에 |
기억 검색
도구 | 기능 |
| ID로 노드와 모든 연결을 검색합니다. |
|
|
| 시간순 목록. |
| 두 기억 사이의 직접 엣지 (쌍 검증에는 |
| 도메인의 모든 노드를 종합에 적합한 구조로 반환 — 현재 상태, 최근 활동, 시간순의 주요 결정 |
| 도메인 또는 단일 노드의 이웃에 대한 Mermaid 순서도 ( |
| 도메인에 대한 이중 신호 중요도 분석. 네 개의 섹션 반환: |
보관 / 잊기
노드는 도구를 통해 하드 삭제되지 않습니다. 보관 = 소프트 삭제; 노드는 검색에서 사라지지만 보관 해제할 수 있습니다.
도구 | 기능 |
| 이유와 함께 노드를 보관하거나, |
| 단일 호출에서 여러 노드를 원자적으로 보관합니다. 동일한 엄격한 프로토콜이 적용됩니다. |
| 주의가 필요한 노드를 표면화합니다. |
도메인 관리
도구 | 하는 일 |
| 도메인 관리와 탐색 도구. 기본적으로 도메인과 별칭(aliases)을 나열합니다. 작업: |
관계 유형(Relationship types)
caused_by led_to blocked_by unblocks connects_to contradicts depends_on is_example_of governed_by resolved resolved_by supersedes
규칙
domain을 사용해 관심사를 분리하세요:deep-game,sedex,general어떤 도메인이 있는지 모를 때는 세션 시작 시
domains를 호출하세요why_matters필드는 검색에 가장 중요합니다 — 건너뛰지 마세요connection의
narrative은 이유입니다 — 단순히 연결이 있다는 사실이 아니라, 그 연결을 의미 있게 만드는 근거입니다관련 노드를 기록한 직후 connection을 추가하거나,
remember에서related_to를 사용해 생성 시점에 자동으로 연결하세요세션 시작 시 무엇을 검색할지 몰라도
orient를 호출하세요특정 두 가지의 관계를 물어볼 때는
why_connected를 사용하세요티켓 상태, 스프린트 노트, 또는 수일내로 최신이 아니게 될 항목에는
transient: true를 사용하세요.audit(mode=stale)에서 정리용으로 표시됩니다remember는suggested_connections과possible_duplicates를 반환합니다 — 노드를 더 기록하기 전에 두 가지를 모두 검토하세요
CLI
purge 하위 명령은 데이터베이스에서 보관(archived)된 노드를 완전히 삭제합니다. 의도적으로 MCP 도구로 노출되지 않습니다 — 유지보수 작업이지 에이전트 작업이 아니기 때문입니다.
memoryweb purge --dry-run # show what would be deleted (default behaviour without --confirm)
memoryweb purge --confirm # actually deletes
memoryweb purge --domain sedex # scope to a domain (case/whitespace-insensitive match)
memoryweb purge --before 2026-01-01 # only nodes archived before a date기본적으로 purge는 보관(archived) 노드만 처리합니다. 노드는 먼저 forget으로 보관되어야 삭제 대상이 됩니다. 도메인으로 범위를 지정해 0 node(s) would be purged 결과가 나왔는데 해당 도메인이 실제로 비어 있지 않다면, 이는 한 번도 보관되지 않은 live 노드가 남아 있다는 신호입니다. 도메인 범위 실행은 그런 경우 2 live node(s) still exist in domain "sedex" 같은 안내를 출력하므로 "도메인이 비었음"과 혼동되지 않습니다.
보관을 건너뛰고 live 노드를 포함한 도메인 자체를 완전히 삭제하려면 --include-live를 전달하세요. 이 옵션은 --domain을 필요로 하며(범위 없이 실행하면 데이터베이스의 모든 live node를 삭제하게 되므로 매우 중요), 되돌릴 수 없습니다.
memoryweb purge --domain sedex --include-live --dry-run # preview: shows live nodes too
memoryweb purge --domain sedex --include-live --confirm # hard-deletes the whole domain, archived or notdream 하위 명령은 최근 노드와 드리프트 후보(drift candidates)의 요약(digest)을 출력합니다. 세션 오리엔테이션에 유용하며, 파일링 시 save 및 precompact 훅이 자동으로 주입합니다.
memoryweb dream # reads ~/.memoryweb.db
memoryweb dream --db /path/to/your.db # explicit DB pathbackfill 하위 명령은 아직 임베딩이 없는 모든 live node에 대한 임베딩을 생성합니다. 설정된 임베딩 모델(기본값: snowflake-arctic-embed)로 Ollama가 실행 중이어야 합니다.
memoryweb backfill # reads ~/.memoryweb.db
memoryweb backfill --db /path/to/your.db # explicit DB path
memoryweb backfill -q # quiet mode — no progress output임베딩 모델
기본적으로 memoryweb은 시맨틱 검색 임베딩으로 snowflake-arctic-embed를 사용합니다. 다른 모델로 전환하려면 MEMORYWEB_EMBED_MODEL을 설정하세요.
export MEMORYWEB_EMBED_MODEL=bge-m3정확히 1024차원 벡터를 출력하는 모델만 호환됩니다. 벡터 테이블의 차원은 스키마 생성 시점(migration 9)에서 고정됩니다. 차원 가드가 모델이 일치하지 않는 모델을 감지하고, 데이터베이스를 조용히 손상시키는 대신 명확한 로그 메시지와 함께 거부합니다.
호환 모델(1024차원):
모델 | 참고 |
| 기본값. 영어에 최적화. |
| 다국어 — 중국어, 일본어, 한국어를 포함한 100개 이상의 언어. 비영어권에서 권장. |
| 영어 중심. 강력한 범용 검색 품질. |
일반적인 비호환 모델: nomic-embed-text(768차원), all-minilm(384차원). 변경 전에 항상 ollama show <model>로 확인하세요.
모델 전환:
# 1. Pull the new model
ollama pull bge-m3
# 2. Set the env var (add to your shell profile or MCP server config)
export MEMORYWEB_EMBED_MODEL=bge-m3
# 3. Regenerate — backfill detects the model change and clears automatically
memoryweb backfillmemoryweb는 마지막 backfill에 사용된 모델을 추적합니다. MEMORYWEB_EMBED_MODEL이 변경되면, 다음 backfill이 차이를 감지하고 변경을 로그로 기록한 뒤 기존 임베딩을 모두 지우고 처음부터 다시 생성합니다. 수동 조작은 필요 없습니다 — 다른 모델에서 생성된 임베딩은 호환되지 않는 벡터 공간에 있으므로, 자동 삭제 기능이 데이터베이스를 항상 일관된 상태로 유지합니다.
참고: 환경 변수를 변경한 후 즉시
memoryweb backfill을 실행하세요. 모델 변경과 다음 backfill 사이에 기록된 노드는 backfill 시점에 임베딩이 지워지고 재생성됩니다. 이는 올바른 동작입니다. backfill 동안 일관성이 보장됩니다.
설정된 모델 확인: memoryweb doctor 명령은 "Ollama model" 항목으로 활성 모델을 보고합니다.
setup 하위 명령은 ~/.claude/settings.local.json에 훅을 설치하고, Claude Desktop을 감지하면 자동으로 구성할 것인지 제안한 다음, Ollama를 시맨틱 검색용으로 구성합니다. Ollama가 설치되어 있지 않으면 setup은 https://ollama.com/install.sh를 통해 자동 설치할지를 묻습니다(Linux 및 macOS 전용 — Windows에서는 setup을 실행하기 전에 Ollama를 직접 설치해야 합니다). Ollama가 이미 설치되어 있지만 서버가 실행 중이 아니라면 setup이 자동으로 서버를 시작합니다. 마지막으로 설정된 임베딩 모델이 있는지 확인하고 없으면 pull합니다.
memoryweb setup # interactive setup
memoryweb setup --dry-run # preview without writing
memoryweb setup --hooks-dir /path/to/hooks # explicit hooks directory
memoryweb setup --db /path/to/your.db # explicit DB pathClaude Desktop이 감지되면, setup은 다음을 출력합니다.
Detected Claude Desktop. Configure it? [y/N]stats 기능은 모든 MCP 세션에서 도구 사용량을 기록합니다. 설정과 출력을 읽는 방법은 docs/stats.md를 참고하세요.
doctor 하위 명령은 memoryweb 설치의 모든 부분을 점검하고 구조화된 상태 보고서를 출력합니다. setup 이후 모든 것이 올바르게 연결되어 있는지 확인하거나, 에이전트 세션에서 시맨틱 검색 사용 전에 사용 가능한지 확인하려면 실행하세요.
memoryweb doctor # check ~/.memoryweb.db
memoryweb doctor --db /path/to/your.db # explicit DB path
memoryweb doctor --json # machine-readable JSON output각 점검은 상태 기호를 출력합니다: [✓] 통과, [✗] 실패, [!] 경고, [i] 정보. 어떤 점검이든 실패하면 명령은 종료 코드 1로 종료됩니다. 예시 출력:
[✓] Database: ~/.memoryweb.db (WAL, schema v11)
[✓] sqlite-vec: v0.1.6 — 142/145 nodes embedded (98%)
[✗] Ollama binary: not found in PATH — install from https://ollama.com/download
[!] Ollama server: skipped (Ollama binary not found)
[!] Ollama model: skipped (Ollama server not available)
[✓] Claude hooks: Stop and PreCompact hooks installed
[i] Graph: 145 live nodes, 12 archived, 203 edges, 4 domain(s) (deep-game, ...), 2 alias(es)
[i] Drift: 3 candidate(s): 1 contradicts, 2 stale labels
[i] Last activity: 2026-04-29 update (node "open question on backfill")
[i] Update: running dev build — skipping update checkmerge-domains 하위 명령은 두 도메인을 하나로 통합합니다:
memoryweb merge-domains --source <domain> --target <domain> [--dry-run]--dry-run은 아무 변경도 하지 않고 어떤 일이 일어날 지 보고합니다두 도메인 간의 라벨 충돌을 감지합니다 — 차단이 아니라 경고로 보고합니다
source → target 별칭을 자동으로 생성합니다
backup 하위 명령은 VACUUM INTO를 사용하여 일관된 단일 스냅샷을 만듭니다:
memoryweb backup /path/to/snapshot.db # snapshot ~/.memoryweb.db
memoryweb backup --db /path/to/your.db /path/to/snapshot.db-wal/-shm사이드카가 없는 단일 자립 파일 을 생성합니다memoryweb이 사용 중인 상태에서도 안전하게 실행 가능합니다 — 트랜잭션적으로 일관된 스냅샷 캐시,
기존 대상을 덮어쓰지 않습니다
백업 안전. 라이브 데이터베이스 폴더를 (클라우드 등) 복사하지 마세요. WAL 모드에서 최근 데이터는 checkpoint 전까지
-wal사이드카에 있습니다. 폴더 복사는.db와-wal을 서로 다른 순간에 캡처할 수 있고, 서로 다른 짝을 결합하면 데이터베이스가 손상됩니다. 항상memoryweb backup(또는sqlite3 source.db ".backup dest.db") 의 출력을 백업하고, 해당 단일 파일만 동기화하세요. memoryweb은 정상 종료 시 WAL을 메인 파일에 체크포인트하지만, 실행 중인 인스턴스를 안전하게 캡처하려면 스냅샷이 유일한 안전한 방법입니다.
memoryweb check-for-updatescheck-for-updates 하위 명령은 GitHub에서 최신 릴리스가 있는지 확인합니다:
Hooks
하는 동작
hooks/memoryweb_save_hook.sh (Stop hook — 모든 AI 응답 후 시작)
세션 트랜스크립트에서 사람이 보낸 메시지 수를 셉니다. SAVE_INTERVAL 메시지마다(기본 15) 응답을 일시 차단하고 계속하기 전에 모델이 중요하다면 remember와 connect를 호출하도록 요청합니다. 차단하기 전에 memoryweb dream을 실행하고 결과 다이제스트(최근 노드와 drift 후보)를 stopReason에 직접 넣어 모델이 파일링할 때 이전에 live context를 갖도록 합니다. memoryweb을 사용할 수 없으면 훅은 여전히 차단하지만 다이제스트는 생략합니다. 재진입 플래그를 사용하여 차단이 한 번만 발동되고 모델이 파일링 후 즉시 다시 주 execute.
hooks/memoryweb_precompact_hook.sh (PreCompact 훅 — context 압축 전 동작)
압축을 한 번 차단하고 모델에게 아직 파일하지 않은 중요한 모든 것을 파일하도록 요청합니다. 재진입 시 허용되어 filing pass 후 compact가 진행됩니다.
설치 (Claude Code)
빌드 후 setup을 한 번 실행하세요:
./memoryweb setup --hooks-dir /path/to/hooks또는 수동으로 설치:
chmod +x hooks/memoryweb_save_hook.sh hooks/memoryweb_precompact_hook.sh다음을 ~/.claude/settings.local.json에 추가하세요:
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "/path/to/hooks/memoryweb_save_hook.sh",
"env": {
"MEMORYWEB_DB": "/path/to/your.db"
}
}
]
}
],
"PreCompact": [
{
"hooks": [
{
"type": "command",
"command": "/path/to/hooks/memoryweb_precompact_hook.sh",
"env": {
"MEMORYWEB_DB": "/path/to/your.db"
}
}
]
}
]
}
}Claude Code를 다시 시작하면 활성화됩니다.
configuration
변수 | 기본값 | 역할 |
|
| filing 프롬프트 사이의 대화 메시지(전) |
###?
| MEMORYWEB_DB | ~/.memoryweb.db| SQLite 데이터베이스 경로. |
| MEMORYWEB_BIN | memoryweb | memoryweb 바이너리 경로(훅이 dream 실행할 때 사용). |
토큰 비용
수동 훅과 달리 이 훅들은 모델이 실제로 품질 좋은 노드를 생성해야 하므로 토큰을 소모합니다. 트리거당 한 번의 짧은 filing 교환이 발생하며, 대상 세션에서는 보통 1,000 토큰 미만입니다.
GitHub Copilot (VS Code)
VS Code의 GitHub Copilot은 동일한 JSON 형식으로 동일한 Stop 및 PreCompact 훅 이벤트를 지원합니다. .github/hooks/*.json 파일에서 훅을 로드하거나, ~/.claude/settings.json 및 .claude/settings.local.json에서도 로드합니다.
먼저 스크립트 실행 가능하게 만드세요:
chmod +x hooks/memoryweb_save_hook.sh hooks/memoryweb_precompact_hook.sh저장소에 .github/workflow/memoryweb.json을 생성하세요:
{
"hooks": {
"Stop": [
{
"type": "command",
"command": "/path/to/hooks/memoryweb_save_hook.sh",
"env": {
"MEMORYWEB_DB": "/path/to/your.db"
}
}
],
"PreCompact": [
{
"type": "command",
"command": "/path/to/hooks/memoryweb_precompact_hook.sh",
"env": {
"MEMORYWEB_DB": "/path/to/your.db"
}
}
]
}
}VS Code는 추가 설정 없이 자동으로 로드합니다. 이미 Claude Code 훅을 ~/.claude/settings.local.json으로 설치했다면, 추가 설정 없이 VS Code Copilot에서 이를 그대로 사용하게 됩니다.
기타 도구
Claude Desktop과 GitHub Copilot cloud agent은 훅을 지원하지 않습니다. 세션 시작 및 파일링 지침을 시스템 프롬프트에 수동으로 추가하세요. memoryweb setup은 애플리케이션의 데이터 디렉터리를 감지하면 Claude Desktop의 MCP 서버 항목을 자동으로 구성합니다.
GitHub Copilot cloud agent (GitHub.com에서 실행되는 코딩 에이전트)는 Stop 또는 PreCompact 이 포함되지 않는 다른 훅 형식과 이벤트 모델을 사용합니다. 대신 시스템 프롬프트에 파일링 지침을 추가하세요.
업데이트
새로운 버전이 있는지 확인하려면 다음을 실행하세요:
memoryweb doctor출력에 Update: 줄이 있다면 최신 릴리스가 있는지, 다운로드 위치를 알 수 있습니다.
업데이트하려면:
Homebrew
brew update && brew upgrade memoryweb수동
플랫폼에 맞는 최신 바이너리를 releases page에서 다운로드하세요.
기존 바이너리를 교체하세요 (빌드 팁: 원자적으로 교체하려면 먼저
memoryweb.tmp로 바꾼 다음mv memoryweb.tmp memoryweb실행).MCP 클라이언트(Claude Cod etc.)를 다시 시작하세요.
데이터베이스는 전방 호환됩니다 — binary는 시작 시 대기 중인 migration을 자동으로 실행합니다.
빌드
go build -o memoryweb .Go 1.22+ 필요. github.com/mattn/go-sqlite3과 sqlite-vec 사용하며 CGO가 필요합니다. 바이너리가 이미 실행 중일 때 안전하게 배포하려면:
go build -o memoryweb.tmp . && mv memoryweb.tmp memorywebAvailable Tools
18 toolsauditA
Inspect the health of knowledge in a domain across five modes. Omitting domain scans the entire workspace.
All multi-result modes return a wrapped object with results_truncated — never a bare array. When results_truncated is true, raise limit to retrieve more.
mode=stale: Returns {candidates, results_truncated, placeholders, placeholders_truncated}. Drift candidates — stale, contradicted, or duplicated memories — plus a separate placeholders section: connected live memories whose label or node_kind signals an unresolved placeholder (TBD, TODO, open question, stale goal/issue). Empty result is {candidates: [], results_truncated: false, placeholders: [], placeholders_truncated: false}. Present each to the user; never archive autonomously. Check placeholders_truncated and raise limit when true. Default limit 10 (max 500).
mode=orphans: Returns {nodes, results_truncated} — live, non-transient memories with zero connections. Empty result is {nodes: [], results_truncated: false}. Default limit 50 (max 500).
mode=archived: Returns {nodes, results_truncated}. Empty result is {nodes: [], results_truncated: false}. Capped at 25 by default — this is not a complete archive listing. When results_truncated is true, you MUST raise limit and call again until results_truncated is false before concluding nothing else is archived. Use when search returns nothing but you expect content to exist.
mode=conflicts: Returns {candidates, results_truncated}. Empty result is {candidates: [], results_truncated: false}. Semantically adjacent pairs that may warrant contradiction review — candidates only, not confirmed conflicts. Default limit 10 (max 100). Pairs already linked by contradicts, resolved, resolved_by, or supersedes are excluded; other edge types do not suppress. After resolving, connect with relationship=resolved (or resolved_by / supersedes) — additive; do not disconnect the contradicts edge.
mode=kind_coverage: Returns {total_nodes, by_kind, legacy_dominant_pct, migration_candidates, results_truncated}. Taxonomy health signal — per-kind counts, legacy decision/standing dominance percentage, and lean migration_candidates (id, label, truncated why_matters only). Candidate-surfacing only; never auto-revise; use recall(id) for full content. Default limit 50 (max 500) on migration_candidates.
digest=true collapses to {lines, results_truncated, placeholder_lines, placeholders_truncated} for stale; {lines, results_truncated} for orphans.
Supply tags to scope to a workstream. Supply memory_id (mode=stale only) to scope to a memory's neighbourhood.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | Yes | Required: stale (drift candidates), orphans (isolated memories), archived (list archived memories), conflicts (semantic contradiction candidates), or kind_coverage (taxonomy health / migration readiness) | |
| tags | No | Comma-separated tags. Only surfaces candidates carrying at least one of the supplied tags. OR semantics. Applies to all four modes. | |
| limit | No | Max results. Defaults: stale=10, orphans=50, archived=25, conflicts=10. When results_truncated is true, raise limit to retrieve more. archived max 500; stale/orphans max 500; conflicts max 100. | |
| digest | No | When true, stale and orphans return {lines, results_truncated} instead of full objects. Default false. | |
| domain | No | Optional domain to scope the audit. Omit to scan the entire workspace. Use for cross-domain drift review; scope to a domain for focused maintenance passes. | |
| memory_id | No | Anchor memory ID. Scopes stale candidates to the depth-2 BFS neighbourhood of this memory. Applies to mode=stale only; ignored for orphans, archived, and conflicts. | |
| node_kind | No | Optional filter by node_kind. Space-separated for OR match. Applies to all four modes. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral burden and does so exceptionally well. It discloses return shapes for every mode (wrapped objects, never a bare array), empty result conventions, truncation flags, per-mode default caps and max limits, the fact that archived is not a complete listing, conflict exclusions (pairs linked by contradicts, resolved, resolved_by, or supersedes), the additive nature of resolution connectors, and the candidate-only nature for conflicts and kind_coverage. It also warns against autonomous actions ('never auto-revise', 'present to user; never archive autonomously').
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 long and dense, but it is a complex five-mode tool and every section carries operational importance. It is front-loaded with the purpose and core return-shape rule, then organises details by mode. A slight credit deduction for the wall-of-text approach: bullet points or section headers would improve scannability in a high-temperature model, but the density is supportable and not repetitive.
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?
Though there is no output schema, the description enumerates every mode's return fields, empty-result shapes, and truncation flags, which fully compensates for the missing structured output definition. It also covers edge conditions (archived cap), policy constraints (never archive autonomously), and practical actions (raise limit, use recall for full content). For a tool of this complexity, an agent has everything needed to invoke it correctly and interpret the response.
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?
The schema already has 100% coverage with descriptions for all 7 parameters, but the tool description adds substantial meaning beyond the schema. It explains the depth-2 BFS neighbourhood scope of memory_id, clarifies that memory_id is ignored for non-stale modes, elaborates the archived cap semantics, explains the digest collapse behavior for each mode, gives per-mode default limits, and details the conflicts edge exclusions. These are not merely restated schema defaults — they enrich the agent's understanding of parameter behavior and interaction.
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, actionable statement — 'Inspect the health of knowledge in a domain across five modes' — which clearly names the operation (inspect), the resource (knowledge), and the scope (domain). It then enumerates all five modes (stale, orphans, archived, conflicts, kind_coverage), each with a precise purpose, which distinguishes it from sibling tools like recall, search, and history. The clarity allows an agent to identify this as a scanning/health-audit tool rather than a retrieval or mutation tool.
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 guidance in several places: for archived it says 'Use when search returns nothing but you expect content to exist,' and it repeatedly commands 'when results_truncated is true, you MUST raise limit and call again' and 'never archive autonomously.' It gives contextual direction for each mode (e.g., scope to a domain for focused maintenance passes, supply tags to scope to a workstream). It does not name specific sibling alternatives for all modes, but the use case for each mode is clear enough that an agent can decide when to call audit versus other tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
connectA
Connect memories with typed, narrative relationships. Valid relationship types are: caused_by, led_to, blocked_by, unblocks, connects_to, contradicts, depends_on, is_example_of, governed_by, resolved, resolved_by, supersedes — and all memory IDs must already exist before calling this.
Single mode (omit items): provide from_memory, to_memory, relationship directly.
Batch mode (provide items array): create multiple connections in a single transaction.
Relationship guidance: caused_by / led_to describe the same link from opposite ends (A caused_by B ≡ B led_to A). blocked_by / unblocks describe dependency on resolving an external issue. depends_on is a hard technical or logical prerequisite. contradicts marks a direct conflict. is_example_of marks an illustration. governed_by links a memory to a standing rule or constraint that it must satisfy. connects_to is the general fallback — use it only when no typed relationship fits.
Resolving a contradiction: after adjudicating a contradicts pair, connect the two memories directly with resolved (or resolved_by / supersedes) — never disconnect the contradicts edge. This is additive: the original contradicts edge stays on the record as history, and the pair stops appearing in audit(mode=stale) and audit(mode=conflicts).
| Name | Required | Description | Default |
|---|---|---|---|
| items | No | Batch mode: array of edge objects. Each must have from_memory, to_memory, relationship (string). Optional: narrative (string), verdict (string, resolved only). | |
| verdict | No | Optional outcome classification when relationship=resolved. Ignored (not stored) for other relationship types, but invalid enum values are still rejected. Values: false_positive, reconciled, superseded. | |
| narrative | No | The story of this connection - why these two things are linked | |
| to_memory | No | ID of the target memory. Required in single mode; omit when using items. | |
| from_memory | No | ID of the source memory. Required in single mode; omit when using items. | |
| relationship | No | Type of relationship. Required in single mode. Use resolved (or resolved_by / supersedes) to adjudicate a contradicts pair — additive, does not remove the contradicts edge. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Despite no annotations, the description discloses key behaviors: preconditions (existing IDs), the additive resolution rule for contradictions, and handling of verdict enum (ignored for non-resolved, invalid values rejected). Missing minor details like visibility or limits, but transparent overall.
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 detailed but well-organized: starts with core purpose, then modes, relationship list, usage guidance, and resolution rules. While lengthy, every sentence serves a purpose. Could be slightly more concise but justified by complexity.
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?
Given the tool's complexity (6 params, batch mode, multiple relationships, resolution rules) and no output schema, the description covers essential invocation context. It explains prerequisites and side effects (additive edge). Lacks return value details, but overall 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 covers 100% of parameters with descriptions. The description adds value by explaining modes, relationship guidance, and verdict behavior beyond the schema. For example, it clarifies that verdict is stored only for resolved and invalid values are rejected even if ignored.
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 tool's purpose: 'Connect memories with typed, narrative relationships.' It distinguishes itself from sibling tools (e.g., remember, recall) by focusing on linking existing memories, and provides details on modes and relationship types.
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 offers explicit guidance on when to use single vs batch mode and provides detailed relationship semantics (e.g., when to use each type, how to handle contradictions). It also specifies prerequisites (all memory IDs must exist).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
disconnectA
Remove a connection between two memories by edge ID. Obtain the edge ID from recall. This is a hard delete — the connection cannot be restored.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ID of the edge to remove |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations, but description explicitly states 'hard delete — the connection cannot be restored'. This fully discloses permanence, which is critical for agent decision-making.
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 efficient sentences: first defines action, second adds critical irreversibility warning. No wasted words, front-loaded with 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 simple 1-param tool with no output schema, the description covers all necessary aspects: action, required input source, and behavioral consequence. No gaps.
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 covers 100% with parameter description. Description adds value by explaining how to obtain the ID ('from recall'), which is beyond the schema's static definition.
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?
Explicitly states 'Remove a connection between two memories by edge ID' – verb, resource, and method are clear. Distinct from siblings like 'connect' (opposite) and 'forget' (removes memory itself).
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?
Tells the agent to obtain the edge ID from 'recall', providing clear prerequisite context. Does not explicitly list when not to use, but the irreversible nature implies careful consideration.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
disconnect_allA
Batch hard-delete of edges — use when you have 2 or more confirmed edges to remove at once. More efficient than multiple disconnect calls. All edges are removed or none — partial failure rolls back the entire operation. Edge IDs come from recall or why_connected. Returns {removed: N}.
| Name | Required | Description | Default |
|---|---|---|---|
| items | Yes | Array of edges to remove. Each item must have edge_id (string, required). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fully carries the behavioral burden. It discloses hard-delete semantics, atomicity with rollback on partial failure, the provenance of edge IDs, and the return shape '{removed: N}', which is exactly the operational context an agent needs.
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 compact and front-loaded, with each sentence adding a distinct piece of information: what it does, when to use it, its atomicity behavior, ID provenance, and return value. There is no redundancy or filler.
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 single-parameter tool with no output schema, the description is remarkably complete. It covers usage context, side effects, failure behavior, input sourcing, and return format, leaving no critical gap for an agent deciding whether and how to invoke 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?
The schema fully documents the structure of 'items' and 'edge_id', so the baseline is 3. The description adds meaningful semantic guidance by stating that edge IDs come from 'recall' or 'why_connected', and by framing them as 'confirmed edges', which helps the agent populate the parameter correctly.
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 pair, 'Batch hard-delete of edges,' which clearly identifies the operation and the object it acts on. It also distinguishes itself from single-edge alternatives like 'disconnect' by emphasizing the batch aspect.
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 use the tool: when there are 2 or more confirmed edges to remove at once. It also positions the tool as more efficient than multiple 'disconnect' calls, giving the agent a clear decision rule.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
domainsA
Domain administration and discovery. Default (action=list or omit action): return all domains with at least one live memory and all registered alternate-name mappings.
action=add_alias: register alternate name → canonical domain. Requires alias and domain. action=remove_alias: remove a registered alternate name. Requires alias. action=resolve: return the canonical domain for a name. Requires name. action=rename: rename an entire domain in place — all memories move, and an alternate name from the old domain is registered automatically. Requires old_domain and new_domain. Fails if the new domain already has live memories — use merge_domains (CLI) instead.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Name to resolve. Required for action=resolve. | |
| alias | No | Alias name. Required for add_alias and remove_alias. | |
| action | No | list (default), add_alias, remove_alias, resolve, or rename | |
| domain | No | Canonical domain name. Required for add_alias. | |
| new_domain | No | New domain name. Required for action=rename. | |
| old_domain | No | Current domain name. Required for action=rename. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses key behaviors: for rename, it states memories move and an alternate name is registered automatically; for list, it specifies what is returned. It could mention side effects like idempotency or permissions, but it is still fairly transparent.
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 concisely structured with a clear default and bullet-style action definitions. Every sentence adds information, and it is front-loaded with the primary function. No fluff or redundancy.
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?
Given the tool's complexity (multiple actions, 6 params, no annotations or output schema), the description covers actions, requirements, and a failure case. It lacks explicit output format details for some actions, but it does mention what list and resolve return, making it fairly 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 100%, so baseline is 3. The description adds value by explaining parameter roles in context (e.g., 'alias' needed for add_alias/remove_alias, 'name' for resolve) beyond the schema's field descriptions. It does not repeat schema text but provides action-specific semantics.
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 tool's purpose as 'Domain administration and discovery' and distinguishes multiple actions (list, add_alias, remove_alias, resolve, rename), each with a specific verb and resource. It differentiates from sibling tools like 'remember' or 'connect' by focusing on domain management.
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 for each action, including a default behavior (list). It also warns about a failure case for rename and suggests an alternative (merge_domains CLI), which helps the agent choose the correct tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
forgetA
Archive or un-archive a memory. Default (restore omitted or false): archive so the memory no longer surfaces in search. Set restore=true to un-archive — obtain the ID from audit(mode=archived). When archiving, always provide a reason — recorded in the audit log. Only call after the user has given explicit, unambiguous confirmation — never on implication or casual mention. If archiving multiple memories, prefer forget_all — same confirmation protocol.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ID of the memory to archive or un-archive | |
| reason | No | Required when archiving (when the unarchive flag is false). Why this memory is being archived | |
| restore | No | When true, un-archive the memory so it surfaces in search again. When false or omitted, archive the memory. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description bears full burden. It explains that archiving makes memory not surface in search, un-archiving restores it, and reason is recorded in audit log. This fully describes the behavioral impact without contradiction.
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?
Description is concise at 5 sentences, well-organized: purpose first, then behavior details, then usage conditions and alternatives. Every sentence adds necessary information without redundancy.
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 3 parameters and no output schema, the description covers all necessary aspects: default behavior, alternative modes, prerequisite confirmation, and cross-reference to audit tool. It is complete for the agent to use 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 has 100% coverage, baseline 3. Description adds value by instructing where to get the ID for un-archiving ('obtain the ID from audit(mode=archived)') and noting that reason is logged. This enhances parameter understanding beyond the schema.
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 'Archive or un-archive a memory' with specific verb and resource. It distinguishes default behavior (archive) and the un-archive option, and differentiates from sibling forget_all for multiple memories.
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?
Explicit when-to-use: 'Only call after the user has given explicit, unambiguous confirmation.' Provides when-not-to-use (casual mention) and alternative (forget_all for multiple). Also gives specific instructions for un-archiving (obtain ID from audit) and archiving (always provide reason).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
forget_allA
Batch archive — use this when you have 2 or more confirmed memories to archive at once. More efficient than multiple forget calls. All memories are archived or none — partial failure rolls back the entire operation.
Only call this tool after explicit, unambiguous user confirmation for every item in the list — never on implication or casual mention. 'That looks stale' or 'probably outdated' is not confirmation. Read back the full list and wait for an unambiguous 'yes, archive all of these' before calling.
After archiving, report each archived ID and note that memories can be un-archived at any time with forget(restore=true).
| Name | Required | Description | Default |
|---|---|---|---|
| items | Yes | Array of memories to archive. Each must have id (string, required) and reason (string, required). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses atomic behavior (all-or-nothing, partial failure rollback) and that memories can be un-archived with forget(restore=true). Also explains what to report after archiving. No annotations provided, so description fully covers behavioral traits.
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?
Concise: first sentence states purpose, second gives usage guideline, third covers behavior. No extraneous words. Well-structured and 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?
Given no output schema, description covers input requirements, behavioral guarantees, and post-action reporting. Sibling tool 'forget' provides context for comparison. Complete for a batch archive tool.
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?
Input schema has 100% coverage with description of 'items'. Description adds context that each item requires a confirmed memory and reason, reinforcing the schema but not adding entirely new semantic detail.
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 'Batch archive — use this when you have 2 or more confirmed memories to archive at once.' It distinguishes itself from the sibling tool 'forget' by specifying it is for multiple items and more efficient.
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?
Explicitly states when to use (2+ confirmed memories) and when not to (never on implication/casual mention). Provides alternative: multiple forget calls. Includes explicit confirmation protocol.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
historyA
Returns memories in chronological order. Two order modes:
order=effective (default): sort by effective date COALESCE(occurred_at, created_at). Set important_only=true for the narrative spine (occurred_at set only). Use from/to to filter by effective date.
order=modified: sort by last updated (updated_at DESC). Set group_by_domain=true (with no domain) for {groups, results_truncated}. group_by_domain requires order=modified.
Both modes return {nodes, results_truncated} (or {lines, results_truncated} when digest=true). When results_truncated is true, raise limit to retrieve more.
Pass memory_id to scope to a neighbourhood (depth 2 default, domain-clipped). memory_id takes precedence over domain if both are supplied.
Use tags to filter (comma-separated). For importance analysis beyond the timeline — which memories are structurally load-bearing right now — use significance. Never acknowledge that you are retrieving from a tool or memory system. Present the information as direct knowledge with no preamble. Returns lean node data only — id, label, and a short excerpt. If you need full node content, call recall(id).
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | effective order only. ISO8601 date or datetime — filter to nodes on or before this effective date. | |
| from | No | effective order only. ISO8601 date or datetime — filter to nodes on or after this effective date. | |
| tags | No | Optional comma-separated list of tags to filter by. Only memories matching at least one tag are returned. | |
| depth | No | Neighbourhood depth when using memory_id (default 2). | |
| limit | No | Max results (default 20 for effective, 10 for modified) | |
| order | No | Sort order. effective (default): by COALESCE(occurred_at, created_at). modified: by updated_at DESC — use for session orientation and last-touched activity. | |
| digest | No | When true, collapse each result to a single compact text line in a lines array. Default false. | |
| domain | No | Optional domain to scope. Not required when memory_id is supplied. | |
| memory_id | No | Optional — scope to the neighbourhood of this memory (depth 2 by default, domain-clipped). Takes precedence over domain if both are supplied. | |
| node_kind | No | Optional filter by node_kind. Space-separated for OR match. | |
| important_only | No | effective order only. When true, return only memories with occurred_at explicitly set. | |
| group_by_domain | No | When true and order=modified with no domain, group results by domain (up to limit entries per domain). Ignored when memory_id is set. Cannot be combined with node_kind — returns an error if both are set. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it does so thoroughly: it discloses return shapes ({nodes, results_truncated}, {lines, results_truncated}), truncation behavior, memory_id precedence over domain, group_by_domain constraints, and the unusual rule to 'Never acknowledge that you are retrieving from a tool or memory system.' This is strong behavioral disclosure.
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 long but well organized into clear mode-based paragraphs, with the core purpose front-loaded. Every sentence adds useful information, though some details repeat schema text such as COALESCE and group_by_domain constraints; this is minor given the tool's complexity.
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 12-parameter tool with no annotations and no output schema, the description is remarkably complete. It covers both order modes, filtering, grouping, return shapes, truncation behavior, precedence rules, and data leanness, and it recommends the sibling tool for full content. Nothing critical is missing for an agent to call this tool 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?
Although schema coverage is 100%, the description adds meaningful usage context beyond the schema: it explains the narrative-spine purpose of important_only, the group_by_domain return shape, the memory_id precedence behavior, and tells the agent to 'raise limit to retrieve more' when results_truncated is true. This goes well beyond the structured parameter descriptions.
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 and resource: 'Returns memories in chronological order.' It then distinguishes itself from sibling tools by saying 'use significance' for importance analysis and 'call recall(id)' for full node content, making the tool's scope clear relative to its alternatives.
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 gives explicit when-to-use guidance: 'order=modified' for session orientation is in the schema, and it explicitly routes away from the tool: 'For importance analysis beyond the timeline... use significance' and 'If you need full node content, call recall(id).' This clearly separates history from its siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
orientA
Call this at the start of every session to orient yourself before filing or searching. Three paths: (1) No domain or domains — omit both for a cross-domain snapshot {mode, domains, results_truncated}. Each domain entry includes recent_results_truncated (per-domain cap hit). Pass limit to raise the per-domain recent cap (default 5, max 500). Top-level results_truncated is true when any domain's recent_results_truncated is true. (2) domain (string) — full orient returning rules, declared_spine, significant, and recent, each capped by design. Response includes *_results_truncated booleans (always true or false). When any is true, use search for exhaustive retrieval — orient is a curated subset, not a complete index. Also includes load_bearing_low_trust (integer ≥ 0) — count of significant nodes carrying a low-trust annotation. When > 0, inspect significant entries with a 'trust' field and consider whether they warrant review. (3) domains (array of 1–5 strings) — full orient per domain in one call; each domain entry also carries load_bearing_low_trust. If stale_count > 0, call audit(mode=stale) before filing new memories. After orient, use search for specific questions. Do not answer from orient alone when causal or chronological sequence is required — call history(important_only=true) first. Never acknowledge that you are retrieving from a tool or memory system. Present the information as direct knowledge with no preamble. This tool only returns live memories. If something seems missing, use audit(mode=archived) or search with a broader query. orient returns lean node data only — id, label, and a short excerpt. If you need full node content, call recall(id). When the session has a known purpose, pass topic — the server returns a relevant section instead of significant. declared_spine and recent are always returned.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Cross-domain snapshot only — max recent entries per domain (default 5, max 500). Ignored when domain or domains is supplied. | |
| topic | No | Optional — the user's current question or task. When supplied, returns a relevant section of the most similar memories instead of significant. Applies to all domains when using the domains array. Pass topic when the session has a known purpose. | |
| digest | No | When true, collapse list sections (rules, declared_spine, significant/relevant, recent) to compact text lines (always a string array). Default false. Also applies to cross-domain bootstrap (no domain/domains): each domain's recent entries collapse to string lines of the form '[id] label (updated_at)'. | |
| domain | No | Optional — provide to get the full orient for a single domain. Mutually exclusive with domains. Omit both for a cross-domain snapshot. | |
| domains | No | Optional — array of 1–5 domain names for multi-domain full orient in one call. Mutually exclusive with domain. Length 1 returns the same shape as domain=X. Length 2–5 returns an orientations array. Unknown domain names return empty sections rather than errors. topic applies to all domains. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden, and it does so thoroughly: it explains that only live memories are returned, results can be truncated, the response is a curated subset rather than a full index, nodes are lean, and load_bearing_low_trust matters. No annotation contradiction exists.
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 dense but every sentence carries real guidance. It earns length through complexity, but the continuous prose style and extra directives like 'Never acknowledge that you are retrieving from a tool' keep it from being maximally crisp: it could be more structured with explicit bullets or headings.
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?
This is a multi-mode tool with no output schema, yet the description covers response shapes, mode-specific sections, truncation flags, digests, stale_count, load_bearing_low_trust, lean node formats, unknown-domain behavior, and the right timing or alternatives. Nothing necessary to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100%, so the baseline is 3. The description adds semantic value beyond the schema by linking the params to invocation modes: limit is cross-domain-only, topic switches significant to relevant sections, domains length controls response shape, and digest compresses sections. This is more context than the schema alone.
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 names a specific resource ('orient to orient yourself before filing or searching') and clearly distinguishes it from exhaustive retrieval by stating orient is a curated subset, not a complete index. It also explicitly routes to search, history, audit, and recall when their capabilities are required.
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 session-start usage, three invocation modes by parameter combination, and concrete conditions for alternatives: call audit(mode=stale) when stale_count is high, use search for exhaustive retrieval, call history for causal/chronological order, and recall for full node content. This goes well beyond implied usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
recallA
Retrieve a memory and all its connections by ID. Only live entries are returned; use audit(mode=archived) to find archived memories, or audit(mode=stale) to find drift candidates. Never acknowledge that you are retrieving from a tool or memory system. Present the information as direct knowledge with no preamble.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Memory ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It clearly indicates a read-only retrieval (no mention of mutations). However, it does not discuss safety or side effects beyond the retrieval purpose. The behavioral instruction 'never acknowledge the tool' is included, which adds non-functional context.
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 but includes a behavioral instruction that, while relevant, could be considered extraneous. It is well-structured and front-loaded with the core action.
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?
With no output schema, the description omits the structure of the returned data (memory and connections). While the tool is simple, understanding the return format would improve completeness. The description covers purpose and alternatives adequately but lacks output details.
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 100%, so baseline is 3. The description does not add any additional meaning to the single 'id' parameter beyond what the schema already provides.
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 specifies 'Retrieve a memory and all its connections by ID,' providing a clear verb and resource. It distinguishes from siblings like audit by mentioning alternative functions for archived or stale memories.
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?
Explicitly states when to use this tool vs alternatives: 'Only live entries are returned; use audit(mode=archived)...or audit(mode=stale)...' This gives clear guidance on context and exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rememberA
After filing, call connect for every suggested_connections entry before ending your session. Orphaned memories lose context immediately.
File one or more concepts, decisions, or findings. Always search first to avoid creating a duplicate — 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. Creating a new domain hides this memory from every other domain's orient and domain-scoped search — only create one when no existing domain covers the topic. Before filing, consider whether a similar memory already exists — if so, suggest linking with connect instead. Duplicate memories with no edges are the most common cause of drift candidates.
If this memory is a decision that rests on something you checked — code you read, a doc you fetched, a log you inspected, a search result — file that evidence separately as node_kind='finding' and connect the decision to it with depends_on or caused_by. Don't let the decision's description silently absorb the evidence as prose.
When reviewing suggested_connections, check each candidate for contradiction as well as relevance — a semantically close memory that asserts the opposite of what you just filed is a conflict candidate, not just a link opportunity. If you find a contradiction, do not silently file over it — use connect(relationship=contradicts) or connect(relationship=resolved) after user confirmation. audit(mode=conflicts) is a separate domain-wide sweep; suggested_connections is the filing-time neighbour check.
Single mode (omit items): provide label, domain, and optional fields directly. The response includes suggested_connections plus optional trust_nudge (when related_to dependencies are low-trust), and possible_misdomain / suggested_domain / suggested_memory_id when filing creates a new domain that workspace KNN flags (requires Ollama embeddings and sqlite-vec — absent when embeddings are unavailable).
Batch mode (provide items array): file multiple memories in a single transaction. Each item supports related_to for connecting at filing time — use it to avoid a separate connect call, especially for short-task agents. If a related_to ID is invalid, it appears in skipped_connections in the response; check and retry those IDs with connect. Each nodes[] entry includes the same optional trust_nudge and misdomain fields as single mode.
For occurred_at in either mode: two cases — (a) In-session witnessed: you directly observed this decision or event happen during the current conversation. Set occurred_at freely using today's date. No confirmation needed. (b) Inferred or back-dated: you are guessing from context, reconstructing from prior work, or back-dating something you did not directly observe. Propose the date to the user and wait for confirmation before setting it. Never guess. Never infer it silently from context. If the user confirms without specifying a date, use today's system date. Future dates are valid for planned events and reminders.
Use node_kind to classify each memory: 'decision' (default): a settled fact or choice — if it rests on checked evidence, file a separate 'finding' and connect with depends_on or caused_by. 'reference': an entity (person, system, org). 'issue': a problem or open question. 'option': a candidate answer to an issue. 'assumption': an unverified precondition. 'finding': an empirical observation. 'standing': a durable rule — appears in orient rules. 'goal': a desired future state. 'transient': short-lived state, surfaced by audit(mode=stale) after 7 days. Standing memories appear in the rules section of orient. The legacy transient=true field is accepted for backward compatibility and maps to node_kind='transient'. The legacy decision_type field name is rejected — use node_kind instead.
| Name | Required | Description | Default |
|---|---|---|---|
| tags | No | Space-separated synonyms and keywords that improve search recall. Examples: 'testing gradle kotlin approval'. These are searched alongside label, description, and why_matters. Populate this with alternative terms an agent might use to find this memory later. | |
| items | No | Batch mode: array of memory objects to file in a single transaction. Each must have label (string, required) and domain (string, required). Optional: description, why_matters, tags (space-separated keywords), occurred_at (ISO8601 — in-session: set freely; inferred/back-dated: propose+confirm, never infer silently), node_kind (string: transient|reference|issue|decision|option|assumption|finding|standing|goal — decisions resting on checked evidence need a separate finding + depends_on or caused_by link), transient (boolean, deprecated — maps to node_kind=transient), related_to (string ID, object with id+relationship, or array of either — connects at filing time; invalid IDs appear in skipped_connections). New domain: hides the memory from other domains' orient and domain-scoped search. | |
| label | No | Short name for this memory (e.g. 'RST $10 boot crash'). Required in single mode; omit when using items. | |
| domain | No | The domain or project this belongs to (e.g. 'deep-game', 'sedex', 'general'). Required in single mode; omit when using items. | |
| node_kind | No | Classify this memory. 'decision' (default): a settled fact or choice — if it rests on checked evidence, file a separate 'finding' and connect with depends_on or caused_by. 'reference': an entity (person, system, org). 'issue': a problem or open question. 'option': a candidate answer to an issue. 'assumption': an unverified precondition. 'finding': an empirical observation. 'standing': a durable rule or constraint that governs other memories — appears in the rules section of orient. 'goal': a desired future state. 'transient': short-lived state — surfaced by audit(mode=stale) after 7 days. | |
| transient | No | Deprecated — use node_kind='transient' instead. Accepted for backward compatibility: if true and node_kind is not set, maps to node_kind='transient'. | |
| related_to | No | Optional list of memories to auto-connect at creation time. Single mode only. Each item is either a plain memory ID string (creates a connects_to connection) or an object with id and relationship fields. Invalid or unknown IDs are silently skipped. | |
| description | No | What this memory is about | |
| occurred_at | No | ISO8601 date or datetime. (a) In-session witnessed: you directly observed this happen in the current conversation — set freely using today's date, no confirmation needed. (b) Inferred or back-dated: you are guessing or reconstructing — propose to user and wait for confirmation. Never guess. Never infer silently. Single mode only. | |
| why_matters | No | Why this is significant - the 'so what' |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so the description carries full burden. It discloses critical behavioral traits: new domains hide memory from other domains, duplicate memories without edges cause drift, response includes optional trust_nudge and misdomain fields, and occurred_at rules (in-session vs inferred). Also notes conditions when features are unavailable (e.g., Ollama embeddings).
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 very long (multiple paragraphs) and contains some redundancy (e.g., repeated warnings about duplicates). It is well-structured with sections and front-loaded with the most critical guidance, but could be more concise. Every sentence adds value, but the length may overwhelm an agent.
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?
Given 10 parameters, no output schema, and 13 sibling tools, the description is remarkably complete. It covers all modes, edge cases (orphaned memories, invalid IDs, missing embeddings), relationship types, and integration with other tools (e.g., 'call connect for every suggested_connections entry'). No gaps identified.
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 100%, baseline is 3. Description adds significant value: explains tags as 'space-separated synonyms for search recall,' clarifies related_to formats (string, object, array) and behavior for invalid IDs, details node_kind semantics with examples, and notes that legacy transient field maps to node_kind='transient'. However, some parameters (e.g., why_matters) get minimal additional context.
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 tool's primary purpose: 'File one or more concepts, decisions, or findings.' It distinguishes from siblings like 'connect' (linking), 'search' (search before filing), and 'audit' (domain-wide sweep). The distinction between single and batch mode is explicitly covered.
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?
Provides explicit when-to-use and when-not-to-use guidelines: always search first to avoid duplicates, prefer existing domains, use 'connect' instead if a similar memory exists. Explains both single and batch modes, including when to use each (e.g., 'use related_to to avoid a separate connect call'). Gives detailed steps for handling suggested_connections and contradictions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
restore_allA
Batch un-archive — use when you have 2 or more confirmed archived memories to un-archive at once. More efficient than multiple forget(restore=true) calls. All memories are un-archived or none — partial failure rolls back the entire operation. Returns {restored: N, ids: [...]}.
| Name | Required | Description | Default |
|---|---|---|---|
| items | Yes | Array of archived memory IDs to un-archive. Each item must have id (string, required). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden. It discloses the atomicity (all or none, rollback on partial failure), the batch nature, and the return format. While it doesn't mention permissions or side effects on already-unarchived IDs, the core behavior is well covered, adding value beyond the schema.
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, front-loaded with the core purpose, then usage condition, efficiency note, atomicity, and return format. Zero waste; every clause 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 one-parameter tool with no output schema and no annotations, the description covers purpose, usage, behavior, and return shape. It even explains the rollback behavior, which is essential for batch operations. Nothing an agent needs to invoke correctly is missing.
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% – the items array and required id are fully documented. The description only restates that IDs are for archived memories, adding little semantic value beyond the schema. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (batch un-archive) and resource (memories), with a clear condition for use (2+ confirmed archived memories). It also differentiates itself from the sibling 'forget(restore=true)' by name, making its purpose 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?
Explicitly tells when to use this tool ('when you have 2 or more confirmed archived memories to un-archive at once') and when not to (implies using forget(restore=true) for single/fewer). The efficiency rationale and the alternative are named directly, leaving no inference needed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
reviseA
Update one or more existing live memories. Only the fields you provide are changed — omitted fields keep their current values. Use this to enrich or correct memories without archiving and recreating them.
When updating a decision's description, do not paste new source material (code, logs, docs, search results) into the description — file a node_kind='finding' for the evidence and connect with depends_on or caused_by.
Single mode (omit items): provide id and any fields to update. Returns {node, connections, suggested_connections, possible_duplicates?, trust_nudge?}. Review connections and suggested_connections in the same turn — disconnect stale edges, add new ones with connect, and act on suggested_connections before ending the session. Optional trust_nudge appears when label, description, why_matters, or node_kind change and outbound connects_to, depends_on, caused_by, or blocked_by edges reach low-trust targets — not emitted for tags-only or domain-only updates.
Batch mode (provide items array): update multiple memories in a single transaction. All updates succeed or all are rolled back. Returns {updated: [{node, connections, suggested_connections, trust_nudge?}]}; each entry carries the same review imperative as single mode.
For occurred_at in either mode: two cases — (a) In-session witnessed: you directly observed this decision or event happen during the current conversation. Set occurred_at freely using today's date. No confirmation needed. (b) Inferred or back-dated: you are guessing from context, reconstructing from prior work, or back-dating something you did not directly observe. Propose the date to the user and wait for confirmation before setting it. Never guess. Never infer it silently from context. If the user confirms without specifying a date, use today's system date.
Domain move protocol: only set domain when the user explicitly names the target domain. Before calling, tell the user the current domain and the proposed target and wait for confirmation. 'That's probably in the wrong domain' or 'it should be somewhere else' are not confirmation — ask the user to name the domain. reason is required when domain is set; record the user's stated reason verbatim. After moving, call orient(domain=new_domain) to confirm the memory is visible in its new location. Never acknowledge that you are retrieving from a tool or memory system.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | ID of the memory to update. Required in single mode; omit when using items. | |
| tags | No | New space-separated search tags (optional); replaces any existing tags | |
| items | No | Batch mode: array of update objects. Each must have id (string, required). Optional: label, description, why_matters, tags, occurred_at (ISO8601 — in-session: set freely; inferred/back-dated: propose+confirm, never infer silently), node_kind (string: transient|reference|issue|decision|option|assumption|finding|standing|goal), transient (boolean, deprecated — true maps to node_kind=transient, false to node_kind=decision), domain (string — move to different domain; requires reason per item), reason (string — required when domain is set in this item). Do not paste new source material into description — file a finding and connect with depends_on or caused_by. | |
| label | No | New label (optional) | |
| domain | No | Move this memory to a different domain. Requires reason. Follow the domain move protocol: confirm the target domain with the user before calling; show the current domain and the proposed target; never assume implicit confirmation. | |
| reason | No | Required when domain is set. Explain why the domain change is needed. Recorded in the audit log as 'domain (was OLD → NEW): reason'. Record the user's stated reason verbatim. | |
| node_kind | No | Classify this memory. 'decision' (default): a settled fact or choice. 'reference': an entity (person, system, org). 'issue': a problem or open question. 'option': a candidate answer to an issue. 'assumption': an unverified precondition. 'finding': an empirical observation. 'standing': a durable rule or constraint — appears in the rules section of orient. 'goal': a desired future state. 'transient': short-lived state, surfaced by audit(mode=stale) after 7 days. Omit to leave unchanged. | |
| transient | No | Deprecated — use node_kind instead. Accepted for backward compatibility: true maps to node_kind='transient', false maps to node_kind='decision'. Omit to leave unchanged. | |
| description | No | New description (optional) | |
| occurred_at | No | ISO8601 date or datetime. (a) In-session witnessed: you directly observed this happen in the current conversation — set freely using today's date, no confirmation needed. (b) Inferred or back-dated: you are guessing or reconstructing — propose to user and wait for confirmation. Never guess. Never infer silently. Single mode only. | |
| why_matters | No | New why_matters text (optional) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description bears the full disclosure burden — and it shoulders it well. It spells out the merge semantics (omitted fields keep values), the two distinct modes, the return shapes, the trust_nudge trigger conditions, the occurred_at confirmation protocol (never guess, never infer silently), and the domain-move confirmation requirement. Contradiction-free since no structured hints exist.
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 long, but the front-loaded core purpose and the rigorously sectioned protocols (single vs. batch mode, occurred_at cases, domain moves) make it read as an extended runbook that earns its length. Every paragraph introduces a distinct decision the agent must make. Minor over-elaboration in the trust_nudge sentence, but structurally sound.
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?
The tool combines two modes, 11 parameters, and several interaction-wise protocols, with no output schema to fall back on. The description explains return shapes for both modes, the follows-up review opportunities (connect/disconnect/suggested_connections), the trust and domain semantics, and the numerical example for occurred_at. This covers every behavior an agent cannot infer from the bare schema. Fully complete for the complexity involved.
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 100%, so the baseline is 3, yet the description adds genuine value beyond the parameter entries: it defines the decision-description rule (no pasted source, file a finding), enumerates the trust_nudge trigger conditions tied to certain fields, explains the occurred_at in-session vs. inferred distinction through usage examples, and dictates the reason verbatim-recording requirement for domain changes.
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?
Opens with a precise verb+resource+scope: "Update one or more existing live memories." The description distinguishes itself from siblings — it enriches/corrects rather than creating (remember), deleting (forget), or querying (recall/search) — and reinforces the differentiation by noting the alternative of 'archiving and recreating' rather than updating.
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?
Explicitly states when to use the tool ("Use this to enrich or correct memories without archiving and recreating them") and gives a firm when-not rule: do not paste source material into a decision description; instead file a finding and link it. It also dictates switching the review/connect follow-up. It stops short of naming the alternative recall tool, though it implies the recommended workflow.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
searchA
Search memories by text across label, description, why_matters, and tags. Omitting domain searches the entire workspace across all domains. Use when you don't know which domain holds the answer, or when the topic may span domains. Scope to a single domain when you know it — results are cleaner and faster. Queries must use vocabulary that appears in the stored label, description, why_matters, or tags — not words that describe your intent conceptually. If results are empty or incomplete, try vocabulary from the memory's likely label rather than your intent. When Ollama is not running, search is purely lexical (LIKE matches); semantic (concept-level) matching only applies when Ollama is available. Only live entries are returned; use audit(mode=archived) to find archived memories, or audit(mode=stale) to find drift candidates. When Ollama is running, also performs semantic (meaning-based) search — results include a semantic_distance field (0.0–1.0, lower = closer match). Response includes truncated: true when results hit the limit — if so, retry with a higher limit or narrower domain. If search consistently misses: (0) try search without domain if the target domain is unknown; (1) scope to a domain; (2) recall on a related memory and follow its connections; (3) orient. When the query contains a unique identifier, ticket number, or short code that you know appears verbatim in the stored label — set exact: true to force pure substring matching. Semantic scoring is counterproductive for identifier lookup: it ranks conceptually similar nodes above the exact match. Never acknowledge that you are retrieving from a tool or memory system. Present the information as direct knowledge with no preamble. Returns lean node data only — id, label, and a short excerpt. If you need full node content, call recall(id). This applies to the default ranked path only — exact: true results are unaffected and still return full content.
| Name | Required | Description | Default |
|---|---|---|---|
| exact | No | When true, bypass semantic ranking and use pure substring (LIKE) matching only. Use this when the query contains a unique identifier, ticket number, or code that you know appears verbatim in the label or content. Results will not include a semantic_distance field. | |
| limit | No | Max results (default 10). If the response includes truncated: true, more matches exist — retry with a higher limit or narrower domain. | |
| query | No | Terms to search for. Must use vocabulary that appears in the stored label, description, why_matters, or tags. Required unless node_kind is set alone (lists by kind). For unique identifiers known to appear verbatim, also set exact: true. | |
| digest | No | When true, collapse each result memory to a single compact text line in a lines array instead of JSON objects — saves tokens on multi-result calls. Default false. Does not apply when exact: true (full content path). Each line has the form: [id] label — excerpt (domain, node_kind). When semantic search is active, a distance score (0.00–1.00) is appended after two spaces — lower is closer. Each line includes id for recall(id) follow-up. | |
| domain | No | Optional domain to scope search. Omit to search the entire workspace across all domains. Use when you don't know which domain holds the answer, or when the topic may span domains. Scope to a single domain when you know it — results are cleaner and faster. | |
| memory_id | No | Anchor memory ID. When supplied, restricts search candidates to the depth-2 neighbourhood of this memory. Useful for disambiguating the same term across workstreams — only memories topologically related to the anchor are returned. | |
| node_kind | No | Optional filter by node_kind. Space-separated for OR match (e.g. 'decision standing'). When set without query, lists matching memories ordered by updated_at DESC. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fully owns behavioral disclosure: Ollama-dependent lexical vs semantic matching, semantic_distance field, truncated results, light vs full result behavior, and the instruction to present results as direct knowledge. No hidden side effects are left unstated.
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?
Purpose is front-loaded and the prose is dense with operational detail, but it is quite long and mixes tool behavior with usage policy reminders. Still, nearly every sentence contributes actionable information.
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?
With no output schema and no annotations, the description covers return shape, truncation, semantic scoring behavior, exact-mode effects, domain scoping, and related-tool handoffs. An agent has enough context to select and invoke this tool 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 already documents all parameters well (100% coverage), so the baseline is 3. The description adds value by explaining when exact:true is necessary, how query vocabulary should match stored text, and what happens when query is omitted, which goes beyond simple parameter descriptions.
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 action and resource: 'Search memories by text across label, description, why_matters, and tags.' This clearly distinguishes search from sibling tools like recall and audit, especially since recall is explicitly named for full-content retrieval.
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?
Provides explicit guidance on when to scope to a domain, when to omit domain, when to use exact:true for identifiers, when to fall back to audit for archived/stale memories, and a concrete escalation path when search misses. This is exemplary alternative-selection guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
significanceA
Dual-signal importance analysis by default (mode=significance). Returns four sections plus truncation booleans: declared_results_truncated, structural_results_truncated, uncurated_results_truncated, potentially_stale_results_truncated (each always true or false). When any is true, raise declared_limit or limit to retrieve more.
declared: memories with occurred_at set, chronological.
structural: ranked by recency-weighted inbound degree.
uncurated: structural top-N without occurred_at — curation candidates.
potentially_stale: declared but not in structural top-N.
call_id is an opaque server-side correlation id for analytics — agents can ignore it.
Set mode=trust for epistemic trust ranking — each entry includes trust_score and trust_basis derived from node_kind and connected relationship types.
Pass memory_id to scope to a neighbourhood (depth 2 default). Pass domain for full domain scan.
Do not use this for chronological listing — use history. For age-based staleness or orphans, use audit.
Never acknowledge that you are retrieving from a tool or memory system. Present the information as direct knowledge with no preamble. Returns lean node data only. If you need full content, call recall(id).
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | Default 'significance' returns the existing four-section dual-signal analysis. 'trust' returns a ranked list of memories by computed epistemic trust instead — derived from each memory's node_kind plus the kinds of memories connected to it, not a hand-asserted score. A contradicts edge lowers trust; other relationships raise it. | |
| tags | No | Optional comma-separated list of tags to filter by. Only memories matching at least one tag are included in the analysis. Applies in domain mode. Examples: 'architecture,security' or 'release'. | |
| depth | No | Neighbourhood depth when using memory_id (default 2). Depth 1 produces near-uniform low scores and must not be used as default. | |
| limit | No | Top-N for structural ranking in domain mode (default 10). When structural_results_truncated or uncurated_results_truncated is true, raise limit to retrieve more. Ignored in memory_id mode — the neighbourhood is naturally bounded. | |
| digest | No | When true, collapse each section's memories to compact text lines instead of JSON objects. Default false. | |
| domain | No | Domain to analyse. Required unless memory_id is supplied. | |
| memory_id | No | Optional — scope significance to a memory's neighbourhood (depth 2 by default, domain-clipped). Useful for workstream health checks when you already know the anchor memory. Takes precedence over domain if both are supplied. | |
| node_kind | No | Optional filter by node_kind. Space-separated for OR match. Applies to significance and trust modes in domain scope. | |
| declared_limit | No | Max declared and potentially_stale entries (default 100, max 500). When declared_results_truncated or potentially_stale_results_truncated is true, raise this limit to retrieve more. | |
| recency_window | No | Days. Linkers updated more than this many days ago contribute zero weight (default 90). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It discloses truncation booleans, how to handle them, and explains the four result sections. Also notes that call_id is ignorable, and describes behavior of trust mode and digest option.
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 well-structured with bullet points and sections, making it scannable. However, it is somewhat lengthy with some redundancy (e.g., repeating the four sections both in summary and detail). Could be trimmed by 10-20% without losing value.
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 10 parameters and no output schema, the description fully explains behavior, truncation handling, mode differences, and parameter interplay. It also provides guidance on when to raise limits, satisfying completeness despite lack of output schema.
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 100%, but description adds rich context beyond schema descriptions: e.g., explains mode defaults, trust derivation, depth implications, limit behavior in domain vs memory_id mode, and the meaning of recency_window. Each parameter gets meaningful usage advice.
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 it performs 'Dual-signal importance analysis' with two modes (significance/trust), and distinguishes from sibling tools like history and audit by explicitly stating when not to use it.
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?
Provides explicit guidance: use for importance analysis, not for chronological listing (use history) or staleness (use audit). Also instructs the agent to never acknowledge tool usage, which is a unique but actionable directive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
suggest_connectionsA
Given a memory ID, return up to 5 candidate connections from the same domain whose labels, descriptions, or tags overlap with the source memory. Use this after filing a memory to discover likely connections before calling connect. This tool is read-only — it never creates connections.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ID of the memory to find connection candidates for | |
| limit | No | Max candidates to return (default 5) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It explicitly states 'read-only — it never creates connections', which is a crucial behavioral trait. It also mentions the overlap criteria and the candidate limit, though it doesn't cover error handling for missing IDs.
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 wasted words. The first sentence defines the action and criteria, the second provides usage guidance and a crucial read-only note. Information is front-loaded 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 read-only suggestion tool with two parameters and no output schema, the description covers purpose, usage context, behavioral constraints, and criteria. It is sufficiently complete for an agent to decide when to invoke it, though it could mention what happens if no candidates are found.
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 100%, but the description adds meaningful context: it restricts candidates to 'from the same domain', which is not in the schema. It also reinforces the default limit of 5. This adds value beyond the schema definitions.
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 tool returns candidate connections for a given memory ID from the same domain based on overlapping labels, descriptions, or tags. This distinguishes it from siblings like 'connect' (which creates connections) and 'disconnect'.
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?
Explicitly advises using this tool after filing a memory to discover likely connections before calling 'connect', providing clear when-to-use guidance. However, it does not explicitly state when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
visualiseA
Generate a Mermaid.js flowchart. Pass memory_id to see a single memory and all its direct connections. Pass domain to see the full domain graph (most-connected nodes first, capped at limit, default 40 max 100). Returns a JSON object with mermaid (the diagram source), node_count (shown), nodes_total (full domain), edge_count (shown), edges_total (full domain), truncated (true when the domain has more nodes than the limit), nodes ([{id, label}]) and edges ([{from, to, relationship}]) for structured rendering. Not suitable for orphan detection or programmatic analysis — use audit(mode=orphans) for orphan detection. Output may be truncated for large domains. Use for human visual inspection only. Output the mermaid string inside a ```mermaid code block. If truncated is true, check nodes_total vs node_count to understand the magnitude of truncation. Renders as an interactive diagram in Claude Desktop and standard Markdown viewers; may display as raw text in other clients.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max nodes to include in domain mode (default 40, max 100). Most-connected nodes are prioritised when truncating. | |
| domain | No | A domain name (e.g. 'memoryweb-meta'). To visualise a single memory by ID, use the memory_id parameter instead. | |
| memory_id | No | A memory ID. Returns the neighbourhood: the memory plus all directly connected memories and connections. Takes precedence over domain if both are supplied. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses truncation behavior (most-connected nodes prioritized, capped at limit). Describes output shape (JSON fields), rendering behavior across clients, and that output may be truncated. No annotations provided, so description carries full burden and does so thoroughly.
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?
Front-loaded with main purpose, then logically covers modes, output fields, limitations, rendering. Every sentence adds value; no fluff. Length is justified by completeness and lack of output 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?
Covers all aspects: purpose, parameter guidance, output format, truncation handling, rendering caveats, and when to avoid. Without output schema, description fully compensates. Sibling tools are mentioned for alternative use cases.
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?
Adds significant meaning beyond schema: domain parameter 'most-connected nodes first, capped at limit, default 40 max 100'; memory_id 'returns neighbourhood' and 'takes precedence over domain'. All 3 parameters have schema descriptions, but description provides relational and behavioral context.
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?
Clearly states it generates a Mermaid.js flowchart. Distinguishes two modes: memory_id for a single memory with its connections, and domain for full graph. Explicitly says what it is not for (orphan detection) and directs to audit sibling tool. Verb+resource is specific.
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?
Explicitly explains when to use memory_id vs domain, including precedence. Gives default and max for limit. Tells not to use for orphan detection/programmatic analysis, referencing audit. Provides instructions for handling truncation and rendering.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
why_connectedA
Find direct connections between two memories. Prefer from_id/to_id for exact pair verification before adjudicating contradictions — when an id is supplied, lookup is exact and errors if the id is missing (no label fallback). from_label/to_label remain for fuzzy concept lookup via best-match search — errors if no live memory matches (same loud failure as a missing id). Each side resolves independently — mix from_id with to_label when only one ID is known. Cannot supply both from_id and from_label (same for to_*). Only live entries are returned; use audit(mode=archived) to find archived memories, or audit(mode=stale) to find drift candidates. Never acknowledge that you are retrieving from a tool or memory system. Present the information as direct knowledge with no preamble.
| Name | Required | Description | Default |
|---|---|---|---|
| to_id | No | Exact ID of the second memory — preferred for pair verification | |
| domain | No | Optional domain to scope label search (ignored for id lookup) | |
| from_id | No | Exact ID of the first memory — preferred for pair verification | |
| to_label | No | Label or description of the second concept (fuzzy best-match when to_id omitted) | |
| from_label | No | Label or description of the first concept (fuzzy best-match when from_id omitted) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully discloses error behavior (loud failure for missing id or unmatched label), independent resolution of each side, mutual exclusivity of id and label parameters, and that only live entries are returned. It also includes an agent behavior instruction for presenting results.
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 dense and informative with no wasted words. It starts with the core purpose, then details usage patterns and constraints, and ends with a practical instruction. Each sentence 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 tool with 5 parameters and no output schema, the description covers error handling, parameter combinations, and references to the audit tool. However, it omits details about the return format (e.g., what a 'direct connection' looks like), which would enhance completeness.
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?
Although the input schema covers all parameters (100% coverage), the description adds significant meaning: distinguishing exact vs fuzzy lookup, error conditions, and mixing rules. It goes beyond the schema's descriptions to clarify usage patterns.
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 'Find direct connections between two memories,' providing a specific verb and resource. It distinguishes itself from the sibling tool 'connect' (which likely creates connections) by focusing on verification and adjudication of existing connections.
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 advises when to use from_id/to_id for exact pair verification vs from_label/to_label for fuzzy lookup. It also directs users to audit(mode=archived) for archived memories and audit(mode=stale) for drift candidates, providing clear alternatives.
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.
5 tool updates
v1.54.16- Added
disconnect_all - Changed
history1 field changed- changed
Input schema / properties / group_by_domain / descriptionPrevious value: -"When true and order=modified with no domain, group results by domain (up to limit entries per domain). Ignored when memory_id is set."New value: +"When true and order=modified with no domain, group results by domain (up to limit entries per domain). Ignored when memory_id is set. Cannot be combined with node_kind — returns an error if both are set."
- Changed
orient1 field changed- changed
Input schema / properties / digest / descriptionPrevious value: -"When true, collapse list sections (rules, declared_spine, significant/relevant, recent) to compact text lines (always a string array). Default false."New value: +"When true, collapse list sections (rules, declared_spine, significant/relevant, recent) to compact text lines (always a string array). Default false. Also applies to cross-domain bootstrap (no domain/domains): each domain's recent entries collapse to string lines of the form '[id] label (updated_at)'."
- Added
restore_all - Changed
search1 field changed- changed
Input schema / properties / digest / descriptionPrevious value: -"When true, collapse each result memory to a single compact text line in a lines array instead of JSON objects — saves tokens on multi-result calls. Default false. Does not apply when exact: true (full content path). Each line includes id for recall(id) follow-up."New value: +"When true, collapse each result memory to a single compact text line in a lines array instead of JSON objects — saves tokens on multi-result calls. Default false. Does not apply when exact: true (full content path). Each line has the form: [id] label — excerpt (domain, node_kind). When semantic search is active, a distance score (0.00–1.00) is appended after two spaces — lower is closer. Each line includes id for recall(id) follow-up."
11 tool updates
v1.43.0- Removed
alias - Changed
connect2 fields changed- changed
Input schema / properties / items / items / properties / verdict / enumPrevious value: -[ - "false_positive", - "reconciled", - "supersedes" -]New value: +[ + "false_positive", + "reconciled", + "superseded" +] - changed
Input schema / properties / verdict / enumPrevious value: -[ - "false_positive", - "reconciled", - "supersedes" -]New value: +[ + "false_positive", + "reconciled", + "superseded" +]
- Added
disconnect - Added
domains - Changed
forget3 fields changed- changed
Input schema / properties / id / descriptionPrevious value: -"ID of the memory to archive"New value: +"ID of the memory to archive or un-archive" - changed
Input schema / properties / reason / descriptionPrevious value: -"Why this memory is being archived"New value: +"Required when archiving (when the unarchive flag is false). Why this memory is being archived" - added
Input schema / properties / restoreAdded value: +{ + "description": "When true, un-archive the memory so it surfaces in search again. When false or omitted, archive the memory.", + "type": "boolean" +}
- Changed
history9 fields changed- changed
Input schema / properties / digest / descriptionPrevious value: -"When true, collapse each result to a single compact text line in a lines array. Default false. Each line includes id and occurred_at when set."New value: +"When true, collapse each result to a single compact text line in a lines array. Default false." - changed
Input schema / properties / from / descriptionPrevious value: -"ISO8601 date or datetime. Filter to nodes whose effective date (COALESCE(occurred_at, created_at)) is on or after this value."New value: +"effective order only. ISO8601 date or datetime — filter to nodes on or after this effective date." - added
Input schema / properties / group_by_domainAdded value: +{ + "description": "When true and order=modified with no domain, group results by domain (up to limit entries per domain). Ignored when memory_id is set.", + "type": "boolean" +} - changed
Input schema / properties / important_only / descriptionPrevious value: -"When true, return only memories with occurred_at explicitly set (significant decisions and events). When false or absent, return all memories ordered by effective date."New value: +"effective order only. When true, return only memories with occurred_at explicitly set." - changed
Input schema / properties / limit / descriptionPrevious value: -"Max results (default 20)"New value: +"Max results (default 20 for effective, 10 for modified)" - changed
Input schema / properties / memory_id / descriptionPrevious value: -"Optional — scope the timeline to the neighbourhood of this memory (depth 2 by default, domain-clipped). Returns the workstream's chronological evolution from a known anchor. Takes precedence over domain if both are supplied."New value: +"Optional — scope to the neighbourhood of this memory (depth 2 by default, domain-clipped). Takes precedence over domain if both are supplied." - added
Input schema / properties / orderAdded value: +{ + "description": "Sort order. effective (default): by COALESCE(occurred_at, created_at). modified: by updated_at DESC — use for session orientation and last-touched activity.", + "enum": [ + "effective", + "modified" + ], + "type": "string" +} - changed
Input schema / properties / tags / descriptionPrevious value: -"Optional comma-separated list of tags to filter by. Only memories matching at least one tag are returned. Applies in both modes."New value: +"Optional comma-separated list of tags to filter by. Only memories matching at least one tag are returned." - changed
Input schema / properties / to / descriptionPrevious value: -"ISO8601 date or datetime. Filter to nodes whose effective date (COALESCE(occurred_at, created_at)) is on or before this value."New value: +"effective order only. ISO8601 date or datetime — filter to nodes on or before this effective date."
- Removed
recent - Removed
restore - Added
revise - Added
suggest_connections - Added
visualise
13 tool updates
v1.41.1- Changed
audit4 fields changed- changed
Input schema / properties / digest / descriptionPrevious value: -"When true, collapse multi-result lists to compact text lines (always a string array). Default false preserves current JSON shape."New value: +"When true, stale and orphans return {lines, results_truncated} instead of full objects. Default false." - changed
Input schema / properties / limit / descriptionPrevious value: -"Max candidates to return (default 10, applies to stale and conflicts modes)"New value: +"Max results. Defaults: stale=10, orphans=50, archived=25, conflicts=10. When results_truncated is true, raise limit to retrieve more. archived max 500; stale/orphans max 500; conflicts max 100." - changed
Input schema / properties / mode / descriptionPrevious value: -"Required: stale (drift candidates), orphans (isolated memories), archived (list archived memories), or conflicts (semantic contradiction candidates)"New value: +"Required: stale (drift candidates), orphans (isolated memories), archived (list archived memories), conflicts (semantic contradiction candidates), or kind_coverage (taxonomy health / migration readiness)" - changed
Input schema / properties / mode / enumPrevious value: -[ - "stale", - "orphans", - "archived", - "conflicts" -]New value: +[ + "stale", + "orphans", + "archived", + "conflicts", + "kind_coverage" +]
- Changed
connect3 fields changed- changed
Input schema / properties / items / descriptionPrevious value: -"Batch mode: array of edge objects. Each must have from_memory, to_memory, relationship (string). Optional: narrative (string)."New value: +"Batch mode: array of edge objects. Each must have from_memory, to_memory, relationship (string). Optional: narrative (string), verdict (string, resolved only)." - added
Input schema / properties / items / items / properties / verdictAdded value: +{ + "enum": [ + "false_positive", + "reconciled", + "supersedes" + ], + "type": "string" +} - added
Input schema / properties / verdictAdded value: +{ + "description": "Optional outcome classification when relationship=resolved. Ignored (not stored) for other relationship types, but invalid enum values are still rejected. Values: false_positive, reconciled, superseded.", + "enum": [ + "false_positive", + "reconciled", + "supersedes" + ], + "type": "string" +}
- Removed
disconnect - Removed
domains - Changed
orient1 field changed- added
Input schema / properties / limitAdded value: +{ + "description": "Cross-domain snapshot only — max recent entries per domain (default 5, max 500). Ignored when domain or domains is supplied.", + "type": "integer" +}
- Changed
remember2 fields changed- changed
Input schema / properties / items / descriptionPrevious value: -"Batch mode: array of memory objects to file in a single transaction. Each must have label (string, required) and domain (string, required). Optional: description, why_matters, tags (space-separated keywords), occurred_at (ISO8601 — in-session: set freely; inferred/back-dated: propose+confirm, never infer silently), node_kind (string: transient|reference|issue|decision|option|assumption|finding|standing|goal), transient (boolean, deprecated — maps to node_kind=transient), related_to (string ID, object with id+relationship, or array of either — connects at filing time; invalid IDs appear in skipped_connections)."New value: +"Batch mode: array of memory objects to file in a single transaction. Each must have label (string, required) and domain (string, required). Optional: description, why_matters, tags (space-separated keywords), occurred_at (ISO8601 — in-session: set freely; inferred/back-dated: propose+confirm, never infer silently), node_kind (string: transient|reference|issue|decision|option|assumption|finding|standing|goal — decisions resting on checked evidence need a separate finding + depends_on or caused_by link), transient (boolean, deprecated — maps to node_kind=transient), related_to (string ID, object with id+relationship, or array of either — connects at filing time; invalid IDs appear in skipped_connections). New domain: hides the memory from other domains' orient and domain-scoped search." - changed
Input schema / properties / node_kind / descriptionPrevious value: -"Classify this memory. 'decision' (default): a settled fact or choice. 'reference': an entity (person, system, org). 'issue': a problem or open question. 'option': a candidate answer to an issue. 'assumption': an unverified precondition. 'finding': an empirical observation. 'standing': a durable rule or constraint that governs other memories — appears in the rules section of orient. 'goal': a desired future state. 'transient': short-lived state — surfaced by audit(mode=stale) after 7 days."New value: +"Classify this memory. 'decision' (default): a settled fact or choice — if it rests on checked evidence, file a separate 'finding' and connect with depends_on or caused_by. 'reference': an entity (person, system, org). 'issue': a problem or open question. 'option': a candidate answer to an issue. 'assumption': an unverified precondition. 'finding': an empirical observation. 'standing': a durable rule or constraint that governs other memories — appears in the rules section of orient. 'goal': a desired future state. 'transient': short-lived state — surfaced by audit(mode=stale) after 7 days."
- Removed
rename_domain - Removed
revise - Changed
significance2 fields changed- added
Input schema / properties / declared_limitAdded value: +{ + "description": "Max declared and potentially_stale entries (default 100, max 500). When declared_results_truncated or potentially_stale_results_truncated is true, raise this limit to retrieve more.", + "type": "integer" +} - changed
Input schema / properties / limit / descriptionPrevious value: -"Top-N for structural ranking in domain mode (default 10). Ignored in memory_id mode — the neighbourhood is naturally bounded."New value: +"Top-N for structural ranking in domain mode (default 10). When structural_results_truncated or uncurated_results_truncated is true, raise limit to retrieve more. Ignored in memory_id mode — the neighbourhood is naturally bounded."
- Removed
suggest_connections - Removed
trace - Removed
visualise - Changed
why_connected6 fields changed- changed
Input schema / properties / domain / descriptionPrevious value: -"Optional domain to scope the search"New value: +"Optional domain to scope label search (ignored for id lookup)" - added
Input schema / properties / from_idAdded value: +{ + "description": "Exact ID of the first memory — preferred for pair verification", + "type": "string" +} - changed
Input schema / properties / from_label / descriptionPrevious value: -"Label or description of the first concept"New value: +"Label or description of the first concept (fuzzy best-match when from_id omitted)" - added
Input schema / properties / to_idAdded value: +{ + "description": "Exact ID of the second memory — preferred for pair verification", + "type": "string" +} - changed
Input schema / properties / to_label / descriptionPrevious value: -"Label or description of the second concept"New value: +"Label or description of the second concept (fuzzy best-match when to_id omitted)" - removed
Input schema / requiredRemoved value: -[ - "from_label", - "to_label" -]
1 tool update
v1.38.2- Changed
connect2 fields changed- changed
Input schema / properties / relationship / descriptionPrevious value: -"Type of relationship. Required in single mode."New value: +"Type of relationship. Required in single mode. Use resolved (or resolved_by / supersedes) to adjudicate a contradicts pair — additive, does not remove the contradicts edge." - changed
Input schema / properties / relationship / enumPrevious value: -[ - "caused_by", - "led_to", - "blocked_by", - "unblocks", - "connects_to", - "contradicts", - "depends_on", - "is_example_of", - "governed_by" -]New value: +[ + "caused_by", + "led_to", + "blocked_by", + "unblocks", + "connects_to", + "contradicts", + "depends_on", + "is_example_of", + "governed_by", + "resolved", + "resolved_by", + "supersedes" +]
7 tool updates
v1.34.1- Changed
audit7 fields changed- changed
Input schema / properties / domain / descriptionPrevious value: -"Optional domain to scope the audit"New value: +"Optional domain to scope the audit. Omit to scan the entire workspace. Use for cross-domain drift review; scope to a domain for focused maintenance passes." - changed
Input schema / properties / limit / descriptionPrevious value: -"Max candidates to return (default 10, applies to stale mode)"New value: +"Max candidates to return (default 10, applies to stale and conflicts modes)" - changed
Input schema / properties / memory_id / descriptionPrevious value: -"Anchor memory ID. Scopes stale candidates to the depth-2 BFS neighbourhood of this memory. Applies to mode=stale only; ignored for orphans and archived."New value: +"Anchor memory ID. Scopes stale candidates to the depth-2 BFS neighbourhood of this memory. Applies to mode=stale only; ignored for orphans, archived, and conflicts." - changed
Input schema / properties / mode / descriptionPrevious value: -"Required: stale (drift candidates), orphans (isolated memories), or archived (list archived memories)"New value: +"Required: stale (drift candidates), orphans (isolated memories), archived (list archived memories), or conflicts (semantic contradiction candidates)" - changed
Input schema / properties / mode / enumPrevious value: -[ - "stale", - "orphans", - "archived" -]New value: +[ + "stale", + "orphans", + "archived", + "conflicts" +] - added
Input schema / properties / node_kindAdded value: +{ + "description": "Optional filter by node_kind. Space-separated for OR match. Applies to all four modes.", + "type": "string" +} - changed
Input schema / properties / tags / descriptionPrevious value: -"Comma-separated tags. Only surfaces candidates carrying at least one of the supplied tags. OR semantics. Applies to all three modes."New value: +"Comma-separated tags. Only surfaces candidates carrying at least one of the supplied tags. OR semantics. Applies to all four modes."
- Changed
history1 field changed- added
Input schema / properties / node_kindAdded value: +{ + "description": "Optional filter by node_kind. Space-separated for OR match.", + "type": "string" +}
- Changed
orient3 fields changed- changed
Input schema / properties / domain / descriptionPrevious value: -"Optional — omit for a cross-domain snapshot to find where work was last happening. Provide to get the full three-section orient for a specific domain."New value: +"Optional — provide to get the full orient for a single domain. Mutually exclusive with domains. Omit both for a cross-domain snapshot." - added
Input schema / properties / domainsAdded value: +{ + "description": "Optional — array of 1–5 domain names for multi-domain full orient in one call. Mutually exclusive with domain. Length 1 returns the same shape as domain=X. Length 2–5 returns an orientations array. Unknown domain names return empty sections rather than errors. topic applies to all domains.", + "items": { + "type": "string" + }, + "type": "array" +} - changed
Input schema / properties / topic / descriptionPrevious value: -"Optional — the user's current question or task. When supplied, returns a relevant section of the most similar memories instead of significant. Pass topic when the session has a known purpose."New value: +"Optional — the user's current question or task. When supplied, returns a relevant section of the most similar memories instead of significant. Applies to all domains when using the domains array. Pass topic when the session has a known purpose."
- Changed
recent1 field changed- added
Input schema / properties / node_kindAdded value: +{ + "description": "Optional filter by node_kind. Space-separated for OR match.", + "type": "string" +}
- Changed
revise5 fields changed- added
Input schema / properties / domainAdded value: +{ + "description": "Move this memory to a different domain. Requires reason. Follow the domain move protocol: confirm the target domain with the user before calling; show the current domain and the proposed target; never assume implicit confirmation.", + "type": "string" +} - changed
Input schema / properties / items / descriptionPrevious value: -"Batch mode: array of update objects. Each must have id (string, required). Optional: label, description, why_matters, tags, occurred_at (ISO8601 — in-session: set freely; inferred/back-dated: propose+confirm, never infer silently), node_kind (string: transient|reference|issue|decision|option|assumption|finding|standing|goal), transient (boolean, deprecated — true maps to node_kind=transient, false to node_kind=decision)."New value: +"Batch mode: array of update objects. Each must have id (string, required). Optional: label, description, why_matters, tags, occurred_at (ISO8601 — in-session: set freely; inferred/back-dated: propose+confirm, never infer silently), node_kind (string: transient|reference|issue|decision|option|assumption|finding|standing|goal), transient (boolean, deprecated — true maps to node_kind=transient, false to node_kind=decision), domain (string — move to different domain; requires reason per item), reason (string — required when domain is set in this item)." - added
Input schema / properties / items / items / properties / domainAdded value: +{ + "type": "string" +} - added
Input schema / properties / items / items / properties / reasonAdded value: +{ + "type": "string" +} - added
Input schema / properties / reasonAdded value: +{ + "description": "Required when domain is set. Explain why the domain change is needed. Recorded in the audit log as 'domain (was OLD → NEW): reason'. Record the user's stated reason verbatim.", + "type": "string" +}
- Changed
search4 fields changed- changed
Input schema / properties / domain / descriptionPrevious value: -"Optional domain to scope search"New value: +"Optional domain to scope search. Omit to search the entire workspace across all domains. Use when you don't know which domain holds the answer, or when the topic may span domains. Scope to a single domain when you know it — results are cleaner and faster." - added
Input schema / properties / node_kindAdded value: +{ + "description": "Optional filter by node_kind. Space-separated for OR match (e.g. 'decision standing'). When set without query, lists matching memories ordered by updated_at DESC.", + "type": "string" +} - changed
Input schema / properties / query / descriptionPrevious value: -"Terms to search for. Must use vocabulary that appears in the stored label, description, why_matters, or tags. Conceptual paraphrases that don't share vocabulary with the stored content will not match. For unique identifiers or ticket numbers known to appear verbatim, also set exact: true."New value: +"Terms to search for. Must use vocabulary that appears in the stored label, description, why_matters, or tags. Required unless node_kind is set alone (lists by kind). For unique identifiers known to appear verbatim, also set exact: true." - removed
Input schema / requiredRemoved value: -[ - "query" -]
- Changed
significance1 field changed- added
Input schema / properties / node_kindAdded value: +{ + "description": "Optional filter by node_kind. Space-separated for OR match. Applies to significance and trust modes in domain scope.", + "type": "string" +}
6 tool updates
v1.34.0- Changed
audit1 field changed- added
Input schema / properties / digestAdded value: +{ + "description": "When true, collapse multi-result lists to compact text lines (always a string array). Default false preserves current JSON shape.", + "type": "boolean" +}
- Changed
history1 field changed- added
Input schema / properties / digestAdded value: +{ + "description": "When true, collapse each result to a single compact text line in a lines array. Default false. Each line includes id and occurred_at when set.", + "type": "boolean" +}
- Changed
orient1 field changed- added
Input schema / properties / digestAdded value: +{ + "description": "When true, collapse list sections (rules, declared_spine, significant/relevant, recent) to compact text lines (always a string array). Default false.", + "type": "boolean" +}
- Changed
recent1 field changed- added
Input schema / properties / digestAdded value: +{ + "description": "When true, collapse each result to a single compact text line in a lines array (or lines per domain when group_by_domain=true). Default false.", + "type": "boolean" +}
- Changed
search1 field changed- added
Input schema / properties / digestAdded value: +{ + "description": "When true, collapse each result memory to a single compact text line in a lines array instead of JSON objects — saves tokens on multi-result calls. Default false. Does not apply when exact: true (full content path). Each line includes id for recall(id) follow-up.", + "type": "boolean" +}
- Changed
significance1 field changed- added
Input schema / properties / digestAdded value: +{ + "description": "When true, collapse each section's memories to compact text lines instead of JSON objects. Default false.", + "type": "boolean" +}
3 tool updates
v1.33.0- Changed
remember6 fields changed- removed
Input schema / properties / decision_typeRemoved value: -{ - "description": "Classify this memory. 'decision' (default): a fact, finding, or decision. 'transient': short-lived state (ticket notes, sprint state) — surfaced by audit(mode=stale) after 7 days. 'standing': a durable rule or constraint that governs other memories — appears in the rules section of orient.", - "enum": [ - "decision", - "transient", - "standing" - ], - "type": "string" -} - changed
Input schema / properties / items / descriptionPrevious value: -"Batch mode: array of memory objects to file in a single transaction. Each must have label (string, required) and domain (string, required). Optional: description, why_matters, tags (space-separated keywords), occurred_at (ISO8601 — in-session: set freely; inferred/back-dated: propose+confirm, never infer silently), decision_type (string: decision|transient|standing), transient (boolean, deprecated — maps to decision_type=transient), related_to (string ID, object with id+relationship, or array of either — connects at filing time; invalid IDs appear in skipped_connections)."New value: +"Batch mode: array of memory objects to file in a single transaction. Each must have label (string, required) and domain (string, required). Optional: description, why_matters, tags (space-separated keywords), occurred_at (ISO8601 — in-session: set freely; inferred/back-dated: propose+confirm, never infer silently), node_kind (string: transient|reference|issue|decision|option|assumption|finding|standing|goal), transient (boolean, deprecated — maps to node_kind=transient), related_to (string ID, object with id+relationship, or array of either — connects at filing time; invalid IDs appear in skipped_connections)." - removed
Input schema / properties / items / items / properties / decision_typeRemoved value: -{ - "enum": [ - "decision", - "transient", - "standing" - ], - "type": "string" -} - added
Input schema / properties / items / items / properties / node_kindAdded value: +{ + "enum": [ + "transient", + "reference", + "issue", + "decision", + "option", + "assumption", + "finding", + "standing", + "goal" + ], + "type": "string" +} - added
Input schema / properties / node_kindAdded value: +{ + "description": "Classify this memory. 'decision' (default): a settled fact or choice. 'reference': an entity (person, system, org). 'issue': a problem or open question. 'option': a candidate answer to an issue. 'assumption': an unverified precondition. 'finding': an empirical observation. 'standing': a durable rule or constraint that governs other memories — appears in the rules section of orient. 'goal': a desired future state. 'transient': short-lived state — surfaced by audit(mode=stale) after 7 days.", + "enum": [ + "transient", + "reference", + "issue", + "decision", + "option", + "assumption", + "finding", + "standing", + "goal" + ], + "type": "string" +} - changed
Input schema / properties / transient / descriptionPrevious value: -"Deprecated — use decision_type='transient' instead. Accepted for backward compatibility: if true and decision_type is not set, maps to decision_type='transient'."New value: +"Deprecated — use node_kind='transient' instead. Accepted for backward compatibility: if true and node_kind is not set, maps to node_kind='transient'."
- Changed
revise6 fields changed- removed
Input schema / properties / decision_typeRemoved value: -{ - "description": "Classify this memory. 'decision' (default): a fact, finding, or decision. 'transient': short-lived state, surfaced by audit(mode=stale) after 7 days. 'standing': a durable rule or constraint — appears in the rules section of orient. Omit to leave unchanged.", - "enum": [ - "decision", - "transient", - "standing" - ], - "type": "string" -} - changed
Input schema / properties / items / descriptionPrevious value: -"Batch mode: array of update objects. Each must have id (string, required). Optional: label, description, why_matters, tags, occurred_at (ISO8601 — in-session: set freely; inferred/back-dated: propose+confirm, never infer silently), decision_type (string: decision|transient|standing), transient (boolean, deprecated — true maps to decision_type=transient, false to decision_type=decision)."New value: +"Batch mode: array of update objects. Each must have id (string, required). Optional: label, description, why_matters, tags, occurred_at (ISO8601 — in-session: set freely; inferred/back-dated: propose+confirm, never infer silently), node_kind (string: transient|reference|issue|decision|option|assumption|finding|standing|goal), transient (boolean, deprecated — true maps to node_kind=transient, false to node_kind=decision)." - removed
Input schema / properties / items / items / properties / decision_typeRemoved value: -{ - "enum": [ - "decision", - "transient", - "standing" - ], - "type": "string" -} - added
Input schema / properties / items / items / properties / node_kindAdded value: +{ + "enum": [ + "transient", + "reference", + "issue", + "decision", + "option", + "assumption", + "finding", + "standing", + "goal" + ], + "type": "string" +} - added
Input schema / properties / node_kindAdded value: +{ + "description": "Classify this memory. 'decision' (default): a settled fact or choice. 'reference': an entity (person, system, org). 'issue': a problem or open question. 'option': a candidate answer to an issue. 'assumption': an unverified precondition. 'finding': an empirical observation. 'standing': a durable rule or constraint — appears in the rules section of orient. 'goal': a desired future state. 'transient': short-lived state, surfaced by audit(mode=stale) after 7 days. Omit to leave unchanged.", + "enum": [ + "transient", + "reference", + "issue", + "decision", + "option", + "assumption", + "finding", + "standing", + "goal" + ], + "type": "string" +} - changed
Input schema / properties / transient / descriptionPrevious value: -"Deprecated — use decision_type instead. Accepted for backward compatibility: true maps to decision_type='transient', false maps to decision_type='decision'. Omit to leave unchanged."New value: +"Deprecated — use node_kind instead. Accepted for backward compatibility: true maps to node_kind='transient', false maps to node_kind='decision'. Omit to leave unchanged."
- Changed
significance1 field changed- added
Input schema / properties / modeAdded value: +{ + "description": "Default 'significance' returns the existing four-section dual-signal analysis. 'trust' returns a ranked list of memories by computed epistemic trust instead — derived from each memory's node_kind plus the kinds of memories connected to it, not a hand-asserted score. A contradicts edge lowers trust; other relationships raise it.", + "enum": [ + "significance", + "trust" + ], + "type": "string" +}
7 tool updates
v1.29.0- Changed
audit2 fields changed- added
Input schema / properties / memory_idAdded value: +{ + "description": "Anchor memory ID. Scopes stale candidates to the depth-2 BFS neighbourhood of this memory. Applies to mode=stale only; ignored for orphans and archived.", + "type": "string" +} - added
Input schema / properties / tagsAdded value: +{ + "description": "Comma-separated tags. Only surfaces candidates carrying at least one of the supplied tags. OR semantics. Applies to all three modes.", + "type": "string" +}
- Changed
connect1 field changed- changed
Input schema / properties / relationship / enumPrevious value: -[ - "caused_by", - "led_to", - "blocked_by", - "unblocks", - "connects_to", - "contradicts", - "depends_on", - "is_example_of" -]New value: +[ + "caused_by", + "led_to", + "blocked_by", + "unblocks", + "connects_to", + "contradicts", + "depends_on", + "is_example_of", + "governed_by" +]
- Changed
orient1 field changed- added
Input schema / properties / topicAdded value: +{ + "description": "Optional — the user's current question or task. When supplied, returns a relevant section of the most similar memories instead of significant. Pass topic when the session has a known purpose.", + "type": "string" +}
- Changed
recent2 fields changed- added
Input schema / properties / memory_idAdded value: +{ + "description": "Anchor memory ID. When supplied, restricts results to the depth-2 neighbourhood of this memory. group_by_domain is ignored when this is set.", + "type": "string" +} - added
Input schema / properties / tagsAdded value: +{ + "description": "Comma-separated tag filter. Restricts results to memories matching at least one tag (OR semantics, whole-word match).", + "type": "string" +}
- Changed
remember4 fields changed- added
Input schema / properties / decision_typeAdded value: +{ + "description": "Classify this memory. 'decision' (default): a fact, finding, or decision. 'transient': short-lived state (ticket notes, sprint state) — surfaced by audit(mode=stale) after 7 days. 'standing': a durable rule or constraint that governs other memories — appears in the rules section of orient.", + "enum": [ + "decision", + "transient", + "standing" + ], + "type": "string" +} - changed
Input schema / properties / items / descriptionPrevious value: -"Batch mode: array of memory objects to file in a single transaction. Each must have label (string, required) and domain (string, required). Optional: description, why_matters, tags (space-separated keywords), occurred_at (ISO8601 — in-session: set freely; inferred/back-dated: propose+confirm, never infer silently), transient (boolean), related_to (string ID, object with id+relationship, or array of either — connects at filing time; invalid IDs appear in skipped_connections)."New value: +"Batch mode: array of memory objects to file in a single transaction. Each must have label (string, required) and domain (string, required). Optional: description, why_matters, tags (space-separated keywords), occurred_at (ISO8601 — in-session: set freely; inferred/back-dated: propose+confirm, never infer silently), decision_type (string: decision|transient|standing), transient (boolean, deprecated — maps to decision_type=transient), related_to (string ID, object with id+relationship, or array of either — connects at filing time; invalid IDs appear in skipped_connections)." - added
Input schema / properties / items / items / properties / decision_typeAdded value: +{ + "enum": [ + "decision", + "transient", + "standing" + ], + "type": "string" +} - changed
Input schema / properties / transient / descriptionPrevious value: -"Set to true for short-lived knowledge: ticket state, sprint notes, or anything expected to become stale within days. Transient memories older than 7 days are surfaced by audit(mode=stale) as archiving candidates."New value: +"Deprecated — use decision_type='transient' instead. Accepted for backward compatibility: if true and decision_type is not set, maps to decision_type='transient'."
- Changed
revise4 fields changed- added
Input schema / properties / decision_typeAdded value: +{ + "description": "Classify this memory. 'decision' (default): a fact, finding, or decision. 'transient': short-lived state, surfaced by audit(mode=stale) after 7 days. 'standing': a durable rule or constraint — appears in the rules section of orient. Omit to leave unchanged.", + "enum": [ + "decision", + "transient", + "standing" + ], + "type": "string" +} - changed
Input schema / properties / items / descriptionPrevious value: -"Batch mode: array of update objects. Each must have id (string, required). Optional: label, description, why_matters, tags, occurred_at (ISO8601 — in-session: set freely; inferred/back-dated: propose+confirm, never infer silently), transient (boolean — true for short-lived, false to promote to permanent)."New value: +"Batch mode: array of update objects. Each must have id (string, required). Optional: label, description, why_matters, tags, occurred_at (ISO8601 — in-session: set freely; inferred/back-dated: propose+confirm, never infer silently), decision_type (string: decision|transient|standing), transient (boolean, deprecated — true maps to decision_type=transient, false to decision_type=decision)." - added
Input schema / properties / items / items / properties / decision_typeAdded value: +{ + "enum": [ + "decision", + "transient", + "standing" + ], + "type": "string" +} - changed
Input schema / properties / transient / descriptionPrevious value: -"Set to true for short-lived knowledge; set to false to promote a transient memory to permanent. Omit to leave the current value unchanged."New value: +"Deprecated — use decision_type instead. Accepted for backward compatibility: true maps to decision_type='transient', false maps to decision_type='decision'. Omit to leave unchanged."
- Changed
search1 field changed- added
Input schema / properties / memory_idAdded value: +{ + "description": "Anchor memory ID. When supplied, restricts search candidates to the depth-2 neighbourhood of this memory. Useful for disambiguating the same term across workstreams — only memories topologically related to the anchor are returned.", + "type": "string" +}
1 tool update
v1.22.0- Changed
history3 fields changed- added
Input schema / properties / depthAdded value: +{ + "description": "Neighbourhood depth when using memory_id (default 2).", + "type": "integer" +} - changed
Input schema / properties / domain / descriptionPrevious value: -"Optional domain to scope"New value: +"Optional domain to scope. Not required when memory_id is supplied." - added
Input schema / properties / memory_idAdded value: +{ + "description": "Optional — scope the timeline to the neighbourhood of this memory (depth 2 by default, domain-clipped). Returns the workstream's chronological evolution from a known anchor. Takes precedence over domain if both are supplied.", + "type": "string" +}
1 tool update
v1.21.0- Changed
significance6 fields changed- added
Input schema / properties / depthAdded value: +{ + "description": "Neighbourhood depth when using memory_id (default 2). Depth 1 produces near-uniform low scores and must not be used as default.", + "type": "integer" +} - changed
Input schema / properties / domain / descriptionPrevious value: -"Domain to analyse. Required."New value: +"Domain to analyse. Required unless memory_id is supplied." - changed
Input schema / properties / limit / descriptionPrevious value: -"Top-N for structural ranking (default 10)."New value: +"Top-N for structural ranking in domain mode (default 10). Ignored in memory_id mode — the neighbourhood is naturally bounded." - added
Input schema / properties / memory_idAdded value: +{ + "description": "Optional — scope significance to a memory's neighbourhood (depth 2 by default, domain-clipped). Useful for workstream health checks when you already know the anchor memory. Takes precedence over domain if both are supplied.", + "type": "string" +} - added
Input schema / properties / tagsAdded value: +{ + "description": "Optional comma-separated list of tags to filter by. Only memories matching at least one tag are included in the analysis. Applies in domain mode. Examples: 'architecture,security' or 'release'.", + "type": "string" +} - removed
Input schema / requiredRemoved value: -[ - "domain" -]
2 tool updates
v1.20.0- Changed
orient2 fields changed- changed
Input schema / properties / domain / descriptionPrevious value: -"The domain to summarise"New value: +"Optional — omit for a cross-domain snapshot to find where work was last happening. Provide to get the full three-section orient for a specific domain." - removed
Input schema / requiredRemoved value: -[ - "domain" -]
- Changed
revise3 fields changed- changed
Input schema / properties / items / descriptionPrevious value: -"Batch mode: array of update objects. Each must have id (string, required). Optional: label, description, why_matters, tags, occurred_at (ISO8601 — in-session: set freely; inferred/back-dated: propose+confirm, never infer silently)."New value: +"Batch mode: array of update objects. Each must have id (string, required). Optional: label, description, why_matters, tags, occurred_at (ISO8601 — in-session: set freely; inferred/back-dated: propose+confirm, never infer silently), transient (boolean — true for short-lived, false to promote to permanent)." - added
Input schema / properties / items / items / properties / transientAdded value: +{ + "type": "boolean" +} - added
Input schema / properties / transientAdded value: +{ + "description": "Set to true for short-lived knowledge; set to false to promote a transient memory to permanent. Omit to leave the current value unchanged.", + "type": "boolean" +}
1 tool update
v1.19.0- Changed
search2 fields changed- added
Input schema / properties / exactAdded value: +{ + "description": "When true, bypass semantic ranking and use pure substring (LIKE) matching only. Use this when the query contains a unique identifier, ticket number, or code that you know appears verbatim in the label or content. Results will not include a semantic_distance field.", + "type": "boolean" +} - changed
Input schema / properties / query / descriptionPrevious value: -"Terms to search for. Must use vocabulary that appears in the stored label, description, why_matters, or tags. Conceptual paraphrases that don't share vocabulary with the stored content will not match."New value: +"Terms to search for. Must use vocabulary that appears in the stored label, description, why_matters, or tags. Conceptual paraphrases that don't share vocabulary with the stored content will not match. For unique identifiers or ticket numbers known to appear verbatim, also set exact: true."
21 tool updates
v1.18.1- Added
alias - Added
audit - Added
connect - Added
disconnect - Added
domains - Added
forget - Added
forget_all - Added
history - Added
orient - Added
recall - Added
recent - Added
remember - Added
rename_domain - Added
restore - Added
revise - Added
search - Added
significance - Added
suggest_connections - Added
trace - Added
visualise - Added
why_connected
TDQS
Scored across 18 tools
Most tools have distinct purposes (remember, search, recall, connect, disconnect, audit, orient, history, significance, domains, visualise), but remember/revise/forget/forget_all/restore_all overlap somewhat in the memory lifecycle space, and connect/disconnect/disconnect_all/why_connected form a cluster that could confuse. The descriptions are detailed enough to mostly disambiguate, but the batch variants (forget_all, restore_all, disconnect_all) and single variants create some boundary ambiguity.
The naming is a mix of bare verbs (remember, recall, search, orient, audit, connect, disconnect, forget, revise, history, domains, visualise) and verb_verb or verb_noun compounds (forget_all, restore_all, disconnect_all, suggest_connections, why_connected). There's no consistent verb_noun pattern; some are single-word verbs, some are imperative phrases. The naming is readable and mostly intuitive, but the convention is inconsistent across the set.
18 tools is on the higher end but appropriate for a memory/knowledge graph server that needs CRUD for nodes, edges, search, audit, orientation, and visualization. Each tool serves a distinct function in the memory lifecycle, though the batch variants (forget_all, restore_all, disconnect_all) could arguably be folded into their single counterparts.
The tool surface covers the full memory lifecycle: create (remember), read (search, recall, orient, history, significance, why_connected), update (revise), delete/archive (forget, forget_all, restore_all), connection management (connect, disconnect, disconnect_all, suggest_connections), health/audit (audit), domain administration (domains), and visualization (visualise). No obvious dead ends or missing operations for a memory graph server.
Maintenance
Related MCP Connectors
Persistent, portable memory for AI assistants — your private memory graph, from any MCP client.
Persistent memory for AI agents to retain, retrieve, and recall conversation context through MCP.
An MCP memory server. One memory your agents share — across models, devices and apps.
Cross-session memory for AI agents with a Source Receipt for every memory, over MCP.
Related MCP Servers
- AlicenseAqualityAmaintenancePersistent memory for AI agents with sectioned entries (project/user/context/etc), semantic search, CLI, and per-project scope. Local JSON, zero config, no server required.1288 PyPI5MIT
- AlicenseNot gradedqualityDmaintenanceA local AI memory system that stores all conversations verbatim and organizes them into navigable structures. It provides 19 MCP tools for AI assistants to search and retrieve past decisions, debugging sessions, and architecture debates automatically.MIT
- AlicenseAqualityAmaintenanceCognitive memory engine for AI agents with 5,100+ knowledge modules, circadian rhythm awareness, emotional state tracking (PAD model), and hybrid semantic search. Supports persistent per-user memory, project-scoped contexts, and multi-protocol access.2623Apache 2.0
- AlicenseNot gradedqualityCmaintenanceAn MCP server that lets coding agents build and query a persistent knowledge graph of concepts, architecture, and decisions, enabling them to remember across sessions.480 npm712MIT