Skip to main content

railtech-mme

PyPI version CI Python License

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:

  1. Extract seed tags from the prompt
  2. Spread activation across the tag graph (bounded depth, beam width, decay)
  3. Score memories (activation + recency + importance + status − diversity penalty)
  4. 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/:

Each one reads RAILTECH_API_KEY from the environment.

Links

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)

Source distribution for railtech-mme 0.1.1
File Size Uploaded
railtech_mme-0.1.1.tar.gz 27.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for railtech-mme 0.1.1
File Interpreter ABI Platform
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 log

Release 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

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page