# SEF Tool Namespace Consolidation Plan

## The Problem

Your current `server.py` registers 60+ tools flat on a single FastMCP server. When Cursor
evaluates which tool to call, it scans the entire list on every turn. The model's attention
degrades past ~20 registered tools. Tools beyond that threshold get deprioritized silently.
That's the inconsistency. Not a bug. Attention budget exhaustion.

## The Fix: 8 Namespaced Tool Groups

Consolidate 60+ flat tools into 8 logical groups. Each group exposes 1-3 entry points.
The internal implementations stay exactly as they are. Only the registration surface changes.

---

## Namespace Map

### 1. `workflow.*` — Story Lifecycle (5 tools → 3)

**Current (5 tools):**
- `init_workflow`
- `get_workflow_state`
- `suggest_next_agent`
- `start_parallel_validation`
- `complete_parallel_task`

**Consolidated (3 tools):**

```python
@mcp.tool()
def workflow(action: str, story_id: str = "", **kwargs) -> str:
    """Workflow state machine. action: init | state | next | parallel_start | parallel_complete"""
    dispatch = {
        "init": workflow_tools.init_workflow,
        "state": workflow_tools.get_workflow_state,
        "next": workflow_tools.suggest_next_agent,
        "parallel_start": workflow_tools.start_parallel_validation,
        "parallel_complete": workflow_tools.complete_parallel_task,
    }
    ...
```

**Why:** The IDE picks one well-named tool reliably. It stops choosing between 5 near-identical names.

---

### 2. `agent.*` — Agent Activation (3 tools → 2)

**Current (3 tools):**
- `set_active_agent`
- `get_available_agents`
- `identify_agent`
- `check_agent_prerequisites`

**Consolidated (2 tools):**

```python
@mcp.tool()
def agent(action: str, name: str = "", context: str = "") -> str:
    """Agent control. action: list | activate | identify | check"""
    ...

@mcp.tool()
def set_project_root(path: str) -> str:
    """Set project root. Keep standalone — called once per session."""
    ...
```

**Why:** `set_project_root` stays solo because it's called at session start, not during agent dispatch.

---

### 3. `scan.*` — Analysis & Health (10 tools → 2)

**Current (10 tools):**
- `scan_health`
- `scan_debt`
- `scan_dead_code`
- `scan_complexity`
- `scan_external_dependencies`
- `scan_regression_risk`
- `validate_compliance`
- `validate_docs`
- `detect_ai_patterns`
- `run_security_audit`
- `scan_code_quality`

**Consolidated (2 tools):**

```python
@mcp.tool()
def scan(target: str, directory: str = "", files: str = "") -> str:
    """
    Codebase analysis. target:
      health       — full orchestrated health report (runs all scanners)
      debt         — technical debt registry
      dead_code    — unused code detection
      complexity   — cyclomatic + cognitive complexity
      external     — external API/env var detection
      regression   — high-risk change patterns
      compliance   — SEF quality standards
      docs         — documentation quality
      ai_patterns  — AI anti-pattern detection
      security     — full vulnerability audit
      code_quality — code quality issues
    """
    ...

@mcp.tool()
def generate_codemap(directory: str) -> str:
    """Generate CODE_MAP.md. Keep standalone — heavy operation, explicit intent."""
    ...
```

**Why:** `scan(target="health")` is unambiguous. The model doesn't have to choose between 10 scan variants.

---

### 4. `log.*` — Audit Trail (6 tools → 1)

**Current (6 tools):**
- `log_escalation`
- `log_ownership_transfer`
- `log_replan`
- `log_debt`
- `log_phase`
- `mark_artifact_complete`

**Consolidated (1 tool):**

```python
@mcp.tool()
def log(event: str, story_id: str = "", **kwargs) -> str:
    """
    Audit logging. event:
      escalation  — level, reason, to_agents
      ownership   — to_owner, reason
      replan      — trigger, impact
      debt        — debt_type, severity, location
      phase       — phase, outcome, next_phase
      artifact    — artifact name
    """
    dispatch = {
        "escalation": handoff_tools.log_escalation,
        "ownership": handoff_tools.log_ownership_transfer,
        "replan": handoff_tools.log_replan,
        "debt": handoff_tools.log_debt,
        "phase": handoff_tools.log_phase,
        "artifact": workflow_tools.mark_artifact_complete,
    }
    ...
```

