MemoryOS 2.0.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- memoryos-2.0.3.dist-info/METADATA +418 -0
- memoryos-2.0.3.dist-info/RECORD +315 -0
- memoryos-2.0.3.dist-info/WHEEL +4 -0
- memoryos-2.0.3.dist-info/entry_points.txt +3 -0
- memoryos-2.0.3.dist-info/licenses/LICENSE +201 -0
- memos/__init__.py +20 -0
- memos/api/client.py +571 -0
- memos/api/config.py +1018 -0
- memos/api/context/dependencies.py +50 -0
- memos/api/exceptions.py +53 -0
- memos/api/handlers/__init__.py +62 -0
- memos/api/handlers/add_handler.py +158 -0
- memos/api/handlers/base_handler.py +194 -0
- memos/api/handlers/chat_handler.py +1401 -0
- memos/api/handlers/component_init.py +388 -0
- memos/api/handlers/config_builders.py +190 -0
- memos/api/handlers/feedback_handler.py +93 -0
- memos/api/handlers/formatters_handler.py +237 -0
- memos/api/handlers/memory_handler.py +316 -0
- memos/api/handlers/scheduler_handler.py +497 -0
- memos/api/handlers/search_handler.py +222 -0
- memos/api/handlers/suggestion_handler.py +117 -0
- memos/api/mcp_serve.py +614 -0
- memos/api/middleware/request_context.py +101 -0
- memos/api/product_api.py +38 -0
- memos/api/product_models.py +1206 -0
- memos/api/routers/__init__.py +1 -0
- memos/api/routers/product_router.py +477 -0
- memos/api/routers/server_router.py +394 -0
- memos/api/server_api.py +44 -0
- memos/api/start_api.py +433 -0
- memos/chunkers/__init__.py +4 -0
- memos/chunkers/base.py +24 -0
- memos/chunkers/charactertext_chunker.py +41 -0
- memos/chunkers/factory.py +24 -0
- memos/chunkers/markdown_chunker.py +62 -0
- memos/chunkers/sentence_chunker.py +54 -0
- memos/chunkers/simple_chunker.py +50 -0
- memos/cli.py +113 -0
- memos/configs/__init__.py +0 -0
- memos/configs/base.py +82 -0
- memos/configs/chunker.py +59 -0
- memos/configs/embedder.py +88 -0
- memos/configs/graph_db.py +236 -0
- memos/configs/internet_retriever.py +100 -0
- memos/configs/llm.py +151 -0
- memos/configs/mem_agent.py +54 -0
- memos/configs/mem_chat.py +81 -0
- memos/configs/mem_cube.py +105 -0
- memos/configs/mem_os.py +83 -0
- memos/configs/mem_reader.py +91 -0
- memos/configs/mem_scheduler.py +385 -0
- memos/configs/mem_user.py +70 -0
- memos/configs/memory.py +324 -0
- memos/configs/parser.py +38 -0
- memos/configs/reranker.py +18 -0
- memos/configs/utils.py +8 -0
- memos/configs/vec_db.py +80 -0
- memos/context/context.py +355 -0
- memos/dependency.py +52 -0
- memos/deprecation.py +262 -0
- memos/embedders/__init__.py +0 -0
- memos/embedders/ark.py +95 -0
- memos/embedders/base.py +106 -0
- memos/embedders/factory.py +29 -0
- memos/embedders/ollama.py +77 -0
- memos/embedders/sentence_transformer.py +49 -0
- memos/embedders/universal_api.py +51 -0
- memos/exceptions.py +30 -0
- memos/graph_dbs/__init__.py +0 -0
- memos/graph_dbs/base.py +274 -0
- memos/graph_dbs/factory.py +27 -0
- memos/graph_dbs/item.py +46 -0
- memos/graph_dbs/nebular.py +1794 -0
- memos/graph_dbs/neo4j.py +1942 -0
- memos/graph_dbs/neo4j_community.py +1058 -0
- memos/graph_dbs/polardb.py +5446 -0
- memos/hello_world.py +97 -0
- memos/llms/__init__.py +0 -0
- memos/llms/base.py +25 -0
- memos/llms/deepseek.py +13 -0
- memos/llms/factory.py +38 -0
- memos/llms/hf.py +443 -0
- memos/llms/hf_singleton.py +114 -0
- memos/llms/ollama.py +135 -0
- memos/llms/openai.py +222 -0
- memos/llms/openai_new.py +198 -0
- memos/llms/qwen.py +13 -0
- memos/llms/utils.py +14 -0
- memos/llms/vllm.py +218 -0
- memos/log.py +237 -0
- memos/mem_agent/base.py +19 -0
- memos/mem_agent/deepsearch_agent.py +391 -0
- memos/mem_agent/factory.py +36 -0
- memos/mem_chat/__init__.py +0 -0
- memos/mem_chat/base.py +30 -0
- memos/mem_chat/factory.py +21 -0
- memos/mem_chat/simple.py +200 -0
- memos/mem_cube/__init__.py +0 -0
- memos/mem_cube/base.py +30 -0
- memos/mem_cube/general.py +240 -0
- memos/mem_cube/navie.py +172 -0
- memos/mem_cube/utils.py +169 -0
- memos/mem_feedback/base.py +15 -0
- memos/mem_feedback/feedback.py +1192 -0
- memos/mem_feedback/simple_feedback.py +40 -0
- memos/mem_feedback/utils.py +230 -0
- memos/mem_os/client.py +5 -0
- memos/mem_os/core.py +1203 -0
- memos/mem_os/main.py +582 -0
- memos/mem_os/product.py +1608 -0
- memos/mem_os/product_server.py +455 -0
- memos/mem_os/utils/default_config.py +359 -0
- memos/mem_os/utils/format_utils.py +1403 -0
- memos/mem_os/utils/reference_utils.py +162 -0
- memos/mem_reader/__init__.py +0 -0
- memos/mem_reader/base.py +47 -0
- memos/mem_reader/factory.py +53 -0
- memos/mem_reader/memory.py +298 -0
- memos/mem_reader/multi_modal_struct.py +965 -0
- memos/mem_reader/read_multi_modal/__init__.py +43 -0
- memos/mem_reader/read_multi_modal/assistant_parser.py +311 -0
- memos/mem_reader/read_multi_modal/base.py +273 -0
- memos/mem_reader/read_multi_modal/file_content_parser.py +826 -0
- memos/mem_reader/read_multi_modal/image_parser.py +359 -0
- memos/mem_reader/read_multi_modal/multi_modal_parser.py +252 -0
- memos/mem_reader/read_multi_modal/string_parser.py +139 -0
- memos/mem_reader/read_multi_modal/system_parser.py +327 -0
- memos/mem_reader/read_multi_modal/text_content_parser.py +131 -0
- memos/mem_reader/read_multi_modal/tool_parser.py +210 -0
- memos/mem_reader/read_multi_modal/user_parser.py +218 -0
- memos/mem_reader/read_multi_modal/utils.py +358 -0
- memos/mem_reader/simple_struct.py +912 -0
- memos/mem_reader/strategy_struct.py +163 -0
- memos/mem_reader/utils.py +157 -0
- memos/mem_scheduler/__init__.py +0 -0
- memos/mem_scheduler/analyzer/__init__.py +0 -0
- memos/mem_scheduler/analyzer/api_analyzer.py +714 -0
- memos/mem_scheduler/analyzer/eval_analyzer.py +219 -0
- memos/mem_scheduler/analyzer/mos_for_test_scheduler.py +571 -0
- memos/mem_scheduler/analyzer/scheduler_for_eval.py +280 -0
- memos/mem_scheduler/base_scheduler.py +1319 -0
- memos/mem_scheduler/general_modules/__init__.py +0 -0
- memos/mem_scheduler/general_modules/api_misc.py +137 -0
- memos/mem_scheduler/general_modules/base.py +80 -0
- memos/mem_scheduler/general_modules/init_components_for_scheduler.py +425 -0
- memos/mem_scheduler/general_modules/misc.py +313 -0
- memos/mem_scheduler/general_modules/scheduler_logger.py +389 -0
- memos/mem_scheduler/general_modules/task_threads.py +315 -0
- memos/mem_scheduler/general_scheduler.py +1495 -0
- memos/mem_scheduler/memory_manage_modules/__init__.py +5 -0
- memos/mem_scheduler/memory_manage_modules/memory_filter.py +306 -0
- memos/mem_scheduler/memory_manage_modules/retriever.py +547 -0
- memos/mem_scheduler/monitors/__init__.py +0 -0
- memos/mem_scheduler/monitors/dispatcher_monitor.py +366 -0
- memos/mem_scheduler/monitors/general_monitor.py +394 -0
- memos/mem_scheduler/monitors/task_schedule_monitor.py +254 -0
- memos/mem_scheduler/optimized_scheduler.py +410 -0
- memos/mem_scheduler/orm_modules/__init__.py +0 -0
- memos/mem_scheduler/orm_modules/api_redis_model.py +518 -0
- memos/mem_scheduler/orm_modules/base_model.py +729 -0
- memos/mem_scheduler/orm_modules/monitor_models.py +261 -0
- memos/mem_scheduler/orm_modules/redis_model.py +699 -0
- memos/mem_scheduler/scheduler_factory.py +23 -0
- memos/mem_scheduler/schemas/__init__.py +0 -0
- memos/mem_scheduler/schemas/analyzer_schemas.py +52 -0
- memos/mem_scheduler/schemas/api_schemas.py +233 -0
- memos/mem_scheduler/schemas/general_schemas.py +55 -0
- memos/mem_scheduler/schemas/message_schemas.py +173 -0
- memos/mem_scheduler/schemas/monitor_schemas.py +406 -0
- memos/mem_scheduler/schemas/task_schemas.py +132 -0
- memos/mem_scheduler/task_schedule_modules/__init__.py +0 -0
- memos/mem_scheduler/task_schedule_modules/dispatcher.py +740 -0
- memos/mem_scheduler/task_schedule_modules/local_queue.py +247 -0
- memos/mem_scheduler/task_schedule_modules/orchestrator.py +74 -0
- memos/mem_scheduler/task_schedule_modules/redis_queue.py +1385 -0
- memos/mem_scheduler/task_schedule_modules/task_queue.py +162 -0
- memos/mem_scheduler/utils/__init__.py +0 -0
- memos/mem_scheduler/utils/api_utils.py +77 -0
- memos/mem_scheduler/utils/config_utils.py +100 -0
- memos/mem_scheduler/utils/db_utils.py +50 -0
- memos/mem_scheduler/utils/filter_utils.py +176 -0
- memos/mem_scheduler/utils/metrics.py +125 -0
- memos/mem_scheduler/utils/misc_utils.py +290 -0
- memos/mem_scheduler/utils/monitor_event_utils.py +67 -0
- memos/mem_scheduler/utils/status_tracker.py +229 -0
- memos/mem_scheduler/webservice_modules/__init__.py +0 -0
- memos/mem_scheduler/webservice_modules/rabbitmq_service.py +485 -0
- memos/mem_scheduler/webservice_modules/redis_service.py +380 -0
- memos/mem_user/factory.py +94 -0
- memos/mem_user/mysql_persistent_user_manager.py +271 -0
- memos/mem_user/mysql_user_manager.py +502 -0
- memos/mem_user/persistent_factory.py +98 -0
- memos/mem_user/persistent_user_manager.py +260 -0
- memos/mem_user/redis_persistent_user_manager.py +225 -0
- memos/mem_user/user_manager.py +488 -0
- memos/memories/__init__.py +0 -0
- memos/memories/activation/__init__.py +0 -0
- memos/memories/activation/base.py +42 -0
- memos/memories/activation/item.py +56 -0
- memos/memories/activation/kv.py +292 -0
- memos/memories/activation/vllmkv.py +219 -0
- memos/memories/base.py +19 -0
- memos/memories/factory.py +42 -0
- memos/memories/parametric/__init__.py +0 -0
- memos/memories/parametric/base.py +19 -0
- memos/memories/parametric/item.py +11 -0
- memos/memories/parametric/lora.py +41 -0
- memos/memories/textual/__init__.py +0 -0
- memos/memories/textual/base.py +92 -0
- memos/memories/textual/general.py +236 -0
- memos/memories/textual/item.py +304 -0
- memos/memories/textual/naive.py +187 -0
- memos/memories/textual/prefer_text_memory/__init__.py +0 -0
- memos/memories/textual/prefer_text_memory/adder.py +504 -0
- memos/memories/textual/prefer_text_memory/config.py +106 -0
- memos/memories/textual/prefer_text_memory/extractor.py +221 -0
- memos/memories/textual/prefer_text_memory/factory.py +85 -0
- memos/memories/textual/prefer_text_memory/retrievers.py +177 -0
- memos/memories/textual/prefer_text_memory/spliter.py +132 -0
- memos/memories/textual/prefer_text_memory/utils.py +93 -0
- memos/memories/textual/preference.py +344 -0
- memos/memories/textual/simple_preference.py +161 -0
- memos/memories/textual/simple_tree.py +69 -0
- memos/memories/textual/tree.py +459 -0
- memos/memories/textual/tree_text_memory/__init__.py +0 -0
- memos/memories/textual/tree_text_memory/organize/__init__.py +0 -0
- memos/memories/textual/tree_text_memory/organize/handler.py +184 -0
- memos/memories/textual/tree_text_memory/organize/manager.py +518 -0
- memos/memories/textual/tree_text_memory/organize/relation_reason_detector.py +238 -0
- memos/memories/textual/tree_text_memory/organize/reorganizer.py +622 -0
- memos/memories/textual/tree_text_memory/retrieve/__init__.py +0 -0
- memos/memories/textual/tree_text_memory/retrieve/advanced_searcher.py +364 -0
- memos/memories/textual/tree_text_memory/retrieve/bm25_util.py +186 -0
- memos/memories/textual/tree_text_memory/retrieve/bochasearch.py +419 -0
- memos/memories/textual/tree_text_memory/retrieve/internet_retriever.py +270 -0
- memos/memories/textual/tree_text_memory/retrieve/internet_retriever_factory.py +102 -0
- memos/memories/textual/tree_text_memory/retrieve/reasoner.py +61 -0
- memos/memories/textual/tree_text_memory/retrieve/recall.py +497 -0
- memos/memories/textual/tree_text_memory/retrieve/reranker.py +111 -0
- memos/memories/textual/tree_text_memory/retrieve/retrieval_mid_structs.py +16 -0
- memos/memories/textual/tree_text_memory/retrieve/retrieve_utils.py +472 -0
- memos/memories/textual/tree_text_memory/retrieve/searcher.py +848 -0
- memos/memories/textual/tree_text_memory/retrieve/task_goal_parser.py +135 -0
- memos/memories/textual/tree_text_memory/retrieve/utils.py +54 -0
- memos/memories/textual/tree_text_memory/retrieve/xinyusearch.py +387 -0
- memos/memos_tools/dinding_report_bot.py +453 -0
- memos/memos_tools/lockfree_dict.py +120 -0
- memos/memos_tools/notification_service.py +44 -0
- memos/memos_tools/notification_utils.py +142 -0
- memos/memos_tools/singleton.py +174 -0
- memos/memos_tools/thread_safe_dict.py +310 -0
- memos/memos_tools/thread_safe_dict_segment.py +382 -0
- memos/multi_mem_cube/__init__.py +0 -0
- memos/multi_mem_cube/composite_cube.py +86 -0
- memos/multi_mem_cube/single_cube.py +874 -0
- memos/multi_mem_cube/views.py +54 -0
- memos/parsers/__init__.py +0 -0
- memos/parsers/base.py +15 -0
- memos/parsers/factory.py +21 -0
- memos/parsers/markitdown.py +28 -0
- memos/reranker/__init__.py +4 -0
- memos/reranker/base.py +25 -0
- memos/reranker/concat.py +103 -0
- memos/reranker/cosine_local.py +102 -0
- memos/reranker/factory.py +72 -0
- memos/reranker/http_bge.py +324 -0
- memos/reranker/http_bge_strategy.py +327 -0
- memos/reranker/noop.py +19 -0
- memos/reranker/strategies/__init__.py +4 -0
- memos/reranker/strategies/base.py +61 -0
- memos/reranker/strategies/concat_background.py +94 -0
- memos/reranker/strategies/concat_docsource.py +110 -0
- memos/reranker/strategies/dialogue_common.py +109 -0
- memos/reranker/strategies/factory.py +31 -0
- memos/reranker/strategies/single_turn.py +107 -0
- memos/reranker/strategies/singleturn_outmem.py +98 -0
- memos/settings.py +10 -0
- memos/templates/__init__.py +0 -0
- memos/templates/advanced_search_prompts.py +211 -0
- memos/templates/cloud_service_prompt.py +107 -0
- memos/templates/instruction_completion.py +66 -0
- memos/templates/mem_agent_prompts.py +85 -0
- memos/templates/mem_feedback_prompts.py +822 -0
- memos/templates/mem_reader_prompts.py +1096 -0
- memos/templates/mem_reader_strategy_prompts.py +238 -0
- memos/templates/mem_scheduler_prompts.py +626 -0
- memos/templates/mem_search_prompts.py +93 -0
- memos/templates/mos_prompts.py +403 -0
- memos/templates/prefer_complete_prompt.py +735 -0
- memos/templates/tool_mem_prompts.py +139 -0
- memos/templates/tree_reorganize_prompts.py +230 -0
- memos/types/__init__.py +34 -0
- memos/types/general_types.py +151 -0
- memos/types/openai_chat_completion_types/__init__.py +15 -0
- memos/types/openai_chat_completion_types/chat_completion_assistant_message_param.py +56 -0
- memos/types/openai_chat_completion_types/chat_completion_content_part_image_param.py +27 -0
- memos/types/openai_chat_completion_types/chat_completion_content_part_input_audio_param.py +23 -0
- memos/types/openai_chat_completion_types/chat_completion_content_part_param.py +43 -0
- memos/types/openai_chat_completion_types/chat_completion_content_part_refusal_param.py +16 -0
- memos/types/openai_chat_completion_types/chat_completion_content_part_text_param.py +16 -0
- memos/types/openai_chat_completion_types/chat_completion_message_custom_tool_call_param.py +27 -0
- memos/types/openai_chat_completion_types/chat_completion_message_function_tool_call_param.py +32 -0
- memos/types/openai_chat_completion_types/chat_completion_message_param.py +18 -0
- memos/types/openai_chat_completion_types/chat_completion_message_tool_call_union_param.py +15 -0
- memos/types/openai_chat_completion_types/chat_completion_system_message_param.py +36 -0
- memos/types/openai_chat_completion_types/chat_completion_tool_message_param.py +30 -0
- memos/types/openai_chat_completion_types/chat_completion_user_message_param.py +34 -0
- memos/utils.py +123 -0
- memos/vec_dbs/__init__.py +0 -0
- memos/vec_dbs/base.py +117 -0
- memos/vec_dbs/factory.py +23 -0
- memos/vec_dbs/item.py +50 -0
- memos/vec_dbs/milvus.py +654 -0
- memos/vec_dbs/qdrant.py +355 -0
memos/api/mcp_serve.py
ADDED
|
@@ -0,0 +1,614 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from dotenv import load_dotenv
|
|
7
|
+
from fastmcp import FastMCP
|
|
8
|
+
|
|
9
|
+
# Assuming these are your imports
|
|
10
|
+
from memos.mem_os.main import MOS
|
|
11
|
+
from memos.mem_os.utils.default_config import get_default
|
|
12
|
+
from memos.mem_user.user_manager import UserRole
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
load_dotenv()
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def load_default_config(user_id="default_user"):
|
|
19
|
+
"""
|
|
20
|
+
Load MOS configuration from environment variables.
|
|
21
|
+
|
|
22
|
+
IMPORTANT for Neo4j Community Edition:
|
|
23
|
+
Community Edition does not support administrative commands like 'CREATE DATABASE'.
|
|
24
|
+
To avoid errors, ensure the following environment variables are set correctly:
|
|
25
|
+
- NEO4J_DB_NAME=neo4j (Must use the default database)
|
|
26
|
+
- NEO4J_AUTO_CREATE=false (Disable automatic database creation)
|
|
27
|
+
- NEO4J_USE_MULTI_DB=false (Disable multi-tenant database mode)
|
|
28
|
+
"""
|
|
29
|
+
# Define mapping between environment variables and configuration parameters
|
|
30
|
+
# We support both clean names and MOS_ prefixed names for compatibility
|
|
31
|
+
env_mapping = {
|
|
32
|
+
"OPENAI_API_KEY": "openai_api_key",
|
|
33
|
+
"OPENAI_API_BASE": "openai_api_base",
|
|
34
|
+
"MOS_TEXT_MEM_TYPE": "text_mem_type",
|
|
35
|
+
"NEO4J_URI": "neo4j_uri",
|
|
36
|
+
"NEO4J_USER": "neo4j_user",
|
|
37
|
+
"NEO4J_PASSWORD": "neo4j_password",
|
|
38
|
+
"NEO4J_DB_NAME": "neo4j_db_name",
|
|
39
|
+
"NEO4J_AUTO_CREATE": "neo4j_auto_create",
|
|
40
|
+
"NEO4J_USE_MULTI_DB": "use_multi_db",
|
|
41
|
+
"MOS_NEO4J_SHARED_DB": "mos_shared_db", # Special handle later
|
|
42
|
+
"MODEL_NAME": "model_name",
|
|
43
|
+
"MOS_CHAT_MODEL": "model_name",
|
|
44
|
+
"EMBEDDER_MODEL": "embedder_model",
|
|
45
|
+
"MOS_EMBEDDER_MODEL": "embedder_model",
|
|
46
|
+
"CHUNK_SIZE": "chunk_size",
|
|
47
|
+
"CHUNK_OVERLAP": "chunk_overlap",
|
|
48
|
+
"ENABLE_MEM_SCHEDULER": "enable_mem_scheduler",
|
|
49
|
+
"MOS_ENABLE_SCHEDULER": "enable_mem_scheduler",
|
|
50
|
+
"ENABLE_ACTIVATION_MEMORY": "enable_activation_memory",
|
|
51
|
+
"TEMPERATURE": "temperature",
|
|
52
|
+
"MOS_CHAT_TEMPERATURE": "temperature",
|
|
53
|
+
"MAX_TOKENS": "max_tokens",
|
|
54
|
+
"MOS_MAX_TOKENS": "max_tokens",
|
|
55
|
+
"TOP_P": "top_p",
|
|
56
|
+
"MOS_TOP_P": "top_p",
|
|
57
|
+
"TOP_K": "top_k",
|
|
58
|
+
"MOS_TOP_K": "top_k",
|
|
59
|
+
"SCHEDULER_TOP_K": "scheduler_top_k",
|
|
60
|
+
"MOS_SCHEDULER_TOP_K": "scheduler_top_k",
|
|
61
|
+
"SCHEDULER_TOP_N": "scheduler_top_n",
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
# Fields that should always be kept as strings (not converted to numbers)
|
|
65
|
+
string_only_fields = {
|
|
66
|
+
"openai_api_key",
|
|
67
|
+
"openai_api_base",
|
|
68
|
+
"neo4j_uri",
|
|
69
|
+
"neo4j_user",
|
|
70
|
+
"neo4j_password",
|
|
71
|
+
"neo4j_db_name",
|
|
72
|
+
"text_mem_type",
|
|
73
|
+
"model_name",
|
|
74
|
+
"embedder_model",
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
kwargs = {"user_id": user_id}
|
|
78
|
+
for env_key, param_key in env_mapping.items():
|
|
79
|
+
val = os.getenv(env_key)
|
|
80
|
+
if val is not None:
|
|
81
|
+
# Strip quotes if they exist (sometimes happens with .env)
|
|
82
|
+
if (val.startswith('"') and val.endswith('"')) or (
|
|
83
|
+
val.startswith("'") and val.endswith("'")
|
|
84
|
+
):
|
|
85
|
+
val = val[1:-1]
|
|
86
|
+
|
|
87
|
+
# Handle boolean conversions
|
|
88
|
+
if val.lower() in ("true", "false"):
|
|
89
|
+
kwargs[param_key] = val.lower() == "true"
|
|
90
|
+
# Keep certain fields as strings
|
|
91
|
+
elif param_key in string_only_fields:
|
|
92
|
+
kwargs[param_key] = val
|
|
93
|
+
else:
|
|
94
|
+
# Try numeric conversions (int first, then float)
|
|
95
|
+
try:
|
|
96
|
+
if "." in val:
|
|
97
|
+
kwargs[param_key] = float(val)
|
|
98
|
+
else:
|
|
99
|
+
kwargs[param_key] = int(val)
|
|
100
|
+
except ValueError:
|
|
101
|
+
kwargs[param_key] = val
|
|
102
|
+
|
|
103
|
+
# Logic handle for MOS_NEO4J_SHARED_DB vs use_multi_db
|
|
104
|
+
if "mos_shared_db" in kwargs:
|
|
105
|
+
kwargs["use_multi_db"] = not kwargs.pop("mos_shared_db")
|
|
106
|
+
|
|
107
|
+
# Extract mandatory or special params
|
|
108
|
+
openai_api_key = kwargs.pop("openai_api_key", os.getenv("OPENAI_API_KEY"))
|
|
109
|
+
openai_api_base = kwargs.pop("openai_api_base", "https://api.openai.com/v1")
|
|
110
|
+
text_mem_type = kwargs.pop("text_mem_type", "tree_text")
|
|
111
|
+
|
|
112
|
+
# Ensure embedder_model has a default value if not set
|
|
113
|
+
if "embedder_model" not in kwargs:
|
|
114
|
+
kwargs["embedder_model"] = os.getenv("EMBEDDER_MODEL", "nomic-embed-text:latest")
|
|
115
|
+
|
|
116
|
+
config, cube = get_default(
|
|
117
|
+
openai_api_key=openai_api_key,
|
|
118
|
+
openai_api_base=openai_api_base,
|
|
119
|
+
text_mem_type=text_mem_type,
|
|
120
|
+
**kwargs,
|
|
121
|
+
)
|
|
122
|
+
return config, cube
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
class MOSMCPStdioServer:
|
|
126
|
+
def __init__(self):
|
|
127
|
+
self.mcp = FastMCP("MOS Memory System")
|
|
128
|
+
config, cube = load_default_config()
|
|
129
|
+
self.mos_core = MOS(config=config)
|
|
130
|
+
self.mos_core.register_mem_cube(cube)
|
|
131
|
+
self._setup_tools()
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
class MOSMCPServer:
|
|
135
|
+
"""MCP Server that accepts an existing MOS instance."""
|
|
136
|
+
|
|
137
|
+
def __init__(self, mos_instance: MOS | None = None):
|
|
138
|
+
self.mcp = FastMCP("MOS Memory System")
|
|
139
|
+
if mos_instance is None:
|
|
140
|
+
# Fall back to creating from default config
|
|
141
|
+
config, cube = load_default_config()
|
|
142
|
+
self.mos_core = MOS(config=config)
|
|
143
|
+
self.mos_core.register_mem_cube(cube)
|
|
144
|
+
else:
|
|
145
|
+
self.mos_core = mos_instance
|
|
146
|
+
self._setup_tools()
|
|
147
|
+
|
|
148
|
+
def _setup_tools(self):
|
|
149
|
+
"""Setup MCP tools"""
|
|
150
|
+
|
|
151
|
+
@self.mcp.tool()
|
|
152
|
+
async def chat(query: str, user_id: str | None = None) -> str:
|
|
153
|
+
"""
|
|
154
|
+
Chat with MOS system using memory-enhanced responses.
|
|
155
|
+
|
|
156
|
+
This method provides intelligent responses by searching through user's memory cubes
|
|
157
|
+
and incorporating relevant context. It supports both standard chat mode and enhanced
|
|
158
|
+
Chain of Thought (CoT) mode for complex queries when PRO_MODE is enabled.
|
|
159
|
+
|
|
160
|
+
Args:
|
|
161
|
+
query (str): The user's query or question to be answered
|
|
162
|
+
user_id (str, optional): User ID for the chat session. If not provided, uses the default user
|
|
163
|
+
|
|
164
|
+
Returns:
|
|
165
|
+
str: AI-generated response incorporating relevant memories and context
|
|
166
|
+
"""
|
|
167
|
+
try:
|
|
168
|
+
response = self.mos_core.chat(query, user_id)
|
|
169
|
+
return response
|
|
170
|
+
except Exception as e:
|
|
171
|
+
import traceback
|
|
172
|
+
|
|
173
|
+
error_details = traceback.format_exc()
|
|
174
|
+
return f"Chat error: {e!s}\nTraceback:\n{error_details}"
|
|
175
|
+
|
|
176
|
+
@self.mcp.tool()
|
|
177
|
+
async def create_user(
|
|
178
|
+
user_id: str, role: str = "USER", user_name: str | None = None
|
|
179
|
+
) -> str:
|
|
180
|
+
"""
|
|
181
|
+
Create a new user in the MOS system.
|
|
182
|
+
|
|
183
|
+
This method creates a new user account with specified role and name.
|
|
184
|
+
Users can have different access levels and can own or access memory cubes.
|
|
185
|
+
|
|
186
|
+
Args:
|
|
187
|
+
user_id (str): Unique identifier for the user
|
|
188
|
+
role (str): User role - "USER" for regular users, "ADMIN" for administrators
|
|
189
|
+
user_name (str, optional): Display name for the user. If not provided, uses user_id
|
|
190
|
+
|
|
191
|
+
Returns:
|
|
192
|
+
str: Success message with the created user ID
|
|
193
|
+
"""
|
|
194
|
+
try:
|
|
195
|
+
user_role = UserRole.ADMIN if role.upper() == "ADMIN" else UserRole.USER
|
|
196
|
+
created_user_id = self.mos_core.create_user(user_id, user_role, user_name)
|
|
197
|
+
return f"User created successfully: {created_user_id}"
|
|
198
|
+
except Exception as e:
|
|
199
|
+
return f"Error creating user: {e!s}"
|
|
200
|
+
|
|
201
|
+
@self.mcp.tool()
|
|
202
|
+
async def create_cube(
|
|
203
|
+
cube_name: str, owner_id: str, cube_path: str | None = None, cube_id: str | None = None
|
|
204
|
+
) -> str:
|
|
205
|
+
"""
|
|
206
|
+
Create a new memory cube for a user.
|
|
207
|
+
|
|
208
|
+
Memory cubes are containers that store different types of memories (textual, activation, parametric).
|
|
209
|
+
Each cube can be owned by a user and shared with other users.
|
|
210
|
+
|
|
211
|
+
Args:
|
|
212
|
+
cube_name (str): Human-readable name for the memory cube
|
|
213
|
+
owner_id (str): User ID of the cube owner who has full control
|
|
214
|
+
cube_path (str, optional): File system path where cube data will be stored
|
|
215
|
+
cube_id (str, optional): Custom unique identifier for the cube. If not provided, one will be generated
|
|
216
|
+
|
|
217
|
+
Returns:
|
|
218
|
+
str: Success message with the created cube ID
|
|
219
|
+
"""
|
|
220
|
+
try:
|
|
221
|
+
created_cube_id = self.mos_core.create_cube_for_user(
|
|
222
|
+
cube_name, owner_id, cube_path, cube_id
|
|
223
|
+
)
|
|
224
|
+
return f"Cube created successfully: {created_cube_id}"
|
|
225
|
+
except Exception as e:
|
|
226
|
+
return f"Error creating cube: {e!s}"
|
|
227
|
+
|
|
228
|
+
@self.mcp.tool()
|
|
229
|
+
async def register_cube(
|
|
230
|
+
cube_name_or_path: str, cube_id: str | None = None, user_id: str | None = None
|
|
231
|
+
) -> str:
|
|
232
|
+
"""
|
|
233
|
+
Register an existing memory cube with the MOS system.
|
|
234
|
+
|
|
235
|
+
This method loads and registers a memory cube from a file path or creates a new one
|
|
236
|
+
if the path doesn't exist. The cube becomes available for memory operations.
|
|
237
|
+
|
|
238
|
+
Args:
|
|
239
|
+
cube_name_or_path (str): File path to the memory cube or name for a new cube
|
|
240
|
+
cube_id (str, optional): Custom identifier for the cube. If not provided, one will be generated
|
|
241
|
+
user_id (str, optional): User ID to associate with the cube. If not provided, uses default user
|
|
242
|
+
|
|
243
|
+
Returns:
|
|
244
|
+
str: Success message with the registered cube ID
|
|
245
|
+
"""
|
|
246
|
+
try:
|
|
247
|
+
if not os.path.exists(cube_name_or_path):
|
|
248
|
+
_, cube = load_default_config(user_id=user_id)
|
|
249
|
+
cube_to_register = cube
|
|
250
|
+
else:
|
|
251
|
+
cube_to_register = cube_name_or_path
|
|
252
|
+
self.mos_core.register_mem_cube(
|
|
253
|
+
cube_to_register, mem_cube_id=cube_id, user_id=user_id
|
|
254
|
+
)
|
|
255
|
+
return f"Cube registered successfully: {cube_id or cube_to_register}"
|
|
256
|
+
except Exception as e:
|
|
257
|
+
return f"Error registering cube: {e!s}"
|
|
258
|
+
|
|
259
|
+
@self.mcp.tool()
|
|
260
|
+
async def unregister_cube(cube_id: str, user_id: str | None = None) -> str:
|
|
261
|
+
"""
|
|
262
|
+
Unregister a memory cube from the MOS system.
|
|
263
|
+
|
|
264
|
+
This method removes a memory cube from the active session, making it unavailable
|
|
265
|
+
for memory operations. The cube data remains intact on disk.
|
|
266
|
+
|
|
267
|
+
Args:
|
|
268
|
+
cube_id (str): Unique identifier of the cube to unregister
|
|
269
|
+
user_id (str, optional): User ID for access validation. If not provided, uses default user
|
|
270
|
+
|
|
271
|
+
Returns:
|
|
272
|
+
str: Success message confirming the cube was unregistered
|
|
273
|
+
"""
|
|
274
|
+
try:
|
|
275
|
+
self.mos_core.unregister_mem_cube(cube_id, user_id)
|
|
276
|
+
return f"Cube unregistered successfully: {cube_id}"
|
|
277
|
+
except Exception as e:
|
|
278
|
+
return f"Error unregistering cube: {e!s}"
|
|
279
|
+
|
|
280
|
+
@self.mcp.tool()
|
|
281
|
+
async def search_memories(
|
|
282
|
+
query: str, user_id: str | None = None, cube_ids: list[str] | None = None
|
|
283
|
+
) -> dict[str, Any]:
|
|
284
|
+
"""
|
|
285
|
+
Search for memories across user's accessible memory cubes.
|
|
286
|
+
|
|
287
|
+
This method performs semantic search through textual memories stored in the specified
|
|
288
|
+
cubes, returning relevant memories based on the query. Results are ranked by relevance.
|
|
289
|
+
|
|
290
|
+
Args:
|
|
291
|
+
query (str): Search query to find relevant memories
|
|
292
|
+
user_id (str, optional): User ID whose cubes to search. If not provided, uses default user
|
|
293
|
+
cube_ids (list[str], optional): Specific cube IDs to search. If not provided, searches all user's cubes
|
|
294
|
+
|
|
295
|
+
Returns:
|
|
296
|
+
dict: Search results containing text_mem, act_mem, and para_mem categories with relevant memories
|
|
297
|
+
"""
|
|
298
|
+
try:
|
|
299
|
+
result = self.mos_core.search(query, user_id, cube_ids)
|
|
300
|
+
return result
|
|
301
|
+
except Exception as e:
|
|
302
|
+
import traceback
|
|
303
|
+
|
|
304
|
+
error_details = traceback.format_exc()
|
|
305
|
+
return {"error": str(e), "traceback": error_details}
|
|
306
|
+
|
|
307
|
+
@self.mcp.tool()
|
|
308
|
+
async def add_memory(
|
|
309
|
+
memory_content: str | None = None,
|
|
310
|
+
doc_path: str | None = None,
|
|
311
|
+
messages: list[dict[str, str]] | None = None,
|
|
312
|
+
cube_id: str | None = None,
|
|
313
|
+
user_id: str | None = None,
|
|
314
|
+
) -> str:
|
|
315
|
+
"""
|
|
316
|
+
Add memories to a memory cube.
|
|
317
|
+
|
|
318
|
+
This method can add memories from different sources: direct text content, document files,
|
|
319
|
+
or conversation messages. The memories are processed and stored in the specified cube.
|
|
320
|
+
|
|
321
|
+
Args:
|
|
322
|
+
memory_content (str, optional): Direct text content to add as memory
|
|
323
|
+
doc_path (str, optional): Path to a document file to process and add as memories
|
|
324
|
+
messages (list[dict[str, str]], optional): List of conversation messages to add as memories
|
|
325
|
+
cube_id (str, optional): Target cube ID. If not provided, uses user's default cube
|
|
326
|
+
user_id (str, optional): User ID for access validation. If not provided, uses default user
|
|
327
|
+
|
|
328
|
+
Returns:
|
|
329
|
+
str: Success message confirming memories were added
|
|
330
|
+
"""
|
|
331
|
+
try:
|
|
332
|
+
self.mos_core.add(
|
|
333
|
+
messages=messages,
|
|
334
|
+
memory_content=memory_content,
|
|
335
|
+
doc_path=doc_path,
|
|
336
|
+
mem_cube_id=cube_id,
|
|
337
|
+
user_id=user_id,
|
|
338
|
+
)
|
|
339
|
+
return "Memory added successfully"
|
|
340
|
+
except Exception as e:
|
|
341
|
+
return f"Error adding memory: {e!s}"
|
|
342
|
+
|
|
343
|
+
@self.mcp.tool()
|
|
344
|
+
async def get_memory(
|
|
345
|
+
cube_id: str, memory_id: str, user_id: str | None = None
|
|
346
|
+
) -> dict[str, Any]:
|
|
347
|
+
"""
|
|
348
|
+
Retrieve a specific memory from a memory cube.
|
|
349
|
+
|
|
350
|
+
This method fetches a single memory item by its unique identifier from the specified cube.
|
|
351
|
+
|
|
352
|
+
Args:
|
|
353
|
+
cube_id (str): Unique identifier of the cube containing the memory
|
|
354
|
+
memory_id (str): Unique identifier of the specific memory to retrieve
|
|
355
|
+
user_id (str, optional): User ID for access validation. If not provided, uses default user
|
|
356
|
+
|
|
357
|
+
Returns:
|
|
358
|
+
dict: Memory content with metadata including memory text, creation time, and source
|
|
359
|
+
"""
|
|
360
|
+
try:
|
|
361
|
+
memory = self.mos_core.get(cube_id, memory_id, user_id)
|
|
362
|
+
return {"memory": str(memory)}
|
|
363
|
+
except Exception as e:
|
|
364
|
+
return {"error": str(e)}
|
|
365
|
+
|
|
366
|
+
@self.mcp.tool()
|
|
367
|
+
async def update_memory(
|
|
368
|
+
cube_id: str, memory_id: str, memory_content: str, user_id: str | None = None
|
|
369
|
+
) -> str:
|
|
370
|
+
"""
|
|
371
|
+
Update an existing memory in a memory cube.
|
|
372
|
+
|
|
373
|
+
This method modifies the content of a specific memory while preserving its metadata.
|
|
374
|
+
Note: Update functionality may not be supported by all memory backends (e.g., tree_text).
|
|
375
|
+
|
|
376
|
+
Args:
|
|
377
|
+
cube_id (str): Unique identifier of the cube containing the memory
|
|
378
|
+
memory_id (str): Unique identifier of the memory to update
|
|
379
|
+
memory_content (str): New content to replace the existing memory
|
|
380
|
+
user_id (str, optional): User ID for access validation. If not provided, uses default user
|
|
381
|
+
|
|
382
|
+
Returns:
|
|
383
|
+
str: Success message confirming the memory was updated
|
|
384
|
+
"""
|
|
385
|
+
try:
|
|
386
|
+
from memos.memories.textual.item import TextualMemoryItem, TextualMemoryMetadata
|
|
387
|
+
|
|
388
|
+
metadata = TextualMemoryMetadata(
|
|
389
|
+
user_id=user_id or self.mos_core.user_id,
|
|
390
|
+
session_id=self.mos_core.session_id,
|
|
391
|
+
source="mcp_update",
|
|
392
|
+
)
|
|
393
|
+
memory_item = TextualMemoryItem(memory=memory_content, metadata=metadata)
|
|
394
|
+
|
|
395
|
+
self.mos_core.update(cube_id, memory_id, memory_item, user_id)
|
|
396
|
+
return f"Memory updated successfully: {memory_id}"
|
|
397
|
+
except Exception as e:
|
|
398
|
+
return f"Error updating memory: {e!s}"
|
|
399
|
+
|
|
400
|
+
@self.mcp.tool()
|
|
401
|
+
async def delete_memory(cube_id: str, memory_id: str, user_id: str | None = None) -> str:
|
|
402
|
+
"""
|
|
403
|
+
Delete a specific memory from a memory cube.
|
|
404
|
+
|
|
405
|
+
This method permanently removes a memory item from the specified cube.
|
|
406
|
+
The operation cannot be undone.
|
|
407
|
+
|
|
408
|
+
Args:
|
|
409
|
+
cube_id (str): Unique identifier of the cube containing the memory
|
|
410
|
+
memory_id (str): Unique identifier of the memory to delete
|
|
411
|
+
user_id (str, optional): User ID for access validation. If not provided, uses default user
|
|
412
|
+
|
|
413
|
+
Returns:
|
|
414
|
+
str: Success message confirming the memory was deleted
|
|
415
|
+
"""
|
|
416
|
+
try:
|
|
417
|
+
self.mos_core.delete(cube_id, memory_id, user_id)
|
|
418
|
+
return f"Memory deleted successfully: {memory_id}"
|
|
419
|
+
except Exception as e:
|
|
420
|
+
return f"Error deleting memory: {e!s}"
|
|
421
|
+
|
|
422
|
+
@self.mcp.tool()
|
|
423
|
+
async def delete_all_memories(cube_id: str, user_id: str | None = None) -> str:
|
|
424
|
+
"""
|
|
425
|
+
Delete all memories from a memory cube.
|
|
426
|
+
|
|
427
|
+
This method permanently removes all memory items from the specified cube.
|
|
428
|
+
The operation cannot be undone and will clear all textual memories.
|
|
429
|
+
|
|
430
|
+
Args:
|
|
431
|
+
cube_id (str): Unique identifier of the cube to clear
|
|
432
|
+
user_id (str, optional): User ID for access validation. If not provided, uses default user
|
|
433
|
+
|
|
434
|
+
Returns:
|
|
435
|
+
str: Success message confirming all memories were deleted
|
|
436
|
+
"""
|
|
437
|
+
try:
|
|
438
|
+
self.mos_core.delete_all(cube_id, user_id)
|
|
439
|
+
return f"All memories deleted successfully from cube: {cube_id}"
|
|
440
|
+
except Exception as e:
|
|
441
|
+
return f"Error deleting all memories: {e!s}"
|
|
442
|
+
|
|
443
|
+
@self.mcp.tool()
|
|
444
|
+
async def clear_chat_history(user_id: str | None = None) -> str:
|
|
445
|
+
"""
|
|
446
|
+
Clear the chat history for a user.
|
|
447
|
+
|
|
448
|
+
This method resets the conversation history, removing all previous messages
|
|
449
|
+
while keeping the memory cubes and stored memories intact.
|
|
450
|
+
|
|
451
|
+
Args:
|
|
452
|
+
user_id (str, optional): User ID whose chat history to clear. If not provided, uses default user
|
|
453
|
+
|
|
454
|
+
Returns:
|
|
455
|
+
str: Success message confirming chat history was cleared
|
|
456
|
+
"""
|
|
457
|
+
try:
|
|
458
|
+
self.mos_core.clear_messages(user_id)
|
|
459
|
+
target_user = user_id or self.mos_core.user_id
|
|
460
|
+
return f"Chat history cleared for user: {target_user}"
|
|
461
|
+
except Exception as e:
|
|
462
|
+
return f"Error clearing chat history: {e!s}"
|
|
463
|
+
|
|
464
|
+
@self.mcp.tool()
|
|
465
|
+
async def dump_cube(
|
|
466
|
+
dump_dir: str, user_id: str | None = None, cube_id: str | None = None
|
|
467
|
+
) -> str:
|
|
468
|
+
"""
|
|
469
|
+
Export a memory cube to a directory.
|
|
470
|
+
|
|
471
|
+
This method creates a backup or export of a memory cube, including all memories
|
|
472
|
+
and metadata, to the specified directory for backup or migration purposes.
|
|
473
|
+
|
|
474
|
+
Args:
|
|
475
|
+
dump_dir (str): Directory path where the cube data will be exported
|
|
476
|
+
user_id (str, optional): User ID for access validation. If not provided, uses default user
|
|
477
|
+
cube_id (str, optional): Cube ID to export. If not provided, uses user's default cube
|
|
478
|
+
|
|
479
|
+
Returns:
|
|
480
|
+
str: Success message with the export directory path
|
|
481
|
+
"""
|
|
482
|
+
try:
|
|
483
|
+
self.mos_core.dump(dump_dir, user_id, cube_id)
|
|
484
|
+
return f"Cube dumped successfully to: {dump_dir}"
|
|
485
|
+
except Exception as e:
|
|
486
|
+
return f"Error dumping cube: {e!s}"
|
|
487
|
+
|
|
488
|
+
@self.mcp.tool()
|
|
489
|
+
async def share_cube(cube_id: str, target_user_id: str) -> str:
|
|
490
|
+
"""
|
|
491
|
+
Share a memory cube with another user.
|
|
492
|
+
|
|
493
|
+
This method grants access to a memory cube to another user, allowing them
|
|
494
|
+
to read and search through the memories stored in that cube.
|
|
495
|
+
|
|
496
|
+
Args:
|
|
497
|
+
cube_id (str): Unique identifier of the cube to share
|
|
498
|
+
target_user_id (str): User ID of the person to share the cube with
|
|
499
|
+
|
|
500
|
+
Returns:
|
|
501
|
+
str: Success message confirming the cube was shared or error message if failed
|
|
502
|
+
"""
|
|
503
|
+
try:
|
|
504
|
+
success = self.mos_core.share_cube_with_user(cube_id, target_user_id)
|
|
505
|
+
if success:
|
|
506
|
+
return f"Cube {cube_id} shared successfully with user {target_user_id}"
|
|
507
|
+
else:
|
|
508
|
+
return f"Failed to share cube {cube_id} with user {target_user_id}"
|
|
509
|
+
except Exception as e:
|
|
510
|
+
return f"Error sharing cube: {e!s}"
|
|
511
|
+
|
|
512
|
+
@self.mcp.tool()
|
|
513
|
+
async def get_user_info(user_id: str | None = None) -> dict[str, Any]:
|
|
514
|
+
"""
|
|
515
|
+
Get detailed information about a user and their accessible memory cubes.
|
|
516
|
+
|
|
517
|
+
This method returns comprehensive user information including profile details,
|
|
518
|
+
role, creation time, and a list of all memory cubes the user can access.
|
|
519
|
+
|
|
520
|
+
Args:
|
|
521
|
+
user_id (str, optional): User ID to get information for. If not provided, uses current user
|
|
522
|
+
|
|
523
|
+
Returns:
|
|
524
|
+
dict: User information including user_id, user_name, role, created_at, and accessible_cubes
|
|
525
|
+
"""
|
|
526
|
+
try:
|
|
527
|
+
if user_id and user_id != self.mos_core.user_id:
|
|
528
|
+
# Temporarily switch user
|
|
529
|
+
original_user = self.mos_core.user_id
|
|
530
|
+
self.mos_core.user_id = user_id
|
|
531
|
+
user_info = self.mos_core.get_user_info()
|
|
532
|
+
self.mos_core.user_id = original_user
|
|
533
|
+
return user_info
|
|
534
|
+
else:
|
|
535
|
+
return self.mos_core.get_user_info()
|
|
536
|
+
except Exception as e:
|
|
537
|
+
return {"error": str(e)}
|
|
538
|
+
|
|
539
|
+
@self.mcp.tool()
|
|
540
|
+
async def control_memory_scheduler(action: str) -> str:
|
|
541
|
+
"""
|
|
542
|
+
Control the memory scheduler service.
|
|
543
|
+
|
|
544
|
+
The memory scheduler is responsible for processing and organizing memories
|
|
545
|
+
in the background. This method allows starting or stopping the scheduler service.
|
|
546
|
+
|
|
547
|
+
Args:
|
|
548
|
+
action (str): Action to perform - "start" to enable the scheduler, "stop" to disable it
|
|
549
|
+
|
|
550
|
+
Returns:
|
|
551
|
+
str: Success message confirming the scheduler action or error message if failed
|
|
552
|
+
"""
|
|
553
|
+
try:
|
|
554
|
+
if action.lower() == "start":
|
|
555
|
+
success = self.mos_core.mem_scheduler_on()
|
|
556
|
+
return (
|
|
557
|
+
"Memory scheduler started"
|
|
558
|
+
if success
|
|
559
|
+
else "Failed to start memory scheduler"
|
|
560
|
+
)
|
|
561
|
+
elif action.lower() == "stop":
|
|
562
|
+
success = self.mos_core.mem_scheduler_off()
|
|
563
|
+
return (
|
|
564
|
+
"Memory scheduler stopped" if success else "Failed to stop memory scheduler"
|
|
565
|
+
)
|
|
566
|
+
else:
|
|
567
|
+
return "Invalid action. Use 'start' or 'stop'"
|
|
568
|
+
except Exception as e:
|
|
569
|
+
return f"Error controlling memory scheduler: {e!s}"
|
|
570
|
+
|
|
571
|
+
|
|
572
|
+
def _run_mcp(self, transport: str = "stdio", **kwargs):
|
|
573
|
+
if transport == "stdio":
|
|
574
|
+
self.mcp.run(transport="stdio")
|
|
575
|
+
elif transport == "http":
|
|
576
|
+
host = kwargs.get("host", "localhost")
|
|
577
|
+
port = kwargs.get("port", 8000)
|
|
578
|
+
asyncio.run(self.mcp.run_http_async(host=host, port=port))
|
|
579
|
+
elif transport == "sse":
|
|
580
|
+
host = kwargs.get("host", "localhost")
|
|
581
|
+
port = kwargs.get("port", 8000)
|
|
582
|
+
self.mcp.run(transport="sse", host=host, port=port)
|
|
583
|
+
else:
|
|
584
|
+
raise ValueError(f"Unsupported transport: {transport}")
|
|
585
|
+
|
|
586
|
+
|
|
587
|
+
MOSMCPStdioServer.run = _run_mcp
|
|
588
|
+
MOSMCPServer.run = _run_mcp
|
|
589
|
+
|
|
590
|
+
|
|
591
|
+
# Usage example
|
|
592
|
+
if __name__ == "__main__":
|
|
593
|
+
import argparse
|
|
594
|
+
|
|
595
|
+
from dotenv import load_dotenv
|
|
596
|
+
|
|
597
|
+
load_dotenv()
|
|
598
|
+
|
|
599
|
+
# Parse command line arguments
|
|
600
|
+
parser = argparse.ArgumentParser(description="MOS MCP Server")
|
|
601
|
+
parser.add_argument(
|
|
602
|
+
"--transport",
|
|
603
|
+
choices=["stdio", "http", "sse"],
|
|
604
|
+
default="stdio",
|
|
605
|
+
help="Transport method (default: stdio)",
|
|
606
|
+
)
|
|
607
|
+
parser.add_argument("--host", default="localhost", help="Host for HTTP/SSE transport")
|
|
608
|
+
parser.add_argument("--port", type=int, default=8000, help="Port for HTTP/SSE transport")
|
|
609
|
+
|
|
610
|
+
args = parser.parse_args()
|
|
611
|
+
|
|
612
|
+
# Create and run MCP server
|
|
613
|
+
server = MOSMCPStdioServer()
|
|
614
|
+
server.run(transport=args.transport, host=args.host, port=args.port)
|