Skip to content

Commit 48a8bb5

Browse files
Merge pull request #69 from agentclash/issue-63-mcp-packaging
Package MCP server and document setup
2 parents 8e2fe1f + c68bdfa commit 48a8bb5

4 files changed

Lines changed: 286 additions & 30 deletions

File tree

README.md

Lines changed: 222 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,52 @@ Built on **Gemini Embedding 2** for natively multimodal embeddings — text, ima
1010

1111
## Quickstart
1212

13-
### 1. Install dependencies
13+
### 1. Create a virtual environment
1414

1515
```bash
1616
python3 -m venv .venv
1717
source .venv/bin/activate
18+
python -m pip install --upgrade pip
19+
```
20+
21+
### 2. Install only the pieces you need
22+
23+
```bash
24+
# Core memory runtime only
25+
pip install .
26+
27+
# FastAPI server
28+
pip install ".[api]"
29+
30+
# MCP server only
31+
pip install ".[mcp]"
32+
33+
# Local backend development (API + MCP)
34+
pip install ".[api,mcp]"
35+
```
36+
37+
`requirements.txt` remains as a convenience alias for the legacy "install API + MCP together" flow:
38+
39+
```bash
1840
pip install -r requirements.txt
1941
```
2042

21-
### 2. Set up environment
43+
The MCP packaging is tested against `mcp[cli]==1.26.0`.
44+
45+
### 3. Set up environment
2246

2347
Create a `.env` file in the project root:
2448

25-
```
49+
```dotenv
2650
GEMINI_API_KEY=your_key_here
51+
MEMORY_CHROMA_PATH=./chroma_db
52+
MEMORY_MEDIA_DIR=./data/media
53+
EMBEDDING_DIMENSIONS=768
2754
```
2855

29-
### 3. Install system dependencies
56+
### 4. Install system dependencies
3057

31-
Audio and video chunking requires ffmpeg:
58+
Audio and video chunking requires `ffmpeg`:
3259

3360
```bash
3461
# arch
@@ -41,46 +68,223 @@ sudo apt install ffmpeg
4168
brew install ffmpeg
4269
```
4370

44-
### 4. Start the API server
71+
### 5. Run only what you need
72+
73+
Start the API server:
4574

4675
```bash
4776
.venv/bin/python -m uvicorn api.app:app --port 8000 --reload
4877
```
4978

50-
The API is now running at `http://localhost:8000`. Interactive docs at `http://localhost:8000/docs`.
79+
The API runs at `http://localhost:8000`. Interactive docs are at `http://localhost:8000/docs`.
80+
81+
Start the MCP server over local stdio:
82+
83+
```bash
84+
MEMORY_MCP_TRANSPORT=stdio .venv/bin/agentic-memory-mcp
85+
```
86+
87+
Start the MCP server over streamable HTTP:
88+
89+
```bash
90+
MEMORY_MCP_TRANSPORT=streamable-http \
91+
MEMORY_MCP_HOST=127.0.0.1 \
92+
MEMORY_MCP_PORT=8001 \
93+
MEMORY_MCP_PATH=/mcp \
94+
.venv/bin/agentic-memory-mcp
95+
```
96+
97+
For streamable HTTP, the MCP endpoint is mounted at `/mcp` and health is exposed at `/health`.
5198

52-
### 5. Start the playground UI
99+
Start the playground UI:
53100

54101
```bash
55102
cd web
56103
npm install
57104
NEXT_PUBLIC_MEMORY_API_BASE_URL=http://localhost:8000 npm run dev
58105
```
59106

60-
The playground is now running at `http://localhost:3000`.
107+
The playground runs at `http://localhost:3000`.
61108

62109
---
63110

64111
## MCP Server
65112

66-
The repo also ships a thin MCP server under `mcp_server/` that reuses the shared runtime.
113+
The repo ships a standalone MCP server under `mcp_server/` that reuses the shared runtime and does not require FastAPI or Next.js to be running.
114+
115+
### Client setup examples
67116

