memory-mcp

memory-mcp

Personal memory MCP server for Claude Code with an Obsidian-style graph. Enables persistent, queryable memories across sessions using Markdown files with bidirectional wiki-links and a D3.js force-directed graph UI.

Category
访问服务器

README

memory-mcp

Personal memory MCP server for Claude Code with an Obsidian-style interactive graph.

TypeScript Node.js License Tests

Persistent, queryable memory across Claude Code sessions. Memories are plain Markdown files with YAML frontmatter. Wiki-links ([[Memory Name]]) create bidirectional connections visualized in a D3.js force-directed graph at localhost:4242.


Screenshot

(graph UI screenshot here)


Features

  • 8 MCP tools — save, read, search, list, delete, graph data, stats, open graph
  • D3.js force-directed graph — Obsidian-style visual graph of all memories and their connections
  • Wiki-links[[Memory Name]] in content auto-creates bidirectional links
  • Fuzzy search — powered by Fuse.js, searches name, content, and tags
  • 5 memory types — each rendered as a distinct color in the graph
  • Plain Markdown storage — memories are .md files with YAML frontmatter, readable without any tooling
  • Web UI at localhost:4242 — search, type filters, node click opens a sidebar with rendered Markdown
  • 96% test coverage — Vitest, isolated per module with temp vault directories

Quick Start

git clone https://github.com/otaviosenne/memory-mcp
cd memory-mcp
npm install
npm run build

Add to Claude Code's ~/.claude/mcp.json:

{
  "mcpServers": {
    "memory-mcp": {
      "type": "stdio",
      "command": "node",
      "args": ["/path/to/memory-mcp/dist/index.js"],
      "env": {
        "MEMORY_VAULT_PATH": "~/.local/share/memory-mcp/vault",
        "MEMORY_WEB_PORT": "4242"
      }
    }
  }
}

Restart Claude Code. The MCP server starts automatically with the session.


MCP Tools

Tool Description
memory_save Create or update a memory by name
memory_read Read a single memory by ID or name
memory_search Fuzzy search across name, content, and tags
memory_list List all memories, optionally filtered by type
memory_delete Delete a memory by ID
memory_graph_data Return all nodes and edges for graph rendering
memory_stats Count memories by type, total links, vault size
memory_open_graph Open the web UI in the default browser

Example: memory_save

Input:

{
  "name": "Chrome Agent MCP",
  "type": "project",
  "content": "Browser automation MCP using Chrome DevTools Protocol. Built on [[memory-mcp]] for session context.",
  "tags": ["mcp", "typescript", "chrome"]
}

Output:

{
  "id": "a1b2c3d4-...",
  "name": "Chrome Agent MCP",
  "type": "project",
  "links": ["<uuid-of-memory-mcp>"],
  "created": "2026-03-24T10:00:00.000Z"
}

Example: memory_search

Input:

{ "query": "typescript mcp" }

Output: array of matching memories, sorted by relevance score.

Example: memory_stats

Output:

{
  "total": 24,
  "byType": { "project": 10, "user": 5, "feedback": 4, "reference": 3, "note": 2 },
  "totalLinks": 38
}

Memory Types

Type Graph Color When to Use
user Green Personal info, preferences, skills, background
project Blue Project decisions, tech stack, current status, constraints
feedback Yellow Corrections and confirmed patterns ("don't do X", "yes, exactly like this")
reference Pink External resources, accounts, tools, links
note Gray General context that doesn't fit other types

Wiki-links

Use [[Memory Name]] syntax anywhere in a memory's content to reference another memory by exact name.

This project depends on [[memory-mcp]] for persistent context across sessions.
The architecture follows the patterns described in [[SOLID Design Principles]].

Links are resolved at save time. Both the source and target memory store the connection — the graph is always bidirectional. If the target memory does not exist yet, the link is stored as unresolved and re-evaluated when the target is created.


Graph UI

Open localhost:4242 while the MCP server is running (or call memory_open_graph).

  • Node size scales with connection count — highly-linked memories appear larger
  • Node color maps to memory type
  • Click a node to open a sidebar with the full Markdown content, rendered
  • Search bar filters nodes by name or tag in real time
  • Type toggles show or hide entire memory types
  • Zoom and pan are supported via D3 zoom behavior

The graph updates live — refresh the page to reflect new memories.


Claude Code Skill: /save-memories

At the end of a session, run /save-memories to extract and persist meaningful context automatically.

The skill reviews the conversation and decides what is worth saving. It skips trivial fixes and ephemeral tasks — it only saves things that would be genuinely useful in a future session.

~/.claude/skills/save-memories/SKILL.md:

---
name: save-memories
description: Analyze the current conversation and save meaningful memories to the personal memory vault. Use at the end of any session where something worth remembering was discussed — new projects, preferences revealed, corrections made, important context.
user-invocable: true
---

