locus
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@locuslist rooms in my palace"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Locus
Hierarchical markdown-based memory system for autonomous AI agents. Each directory is a room (locus) in the palace, containing specific knowledge navigated on demand. Named for the atomic unit of the Method of Loci.
Core idea: Keep context windows small. Load only the room you need, not the whole palace.
How it works
palace/
INDEX.md ← always read first (~50 lines max)
global/
toolchain/
toolchain.md ← canonical facts about tools
projects/
my-project/
my-project.md ← room overview + key files
technical-gotchas.md ← specialty: issues & resolutions
sessions/
2026-03-02.md ← append-only session logAn agent reads INDEX.md, navigates to the relevant room, and reads only that room.
Session logs accumulate until consolidation merges them into canonical files.
See the wiki for full documentation.
Related MCP server: Strata Memory MCP Server
Quick start
# Install
pip install locus-mcp
# or: uvx locus-mcp --palace ~/.locus (no install needed)
# Create a palace from the packaged example
locus init ~/.locus
# Edit ~/.locus/INDEX.md to describe your palace
# Run the MCP server
locus-mcp --palace ~/.locus
# or: LOCUS_PALACE=~/.locus locus-mcpInstallation
MCP server (recommended for MCP-capable clients)
pip install locus-mcpOr run without installing using uvx:
uvx locus-mcp --palace ~/.locusAgent skills
The skill files are the one part of Locus written for a specific runtime. The
palace convention, the MCP server, and the recall / lint / index CLIs are
runtime-neutral and work from anything that can read a file or speak MCP. The
skills in skills/claude/ are written and maintained for Claude Code, and that is
the only set shipped here. They are plain markdown with YAML frontmatter, so
another runtime is welcome to adapt them. Per-runtime copies used to live in
skills/codex/ and skills/gemini/; they were removed because keeping three
variants honest cost more than it returned.
Install them from a clone:
git clone https://github.com/Nano-Nimbus/locus.git
cd locus
make install-skills # copies skills/claude/* to ~/.claude/skills/
make install-skills-dry # print what would be copied, write nothingCLAUDE_SKILLS_DIR overrides the destination.
Skill | Command | Description |
|
| Recall, navigate the palace, write rooms and session logs, regenerate indexes |
|
| Merge session logs into canonical files |
|
| Audit palace health |
|
| Record explicit feedback on a palace recall |
|
| Post-release verification workflow (contributors) |
|
| Trust tags, nonce discipline, and the |
|
| Bootstrap a palace from existing memory files |
Agent SDK (Python)
pip install locus-mcp
locus --palace ~/.locus --task "What toolchain conventions are set?"MCP Server
The locus-mcp command exposes five tools over the Model Context Protocol.
Use stdio for all local integrations (Claude Desktop, Claude Code, Codex, Gemini — default, no extra flags needed).
SSE transport is available for network deployments (--transport sse) and requires FASTMCP_HOST=0.0.0.0
to be set explicitly — the server binds to loopback by default.
Tool | Description |
| Returns |
| Reads any file in the palace |
| Atomically writes a file (guarded — cannot write to |
| Ranked full-text search over the shared FTS5 index (see Recall); ripgrep only without FTS5 |
| Reads up to 20 palace files in a single call — use for multi-room loads |
Add --security to enable Ed25519 signature verification on reads and automatic signing on writes.
See Security below.
Claude Desktop (claude_desktop_config.json)
{
"mcpServers": {
"locus": {
"command": "locus-mcp",
"args": ["--palace", "/path/to/palace"]
}
}
}Or using uvx (no install required):
{
"mcpServers": {
"locus": {
"command": "uvx",
"args": ["locus-mcp", "--palace", "/path/to/palace"]
}
}
}Cursor / Zed
{
"mcp": {
"servers": {
"locus": {
"command": "locus-mcp",
"args": ["--palace", "/path/to/palace"]
}
}
}
}Environment variable
All clients support LOCUS_PALACE as an alternative to --palace:
export LOCUS_PALACE=~/.locus
locus-mcpSee MCP Server Configuration
for the full client setup guide and spec/mcp-server.md for architecture details.
Recall
locus recall answers "what do I already know about this?" in one call, fast enough
to run on every prompt from a hook. It keeps a SQLite FTS5 index (standard library only,
no PyYAML) over any number of markdown roots: a palace, an OKF bundle, a Claude Code
memory directory, or all of them at once.
locus recall --root ~/memory --root ./docs "why does the flux kustomization stall"Recalled memory:
1. Flux healthcheck stall (human-reviewed, 2026-08-22)
/home/me/memory/project_flux-healthcheck-stall.md
Flux Kustomization with wait:true stalls on health checks for a bad revision ...
2. [STALE] Old Flux bootstrap procedure (unverified, 2025-11-02)
/home/me/docs/runbooks/flux-bootstrap.md
Bootstrap Flux with a personal access token ...Flag | Default | Meaning |
|
| Directory to index; repeatable |
| 3 | Number of hits |
| 4096 | Hard cap on text output |
| off | Include |
| all | Only this frontmatter type; repeatable |
| off | Print a JSON list instead of text |
| off | Rebuild the index from scratch |
Frontmatter drives the result: title (or name, or the first heading), description,
tags, type (or metadata.type), modified (else generated.at, else file mtime),
status, stale_after, and verified. Ranking is bm25 with title and description
weighted above the body; exact ties go to human-reviewed files, then to the newest
modified. A hit is flagged STALE when its stale_after has passed or its status is
deprecated. Trust tiers follow OKF: unverified, machine-confirmed (only non-human
verified entries), human-reviewed (any verified entry whose by starts with human:).
Roots can live in a .locus.toml in the project or any parent directory:
[recall]
roots = ["docs", "~/memory/shared"]The index is stored at ${XDG_CACHE_HOME:-~/.cache}/locus/<hash-of-roots>.sqlite, never
inside a root, and is refreshed incrementally (mtime, then content hash) on every call.
With no hits the text output is empty and the exit status is still 0, so a prompt hook can
call it unconditionally:
#!/bin/sh
# Claude Code UserPromptSubmit hook: whatever this prints is injected as context.
prompt=$(jq -r .prompt)
exec locus recall -k 3 --budget 4096 "$prompt"The MCP server's memory_search uses the same index, so MCP results are ranked the
same way. Full rules in spec/recall.md.
Lint and index
locus lint checks markdown roots for Open Knowledge Format
v0.2 conformance and the Locus palace conventions. locus index generates the
index files those conventions define. Both read the same frontmatter recall
indexes, and neither imports the Agent SDK, so a CI job that only checks
conformance does not install it.
locus lint --root docs --check # CI gate: exit 1 on any error
locus lint --root docs --fix # add inferable fields, rewrite nothing
locus index --root docs --check # exit 1 when a generated index drifteddocs/runbooks/valve-chatter.md: error [okf.type-missing] frontmatter has no non-empty type (fix: add type: Runbook)
docs/log.md: error [okf.log-order] entries run oldest first: 2026-05-09 follows 2026-05-01
docs/reference/platform.md: warning [locus.size-limit] 214 lines exceeds the 200-line soft limit for a specialty file
2 error(s), 1 warning(s), 1 fixablelint
Flag | Default | Meaning |
|
| Directory to check; repeatable |
| off | Exit non-zero on any error. For CI |
| off | Treat warnings as errors under |
| off | Add inferable fields. Never rewrites an existing key |
| none | Infer this OKF type under DIR; repeatable |
| none | Paths that should carry |
| off | Print a JSON report instead of text |
Rules split in two. okf.* checks what the specification requires: a parseable
frontmatter block with a non-empty type on every non-reserved document, an
index.md with no frontmatter beyond a bundle-root okf_version, a log.md
that is date-headed and newest first, and ISO 8601 timestamps. Unknown keys and
unknown type values are never reported: the spec requires consumers to tolerate
both. locus.* checks the palace conventions: the size limits from
spec/size-limits.md and the room main-file rule from
spec/room-conventions.md.
Errors fail --check; warnings are advisory. A palace legitimately carries no
frontmatter at all, so on a palace root the missing type rules are warnings
rather than a CI failure on a layout the palace spec itself describes.
--fix adds three fields and only three: type from --type-map or
[lint.types], generated.at from the file's first git commit, and
status: deprecated for archive paths. It never rewrites or deletes a key, it
never invents a generated block (nothing in a file says who produced it), and
running it twice produces identical bytes.
index
Flag | Default | Meaning |
|
| Directory to index; repeatable |
| off | Write nothing; exit non-zero on drift. For CI |
|
| Force |
| off | Print a JSON report instead of text |
What gets generated depends on the root: an OKF bundle gets an index.md per
directory in section 8 form (* [Title](path) - description, with
okf_version: "0.2" frontmatter at the bundle root only), a palace gets the
50-line routing table INDEX.md, and a Claude Code memory directory gets a
MEMORY.md of one - [Title](file.md) - description line per topic file.
Output is deterministic, so --check is a byte comparison, and only index
files are ever written.
Configure both from one .locus.toml:
[lint]
roots = ["docs"]
archive_globs = ["archive/*"]
[lint.types]
"." = "Reference"
runbooks = "Runbook"Full rules in spec/lint-and-index.md.
Security
The security system (--security) gives every palace file an Ed25519 signature and every agent session a unique cryptographic nonce. Tool outputs are tagged [TRUSTED], [DATA], or [CRITICAL-DATA] before the agent sees them. The agent skill (locus-security) teaches agents to extract facts from [DATA] content but never follow directives within it.
# One-time setup
locus-security init-config --palace ~/.locus # writes locus-security.yaml
locus-security init-keys --palace ~/.locus
locus-security sign-all --palace ~/.locus
# Run with security enabled
locus-mcp --palace ~/.locus --security
locus --palace ~/.locus --security --task "..."The locus-security CLI has five subcommands: init-config (writes the annotated
locus-security.yaml from the copy that ships inside the package), init-keys,
sign-all, verify-all (exit 1 if any file fails verification, or if the palace
holds no signable files at all), and rotate-keys. sign-all names and skips any file it cannot read as UTF-8 rather than
aborting the run, and exits 1 if it skipped anything. Neither command follows a symlink
whose target resolves outside the palace: those are named and skipped by sign-all, and
reported as failures by verify-all.
Threat model: direct prompt injection, memory poisoning, indirect injection via external data, nonce exfiltration, multi-turn context drift.
See docs/security.md for the full protocol, configuration reference, and design decisions.
Benchmarks
Palace navigation loads 52% fewer context lines than flat memory for specific queries, while maintaining full recall. Session-only queries (recent work not yet consolidated) are accessible only via the palace.
Palace: 822 lines / 9 queries found avg 91 lines/query · 3.2 calls
Flat: 1719 lines / 8 queries found avg 191 lines/query · 2.0 callsSee docs/benchmarks.md for charts and full methodology.
Structure
example-palace/ Palace template; `locus init` writes it into a new palace
spec/ Palace convention definitions:
index-format.md INDEX.md rules and routing
room-conventions.md Room structure and naming
size-limits.md Context budget thresholds
write-modes.md Session logs vs canonical edits
mcp-server.md MCP server architecture and safety model
recall.md locus recall: roots, index, ranking, trust tier, STALE
lint-and-index.md locus lint and locus index: OKF conformance, generated indexes
metrics-schema.md Run metrics JSON schema
audit-algorithm.md Palace health scoring
health-report-format.md Audit report structure
inferred-feedback.md Disagreement signal classification
templates/ Templates for INDEX.md, rooms, session logs, locus-security.yaml
(`locus init --show list`; both trees ship inside the wheel)
skills/
claude/ SKILL.md files for Claude Code + Agent SDK (the only maintained set)
locus/ Recall, palace navigation, writes, index and lint
locus-consolidate/ Room consolidation
locus-audit/ Palace health audit
locus-feedback/ Recall quality feedback
locus-palace-init/ Bootstrap a palace from existing memory files
locus-release/ Post-release verification (contributors)
locus-security/ Security conventions (trust tags, nonce discipline)
docs/
architecture.md Mermaid diagrams — palace, MCP, security, agent interfaces
benchmarks.md Benchmark results and charts (palace vs flat, security overhead)
onboarding.md Step-by-step agent onboarding guide
security.md Full security protocol, key management, config reference
bench/ Per-version benchmark JSON (read by generate-charts.py)
scripts/
bench-mcp.py 45-case MCP integration benchmark (includes security + batch)
bench-compare.py Palace vs flat recall comparison
generate-charts.py Regenerate docs/img/ charts (reads docs/bench/ automatically)
locus/
agent/ Python Agent SDK (CLI + metrics)
audit/ Palace health auditor (locus-audit CLI)
feedback/ Inferred feedback classifier
mcp/ MCP server (locus-mcp CLI) — palace.py, server.py, main.py
conform/ locus lint and locus index: OKF conformance, index generation
recall/ locus recall: FTS5 index shared with memory_search
security/ Ed25519 security system — keys, signing, taint, nonce, middleware
scaffold.py locus init: packaged templates and palace scaffolding
utils.py Shared utilities (slug_from_path)Roadmap
Milestone | Status | Focus |
v0.1 - Foundation | ✅ Complete | Spec, conventions, size limits |
v0.2 - Core Palace | ✅ Complete | Templates, skills, Agent SDK, benchmark |
v0.3 - Performance Metrics | ✅ Complete | Context tracking, feedback, suggestions |
v0.4 - Self Evaluation | ✅ Complete | Palace audit, health reports, inferred feedback |
v0.5 - MCP Server | ✅ Complete | MCP server with memory_list/read/write/search |
v0.6 - Public release | ✅ Complete | Benchmarks, docs, CI, PyPI |
v0.7 - Remote MCP Server | ✅ Complete | SSE transport, Bearer auth, Docker image, K8s deploy |
v0.8 - Auto-Memory Bridge | ✅ Complete | Claude Code auto-memory detection, memory_batch tool |
v0.9 - Security System | ✅ Complete | Ed25519 signing, taint tracking, nonce watermark, --security flag |
Contributing
See CONTRIBUTING.md for dev setup, test instructions, and PR guidelines.
License
Available Tools
5 toolsmemory_batchA
Read multiple palace files in a single call.
paths is a list of paths relative to the palace root (maximum
_MAX_BATCH_PATHS entries). Returns all files joined by \n---\n,
each section headed by ## <path>.
Missing files, directories, and path-traversal violations are noted
inline and do not raise exceptions, so partial results are always
returned for valid calls. Raises ValueError only for invalid
arguments (e.g. more than _MAX_BATCH_PATHS paths).
Returns an empty string for an empty paths list.
| Name | Required | Description | Default |
|---|---|---|---|
| paths | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully discloses behavior: returns joined files with headers, handles missing/invalid paths inline without exceptions, raises ValueError for invalid args, returns empty string for empty list. Transparent about internal constant _MAX_BATCH_PATHS.
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 two-paragraph description, no redundancy. Front-loaded with purpose, then clear parameter descriptions. Every sentence adds 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?
Given the simple parameter (one array) and existence of output schema, the description covers input expectations, return format, error handling, and edge cases (empty list, missing files). Complete for this 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?
Schema coverage is 0%, but description adds meaning: 'paths' is a list of relative paths with a maximum count, and explains format. Provides enough context beyond the bare 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 it reads multiple palace files in a single call, specifying the action (read multiple) and resource (palace files). It differentiates from siblings like memory_read (single file) and memory_write (write operation).
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 context on when to use (batch reading) and behavior details (max paths, partial results). Does not explicitly list alternatives but implies usage for multiple files versus single file reads.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
memory_listA
List the palace index or the files within a room.
Call without path (or with an empty string) to retrieve INDEX.md,
the top-level routing table for the palace. Pass a relative room path
(e.g. "global/networking") to list the markdown files in that room.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden of disclosing behavioral traits. It states the tool lists files (implied read-only) and differentiates between index retrieval and room listing. It does not mention side effects, permissions, or error handling, but the behavior is predictable and non-destructive. The presence of an output schema compensates for missing return value details.
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 two sentences long, each carrying distinct, necessary information. It is front-loaded with the core purpose, then provides specific usage details. No word is wasted, and the structure makes it easy to scan.
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 has one optional parameter, no required fields, and an output schema, the description covers the primary use cases. However, it does not specify what happens if an invalid path is given (e.g., non-existent room), and it mentions 'markdown files' specifically, which might imply only .md files are listed. These are minor gaps, but the description is mostly complete for a simple list 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?
The input schema has no descriptions (0% coverage), so the description must add all parameter meaning. It fully explains the 'path' parameter's role: empty string retrieves the index, a room path lists files. This completely compensates for the schema's lack of documentation, making the parameter semantics crystal clear.
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 lists the palace index or files within a room, with specific behavior for empty vs non-empty path. It distinguishes the two main use cases and uses a specific verb ('list') and resource structure ('palace index', 'room files'). This is precise and leaves no ambiguity about the tool's purpose.
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 clear guidance on when to call without path (to retrieve INDEX.md) and when to pass a room path (to list files in that room). It does not explicitly mention when not to use this tool or suggest alternatives like memory_search or memory_read, but the usage context is well-defined and easy to follow.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
memory_readA
Read a file from the palace.
path is relative to the palace root (e.g. "global/networking/networking.md").
Returns the full file contents as a string, prefixed with [TRUSTED] or [DATA]
when the security system is active.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses that the return is a string prefixed with [TRUSTED] or [DATA] under security conditions. However, it omits details about error handling (e.g., missing file) or if the tool is read-only, leaving gaps.
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 extremely concise with three sentences: one for core purpose and two for path format and return value. Every sentence adds essential information with no wasted words.
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 simplicity (one parameter, no annotations, but has an output schema), the description covers the key aspects: what it reads, how to specify the path, and the return format with security prefix. It lacks error behavior but is fairly complete for a read 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?
The schema description coverage is 0%, so the description must compensate. It adds meaning by explaining that 'path is relative to the palace root' and provides a concrete example, giving context beyond the raw 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 'Read a file from the palace,' providing a specific verb and resource. While it distinguishes from sibling tools like memory_write and memory_search, it does not explicitly differentiate from memory_batch, which could also read files. Still, the purpose is well-understood.
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 a path format example but offers no guidance on when to use this tool versus alternatives like memory_list or memory_search. There is no mention of prerequisites, context, or 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.
memory_searchA
Full-text search across the palace (or a sub-path).
Uses ripgrep (rg) if available; falls back to Python re.
Returns up to 20 matches, each showing the relative file path, line
number, and matched line with 1 line of context on each side.
path narrows the search to a specific room or subdirectory.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | ||
| path | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries full burden. It discloses implementation (ripgrep vs. Python re), result limit of 20 matches, output structure (path, line number, line, context), and use of path parameter for scope. Missing details like authorization or performance, but overall strong.
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, front-loads the purpose, and every sentence contributes useful information without redundancy. It efficiently covers implementation, limits, parameters, and output format in a short paragraph.
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 presence of an output schema (context signal) and the tool's complexity, the description covers core functionality, implementation, limits, and parameter effects. It omits explanation of the 'palace' metaphor and result ordering, but overall is sufficient for an AI 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?
With 0% schema description coverage, the description must compensate. It clarifies that 'query' is a search term (implied regex) and 'path' narrows to a subdirectory. This adds meaning but could be more specific about query syntax and behavior when omitted.
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 performs full-text search across the palace (or sub-path), specifying the search engine used and result limits. This distinguishes it from sibling tools like memory_list or memory_read which are not search-oriented.
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 does not explicitly advise when to use this tool versus alternatives. It only hints at narrowing search via the path parameter but lacks explicit 'when-to-use' or 'when-not-to-use' guidance, nor does it mention sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
memory_writeA
Write content to a file within the palace.
path is relative to the palace root. The write is atomic (write to a
temp file, then rename). Writes to _metrics/, sessions/, or
archived/ are rejected, as are non-text file extensions.
Creates parent directories as needed.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | ||
| content | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully bears the burden of disclosing behavior. It reveals the write is atomic (temp file then rename), rejects writes to certain directories and non-text extensions, and creates parent directories as needed. This goes beyond a simple 'write' statement, though it omits whether overwriting occurs or error handling.
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 (3 sentences) with front-loaded purpose and no redundant information. Every sentence adds value: purpose, path semantics, atomicity, restrictions, and directory creation.
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 that an output schema exists (context confirms), the description does not need to explain return values. It covers key aspects: path behavior, atomicity, restrictions, and directory creation. However, it could mention overwrite behavior or error cases for 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?
Schema description coverage is 0%, so the description must compensate. It adds meaning for 'path' (relative to palace root, restricted directories, non-text extensions) but for 'content' only mentions 'content' without format details. The description partially fills the gap but not fully.
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 'Write content to a file within the palace.' with specific verb and resource. It differentiates from siblings like memory_batch (batch writes) and memory_read (read). The additional details about path, atomicity, and restrictions reinforce the purpose.
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?
While the description provides important usage constraints (path relative to palace root, atomic write, rejected paths/extensions, creates parent dirs), it lacks explicit guidance on when to use this tool versus alternatives like memory_batch for batch operations. The context is implicit rather than directly stated.
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
v0.10.0- First observed
memory_batch - First observed
memory_list - First observed
memory_read - First observed
memory_search - First observed
memory_write
TDQS
Scored across 5 tools
Each tool targets a distinct operation: batch read, list directory, single read, full-text search, and write. There is no overlap in functionality.
All tools follow a consistent 'memory_verb' pattern (batch, list, read, search, write), making it easy to infer purpose from name.
Five tools cover the core operations for a file-based memory system without being excessive or insufficient.
CRUD operations are covered except for delete/remove; a delete tool is missing, which could hinder agents needing to clean up files.
Maintenance
Related MCP Connectors
Token-efficient MCP memory for Markdown vaults. Tiered search, GraphRAG, AI memories.
Portable AI memory shared across models and harnesses - plain markdown you own.
Memory system for AI agents with semantic search. Store and recall memories with ease.
Persistent memory and knowledge graphs for AI agents. Hybrid search, context checkpoints, and more.
Related MCP Servers
- AlicenseAqualityFmaintenanceEnables AI assistants to maintain persistent project context across sessions by storing and retrieving structured information in markdown files organized in a memory bank directory.457Apache 2.0
- AlicenseAqualityCmaintenanceEnables AI agents to manage hierarchical memory with Markdown-based storage, tiered architecture (L0-L3), and hybrid retrieval for transparent and persistent context.8MIT
- AlicenseNot gradedqualityBmaintenancePersistent shared memory for AI coding agents that turns a folder of markdown files into searchable memory across sessions, repos, and machines.11 npmFunctional Source , Version 1.1, MIT Future
- FlicenseNot gradedqualityBmaintenancePersistent memory for AI agents enabling saving, searching, and managing knowledge across sessions with local markdown files.2-