Skip to main content
Glama
Nanda-Kiran

Yunaki Memory MCP

by Nanda-Kiran

Yunaki Memory MCP

Git-backed, per-repo memory for coding agents, exposed as an MCP server.

Each git repo the server is used in gets its own memory store. The store is a separate git repository under ~/.yunaki/memory/<repo-id>/. Every memory_write is a commit, and each memory_ingest run is one commit. What an agent records about a repo becomes plain-text history you can read, diff and revert. Memories are never written into your project's files. The one thing the server writes inside your repo is an id in .git/config, and only for a repo that has no commits yet.

How it works

  • Stable repo identity. A repo is keyed by its root-commit SHA (git rev-list --max-parents=0 HEAD, first 12 chars). On your machine, its memory stays with it after a re-clone, a rename or a remote change. A shallow clone (git clone --depth ...) reports a different root commit, so it gets a separate store. A repo with no commits gets a UUID cached in its .git/config (yunaki.memoryId). After its first commit, the repo is keyed by its root commit, and the UUID store is not carried over.

  • Created on first use. Every tool call resolves the repo first. If the path is not inside a git repository, the call returns an error. On first touch the server git inits the store, seeds repo.json and MEMORY.md, and commits.

  • One file per memory. Each memory is a Markdown file with YAML frontmatter at <type>/<slug>.md, so every change is a small, separate diff. MEMORY.md is rebuilt as an index on every write.

  • Seed from the repo. memory_ingest writes reference memories built from the repo's file list, its package.json and its docs. A new store then starts with an overview of the repo rather than empty.

~/.yunaki/memory/<repo-id>/      # its own git repo (root overridable with YUNAKI_MEMORY_ROOT)
├── repo.json                    # root commit, remote, last seen path, createdAt
├── MEMORY.md                    # index, sorted by confidence
├── heuristic/use-pnpm-in-this-repo-not-npm-lockfile-is-pnpm-lock-yaml.md
└── reference/
    ├── repo-overview.md
    ├── repo-structure.md
    └── doc-readme-md.md

A memory file:

---
id: use-pnpm-in-this-repo-not-npm-lockfile-is-pnpm-lock-yaml
type: heuristic
tags:
  - tooling
  - package-manager
confidence: 0.5
usage_count: 0
last_used: '2026-06-28'
status: active
source: ''
created: '2026-06-28'
updated: '2026-06-28'
---
Use pnpm in this repo, not npm — lockfile is pnpm-lock.yaml.

Related MCP server: memory-mcp

Tools

Tool

What it does

memory_write

Saves a memory of type fact (default), heuristic, failure, success, preference or reference, with optional tags, title and source. The title, or the content's first line if there is no title, becomes the filename. If that file already exists, a short suffix is added so nothing is overwritten. Rebuilds the index and commits.

memory_search

Scores each memory by how many query terms appear in its id, tags and body, adds its confidence, and returns the top limit (default 8, max 50). There is no score cutoff, so memories with no keyword hits can fill the remaining slots. You can filter by type and by tags; a memory must carry every tag you pass. Memories whose status is deprecated are skipped. An empty query returns the top memories by confidence.

memory_ingest

Lists tracked files plus untracked files that are not gitignored, then writes three kinds of reference memory. The first is a repo overview: name, file count, stack detected from marker files such as package.json, pyproject.toml, Cargo.toml or go.mod, top file types, npm scripts, bin entries and the first 12 dependencies. The second is a file tree, collapsed below maxDepth (default 3). The third is the text of doc files: .md, .mdx, .rst, .txt and .adoc files under docs/, plus any file whose name starts with README, CONTRIBUTING, ARCHITECTURE, CHANGELOG, USAGE, INSTALL, GETTING-STARTED, DESIGN, ROADMAP or NOTES. It captures up to maxDocs docs (default 20) and keeps the first maxDocBytes of each (default 4,000). Slugs are stable and the whole run is one commit, so re-running updates the same entries.

memory_repo_info

Shows the resolved repo id, remote, root, memory directory and entry count.

Every tool takes an optional repoPath, which can be any path inside the target repo. Without it, the server uses YUNAKI_REPO if that is set, and otherwise its own working directory (Claude Code starts it inside your project).

