From 049a3c30c553aefdaaa6e41d3b84467f12c3ef9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D1=80=D0=B8=D1=8F=20=D0=91=D0=B5=D1=80=D0=B4?= =?UTF-8?q?=D0=BD=D0=B8=D0=BA=D0=BE=D0=B2=D0=B0?= Date: Wed, 27 May 2026 08:04:19 +0000 Subject: [PATCH] =?UTF-8?q?MCP-=D1=81=D0=B5=D1=80=D0=B2=D0=B5=D1=80=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D1=83=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F=20=D0=BF=D0=B0=D0=BC=D1=8F=D1=82=D1=8C=D1=8E?= =?UTF-8?q?=20=D0=B0=D0=B3=D0=B5=D0=BD=D1=82=D0=B0:=20memory=5Fclient.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../memory_client.py | 132 +++++++++++------- 1 file changed, 85 insertions(+), 47 deletions(-) diff --git a/solutions/69f8e929da860fb4533faa2a_MCP-сервер_для_управления_памятью_агента/memory_client.py b/solutions/69f8e929da860fb4533faa2a_MCP-сервер_для_управления_памятью_агента/memory_client.py index 1bc4d7f..5241d95 100644 --- a/solutions/69f8e929da860fb4533faa2a_MCP-сервер_для_управления_памятью_агента/memory_client.py +++ b/solutions/69f8e929da860fb4533faa2a_MCP-сервер_для_управления_памятью_агента/memory_client.py @@ -1,58 +1,96 @@ -# memory_client.py -""" -Клиент для тестирования MCP‑сервера памяти. -Подключается к серверу через stdio и демонстрирует работу инструментов: -- save_with_namespace -- get_by_namespace -- list_keys -""" +import json +import sys +from pathlib import Path -import asyncio -from fastmcp import Client +import httpx -async def main() -> None: - """ - Основная асинхронная функция, которая: - 1. Создаёт клиент для сервера memory_server.py. - 2. Подключается к серверу. - 3. Выполняет серию вызовов инструментов и выводит результаты. - 4. Закрывает соединение. - """ - # Инициализируем клиента, указывая путь к исполняемому скрипту сервера - client = Client("python memory_server.py") +BASE_URL = "http://127.0.0.1:8000" - # Подключаемся к серверу (стандартный ввод/вывод) - await client.connect() - try: - # Сохраняем данные в namespace "default" - result = await client.call_tool( - "save_with_namespace", - {"key": "username", "value": "Алексей", "namespace": "default"}, - ) - print(f"Сохранено: {result}") +def save(key: str, value: str) -> dict: + """Сохраняет значение по ключу.""" + resp = httpx.post(f"{BASE_URL}/save", json={"key": key, "value": value}) + return resp.json() - # Читаем все ключи из namespace "default" - result = await client.call_tool( - "get_by_namespace", - {"namespace": "default"}, - ) - print("Данные namespace 'default':") - for item in result: - print(f" {item['key']}: {item['value']}") - # Ищем ключи, содержащие подстроку 'name' - keys = await client.call_tool( - "list_keys", - {"pattern": "*name"}, - ) - print("Ключи с 'name':", keys) +def get(key: str) -> dict: + """Получает значение по ключу.""" + resp = httpx.get(f"{BASE_URL}/get", params={"key": key}) + return resp.json() - finally: - # Завершаем соединение - await client.close() + +def delete(key: str) -> dict: + """Удаляет запись по ключу.""" + resp = httpx.delete(f"{BASE_URL}/delete", params={"key": key}) + return resp.json() + + +def list_keys() -> dict: + """Возвращает список всех ключей.""" + resp = httpx.get(f"{BASE_URL}/list_keys") + return resp.json() + + +def save_with_namespace(namespace: str, key: str, value: str) -> dict: + """Сохраняет значение в указанном пространстве имён.""" + resp = httpx.post( + f"{BASE_URL}/save_with_namespace", + json={"namespace": namespace, "key": key, "value": value}, + ) + return resp.json() + + +def get_by_namespace(namespace: str, key: str) -> dict: + """Получает значение из указанного пространства имён.""" + resp = httpx.get( + f"{BASE_URL}/get_by_namespace", + params={"namespace": namespace, "key": key}, + ) + return resp.json() + + +def main() -> None: + print("=== Тестирование MCP‑сервера ===") + # 1. Сохраняем пару ключ‑значение + print("\nСохранение 'foo':'bar'") + print(json.dumps(save("foo", "bar"), indent=2)) + + # 2. Получаем значение по ключу + print("\nПолучаем 'foo'") + print(json.dumps(get("foo"), indent=2)) + + # 3. Список всех ключей + print("\nСписок ключей") + print(json.dumps(list_keys(), indent=2)) + + # 4. Удаляем ключ + print("\nУдаляем 'foo'") + print(json.dumps(delete("foo"), indent=2)) + + # 5. Проверяем, что ключ удалён + print("\nПолучаем 'foo' после удаления") + print(json.dumps(get("foo"), indent=2)) + + # 6. Работа с пространством имён + ns = "experiment" + print(f"\nСохраняем в namespace '{ns}' key='x', value='123'") + print(json.dumps(save_with_namespace(ns, "x", "123"), indent=2)) + + print("\nПолучаем из namespace") + print(json.dumps(get_by_namespace(ns, "x"), indent=2)) + + # 7. Список ключей (должен быть пустой после удаления) + print("\nСписок ключей после всех операций") + print(json.dumps(list_keys(), indent=2)) if __name__ == "__main__": - asyncio.run(main()) \ No newline at end of file + try: + main() + except httpx.RequestError as exc: + print(f"Ошибка соединения с сервером: {exc}") + sys.exit(1) + except Exception as e: + print(f"Неожиданная ошибка: {e}") + sys.exit(1) \ No newline at end of file