# Save Memories

Analyze the current conversation and save relevant memories to the vault at `/home/senne/.local/share/memory-mcp/vault/`.

## Step 1 — Review the conversation

Read back through what was discussed. Ask: what here would be useful to know in a future conversation that isn't already obvious from the code?

## Step 2 — Decide what to save

Only save if it reveals:

| Type | Save when |
|------|-----------|
| `user` | Personal info, skills, preferences, opinions, background |
| `feedback` | Corrections ("not like that"), confirmed patterns ("yes, exactly") |
| `project` | Project decisions, stack, current status, key constraints |
| `reference` | External resources, accounts, tools, links, credentials context |
| `note` | Important context that doesn't fit other types |

**Skip:** trivial bug fixes, ephemeral tasks, things obvious from the code, duplicates.

## Step 3 — Save each memory

For each memory, run:

```bash
node -e "
import('/path/to/memory-mcp/dist/core/vault.js').then(async ({ Vault }) => {
  const vault = new Vault('/path/to/vault');
  await vault.initialize();
  const saved = await vault.save({
    name: 'MEMORY NAME',
    type: 'project',
    content: 'Content here. Use [[Other Memory Name]] to link related memories.',
    tags: ['tag1', 'tag2'],
  });
  console.log('Saved:', saved.name, '| links:', saved.links.length);
  process.exit(0);
});
" 2>/dev/null

Use [[wiki-links]] in content to connect related memories. The exact name must match an existing memory name.

Step 4 — Report

After saving, briefly list what was saved and why. Keep it to one line per memory.


---

## Architecture

src/ ├── index.ts # MCP server entry point, tool registration ├── types/index.ts # All TypeScript types and interfaces ├── core/ │ ├── storage.ts # File I/O abstraction (read, write, delete, list) │ ├── parser.ts # Frontmatter parsing and serialization (gray-matter) │ ├── linker.ts # Wiki-link extraction and bidirectional resolution │ └── vault.ts # Orchestrator: CRUD, search, graph, stats ├── tools/ # 8 MCP tool handlers, one file per tool └── web/ ├── server.ts # Express REST API serving graph data └── public/index.html # D3.js graph UI, single-file, no build step


Each module has one responsibility. The `Vault` class composes `Storage`, `Parser`, and `Linker` — it does not implement any of their logic directly.

---

## Tech Stack

| Package | Role |
|---------|------|
| `@modelcontextprotocol/sdk` | MCP server protocol |
| `d3` v7 | Force-directed graph in the browser |
| `express` | REST API for the web UI |
| `gray-matter` | YAML frontmatter parsing |
| `fuse.js` | Fuzzy search |
| `zod` | Tool input validation |
| `vitest` | Tests (96% coverage) |
| TypeScript strict mode | Type safety throughout |

---

## Code Patterns & SOLID

The codebase applies SOLID principles throughout:

**Single Responsibility** — each module does exactly one thing. `Storage` handles file I/O. `Parser` handles Markdown/frontmatter. `Linker` handles wiki-link extraction and resolution. `Vault` orchestrates them.

**Open/Closed** — new memory types can be added by extending the `MemoryType` union in `types/index.ts`. No core logic changes.

**Dependency Inversion** — `Vault` depends on the `Storage` and `Parser` interfaces, not their concrete implementations. This makes the core fully testable with mock implementations.

**Small files** — every file stays under 100 lines. No file mixes concerns.

No comments in the source — names are the documentation. No magic numbers — all constants are named. All code is in English.

---

## Testing

```bash
npm test               # run all tests
npm run test:coverage  # coverage report (target: 70%+, actual: 96%)

Tests live in tests/, mirroring src/:

tests/
├── core/
│   ├── storage.test.ts
│   ├── parser.test.ts
│   ├── linker.test.ts
│   └── vault.test.ts
└── tools/
    └── *.test.ts

Each test suite creates a temporary vault directory and tears it down after. No shared state between tests.


Environment Variables

Variable Default Description
MEMORY_VAULT_PATH ~/.local/share/memory-mcp/vault Directory where memory .md files are stored
MEMORY_WEB_PORT 4242 Port for the graph web UI

Memory File Format

Each memory is stored as a .md file with YAML frontmatter:

---
id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
name: Chrome Agent MCP
type: project
tags:
  - mcp
  - typescript
  - chrome
created: 2026-03-24T10:00:00.000Z
updated: 2026-03-24T10:00:00.000Z
links:
  - b2c3d4e5-f6a7-8901-bcde-f12345678901
---

Browser automation MCP using Chrome DevTools Protocol.
Built on [[memory-mcp]] for persistent session context.
Supports screenshot, click, fill, scroll, and JS evaluation.

Files are human-readable and can be edited directly. The links array is managed automatically by the linker — manual edits to links are valid but wiki-links in content take precedence on next save.


License

MIT

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选