Install

Requires Node 18+ and git on your PATH. The server speaks MCP over stdio, so each person runs a local copy against their own repos.

From GitHub with npx (the prepare script compiles the TypeScript on install):

claude mcp add yunaki-memory -- npx -y github:Nanda-Kiran/yunaki-memory-mcp

Or clone and build:

git clone https://github.com/Nanda-Kiran/yunaki-memory-mcp.git
cd yunaki-memory-mcp && npm install && npm run build
claude mcp add yunaki-memory -- node "$(pwd)/dist/index.js"

Or commit a .mcp.json to share the config with collaborators:

{
  "mcpServers": {
    "yunaki-memory": {
      "command": "npx",
      "args": ["-y", "github:Nanda-Kiran/yunaki-memory-mcp"]
    }
  }
}

Memory is stored per user. Installing the server does not share memories between people.

When you adopt a repo, run memory_ingest once to seed it.

Develop

npm install
npm run build
npm run smoke                 # temp repo: two writes, a search, the store's git log, a re-open
node test/ingest-smoke.mjs    # run from the repo root: ingests it twice, prints the entry count before and after

Both scripts point YUNAKI_MEMORY_ROOT at a temp directory, so they leave ~/.yunaki alone. They print their results without asserting on them, so they fail only if a call throws.

File

Role

src/index.ts

MCP server and tool schemas (zod)

src/repo.ts

Repo identity and lazy store creation

src/memory.ts

Memory files, index, search

src/ingest.ts

Repo scan, stack detection, file tree, doc capture

src/git.ts

git calls via execFile

src/config.ts

Store root, default repo, memory types

Stack: TypeScript, Node.js, @modelcontextprotocol/sdk, zod, gray-matter, git.

Status

v0.1.0, early. The per-repo store and the four tools are implemented and exercised by the two smoke scripts above. There are no assertion-based tests and no CI yet. The package is not published to npm. confidence and usage_count are stored, but nothing updates them yet. Every new memory is written at 0.5, so search ranking currently comes down to keyword hits.

Known gaps:

  • Ingest matches doc names by prefix anywhere in the tree, so a file such as scripts/install.sh is captured as a doc.

  • Ingest does not remove entries for docs that were deleted or renamed.

  • No tool sets status: deprecated yet. Search honors it only if you edit a memory file by hand.

  • A shallow clone gets its own store (see How it works).

Roadmap (not built yet)

  1. memory_reinforce(id, outcome): raise or decay confidence and usage_count instead of writing duplicates.

  2. Dedup before write: match near-duplicates by slug or meaning so reinforcement replaces them.

  3. memory_consolidate(): merge duplicates, prune stale entries, and promote high-confidence memories into a Claude skill's SKILL.md, so the skill's improvements show up as a git diff.

  4. Embedding rerank, cached in an .index/ directory kept out of each store's git history.

  5. memory_sync(): push and pull each store to a remote for shared team memory.

License

MIT

Available Tools

4 tools
memory_ingestIngest repo contentA