68-
### Local stdio transport
117+
#### Claude Code
118+
119+
Add a local stdio server for the current project:
69120

70121
```bash
71-
MEMORY_MCP_TRANSPORT=stdio .venv/bin/python -m mcp_server
122+
claude mcp add agentic-memory \
123+
-s project \
124+
-e GEMINI_API_KEY="$GEMINI_API_KEY" \
125+
-e MEMORY_CHROMA_PATH="$PWD/chroma_db" \
126+
-e MEMORY_MEDIA_DIR="$PWD/data/media" \
127+
-- .venv/bin/agentic-memory-mcp
72128
```
73129

74-
### Streamable HTTP transport
130+
Add a streamable HTTP server instead:
75131

76132
```bash
77-
MEMORY_MCP_TRANSPORT=streamable-http \
78-
MEMORY_MCP_HOST=127.0.0.1 \
79-
MEMORY_MCP_PORT=8000 \
80-
.venv/bin/python -m mcp_server
133+
claude mcp add --transport http agentic-memory http://127.0.0.1:8001/mcp
134+
```
135+
136+
#### Cursor
137+
138+
Project-local stdio config in `.cursor/mcp.json`:
139+
140+
```json
141+
{
142+
"mcpServers": {
143+
"agentic-memory": {
144+
"command": "${workspaceFolder}/.venv/bin/agentic-memory-mcp",
145+
"env": {
146+
"GEMINI_API_KEY": "${env:GEMINI_API_KEY}",
147+
"MEMORY_CHROMA_PATH": "${workspaceFolder}/chroma_db",
148+
"MEMORY_MEDIA_DIR": "${workspaceFolder}/data/media",
149+
"MEMORY_MCP_TRANSPORT": "stdio"
150+
}
151+
}
152+
}
153+
}
81154
```
82155

