fix(mcp): Fix three critical bugs in beads MCP plugin
This PR fixes three bugs that prevented the MCP plugin from working:
1. **Fixed parameter name mismatch in tools.py**
- Changed `workspace_root=workspace_root` to `working_dir=workspace_root`
- The `create_bd_client()` function expects `working_dir` parameter,
but tools.py was passing `workspace_root`
- This caused "got an unexpected keyword argument 'workspace_root'" error
2. **Added version check guard for daemon client**
- Added `hasattr(_client, '_check_version')` check before calling
- BdDaemonClient doesn't have `_check_version()` method, only BdCliClient does
- This caused "'BdDaemonClient' object has no attribute '_check_version'" error
3. **Implemented proper daemon socket detection for fallback**
- Added synchronous socket file existence check before creating daemon client
- Walks up directory tree looking for `.beads/bd.sock` file
- Only creates daemon client if socket exists, otherwise falls back to CLI
- Previously, daemon client was created but failed on first method call
- This enables the documented "prefer_daemon with automatic CLI fallback" behavior
**Testing:**
- Verified MCP tools work correctly with single-repo setup
- Confirmed automatic fallback to CLI when daemon isn't running
- Tested on macOS with bd v0.9.9
**Related Issues:**
- Addresses symptoms similar to #65 (Windows BEADS_WORKING_DIR issue)
This commit is contained in:
@@ -637,16 +637,39 @@ def create_bd_client(
|
||||
if prefer_daemon:
|
||||
try:
|
||||
from .bd_daemon_client import BdDaemonClient
|
||||
from pathlib import Path
|
||||
|
||||
# Create daemon client with working_dir for context
|
||||
client = BdDaemonClient(
|
||||
working_dir=working_dir,
|
||||
actor=actor,
|
||||
)
|
||||
# Try to ping - if this works, use daemon
|
||||
# Note: This is sync check, actual usage is async
|
||||
# The caller will need to handle daemon not running at call time
|
||||
return client
|
||||
# Check if daemon socket exists before creating client
|
||||
# Walk up from working_dir to find .beads/bd.sock
|
||||
search_dir = Path(working_dir) if working_dir else Path.cwd()
|
||||
socket_found = False
|
||||
|
||||
current = search_dir.resolve()
|
||||
while True:
|
||||
beads_dir = current / ".beads"
|
||||
if beads_dir.is_dir():
|
||||
sock_path = beads_dir / "bd.sock"
|
||||
if sock_path.exists():
|
||||
socket_found = True
|
||||
break
|
||||
# Found .beads but no socket - daemon not running
|
||||
break
|
||||
|
||||
# Move up one directory
|
||||
parent = current.parent
|
||||
if parent == current:
|
||||
# Reached filesystem root
|
||||
break
|
||||
current = parent
|
||||
|
||||
if socket_found:
|
||||
# Daemon is running, use it
|
||||
client = BdDaemonClient(
|
||||
working_dir=working_dir,
|
||||
actor=actor,
|
||||
)
|
||||
return client
|
||||
# No socket found, fall through to CLI client
|
||||
except ImportError:
|
||||
# Daemon client not available (shouldn't happen but be defensive)
|
||||
pass
|
||||
|
||||
@@ -51,12 +51,13 @@ async def _get_client() -> BdClientBase:
|
||||
|
||||
_client = create_bd_client(
|
||||
prefer_daemon=use_daemon,
|
||||
workspace_root=workspace_root
|
||||
working_dir=workspace_root
|
||||
)
|
||||
|
||||
# Check version once per server lifetime
|
||||
# Check version once per server lifetime (only for CLI client)
|
||||
if not _version_checked:
|
||||
await _client._check_version()
|
||||
if hasattr(_client, '_check_version'):
|
||||
await _client._check_version()
|
||||
_version_checked = True
|
||||
|
||||
return _client
|
||||
|
||||
Reference in New Issue
Block a user