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 +32 -0
- becomer-0.1.0/becomer/__init__.py +4 -0
- becomer-0.1.0/becomer/__main__.py +122 -0
- becomer-0.1.0/becomer/client.py +55 -0
- becomer-0.1.0/becomer.egg-info/PKG-INFO +32 -0
- becomer-0.1.0/becomer.egg-info/SOURCES.txt +10 -0
- becomer-0.1.0/becomer.egg-info/dependency_links.txt +1 -0
- becomer-0.1.0/becomer.egg-info/entry_points.txt +2 -0
- becomer-0.1.0/becomer.egg-info/top_level.txt +1 -0
- becomer-0.1.0/pyproject.toml +3 -0
- becomer-0.1.0/setup.cfg +4 -0
- becomer-0.1.0/setup.py +38 -0
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,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 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
becomer
|
becomer-0.1.0/setup.cfg
ADDED
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
|
+
)
|