83-
When running over HTTP, the MCP endpoint is mounted at `/mcp` and health is exposed at `/health`.
156+
Project-local streamable HTTP config:
157+
158+
```json
159+
{
160+
"mcpServers": {
161+
"agentic-memory": {
162+
"url": "http://127.0.0.1:8001/mcp"
163+
}
164+
}
165+
}
166+
```
167+
168+
#### Windsurf
169+
170+
User config lives at `~/.codeium/windsurf/mcp_config.json`.
171+
172+
Local stdio config:
173+
174+
```json
175+
{
176+
"mcpServers": {
177+
"agentic-memory": {
178+
"command": "/absolute/path/to/agentic-memory/.venv/bin/agentic-memory-mcp",
179+
"env": {
180+
"GEMINI_API_KEY": "${env:GEMINI_API_KEY}",
181+
"MEMORY_CHROMA_PATH": "/absolute/path/to/agentic-memory/chroma_db",
182+
"MEMORY_MEDIA_DIR": "/absolute/path/to/agentic-memory/data/media",
183+
"MEMORY_MCP_TRANSPORT": "stdio"
184+
}
185+
}
186+
}
187+
}
188+
```
189+
190+
Streamable HTTP config:
191+
192+
```json
193+
{
194+
"mcpServers": {
195+
"agentic-memory": {
196+
"serverUrl": "http://127.0.0.1:8001/mcp"
197+
}
198+
}
199+
}
200+
```
201+
202+
#### Generic streamable HTTP clients
203+
204+
Any MCP client that supports streamable HTTP should point at the full MCP endpoint URL, not just the host:
205+
206+
```text
207+
http://127.0.0.1:8001/mcp
208+
```
209+
210+
Health checks are available separately at:
211+
212+
```text
213+
http://127.0.0.1:8001/health
214+
```
215+
216+
### Environment variables
217+
218+
#### Shared runtime
219+
220+
| Variable | Default | Used by | Notes |
221+
|----------|---------|---------|-------|
222+
| `GEMINI_API_KEY` | unset | core, API, MCP | Required for real embeddings; tests use deterministic embedders instead. |
223+
| `EMBEDDING_DIMENSIONS` | `768` | core, API, MCP | Must match the dimensions of already-indexed vectors. Changing this requires reindexing into a fresh Chroma path. |
224+
| `MEDIA_STORAGE_PATH` | `./data/media` | core | Base default for app-owned media storage. |
225+
| `MEMORY_MEDIA_DIR` | falls back to `MEDIA_STORAGE_PATH` | API, MCP | Explicit media root for API and MCP processes. Prefer an absolute path for remote HTTP deployments. |
226+
| `MEMORY_CHROMA_PATH` | falls back to `./chroma_db` | MCP | Explicit Chroma persistence path for the MCP server. Prefer an absolute path for remote HTTP deployments. |
227+
| `MEDIA_EMBED_MAX_BYTES` | `20971520` | core, API, MCP | Per-file embedding limit in bytes. |
228+
229+
#### API transport
230+
231+
| Variable | Default | Notes |
232+
|----------|---------|-------|
233+
| `MEMORY_ALLOWED_ORIGINS` | `http://localhost:3000,https://memory.agentclash.dev` | Comma-separated CORS allowlist for the FastAPI server. |
234+
235+
#### MCP transport
236+
237+
| Variable | Default | Notes |
238+
|----------|---------|-------|
239+
| `MEMORY_MCP_TRANSPORT` | `stdio` | One of `stdio` or `streamable-http`. |
240+
| `MEMORY_MCP_HOST` | `127.0.0.1` | Bind host for streamable HTTP mode. |
241+
| `MEMORY_MCP_PORT` | `8000` | Bind port for streamable HTTP mode. |
242+
| `MEMORY_MCP_PATH` | `/mcp` | Mount path for the MCP endpoint. |
243+
244+
#### Forgetting and ranking tuning
245+
246+
| Variable | Default |
247+
|----------|---------|
248+
| `SEMANTIC_HALF_LIFE_DAYS` | `365` |
249+
| `EPISODIC_HALF_LIFE_DAYS` | `30` |
250+
| `PROCEDURAL_HALF_LIFE_DAYS` | `180` |
251+
| `IMPORTANCE_FLOOR_THRESHOLD` | `0.8` |
252+
| `IMPORTANCE_FLOOR_MULTIPLIER` | `3.0` |
253+
| `ACCESS_NORMALIZATION_CONSTANT` | `50` |
254+
| `SEMANTIC_PRUNE_THRESHOLD` | `0.1` |
255+
| `SEMANTIC_FADE_THRESHOLD` | `0.2` |
256+
| `EPISODIC_PRUNE_THRESHOLD` | `0.2` |
257+
| `EPISODIC_FADE_THRESHOLD` | `0.35` |
258+
| `PROCEDURAL_PRUNE_THRESHOLD` | `0.15` |
259+
| `PROCEDURAL_FADE_THRESHOLD` | `0.3` |
260+
| `SEMANTIC_DUPLICATE_THRESHOLD` | `0.95` |
261+
| `FADE_FACTOR` | `0.5` |
262+
| `FADE_FLOOR` | `0.01` |
263+
| `PROCEDURAL_LOW_PERF_WILSON_THRESHOLD` | `0.1` |
264+
| `PROCEDURAL_LOW_PERF_MIN_OUTCOMES` | `10` |
265+
266+
### Operational caveats
267+
268+
#### Remote media-path caveat
269+
270+
When an MCP tool call includes `media.file_path`, that path is resolved from the MCP server host's filesystem, not the caller's machine. For remote `streamable-http` deployments:
271+
272+
- use inline base64 media when the client cannot write to the server host
273+
- or mount a shared filesystem and pass server-visible absolute paths
274+
- set `MEMORY_CHROMA_PATH` and `MEMORY_MEDIA_DIR` to absolute paths to avoid working-directory drift
275+
276+
Relative paths are acceptable for local development but are intentionally treated as risky for remote HTTP deployments.
277+
278+
#### 768 to 1536 embedding migration
279+
280+
The default embedding size is `768`. Switching to `1536` is a reindex migration, not a live in-place flip:
281+
282+
1. Stop writers to the old store.
283+
2. Point `EMBEDDING_DIMENSIONS=1536` at a fresh Chroma directory.
284+
3. Re-ingest memories into that new directory so every stored vector is regenerated at `1536` dimensions.
285+
4. Cut clients over only after the new store is fully rebuilt.
286+
287+
Do not change `EMBEDDING_DIMENSIONS` against an existing Chroma dataset and continue writing to it. Mixed vector sizes will break retrieval and store invariants.
84288

