Commit Graph

21 Commits

Author SHA1 Message Date
Steve Yegge
44179d7326 Fix bd-8zf2: MCP server auto-detects workspace from CWD
- Add _find_beads_db_in_tree() to walk up looking for .beads/*.db
- Update _get_client() to auto-detect when workspace not set
- Matches CLI behavior (no manual set_context needed after restart)
- Add 8 comprehensive tests for auto-detection
- Update existing tests to mock auto-detection in error cases

Fixes silent failures after Amp restart.

Amp-Thread-ID: https://ampcode.com/threads/T-c47f524d-c101-40d5-839a-659f52b9be48
Co-authored-by: Amp <amp@ampcode.com>
2025-11-07 23:59:57 -08:00
Steve Yegge
f6dbcd1a4f Add test safeguards to prevent production database pollution (bd-2c5a)
- Add failIfProductionDatabase() check in Go test helpers
- Add temp directory verification in RPC test setup
- Create conftest.py with pytest safety checks for Python tests
- Add BEADS_TEST_MODE env var to mark test execution
- Tests now fail fast if they detect production .beads/ usage

This prevents test issues from polluting the production database
like the incident on Nov 7, 2025 where 29+ test issues were created
in .beads/beads.db instead of isolated test databases.

Resolves: bd-2c5a
Amp-Thread-ID: https://ampcode.com/threads/T-635a8807-1120-4122-a0cb-4c21970362ce
Co-authored-by: Amp <amp@ampcode.com>
2025-11-07 21:58:22 -08:00
Steve Yegge
d97df21a65 Fix MCP server integration tests - add env variable propagation
- Fix BdCliClient._run_command() to pass BEADS_DIR/BEADS_DB env vars to subprocess
- Update temp_db fixture to create .beads in workspace and return .beads dir path
- Update mcp_client fixture to use beads_dir and enable BEADS_NO_DAEMON mode
- Simplify test_init_tool to work with connection pool architecture

Result: All 19 integration tests now pass (was 19 failing)
Amp-Thread-ID: https://ampcode.com/threads/T-c1da2a55-f086-4284-9c85-0dfa4c479cf9
Co-authored-by: Amp <amp@ampcode.com>
2025-11-07 19:27:22 -08:00
Steve Yegge
0e8936bf61 Fix test failures: update to new AddDependencyParams field names
- Update tests to use issue_id/depends_on_id instead of from_id/to_id
- Fix test_client_lazy_initialization to mock create_bd_client instead of BdClient
- Add workspace setup for lazy initialization test
- Fixes 2 test failures (now 123 passing, down from 121)

Amp-Thread-ID: https://ampcode.com/threads/T-71b3ce65-87cb-451a-a30d-162d76d92f9c
Co-authored-by: Amp <amp@ampcode.com>
2025-11-07 19:07:49 -08:00
Steve Yegge
d2920e3701 Remove cache_size from MCP docs and tests 2025-10-28 10:50:00 -07:00
Steve Yegge
744563e87f Add health checks and reconnection logic for stale daemon sockets (bd-137)
- Add ping() and health() methods to BdDaemonClient for connection verification
- Implement _health_check_client() to verify cached client connections
- Add _reconnect_client() with exponential backoff (0.1s, 0.2s, 0.4s, max 3 retries)
- Update _get_client() to health-check before returning cached clients
- Automatically detect and remove stale connections from pool
- Add comprehensive test suite with 14 tests covering all scenarios
- Handle daemon restarts, upgrades, and long-idle connections gracefully

Amp-Thread-ID: https://ampcode.com/threads/T-2366ef1b-389c-4293-8145-7613037c9dfa
Co-authored-by: Amp <amp@ampcode.com>
2025-10-25 17:39:21 -07:00
Steve Yegge
de03466da9 Fix bd-143: Prevent daemon auto-sync from wiping out issues.jsonl with empty database
- 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>
2025-10-25 16:36:18 -07:00
Steve Yegge
feac3f86e7 MCP: Smart routing for lifecycle status changes in update tool
- update(status="closed") now routes to close() tool
- update(status="open") now routes to reopen() tool
- Respects Claude Code approval workflows for lifecycle events
- Prevents bypass of approval settings
- bd CLI remains unopinionated; routing only in MCP layer
- Users can safely auto-approve benign updates without exposing closure bypass

Fixes #123

Amp-Thread-ID: https://ampcode.com/threads/T-8b85a68e-7e06-460e-9840-9c6b6a6b7e85
Co-authored-by: Amp <amp@ampcode.com>
2025-10-23 14:10:33 -07:00
Steve Yegge
4f1d1a2cca Fix MCP dep tool parameter names to match CLI (issue_id/depends_on_id)
- Changed from confusing from_id/to_id to clear issue_id/depends_on_id
- Matches CLI convention: bd dep add [issue-id] [depends-on-id]
- Updated all tests and implementations
- Fixes GH #113 where Claude Code was creating dependencies backwards

Closes bd-58

Amp-Thread-ID: https://ampcode.com/threads/T-f01aca11-a10f-4908-9ce6-7e1734f2068f
Co-authored-by: Amp <amp@ampcode.com>
2025-10-23 13:07:44 -07:00
Steve Yegge
10a313e3a6 Add integration tests for worktree workflow with separate databases
- Created test_worktree_separate_dbs.py with 6 comprehensive tests
- Verifies recommended workflow: one .beads database per worktree
- Tests confirm MCP works with BEADS_USE_DAEMON=0 in worktrees
- Validates database isolation, git syncing, and --no-daemon flag
- All tests passing

Addresses GH #119

Amp-Thread-ID: https://ampcode.com/threads/T-57d5c589-0522-4059-8183-2f0f7f1dccba
Co-authored-by: Amp <amp@ampcode.com>
2025-10-23 13:06:05 -07:00
Steve Yegge
42762188ed Fix MCP close tool method signature error (GH #107)
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).
2025-10-22 17:43:11 -07:00
Steve Yegge
5e0030d283 Add lifecycle management for beads-mcp processes (bd-148)
- 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>
2025-10-18 14:27:37 -07:00
Steve Yegge
b40de9bc41 Implement daemon RPC with per-request context routing (bd-115)
- 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
2025-10-17 16:28:29 -07:00
Baishampayan Ghose
32a718dacd feat(mcp): Add reopen command support for closed issues
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`.
2025-10-16 12:01:04 -07:00
Steve Yegge
691f90f833 Auto-fix remaining linting issues - remove unused imports 2025-10-15 11:45:11 -07:00
Steve Yegge
3347fd65ca Fix remaining linting issues - combine nested with statements 2025-10-15 11:44:59 -07:00
Baishampayan Ghose
4353592fe6 test(mcp): Fix two failing integration tests and linting errors
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%
```
2025-10-15 16:59:16 +05:30
Steve Yegge
061e8c4a27 feat(mcp): improve error messages for missing bd CLI
Add helpful installation instructions when bd CLI is not found,
making it clear that the CLI must be installed separately.

Changes:
- Add BdNotFoundError.installation_message() with clear install steps
- Update all BdNotFoundError raises to use new formatted message
- Improve config error message with installation instructions first
- Update tests to match new error message format

Error message now shows:
- Clear explanation that bd CLI is required
- Installation command with curl one-liner
- Link to GitHub installation docs
- Reminder to restart Claude Code after installation

Test results: 90/91 tests passing (1 unrelated path assertion)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-14 17:33:54 -07:00
Steve Yegge
ba8fdf1a8c fix: MCP init tool creates .beads in current directory
Critical bug: MCP init tool reported success but didn't create .beads
directory. It was using --db flag which tells bd to use an existing
database elsewhere instead of creating a new one.

Root cause:
- bd_client.init() was calling _global_flags() which adds --db flag
- bd init --db <path> uses existing db instead of creating new one
- Result: init appeared to succeed but created nothing

Fix:
- Remove _global_flags() from init command
- Only pass --actor flag (safe for init)
- Do NOT pass --db flag to init (defeats the purpose)
- Add explicit comment explaining why

Testing:
- Added test_init_creates_beads_directory() integration test
- Verifies .beads directory is created in current working directory
- Verifies database file has correct prefix
- All 91 tests pass

This was causing silent failures where agents thought they initialized
bd but the .beads directory was never created.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-14 16:47:29 -07:00
Steve Yegge
800ed300a6 fix: MCP server bd executable path resolution
Fixes issue where MCP tools failed with "bd executable not found"
when BEADS_PATH was set to command name instead of absolute path.

Changes:
- Remove BEADS_PATH=bd from plugin.json (use auto-detection)
- Enhance config validator to resolve command names via PATH
- Add comprehensive config validation tests (11 new tests)

The validator now accepts both:
  - Absolute paths: /usr/local/bin/bd
  - Command names: bd (resolved via shutil.which)

This makes the MCP server more robust and user-friendly while
maintaining backward compatibility.

All 90 tests pass.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-14 16:37:59 -07:00
Baishampayan Ghose
1b1380e6c3 feat: Add Beads MCP Server [bd-5]
Implements MCP server for beads issue tracker, exposing all bd CLI functionality to MCP clients like Claude Desktop.

Features:
- Complete bd command coverage (init, create, list, ready, show, update, close, dep, blocked, stats)
- Type-safe Pydantic models with validation
- Comprehensive test suite (unit + integration tests)
- Production-ready Python package structure
- Environment variable configuration support
- Quickstart resource (beads://quickstart)

Ready for PyPI publication after real-world testing.

Co-authored-by: ghoseb <baishampayan.ghose@gmail.com>
2025-10-14 11:13:52 -07:00