Skip to content

Commit fda6884

Browse files
committed
Expand README, fix topics parsing
1 parent d77b399 commit fda6884

File tree

6 files changed

+95
-12
lines changed

6 files changed

+95
-12
lines changed

README.md

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,15 +133,29 @@ Agent Memory Server offers an MCP (Model Context Protocol) server interface powe
133133

134134
### Local Install
135135

136-
1. Install the package and required dependencies:
136+
First, you'll need to download this repository. After you've downloaded it, you can install and run the servers.
137+
138+
1. Install the package and required dependencies with pip, ideally into a virtual environment:
137139
```bash
138140
pip install -e .
139141
```
140142

141-
2. Start both the REST API server and MCP server:
143+
**NOTE:** This project uses `uv` for dependency management, so if you have uv installed, you can run `uv sync` instead of `pip install ...` to install the project's dependencies.
144+
145+
2 (a). The easiest way to start the REST API server and MCP server in SSE mode is to use Docker Compose. See the Docker Compose section of this file for more details.
146+
147+
2 (b). You can also run the REST API and MCP servers directly:
148+
#### REST API
142149
```bash
143150
python -m agent_memory_server.main
144151
```
152+
#### MCP Server
153+
The MCP server can run in either SSE mode or stdio:
154+
```bash
155+
python -m agent_memory_server.mcp <sse|stdio>
156+
```
157+
158+
**NOTE:** With uv, just prefix the command with `uv`, e.g.: `uv run python -m agent_memory_server.mcp sse`.
145159

146160
### Docker Compose
147161

@@ -161,6 +175,51 @@ To start the API using Docker Compose, follow these steps:
161175
6. To stop the containers, press Ctrl+C in the terminal and then run:
162176
docker-compose down
163177

178+
## Using the MCP Server with Claude Desktop, Cursor, etc.
179+
You can use the MCP server that comes with this project in any application or SDK that supports MCP tools.
180+
181+
### Claude
182+
<img src="claude.png">
183+
184+
For example, with Claude, use the following configuration:
185+
```json
186+
{
187+
"mcpServers": {
188+
"redis-memory-server": {
189+
"command": "uv",
190+
"args": [
191+
"--directory",
192+
"/ABSOLUTE/PATH/TO/REPO/DIRECTORY/agent-memory-server",
193+
"run",
194+
"python",
195+
"-m",
196+
"agent_memory_server.mcp",
197+
"stdio"
198+
]
199+
}
200+
}
201+
}
202+
```
203+
**NOTE:** On a Mac, this configuration requires that you use `brew install uv` to install uv. Probably any method that makes the `uv`
204+
command globally accessible, so Claude can find it, would work.
205+
206+
### Cursor
207+
208+
<img src="cursor.png">
209+
210+
Cursor's MCP config is similar to Claude's, but it also supports SSE servers, so you can run the server yourself and pass in the URL:
211+
212+
```json
213+
{
214+
"mcpServers": {
215+
"redis-memory-server": {
216+
"url": "http://localhost:9000/sse"
217+
}
218+
}
219+
}
220+
```
221+
222+
164223
## Configuration
165224

166225
You can configure the service using environment variables:

agent_memory_server/long_term_memory.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,14 @@ async def search_long_term_memories(
196196
results = []
197197

198198
for doc in search_result.docs:
199+
topics = safe_get(doc, "topics", [])
200+
if isinstance(topics, str):
201+
topics: list[str] = topics.split(",") # type: ignore
202+
203+
entities = safe_get(doc, "entities", [])
204+
if isinstance(entities, str):
205+
entities: list[str] = entities.split(",") # type: ignore
206+
199207
results.append(
200208
LongTermMemoryResult(
201209
id_=safe_get(doc, "id_"),
@@ -206,8 +214,8 @@ async def search_long_term_memories(
206214
user_id=safe_get(doc, "user_id"),
207215
session_id=safe_get(doc, "session_id"),
208216
namespace=safe_get(doc, "namespace"),
209-
topics=safe_get(doc, "topics", []),
210-
entities=safe_get(doc, "entities", []),
217+
topics=topics,
218+
entities=entities,
211219
)
212220
)
213221
total_results = search_result.total

agent_memory_server/mcp.py

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import asyncio
12
import logging
23
import sys
34

@@ -21,7 +22,11 @@
2122

2223

2324
logger = logging.getLogger(__name__)
24-
mcp_app = FastMCP("Redis Agent Memory Server", port=settings.mcp_port)
25+
mcp_app = FastMCP(
26+
"Redis Agent Memory Server - ALWAYS check memory for user information",
27+
port=settings.mcp_port,
28+
instructions="When responding to user queries, ALWAYS check memory first before answering questions about user preferences, history, or personal information.",
29+
)
2530

2631

2732
@mcp_app.tool()
@@ -79,7 +84,9 @@ async def search_long_term_memory(
7984
payload: SearchPayload,
8085
) -> LongTermMemoryResults:
8186
"""
82-
Search for long-term memories using semantic similarity and filters.
87+
Search for memories related to a text query.
88+
89+
Finds memories based on a combination of semantic similarity and input filters.
8390
8491
This tool performs a semantic search on stored memories using the query text and filters
8592
in the payload. Results are ranked by relevance.
@@ -151,9 +158,18 @@ async def hydrate_memory_prompt(
151158
"""
152159
Hydrate a user prompt with relevant session history and long-term memories.
153160
154-
This tool enriches the user's query with:
155-
1. Context from the current conversation session (if available, based on session ID)
156-
2. Relevant long-term memories related to the query text
161+
CRITICAL: Use this tool for EVERY question that might benefit from memory context,
162+
especially when you don't have sufficient information to answer confidently.
163+
164+
This tool enriches the user's query by retrieving:
165+
1. Context from the current conversation session
166+
2. Relevant long-term memories related to the query
167+
168+
ALWAYS use this tool when:
169+
- The user references past conversations
170+
- The question is about user preferences or personal information
171+
- You need additional context to provide a complete answer
172+
- The question seems to assume information you don't have in current context
157173
158174
The function uses the text field from the payload as the user's query,
159175
and any filters to retrieve relevant memories.
@@ -244,6 +260,6 @@ async def hydrate_memory_prompt(
244260

245261
if __name__ == "__main__":
246262
if len(sys.argv) > 1 and sys.argv[1] == "sse":
247-
mcp_app.run(transport="sse")
263+
asyncio.run(mcp_app.run_sse_async())
248264
else:
249-
mcp_app.run(transport="stdio")
265+
asyncio.run(mcp_app.run_stdio_async())

claude.png

176 KB
Loading

cursor.png

190 KB
Loading

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)