55
66import datetime
77import importlib
8- import logging
98import sys
109
1110import click
1211import uvicorn
1312
1413from agent_memory_server .config import settings
15- from agent_memory_server .logging import configure_logging , get_logger
14+ from agent_memory_server .logging import (
15+ configure_logging ,
16+ configure_mcp_logging ,
17+ get_logger ,
18+ )
1619from agent_memory_server .migrations import (
1720 migrate_add_discrete_memory_extracted_2 ,
1821 migrate_add_memory_hashes_1 ,
2124from agent_memory_server .utils .redis import ensure_search_index_exists , get_redis_conn
2225
2326
24- configure_logging ()
27+ # Don't configure logging at module level - let each command handle it
2528logger = get_logger (__name__ )
2629
2730VERSION = "0.2.0"
@@ -44,6 +47,8 @@ def rebuild_index():
4447 """Rebuild the search index."""
4548 import asyncio
4649
50+ configure_logging ()
51+
4752 async def setup_and_run ():
4853 redis = await get_redis_conn ()
4954 await ensure_search_index_exists (redis , overwrite = True )
@@ -56,6 +61,7 @@ def migrate_memories():
5661 """Migrate memories from the old format to the new format."""
5762 import asyncio
5863
64+ configure_logging ()
5965 click .echo ("Starting memory migrations..." )
6066
6167 async def run_migrations ():
@@ -81,6 +87,7 @@ def api(port: int, host: str, reload: bool):
8187 """Run the REST API server."""
8288 from agent_memory_server .main import on_start_logger
8389
90+ configure_logging ()
8491 on_start_logger (port )
8592 uvicorn .run (
8693 "agent_memory_server.main:app" ,
@@ -102,6 +109,12 @@ def mcp(port: int, mode: str):
102109 """Run the MCP server."""
103110 import asyncio
104111
112+ # Configure MCP-specific logging BEFORE any imports to avoid stdout contamination
113+ if mode == "stdio" :
114+ configure_mcp_logging ()
115+ else :
116+ configure_logging ()
117+
105118 # Update the port in settings FIRST
106119 settings .mcp_port = port
107120
@@ -116,14 +129,7 @@ async def setup_and_run():
116129 logger .info (f"Starting MCP server on port { port } \n " )
117130 await mcp_app .run_sse_async ()
118131 elif mode == "stdio" :
119- # Try to force all logging to stderr because stdio-mode MCP servers
120- # use standard output for the protocol.
121- logging .basicConfig (
122- level = settings .log_level ,
123- stream = sys .stderr ,
124- force = True , # remove any existing handlers
125- format = "%(asctime)s %(name)s %(levelname)s %(message)s" ,
126- )
132+ # Logging already configured above
127133 await mcp_app .run_stdio_async ()
128134 else :
129135 raise ValueError (f"Invalid mode: { mode } " )
@@ -153,6 +159,8 @@ def schedule_task(task_path: str, args: list[str]):
153159
154160 from docket import Docket
155161
162+ configure_logging ()
163+
156164 # Parse the arguments
157165 task_args = {}
158166 for arg in args :
@@ -218,6 +226,8 @@ def task_worker(concurrency: int, redelivery_timeout: int):
218226
219227 from docket import Worker
220228
229+ configure_logging ()
230+
221231 if not settings .use_docket :
222232 click .echo ("Docket is disabled in settings. Cannot run worker." )
223233 sys .exit (1 )
0 commit comments