Official Python SDK for MME (Modular Memory Engine) — tag-graph memory for LLMs, built by Rail Tech.
Project description
railtech-mme
Python SDK for MME — the Modular Memory Engine by Rail Tech.
Tag-graph memory for LLMs. Bounded retrieval. Hard token budgets. Learns from use. No vector DB.
pip install railtech-mme
Requires Python 3.9+.
Quick start
from railtech_mme import MME
mme = MME(api_key="mme_live_...") # get one at https://mme.railtech.io
mme.save("I prefer dark chocolate over milk.")
pack = mme.inject("What do I like to eat?")
for item in pack.items:
print(f"- {item.title}: {item.excerpt}")
mme.feedback(pack_id=pack.pack_id, accepted=True)
That's the whole loop: save facts as they happen, inject them at prompt time, feedback to improve future packs.
Async
import asyncio
from railtech_mme import AsyncMME
async def main():
async with AsyncMME(api_key="mme_live_...") as mme:
await mme.save("hello")
pack = await mme.inject("hello")
print(pack.items[0].excerpt)
asyncio.run(main())
AsyncMME is a 1:1 mirror of MME. Same methods, same exceptions, same return types.
LangChain
pip install "railtech-mme[langchain]"
from railtech_mme import MME
from railtech_mme.langchain import MMESaveTool, MMEInjectTool
mme = MME(api_key="mme_live_...")
tools = [MMESaveTool(mme=mme), MMEInjectTool(mme=mme)]
# hand `tools` to your agent — see examples/langchain_agent.py for a runnable demo
The tools are LangChain BaseTool subclasses, so they drop into any agent that accepts tools (LangChain, LangGraph, AutoGen wrappers, etc.).
API surface
| Method | What it does |
|---|---|
mme.save(content, *, tags=None, section=None, status=None, source=None) |
Persist a memory block. Returns SaveResult. |
mme.inject(prompt, *, token_budget=2048, limit=None, filters=None, debug=False) |
Retrieve a token-budgeted Pack. |
mme.feedback(*, pack_id, accepted, item_ids=None, tags=None) |
Mark a pack as useful or not — trains the edge graph. |
mme.recent(*, limit=20, section=None) |
List the most recent memories. |
mme.delete(memory_id) |
Remove a memory. |
mme.tags() |
List all tags known for the org. |
AsyncMME exposes the same surface with async def / await.
Filters
Narrow a retrieval to a section, a status, or a time window:
import datetime as dt
from railtech_mme import MME, InjectFilters
mme = MME()
pack = mme.inject(
"what shipped this sprint?",
filters=InjectFilters(
section="work",
since=dt.datetime(2026, 4, 1, tzinfo=dt.timezone.utc),
),
)
Auth
Get your mme_live_... API key at https://mme.railtech.io → API Key.
The SDK reads it from the RAILTECH_API_KEY environment variable if you don't pass it explicitly:
export RAILTECH_API_KEY=mme_live_...
from railtech_mme import MME
mme = MME() # reads from env
The SDK exchanges your API key for a short-lived JWT on first use and caches it for the life of the client. Token refresh is automatic on 401.
Errors
All SDK errors inherit from MMEError:
import time
from railtech_mme import MME, MMEError, MMEAuthError, MMERateLimitError
mme = MME()
try:
mme.save("...")
except MMERateLimitError as e:
time.sleep(e.retry_after or 60)
except MMEAuthError:
# API key is invalid or revoked — get a new one
raise
except MMEError as e:
print(e.status_code, e.response_body)
The full taxonomy: MMEError → MMEAuthError, MMEClientError, MMERateLimitError, MMEServerError, MMETimeoutError, MMEBudgetExceeded.
Architecture — what MME does differently
MME does not use vector embeddings. It uses a bounded tag-graph that learns from pack accept/reject events. Retrieval is:
- Extract seed tags from the prompt
- Spread activation across the tag graph (bounded depth, beam width, decay)
- Score memories (activation + recency + importance + status − diversity penalty)
- Pack into a hard token budget greedily
Every pack respects the budget exactly. Every retrieval is explainable — seed tags, bounds, and activation paths come back in the response. Read the whitepaper for the full picture.
Examples
Runnable scripts in examples/:
basic.py— sync save / inject / feedbackasync_basic.py— async equivalentlangchain_agent.py— minimal ReAct agent with both MME tools
Each one reads RAILTECH_API_KEY from the environment.
Links
- Dashboard & API key: https://mme.railtech.io
- Issues: https://github.com/gokulJinu01/railtech-mme-python/issues
- Changelog: CHANGELOG.md
License
Apache-2.0
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file railtech_mme-0.1.0.tar.gz.
File metadata
- Download URL: railtech_mme-0.1.0.tar.gz
- Upload date:
- Size: 26.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
06f1c27317308a2d30898d4b202f2469572629445a300ab70fb0e9291085326b
|
|
| MD5 |
0cf07126addc7989e9884e0013395070
|
|
| BLAKE2b-256 |
aae7dc4509cc5835f5a468f64e09c84ad34242aa4a508d41a3da52821481385c
|
Provenance
The following attestation bundles were made for railtech_mme-0.1.0.tar.gz:
Publisher:
publish.yml on gokulJinu01/railtech-mme-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
railtech_mme-0.1.0.tar.gz -
Subject digest:
06f1c27317308a2d30898d4b202f2469572629445a300ab70fb0e9291085326b - Sigstore transparency entry: 1360801236
- Sigstore integration time:
-
Permalink:
gokulJinu01/railtech-mme-python@ffc81928f31170cfecf5f506c23a3d3a387bd739 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/gokulJinu01
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@ffc81928f31170cfecf5f506c23a3d3a387bd739 -
Trigger Event:
push
-
Statement type:
File details
Details for the file railtech_mme-0.1.0-py3-none-any.whl.
File metadata
- Download URL: railtech_mme-0.1.0-py3-none-any.whl
- Upload date:
- Size: 24.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
30e74987cc9173e2deeda4bf760181e4ba5e1b4c79e1574adcd0775cb6dd6c1e
|
|
| MD5 |
f6c6ce06d0180f1af3a07c3b70214cab
|
|
| BLAKE2b-256 |
0bb69ad8e461b389763a28bd1d8a12c4fc72cffe08a8db8c67d55df29f75239e
|
Provenance
The following attestation bundles were made for railtech_mme-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on gokulJinu01/railtech-mme-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
railtech_mme-0.1.0-py3-none-any.whl -
Subject digest:
30e74987cc9173e2deeda4bf760181e4ba5e1b4c79e1574adcd0775cb6dd6c1e - Sigstore transparency entry: 1360801558
- Sigstore integration time:
-
Permalink:
gokulJinu01/railtech-mme-python@ffc81928f31170cfecf5f506c23a3d3a387bd739 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/gokulJinu01
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@ffc81928f31170cfecf5f506c23a3d3a387bd739 -
Trigger Event:
push
-
Statement type: