mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-09-06 08:18:58 +00:00
## Summary
Adds a new `fabro_run_get` MCP tool that returns a run's summary,
resolved ID, projection, and pending questions without any mutation
capability. This separates read-only inspection from operational
control, allowing Ask Fabro sessions to inspect runs safely without
access to write operations.
## What changed and why
**New tool (`fabro-tool/src/get.rs`):** `FabroRunGetParams` /
`ValidatedRunGet` / `RunGetResult` follow the same
validation-and-dispatch pattern as other run tools. The implementation
resolves a selector, then fans out to three read-only API calls
(retrieve run, get state, list questions) and assembles them into a
single structured result.
**Tool registry and dispatch:** `FABRO_RUN_GET_TOOL_NAME` is exported
from `common.rs` and `lib.rs`, added to `TOOL_DEFINITIONS`, wired into
the MCP stdio server (`fabro-mcp-server/src/server.rs`), and dispatched
in the LLM agent executor (`fabro-workflow/src/handler/llm/api.rs`).
**Ask Fabro access policy (`fabro-server/.../sessions.rs`):** The
session now registers and allows only `fabro_run_events` +
`fabro_run_get` via the new `ASK_FABRO_RUN_TOOL_NAMES` constant.
`fabro_run_interact` is explicitly moved to the denied set, closing off
mutation from that session type. The policy match arm is refactored from
a hardcoded `|`-chain to a slice `contains` check so the constant is the
single source of truth.
**Docs:** `mcp.mdx` now lists `fabro_run_get` as the inspection tool and
redescribes `fabro_run_interact` as control-oriented.
**Backward compatibility:** `fabro_run_interact` (including `get` and
`get_questions` actions) is unchanged and still fully operational for
contexts that allow it.
### Plan Summary
- New `get.rs` module in `fabro-tool` with validation, async fetch, and
unit tests
- Constants + schema registration in `common.rs` / `lib.rs`
- MCP server and LLM dispatch branches added for
`FABRO_RUN_GET_TOOL_NAME`
- Ask Fabro session swaps `FABRO_RUN_INTERACT_TOOL_NAME` →
`FABRO_RUN_GET_TOOL_NAME` in registry and policy
- MCP integration tests: tool count constant, schema assertions, two new
end-to-end tests
(`mcp_get_resolves_selector_and_returns_summary_projection_and_questions`,
`mcp_get_rejects_blank_run_id_before_auth_or_network`)
- Public MCP docs updated
### Fabro Details
<details>
<summary>Ran 9 stages in 43m 30s for $13.42</summary>
| Stage | Duration | Cost | Retries |
|---|---|---|---|
| start | 0s | – | 0 |
| toolchain | 1s | – | 0 |
| preflight_compile | 2m 2s | – | 0 |
| preflight_lint | 2m 14s | – | 0 |
| implement | 19m 43s | $8.85 | 0 |
| simplify_opus | 5m 52s | $1.45 | 0 |
| simplify_gpt | 10m 16s | $3.12 | 0 |
| verify | 2m 53s | – | 0 |
| fmt | 3s | – | 0 |
| **Total** | **43m 30s** | **$13.42** | **0** |
</details>
<details>
<summary>Ran <code>ImplementPlan.fabro</code> (12 nodes and 15
edges)</summary>
```dot
digraph ImplementPlan {
graph [
goal="Implement and simplify",
model_stylesheet="
* { model: claude-opus-4-7; }
"
]
rankdir=LR
start [shape=Mdiamond, label="Start"]
exit [shape=Msquare, label="Exit"]
toolchain [label="Toolchain", shape=parallelogram, script="command -v cargo >/dev/null || { curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && sudo ln -sf $HOME/.cargo/bin/* /usr/local/bin/; }; cargo --version 2>&1", max_retries=0]
preflight_compile [label="Preflight Compile", shape=parallelogram, script="cargo check -q --workspace 2>&1", max_retries=0]
preflight_lint [label="Preflight Lint", shape=parallelogram, script="cargo +nightly-2026-04-14 clippy -q --workspace --all-targets -- -D warnings 2>&1", max_retries=0]
fix_lints [label="Fix Lints", prompt="The preflight lint step failed. Read the build output from context and fix all clippy lint warnings.", max_visits=3]
implement [label="Implement", prompt="Read the plan file referenced in the goal and implement every step. Make all the code changes described in the plan. Use red/green TDD."]
simplify_opus [label="Simplify (Opus)", prompt="@prompts/simplify.md"]
simplify_gpt [label="Simplify (GPT-55)", prompt="@prompts/simplify.md", model="gpt-55"]
verify [label="Verify", shape=parallelogram, script="cargo +nightly-2026-04-14 clippy -q --workspace --all-targets -- -D warnings 2>&1 && cargo nextest run --cargo-quiet --workspace --status-level fail 2>&1 && cargo dev docs refresh 2>&1 && cargo dev docs check 2>&1", goal_gate=true, retry_target="fixup"]
fixup [label="Fixup", prompt="The verify step failed. Read the build output from context and fix all clippy lint warnings, test failures, and generated docs errors.", max_visits=3]
fmt [label="Format", shape=parallelogram, script="cargo +nightly-2026-04-14 fmt --all 2>&1", max_retries=0]
start -> toolchain
toolchain -> preflight_compile [condition="outcome=succeeded"]
toolchain -> exit
preflight_compile -> preflight_lint [condition="outcome=succeeded"]
preflight_compile -> exit
preflight_lint -> implement [condition="outcome=succeeded"]
preflight_lint -> fix_lints
fix_lints -> preflight_lint
implement -> simplify_opus -> simplify_gpt -> verify
verify -> fmt [condition="outcome=succeeded"]
verify -> fixup
fixup -> verify
fmt -> exit
}
```
</details>
⚒️ Generated with [Fabro](https://fabro.sh)
---------
Co-authored-by: Fabro <noreply@fabro.sh>
|
||
|---|---|---|
| .. | ||
| hooks.mdx | ||
| mcp.mdx | ||
| outputs.mdx | ||
| permissions.mdx | ||
| prompts.mdx | ||
| skills.mdx | ||
| subagents.mdx | ||
| tools.mdx | ||