Scan the current git repo (tracked + non-ignored files) and write reference memories: a repo overview (stack, npm scripts, file types), the file-structure tree, and the contents of docs (README, CONTRIBUTING, docs/*). Idempotent — re-running updates the same entries in a single commit. Run this once when adopting a repo to seed memory.

ParametersJSON Schema
NameRequiredDescriptionDefault
maxDocsNoMax doc files to capture (default 20).
maxDepthNoFile-tree depth before collapsing (default 3).
repoPathNoA path inside the target repo. Defaults to the server's cwd.
maxDocBytesNoMax bytes per doc (default 4000).

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Discloses idempotency, single-commit behavior, and scope (tracked+non-ignored files, docs). No annotations exist, so description fully compensates.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences with no fluff. Front-loaded with action, then consequences and usage advice.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Complete for a side-effect tool: covers input, operation, idempotency, and use case. No output schema needed as write is the primary action.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema covers 100% of parameters with good descriptions. Description adds context about how parameters relate to tool behavior (e.g., depth to tree), but doesn't detail each param.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States specific verb 'scan' and resource 'git repo', enumerates outputs (overview, tree, docs). Distinguishes from siblings like memory_repo_info and memory_search.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly advises 'Run this once when adopting a repo to seed memory', clearly indicating when to use. Sibling tool names provide alternative contexts.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

memory_repo_infoRepo memory infoC

Show the resolved identity and memory location for the current git repo.

ParametersJSON Schema
NameRequiredDescriptionDefault
repoPathNo

TDQS

C2.6/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided; description is minimal. Does not disclose what 'resolved identity' or 'memory location' entails, or any potential side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Single short sentence, no waste. But under-specified; conciseness without completeness reduces usefulness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness1/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Very incomplete: missing parameter explanation, return value, and usage context for a tool with no output schema or annotations.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema has one parameter repoPath (optional, undocumented) and 0% schema description coverage. Description does not explain repoPath at all, leaving agents clueless.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description uses specific verb 'Show' and resource 'resolved identity and memory location for the current git repo'. Clearly distinguishes from writing/ingesting/searching siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this tool vs alternatives. Lacks explicit context or exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

memory_writeWrite memoryA

Persist a memory for the current git repo. Auto-creates the repo's git-backed memory store on first use and commits the write.

ParametersJSON Schema
NameRequiredDescriptionDefault
tagsNo
typeNofact | heuristic | failure | success | preference | reference
titleNoShort title used for the filename/slug.
sourceNoProvenance, e.g. a run id.
contentYesThe memory body (markdown).
repoPathNoA path inside the target repo. Defaults to the server's cwd.

TDQS

A3.8/5.0
Behavior3/5

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 tool auto-creates the store and commits writes, but does not mention potential side effects like overwriting existing memories, git conflict handling, or permission requirements. The behavioral information is useful but incomplete.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences long, front-loading the main purpose with no redundant or irrelevant information. Every word contributes to understanding, making it highly efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the moderate complexity (6 parameters, 1 required) and high schema coverage, the description is fairly complete. It adds context about the git-backed store and auto-creation. However, it lacks details on idempotency or behavior when a memory with the same title exists, which would improve completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema covers 83% of parameters with descriptions, so the baseline is 3. The tool description adds no extra param-specific semantics beyond the schema, such as formatting or constraints on the 'content' or 'tags' parameters. It merely reiterates the overall behavior.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb ('Persist a memory') and the resource ('for the current git repo'), and distinguishes the tool from siblings by highlighting auto-creation and git-backed store. It explains the side effect of committing the write, making the tool's function unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies this tool is for persisting a single memory, but it does not explicitly mention when to use it versus alternatives like memory_ingest (possible bulk ingestion) or when not to use it. No guidance on prerequisites or exclusion criteria is provided.

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.

  1. 4 tool updatesv0.1.0
    • First observedmemory_ingest
    • First observedmemory_repo_info
    • First observedmemory_search
    • First observedmemory_write

TDQS

A3.5/5.0

Scored across 4 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: ingest scans and writes repo memories, repo_info shows identity, search retrieves memories, and write persists new ones. No overlap or ambiguity.

Naming Consistency4/5

All tools start with 'memory_' prefix, but three use verbs (ingest, search, write) while one uses a noun phrase (repo_info). This slight inconsistency is minor but noticeable.

Tool Count4/5

4 tools is appropriate for a focused memory MCP server. It covers the essential operations without being too few or too many.

Completeness3/5

Covers core operations (ingest, write, search, info) but lacks explicit update or delete functionality. The ingest tool is idempotent and can overwrite, but direct memory removal is missing.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    D
    maintenance
    A persistent memory layer for Claude Code that maintains project information, technology stack, tasks, decisions, and session history between coding sessions, eliminating the need to re-explain project context.
    9
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    A persistent personal memory system for Claude that accumulates and organizes knowledge over time using plain Markdown in a local git repo, providing tools for reading, searching, and capturing short-term memories.
    1
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    Persistent memory for Claude Code — a self-evolving knowledge layer that survives across sessions, grows from every conversation, and surfaces relevant context automatically.
    14
    MIT