# BECOMER — Memory API for AI Applications [![PyPI](https://img.shields.io/pypi/v/becomer)](https://pypi.org/project/becomer/) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) [![LongMemEval](https://img.shields.io/badge/LongMemEval-94.4%25-brightgreen)](https://becomer.net/#benchmarks) **Give your AI app persistent memory in 3 lines of code.** ```python from becomer import Client mem = Client("bk-your-api-key") mem.store("User prefers dark mode and speaks French") memories = mem.recall("user preferences") # → ['User prefers dark mode...'] ``` → [Get your free API key](https://becomer.net/signup.html) · [Docs](https://becomer.net/docs.html) · [Benchmarks](https://becomer.net/#benchmarks) · [Examples](examples/) --- ## Why BECOMER Most memory solutions bolt on a vector store and call it done. BECOMER uses a proprietary retrieval engine benchmarked against **LongMemEval**, the standard academic benchmark for long-term conversational memory. | Benchmark | BECOMER | Hindsight (next best) | |-----------|---------|----------------------| | LongMemEval (500 probes) | **94.4%** | 91.4% | 94.4% means when your user asks "what did I tell you about my diet last week?", the right memory surfaces. Not a vaguely related one. The right one. --- ## Install ```bash pip install becomer ``` Zero dependencies. Pure Python stdlib only. --- ## Quick start ```python from becomer import Client mem = Client("bk-your-api-key") # Store anything worth remembering mem.store("User is building a React app, prefers TypeScript") mem.store("User's name is Sarah, she's a senior engineer at Stripe") # Recall before each LLM call context = mem.recall("what do I know about the user?") # → ['User is building a React app, prefers TypeScript', # "User's name is Sarah, she's a senior engineer at Stripe"] # Build your prompt with memory injected system_prompt = "You are a helpful assistant.\n\nWhat you remember:\n" + "\n".join(context) ``` --- ## Three ways to integrate ### 1. Python SDK (this repo) ```python from becomer import Client mem = Client("bk-your-api-key") mem.store("...") mem.recall("...") ``` ### 2. MCP — works with Claude Desktop, Cursor, any MCP host ```json { "mcpServers": { "becomer": { "command": "python", "args": ["-m", "becomer"], "env": { "BECOMER_API_KEY": "bk-your-api-key" } } } } ``` Claude will automatically store and recall memories across sessions. No code changes needed. ### 3. REST API — language-agnostic ```bash # Store curl -X POST https://becomer.net/v1/store \ -H "Authorization: Bearer bk-your-api-key" \ -H "Content-Type: application/json" \ -d '{"content": "User prefers concise answers"}' # Recall curl -X POST https://becomer.net/v1/recall \ -H "Authorization: Bearer bk-your-api-key" \ -H "Content-Type: application/json" \ -d '{"query": "user preferences", "top_k": 5}' ``` --- ## Multi-tenant (one key, many users) Building a product where each of your users needs their own isolated memory? Pass `user_id` — no extra keys needed. ```python from becomer import Client # One master key for your whole app mem = Client("bk-your-master-key", user_id="user-alice") mem.store("Alice prefers Python over JavaScript") # Different user — completely isolated memory space mem_bob = Client("bk-your-master-key", user_id="user-bob") mem_bob.recall("programming preferences") # → [] (can't see Alice's memories) # Or override per-call mem = Client("bk-your-master-key") mem.store("Bob uses dark mode", user_id="user-bob") mem.recall("preferences", user_id="user-alice") # → Alice's memories only ``` **MCP with per-user isolation:** ```json { "mcpServers": { "becomer": { "command": "python", "args": ["-m", "becomer"], "env": { "BECOMER_API_KEY": "bk-your-master-key", "BECOMER_USER_ID": "alice-123" } } } } ``` **REST API:** ```bash curl -X POST https://becomer.net/v1/store \ -H "Authorization: Bearer bk-your-master-key" \ -H "Content-Type: application/json" \ -d '{"content": "Alice prefers dark mode", "user_id": "alice-123"}' ``` `user_id` can be any string: a UUID, a username, an email — whatever your app uses internally. Memories across different `user_id` values are fully isolated. Billing counts against the master key. --- ## LangChain ```python from langchain.memory import BaseMemory from becomer import Client from pydantic import Field class BecomerMemory(BaseMemory): client: object = Field(default=None) memory_key: str = "history" def __init__(self, api_key: str, **kwargs): super().__init__(**kwargs) self.client = Client(api_key) @property def memory_variables(self): return [self.memory_key] def load_memory_variables(self, inputs): query = inputs.get("input", "") memories = self.client.recall(query) return {self.memory_key: "\n".join(memories)} def save_context(self, inputs, outputs): self.client.store(f"User: {inputs.get('input','')} | AI: {outputs.get('output','')}") def clear(self): self.client.forget() # Usage from langchain.chains import ConversationChain from langchain_openai import ChatOpenAI chain = ConversationChain( llm=ChatOpenAI(model="gpt-4o"), memory=BecomerMemory(api_key="bk-your-api-key") ) chain.predict(input="My name is Sarah and I work at Stripe") # Next session — Sarah is still remembered. ``` --- ## OpenAI / Anthropic direct ```python import openai from becomer import Client mem = Client("bk-your-api-key") def chat(user_message: str) -> str: context = mem.recall(user_message) system = "You are a helpful assistant." if context: system += "\n\nWhat you remember about the user:\n" + "\n".join(f"- {m}" for m in context) response = openai.chat.completions.create( model="gpt-4o", messages=[ {"role": "system", "content": system}, {"role": "user", "content": user_message}, ] ) reply = response.choices[0].message.content mem.store(f"User said: {user_message}") return reply ``` --- ## API reference | Method | Description | |--------|-------------| | `Client(api_key, user_id=None)` | Create a client. `user_id` namespaces all calls to a sub-user. | | `store(content, user_id=None)` | Store a memory | | `recall(query, top_k=5, user_id=None)` | Retrieve top-k relevant memories | | `forget(user_id=None)` | Delete all memories for this key (or sub-user) | | `sync(user_id=None)` | Consolidate working memory into long-term storage | Full REST API docs → [becomer.net/docs.html](https://becomer.net/docs.html) --- ## Examples | File | Framework | |------|-----------| | [quickstart.py](examples/quickstart.py) | Plain Python | | [openai_chat.py](examples/openai_chat.py) | OpenAI SDK | | [anthropic_chat.py](examples/anthropic_chat.py) | Anthropic SDK | | [langchain_memory.py](examples/langchain_memory.py) | LangChain | | [langgraph_memory.py](examples/langgraph_memory.py) | LangGraph | | [llamaindex_memory.py](examples/llamaindex_memory.py) | LlamaIndex | | [crewai_memory.py](examples/crewai_memory.py) | CrewAI | | [autogen_memory.py](examples/autogen_memory.py) | AutoGen | | [mcp.json](examples/mcp.json) | MCP (Claude Desktop / Cursor) | | [mcp_multitenant.json](examples/mcp_multitenant.json) | MCP multi-tenant | --- ## Pricing | Plan | Calls/month | Price | |------|-------------|-------| | Free | 1,000 | Free forever | | Pro | 50,000 | ₹1,140/mo | [Get started free →](https://becomer.net/signup.html) --- ## Built by [Obsidex Pvt Limited](https://www.linkedin.com/company/115424394/) · [Aravind Balaji](https://www.linkedin.com/in/aravind-balaji-2k1/), Founder · [hello@becomer.net](mailto:hello@becomer.net)