179 lines
5.0 KiB
Markdown
179 lines
5.0 KiB
Markdown
# MCP‑Server for Agent Memory Management
|
||
|
||
A lightweight **Model Context Protocol (MCP)** server that exposes a REST API for storing, retrieving, and deleting memory chunks for autonomous agents.
|
||
The server is built on **FastAPI** and uses **Qdrant** as a vector store for semantic search.
|
||
A small CLI client (`client.py`) demonstrates how to interact with the server.
|
||
|
||
---
|
||
|
||
## Table of Contents
|
||
|
||
- [Features](#features)
|
||
- [Architecture](#architecture)
|
||
- [Prerequisites](#prerequisites)
|
||
- [Installation](#installation)
|
||
- [Running the Server](#running-the-server)
|
||
- [Running the Client](#running-the-client)
|
||
- [Example Usage](#example-usage)
|
||
- [API Endpoints](#api-endpoints)
|
||
- [License](#license)
|
||
|
||
---
|
||
|
||
## Features
|
||
|
||
| Feature | Description |
|
||
|---------|-------------|
|
||
| **Add memory** | Store a key‑value pair in the vector store. |
|
||
| **Retrieve memory** | Query by key or semantic similarity. |
|
||
| **Delete memory** | Remove a memory entry by key. |
|
||
| **CORS enabled** | Works from any origin (useful for browser‑based agents). |
|
||
| **Rich console output** | Pretty tables and logs for debugging. |
|
||
| **FastAPI** | Modern, async, and fully typed. |
|
||
| **Qdrant** | Fast, scalable vector search. |
|
||
|
||
---
|
||
|
||
## Architecture
|
||
|
||
```
|
||
┌───────────────────────┐
|
||
│ Agent (client.py) │
|
||
│ ├─ add_memory() │
|
||
│ ├─ get_memory() │
|
||
│ └─ delete_memory() │
|
||
└────────────┬──────────┘
|
||
│ HTTP
|
||
▼
|
||
┌───────────────────────┐
|
||
│ MCP‑Server (server.py)│
|
||
│ ├─ FastAPI endpoints │
|
||
│ ├─ Qdrant vector store │
|
||
│ └─ OpenAI embeddings │
|
||
└───────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## Prerequisites
|
||
|
||
| Component | Minimum Version | Notes |
|
||
|-----------|-----------------|-------|
|
||
| Python | 3.10+ | Use a virtual environment. |
|
||
| Qdrant | 1.7+ | Run locally or use a hosted instance. |
|
||
| OpenAI API key | N/A | Required for embeddings. Set `OPENAI_API_KEY` env var. |
|
||
|
||
---
|
||
|
||
## Installation
|
||
|
||
```bash
|
||
# 1. Clone the repo
|
||
git clone https://github.com/yourorg/agent-mcp.git
|
||
cd agent-mcp
|
||
|
||
# 2. Create a virtual environment
|
||
python -m venv .venv
|
||
source .venv/bin/activate # Windows: .venv\Scripts\activate
|
||
|
||
# 3. Install dependencies
|
||
pip install -r requirements.txt
|
||
```
|
||
|
||
`requirements.txt` contains:
|
||
|
||
```text
|
||
fastapi
|
||
uvicorn
|
||
langchain
|
||
qdrant-client
|
||
openai
|
||
rich
|
||
requests
|
||
```
|
||
|
||
> **Tip:** If you don't have a Qdrant instance, start a local Docker container:
|
||
|
||
```bash
|
||
docker run -p 6333:6333 qdrant/qdrant
|
||
```
|
||
|
||
---
|
||
|
||
## Running the Server
|
||
|
||
```bash
|
||
# Activate the virtual environment if not already
|
||
source .venv/bin/activate
|
||
|
||
# Start the FastAPI server
|
||
uvicorn server:app --host 0.0.0.0 --port 8000 --reload
|
||
```
|
||
|
||
The server will be available at `http://localhost:8000`.
|
||
CORS is enabled for all origins, so the client can run from any host.
|
||
|
||
---
|
||
|
||
## Running the Client
|
||
|
||
The client is a simple CLI wrapper around the MCP API.
|
||
|
||
```bash
|
||
# Add a memory entry
|
||
python client.py add --server http://localhost:8000 --key "greeting" --value "Hello, world!"
|
||
|
||
# Retrieve a memory entry
|
||
python client.py get --server http://localhost:8000 --key "greeting"
|
||
|
||
# Delete a memory entry
|
||
python client.py delete --server http://localhost:8000 --key "greeting"
|
||
```
|
||
|
||
Run `python client.py --help` for full options.
|
||
|
||
---
|
||
|
||
## Example Usage
|
||
|
||
```bash
|
||
# 1. Start the server (in one terminal)
|
||
uvicorn server:app --host 0.0.0.0 --port 8000 --reload
|
||
|
||
# 2. In another terminal, add a memory
|
||
python client.py add --server http://localhost:8000 --key "weather" --value "Sunny in San Francisco"
|
||
|
||
# 3. Retrieve it
|
||
python client.py get --server http://localhost:8000 --key "weather"
|
||
# Output:
|
||
# ┏━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||
# ┃ Key ┃ Value ┃
|
||
# ┡━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
|
||
# │ weather │ Sunny in San Francisco │
|
||
# └──────────┴──────────────────────────────────────┘
|
||
|
||
# 4. Delete it
|
||
python client.py delete --server http://localhost:8000 --key "weather"
|
||
# Output:
|
||
# Memory with key 'weather' deleted successfully.
|
||
```
|
||
|
||
---
|
||
|
||
## API Endpoints
|
||
|
||
| Method | Path | Description | Request Body | Response |
|
||
|--------|------|-------------|--------------|----------|
|
||
| `POST` | `/memory/add` | Add a key‑value pair | `{"key": str, "value": str}` | `{"status": "ok", "id": str}` |
|
||
| `GET` | `/memory/get` | Retrieve by key | Query param `key` | `{"key": str, "value": str}` |
|
||
| `DELETE` | `/memory/delete` | Delete by key | Query param `key` | `{"status": "deleted"}` |
|
||
|
||
All responses are JSON. Errors return HTTP status codes with a JSON body containing `detail`.
|
||
|
||
---
|
||
|
||
## License
|
||
|
||
MIT © 2026 Your Name
|
||
|
||
--- |