becomer 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
becomer-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,32 @@
1
+ Metadata-Version: 2.4
2
+ Name: becomer
3
+ Version: 0.1.0
4
+ Summary: Persistent memory API for any LLM — Python SDK + MCP server
5
+ Home-page: https://becomer.net
6
+ Author: BECOMER
7
+ Author-email: hello@becomer.net
8
+ Project-URL: Documentation, https://becomer.net
9
+ Keywords: memory,llm,ai,mcp,claude,gpt,persistent-memory
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.9
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Intended Audience :: Developers
18
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
19
+ Requires-Python: >=3.9
20
+ Description-Content-Type: text/plain
21
+ Dynamic: author
22
+ Dynamic: author-email
23
+ Dynamic: classifier
24
+ Dynamic: description
25
+ Dynamic: description-content-type
26
+ Dynamic: home-page
27
+ Dynamic: keywords
28
+ Dynamic: project-url
29
+ Dynamic: requires-python
30
+ Dynamic: summary
31
+
32
+ BECOMER gives any LLM persistent memory. Store, recall, and forget memories via a simple API. Includes a built-in MCP server for Claude Desktop and compatible clients. See https://becomer.net for full documentation.
@@ -0,0 +1,4 @@
1
+ from .client import Client
2
+
3
+ __all__ = ["Client"]
4
+ __version__ = "0.1.0"
@@ -0,0 +1,122 @@
1
+ """
2
+ BECOMER MCP server — exposes store/recall/forget as MCP tools.
3
+
4
+ Usage in mcp.json:
5
+ {
6
+ "mcpServers": {
7
+ "becomer": {
8
+ "command": "python",
9
+ "args": ["-m", "becomer"],
10
+ "env": { "BECOMER_API_KEY": "YOUR_API_KEY" }
11
+ }
12
+ }
13
+ }
14
+ """
15
+ import os
16
+ import sys
17
+ import json
18
+
19
+ from .client import Client, BecomerError
20
+
21
+ TOOLS = [
22
+ {
23
+ "name": "store",
24
+ "description": "Store a memory in BECOMER. Call this when you learn something worth remembering about the user.",
25
+ "inputSchema": {
26
+ "type": "object",
27
+ "properties": {
28
+ "content": {"type": "string", "description": "The memory to store."}
29
+ },
30
+ "required": ["content"],
31
+ },
32
+ },
33
+ {
34
+ "name": "recall",
35
+ "description": "Recall relevant memories from BECOMER for a query.",
36
+ "inputSchema": {
37
+ "type": "object",
38
+ "properties": {
39
+ "query": {"type": "string", "description": "What to search for in memory."},
40
+ "top_k": {"type": "integer", "description": "Number of memories to return (default 5).", "default": 5},
41
+ },
42
+ "required": ["query"],
43
+ },
44
+ },
45
+ {
46
+ "name": "forget",
47
+ "description": "Delete all memories stored under this API key.",
48
+ "inputSchema": {"type": "object", "properties": {}},
49
+ },
50
+ ]
51
+
52
+
53
+ def send(obj: dict) -> None:
54
+ sys.stdout.write(json.dumps(obj) + "\n")
55
+ sys.stdout.flush()
56
+
57
+
58
+ def handle(msg: dict, client: Client) -> dict:
59
+ method = msg.get("method", "")
60
+ mid = msg.get("id")
61
+
62
+ if method == "initialize":
63
+ return {
64
+ "jsonrpc": "2.0", "id": mid,
65
+ "result": {
66
+ "protocolVersion": "2024-11-05",
67
+ "capabilities": {"tools": {}},
68
+ "serverInfo": {"name": "becomer", "version": "0.1.0"},
69
+ },
70
+ }
71
+
72
+ if method == "tools/list":
73
+ return {"jsonrpc": "2.0", "id": mid, "result": {"tools": TOOLS}}
74
+
75
+ if method == "tools/call":
76
+ name = msg["params"]["name"]
77
+ args = msg["params"].get("arguments", {})
78
+ try:
79
+ if name == "store":
80
+ result = client.store(args["content"])
81
+ text = "Memory stored."
82
+ elif name == "recall":
83
+ memories = client.recall(args["query"], args.get("top_k", 5))
84
+ text = "\n".join(f"- {m}" for m in memories) if memories else "No relevant memories found."
85
+ elif name == "forget":
86
+ client.forget()
87
+ text = "All memories deleted."
88
+ else:
89
+ text = f"Unknown tool: {name}"
90
+ except BecomerError as e:
91
+ text = f"Error: {e}"
92
+
93
+ return {
94
+ "jsonrpc": "2.0", "id": mid,
95
+ "result": {"content": [{"type": "text", "text": text}]},
96
+ }
97
+
98
+ return {"jsonrpc": "2.0", "id": mid, "result": {}}
99
+
100
+
101
+ def main() -> None:
102
+ api_key = os.environ.get("BECOMER_API_KEY", "")
103
+ if not api_key:
104
+ sys.stderr.write("BECOMER_API_KEY environment variable not set\n")
105
+ sys.exit(1)
106
+
107
+ client = Client(api_key)
108
+
109
+ for line in sys.stdin:
110
+ line = line.strip()
111
+ if not line:
112
+ continue
113
+ try:
114
+ msg = json.loads(line)
115
+ response = handle(msg, client)
116
+ send(response)
117
+ except Exception as e:
118
+ sys.stderr.write(f"Error: {e}\n")
119
+
120
+
121
+ if __name__ == "__main__":
122
+ main()
@@ -0,0 +1,55 @@
1
+ import urllib.request
2
+ import urllib.error
3
+ import json
4
+ from typing import Optional
5
+
6
+ BASE_URL = "https://becomer.net"
7
+
8
+
9
+ class BecomerError(Exception):
10
+ pass
11
+
12
+
13
+ class Client:
14
+ def __init__(self, api_key: str, base_url: str = BASE_URL):
15
+ if not api_key:
16
+ raise BecomerError("api_key is required")
17
+ self._key = api_key
18
+ self._base = base_url.rstrip("/")
19
+
20
+ def _request(self, method: str, path: str, body: Optional[dict] = None) -> dict:
21
+ url = self._base + path
22
+ data = json.dumps(body).encode() if body else None
23
+ req = urllib.request.Request(
24
+ url,
25
+ data=data,
26
+ headers={
27
+ "Authorization": f"Bearer {self._key}",
28
+ "Content-Type": "application/json",
29
+ },
30
+ method=method,
31
+ )
32
+ try:
33
+ with urllib.request.urlopen(req, timeout=15) as r:
34
+ return json.loads(r.read().decode())
35
+ except urllib.error.HTTPError as e:
36
+ raise BecomerError(f"HTTP {e.code}: {e.read().decode()}") from e
37
+ except Exception as e:
38
+ raise BecomerError(str(e)) from e
39
+
40
+ def store(self, content: str) -> dict:
41
+ """Store a memory."""
42
+ return self._request("POST", "/v1/store", {"content": content})
43
+
44
+ def recall(self, query: str, top_k: int = 5) -> list[str]:
45
+ """Recall relevant memories for a query."""
46
+ result = self._request("POST", "/v1/recall", {"query": query, "top_k": top_k})
47
+ return result.get("memories", [])
48
+
49
+ def forget(self) -> dict:
50
+ """Delete all memories for this API key."""
51
+ return self._request("POST", "/v1/forget", {"forget_all": True})
52
+
53
+ def sync(self) -> dict:
54
+ """Consolidate working memory into long-term storage."""
55
+ return self._request("POST", "/v1/sync", {})
@@ -0,0 +1,32 @@
1
+ Metadata-Version: 2.4
2
+ Name: becomer
3
+ Version: 0.1.0
4
+ Summary: Persistent memory API for any LLM — Python SDK + MCP server
5
+ Home-page: https://becomer.net
6
+ Author: BECOMER
7
+ Author-email: hello@becomer.net
8
+ Project-URL: Documentation, https://becomer.net
9
+ Keywords: memory,llm,ai,mcp,claude,gpt,persistent-memory
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.9
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Intended Audience :: Developers
18
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
19
+ Requires-Python: >=3.9
20
+ Description-Content-Type: text/plain
21
+ Dynamic: author
22
+ Dynamic: author-email
23
+ Dynamic: classifier
24
+ Dynamic: description
25
+ Dynamic: description-content-type
26
+ Dynamic: home-page
27
+ Dynamic: keywords
28
+ Dynamic: project-url
29
+ Dynamic: requires-python
30
+ Dynamic: summary
31
+
32
+ BECOMER gives any LLM persistent memory. Store, recall, and forget memories via a simple API. Includes a built-in MCP server for Claude Desktop and compatible clients. See https://becomer.net for full documentation.
@@ -0,0 +1,10 @@
1
+ pyproject.toml
2
+ setup.py
3
+ becomer/__init__.py
4
+ becomer/__main__.py
5
+ becomer/client.py
6
+ becomer.egg-info/PKG-INFO
7
+ becomer.egg-info/SOURCES.txt
8
+ becomer.egg-info/dependency_links.txt
9
+ becomer.egg-info/entry_points.txt
10
+ becomer.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ becomer = becomer.__main__:main
@@ -0,0 +1 @@
1
+ becomer
@@ -0,0 +1,3 @@
1
+ [build-system]
2
+ requires = ["setuptools>=42", "wheel"]
3
+ build-backend = "setuptools.build_meta"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
becomer-0.1.0/setup.py ADDED
@@ -0,0 +1,38 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ setup(
4
+ name="becomer",
5
+ version="0.1.0",
6
+ description="Persistent memory API for any LLM — Python SDK + MCP server",
7
+ long_description=(
8
+ "BECOMER gives any LLM persistent memory. "
9
+ "Store, recall, and forget memories via a simple API. "
10
+ "Includes a built-in MCP server for Claude Desktop and compatible clients. "
11
+ "See https://becomer.net for full documentation."
12
+ ),
13
+ long_description_content_type="text/plain",
14
+ author="BECOMER",
15
+ author_email="hello@becomer.net",
16
+ url="https://becomer.net",
17
+ project_urls={
18
+ "Documentation": "https://becomer.net",
19
+ },
20
+ packages=find_packages(exclude=["__pycache__"]),
21
+ python_requires=">=3.9",
22
+ install_requires=[],
23
+ entry_points={
24
+ "console_scripts": ["becomer=becomer.__main__:main"],
25
+ },
26
+ classifiers=[
27
+ "Programming Language :: Python :: 3",
28
+ "Programming Language :: Python :: 3.9",
29
+ "Programming Language :: Python :: 3.10",
30
+ "Programming Language :: Python :: 3.11",
31
+ "Programming Language :: Python :: 3.12",
32
+ "License :: OSI Approved :: MIT License",
33
+ "Operating System :: OS Independent",
34
+ "Intended Audience :: Developers",
35
+ "Topic :: Software Development :: Libraries :: Python Modules",
36
+ ],
37
+ keywords=["memory", "llm", "ai", "mcp", "claude", "gpt", "persistent-memory"],
38
+ )