---
phase: 04-add-jq-and-yq-for-querying-large-json-and-yaml-files
plan: 1
type: execute
wave: 1
depends_on: []
files_modified:
  - src/fs_mcp/utils.py
  - src/fs_mcp/server.py
autonomous: true

must_haves:
  truths:
    - "Server detects jq availability at startup"
    - "Server detects yq availability at startup"
    - "Server continues running if jq or yq are missing"
    - "Platform-specific install instructions shown for missing tools"
  artifacts:
    - path: "src/fs_mcp/utils.py"
      provides: "jq and yq availability checks with platform-specific install guidance"
      exports: ["check_jq", "check_yq"]
      min_lines: 70
    - path: "src/fs_mcp/server.py"
      provides: "Global availability flags and startup initialization"
      contains: "IS_JQ_AVAILABLE"
      contains: "IS_YQ_AVAILABLE"
      min_lines: 20
  key_links:
    - from: "src/fs_mcp/server.py::initialize()"
      to: "src/fs_mcp/utils.py::check_jq()"
      via: "startup check"
      pattern: "check_jq\\(\\)"
    - from: "src/fs_mcp/server.py::initialize()"
      to: "src/fs_mcp/utils.py::check_yq()"
      via: "startup check"
      pattern: "check_yq\\(\\)"
---

<objective>
Add jq and yq dependency detection to fs-mcp server with graceful degradation when tools are missing.

Purpose: Enable structured data query tools (query_json, query_yaml) to check for CLI tool availability before execution, following the established ripgrep pattern.
Output: Startup checks for jq and yq with platform-specific install instructions; global availability flags for use by query tools.
</objective>

<execution_context>
@~/.config/opencode/get-shit-done/workflows/execute-plan.md
@~/.config/opencode/get-shit-done/templates/summary.md
</execution_context>

<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
@.planning/phases/04-add-jq-and-yq-for-querying-large-json-and-yaml-files/04-CONTEXT.md
@.planning/phases/04-add-jq-and-yq-for-querying-large-json-and-yaml-files/04-RESEARCH.md
@src/fs_mcp/utils.py
@src/fs_mcp/server.py
</context>

<tasks>

<task type="auto">
  <name>Task 1: Add jq and yq availability checks to utils.py</name>
  <files>src/fs_mcp/utils.py</files>
  <action>
Create check_jq() and check_yq() functions following the exact pattern established by check_ripgrep().

**For check_jq():**
- Use shutil.which('jq') to detect binary
- Return (True, "jq is installed.") if found
- If not found, provide platform-specific install commands:
  - Darwin: "brew install jq"
  - Windows: "choco install jq"
  - Linux (ubuntu/debian): "sudo apt-get install jq"
  - Linux (fedora/centos/rhel): "sudo dnf install jq"
  - Other: fallback message
- Warning message: "Warning: jq is not installed. The 'query_json' tool will be disabled. Please install it with: {install_cmd}"

**For check_yq():**
- Use shutil.which('yq') to detect binary
- Return (True, "yq is installed.") if found
- If not found, provide platform-specific install commands:
  - Darwin: "brew install yq"
  - Windows: "choco install yq"
  - Linux: Special handling - yq (mikefarah) not available in most repos, recommend: "Download from https://github.com/mikefarah/yq/releases or use 'brew install yq' if brew is available"
  - Other: fallback message
- Warning message: "Warning: yq is not installed. The 'query_yaml' tool will be disabled. Please install it with: {install_cmd}"

**Pattern to follow:** Identical structure to check_ripgrep() (lines 5-35 in utils.py).
  </action>
  <verify>
Run: python -c "from src.fs_mcp.utils import check_jq, check_yq; print(check_jq()); print(check_yq())"

Expected output format: (bool, str) tuples with appropriate messages.
  </verify>
  <done>
check_jq() and check_yq() functions exist in utils.py, return (bool, str) tuples, provide platform-specific install commands when tools are missing.
  </done>
</task>

<task type="auto">
  <name>Task 2: Initialize jq/yq availability checks in server.py</name>
  <files>src/fs_mcp/server.py</files>
  <action>
Update server.py to check for jq and yq at startup, following the ripgrep pattern.

**Add imports:**
- Add check_jq and check_yq to the import from .utils (line 28): `from .utils import check_ripgrep, check_jq, check_yq`

**Add global flags (after line 36):**
```python
IS_JQ_AVAILABLE = False
IS_YQ_AVAILABLE = False
```

**Update initialize() function (lines 41-48):**
- Add IS_JQ_AVAILABLE and IS_YQ_AVAILABLE to the global declaration (line 41)
- After the ripgrep check (lines 46-48), add:
```python
IS_JQ_AVAILABLE, jq_message = check_jq()
if not IS_JQ_AVAILABLE:
    print(jq_message)
    
IS_YQ_AVAILABLE, yq_message = check_yq()
if not IS_YQ_AVAILABLE:
    print(yq_message)
```

**Why this pattern:** Matches ripgrep's graceful degradation - server continues running with warnings, tools are disabled individually if dependencies are missing.
  </action>
  <verify>
Run: uvx fs-mcp (with jq/yq missing) and check startup output for warning messages.

Expected: Server starts successfully, prints warning messages for missing tools.
  </verify>
  <done>
Server initializes IS_JQ_AVAILABLE and IS_YQ_AVAILABLE flags at startup, prints platform-specific install instructions when tools are missing, continues running normally.
  </done>
</task>

</tasks>

<verification>
1. Check utils.py exports check_jq and check_yq functions
2. Check server.py has IS_JQ_AVAILABLE and IS_YQ_AVAILABLE globals
3. Run server startup with jq/yq missing - verify warning messages appear
4. Run server startup with jq/yq present - verify no warnings
5. Grep for pattern consistency: check_jq/check_yq follow same structure as check_ripgrep
</verification>

<success_criteria>
1. check_jq() and check_yq() functions exist in utils.py with platform-specific install guidance
2. Server.py declares IS_JQ_AVAILABLE and IS_YQ_AVAILABLE global flags
3. initialize() function checks both tools at startup and logs warnings if missing
4. Server continues running normally when jq or yq are missing (graceful degradation)
5. Warning messages match ripgrep pattern for consistency
</success_criteria>

<output>
After completion, create `.planning/phases/04-add-jq-and-yq-for-querying-large-json-and-yaml-files/04-01-SUMMARY.md`
</output>