85289
---
86290

mcp_server/server.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,7 @@ def _load_fastmcp():
554554
except ImportError as exc: # pragma: no cover - import depends on optional dependency
555555
raise RuntimeError(
556556
"The 'mcp' package is required to run the MCP server. "
557-
"Install it with: pip install \"mcp[cli]\""
557+
"Install it with: pip install \".[mcp]\""
558558
) from exc
559559
return FastMCP
560560

@@ -803,7 +803,8 @@ def create_http_app(server: MemoryMCPServer):
803803
except ImportError as exc: # pragma: no cover - import depends on optional dependency
804804
raise RuntimeError(
805805
"Starlette is required for streamable-http transport. "
806-
"Install the API or MCP dependencies before starting the HTTP server."
806+
"Install the MCP dependencies before starting the HTTP server: "
807+
"pip install \".[mcp]\""
807808
) from exc
808809

809810
mcp = create_mcp_server(server)
@@ -845,7 +846,8 @@ def main() -> None:
845846
import uvicorn
846847
except ImportError as exc: # pragma: no cover - import depends on optional dependency
847848
raise RuntimeError(
848-
"uvicorn is required for streamable-http transport."
849+
"uvicorn is required for streamable-http transport. "
850+
"Install it with: pip install \".[mcp]\""
849851
) from exc
850852

851853
app = create_http_app(server)

pyproject.toml

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
[build-system]
2+
requires = ["setuptools>=69", "wheel"]
3+
build-backend = "setuptools.build_meta"
4+
5+
[project]
6+
name = "agentic-memory"
7+
version = "0.1.0"
8+
description = "Cognitive memory framework for AI agents with API and MCP transports."
9+
readme = "README.md"
10+
requires-python = ">=3.10"
11+
dependencies = [
12+
"chromadb==1.5.5",
13+
"google-genai==1.68.0",
14+
"httpx==0.28.1",
15+
"numpy==2.4.3",
16+
"pydantic>=2,<3",
17+
"python-dotenv==1.2.2",
18+
]
19+
20+
[project.optional-dependencies]
21+
api = [
22+
"fastapi==0.116.1",
23+
"python-multipart==0.0.20",
24+
"uvicorn==0.35.0",
25+
]
26+
mcp = [
27+
"mcp[cli]==1.26.0",
28+
"uvicorn==0.35.0",
29+
]
30+
dev = [
31+
"pytest>=8,<9",
32+
]
33+
34+
[project.scripts]
35+
agentic-memory-mcp = "mcp_server.server:main"
36+
37+
[tool.setuptools]
38+
py-modules = ["config", "runtime"]
39+
40+
[tool.setuptools.packages.find]
41+
include = [
42+
"api",
43+
"api.*",
44+
"events",
45+
"events.*",
46+
"forgetting",
47+
"forgetting.*",
48+
"mcp_server",
49+
"mcp_server.*",
50+
"models",
51+
"models.*",
52+
"retrieval",
53+
"retrieval.*",
54+
"stores",
55+
"stores.*",
56+
"utils",
57+
"utils.*",
58+
]

requirements.txt

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1 @@
1-
chromadb==1.5.5
2-
fastapi==0.116.1
3-
google-genai==1.68.0
4-
httpx==0.28.1
5-
mcp[cli]==1.26.0
6-
numpy==2.4.3
7-
python-multipart==0.0.20
8-
python-dotenv==1.2.2
9-
uvicorn==0.35.0
1+
.[api,mcp]

0 commit comments

Comments
 (0)