MCP-сервер для управления памятью агента: server.py

This commit is contained in:
2026-05-29 06:26:57 +00:00
parent b2d5dbf264
commit a5e58543ff
+121
View File
@@ -0,0 +1,121 @@
import json
import uuid
from typing import List, Optional
from fastapi import FastAPI, HTTPException, Request
from fastapi.responses import JSONResponse
from fastapi.middleware.cors import CORSMiddleware
from fastapi.logger import logger as fastapi_logger
from fastmcp import MCPServer, MCPRequest, MCPResponse
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Qdrant
from langchain.schema import Document
from rich.console import Console
from rich.table import Table
# Настройки сервера
APP_NAME = "AgentMemoryMCP"
APP_VERSION = "1.0.0"
QDRANT_URL = "http://localhost:6333"
COLLECTION_NAME = "agent_memory"
# Инициализация консоли rich
console = Console()
# Создаём FastAPI приложение
app = FastAPI(title=APP_NAME, version=APP_VERSION)
# CORS (если понадобится)
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Инициализация Qdrant
embeddings = OpenAIEmbeddings()
vectorstore = Qdrant(
client=qdrant_client := Qdrant(
url=QDRANT_URL,
collection_name=COLLECTION_NAME,
embeddings=embeddings,
),
embeddings=embeddings,
collection_name=COLLECTION_NAME,
)
# Создаём MCP сервер
mcp_server = MCPServer(app=app, name=APP_NAME, version=APP_VERSION)
# Вспомогательные функции
def _log_request(req: MCPRequest):
table = Table(title="MCP Request", show_header=True, header_style="bold magenta")
table.add_column("Method")
table.add_column("Path")
table.add_column("Body")
table.add_row(req.method, req.path, json.dumps(req.body, indent=2))
console.print(table)
def _log_response(res: MCPResponse):
table = Table(title="MCP Response", show_header=True, header_style="bold green")
table.add_column("Status")
table.add_column("Body")
table.add_row(str(res.status), json.dumps(res.body, indent=2))
console.print(table)
# Обработчики MCP
@mcp_server.on("memory.add")
async def handle_memory_add(req: MCPRequest) -> MCPResponse:
_log_request(req)
content = req.body.get("content")
if not content:
raise HTTPException(status_code=400, detail="Missing 'content' field")
# Создаём документ и сохраняем в Qdrant
doc = Document(page_content=content, metadata={"id": str(uuid.uuid4())})
vectorstore.add_documents([doc])
res = MCPResponse(status=200, body={"id": doc.metadata["id"]})
_log_response(res)
return res
@mcp_server.on("memory.get")
async def handle_memory_get(req: MCPRequest) -> MCPResponse:
_log_request(req)
query = req.body.get("query")
if not query:
raise HTTPException(status_code=400, detail="Missing 'query' field")
# Поиск похожих документов
results = vectorstore.similarity_search(query, k=5)
res_body = [
{"id": doc.metadata.get("id"), "content": doc.page_content} for doc in results
]
res = MCPResponse(status=200, body=res_body)
_log_response(res)
return res
@mcp_server.on("memory.delete")
async def handle_memory_delete(req: MCPRequest) -> MCPResponse:
_log_request(req)
doc_id = req.body.get("id")
if not doc_id:
raise HTTPException(status_code=400, detail="Missing 'id' field")
# Удаляем документ по id
deleted = vectorstore.delete(ids=[doc_id])
res = MCPResponse(status=200, body={"deleted": deleted})
_log_response(res)
return res
# Запуск через uvicorn
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)