- Add repair_deps(fix=False) for orphaned dependencies
- Add detect_pollution(clean=False) for test issue detection
- Add validate(checks=None, fix_all=False) for health checks
- Implemented in BdCliClient, stubs in BdDaemonClient
- Registered as MCP tools in server.py
Amp-Thread-ID: https://ampcode.com/threads/T-9ce04c75-201b-4019-b9f1-0cf10663557c
Co-authored-by: Amp <amp@ampcode.com>
- Add shell=True for subprocess.run() on Windows platform
- Improves git command PATH resolution on Windows
- Add debug logging for git detection failures
- Fixes GH#245 timeout issue where git rev-parse times out in MCP server
Amp-Thread-ID: https://ampcode.com/threads/T-71b3ce65-87cb-451a-a30d-162d76d92f9c
Co-authored-by: Amp <amp@ampcode.com>
- Increase timeout to 5s for slow git operations
- Return error instead of falling back to unverified path
- Prevents accidental .beads creation in wrong directory
Move blocking subprocess.run() call off event loop using asyncio.to_thread()
with timeout to prevent deadlock when using stdio transport.
- Wrap _resolve_workspace_root() in asyncio.to_thread() with 2s timeout
- Add fallback to os.path.abspath() on timeout
- Ensure logging uses stderr to avoid stdio protocol pollution
Amp-Thread-ID: https://ampcode.com/threads/T-fc335bda-5fca-4daa-bdc1-5d53d0eb818f
Co-authored-by: Amp <amp@ampcode.com>
- Added safety check to exportToJSONLWithStore (daemon path)
- Refuses to export 0 issues over non-empty JSONL file
- Added --force flag to override safety check when intentional
- Added test coverage for empty database export protection
- Prevents data loss when daemon has wrong/empty database
Amp-Thread-ID: https://ampcode.com/threads/T-de18e0ad-bd17-46ec-994b-0581e257dcde
Co-authored-by: Amp <amp@ampcode.com>
Fixes#114 and #122 by adding --description/-d flag to bd update CLI
and description parameter to MCP update_issue tool.
Changes:
- CLI: Added --description flag to updateCmd
- RPC: Added Description field to UpdateArgs
- Daemon: Updated updatesFromArgs to handle description
- MCP: Added description to update_issue, UpdateIssueParams, and clients
- Storage: description already supported in allowedUpdateFields
Tested in both daemon and direct modes.
Renamed BdDaemonClient.close() cleanup method to cleanup() to eliminate
method name collision with async close(params) method for closing issues.
Root cause: Python method resolution meant the non-async close(self)
cleanup method was shadowing the async close(self, params) method that
closes issues, causing 'takes 1 positional argument but 2 were given'.
Changes:
- bd_daemon_client.py: Renamed close() -> cleanup()
- server.py: Updated cleanup code to call cleanup() instead of close()
- test_lifecycle.py: Updated tests to use cleanup()
All close-related tests pass. Fixes GitHub issue #107.
Tracked in bd-67 (closed).
- Add workspace_root param to all MCP tool signatures (accepted but ignored)
- Fix where_am_i to accept workspace_root
- Fix set_context to always set env vars even when DB not found
- Allows init to work immediately after set_context
- Register atexit handler to close daemon connections
- Add signal handlers for SIGTERM/SIGINT for graceful shutdown
- Implement cleanup() to close all daemon client connections
- Track daemon clients globally for cleanup
- Add close() method to BdDaemonClient (no-op since connections are per-request)
- Register client on first use via _get_client()
- Add comprehensive lifecycle tests
This prevents MCP server processes from accumulating without cleanup.
Each tool invocation will now properly clean up on exit.
Amp-Thread-ID: https://ampcode.com/threads/T-05d76b8e-dac9-472b-bfd0-afe10e3457cd
Co-authored-by: Amp <amp@ampcode.com>
Since our implementation uses `async` IO for subprocess communication, it's
crucial to utilize the `fastMCP.run_async()` entry-point of FastMCP.
This should fix crashes on Windows.
ref: steveyegge/beads#53
- Added per-request storage routing in daemon server
- Server now supports Cwd field in requests for database discovery
- Tree-walking to find .beads/*.db from any working directory
- Storage caching for performance across requests
- Created Python daemon client (bd_daemon_client.py)
- RPC over Unix socket communication
- Implements full BdClientBase interface
- Auto-discovery of daemon socket from working directory
- Refactored bd_client.py with abstract interface
- BdClientBase abstract class for common interface
- BdCliClient for CLI-based operations (renamed from BdClient)
- create_bd_client() factory with daemon/CLI fallback
- Backwards-compatible BdClient alias
Next: Update MCP server to use daemon client when available
Implements the `bd` reopen command across the entire MCP stack, enabling
agents to reopen closed issues with optional reason tracking for audit
trails. This addresses the need to handle regressions and incorrectly
closed issues without manual `bd` CLI intervention.
The reopen command is more explicit than `bd update --status open` and
emits a dedicated Reopened event in the audit log, making it easier to
track why issues were reopened during analysis.
Changes:
- `models.py`: Add ReopenIssueParams with issue_ids list and optional reason
- `bd_client.py`: Implement reopen() method with JSON response parsing
- `tools.py`: Add beads_reopen_issue() wrapper with Annotated types for MCP
- `server.py`: Register 'reopen' MCP tool with description and parameters
Testing (10 new):
- `test_bd_client.py`: 4 unit tests (mocked subprocess)
- `test_bd_client_integration.py`: 3 integration tests (real `bd` CLI)
- `test_mcp_server_integration.py`: 3 MCP integration tests (FastMCP Client)
- `test_tools.py`: 3 tools wrapper tests (mocked BdClient)
Also updated `README.md`.
1. Fix `test_default_beads_path_auto_detection`
- Changed beads_path to use `Field(default_factory=_default_beads_path)` so the default is evaluated at instance
creation time, not class definition time
- Updated test to mock both `shutil.which` and `os.access`
2. Fix `test_init_creates_beads_directory`
- Fixed test to pass `working_dir=temp_dir` to `BdClient` instead of using `os.chdir()`
- The `_get_working_dir()` method checks `PWD` env var first, which isn't updated by `os.chdir()`
3. Fix minor linting errors reported by `ruff` tool
4. Update `beads` version to `0.9.6` in `uv.lock` file
MCP Server test coverage is now excellent, at 92% overall maintaining our high-standards of production level quality.
```
Name Stmts Miss Cover
------------------------------------------------
src/beads_mcp/__init__.py 1 0 100%
src/beads_mcp/__main__.py 3 3 0%
src/beads_mcp/bd_client.py 214 14 93%
src/beads_mcp/config.py 51 2 96%
src/beads_mcp/models.py 92 1 99%
src/beads_mcp/server.py 58 16 72%
src/beads_mcp/tools.py 59 0 100%
------------------------------------------------
TOTAL 478 36 92%
```
Added a debug tool that reports:
- os.getcwd() value
- PWD environment variable
- BEADS_WORKING_DIR environment variable
- Other relevant environment variables
This will help diagnose where bd commands are running from and whether
Claude Code sets PWD or other variables correctly.
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>