🧠 powr-memory-sdk
Universal AI Agent Memory SDK — Embedded Local SQLite + Central Distributed MCP Server, one unified API.
Give your AI agents persistent memory across turns, users, and services — in 4 lines of code.
⚡ Quickstart
pip install powr-memory-sdk
from memory_sdk import mem
session = mem("user_123")
session.remember("name", "Gunit")
session.add_user("Mujhe Python sikhna hai")
messages = session.to_messages("You are a helpful assistant.")
# → Pass `messages` directly to any LLM (OpenAI, Groq, Anthropic, Ollama)
That's it. No server to start, no config file, no database setup.
🏗️ Two Modes — One API
| Local Mode | Central Mode | |
|---|---|---|
| Storage | Embedded SQLite (your machine) | Deployed MCP Server (shared) |
| Best for | Dev, CLI tools, single agent | Production, multi-agent, microservices |
| Setup | Zero — just a file path | Zero — uses deployed server by default |
| Latency | Sub-millisecond | ~5–20 ms network |
| API | ✅ Identical | ✅ Identical |
The API is 100% identical across both modes — switch anytime with one line.
📦 Installation
# Basic (local SQLite memory only)
pip install powr-memory-sdk
# With OpenAI support
pip install "powr-memory-sdk[openai]"
# With LangChain support
pip install "powr-memory-sdk[openai,langchain-core]"
# Everything
pip install "powr-memory-sdk[all]"
🚀 Usage
Zero-Config — mem Singleton (Recommended)
from memory_sdk import mem
# Uses local SQLite automatically — safe, zero-config, keeps data on your machine
session = mem("user_123")
session.remember("name", "Ali")
session.remember({"city": "Lahore", "diet": "Vegetarian"})
session.add_user("Dinner mein kya khaaon?")
session.add_assistant("Lahore mein vegetarian ke liye Dal Makhani best hai!")
messages = session.to_messages("You are a helpful assistant.")
# → Ready to pass to any LLM API
Switch Mode — One Line
from memory_sdk import mem
# Custom local SQLite database file
mem.configure(mode="local", db_path="app.db")
# Central MCP server (for distributed / multi-agent architectures)
mem.configure(mode="central", url="http://localhost:8765/mcp")
# Back to default local storage
mem.configure(mode="local")
🔌 Integration Examples
OpenAI
from openai import OpenAI
from memory_sdk import mem
client = OpenAI()
def chat(user_id: str, message: str) -> str:
session = mem(user_id)
session.add_user(message)
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=session.to_messages("You are a helpful assistant.")
)
reply = response.choices[0].message.content
session.add_assistant(reply)
return reply
AutoOpenAI — 1-Line Drop-in Replacement
# Change just this one line in your existing OpenAI project:
# from openai import OpenAI
from memory_sdk import AutoOpenAI as OpenAI
client = OpenAI(session_id="user_123") # Memory is fully automatic
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Mera naam Ali hai"}]
)
# SDK automatically saves the message and injects memory on next call
FastAPI
from fastapi import FastAPI
from memory_sdk import mem
app = FastAPI()
@app.on_event("startup")
def setup():
mem.configure(mode="local", db_path="prod.db", window_size=10)
@app.post("/chat/{user_id}")
async def chat(user_id: str, message: str):
session = mem(user_id)
session.add_user(message)
messages = session.to_messages("You are a helpful assistant.")
# ... your LLM call here
reply = "Hello!"
session.add_assistant(reply)
return {"reply": reply}
Flask
from flask import Flask, request, jsonify
from memory_sdk import mem
app = Flask(__name__)
mem.configure(mode="local", db_path="app.db")
@app.route("/chat/<user_id>", methods=["POST"])
def chat(user_id):
message = request.json["message"]
session = mem(user_id)
session.add_user(message)
messages = session.to_messages("You are a helpful assistant.")
return jsonify({"messages": messages})
LangChain Agent
from langchain_openai import ChatOpenAI
from memory_sdk import mem
llm = ChatOpenAI(model="gpt-4o-mini")
def chat(user_id: str, message: str) -> str:
session = mem(user_id)
agent = llm.bind_tools(session.get_langchain_tools())
session.add_user(message)
response = agent.invoke(session.to_messages("You are helpful."))
session.add_assistant(response.content)
return response.content
Telegram / WhatsApp Bot
from memory_sdk import mem
def handle_message(chat_id: str, message: str) -> str:
session = mem(chat_id) # chat_id = unique user identifier
session.add_user(message)
messages = session.to_messages("You are a helpful assistant.")
reply = your_llm(messages) # your LLM call
session.add_assistant(reply)
return reply
📖 Full API Reference
mem — Zero-Config Singleton
from memory_sdk import mem
mem.configure(mode, **kwargs) # Configure once at startup
session = mem("user_id") # Get/create a session (callable)
session = mem.session("user_id") # Same — explicit style
mem.close() # Release resources
Session Methods
session = mem("user_123")
# ── Save facts ────────────────────────────────────────────────────
session.remember("key", "value") # single fact
session.remember({"k1": "v1", "k2": "v2"}) # multiple facts at once
# ── Read facts ────────────────────────────────────────────────────
session.recall("key") # one fact → value or None
session.recall() # all facts → dict
session.profile() # all facts → dict (alias)
# ── Conversation ──────────────────────────────────────────────────
session.add_user("...") # record user message
session.add_assistant("...") # record assistant reply
session.add_system("...") # record system message
session.history(limit=10) # recent messages list
# ── LLM-ready output ──────────────────────────────────────────────
session.to_messages(
system_prompt="You are helpful.", # optional base prompt
include_memory=True, # inject facts into system message
)
# → [{"role": "system", "content": "..."}, {"role": "user", ...}, ...]
# ── Cleanup ───────────────────────────────────────────────────────
session.clear(keep_state=True) # clear messages, keep facts
session.forget() # wipe everything (messages + facts)
mem.configure() Options
mem.configure(
mode="central", # "central" (default) or "local"
# Central mode options:
url="http://...", # MCP server URL (or set MCP_SERVER_URL env var)
project="my_app", # namespace for session isolation
# Local mode options:
db_path="app.db", # SQLite file path (or ":memory:" for transient)
window_size=10, # max recent messages to keep in context
auto_summarize=False, # LLM-based rolling summarization
)
⚙️ Environment Variables
Set these instead of hardcoding in code:
# Central server URL (overrides built-in default)
MCP_SERVER_URL=https://your-server.run.app/mcp
# Alternate env var name
MEMORY_SERVER_URL=https://your-server.run.app/mcp
# Required by central mode. JWT-protected servers must use the same secret
# (at least 32 bytes); JWT_ISSUER and JWT_AUDIENCE default to "memory-store".
JWT_SECRET=<shared-secret-at-least-32-bytes>
# Force a mode (optional)
MEMORY_MODE=local
# Local DB path (optional)
MEMORY_DB_PATH=./data/agent.db
# Model for auto-summarization
MEMORY_SUMMARIZER_MODEL=gpt-4o-mini
# OpenAI key (needed only for auto_summarize=True)
OPENAI_API_KEY=sk-...
🏃 Running Your Own Central Server
# Install server extras
pip install "powr-memory-sdk[server]"
# Start the MCP memory server
memory-server --port 8765
# Point your app to it
export MCP_SERVER_URL=http://localhost:8765/mcp
The bundled memory-server is a development server and does not enforce JWT
authentication. For a JWT-protected deployment, use the JWT-enabled memory
store and configure the same JWT_SECRET on the server and client.
Or with Docker:
docker build -t memory-server .
docker run -p 8765:8765 -e PORT=8765 memory-server
Then in your code:
from memory_sdk import mem
mem.configure(mode="central", url="http://localhost:8765/mcp")
🌐 Central MCP Server — Live Deployed
A central memory server is already live and ready to use:
URL : https://memory-module-813340036970.asia-south1.run.app/mcp
Region : asia-south1 (Mumbai)
Protocol: Streamable HTTP (MCP)
This is the default when you use mode="central" without specifying a url. All session data is namespaced by project so different apps don't interfere.
🧪 Testing
# Run all tests
pytest tests/ -v
# With coverage
pytest tests/ --cov=memory_sdk --cov-report=term-missing
Testing tip — use in-memory SQLite:
# conftest.py
import pytest
from memory_sdk import mem
@pytest.fixture(autouse=True)
def isolate_memory():
mem.configure(mode="local", db_path=":memory:")
yield
mem.close()
🗂️ Project Structure
memory-sdk/
├── src/memory_sdk/
│ ├── __init__.py ← mem singleton + all exports
│ ├── factory.py ← Memory() factory router
│ ├── base.py ← BaseMemory / BaseSession protocols
│ ├── local/ ← Embedded SQLite engine
│ │ ├── engine.py
│ │ ├── session.py ← Full session + sliding window + summarizer
│ │ ├── sqlite_storage.py
│ │ ├── tools.py ← OpenAI function-call tool schemas
│ │ └── langchain.py ← LangChain tool wrappers
│ ├── central/ ← Distributed MCP engine
│ │ ├── engine.py
│ │ ├── session.py
│ │ └── client.py ← Async MCP HTTP client
│ ├── server/
│ │ └── server.py ← Standalone MCP memory server
│ └── wrappers/
│ └── openai_wrapper.py ← AutoOpenAI drop-in replacement
├── examples/
│ ├── 01_local_mode_quickstart.py
│ ├── 02_central_mode_quickstart.py
│ ├── 03_switching_modes.py
│ └── 04_openai_autopilot.py
├── tests/
└── pyproject.toml
📋 Compatibility
| Framework | Support |
|---|---|
| Python | 3.10+ |
| OpenAI SDK | ✅ |
| LangChain | ✅ |
| FastAPI | ✅ |
| Flask | ✅ |
| Django | ✅ |
| Groq | ✅ (same OpenAI API) |
| Anthropic | ✅ (via to_messages()) |
| Ollama | ✅ (via to_messages()) |
| Any MCP client | ✅ |
Metadata
Release files for powr-memory-sdk 1.0.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| powr_memory_sdk-1.0.2.tar.gz | 50.6 kB | Without provenance | Details for powr_memory_sdk-1.0.2.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| powr_memory_sdk-1.0.2-py3-none-any.whl | Python 3 | none | any | Details for powr_memory_sdk-1.0.2-py3-none-any.whl |
Total release size: 103.6 kB
Release files / powr_memory_sdk-1.0.2.tar.gz
| Download URL | powr_memory_sdk-1.0.2.tar.gz |
|---|---|
| Size | 50.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6566e21dc6f9d55863e0c97ae116bf4a8126805b1d02685e6561eb8175fe6e26
|
|
BLAKE2b-256 checksum How to use checksums |
8fccf306483af0689cc2c334f7a6632f528fec257cc7c5ac32b76bda9f9348ca
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.16
|
Release files / powr_memory_sdk-1.0.2-py3-none-any.whl
| Download URL | powr_memory_sdk-1.0.2-py3-none-any.whl |
|---|---|
| Size | 52.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
73b651a2d441485b9c13cebee74b38260e679e1317a534055a915b34a7c7538c
|
|
BLAKE2b-256 checksum How to use checksums |
588a65c724b30800c46e5efb9b1d9fafb28c4899cfab237b83c4e2937c21004a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.16
|
Security for powr-memory-sdk 1.0.2
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.