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
# Save a few facts — MME tags them automatically
mme.save("I prefer dark chocolate over milk chocolate.")
mme.save("I'm allergic to peanuts.")
mme.save("My favorite cuisine is Thai.")
# Recall them later — tag-graph activation matches keywords in the prompt
pack = mme.inject("What are my food preferences and allergies?", token_budget=1024)
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.
Tip on prompt phrasing. MME's retrieval is tag-graph-based, not embedding-based: the prompt's keywords seed propagation across the tag graph. Prompts that share concrete words with your saved facts (
food,chocolate,allergies) retrieve reliably even on a brand-new account; abstract paraphrases (dietary preferences) only start working after the graph has built up enough edges to bridge the gap. This is by design — it's why MME stays explainable and bounded.
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 as raw MemoryBlock objects (full content and structured tags). |
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
Release files for railtech-mme 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| railtech_mme-0.1.1.tar.gz | 27.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| railtech_mme-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 52.9 kB
Release files / railtech_mme-0.1.1.tar.gz
| Download URL | railtech_mme-0.1.1.tar.gz |
|---|---|
| Size | 27.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
50412da415a0eec0545294b583ea7c291ef18e38e56b85eac98d5b82b33c7400
|
|
BLAKE2b-256 checksum How to use checksums |
0a86a2603c8c1a931e6ec98164ec0631ff6d3ba4621a7cf05bafa75c5b120262
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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 Apr 23, 2026.
Transparency logRelease files / railtech_mme-0.1.1-py3-none-any.whl
| Download URL | railtech_mme-0.1.1-py3-none-any.whl |
|---|---|
| Size | 25.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
15bbf613c0f8c61956713f54229aca80a0bce543700ae1b321def8018044432a
|
|
BLAKE2b-256 checksum How to use checksums |
c6cb99d391abc51bbe4d8fc84e96ea66a6178943ebdc1a95c4abfc136ab9e50e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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 Apr 23, 2026.
Transparency log