Skip to content

Commit 3e3ac7f

Browse files
committed
Add logging and progress reporting to spawn command
- Add platformdirs dependency for cross-platform log directory management - Implement file-based logging with logs stored in user log directory - Add progress reporting to spawn command with command display - Remove .python-version file (project uses uv for Python version management) - Update uv.lock with new dependency
1 parent c1c42b0 commit 3e3ac7f

File tree

5 files changed

+40
-2
lines changed

5 files changed

+40
-2
lines changed

.python-version

Lines changed: 0 additions & 1 deletion
This file was deleted.

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ authors = [
1010
requires-python = ">=3.13"
1111
dependencies = [
1212
"mcp>=1.12.3",
13+
"platformdirs>=4.3.8",
1314
]
1415

1516
[project.optional-dependencies]

src/async_bash_mcp/__init__.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import asyncio
22
import os
33
import time
4+
import logging
5+
from platformdirs import user_log_dir
46
from contextlib import asynccontextmanager
57
from dataclasses import dataclass
68
from typing import Dict, List, Optional, Union
@@ -219,7 +221,6 @@ async def poll_process(
219221
process_info.stdout_position = len(process_info.stdout_buffer)
220222
process_info.stderr_position = len(process_info.stderr_buffer)
221223

222-
223224
elapsed_time = (time.time() - process_info.start_time) * 1000
224225

225226
result = {
@@ -302,6 +303,12 @@ async def lifespan(app):
302303

303304
# Create FastMCP server
304305
mcp = FastMCP("async-bash-mcp", lifespan=lifespan)
306+
root_log = logging.getLogger()
307+
log_dir = Path(user_log_dir("async_bash_mcp", ""))
308+
log_dir.mkdir(parents=True, exist_ok=True)
309+
handler = logging.FileHandler(log_dir / "log.log")
310+
root_log.addHandler(handler)
311+
logger = logging.getLogger("async_bash_mcp")
305312

306313

307314
@mcp.tool()
@@ -330,8 +337,18 @@ async def spawn(
330337
Returns:
331338
SpawnResult with the unique process ID
332339
"""
340+
341+
progress_token = (
342+
ctx.request_context.meta.progressToken if ctx.request_context.meta else None
343+
)
344+
logger.info(
345+
f"Spawning process for client {ctx.client_id} with command: {command}, cwd: {cwd}, progress token: {progress_token}"
346+
)
347+
progress_message = (cwd or "") + "$ " + command
348+
await ctx.report_progress(0, message=progress_message)
333349
pm = get_client_process_manager(ctx.client_id)
334350
process_id = await pm.spawn_process(command, cwd)
351+
await ctx.report_progress(1, message=progress_message)
335352
return SpawnResult(id=process_id)
336353

337354

tests/test_async_bash_mcp.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,21 @@
1515
)
1616

1717

18+
class MockRequestContext:
19+
def __init__(self):
20+
self.meta = None
21+
22+
1823
class MockContext:
1924
def __init__(self, client_id=None):
2025
if client_id is None:
2126
client_id = str(uuid.uuid4()) # Generate unique client ID
2227
self.client_id = client_id
28+
self.request_context = MockRequestContext()
29+
30+
async def report_progress(self, progress, message=None):
31+
"""Mock progress reporting method"""
32+
pass
2333

2434

2535
@pytest.fixture

uv.lock

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)