plain-text-memory-mcp
Knowledge-graph memory MCP server that tags every entry with the date it was added and the agent that added it. Memory lives in a plain JSONL file inside each repo, so every agent working in that repo shares it.
It is a drop-in replacement for @modelcontextprotocol/server-memory: the
same nine tools and input keys, and it reads files written by the original
server. It adds initialize_memory and export_taxonomy, the cleanup and
export prompts, and the memory://taxonomy resource.
Install
The server runs with uv; uvx downloads and
starts it on demand, so there is nothing else to install.
uvx plain-text-memory-mcp
Started by hand, it waits for an MCP client on stdin; press Ctrl+C to stop.
Configure
Add the server to each agent's MCP config. The server finds the repo from the
folder the agent starts it in, so register it per project, or set
MEMORY_FILE_PATH if a client starts servers somewhere else.
Claude Code, .mcp.json in the repo:
{
"mcpServers": {
"plain-text-memory": {
"type": "stdio",
"command": "uvx",
"args": ["plain-text-memory-mcp"]
}
}
}
Codex, .codex/config.toml:
[mcp_servers.plain-text-memory]
command = "uvx"
args = ["plain-text-memory-mcp"]
Cursor, .cursor/mcp.json in the repo:
{
"mcpServers": {
"plain-text-memory": {
"command": "uvx",
"args": ["plain-text-memory-mcp"]
}
}
}
VS Code, .vscode/mcp.json in the repo:
{
"servers": {
"plain-text-memory": {
"type": "stdio",
"command": "uvx",
"args": ["plain-text-memory-mcp"]
}
}
}
Where memory is stored
MEMORY_FILE_PATH, if set. A relative path resolves against the folder the agent starts the server in.<git root>/.agents/memory.local.jsonl.<start folder>/.agents/memory.local.jsonloutside a git repo.
Writes hold a lock on memory.local.jsonl.lock beside the memory file, so
Claude Code and Codex can write to the same repo's memory at the same time
without losing each other's changes. The file stays after the server exits;
leave it in place.
Tags
Every entity, relation, and observation carries added_at (local time with
UTC offset) and agent (claude-code, codex, or the client's own name).
Set MEMORY_AGENT to override the agent name. Entries written by the original
server show null for both.
Repo guard
The first write adds a header line recording which repo the memory file
belongs to. If the file is later found in a different repo, for example after
copying .agents/ from a template, every tool returns an error instead of
serving the other repo's memories. Resolve it with the initialize_memory
tool:
mode: "fresh"renames the old file tomemory.local.jsonl.bak-<time>and starts an empty graph.mode: "adopt"keeps the memories and points the header at this repo, for a repo that was moved or renamed.
Files without a header, including ones written by the original server, are claimed by the repo that writes to them first.
Prompts
The server publishes two MCP prompts, which clients offer as commands; Claude
Code shows them as /mcp__plain-text-memory__cleanup and
/mcp__plain-text-memory__export.
| Prompt | Use |
|---|---|
cleanup |
Propose deletions and merges; nothing is deleted until approved |
export |
Write the repo's taxonomy and usage to .agents/ and report it |
Guidance for agents
On connect, the server sends every MCP client instructions for using memory well: search before planning, verify what memory says against the repo, save only lasting facts, and resolve the repo guard. Tool and parameter descriptions say what each tool does and returns, and the prompts above carry the cleanup and export workflows. No agent-specific setup is needed.
Taxonomy
taxonomy.json lists every record
type with its purpose and fields, every tool with its parameters and results,
every MCP resource and prompt, and the allowed values for enum fields such
as agent and initialize_memory.mode. It is generated from the code; do
not edit it by hand. Record type purposes live in RECORD_PURPOSES
in records.py. The file ships inside the package, where the server's
export_taxonomy tool reads it. MCP clients can also read it as the
resource memory://taxonomy.
taxonomy_version follows semantic versioning and bumps itself: a removed
item, section, or changed type is major, an added item is minor, and a
description, purpose, title, or package version change is patch. Each bump
adds a changelog entry listing what changed.
Regenerate it with:
.venv/Scripts/python.exe scripts/build_taxonomy.py
The pre-commit hook runs this and stops the commit when the file changes, so the new version is reviewed and staged. A test also fails when the committed file is stale. Enable the hook once per clone:
git config core.hooksPath .githooks
Exporting to a repo
Ask an agent to call the export_taxonomy tool. It writes
.agents/memory.local.taxonomy.jsonc beside the repo's memory file, holding
the versioned schema above plus this repo's usage: entry counts, the entity
and relation types in use, and entries per agent. // comments explain each
section and each record type's purpose. Use it to keep type names consistent
within a repo. The export is local, like the memory file; ignore both with
.agents/*memory.local.*.
Develop
py -3.13 -m venv .venv
.venv/Scripts/python.exe -m pip install -e . --group dev
.venv/Scripts/python.exe -m pytest
To have agents run your working copy instead of the published package,
install it as an editable tool and use plain-text-memory-mcp as the
config's command, with no args:
uv tool install -e .
Code changes then take effect the next time an agent starts the server.
License
MIT, copyright Plain Text Office LLC. See LICENSE.
Metadata
Release files for plain-text-memory-mcp 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| plain_text_memory_mcp-0.1.0.tar.gz | 38.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| plain_text_memory_mcp-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 65.0 kB
Release files / plain_text_memory_mcp-0.1.0.tar.gz
| Download URL | plain_text_memory_mcp-0.1.0.tar.gz |
|---|---|
| Size | 38.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7c6d0ae20d99b0de855eee147c1839d6f1b5c53f0ef33b61ef652e892a5b6af5
|
|
BLAKE2b-256 checksum How to use checksums |
b201c4cba302c6a3ab1767210a82f99f88bf8f99938ef049da731fcfa3b4307d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.
Transparency logRelease files / plain_text_memory_mcp-0.1.0-py3-none-any.whl
| Download URL | plain_text_memory_mcp-0.1.0-py3-none-any.whl |
|---|---|
| Size | 26.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e73e67854b6f2c147b2b7524b970fe5e79f1f4f5e8c435f9cdd712703fa49c4c
|
|
BLAKE2b-256 checksum How to use checksums |
04637bc1f5ba489ef5c3077d41622973b624d738128e09ab8a0436330d56c46a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.
Transparency log