**Why:** Every agent currently has to remember 6 logging tool names. One `log(event=...)` call removes
that cognitive load entirely. The model calls `log` reliably because it's always the right choice
for any state change.

---

### 5. `context.*` — Session & Graph (6 tools → 2)

**Current (6 tools):**
- `manage_context`
- `add_graph_node`
- `get_related_context`
- `get_causality_chain`
- `get_context_graph_data`
- `populate_context_graph`

**Consolidated (2 tools):**

```python
@mcp.tool()
def context(action: str, **kwargs) -> str:
    """
    Session context management. action:
      add | get | clear         — manage_context pass-through
      graph_add                 — add_graph_node
      graph_related             — get_related_context
      graph_chain               — get_causality_chain
      graph_data                — get_context_graph_data
      graph_populate            — populate_context_graph
    """
    ...

@mcp.tool()
def set_story_context(story_id: str, epic_id: str = "") -> str:
    """Set active story. Keep standalone — called explicitly at story start."""
    ...
```

---

### 6. `story.*` — Sequencing & Dependencies (4 tools → 1)

**Current (4 tools):**
- `generate_story_dependency_graph`
- `get_ready_stories`
- `get_critical_path`
- `get_sequencing_analysis`

**Consolidated (1 tool):**

```python
@mcp.tool()
def story(action: str, directory: str = "") -> str:
    """
    Story sequencing. action:
      dependencies — full dependency graph
      ready        — stories with satisfied dependencies
      critical_path — longest dependency chain
      analysis     — full sequencing report
    """
    ...
```

---

### 7. `browser.*` — Frontend Testing (4 tools → 1)

**Current (4 tools):**
- `execute_frontend_tests`
- `verify_test_evidence`
- `check_browser_tools`
- `write_conceptual_tests`

**Consolidated (1 tool):**

```python
@mcp.tool()
def browser(action: str, story_id: str = "", **kwargs) -> str:
    """
    Browser/E2E testing. action:
      check        — check Playwright MCP availability
      write_tests  — write conceptual test cases
      execute      — run frontend tests via Playwright
      verify       — verify test evidence (anti-hallucination)
    """
    ...
```

---

### 8. Keep Standalone (High-Signal, Explicit Tools)

These tools stay as individual registrations. Each has a clear, singular purpose that warrants
explicit naming. Collapsing them would reduce signal, not noise.

| Tool | Reason to Keep Standalone |
|---|---|
| `generate_codemap(directory)` | Heavy operation. Explicit user intent required. |
| `set_project_root(path)` | Called once per session. Needs to be findable immediately. |
| `set_story_context(story_id)` | Explicit story scoping. Always the first call. |
| `generate_project_summary(directory)` | Executive output. Standalone signals its weight. |
| `pattern(action, ...)` | Already parameterized correctly. Keep as-is. |
| `add_blocker / resolve_blocker` | Blocker management is critical-path. Needs prominence. |
| `request_debt_fix_approval` | HALT-triggering tool. Must never be buried. |
| `notify_background_agent` | Async coordination. Distinct enough to stay solo. |

---

## Implementation Approach

**Do NOT refactor the internal tool implementations.** All the Python logic in `tools/*.py`
stays untouched. The only change is in `server.py`: replace the flat `@mcp.tool()` registrations
with dispatcher functions that route via `action` parameter.

**Migration order:**
1. `log.*` first — lowest risk, highest consistency gain
2. `scan.*` second — removes the biggest tool-count problem
3. `workflow.*` third — most impactful for agent drift
4. `agent.*`, `context.*`, `story.*`, `browser.*` — follow in any order

**Backward compatibility:** Keep the old flat tool names registered but marked deprecated
with a redirect to the new namespaced calls. Remove after one release cycle.

---

## Expected Result

| Metric | Before | After |
|---|---|---|
| Registered tools | 60+ | ~18 |
| Model attention per tool | Degraded | Full |
| Cursor drift frequency | High | Low |
| New tool discoverability | Poor | High |
| PyPI install experience | Overwhelming | Clean |