Skip to content
Back to skills

Tmb Recovery

ASecurity

Bro's response when something fails — an MCP tool returns is_error=true (halt + surface), the trajectory-server is unreachable (degraded sqlite3 readonly fallback), or the world model is unavailable (retry, identify the lock holder, reconnect the binding). Loaded reactively on the first failure of a session.

  • 6 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 21, 2026
ai-agentspythongobashsqlreactnodegitdatabase

Works with

  • claude code
  • mcp

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned October 21, 2026

npx -y skills add trustmybot/plugin --skill tmb_recovery --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Tmb Recovery?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Tmb Recovery
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/trustmybot-tmb-recovery/badge)](https://www.skillsdirectory.com/skills/trustmybot-tmb-recovery)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: tmb_recovery
description: Bro's response when something fails — an MCP tool returns is_error=true (halt + surface), the trajectory-server is unreachable (degraded sqlite3 readonly fallback), or the world model is unavailable (retry, identify the lock holder, reconnect the binding). Loaded reactively on the first failure of a session.
allowed-tools: Bash(${CLAUDE_PLUGIN_ROOT}/skills/tmb_recovery/scripts/bro-sqlite-readonly.sh:*), mcp__plugin_tmb_trajectory-server__discussion_append
---

# Recovery — three failure modes, three responses

Bro keeps the user-visible flow moving on recoverable errors. Each failure class has a deterministic fallback path; the judgment is *which class applies*.

The bundled script `${CLAUDE_PLUGIN_ROOT}/skills/tmb_recovery/scripts/bro-sqlite-readonly.sh` is for §B (trajectory-server unreachable). Invoke it via Bash — use it as a black box, not by reading its source directly.

## A. MCP tool returns is_error=true

When any MCP call result has `is_error: true` or content includes `{"error": ...}`, the call was wrong — not the doctrine.

### Protocol

1. **Halt the current flow immediately.** Treat the failed call as the chain's last.
2. **Pick one path** based on the error class:
   - **Surface verbatim** to the Human and ask how to proceed, OR
   - **If recoverable AND you know the corrected call**, append a note recording the error and the corrected retry, then retry.

### Error classification

| Error shape | Meaning | Right response |
|---|---|---|
| `forbidden` | Bro called a tool scoped to another role. | Reconsider whether the action is bro's responsibility. Change the call signature before retrying. |
| `validation` | Input didn't match the schema (e.g. malformed branch_id). | Fix the input. Retry with the corrected payload. |
| Constraint failure | DB integrity violation (foreign key, unique). | Surface to Human; usually means a stale or duplicate write attempt. |
| `no matching deferred tools` | The MCP child process is dead. | Switch to degraded mode (§B). |

## B. Trajectory-server unreachable

Two distinct sub-cases — read the `additionalContext` warning from `mcp-health-check.sh` at session start to tell which one you have.

### B.1 — MCP absent this session

The plugin's MCP server is missing from CC's resolved-plugin list — `/reload-plugins` and full quit + relaunch won't fix it because CC persists the cached config to disk.

<!-- LOAD-BEARING-SAFETY: halt-on-B.1 (MCP absent) is mandatory — state-writing tools are unreachable and silent degradation corrupts the audit trail -->
**During the failure, bro halts.** State-writing tools are unreachable; halt to avoid corrupting the audit trail. Read-only sqlite3 fallback (`${CLAUDE_PLUGIN_ROOT}/skills/tmb_recovery/scripts/bro-sqlite-readonly.sh`) is still available for emergency reads.

Recovery escalation — try IN ORDER, stop at the first that brings MCP back:

1. `/plugin uninstall tmb@<your-marketplace>`, quit CC fully, then reinstall from your marketplace via `/plugin install tmb@<your-marketplace>` — the marketplace-valid remedy (a standard install has only `~/.claude/plugins/cache/`, no plugin source on disk).
2. Dev-only: if you have the plugin source checked out, `claude --plugin-dir <plugin-source>` re-resolves the MCP config from disk with the plugin cache cleared.

### B.2 — MCP died mid-session

The MCP child process was alive at session start but is now gone — CC's plugin list is correct; the process just needs to be re-spawned. (`forbidden`/`validation`/`constraint` errors are §A, not this — they mean the server IS running and rejected bad input.)

**Read fallback:** `${CLAUDE_PLUGIN_ROOT}/skills/tmb_recovery/scripts/bro-sqlite-readonly.sh <tool_name> [json_args]`. Run `--list` to see supported tools. Parse stdout as JSON — same shape as the corresponding MCP tool. Write tools are refused with a structured error; surface the refusal to the Human.

**Recovery:**

1. Kill only THIS project's zombie server — identify it by the `trajectory.db` it holds open, never a machine-wide match that would take down every project's server:
   ```bash
   DB=$(${CLAUDE_PLUGIN_ROOT}/skills/tmb_recovery/scripts/bro-sqlite-readonly.sh --dry-run \
     | python3 -c 'import json,sys; print(json.load(sys.stdin)["db_path"])')
   PIDS=$(lsof -t "$DB" 2>/dev/null); [ -n "$PIDS" ] && kill $PIDS
   ```
2. Restart Claude Code — server re-spawns on fresh session.
3. If the first `mcp__plugin_tmb_*` call still fails, the failure has escalated into the MCP-absent case — follow B.1.

## C. World model unavailable

The graph store is temporarily unreadable — `world_model_get`/`world_model_search` return `warning: world-model-unavailable`, or `scan_run` returns `graph_db_open_failed`. Three moves restore access.

1. **Retry once.** The server re-attempts the graph open on each call, throttled to about one attempt every few seconds. A brief lock — another process opening the graph for a moment — clears on its own; pause, repeat the call, and it confirms.
2. **A persisting lock error names its holder.** Another live process holds the graph open. `lsof <project>/.claude/tmb/world-model.kuzu` lists the holder PIDs; `ps -o pid,ppid,command -p <pid>` traces each PID to its owning CC session. A live session's server legitimately owns the graph — let that session finish or close it, and this session's next call recovers on its own. (The SessionStart orphan scan surfaces the same holders as lock-conflicts.)
3. **A missing native binding** shows up right after a plugin upgrade: the error names a missing kuzu module rather than a lock. The SessionStart banner finishes the pending install on its own; once it reports done, reconnect the trajectory-server through `/mcp` (or quit and relaunch CC) so a fresh server process loads the binding.

**Pre-restart bind check** (when a restart's value is uncertain): from the installed plugin cache's `mcp/trajectory-server` dir, run

```bash
node -e "const kuzu=require('kuzu'); new kuzu.Database('<project>/.claude/tmb/world-model.kuzu'); console.log('bind ok')"
```

`bind ok` means a fresh server process will open the graph; a lock failure means a holder still lives — return to step 2.

Graph data survives all of these — recovery restores access, with no re-scan needed.

Files in this skill

  • SKILL.md6.2 KB
  • scripts/bro-sqlite-readonly.sh14.8 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.