{
  "markdown": "# palace-rs\n\n[![CI](https://github.com/AncientiCe/palace-rs/actions/workflows/ci.yml/badge.svg)](https://github.com/AncientiCe/palace-rs/actions/workflows/ci.yml)\n[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n[![Rust 1.82+](https://img.shields.io/badge/rust-1.82%2B-orange.svg)](https://www.rust-lang.org)\n\nA local-first memory retrieval engine for coding agents, implemented in Rust.\n\nThis project stores verbatim project and conversation memory, embeds it locally,\nand retrieves source-grounded context through MCP. It is built for coding agents\nthat need to remember decisions, prior fixes, commands, project conventions, and\nuser preferences across sessions without running a separate vector database.\n\n## What It Does\n\n- Stores project files and conversation turns in a local SQLite database.\n- Generates local embeddings with ONNX Runtime and `all-MiniLM-L6-v2`.\n- Retrieves memories with hybrid semantic/BM25 search plus coding-agent intent boosts.\n- Tags preference-shaped drawers and runs a dedicated preference recall pass for\n  fuzzy \"what do I prefer?\" and convention questions.\n- Stores preference spans with optional secondary embeddings and exposes a\n  `preference_match` score for preference-shaped queries.\n- Classifies search intent (`preference`, `decision`, `how_to`, `definition`,\n  `temporal`, `unknown`) and can optionally rerank top results with a local\n  interaction reranker.\n- Sanitizes agent-generated query dumps before retrieval.\n- Returns source-grounded results with score provenance and nearby source context.\n- Warms up agents from recent diary entries with project, topic, timestamp, tags,\n  and compact session text.\n- Provides a knowledge graph for temporal entity relationships.\n- Measures real-world usefulness through `palace gain` precision metrics and\n  optional folded feedback on the existing `palace_gain` MCP tool.\n- Exposes MCP tools for assistants that support Model Context Protocol.\n- Offers a small Rust library API for embedding memory into other services.\n- Tracks a first-class wings registry (project vs. topic wings) with on-demand\n  project mining and topic-wing creation.\n- Pins the nine protocol-critical MCP tools resident with `alwaysLoad` so the\n  memory protocol doesn't depend on tool-search deferral (Claude Code >= 2.1.121).\n- Injects real recalled memory — recent diary entries plus top drawers for the\n  session's project — directly into `SessionStart`, not just protocol text.\n\n## Agent Memory Reliability\n\nPalace focuses on the retrieval cases that matter most during coding\nwork: preferences, project conventions, recent session continuity,\nsource-grounded answers, and measurable usefulness in real agent sessions.\nDrawers that look like user preferences or conventions are tagged in metadata\nduring writes and updates, record the matched preference span, and can store a\nsecondary preference embedding. Preference-shaped queries receive a dedicated\n`preference_match` score alongside hybrid semantic/BM25 search.\n\nMCP search responses expose score provenance (`combined`, `cosine`, `bm25`, and\n`coding_boost`, `preference_match`, optional `rerank_score`, and `intent`) plus\nadjacent source context so agents can cite why a memory was returned. Diary tools\nprovide warm-start context for recent sessions, including project path, topic,\ntimestamp, session ID, tags, and compact text.\n\nLibrary consumers can use `Palace::search_with_provenance` when they need the\nsame structured score details that MCP tools return.\n\n## Storage\n\nCollapses Python's dual-store (ChromaDB + SQLite) into **one file** at `~/.palace/palace.db`:\n\n| Table | Purpose |\n|---|---|\n| `drawers` | Text content + embedding BLOB + metadata |\n| `entities` | KG entity nodes |\n| `triples` | KG temporal relationship edges |\n\nEmbeddings are stored as `f32` vectors from `all-MiniLM-L6-v2`. Search uses local cosine similarity over the stored vectors.\n\n---\n\n## Benchmarks\n\n### Coding-Agent Memory Eval\n\nThe repository includes a focused eval fixture for practical coding-agent memory\nquestions. It stores realistic memories about project decisions, prior failures,\ncommands, conventions, user preferences, and current direction, then asks 40\nquestions such as:\n\n- why did we choose bundled sqlite?\n- how did we fix the migration test failure last time?\n- what clippy command should I run?\n- what is the project convention for search results?\n- what changed in the current product direction?\n\nRun it with:\n\n```bash\ncargo test --test coding_agent_eval -- --nocapture\n```\n\nThe test reports `recall@1` and `recall@5` and fails if retrieval drops below the\nstable threshold. This is the product-shaped proof: not broad memory theater,\nbut whether a coding agent can recover the right project context when it matters.\n\n### LongMemEval\n\nRetrieval recall on the LongMemEval `s_cleaned` split — 500 questions over conversational haystacks of ~50 sessions / ~115k tokens each (30 abstention questions are filtered out per the standard convention, leaving 470 evaluated).\n\nThe recipe behind the numbers below:\n\n- **Granularity**: one drawer per session.\n- **Indexed content**: the **full session** — both user and assistant turns are stored and embedded together. No user-turn filtering, no summarization, no LLM extraction.\n- **Embedder**: `all-MiniLM-L6-v2` (384-dim, ONNX), 512-token cap, run locally — no API calls.\n- **Retrieval**: **hybrid baseline** — BM25 (k1=1.5, b=0.75, weight 0.35) fused with cosine similarity (weight 0.65), top-K = 10. These reported LongMemEval numbers used pure score fusion, before the coding-agent intent boosts used by current project-memory search.\n- **No LLM at any stage**: no extraction, no rerank, no answer generation. The recall numbers measure the retriever in isolation.\n- **Metric**: `recall_any@K` at session granularity — does any gold session appear in the top-K results?\n- **Hardware**: Apple M1 Pro, 10 cores (8P + 2E), 32 GB RAM.\n\n| Split | R@1 | R@5 | R@10 |\n|---|---:|---:|---:|\n| `longmemeval_oracle` (sanity check) | 1.000 | 1.000 | 1.000 |\n| `longmemeval_s_cleaned` | **0.889** | **0.981** | **0.991** |\n\nPer-question-type on `s_cleaned`:\n\n| Question type | R@1 | R@5 | R@10 |\n|---|---:|---:|---:|\n| knowledge-update | 0.944 | 1.000 | 1.000 |\n| multi-session | 0.909 | 0.983 | 1.000 |\n| single-session-assistant | 1.000 | 1.000 | 1.000 |\n| single-session-preference | 0.633 | 0.867 | 0.933 |\n| single-session-user | 0.922 | 1.000 | 1.000 |\n| temporal-reasoning | 0.835 | 0.976 | 0.984 |\n\n### Reading the numbers\n\n- **`oracle` is a sanity check, not a real result.** That split hands the retriever only the sessions known to contain the answer, so perfect recall just confirms the pipeline is wired up correctly.\n- **`s_cleaned` is the real test.** ~50 sessions / ~115k tokens of conversational haystack per question, no hints. R@5 = 0.981 means that for 461 of 470 evaluated questions, a gold session appears somewhere in the top 5 retrieved.\n- **R@1 → R@5 → R@10 tells you where the failures cluster.** The jump from 0.889 to 0.981 means most \"misses\" at top-1 are near-misses — the right session is usually rank 2–5, displaced by a lexically similar distractor. The further jump to 0.991 at top-10 means only ~9 questions out of 470 fall outside the top-10 entirely; those are the genuinely hard cases.\n- **Per-question-type breakdown is where the model's blind spots show.**\n  - `single-session-assistant`, `single-session-user`, `knowledge-update`: ≥0.94 at R@1, ≈1.0 at R@5. The retriever handles direct questions where the answer is stated verbatim in one session.\n  - `multi-session` and `temporal-reasoning`: strong at R@5 (~0.98) but lower at R@1 (~0.83–0.91). Multiple sessions are relevant and the \"best\" one is a judgement call — top-1 ranking among near-equivalents is genuinely ambiguous.\n  - `single-session-preference`: the visible weak spot at 0.633 / 0.867 / 0.933. Preference questions (\"what's my favorite X\") are answered by sentences like *\"I like…\"* / *\"I prefer…\"* that don't share keywords with the question. Pure BM25 + frozen MiniLM has no signal for preference-shaped sentences specifically; closing this gap would require either an LLM-extracted preference index or a hand-rolled pattern booster.\n- **What's deliberately *not* in these LongMemEval numbers.** No LLM at any stage — no extraction during ingest, no query rewriting, no rerank, no answer generation. No per-dataset hyperparameter tuning. No GPU. The result is the baseline retriever in isolation, on a single CPU, with fixed defaults.\n\n---\n\n## Installation\n\n### Homebrew (macOS Apple Silicon / Linux)\n\n```bash\nbrew tap AncientiCe/palace\nbrew install palace\n\n# Configure MCP servers\npalace install --all\n```\n\n**Note**: macOS Intel is not supported due to ONNX Runtime unavailability. Apple Silicon and Linux x86_64 are fully supported.\n\n### Install Script (macOS / Linux / Windows)\n\n**macOS / Linux:**\n```bash\ncurl -fsSL https://raw.githubusercontent.com/AncientiCe/palace-rs/main/scripts/install.sh | sh\n```\n\n**Windows:**\n```powershell\nirm https://raw.githubusercontent.com/AncientiCe/palace-rs/main/scripts/install.ps1 | iex\n```\n\nThe installer downloads the matching GitHub Release binary, verifies its SHA-256\nchecksum, installs it locally, and registers the MCP server with Cursor, Codex,\nand Claude Code.\n\n### MCP Registry / MCPB bundle\n\nPalace is published to the official [MCP registry](https://registry.modelcontextprotocol.io)\nas `io.github.ancientice/palace-rs`. Registry-aware clients can discover and\ninstall it directly. Each release also ships a self-contained `palace-<version>.mcpb`\nbundle (Linux x86_64, macOS arm64, Windows x86_64) as a GitHub Release asset for\none-click install in MCPB-aware hosts such as Claude Desktop.\n\n### Development Install\n\n```bash\ncargo install --path .\npalace install\n```\n\nThe first time you run `mine`, the embedding model is downloaded automatically from HuggingFace and cached.\n\n> **Upgrading from `mempalace` (≤ 0.1.9)?** See [Migrating from `mempalace` to `palace`](#migrating-from-mempalace-to-palace). The legacy `mempalace` shim binary and `MEMPALACE_*` env vars were removed in 0.3.0 — install 0.2.x first if you need the automated migration path.\n\n---\n\n## Quick Start\n\n```bash\ncargo install --path .       # development install; release installers do this for you\npalace install               # configures Cursor + Codex + Claude Code\npalace doctor                # verifies MCP config, rules, binary, and drawer count\npalace seed-adoption-facts   # seed KG facts that make agent recall measurable\npalace init ~/my-project     # detect rooms and write palace.yaml\npalace mine ~/my-project     # populate the palace\n```\n\nThen restart your agent app so it reloads MCP configuration. Search manually with\n`palace search \"how did we decide on the database schema\"` or let your agent\ncall the MCP tools when its installed rule tells it to consult memory.\n\n---\n\n## CLI Reference\n\n| Command | Description |\n|---|---|\n| `palace init <dir>` | Detect rooms from folder structure, write `palace.yaml` |\n| `palace mine <dir>` | Chunk, embed, and store project files |\n| `palace mine-convos <dir>` | Ingest conversation exports |\n| `palace search <query>` | Semantic search with similarity scores |\n| `palace wake-up` | Print L0 (identity) + L1 (essential story) context |\n| `palace status` | Palace overview: drawer counts by wing/room |\n| `palace wings` | List registered wings with kind, drawer counts, and last mined time |\n| `palace gain` | Show MCP usage gains, estimated savings, and per-project value |\n| `palace split` | Split Claude Code mega-transcripts by session |\n| `palace repair` | Re-embed any drawers missing vectors |\n| `palace install` | Register the MCP server with Cursor, Codex, and Claude Code |\n| `palace uninstall` | Remove palace from MCP client configs |\n| `palace doctor` | Inspect binary path, palace DB, and MCP config status |\n| `palace seed-adoption-facts` | Seed durable KG facts for Palace adoption and quality gates |\n| `palace upgrade-embeddings` | Re-embed drawers; add `--refresh-preferences` to refresh preference-span vectors |\n| `palace mcp` | Start the MCP stdio server |\n\n### `mine` flags\n\n```bash\npalace mine ~/my-project \\\n  --wing my_project          # Override wing name\n  --limit 100                # Cap at 100 files\n  --dry-run                  # Preview without storing\n  --no-gitignore             # Ignore .gitignore rules\n  --include vendor,third_party  # Force-include these paths\n```\n\n### `mine-convos` flags\n\n```bash\npalace mine-convos ~/Desktop/transcripts \\\n  --wing claude_sessions \\\n  --mode exchange   # or: general (decisions/milestones/emotions)\n  --limit 50\n  --dry-run\n```\n\n### `split` flags\n\n```bash\npalace split \\\n  --source ~/Desktop/transcripts \\\n  --min-sessions 2 \\\n  --dry-run\n```\n\n### `gain`\n\n`palace gain` summarizes automatic MCP usage by Cursor, Codex, Claude Code,\nor any other MCP client. It records local tool-call metadata in `palace.db` and\nestimates value from retrieval hits, duplicate skips, KG facts, diary recalls,\nrepeat questions, and latency.\n\n```bash\npalace gain\npalace gain --project my_project --since 7d\npalace gain --history\npalace gain --json\npalace gain --record <query_id> <drawer_id> useful\n```\n\nExample output:\n\n```text\npalace gain - last 30d (palace_rs)\n  Tool calls         : 412   (sessions: 27)\n  Hit rate           : 88%   (search hits 142/162)\n  Precision@1        : 92%\n  Precision@5        : 95%\n  Tokens saved (est) : ~78,400\n  Re-index skipped   : 31    (duplicate drawers avoided)\n  KG facts recalled  : 56\n  Diary recalls      : 8\n  Repeat Qs avoided  : 19\n  p95 latency        : 41 ms\n  Tool latency       : palace_search(p50 18 ms, p95 41 ms)\n  Top wings          : palace_rs(120), checkout(40)\n```\n\nSet `PALACE_GAIN_DISABLED=1` to disable usage recording.\n\n`palace_gain` also accepts an optional `record` payload for MCP callers that want\nto file explicit usefulness feedback without learning a new tool:\n\n```json\n{\"record\": {\"query_id\": \"query_abc\", \"drawer_id\": \"drawer_xyz\", \"verdict\": \"useful\"}}\n```\n\n---\n\n## MCP Setup\n\n`palace install` is the normal setup command for the four supported local agent\nclients: Cursor, Codex, Claude Code, and Claude Desktop. It writes both:\n\n- an MCP server entry that starts `palace mcp`\n- a small rule that tells the agent when to call `palace_status`,\n  `palace_search`, `palace_preference_search`, `palace_kg_query`, and\n  `palace_diary_write`\n\nThe nine protocol-critical tools (`palace_status`, `palace_session_context`,\n`palace_diary_search`, `palace_project_status`, `palace_search`,\n`palace_kg_query`, `palace_preference_search`, `palace_diary_write`,\n`palace_kg_add`) are also stamped with `_meta.\"anthropic/alwaysLoad\" = true`.\nClients that honor the hint (Claude Code >= 2.1.121) keep them resident at\nsession start instead of deferring them behind tool search, so the mandatory\nthree-trigger protocol doesn't depend on the agent remembering to load tools\nfirst. All other tools remain deferrable.\n\n```bash\npalace install\n```\n\nWhat gets written by default:\n\n| Client | MCP config | Rule file |\n|---|---|---|\n| Cursor | `~/.cursor/mcp.json` | `~/.cursor/rules/palace.mdc` |\n| Codex | `~/.codex/config.toml` | `~/.codex/AGENTS.md` |\n| Claude Code | `~/.claude/mcp_servers.json` | `~/.claude/CLAUDE.md` |\n| Claude Desktop | Claude Desktop config | `~/.claude/CLAUDE.md` |\n\nExisting 0.1.x installs that registered the server as `mempalace` are migrated\nto `palace` automatically the next time you run `palace install`.\n\nInstall for one client:\n\n```bash\npalace install --client cursor\npalace install --client codex\npalace install --client claude\n```\n\nInstall project-scoped rules instead of global rules:\n\n```bash\npalace install --scope project --path /path/to/project\n```\n\nFor project scope, Cursor also gets a project-local MCP config at\n`<project>/.cursor/mcp.json`. Codex and Claude Code keep MCP config in their\nuser-level config files, while their rules go into `<project>/AGENTS.md` and\n`<project>/CLAUDE.md`.\n\nSkip rule files if you only want MCP wiring:\n\n```bash\npalace install --no-rule\n```\n\n### Profiles (developer and non-developer use)\n\nPalace ships three usage profiles that shape the injected agent rule, the\n`palace_status` protocol text, and room auto-detection for the audience:\n\n| Profile | For | Rooms it favors |\n|---|---|---|\n| `coding` (default) | software projects | frontend, backend, testing, docs, config… |\n| `creative` | worldbuilding, D&D, fiction | characters, places, lore, factions, sessions, timeline |\n| `personal` | coaching, caregiving, household, client notes | people, health, finances, home, schedule, notes |\n\n```bash\npalace install --profile creative\npalace install --profile personal\n```\n\nThe chosen profile persists to `~/.palace/config.json`, so the MCP server serves\nmatching protocol wording afterward. Override it for a single process with the\n`PALACE_PROFILE` environment variable. `coding` is the default and preserves the\noriginal behavior, so existing installs are unaffected.\n\nBecause Palace already ingests `.md` and `.txt`, the non-developer profiles make\nit usable straight from Claude Desktop's one-click MCPB install — no code\nrequired. See [MCP prompts](#mcp-prompts) for one-click session continuity.\n\nInspect the current setup:\n\n```bash\npalace doctor\n```\n\nThe installed rule is memory-first for remembered context: decisions, prior\nfixes, conventions, preferences, prior commands, session history, and \"what\nhappened last time?\" should use Palace before grep or code search. Grep remains\nthe right first tool for current symbols, exact definitions, exact files, and\nimplementation details that may have changed since the project was mined.\nIt also tells agents to warm-start with `palace_session_context`, search diaries\nwith `palace_diary_search` before continuing old work, use KG tools for durable\nfacts, and write `palace_diary_write` after substantive work.\n\n### Remote mode (shared palace-server)\n\nBy default `palace mcp` serves the **local** palace. Point it at a shared remote\n[Palace Server](https://palacememory.com) instead — so a whole team shares one\nmemory backend in their own infrastructure — without changing any client's\nstdio registration. In remote mode `palace mcp` becomes a transparent\nstdio→HTTP bridge that forwards each request to the server's `/mcp` endpoint\nwith a `Bearer` API key. Palace Server is the commercial, self-hosted team\nedition — licenses, docs, and deployment guides live at\n[palacememory.com](https://palacememory.com).\n\n```bash\n# Store the endpoint and ps_… API key (prompts for the key if --api-key is omitted)\npalace remote set --endpoint https://palace.yourco.com\n\n# Switch the MCP server to the remote palace-server, then verify\npalace remote on\npalace remote test          # runs the MCP handshake; reports tool count\n\n# Back to the local palace at any time\npalace remote off           # (or: palace local)\n```\n\nInspect the current wiring with `palace remote status` (prints the MCP mode, the\nnormalised `/mcp` endpoint, and a masked API key). Remote settings are read from\nthe `PALACE_MCP_MODE`, `PALACE_REMOTE_ENDPOINT`, and `PALACE_API_KEY` environment\nvariables, falling back to the `mcp_mode`, `remote_endpoint`, and `remote_api_key`\nkeys in `~/.palace/config.json` (written with owner-only `0600` permissions). The\nendpoint accepts a bare host, a base URL, or a full `/mcp` URL.\n\n### Automatic memory hooks\n\n`palace install` registers user-scope hooks for every client that supports\nthem, so memory use is automatic in **every** project without per-project rule\nedits. The three hooks behave the same everywhere:\n\n- **session start** — injects the protocol text plus real recalled memory:\n  recent diary entries for the session's project (cross-agent, so another\n  agent's prior work is visible the next day) and the top drawers of the wing\n  the `cwd` maps to. Fails open — a missing or empty palace yields the\n  protocol text alone. Cursor also exports `PALACE_SESSION_ID`.\n- **post tool use** — auto-recalls relevant memory while the agent\n  investigates, so a prior agent's decisions surface even before the agent\n  thinks to search.\n- **stop** — if the session engaged Palace but recorded nothing, it asks the\n  agent to `palace_diary_write` its investigation and `palace_kg_add` durable\n  decisions before finishing. It nudges at most once.\n\n| Client | Config file | Recall matches | Notes |\n| --- | --- | --- | --- |\n| Cursor | `~/.cursor/hooks.json` | `Grep`/`Read` | flat hook entries + wrapper scripts |\n| Claude Code | `~/.claude/settings.json` | `Grep`/`Read`/`Glob` | nested `hooks` blocks |\n| Codex | `~/.codex/hooks.json` | `Bash` (shell) | nested `hooks` blocks; run `/hooks` once to trust them |\n| Claude Desktop | — | — | no hook system; rules-only (`CLAUDE.md`) |\n\nClaude Code and Codex share a \"Claude-style\" output dialect\n(`hookSpecificOutput.additionalContext` for context, `decision: \"block\"` +\n`reason` to keep the agent working until it saves); Cursor uses its own\n`additional_context` / `followup_message` keys. The runner that produces these\nis `palace hook <event> --client <cursor|claude|codex>`.\n\nCross-agent continuity: `palace_diary_search` accepts `all_agents: true` (and an\noptional `project_path`) to recall investigations recorded by any agent, and\n`palace_session_context` falls back to another agent's recent work for the\nproject when you have none of your own. Durable decisions belong in the\nknowledge graph (`palace_kg_add` / `palace_kg_invalidate`), which dedupes facts\nand tracks changes over time, so re-recalled decisions never duplicate.\n\nSeed durable KG facts for adoption tracking:\n\n```bash\npalace seed-adoption-facts --project my_project\n```\n\nThe seed is idempotent and records the four supported clients, the memory-first\nprotocol, routing rules, user preference for memory-aware agents, and standard\nquality gates. Agents can then recall those facts with `palace_kg_query`.\n\nRemove palace config:\n\n```bash\npalace uninstall\npalace uninstall --client cursor\n```\n\n### Cursor\n\nAfter `palace install --client cursor`, restart Cursor or reload the window.\nSettings -> MCP should show `palace` as an enabled stdio server.\n\nManual Cursor config shape:\n\n```json\n{\n  \"mcpServers\": {\n    \"palace\": {\n      \"command\": \"palace\",\n      \"args\": [\"mcp\"]\n    }\n  }\n}\n```\n\nThe rule is installed as `.cursor/rules/palace.mdc` with `alwaysApply: true`.\n\n### Codex\n\nAfter `palace install --client codex`, restart Codex so it reloads\n`~/.codex/config.toml`.\n\nManual Codex config shape:\n\n```toml\n[mcp_servers.palace]\ncommand = \"palace\"\nargs = [\"mcp\"]\n```\n\nThe rule is installed as a managed palace block in `~/.codex/AGENTS.md` (or\n`<project>/AGENTS.md` with `--scope project`). Existing content is preserved.\n\n### Claude Code\n\nAfter `palace install --client claude`, restart Claude Code so it reloads\n`~/.claude/mcp_servers.json`.\n\nManual Claude JSON shape is the same as Cursor's `mcpServers` object above.\nYou can also use Claude Code's own MCP command:\n\n```bash\nclaude mcp remove palace\nclaude mcp add palace -- palace mcp\n```\n\nThe rule is installed as a managed palace block in `~/.claude/CLAUDE.md` (or\n`<project>/CLAUDE.md` with `--scope project`). Existing content is preserved.\n\n### MCP Tools\n\nThe server exposes tools for status, taxonomy, search, drawer CRUD, knowledge\ngraph operations, graph tunnels, hook acknowledgements, and agent diaries:\n\n| Tool | Description |\n|---|---|\n| `palace_status` | Palace overview + protocol |\n| `palace_gain` | MCP usage gains, estimated savings, and per-project value |\n| `palace_verify` | Verify MCP tools, database health, embeddings, and model cache |\n| `palace_recall_check` | Run project-memory probes and report expected-memory hits |\n| `palace_conflicts` | Surface likely stale or contradictory KG facts |\n| `palace_list_wings` | List registered wings: kind, description, project path, last mined time, drawer counts |\n| `palace_project_status` | Check whether the current project/topic is mined, registered but unmined, or unknown |\n| `palace_mine` | Mine a code repository on demand, after the user agrees |\n| `palace_create_wing` | Declare a topic or project wing in the registry |\n| `palace_list_rooms` | List rooms within a wing |\n| `palace_get_taxonomy` | Full wing → room → count tree |\n| `palace_get_aaak_spec` | AAAK compressed memory dialect spec |\n| `palace_search` | Semantic search over drawers |\n| `palace_preference_search` | Dedicated recall pass for preference-shaped queries |\n| `palace_check_duplicate` | Check if content already exists |\n| `palace_add_drawer` | File content into the palace |\n| `palace_remember` | Shortcut for `palace_add_drawer` with importance=5 |\n| `palace_get_drawer` | Get a drawer by ID |\n| `palace_list_drawers` | List drawers with optional wing/room filters |\n| `palace_update_drawer` | Update drawer content and refresh metadata |\n| `palace_delete_drawer` | Remove a drawer by ID |\n| `palace_forget` | Delete a drawer by ID (outdated/incorrect memory) |\n| `palace_explain` | Full provenance for a drawer: who filed it, when, from where, importance |\n| `palace_kg_query` | Query entity relationships |\n| `palace_kg_add` | Add a fact (subject → predicate → object) |\n| `palace_kg_invalidate` | Mark a fact as no longer true |\n| `palace_kg_timeline` | Chronological fact history |\n| `palace_kg_stats` | Knowledge graph overview |\n| `palace_seed_adoption_facts` | Seed durable KG facts for four-client adoption |\n| `palace_traverse` | BFS graph walk from a room |\n| `palace_find_tunnels` | Rooms bridging two wings |\n| `palace_create_tunnel` | Create a persisted tunnel between two wing/room pairs |\n| `palace_list_tunnels` | List persisted tunnels |\n| `palace_delete_tunnel` | Delete a persisted tunnel |\n| `palace_follow_tunnels` | Follow persisted tunnels from a wing/room pair |\n| `palace_graph_stats` | Palace graph summary |\n| `palace_diary_write` | Write a diary entry in AAAK format |\n| `palace_diary_read` | Read recent diary entries |\n| `palace_diary_search` | Search within an agent's diary entries (or `all_agents: true` for cross-agent) |\n| `palace_session_context` | Get recent diary context for agent warm-start |\n| `palace_list_agents` | List agent diary wings |\n| `palace_export` / `palace_import` | Export/import palace data |\n| `palace_upgrade_embeddings` | Re-embed drawers; refresh preference-span vectors |\n| `palace_prune` | Prune stale or low-value drawers |\n| `palace_hook_settings` | Return hook settings |\n| `palace_memory_report` | Human-readable inventory of what the palace remembers: profile, per-wing/room counts, recent activity — inspect memory without a UI |\n\n### MCP prompts\n\nFor clients that can't run hooks (notably Claude Desktop), the server advertises\nMCP prompts so users get one-click session continuity from the prompt picker:\n\n| Prompt | What it does |\n|---|---|\n| `continue-session` | Loads warm-start context (`palace_status`, `palace_session_context`, `palace_diary_search`) so the agent picks up where you left off |\n| `save-session` | Saves the session to memory (`palace_diary_write`, `palace_kg_add`, `palace_remember`) so it carries over next time |\n\nThe wording adapts to the active [profile](#profiles-developer-and-non-developer-use)\n(e.g. \"this world or story\" for `creative`, \"this person or household\" for\n`personal`).\n\n---\n\n## Migrating from `mempalace` to `palace`\n\nThe 0.2.0 release renamed the project from `mempalace` to `palace`. The 0.2.x line\nkept the old names working with deprecation warnings; they were **removed in 0.3.0**.\nOn current versions, migrate via a 0.2.x release first or rename manually\n(`~/.mempalace` → `~/.palace`, `mempalace.yaml` → `palace.yaml`).\n\n| Surface | Before (0.1.x) | After (0.2.x) |\n|---|---|---|\n| Crate | `mempalace-rs` | `palace-rs` |\n| Primary binary | `mempalace` | `palace` (the `mempalace` binary is now a deprecation shim) |\n| MCP server name | `mempalace` | `palace` (migrated automatically by `palace install`) |\n| MCP tools | `mempalace_*` | `palace_*` |\n| Config / data dir | `~/.mempalace` | `~/.palace` (auto-migrated on first run) |\n| Project config | `mempalace.yaml` | `palace.yaml` (legacy filename still read) |\n| Env vars | `MEMPALACE_*` | `PALACE_*` (legacy names accepted with a warning) |\n| Cursor rule | `.cursor/rules/mempalace.mdc` | `.cursor/rules/palace.mdc` |\n| Release assets | `mempalace-<ver>-<target>` | `palace-<ver>-<target>` |\n\nOne-step migration:\n\n```bash\ncargo install --path .\npalace install\n```\n\n`palace install` rewrites existing MCP client configs (Cursor, Codex, Claude Code)\nand rule files, replacing legacy `mempalace` entries with `palace` entries.\n`~/.mempalace` is moved to `~/.palace` on first run when the legacy directory\nexists and the new one does not.\n\n## Migration from Python\n\nThe Rust version uses a new single-file database (`palace.db`). Your existing ChromaDB data cannot be migrated automatically.\n\n**Steps:**\n\n```bash\n# 1. Re-mine your projects\npalace init ~/my-project && palace mine ~/my-project\n\n# 2. Re-index conversations\npalace mine-convos ~/Desktop/transcripts\n\n# 3. Verify\npalace status\n```\n\nYour `identity.txt`, `people_map.json`, and `known_names.json` in `~/.palace/` (migrated from `~/.mempalace/` if present) are compatible and will be read automatically.\n\n---\n\n## Test on a Project\n\n```bash\npalace init /path/to/project\npalace mine /path/to/project\npalace status\n```\n\nRestart Cursor, Codex, or Claude Code, then ask the agent a project question that\nshould use memory, for example: \"Search the palace for how this project handles\ndatabase migrations.\" The agent should call `palace_search` through MCP\ninstead of re-indexing the repository from scratch.\n\n---\n\n## Configuration\n\n`~/.palace/config.json` is read on startup. Environment variables take highest priority:\n\n| Env Var | Default | Description |\n|---|---|---|\n| `PALACE_PALACE_PATH` | `~/.palace/palace` | Palace data directory |\n\n### `palace.yaml` (per-project)\n\nCreated by `palace init`. Example:\n\n```yaml\nwing: my_project\nrooms:\n  - name: backend\n    description: Server and API code\n    keywords: [api, server, routes, models]\n  - name: frontend\n    description: UI components\n    keywords: [ui, components, pages, views]\n  - name: general\n    description: Everything else\n    keywords: []\n```\n\n---\n\n## Memory Stack\n\n| Layer | Name | Description |\n|---|---|---|\n| L0 | Identity | `~/.palace/identity.txt` — always loaded (~100 tokens) |\n| L1 | Essential Story | Top drawers by importance, grouped by room (~600–900 tokens) |\n| L2 | On-Demand | Wing/room filtered retrieval |\n| L3 | Deep Search | Full semantic search |\n\n`palace wake-up` prints L0 + L1. The AI uses MCP tools for L2/L3.\n\n---\n\n## Development\n\n```bash\ncargo build\ncargo test\ncargo clippy\n```\n\nTests use in-memory SQLite — no palace.db needed. The embedding model is not loaded in tests that don't require it.\n\n---\n\n## Hooks Compatibility\n\nShell hooks that previously called `python -m mempalace.mcp_server` or\n`mempalace mcp` can now call `palace mcp`. Update the binary path in your hooks:\n\n```bash\n# Before (Python)\nexec python -m mempalace.mcp_server\n\n# Before (Rust 0.1.x)\nexec mempalace mcp\n\n# After (Rust 0.2.x+)\nexec palace mcp\n```",
  "bytes": 31187,
  "sha": "1bcc82161b59d1994827b45c771c7777b371994acd902fd31fc002ea298e525f",
  "repo_slug": "ancientice/palace-rs",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_ancientice_palace_rs_7ad4e62e/readme"
}