agentmem-mcp 0.1.0__py3-none-any.whl

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.
@@ -0,0 +1 @@
1
+ __version__ = "0.1.0"
agent_memory/server.py ADDED
@@ -0,0 +1,155 @@
1
+ from mcp.server.fastmcp import FastMCP
2
+ from .storage import MemoryStorage, CATEGORIES
3
+
4
+ mcp = FastMCP(
5
+ "agent-memory",
6
+ instructions=(
7
+ "Persistent graph-backed memory for AI agents. "
8
+ "Use `remember` to store facts, `recall` to search, "
9
+ "`get_related` to traverse the memory graph, "
10
+ "`list_memories` to browse by category, `forget` to delete."
11
+ ),
12
+ )
13
+
14
+ _store = MemoryStorage()
15
+
16
+
17
+ @mcp.tool()
18
+ def remember(content: str, category: str = "fact", tags: str = "") -> str:
19
+ """Store a memory and auto-link it to related existing memories.
20
+
21
+ Args:
22
+ content: The fact, observation, or decision to remember.
23
+ category: One of fact, tool, preference, context, relationship, task, decision.
24
+ tags: Comma-separated keywords for later retrieval.
25
+ """
26
+ if category not in CATEGORIES:
27
+ category = "fact"
28
+ mid = _store.add(content, category, tags)
29
+ edges = _store.edges(mid)
30
+ result = f"Stored [{mid}] ({category}): {content}"
31
+ if edges:
32
+ linked = [f"{r} → [{eid}]" for r, eid, _, _ in edges[:3]]
33
+ result += f"\nAuto-linked: {', '.join(linked)}"
34
+ return result
35
+
36
+
37
+ @mcp.tool()
38
+ def recall(query: str, limit: int = 8) -> str:
39
+ """Search memories by keyword and return matches with their graph connections.
40
+
41
+ Args:
42
+ query: Keywords to search for.
43
+ limit: Maximum number of memories to return (default 8).
44
+ """
45
+ rows = _store.search(query, min(limit, 20))
46
+ if not rows:
47
+ return f"No memories found for: {query}"
48
+
49
+ lines = [f"Found {len(rows)} memory/memories for '{query}':\n"]
50
+ for mid, content, category, tags, created_at in rows:
51
+ lines.append(f"[{mid}] ({category}) {content}")
52
+ if tags:
53
+ lines.append(f" tags: {tags}")
54
+ edges = _store.edges(mid)
55
+ if edges:
56
+ for rel, eid, econtent, _ in edges[:2]:
57
+ lines.append(f" -{rel}→ [{eid}] {econtent[:60]}...")
58
+ lines.append("")
59
+ return "\n".join(lines)
60
+
61
+
62
+ @mcp.tool()
63
+ def get_related(memory_id: str, depth: int = 2) -> str:
64
+ """Traverse the memory graph outward from a specific memory.
65
+
66
+ Args:
67
+ memory_id: The ID of the memory to start traversal from.
68
+ depth: How many hops to traverse (1–3, default 2).
69
+ """
70
+ root = _store.get(memory_id)
71
+ if not root:
72
+ return f"Memory [{memory_id}] not found."
73
+
74
+ depth = max(1, min(depth, 3))
75
+ visited = {memory_id}
76
+ lines = [f"Graph from [{memory_id}]: {root[1]}\n"]
77
+ queue = [(memory_id, 0)]
78
+
79
+ while queue:
80
+ mid, d = queue.pop(0)
81
+ if d >= depth:
82
+ continue
83
+ for rel, eid, econtent, ecat in _store.edges(mid):
84
+ marker = " " * (d + 1)
85
+ lines.append(f"{marker}-{rel}→ [{eid}] ({ecat}) {econtent}")
86
+ if eid not in visited:
87
+ visited.add(eid)
88
+ queue.append((eid, d + 1))
89
+
90
+ if len(lines) == 2:
91
+ lines.append(" (no connected memories)")
92
+ return "\n".join(lines)
93
+
94
+
95
+ @mcp.tool()
96
+ def link_memories(source_id: str, target_id: str, relationship: str) -> str:
97
+ """Manually create a typed edge between two memories.
98
+
99
+ Args:
100
+ source_id: The source memory ID.
101
+ target_id: The target memory ID.
102
+ relationship: Relationship type, e.g. DEPENDS_ON, SUPPORTS, CONTRADICTS, PRECEDES.
103
+ """
104
+ if not _store.get(source_id):
105
+ return f"Memory [{source_id}] not found."
106
+ if not _store.get(target_id):
107
+ return f"Memory [{target_id}] not found."
108
+ ok = _store.link(source_id, target_id, relationship)
109
+ if ok:
110
+ return f"Linked [{source_id}] -{relationship.upper()}→ [{target_id}]"
111
+ return f"Edge already exists or could not be created."
112
+
113
+
114
+ @mcp.tool()
115
+ def list_memories(category: str = "", limit: int = 20) -> str:
116
+ """List stored memories, optionally filtered by category.
117
+
118
+ Args:
119
+ category: Filter to one of: fact, tool, preference, context, relationship, task, decision.
120
+ limit: Maximum memories to return (default 20).
121
+ """
122
+ rows = _store.list_all(category, min(limit, 50))
123
+ if not rows:
124
+ label = f" in category '{category}'" if category else ""
125
+ return f"No memories{label}."
126
+
127
+ stats = _store.stats()
128
+ header = (
129
+ f"{stats['memories']} total memories · {stats['edges']} edges"
130
+ + (f" · showing '{category}'" if category else "")
131
+ + "\n"
132
+ )
133
+ lines = [header]
134
+ for mid, content, cat, tags, created_at in rows:
135
+ ts = created_at[:10]
136
+ lines.append(f"[{mid}] {ts} ({cat}) {content}")
137
+ return "\n".join(lines)
138
+
139
+
140
+ @mcp.tool()
141
+ def forget(memory_id: str) -> str:
142
+ """Delete a memory and all its graph edges.
143
+
144
+ Args:
145
+ memory_id: The ID of the memory to delete.
146
+ """
147
+ row = _store.get(memory_id)
148
+ if not row:
149
+ return f"Memory [{memory_id}] not found."
150
+ _store.delete(memory_id)
151
+ return f"Deleted [{memory_id}]: {row[1]}"
152
+
153
+
154
+ def main():
155
+ mcp.run()
@@ -0,0 +1,148 @@
1
+ import sqlite3
2
+ import uuid
3
+ from datetime import datetime
4
+ from pathlib import Path
5
+
6
+ STOP_WORDS = {
7
+ "a", "an", "the", "is", "in", "it", "of", "to", "and", "or", "for",
8
+ "with", "on", "at", "from", "by", "as", "be", "was", "are", "has",
9
+ "have", "had", "not", "this", "that", "i", "you", "we", "they",
10
+ }
11
+
12
+ CATEGORIES = ("fact", "tool", "preference", "context", "relationship", "task", "decision")
13
+
14
+
15
+ class MemoryStorage:
16
+ def __init__(self, db_path: str = None):
17
+ if db_path is None:
18
+ db_path = Path.home() / ".agent-memory" / "memories.db"
19
+ path = Path(db_path)
20
+ path.parent.mkdir(parents=True, exist_ok=True)
21
+ self.conn = sqlite3.connect(str(path), check_same_thread=False)
22
+ self._init()
23
+
24
+ def _init(self):
25
+ self.conn.executescript("""
26
+ CREATE TABLE IF NOT EXISTS memories (
27
+ id TEXT PRIMARY KEY,
28
+ content TEXT NOT NULL,
29
+ category TEXT DEFAULT 'fact',
30
+ tags TEXT DEFAULT '',
31
+ created_at TEXT NOT NULL
32
+ );
33
+ CREATE TABLE IF NOT EXISTS edges (
34
+ id TEXT PRIMARY KEY,
35
+ source_id TEXT NOT NULL,
36
+ target_id TEXT NOT NULL,
37
+ relationship TEXT NOT NULL,
38
+ created_at TEXT NOT NULL,
39
+ UNIQUE(source_id, target_id, relationship),
40
+ FOREIGN KEY (source_id) REFERENCES memories(id) ON DELETE CASCADE,
41
+ FOREIGN KEY (target_id) REFERENCES memories(id) ON DELETE CASCADE
42
+ );
43
+ PRAGMA foreign_keys = ON;
44
+ CREATE INDEX IF NOT EXISTS idx_memories_category ON memories(category);
45
+ CREATE INDEX IF NOT EXISTS idx_edges_source ON edges(source_id);
46
+ CREATE INDEX IF NOT EXISTS idx_edges_target ON edges(target_id);
47
+ """)
48
+ self.conn.commit()
49
+
50
+ def _new_id(self) -> str:
51
+ return str(uuid.uuid4())[:8]
52
+
53
+ def add(self, content: str, category: str, tags: str) -> str:
54
+ mid = self._new_id()
55
+ self.conn.execute(
56
+ "INSERT INTO memories VALUES (?, ?, ?, ?, ?)",
57
+ (mid, content, category, tags, datetime.utcnow().isoformat()),
58
+ )
59
+ self.conn.commit()
60
+ self._auto_link(mid, content)
61
+ return mid
62
+
63
+ def _auto_link(self, new_id: str, content: str):
64
+ words = {w for w in content.lower().split() if w not in STOP_WORDS and len(w) > 3}
65
+ seen = set()
66
+ for word in list(words)[:6]:
67
+ rows = self.conn.execute(
68
+ "SELECT id FROM memories WHERE LOWER(content) LIKE ? AND id != ? LIMIT 4",
69
+ (f"%{word}%", new_id),
70
+ ).fetchall()
71
+ for (rid,) in rows:
72
+ if rid not in seen:
73
+ seen.add(rid)
74
+ eid = self._new_id()
75
+ self.conn.execute(
76
+ "INSERT OR IGNORE INTO edges VALUES (?, ?, ?, 'RELATES_TO', ?)",
77
+ (eid, new_id, rid, datetime.utcnow().isoformat()),
78
+ )
79
+ if seen:
80
+ self.conn.commit()
81
+
82
+ def link(self, source_id: str, target_id: str, relationship: str) -> bool:
83
+ eid = self._new_id()
84
+ try:
85
+ self.conn.execute(
86
+ "INSERT OR IGNORE INTO edges VALUES (?, ?, ?, ?, ?)",
87
+ (eid, source_id, target_id, relationship.upper(), datetime.utcnow().isoformat()),
88
+ )
89
+ self.conn.commit()
90
+ return True
91
+ except Exception:
92
+ return False
93
+
94
+ def search(self, query: str, limit: int = 10) -> list:
95
+ terms = [t for t in query.lower().split() if t not in STOP_WORDS]
96
+ if not terms:
97
+ terms = query.lower().split()
98
+ conditions = " OR ".join(["LOWER(content) LIKE ?" for _ in terms])
99
+ params = [f"%{t}%" for t in terms] + [limit]
100
+ return self.conn.execute(
101
+ f"SELECT id, content, category, tags, created_at FROM memories "
102
+ f"WHERE {conditions} ORDER BY created_at DESC LIMIT ?",
103
+ params,
104
+ ).fetchall()
105
+
106
+ def get(self, mid: str) -> tuple | None:
107
+ return self.conn.execute(
108
+ "SELECT id, content, category, tags, created_at FROM memories WHERE id = ?",
109
+ (mid,),
110
+ ).fetchone()
111
+
112
+ def edges(self, mid: str) -> list:
113
+ return self.conn.execute(
114
+ """SELECT e.relationship, m.id, m.content, m.category
115
+ FROM edges e JOIN memories m ON e.target_id = m.id
116
+ WHERE e.source_id = ?
117
+ UNION
118
+ SELECT e.relationship, m.id, m.content, m.category
119
+ FROM edges e JOIN memories m ON e.source_id = m.id
120
+ WHERE e.target_id = ?""",
121
+ (mid, mid),
122
+ ).fetchall()
123
+
124
+ def list_all(self, category: str = "", limit: int = 20) -> list:
125
+ if category:
126
+ return self.conn.execute(
127
+ "SELECT id, content, category, tags, created_at FROM memories "
128
+ "WHERE category = ? ORDER BY created_at DESC LIMIT ?",
129
+ (category, limit),
130
+ ).fetchall()
131
+ return self.conn.execute(
132
+ "SELECT id, content, category, tags, created_at FROM memories "
133
+ "ORDER BY created_at DESC LIMIT ?",
134
+ (limit,),
135
+ ).fetchall()
136
+
137
+ def delete(self, mid: str) -> bool:
138
+ cur = self.conn.execute("DELETE FROM memories WHERE id = ?", (mid,))
139
+ self.conn.commit()
140
+ return cur.rowcount > 0
141
+
142
+ def stats(self) -> dict:
143
+ m = self.conn.execute("SELECT COUNT(*) FROM memories").fetchone()[0]
144
+ e = self.conn.execute("SELECT COUNT(*) FROM edges").fetchone()[0]
145
+ cats = self.conn.execute(
146
+ "SELECT category, COUNT(*) FROM memories GROUP BY category"
147
+ ).fetchall()
148
+ return {"memories": m, "edges": e, "by_category": dict(cats)}
@@ -0,0 +1,282 @@
1
+ Metadata-Version: 2.4
2
+ Name: agentmem-mcp
3
+ Version: 0.1.0
4
+ Summary: Persistent graph-backed memory for AI agents via MCP — store, traverse, and recall knowledge across sessions
5
+ Project-URL: Homepage, https://graphifymd.com
6
+ Project-URL: Repository, https://github.com/Yarmoluk/agent-memory-mcp
7
+ Project-URL: Issues, https://github.com/Yarmoluk/agent-memory-mcp/issues
8
+ Author-email: Daniel Yarmoluk <daniel.yarmoluk@gmail.com>
9
+ License: MIT
10
+ Keywords: agent,agentiq,ai-agents,fastmcp,knowledge-graph,llm,mcp,memory,nvidia,persistent-memory
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
19
+ Requires-Python: >=3.10
20
+ Requires-Dist: mcp[cli]>=1.0.0
21
+ Description-Content-Type: text/markdown
22
+
23
+ # agent-memory-mcp
24
+
25
+ **Give your agents memory. Give them direction. Open the context window.**
26
+
27
+ The context window is the most expensive real estate in AI development. Most teams fill it with the same documents, the same re-derived dependencies, the same facts the agent already knew from last session. The window bloats. The cost compounds. The agent still starts from scratch.
28
+
29
+ `agent-memory-mcp` solves the other half of the problem.
30
+
31
+ Not retrieval — traversal. Your agent doesn't search for what looks similar. It walks declared relationships: what came before, what depends on what, what decision caused what outcome. Persistent across sessions. Zero external services. One config entry.
32
+
33
+ Combined with a sealed knowledge appliance ([ckg-mcp](https://pypi.org/project/ckg-mcp/)), your agent has both layers of what a production system needs: memory for what it *did*, and structured knowledge for what's *true*. That's not a wider context window — that's a smarter one.
34
+
35
+ [![PyPI](https://img.shields.io/pypi/v/agent-memory-mcp)](https://pypi.org/project/agent-memory-mcp/)
36
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
37
+
38
+ ![agent-memory-mcp architecture](assets/graph.svg)
39
+
40
+ > ⭐ **If this saves you tokens, star it** — it's how other developers find it.
41
+
42
+ ---
43
+
44
+ ## The problem
45
+
46
+ Most teams give their agents a document dump and call it knowledge. Most agents start every session with no sense of where they've been. The result:
47
+
48
+ - Re-explaining your stack, your preferences, your constraints — every session
49
+ - Re-discovering which tool worked and which didn't
50
+ - Re-fetching context the agent already built last time
51
+ - Burning tokens on what the agent already knew
52
+ - No memory of decisions made, no record of what was tried and failed
53
+
54
+ This isn't a model problem. It's a memory architecture problem — and it compounds with every agent call you pay for.
55
+
56
+ ---
57
+
58
+ ## Install
59
+
60
+ ```bash
61
+ # Run directly — no install needed
62
+ uvx agent-memory-mcp
63
+
64
+ # Or install
65
+ pip install agent-memory-mcp
66
+ ```
67
+
68
+ ---
69
+
70
+ ## MCP config
71
+
72
+ ### Claude Desktop
73
+
74
+ ```json
75
+ {
76
+ "mcpServers": {
77
+ "agent-memory": {
78
+ "command": "uvx",
79
+ "args": ["agent-memory-mcp"]
80
+ }
81
+ }
82
+ }
83
+ ```
84
+
85
+ ### Cursor / Windsurf / NVIDIA AgentIQ
86
+
87
+ Same config — drop it in your `mcp_servers.json`. Any MCP-compatible client works.
88
+
89
+ Memories persist to `~/.agent-memory/memories.db` — SQLite, no external services, no API keys.
90
+
91
+ ---
92
+
93
+ ## Tools
94
+
95
+ | Tool | What it does |
96
+ |---|---|
97
+ | `remember(content, category, tags)` | Store a memory. Auto-links to related existing memories. |
98
+ | `recall(query, limit)` | Search by keyword. Returns matches with their graph connections. |
99
+ | `get_related(memory_id, depth)` | Traverse the graph outward 1–3 hops from a memory. |
100
+ | `link_memories(source, target, relationship)` | Declare a typed edge between two memories. |
101
+ | `list_memories(category, limit)` | Browse by category: fact, tool, decision, preference, context… |
102
+ | `forget(memory_id)` | Delete a memory and all its edges. |
103
+
104
+ **Categories:** `fact` · `tool` · `preference` · `context` · `relationship` · `task` · `decision`
105
+
106
+ **Edge types:** `DEPENDS_ON` · `SUPPORTS` · `CONTRADICTS` · `PRECEDES` · `CAUSES` · `RELATES_TO`
107
+
108
+ ---
109
+
110
+ ## Usage patterns
111
+
112
+ ### 1. Cross-session continuity
113
+
114
+ The agent picks up where it left off — no re-introduction needed.
115
+
116
+ ```
117
+ Session 1:
118
+ remember("User prefers FastAPI over Flask", "preference", ["python", "api"])
119
+ remember("Project uses Postgres 15 on Supabase", "fact", ["database"])
120
+ remember("Avoid Alembic — use raw migrations", "preference", ["database"])
121
+
122
+ Session 2:
123
+ recall("database preferences")
124
+ → Returns Postgres fact + Alembic preference with RELATES_TO edge between them
125
+ ```
126
+
127
+ ### 2. Dependency chain memory
128
+
129
+ The agent stores what it discovered about your stack — so it doesn't re-discover it.
130
+
131
+ ```
132
+ remember("TensorRT requires CUDA 11.8+", "fact", ["tensorrt", "cuda"])
133
+ remember("CUDA 11.8 install requires gcc 9+", "fact", ["cuda", "build"])
134
+ link_memories(tensorrt_id, cuda_id, "DEPENDS_ON")
135
+ link_memories(cuda_id, gcc_id, "DEPENDS_ON")
136
+
137
+ → get_related(tensorrt_id, depth=3) returns the full dependency chain
138
+ ```
139
+
140
+ ### 3. Decision trail
141
+
142
+ The agent remembers why it made a choice — not just what it chose.
143
+
144
+ ```
145
+ remember("Chose ChromaDB over Pinecone: latency and no API key requirement", "decision", ["vector-db"])
146
+ remember("Pinecone rejected: requires API key in CI environment", "context", ["vector-db", "ci"])
147
+ link_memories(decision_id, context_id, "CAUSES")
148
+
149
+ → Three months later: recall("vector db decision") surfaces both with the causal link
150
+ ```
151
+
152
+ ### 4. Tool performance learning
153
+
154
+ The agent tracks what worked — and what didn't.
155
+
156
+ ```
157
+ remember("exa_search returns better results than web_search for technical docs", "tool", ["search"])
158
+ remember("brave_search rate-limited after 10 calls/min in production", "tool", ["search", "production"])
159
+
160
+ → Before next search: recall("search tools") returns ranked performance memories
161
+ ```
162
+
163
+ ### 5. Multi-step task tracking
164
+
165
+ The agent tracks where a long-running task is — even across sessions.
166
+
167
+ ```
168
+ remember("Migration step 1/4 complete: users table done", "task", ["migration", "postgres"])
169
+ remember("Step 2/4 blocked: foreign key constraint on orders table", "task", ["migration", "blocker"])
170
+ link_memories(step1_id, step2_id, "PRECEDES")
171
+
172
+ → Next session: recall("migration status") returns the full chain with the blocker flagged
173
+ ```
174
+
175
+ ### 6. Pair with a sealed knowledge appliance (CKG)
176
+
177
+ Memory tells the agent what it **did**. Knowledge tells it what's **true**.
178
+
179
+ ```
180
+ # Memory: agent remembers what it tried
181
+ remember("NIM deployment failed on t3.medium: insufficient VRAM", "fact", ["nim", "aws"])
182
+
183
+ # Knowledge: CKG tells it the dependency chain it should have known
184
+ query_ckg("NIM", "nvidia-nim", depth=3)
185
+ → NIM → TensorRT-LLM → GPU Memory ≥24GB → A10G minimum
186
+ ```
187
+
188
+ The agent now has both: its own experience (memory) and the declared domain rules (knowledge).
189
+
190
+ See [ckg-mcp](https://pypi.org/project/ckg-mcp/) — 97 domains of sealed knowledge appliances, or build your own at [graphifymd.com/caas](https://graphifymd.com/caas).
191
+
192
+ ---
193
+
194
+ ## Context compression and optimization
195
+
196
+ This is the underlying problem agent-memory-mcp solves — not just "memory."
197
+
198
+ **The standard approach:** inject raw documents into the context window. 2,982 tokens to answer one question about your stack. Every call. Every session.
199
+
200
+ **The graph approach:** traverse declared relationships. 269 tokens for the same answer — the exact chain, nothing more.
201
+
202
+ That's **11× context compression**. Not by summarizing or chunking. By replacing document retrieval with graph traversal. You don't inject a manual — you walk a map.
203
+
204
+ Context optimization means the agent gets *exactly* what it needs to reason:
205
+ - Not "here are 40 pages about CUDA" — but "NIM → TensorRT → CUDA 11.8+ → Hopper SM90"
206
+ - Not "here are your last 200 conversation turns" — but the 3 decisions that led to this moment
207
+ - Not similarity guesses — declared edges the agent itself wrote
208
+
209
+ The result: smaller prompts, faster responses, lower cost, and an agent that reasons rather than retrieves.
210
+
211
+ ---
212
+
213
+ ## Why graph, not vector?
214
+
215
+ Vector similarity finds *related* content. Graph traversal finds *declared* connections.
216
+
217
+ | | Vector | Graph |
218
+ |---|---|---|
219
+ | How it works | Embedding similarity | Declared typed edges |
220
+ | Best for | Fuzzy recall, semantic search | Reasoning chains, dependency traversal |
221
+ | Answer to "what came before X?" | Approximation | Exact traversal |
222
+ | Can be wrong? | Yes — guesses | No — only returns declared edges |
223
+
224
+ `agent-memory-mcp` auto-links new memories to related existing ones on write (via keyword overlap), then lets you declare precise typed edges when the relationship matters.
225
+
226
+ **The graph doesn't guess. It traverses.**
227
+
228
+ ---
229
+
230
+ ## Benchmark
231
+
232
+ Memory quality benchmarked against [KRB Benchmark v0.6.2](https://github.com/Yarmoluk/ckg-benchmark/blob/main/paper/main.pdf):
233
+
234
+ | System | F1 | Tokens/query |
235
+ |---|---|---|
236
+ | **CKG graph traversal** | **0.471** | **269** |
237
+ | RAG (vector retrieval) | 0.123 | 2,982 |
238
+ | GraphRAG | 0.120 | — |
239
+
240
+ ~4× F1 · 11× fewer tokens · auditable by design
241
+
242
+ ---
243
+
244
+ ## Pair it with domain knowledge
245
+
246
+ agent-memory-mcp handles what your agent **experiences**. [ckg-mcp](https://pypi.org/project/ckg-mcp/) handles what your agent **knows**.
247
+
248
+ ```bash
249
+ pip install ckg-mcp
250
+ ```
251
+
252
+ 97 domains ready to query: NVIDIA AI stack, financial regulations, healthcare standards, manufacturing safety, legal frameworks, and more. Free tier included.
253
+
254
+ **[→ Browse domains and pricing at graphifymd.com/caas](https://graphifymd.com/caas)**
255
+
256
+ ---
257
+
258
+ ## Partners and integrations
259
+
260
+ We're looking for:
261
+
262
+ - **MCP client integrations** — if you're building an agent runtime that supports MCP, we'd like to be in your default toolchain
263
+ - **Domain experts** — if you have proprietary knowledge that would be more useful as a traversable graph than a document corpus, let's talk
264
+ - **Enterprise pilots** — regulated industries (finance, healthcare, manufacturing, legal) where agents need auditable, declared knowledge rather than probabilistic retrieval
265
+ - **Researchers** — working on agent memory, knowledge representation, or MCP tooling
266
+
267
+ Reach out: [graphifymd.com](https://graphifymd.com) · [daniel.yarmoluk@gmail.com](mailto:daniel.yarmoluk@gmail.com)
268
+
269
+ ---
270
+
271
+ ## Related
272
+
273
+ - **[ckg-mcp](https://pypi.org/project/ckg-mcp/)** — 97 sealed knowledge appliances via MCP
274
+ - **[ckg-nvidia-ai](https://github.com/Yarmoluk/ckg-nvidia-ai)** — 20 NVIDIA AI domain graphs, 998 nodes, free
275
+ - **[KRB Benchmark](https://huggingface.co/datasets/danyarm/ckg-benchmark)** — open benchmark dataset
276
+ - **[graphifymd.com/caas](https://graphifymd.com/caas)** — Context-as-a-Service: build or subscribe to sealed knowledge appliances
277
+
278
+ ---
279
+
280
+ ## License
281
+
282
+ MIT — built by [Graphify.md](https://graphifymd.com). Patent pending.
@@ -0,0 +1,7 @@
1
+ agent_memory/__init__.py,sha256=kUR5RAFc7HCeiqdlX36dZOHkUI5wI6V_43RpEcD8b-0,22
2
+ agent_memory/server.py,sha256=_SutIjoRWey-VA6M5WWIjyI7xrSy988FmMQChANNQNA,4965
3
+ agent_memory/storage.py,sha256=u3keZuwg3ru51fItsCoUGyqRkkJypQqc_Zo1o3bEgIA,5911
4
+ agentmem_mcp-0.1.0.dist-info/METADATA,sha256=gKZAkg_SYo1PdhaJ8ojcukgc3BdCdN4U5i7B4d669WE,10972
5
+ agentmem_mcp-0.1.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
6
+ agentmem_mcp-0.1.0.dist-info/entry_points.txt,sha256=pqvzbM_eaP4kKPWjMcXXTkhjHib7YVwJMN5sIhaywoA,58
7
+ agentmem_mcp-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.30.1
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ agent-memory = agent_memory.server:main