Skip to main content
Glama

ask-fable: Multi-Model Reasoning MCP Server

ask-fable is a portable, installable MCP (Model Context Protocol) server for AI coding agents. It works in Claude Code, OpenCode, Kimi Code, Grok, Cursor, Codex, and any other harness that can spawn a local MCP server.

It gives those agents guarded code and architecture reasoning from Anthropic's Claude Fable (the newest claude-fable-*), Claude Opus 5 (claude-opus-5), MiniMax (MiniMax-M3), Gemini, Codex, GLM, DeepSeek, Grok, Kimi, Ollama Cloud models, and any model on your own LM Studio server. It can query one backend, synthesize a parallel council, run an ordered refinement chain, or stage a structured adversarial debate.

Fable and Opus 5 use Claude Code's existing OAuth session (through the Agent SDK, with the claude CLI as a fallback). MiniMax, Gemini, Codex, Grok, and local Ollama similarly reuse authenticated local CLIs. LM Studio is a LAN backend that needs no key: ask_model(provider="lmstudio") loads a model on demand with a real context window and does not evict a resident model. GLM, DeepSeek, and Atlas Cloud are optional HTTP backends that need server-side API keys.

Start here

If you need to…

Use

Ask one trusted coding model, with follow-up memory

ask (Fable; add oracle="opus" for Claude Opus)

Ask a cheap, fast Anthropic model (high-volume, single-turn)

ask_model(provider="sonnet") (Claude Sonnet 5)

Compare independent answers in parallel

ask_council

Draft, critique, then decide in order

ask_chain

Stress-test a high-impact decision

ask_debate

Check an answer you already have

ask_verify

Grind a claim down to what survives evidence

ask_falsify

Brainstorm an open question, models arguing to divergence

ask_conference

Select a task-matched Atlas Cloud model

list_models(provider="atlas") → ask_model(provider="atlas")

Atlas council with GPT-5.6 Sol adjudicating

ask_council(provider="atlas")

Ask a model on your LAN LM Studio server

ask_model(provider="lmstudio") (one model) / ask_council(provider="lmstudio") (local panel, Fable synthesizes)

Check the GPU or free a local model

host_status / unload_lms_model

Reuse large code context without pasting it again

context(op="write", …) + context_ref

Investigate a request after it ran

trace_list + trace_get

Start with ask for one hard question. Escalate to a council, chain, or debate only when the decision warrants the extra latency and cost.

Related MCP server: Claude Team MCP

What it gives you

ask-fable gives an MCP client six ways to reason:

Mode

What happens

Best for

Ask

One model answers directly; Fable can remember a session

Everyday debugging and design questions

Council

Several models answer in parallel; Fable reconciles them

Comparing independent opinions

Chain

Models work in order: draft → critique → decide

Deliberate refinement and cost-tiered escalation

Debate

A proposer and opponent test claims; Fable adjudicates

Contentious, hard-to-reverse decisions

Falsify

Claims are asserted, attacked, and resolved by a code clerk; the ledger persists across calls

Grinding a checkable claim down to what receipts actually support

Conference

Models argue together over rounds; a rapporteur maps the disagreement

Open-ended ideation

The same guard, context bus, cache, audit trail, and tracing layer wrap every mode. Backends are optional: use Fable alone, call a specific provider, or mix Fable, Opus 5, MiniMax, Gemini, Codex, Grok, GLM, DeepSeek, Kimi, Ollama, LM Studio, Atlas Cloud, and OpenRouter. Unavailable council members are reported and skipped instead of failing the whole request.

A real example — ask_debate, lazy token bucket vs. background refill task for a per-user rate limiter (resolution: adjudicated):

Use the lazy token bucket. Do not build the background refill task — the timer only approximates at tick granularity what the lazy design computes exactly.

The debate surfaced traps neither side opened with (a 100 req/min bucket permits ~199 requests in a worst-case rolling minute; TTL eviction alone doesn't bound memory) and closed with four ship-it fixes. More real calls, one per mode: docs/EXAMPLES.md.

The cheapest real second opinion is the twin token — the twin flames. It expands to both Anthropic reasoners at once, Fable + Claude Opus 5, and both ride the same OAuth session as ask, so a two-model cross-check costs you no provider keys and no extra setup:

ask_council(models=["twin"])        # or tier="twin" — the pair, in parallel
ask_chain(pipeline="m3 > twin")     # cheap draft, then fable → opus in turn

Five features make the result useful to an agent, not just readable by a human:

  • Structured sidecar — every answer carries a machine-readable sidecar ({recommendation: apply|investigate|reject|needs_more_context, confidence, needs_context}) next to the prose, so an agent acts on it directly. When the model needs more, a followup tells it exactly what to paste, and a per-session terminator stops an unbounded re-ask loop (status:"context_exhausted").

  • Context bus — context(op="write", …) a big codebase context ONCE under a key, then pass context_ref on any ask tool (or council) to pull it in instead of re-pasting. Shared by every agent on the server; context_read() lists what's stored and context_read(key=…) fetches a blob, while context's pack/delete ops round it out.

  • Council consensus — councils return a consensus signal (strong | partial | divergent | unknown) + material_disagreement computed from the panel's recommendations, each sources entry shows that model's recommendation, and the synthesis is anonymized (Expert A/B, Fable last) to blunt self-preference bias. The signal counts labs, not models: a panel that agreed but spans one training lineage (e.g. several Anthropic models) is downgraded from strong, and independent_labs reports how many distinct labs answered — same-lab models don't fail independently, so their agreement isn't independent evidence.

  • Correlated traces — every call includes a trace_id; inspect the ordered request timeline without storing raw prompts in the default safe mode.

  • Session hub — successful turns from local MCP instances are mirrored into a shared, visibility-only dashboard. Agents can use the same label to coordinate work without that shared history ever becoming model context.

How it works

A request enters through MCP, resolves any reusable context_ref, passes the guard, and is routed to the chosen reasoning mode. The result is normalized into an answer plus a machine-readable sidecar, persisted to the configured observability stores, and returned with a trace ID.

The project ships its own two-layer request gate: a size/sanity floor followed by a prohibited-use denylist. Fable's model prompt adds the final semantic scope contract. See The guard for the exact behavior.

The guard

Every question is checked before any model call:

  1. Sanity floor — rejects only empty / too-short (<3 chars) / too-long (>65536 chars) questions. Context is unbounded by default (any cap you set is floored to 512,000 chars). Breadth is allowed.

  2. Prohibited-use denylist — ask-fable's bundled offensive-security and biology dual-use patterns. It scans the question and context (the context scan is on by default; ASK_FABLE_GUARD_SCAN_CONTEXT=0 restricts it to the question) — the provider's own safeguard reads the whole payload, so a block is caught locally and deterministically instead of upstream. Extend it via ASK_FABLE_DENYLIST_FILE (one term per line). Benign multi-word phrases (e.g. request payload) are neutralized before matching so an ambiguous word like payload used in an ordinary engineering sense doesn't false-trip; add your own via ASK_FABLE_ALLOWLIST_FILE (one phrase per line). This only rescues the exact benign phrase — a bare prohibited term still rejects. Legitimate security-engineering work passes trusted=true (operator-authorized via ASK_FABLE_ALLOW_TRUSTED) to run the denylist log-only.

  3. Model scope contract — Fable answers engineering questions, including conceptual/brainstorming ones with no code context (breadth is fine), and replies REFUSED: <reason> only when the question itself directly asks for offensive-security work (exploit development, attack tooling) or non-software domain knowledge (e.g. biology). Questions about security-related code are normal engineering.

Every decision is appended to an owner-only JSONL audit log (question hashed by default; ASK_FABLE_AUDIT_RAW=1 to store raw).

Quick start

1. Install

New here? The setup & usage guide walks through install, registering in Claude Code (OpenCode, Kimi Code, Grok, and other MCP clients use the same server — see below), setting up every backend (API keys, Ollama Cloud, MiniMax/Gemini CLIs), /mcp verification, and how to use every tool.

Want the big picture? The visual architecture map charts the whole server end to end — the request pipeline, the oracle bridges, council/chain orchestration, and on-disk state.

# not on PyPI yet — install from source:
pip install -e .
# or with pipx:
pipx install .

Requires the Claude Code CLI to be installed and logged in (that's the OAuth session Fable is reached through).

2. Register in your coding harness

ask-fable is a local stdio MCP server (ask-fable on PATH). Point any MCP-capable coding harness at it; only the config-file shape changes. Restart the harness after editing — most load MCP servers once at startup. All 40 ask_fable tools then become available. They are grouped into reasoning modes, direct provider calls, context management, configuration, and observability; see the tool guide for the short chooser or CLAUDE.md for the complete one-line inventory.

Claude Code — ~/.claude/.claude.json

Add to ~/.claude/.claude.json (root-owned — edit as the owner, e.g. via sudo):

{
  "mcpServers": {
    "ask_fable": { "command": "ask-fable" }
  }
}

(or "command": "python3", "args": ["-m", "ask_fable"]).

OpenCode — ~/.config/opencode/opencode.json

The docs/OPENCODE.md guide covers the full setup — the exact schema-valid MCP block, optional API keys, the restart-to-load behavior, and troubleshooting. Minimal registration:

{
  "mcp": {
    "ask_fable": {
      "type": "local",
      "command": ["ask-fable"],
      "enabled": true
    }
  }
}

Kimi Code — ~/.kimi-code/mcp.json

{
  "mcpServers": {
    "ask_fable": {
      "transport": "stdio",
      "command": "ask-fable",
      "toolTimeoutMs": 600000
    }
  }
}

Kimi Code's default MCP request timeout is ~60s; oracle calls often run longer. toolTimeoutMs keeps the host from aborting a still-running call. A Request timed out error from the client is that transport timeout, not a refusal — check trace_list before re-asking.

Grok — ~/.grok/config.toml

[mcp_servers.ask_fable]
command = "ask-fable"
enabled = true

Cursor, Codex, and other MCP clients take the same ask-fable command; only the config file shape differs.

3. Ask a question

In your MCP client, call ask with a focused question and the relevant code or error. Reuse the same session key for follow-ups:

{
  "question": "Why does this cache invalidate too early?",
  "context": "<relevant code and failing test output>",
  "session": "cache-investigation"
}

Tool guide

The server exposes 28 MCP tools, but you only need seven entry points — ask, ask_council, ask_chain, ask_debate, ask_verify, ask_falsify, and ask_conference. Everything else selects a specific backend, manages reusable context, or inspects what ran.

Goal

Start with

Escalate when

Solve or debug one problem

ask (Fable; oracle="opus" for Claude Opus 5 — ~half the price, faster)

use context_ref for large reusable context

Get one alternate opinion

ask_model(provider=…) — minimax/deepseek/glm (cheap direct APIs first), gemini/codex/grok/kimi (local CLIs), ollama/atlas/ali/openrouter (gateways, pass model), lmstudio (LAN LM Studio)

use a council when you need comparison

Research a live-web / OSINT question

ask_websearch (opt-in — the one tool that browses; model=grok default, or gemini / a Claude model)

set ASK_FABLE_ALLOW_WEBSEARCH=1 to enable it

Pick an Atlas model for a task

list_models(provider="atlas", task="…")

call ask_model(provider="atlas", …) with the accepted selection or rendered picker

Cross-check with a second strong model

ask_council(models=["twin"]) — Fable + Opus 5 on one OAuth session, no keys

add a third voice with models=["twin","m3"]

Compare several views

ask_council

use ask_chain when order matters

Cross-check Atlas models, GPT adjudicating

ask_council(provider="atlas")

pin the panel with configure_council(provider="atlas")

Cross-check your local LM Studio models

ask_council(provider="lmstudio")

pin the panel with lmstudio_council / ASK_FABLE_LMSTUDIO_COUNCIL

Make a contentious decision

ask_debate

keep the scope narrow; it is the most expensive mode

Check a draft answer before acting on it

ask_verify

pass the draft as answer and its source material as context; read verify.prevented, not the prose

Prove a claim before acting on it

ask_falsify

pack the corpus it must cite; reuse the same session to compound evidence

Brainstorm an open question

ask_conference

raise rounds (default 3, up to 10) when a dilemma needs more back-and-forth

Inspect what happened

trace_list then trace_get

enable full mode only when redacted content is needed

Full reference: docs/TOOLS.md — every tool, its arguments, and when to reach for it. A one-line inventory of all 27 lives in CLAUDE.md.

Observability & response shape

Every answer carries a machine-readable sidecar ({recommendation, confidence, needs_context}) and a trace_id; councils add a consensus signal and debates a deterministic resolution. Results are cached, progress streams to the console, and all persisted state lives under a per-user state dir with owner-only permissions.

Details: docs/OBSERVABILITY.md — the full response contract, caching, console progress, and backend setup.

Configuration

Everything is optional environment variables set in the server's env block, with sensible defaults.

Reference: docs/CONFIGURATION.md — every setting grouped by backend, guard, storage, and observability.

The server injects a short standing instruction so agents reach for these tools unprompted. But weak local models under-attend to system prompts, so for the best results also drop a decision ladder into your project's CLAUDE.md / AGENTS.md / opencode.md (agents re-read those). Copy this block:

## Using ask_fable (external reasoning)
Reach for the ask_fable MCP tools on the hard 5% — cheapest option first:

1. **Answer it yourself** for trivial, low-blast-radius, or already-in-context work.
2. **Double-strike rule:** the moment you've failed the SAME bug/error twice, STOP
   and call `ask` before a third guess. Include what you tried and the exact error.
3. **`ask`** (single Fable, multi-turn) for a real design trade-off, a subtle bug
   hypothesis, "am I reasoning about X right?", or a change spanning >2–3 files.
   Reuse the `session` key for follow-ups on the same problem.
4. **`ask_council`** only for a contentious or hard-to-reverse decision
   (architecture, concurrency, data model, public API, migration). One council
   call per problem, max. Check `quorum`/`degraded` and `consensus` in the result —
   a `1/N` answer (or a `divergent` panel) is not agreement. Reach for **`ask_chain`**
   instead when you want *ordered* refinement rather than a parallel vote — e.g. a
   cheap model drafts and Fable finalizes, or draft → red-team → decide.
5. **Reuse context:** for a big codebase context you'll ask about repeatedly,
   `context(op="write", …)` it once and pass `context_ref=<key>` — don't re-paste each time.
6. **Recommend it, don't just skip it:** if one of these tools would clearly help
   but you're not calling it, say so in one line — which tool and why — so the
   operator can opt in.

Frame questions tightly: paste the real code + real error (don't paraphrase), state
ONE specific decision (ideally A-vs-B), and the constraints. Act on the result's
`sidecar.recommendation`; if you get a `followup`, paste exactly what it names (but
check `likely_already_pasted` and re-read your own paste first) and re-ask on the same
`session`. If tests or a linter can verify the answer, run them instead of asking again.

Companion skills

skills/ ships four skills that drive these tools from Claude Code, OpenCode, Grok, Kimi Code, and other skill-capable harnesses (copy or symlink into ~/.claude/skills/, ~/.agents/skills/, or the harness equivalent):

  • ubercode — treat Fable (and, via ask_council, MiniMax-M3) as a smarter reasoning partner for the hard 5%: oracle escalation when you're stuck, and cross-checked adversarial review before a high-consequence diff.

  • uberplan — fan out N diverse candidate plans locally, use Fable as a comparative judge (optionally cross-checked with ask_council), then synthesize one final plan.

  • uberarch — open-ended architectural ideation: fan abstract ideas out to the oracles (ask_council / ask_chain) for multi-model trade-off analysis before any code exists.

  • uberbrainstorm — design-first, approval-gated brainstorming for the fuzzy front end ("what should we build and why"), with the council red-teaming the chosen design; hands off to uberplan.

Development

uv sync --extra dev           # or: uv pip install -e '.[dev]'
uv run pytest -q              # 841 tests, no network needed
uv run ruff check src tests

salient-core (a richer prohibited-use denylist) is unpublished and therefore not declared as an extra; the guard picks it up automatically at runtime if it is installed in the environment.

Documentation

License

MIT

Available Tools

28 tools
askA

YOUR DEFAULT MOVE on anything non-trivial — use it liberally and early, don't wait to be told and don't wait until you're stuck. Reach for it BEFORE you guess at unfamiliar code, an API, or a library's behavior; whenever you weigh a design or refactor trade-off; when a bug isn't fully understood; or to have a strong reasoner sanity-check a plan or diff before you commit it. One well-framed ask with the code attached beats several bare ones. Set oracle="opus" for this same tool on Claude Opus (newest) — cheaper and faster; use it for high-volume or long back-and-forth work and keep the default Fable for the hardest calls. Ask the selected model to reason about the SOFTWARE/ENGINEERING work you're doing: code structure, functionality, data/control flow, module and function relationships, routing, architecture, and design trade-offs. For questions about EXISTING code, ALWAYS paste the real code into context — the actual function/file/snippet the question is about, plus any error or failing test. The model has NO tools and CANNOT open files, so a bare file path is useless to it. Conceptual/brainstorming questions need no context and are welcome. Frame each call as ONE specific decision ('should X or Y given constraint Z' beats 'thoughts on this code?') or ONE generative prompt ('give me 5 approaches to X, with trade-offs'). Reuse the session key to think through a problem over several follow-up turns instead of restating everything. Answers usually take 1–3 minutes. Broad and conceptual engineering questions — including brainstorming and ideas for future code — are fine. Refused only when the question itself directly asks for offensive-security work (exploit development, attack tooling) or non-software domain knowledge (biology/medicine refused; neuroscience, cognitive science, AI/ML, and CS are in-scope); questions about security-related code are normal engineering. The result carries a sidecar ({recommendation, confidence, needs_context}); when the model needs more, it returns a followup telling you exactly what to paste — paste those (or context_write them and pass context_ref) and re-ask on the SAME session, but first check followup.likely_already_pasted and RE-READ your own paste rather than resending it. A context_exhausted status means the model still can't answer after repeated tries — stop re-asking and use your own judgment.

ParametersJSON Schema
NameRequiredDescriptionDefault
resetNoDump+clear this session before asking, starting a fresh conversation.
oracleNoWhich multi-turn model answers: 'fable' (default) or the Opus family — 'opus' tracks the newest Claude Opus, and 'opus5'/'opus55'/'opus48' name the same Opus session. Opus is roughly half Fable's price and faster, so prefer it for high-volume or long back-and-forth work. For a single-turn model use `ask_model(provider=…)`.fable
contextNoOptional code snippets, file paths, or structural context.
sessionNoConversation key. Reuse it to ask follow-ups (the model keeps context); use a new key or reset=true to start a fresh topic. Fable and Opus sessions are namespaced separately, so the same key on each is two independent conversations.default
trustedNoOperator-authorized. When true, the prohibited-use denylist runs in log-only mode: security vocabulary in the question AND in `context` is audited but does not block. Use for legitimate security-engineering work (PoC analysis, CVE research, binary hardening review) where the ask genuinely needs security terms. Takes effect ONLY when the operator has set ASK_FABLE_ALLOW_TRUSTED (env or config); otherwise the flag is ignored and the denylist still applies.
questionYesA specific question about concrete software code/architecture (structure, functionality, data flow, module/function relationships, routing).
context_refNoKey(s) of context previously saved with `context(op="write", …)` to pull in and prepend to `context` — so you paste a big codebase context ONCE and reference it by key across many asks instead of re-pasting. Missing keys are reported, not fatal.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations are sparse (openWorldHint=true, readOnlyHint=false, destructiveHint=false, idempotentHint=false), so the description carries the full burden and delivers. It discloses latency (1–3 minutes), refusal criteria, the sidecar return shape, the followup mechanism, context_exhausted status, session-keeping behavior, and the trusted flag's denylist semantics — far more than annotations provide. No contradiction with the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness2/5

Is the description appropriately sized, front-loaded, and free of redundancy?

This is a single unbroken paragraph of roughly 350 words with no sectioning, headers, or scannable structure. While the tool's complexity justifies length, the format forces an agent to parse a dense block of prose to find the key instructions. It is under-structured rather than genuinely concise.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool this complex — 7 parameters, session semantics, sidecar/followup return behavior, refusal rules, and a security flag — the description is exceptionally complete. It even explains return values (sidecar, followup, context_exhausted) in the absence of an output schema, so nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, which sets a baseline of 3, but the description adds substantial meaning beyond the schema: it explains oracle value selection, instructs that context must contain real pasted code (since the model cannot open files), elaborates the session reuse semantics, details the context_ref workflow, and clarifies when the trusted flag actually takes effect. This materially helps the agent invoke parameters correctly.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies this as a tool that asks an LLM (Fable/Opus) to reason about software/engineering work, and it distinguishes itself from the sibling ask_model by explicitly noting 'For a single-turn model use `ask_model(provider=…)`.' However, the purpose statement is buried deep in a wall of text rather than stated up front, which slightly dulls its clarity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

This is the description's strongest dimension. It gives explicit when-to-use guidance ('YOUR DEFAULT MOVE on anything non-trivial — use it liberally and early'), when-not-to-use guidance (refused content categories), and names concrete alternatives: ask_model for single-turn and the oracle/Opus variants for high-volume work. It even tells the agent what framing works ('should X or Y given constraint Z') versus what fails.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ask_chainA

DIRECTIONAL, SEQUENTIAL — the relay counterpart to ask_council. Where the council asks N models the SAME question in parallel and synthesizes their independent answers ('what's true?'), the chain threads a question through an ORDERED pipeline where each stage refines the last ('make this answer better'). The operator sets the order as a pipeline string like 'm3 > glm > deepseek > fable' (or an ordered models array). Stage 1 drafts; each middle stage is told to solve independently and CRITIQUE the prior draft before extending it (an anti-anchoring guard); the final stage DECIDES, seeing all prior stages as anonymized peers. Best for two things a council can't do: cost-tiered escalation (a cheap/fast model does the legwork, Fable finalizes) and explicit draft → red-team → decide pipelines. Costs MORE latency than a council (stages run sequentially, not in parallel), so reserve it for when the ordered refinement is the point. Draft → critique → refine is also a natural IDEATION pipeline: a cheap model brainstorms broadly, later stages prune and sharpen the ideas. Order matters and repeats are allowed ('fable > glm > fable' = draft, critique, re-decide). A mid-chain model that refuses/errors is skipped (recorded); if the final stage fails, Fable synthesizes the survivors. The result carries a recommendation_drift trail and material_drift flag — the chain analogue of the council's consensus signal — so you can see whether the answer was refined or just rubber-stamped. Same scope as ask: broad and conceptual engineering questions (including brainstorming) are fine; direct offensive-security asks and non-software domain knowledge (biology/medicine refused; neuroscience, cognitive science, AI/ML, and CS are in-scope) are refused. Aliases: 'm3' = minimax, 'opus5' = opus. Any stage can be 'opus' (Claude Opus 5) — a cheaper, faster terminus than Fable, e.g. 'm3 > opus'. The group token 'twin' (aka 'twin flames') expands in place to two stages, fable then opus, so 'm3 > twin' is a cheap draft finished by both Anthropic reasoners in turn. Default pipeline if none given: minimax > fable.

ParametersJSON Schema
NameRequiredDescriptionDefault
modelsNoThe ordered pipeline as an array (alternative to `pipeline`), e.g. ['minimax','glm','fable']. Order-sensitive; duplicates allowed.
contextNoOptional code snippets, file paths, or structural context (seen by every stage).
sessionNoOptional coordination key for the cross-agent hub (`session_list` / `session_peek`). Reuse the same key across agents working the same decision so turns group together. Defaults to the tool name (`ask_council` / `ask_chain` / `ask_debate` / …) when omitted.
trustedNoOperator-authorized. When true, the prohibited-use denylist runs in log-only mode: security vocabulary in the question AND in `context` is audited but does not block. Use for legitimate security-engineering work (PoC analysis, CVE research, binary hardening review) where the ask genuinely needs security terms. Takes effect ONLY when the operator has set ASK_FABLE_ALLOW_TRUSTED (env or config); otherwise the flag is ignored and the denylist still applies.
pipelineNoThe ordered pipeline as a string, e.g. 'm3 > glm > deepseek > fable'. Split on '>'. Order matters and repeats are allowed. Aliases: 'm3' = minimax. The group token 'twin' (aka 'twin flames') expands in place to two stages, fable then opus — positionally, so a member you also name elsewhere in the pipeline runs twice (repeats are legitimate here and are not collapsed). Ignored when `models` is given.
questionYesA specific software/engineering question to thread through the pipeline.
context_refNoKey(s) of context saved with `context(op="write", …)` to pull in and prepend to `context`.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only say readOnlyHint=false, openWorldHint=true, idempotentHint=false, destructiveHint=false. The description adds substantial behavioral context beyond annotations: stages run sequentially, each middle stage critiques prior draft, final stage decides, mid-chain failures are skipped and recorded, final-stage failure falls back to Fable synthesizing survivors, and the result carries recommendation_drift and material_drift signals. It also discloses the trusted flag behavior and denylist scope. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but information-dense; every sentence adds a distinct fact about behavior, usage, or scope. It is front-loaded with the core directional/sequential concept and the sibling contrast. It could be tightened slightly (e.g., the ideation note and the twin expansion are somewhat redundant with the pipeline semantics), but the length is justified by the tool's complexity and the absence of an output schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex tool with 7 parameters, no output schema, and no enums, the description covers the pipeline mechanics, failure handling, result signals, scope boundaries, aliases, defaults, and the trusted flag's activation condition. An agent has everything needed to decide whether to call it and how to construct a valid pipeline. The only minor gap is that the description doesn't detail the exact shape of the recommendation_drift trail, but that is a return-value detail and no output schema exists; the description at least names the signal.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds meaning beyond the schema: it explains the pipeline string syntax with aliases ('m3' = minimax, 'opus5' = opus), the 'twin' group token expansion, the default pipeline (minimax > fable), and the relationship between pipeline and models (pipeline ignored when models is given). It also clarifies that repeats are allowed and order matters, which the schema mentions but the description enriches with examples. Slight deduction because the description doesn't add much about context/session/trusted beyond what the schema already says, but the pipeline semantics are genuinely enriched.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'DIRECTIONAL, SEQUENTIAL — the relay counterpart to ask_council' and immediately distinguishes the chain from the council: ordered pipeline vs parallel synthesis. It states the specific verb (threads a question through an ordered pipeline) and resource (a chain of models), and names the sibling it is not. An agent can tell it apart from ask_council, ask_debate, and ask without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says when to use the chain over a council: 'Best for two things a council can't do: cost-tiered escalation... and explicit draft → red-team → decide pipelines.' It also gives a negative condition: 'Costs MORE latency than a council... so reserve it for when the ordered refinement is the point.' It names the alternative (ask_council) and the scope boundary (same scope as ask, with refused domains listed). This is explicit when/when-not guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ask_conferenceA

DIVERGENT, MULTI-ROUND — a brainstorming CONFERENCE where several models argue a topic TOGETHER over rounds, each reading the running transcript and building on (or pushing back against) what came before, then a rapporteur writes the MAP OF THE DISAGREEMENT (converged / the crux / what would change it). Unlike ask_council (models answer in isolation, then reconcile) the participants actually hear each other, so positions can move — use it for open-ended ideation and design exploration ('what should we build', 'ways to approach X'), where you want genuine divergence rather than one averaged answer. Pick the bench with models (from ['fable','opus','deepseek','minimax','glm','gemini','codex','grok','kimi'] plus any 'atlas:' / 'openrouter:' / 'ollama:' token); default is the available subset of fable/opus/deepseek/minimax/glm. rounds is 1–10 (default 3) and synthesizer writes the closing map (default 'fable'). When called with no models and the MCP client supports form elicitation, a NATIVE model picker pops up to choose the roster and topic (set interactive: false to skip it). Costs one model call per participant per round plus the synthesis, so it is heavier than a council — keep the bench and rounds modest. Same scope as ask: conceptual software/engineering ideation is in scope; direct offensive-security asks and non-software domains are refused. Aliases: 'm3' = minimax, 'gpt' = codex, 'opus5' = opus.

ParametersJSON Schema
NameRequiredDescriptionDefault
modelsNoThe debater bench (2 or more). From ['fable','opus','deepseek','minimax','glm','gemini','codex','grok','kimi'] plus any 'ollama:<model>' / 'atlas:<id>' / 'openrouter:<id>' token. Omit to be offered a native picker (when the client supports elicitation), else it falls back to the available subset of fable/opus/deepseek/minimax/glm.
roundsNoHow many rounds of turns each participant takes (default 3, up to 10).
contextNoOptional code snippets, file paths, or structural context (shared by all participants).
sessionNoOptional coordination key for the cross-agent hub (`session_list` / `session_peek`). Reuse the same key across agents working the same decision so turns group together. Defaults to the tool name (`ask_council` / `ask_chain` / `ask_debate` / …) when omitted.
trustedNoOperator-authorized. When true, the prohibited-use denylist runs in log-only mode: security vocabulary in the question AND in `context` is audited but does not block. Use for legitimate security-engineering work (PoC analysis, CVE research, binary hardening review) where the ask genuinely needs security terms. Takes effect ONLY when the operator has set ASK_FABLE_ALLOW_TRUSTED (env or config); otherwise the flag is ignored and the denylist still applies.
questionNoThe topic or open question for the models to brainstorm and argue together.
context_refNoKey(s) of context saved with `context(op="write", …)` to pull in and prepend to `context` — paste a big context ONCE, reference it by key here. Missing keys are reported, not fatal.
interactiveNoWhen true and `models` is omitted, pop a native model picker if the MCP client supports form elicitation. Set false to skip it.
synthesizerNoModel that writes the closing map of the disagreement (default 'fable'; 'opus', 'codex', …).fable
attack_premiseNoAfter the blind round, name the premise every opening assumed and assign one participant to argue it is FALSE (two extra calls). This is the challenge nobody else will make, since agreeing on the premise is what lets the rest of the discussion happen. Needs 3+ seats and 2+ rounds; skipped otherwise.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=false, idempotentHint=false, destructiveHint=false, openWorldHint=true. The description adds meaningful behavioral context: cost ('one model call per participant per round plus the synthesis'), interactive picker behavior, the `attack_premise` mechanics (two extra calls, requires 3+ seats and 2+ rounds), and alias handling. It does not contradict annotations and provides transparency beyond the schema flags.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but densely informative, front-loading the core concept and differentiation. Every sentence serves a purpose: definition, contrast, usage, parameters, cost, scope, aliases. It is not padded; the length is justified by the tool's complexity. It could be slightly tighter, but it remains efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 10-parameter tool with no output schema, the description covers most critical aspects: usage, parameters, costs, scope, aliases, and interactive behavior. It hints at the output format (MAP OF THE DISAGREEMENT) but does not fully describe its structure. It also lacks explicit error or fallback behaviors, but overall it is thorough enough for an agent to invoke correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds value: it explains default bench behavior, alias mapping, the `attack_premise` preconditions, and the `interactive` picker interaction. It also clarifies that `context_ref` pulls pre-saved context and that missing keys are non-fatal. These details go beyond the schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'DIVERGENT, MULTI-ROUND — a brainstorming CONFERENCE where several models argue a topic TOGETHER over rounds' and clearly states the output (a MAP OF THE DISAGREEMENT). It explicitly differentiates from `ask_council` by contrasting the interaction model. The verb is specific ('conduct a conference'), the resource is the models, and it is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states when to use it ('use it for open-ended ideation and design exploration') and contrasts it with `ask_council` ('models answer in isolation, then reconcile'). It also gives scope boundaries ('conceptual software/engineering ideation is in scope; direct offensive-security asks and non-software domains are refused'). This gives clear selection criteria.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ask_councilA

DIRECTIONAL — reserve this for a genuinely contentious or HARD-TO-REVERSE decision (architecture, concurrency, data model, public API, migration) where a single opinion isn't enough and you want several models cross-checked, or for divergent brainstorming where you want independent idea sets merged without losing distinct options. It's slower and heavier than ask, so DON'T reach for it on routine questions — default to ask, and use at most one council call per problem. Check quorum/degraded in the result: a 1-of-N answer is one opinion, not consensus. Ask several models at once the same SOFTWARE/ENGINEERING question, then get back one answer that Fable synthesizes by reconciling all of them (each raw answer is also returned under sources). By default asks Fable (whichever id is newest) + MiniMax (MiniMax-M3), plus DeepSeek (deepseek-flash) when ASK_FABLE_DEEPSEEK_API_KEY is configured — cheap direct models are preferred and consulted first. Pass models to choose from ['fable','fable51','opus','deepseek','minimax','glm','gemini','codex','grok','kimi'] ('fable' tracks the newest Fable automatically and 'fable51' pins claude-fable-5-1 even after it stops being newest — they are the same model today, so naming both buys you nothing; 'opus' is the newest Claude Opus on the same OAuth session as Fable — always available, half the price; 'gemini'/'codex'/'grok'/'kimi' need their local CLIs; 'glm'/'deepseek' need API keys configured on the server). You can also add Ollama Cloud models as 'ollama:' tokens (e.g. 'ollama:qwen3-coder:480b-cloud', 'ollama:nemotron-3-ultra:cloud'); these are reached via a local signed-in ollama daemon by default (reported+skipped if unreachable). The group token 'twin' (aka 'twin flames') expands to BOTH Anthropic reasoners at once — fable + opus — so models=['twin'] is a dual Fable/Opus invocation and models=['twin','minimax'] adds a third voice to it. Both ride the OAuth session, so it needs no provider keys and is the cheapest real second opinion available. Instead of listing models, you can pass a named tier: 'default' (fable+minimax, +deepseek when its key is configured), 'twin' (the twin flames, fable+opus), 'middle' (all of the above +opus+glm+gemini+codex+grok+kimi, cheap models first), or 'full' (+the configured Ollama Cloud models). Instead of models/tier, pass provider ('ollama', 'atlas', 'openrouter', or 'lmstudio') to scope the council to ONE gateway: its configured panel is used by default, its members are that provider's tokens, its adjudicator ladder applies (GPT-first for atlas/openrouter), and 'lmstudio' runs the panel one model at a time (a single GPU). An explicit models is honored within the chosen provider; tier is ignored when provider is set. The result carries a consensus signal ('strong' | 'partial' | 'divergent' | 'unknown') and material_disagreement computed from the panelists' recommendations, and each entry in sources shows that model's recommendation — so you can see WHO endorsed what, not just the merged answer. Panel answers are anonymized to the synthesizer to blunt self-preference bias. Pass synthesizer to have a different model adjudicate the panel (default 'fable'; e.g. 'opus' = newest Claude Opus, 'codex'/'gpt' = GPT-5.6 Sol via the local CLI, or 'atlas:openai/gpt-5.6-sol') — it falls back to Fable when unavailable or failing, and the result's synthesis block reports what actually ran. Same scope as ask: broad and conceptual engineering questions (including brainstorming) are fine; direct offensive-security asks and non-software domain knowledge (biology/medicine refused; neuroscience, cognitive science, AI/ML, and CS are in-scope) are refused.

ParametersJSON Schema
NameRequiredDescriptionDefault
tierNoNamed council preset (used when `models` is omitted): 'default' = fable+minimax, +deepseek when its API key is configured; 'twin' = the twin flames, fable+opus — a dual Fable/Opus 5 invocation needing no provider keys at all; 'middle' = +opus+glm+gemini+codex+grok+kimi (cheap models first); 'full' = +the configured Ollama Cloud models (ASK_FABLE_OLLAMA_COUNCIL).default
modelsNoExplicit list of models to ask, from ['fable','opus','deepseek','minimax','glm','gemini','codex','grok','kimi'] (aliases: 'm3' = minimax, 'gpt' = codex, 'xai' = grok, 'opus5' = opus), plus any 'ollama:<model>' cloud token (e.g. 'ollama:kimi-k2.7-code:cloud') or 'atlas:<model-id>' token (e.g. 'atlas:zai-org/glm-5.2'). One entry may be the group token 'twin' (aka 'twin flames'), which expands to BOTH Anthropic reasoners — fable + opus — on the one OAuth session, so ['twin'] is a dual Fable/Opus 5 invocation and ['twin','minimax'] adds a third voice to it. Overrides `tier` when given. 'glm'/'deepseek', 'ollama:*' and 'atlas:*' require API keys configured on the server; unconfigured ones are reported and skipped, not fatal.
contextNoOptional code snippets, file paths, or structural context (shared by all models).
sessionNoOptional coordination key for the cross-agent hub (`session_list` / `session_peek`). Reuse the same key across agents working the same decision so turns group together. Defaults to the tool name (`ask_council` / `ask_chain` / `ask_debate` / …) when omitted.
trustedNoOperator-authorized. When true, the prohibited-use denylist runs in log-only mode: security vocabulary in the question AND in `context` is audited but does not block. Use for legitimate security-engineering work (PoC analysis, CVE research, binary hardening review) where the ask genuinely needs security terms. Takes effect ONLY when the operator has set ASK_FABLE_ALLOW_TRUSTED (env or config); otherwise the flag is ignored and the denylist still applies.
providerNoScope the council to ONE gateway: the default panel comes from that provider's configured set (for atlas/openrouter, else a live-catalog shortlist), members are its tokens, and the adjudicator follows that provider's ladder (GPT-first for atlas/openrouter; Fable otherwise). `lmstudio` runs the panel ONE AT A TIME (a single GPU serves one model at a time). An explicit `models` is honored within the chosen provider; `tier` is ignored when `provider` is set. Omit for a mixed council selected by `models`/`tier`.
questionYesA specific software/engineering question to ask the selected models; Fable then synthesizes their answers into one.
context_refNoKey(s) of context saved with `context(op="write", …)` to pull in and prepend to `context` — paste a big context ONCE, reference it by key here. Missing keys are reported, not fatal.
synthesizerNoModel that reconciles the panel answers into one (default 'fable'). Any council token works: 'opus' (Claude Opus 5 — cheaper and faster than Fable), 'codex' (alias 'gpt', GPT-5.6 Sol via the local CLI), 'atlas:openai/gpt-5.6-sol', 'ollama:<model>', … It may also be a panel member — its own answer is anonymized and read last. If it is unavailable or fails, synthesis falls back to Fable (see `synthesis` in the result).

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations provide only minimal safety flags, so the description carries the full burden, and it delivers: it discloses slowness, one-of-N caveats, result signals (`consensus`, `material_disagreement`, `sources`), anonymization of panel answers, synthesizer fallback, provider-specific behavior, and trusted-mode semantics. No contradiction with the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is accurate and dense but extremely long and formatted as a single wall of text, which hurts scannability. It front-loads the key usage directive, but it repeats details already present in the schema descriptions (e.g., twin expansion, tier defaults) and would benefit from bullets or section breaks.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description compensates well by explaining what the result contains: `consensus`, `material_disagreement`, `sources` with per-model `recommendation`, and a `synthesis` block. It also covers availability, refusal scope, fallback behavior, and configuration-dependent behavior, so the agent has what it needs to call and interpret the tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description goes far beyond field names: it explains the `twin` group token expansion, `tier` meaning relative to `models`, provider-scoped council behavior, synthesizer fallback, and unconfigured-model skipping. This is substantial meaning that the schema alone does not convey.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action: ask several models the same software/engineering question and get one Fable-synthesized answer. It distinguishes itself from `ask` by framing itself for contentious or hard-to-reverse decisions, so an agent can tell siblings apart without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is explicitly conditioned: use for hard-to-reverse decisions, divergent brainstorming, or multi-model cross-checking; do NOT use for routine questions, defaulting to `ask`. It even limits to at most one council call per problem and tells the agent to check `quorum`/`degraded`, which is actionable routing guidance beyond any schema field.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ask_debateA

DIRECTIONAL, ADVERSARIAL — pit two models AGAINST each other over a structured claims ledger, then have a fresh third model adjudicate. Unlike ask_council (N models vote independently) or ask_chain (each stage refines the last), the debate makes one model PROPOSE a position decomposed into load-bearing claims, the other REFUTE each claim (concede or contest-with-a-concrete-failure-scenario), the proposer REVISE under fire, and an anonymized adjudicator RULE on the merits. Reserve it for a genuinely contentious, hard-to-reverse SOFTWARE decision where you want the strongest case for AND against stress-tested — 'is this concurrency design sound', 'should we commit to approach X or Y' — not for questions with a clear answer. Pick the pair with proposer and opponent (e.g. proposer='fable', opponent='codex' for Fable vs GPT-5.6 Sol, or opponent='glm'); defaults to fable vs minimax. adjudicator picks who rules (default 'fable'; e.g. 'opus' for Claude Opus 5, or 'codex') — keep it off the debating pair so the ruling stays third-party. rounds is 1 (default) or 2 (adds a rebuttal pass). The server decides the outcome deterministically from the ledger — resolution is 'conceded' (opponent conceded everything), 'converged' (all contests resolved and both sides agree), 'adjudicated' (the adjudicator decided), or 'stalemate' (both dug in with nothing new → confidence is mechanically downgraded). Costs up to four sequential model calls, so it's the most expensive mode — use it sparingly. Degrades to a single-critic pass when the opponent is unconfigured. Same scope as ask: broad and conceptual engineering questions are fine; direct offensive-security asks and non-software domain knowledge (biology/medicine refused; neuroscience, cognitive science, AI/ML, and CS are in-scope) are refused. Aliases: 'm3' = minimax, 'gpt' = codex, 'opus5' = opus.

ParametersJSON Schema
NameRequiredDescriptionDefault
roundsNo1 (propose→refute→revise, default) or 2 (adds a rebuttal pass before adjudication).
contextNoOptional code snippets, file paths, or structural context (seen by both sides).
sessionNoOptional coordination key for the cross-agent hub (`session_list` / `session_peek`). Reuse the same key across agents working the same decision so turns group together. Defaults to the tool name (`ask_council` / `ask_chain` / `ask_debate` / …) when omitted.
trustedNoOperator-authorized. When true, the prohibited-use denylist runs in log-only mode: security vocabulary in the question AND in `context` is audited but does not block. Use for legitimate security-engineering work (PoC analysis, CVE research, binary hardening review) where the ask genuinely needs security terms. Takes effect ONLY when the operator has set ASK_FABLE_ALLOW_TRUSTED (env or config); otherwise the flag is ignored and the denylist still applies.
opponentNoModel that refutes it (default 'minimax'). Try 'codex' (GPT-5.6 Sol) or 'glm'.minimax
proposerNoModel that proposes the position (default 'fable'). Aliases: 'm3'=minimax, 'gpt'=codex.fable
questionYesA contentious, hard-to-reverse software/engineering decision to debate (e.g. 'is this concurrency design sound?', 'approach X or Y?').
adjudicatorNoModel that rules on the contested claims (default 'fable'; 'opus' for Claude Opus 5, 'codex' for GPT-5.6 Sol, …). It sees the ledger anonymized. Any council token works; keep it off the debating pair so the ruling stays third-party.fable
context_refNoKey(s) of context saved with `context(op="write", …)` to pull in and prepend to `context`.

TDQS

A5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations, the description discloses the adversarial flow, deterministic ledger-based outcome with specific resolution values, degradation to a single-critic pass, and the cost of up to four sequential model calls. None of this contradicts the annotations, and it adds meaningful operational context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but dense and every sentence earns its place: mechanism first, then differentiation, usage, parameter guidance, cost, scope, and aliases. It is front-loaded with the core concept and avoids filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex multi-model tool with no output schema, the description is thorough: it explains mechanism, outcome resolution values, cost, failure/degradation behavior, scope exclusions, and parameter configuration. An agent has enough to decide when to invoke it and how to configure it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Although schema coverage is 100%, the description adds real parameter semantics: examples for proposer/opponent, aliases, the default fable-vs-minimax pairing, the requirement to keep the adjudicator off the debating pair, and the meaning of rounds. This goes well beyond the schema's field names and defaults.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific mechanism: pit two models against each other over a claims ledger, then have a third adjudicate. It explicitly contrasts with ask_council and ask_chain, making the tool's identity and unique role unambiguous even before opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives clear when-to-use guidance ('genuinely contentious, hard-to-reverse SOFTWARE decision') and explicit when-not-to ('not for questions with a clear answer'). It also names alternatives, notes cost ('most expensive mode... use it sparingly'), and states scope limits such as refused offensive-security and non-software domain questions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ask_fable_helpA
Read-onlyIdempotent

FREE, local and instant — no model call, no cost, no network. Returns the part of this server's manual that does NOT fit in the standing instructions (harnesses truncate those at ~2 KB). Call it when: a call came back status:"refused" (topic refused — reframe, never resend the same question); you're about to re-paste context you already sent (topic context — the shared bus, paste once and reference by key); you're configuring an Ollama / Atlas / OpenRouter council (topic setup); or you want the full tool menu with the model tokens usable in councils, chains and debates (topic tools). all returns everything. Cheap enough to call speculatively — prefer it over guessing at an argument.

ParametersJSON Schema
NameRequiredDescriptionDefault
topicNoWhich part of the manual to return. `refused`: what to do with a status:"refused" result (reframe, never resend). `context`: the shared context bus — paste once, reference by key. `setup`: configuring Ollama/Atlas/OpenRouter councils. `tools`: the full tool menu and the model tokens usable in councils/chains/debates. Defaults to `all`.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnly/idempotent/non-destructive, and the description adds substantial context beyond them: it is free, local, instant, with no model call, no cost, and no network. It also discloses the behavioral constraint that harnesses truncate standing instructions at ~2 KB, explaining why the tool exists and what portion it returns.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the key value proposition (free, local, instant) before the topic guidance. It is dense and slightly long, but each clause maps to a usable decision cue; minor redundancy between description and schema topic list keeps it from a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-param, no-output-schema help tool, the description fully explains what is returned per topic and when to call it. Nothing an agent needs to invoke it correctly is missing, and the lack of an output schema is compensated by the per-topic content description.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the enum already documents each topic, so the baseline is 3. The description adds real semantic value beyond the schema by attaching behavior to topics, e.g. for 'refused' it says 'reframe, never resend the same question' and for 'context' it explains the paste-once-by-key model, which the schema only gestures at.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: it returns the portion of this server's manual that does not fit in the standing instructions. This clearly distinguishes it from the ask_* siblings (which make model calls) and the context_* siblings (which manage the shared bus). An agent can tell exactly what this does without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit 'Call it when:' block enumerates four concrete trigger scenarios (refused status, re-pasting context, configuring councils, wanting the tool menu) and maps each to a topic value. It also guides speculative use ('cheap enough to call speculatively — prefer it over guessing at an argument'), which is direct when-to-use guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ask_falsifyA

STATEFUL, ADVERSARIAL — a persistent falsification ledger, the process cousin of ask_debate. An assertor states typed claims; a falsifier (forced to a DIFFERENT lab) attacks them; and a deterministic CODE clerk — not a model — decides commit/kill/survive from receipts it verifies mechanically: a cite quote's VERBATIM presence in context, or a contra edge to a survived claim. A claim may speak, but it cannot compound (move reputation, count as consensus, survive) without a verified receipt — a fabricated or absent quote dies. State PERSISTS across calls under the REQUIRED session key, so a killed claim stays dead and calling again continues the same ledger. Use it to grind a contentious, CHECKABLE question down to what actually survives evidence rather than what sounds convincing — and pack the corpus the claims must cite into context/context_ref. Pick the pair with assertor (default 'minimax') and falsifier (default 'opus'); they must resolve to different labs. rounds is 1-6 assert->attack cycles per call (default 1). Returns the ledger's survived/killed/open/crucible split plus per-model reputation. Same scope as ask; offensive-security asks and non-software domains are refused. Receipts are cite and contra; with the operator opt-in ASK_FABLE_ALLOW_RUN=1 (and bwrap installed), a run: receipt executes a sandboxed Python snippet instead. metamorph: true adds a cold-restatement stability check. Aliases: 'm3' = minimax, 'gpt' = codex, 'opus5' = opus.

ParametersJSON Schema
NameRequiredDescriptionDefault
roundsNoAssert->attack cycles to run this call (default 1). Call again with the same `session` to advance the persisted ledger further.
contextNoThe corpus the claims must cite — code, specs, docs. `cite` receipts are checked for VERBATIM presence here.
sessionYesREQUIRED — the ledger's persistence key. Reuse it to continue the same falsification (a killed claim stays dead); a new key starts fresh.
trustedNoOperator-authorized. When true, the prohibited-use denylist runs in log-only mode: security vocabulary in the question AND in `context` is audited but does not block. Use for legitimate security-engineering work (PoC analysis, CVE research, binary hardening review) where the ask genuinely needs security terms. Takes effect ONLY when the operator has set ASK_FABLE_ALLOW_TRUSTED (env or config); otherwise the flag is ignored and the denylist still applies.
assertorNoModel that asserts claims (default 'minimax'). Aliases: 'm3'=minimax, 'gpt'=codex.minimax
questionYesA contentious, CHECKABLE software/engineering claim or question to grind down to what survives evidence (e.g. 'is this API idempotent as documented?').
falsifierNoModel that attacks the claims (default 'opus'). Must resolve to a DIFFERENT lab than the assertor — a model must not grade its own family.opus
metamorphNoAlso run a metamorphic stability check on unsupported claims: restate a claim (semantics-preserving) and re-ask the assertor COLD — a claim that flips is unstable and cannot compound; a stable one earns WEAK support (the only way a claim survives with no corpus to cite and no code to run). Costs 2 extra model calls per unsupported claim; stability is not truth, so stable-but-unverified survivors are reported separately as `stable_unverified`.
context_refNoKey(s) of context saved with `context(op="write", …)` to pull in and prepend to `context`.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Describes non-obvious behavior: state persists across calls under the required `session` key, a killed claim stays dead, and a deterministic CODE clerk rather than a model decides outcomes. It also discloses the sandboxed code-execution path, the `trusted` flag's env-var dependency, and the metamorphic stability check — far beyond what annotations provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long and dense, covering many behaviors, but it is front-loaded with the core adversarial-ledger concept and organized from mechanics to usage to advanced options. Some redundancy with schema parameter descriptions exists, yet most sentences earn their place given the tool's complexity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description still specifies the return shape: 'survived/killed/open/crucible split plus per-model reputation.' It also covers security refusal, state persistence, model-lab constraints, sandbox execution, and advanced flags, making the tool fully understandable without external references.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Although schema coverage is 100%, the description adds substantial meaning: assertor/falsifier must resolve to different labs, aliases like 'm3'=minimax, `context` must contain the corpus for verbatim receipt checking, `rounds` semantics, and `metamorph` costs extra model calls and yields `stable_unverified`. This is rich, non-redundant parameter context.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'a persistent falsification ledger' where an assertor states claims and a falsifier attacks them. It distinguishes itself from siblings by explicitly naming ask_debate as its 'process cousin' and declaring 'Same scope as ask'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Clear when-to-use guidance is given: 'Use it to grind a contentious, CHECKABLE question down to what actually survives evidence.' It also states exclusions (offensive-security asks and non-software domains are refused) and names ask_debate as a relative. However, it does not fully articulate when a sibling like ask_debate should be preferred over this tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ask_modelA

Ask ONE model — on its own, independent of Fable — to reason about the SOFTWARE/ENGINEERING work you're doing: code structure, functionality, data/control flow, module and function relationships, routing, architecture, and design trade-offs. provider selects the backend; model overrides the model where the backend accepts one. This one tool replaces the per-backend tools: 'minimax' (MiniMax-M3), 'glm', 'deepseek' (cheap direct APIs — prefer these for a quick independent opinion), 'sonnet', 'gemini', 'codex' (GPT-5.6 Sol), 'grok', 'kimi' (local CLIs), and the gateways 'ollama', 'lmstudio', 'atlas', 'ali' (Alibaba/Qwen reasoning), 'openrouter'. Aliases: m3=minimax, gpt=codex, xai=grok. The direct providers have a fixed model and reject model; pass model for a CLI override (grok/kimi) or a gateway (ollama/lmstudio/atlas/ali/openrouter) — call list_models(provider=...) first for the gateway catalogues. Single-turn: for a multi-turn thread use ask (multi-turn; oracle="opus" for Claude Opus). Broad and conceptual engineering questions (including brainstorming/ideas for future code) are fine — add a snippet or file path in context when the question is about existing code. Direct offensive-security asks (exploit development, attack tooling) and non-software domain knowledge (biology/medicine refused; neuroscience, cognitive science, AI/ML, and CS are in-scope) are refused. Prefer a dedicated local CLI over a gateway for the same model. Use ask_council to ask several models and get a synthesized answer.

ParametersJSON Schema
NameRequiredDescriptionDefault
modelNoModel id for a provider that accepts one: a CLI override (grok, kimi) or a gateway model (ollama, lmstudio, atlas, ali, openrouter). Rejected for the fixed-model providers (sonnet, minimax, glm, deepseek, gemini, codex). Omit to use the server default; call `list_models(provider=…)` for a gateway catalogue.
effortNoAnswer budget / reasoning depth, honored by atlas, openrouter, grok and kimi; ignored by the other providers (atlas/openrouter default to 'deep').
contextNoOptional code snippets, file paths, or structural context.
trustedNoOperator-authorized. When true, the prohibited-use denylist runs in log-only mode: security vocabulary in the question AND in `context` is audited but does not block. Use for legitimate security-engineering work (PoC analysis, CVE research, binary hardening review) where the ask genuinely needs security terms. Takes effect ONLY when the operator has set ASK_FABLE_ALLOW_TRUSTED (env or config); otherwise the flag is ignored and the denylist still applies.
providerYesWhich backend answers. Cheap direct APIs (fixed model, no `model`): 'minimax' (MiniMax-M3), 'deepseek', 'glm'. Local CLIs: 'gemini', 'codex' (GPT-5.6 Sol), 'grok', 'kimi'. OAuth: 'sonnet'. Gateways / CLI overrides (pass `model`): 'ollama', 'lmstudio', 'atlas', 'ali' (Alibaba/Qwen), 'openrouter'. Aliases: m3=minimax, gpt=codex, xai=grok.
questionYesA specific software/engineering question to ask ONE model on its own — guarded, single-turn. `provider` selects the backend; `model` overrides the model where the backend accepts one.
context_refNoKey(s) of context saved with `context(op="write", …)` to pull in and prepend to `context`. Missing keys are reported, not fatal.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=false, destructiveHint=false, openWorldHint=true, idempotentHint=false — a moderate safety profile. The description adds substantial context beyond this: the tool is single-turn, direct providers reject `model`, the `trusted` flag runs the denylist in log-only mode only when ASK_FABLE_ALLOW_TRUSTED is set, and content refusals (offensive security, non-software domains) are disclosed. This is rich behavioral disclosure that annotations alone do not carry.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Long, but the length is earned — the tool has 7 parameters, 19 provider enum values, and multiple behavioral modes. The core purpose is front-loaded in the first sentence, and every subsequent sentence carries a distinct routing, alias, or safety fact. Slightly dense but appropriately so for the complexity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 7-parameter, 2-required tool with no output schema, the description is very complete: it covers providers, aliases, model override rules, effort semantics, context usage, multi-turn alternatives, and refusal behavior. The only minor gap is the absence of a described return/error shape, which is somewhat mitigated by the absence of an output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds real value on top: it classifies each provider into categories (cheap direct, local CLI, OAuth, gateway), gives the alias mapping (m3=minimax, gpt=codex, xai=grok), states which providers reject `model`, and specifies which providers honor `effort`. This is beyond what the schema enumerates, though the schema already documents each parameter competently.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a precise statement of what the tool does — 'Ask ONE model — on its own, independent of Fable — to reason about the SOFTWARE/ENGINEERING work you're doing' — and enumerates the exact reasoning domains (code structure, data/control flow, routing, architecture). It also names the sibling tools it is not (ask_council, ask) and the per-backend tools it replaces. No ambiguity about verb, resource, or scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit and exhaustive. It states when to prefer cheap direct APIs, when to pass `model` vs omit it, when to call list_models first, when to use ask_council (several models, synthesized answer), when to use ask (multi-turn with oracle='opus'), and when to use a dedicated local CLI over a gateway. It even lists refusal domains. Nothing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ask_verifyReview a draft answerA

Review a draft answer that ALREADY EXISTS — yours, another model's, or another tool's — and get back the objections a reviewer could actually SHOW, separated from the ones it could only argue.

This is the only mode that takes a finished answer as input. Every other mode reasons from scratch: ask_council fans a question out, ask_debate grows its own position, ask_falsify asserts its own claims. Reach for this when you have an answer in hand and the cost of it being wrong is high.

HOW TO READ THE RESULT. verify.prevented counts objections whose receipt code could check against your context or against a check that failed — those are the only ones that establish anything. verify.unbacked_objections counts argument without evidence: weigh it as opinion. A self-quoting verdict means every objection quoted the draft back at itself, which proves only that the reviewer read it — supply real source material in context and re-run.

WHAT IT DOES NOT DO. It never withholds or rewrites your draft; answer comes back unchanged on every path, including when the reviewer fails. And no objections is NOT a correctness guarantee — it means no fault was demonstrated, not that none exists.

Pass context (the source material a citation may quote) or the review can only produce opinion. Pass drafted_by to refuse a same-lab review. Costs one model call.

ParametersJSON Schema
NameRequiredDescriptionDefault
answerYesREQUIRED — the draft answer to review, as produced by another model, another tool, or you. It is returned unchanged; ask_verify never withholds or rewrites it.
contextNoThe SOURCE MATERIAL a `cite` receipt may quote — code, specs, docs. This is deliberately everything EXCEPT the draft: quoting the draft back at itself proves nothing, so without source material no citation is possible and the review can only produce opinion.
sessionNoOptional coordination key for the cross-agent hub (`session_list` / `session_peek`). Reuse the same key across agents working the same decision so turns group together. Defaults to the tool name (`ask_council` / `ask_chain` / `ask_debate` / …) when omitted.
trustedNoOperator-authorized. When true, the prohibited-use denylist runs in log-only mode: security vocabulary in the question AND in `context` is audited but does not block. Use for legitimate security-engineering work (PoC analysis, CVE research, binary hardening review) where the ask genuinely needs security terms. Takes effect ONLY when the operator has set ASK_FABLE_ALLOW_TRUSTED (env or config); otherwise the flag is ignored and the denylist still applies.
questionYesThe question the draft answer was written for — what it was supposed to answer.
reviewerNoModel that reviews the draft (default 'opus'). Aliases: 'm3'=minimax, 'gpt'=codex.opus
drafted_byNoOptional — the model that WROTE the draft. When given, a same-lab review is refused: a family grading its own homework agrees with itself for reasons unrelated to the draft being right.
context_refNoKey(s) of context saved with `context(op="write", …)` to pull in and prepend to `context`.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations are thin (readOnlyHint false, openWorldHint true, idempotentHint false, destructiveHint false), so the prose carries the burden and it delivers. It discloses that the draft is never withheld or rewritten and comes back unchanged even on failure, that 'no objections' is not a correctness guarantee, that same-lab reviews are refused when drafted_by is set, and that it costs one model call. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but tightly organized with a front-loaded mode definition followed by clear 'HOW TO READ THE RESULT' and 'WHAT IT DOES NOT DO' sections. For a tool with 8 parameters and no output schema, every block earns its place and nothing reads as filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description properly takes on explaining result semantics: verify.prevented, verify.unbacked_objections, self-quoting verdict, the unchanged answer, and the no-guarantee caveat. It also covers the operational requirements (context, drafted_by) and cost, leaving no critical decision information to inference.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and each parameter already has rich descriptions, so the baseline is 3. The prose mostly restates what the schema says about context, drafted_by, and answer rather than adding new parameter-level meaning. The genuinely new content (prevented vs unbacked_objections, one-call cost) is output/cost semantics rather than parameter semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource ('Review a draft answer that ALREADY EXISTS...') and states the tool returns objections a reviewer could show versus only argue. It explicitly distinguishes itself from siblings by saying 'This is the only mode that takes a finished answer as input' and contrasting ask_council, ask_debate, and ask_falsify.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It says exactly when to use it ('Reach for this when you have an answer in hand and the cost of it being wrong is high'), names the alternatives, and explains why they differ. It also gives explicit preconditions: pass context or the review only produces opinion, and pass drafted_by to refuse a same-lab review.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ask_websearchA

OPT-IN web-search / OSINT research agent. Unlike every other ask_* tool (which is toolless and cannot browse), this one runs a model WITH live web search to research a question and return a sourced, cited answer — use it for current/'latest' facts, version/pricing/release lookups, who/what-is research, and open-source intelligence gathering. Pick the model with model: grok (grok-4.6 live search, the default — strong for current events, via the local grok CLI), a Claude model on your OAuth session — sonnet (claude-sonnet-5), opus48 (claude-opus-4-8), opus5, or fable — using native WebSearch/WebFetch, or gemini via the local agy CLI. All run on flat-plan sources (no per-token billing). Put any code/artifact the research is ABOUT in context. Returns a findings summary followed by a Sources: list. DISABLED by default: the operator must set ASK_FABLE_ALLOW_WEBSEARCH=1 (returns {"status":"disabled",...} otherwise). On grok and Claude the search-only boundary is a real tool gate; gemini is search-only for a different reason — agy's own headless permission policy denies page fetch, shell and file tools, and a denial aborts the turn, so that backend is told to use search_web only (use grok or a Claude model when the task needs page content). Requires the grok or agy CLI (for those models) or the Claude OAuth session (for the Claude models). Refuses tasks whose aim is genuinely harmful (attack development, de-anonymizing or surveilling a private individual); legitimate research on software, companies, CVEs, and public events is answered.

ParametersJSON Schema
NameRequiredDescriptionDefault
modelNoWhich search-capable model runs the research. `grok` (grok-4.6 live search) is the default; `sonnet` / `opus48` / `opus5` / `fable` use Claude native WebSearch over the OAuth session; `gemini` uses the local `agy` CLI and is SEARCH-ONLY — agy's headless policy denies page fetch/shell/file tools and a denial aborts the turn, so that backend is told to use search_web only. Omit to use the ASK_FABLE_WEBSEARCH_MODEL default (grok).
contextNoOptional code, artifact, URL, or entity the research is ABOUT (e.g. a library, error text, CVE id, or organization).
trustedNoOperator-authorized. When true, the prohibited-use denylist runs in log-only mode: security vocabulary in the question AND in `context` is audited but does not block. Use for legitimate security-engineering work (PoC analysis, CVE research, binary hardening review) where the ask genuinely needs security terms. Takes effect ONLY when the operator has set ASK_FABLE_ALLOW_TRUSTED (env or config); otherwise the flag is ignored and the denylist still applies.
questionYesA web-search / OSINT research task — a question to research on the LIVE web (current facts, versions/pricing/releases, who/what-is, open-source intel).
context_refNoKey(s) of context saved with `context(op="write", …)` to pull in and prepend to `context` — paste a big context ONCE, reference it by key here. Missing keys are reported, not fatal.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses substantial behavioral traits beyond the annotations: the tool is disabled by default and returns a status object unless ASK_FABLE_ALLOW_WEBSEARCH=1 is set; gemini is search-only due to agy's headless policy and a denial aborts the turn; the result format is a findings summary plus Sources list; and harmful tasks are refused. While annotations declare readOnlyHint=false and openWorldHint=true, the description adds the operational constraints and side-effect nuances that an agent needs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense and front-loaded with the core purpose, and every sentence carries useful information. However, it is a single long run-on paragraph with many parenthetical asides and some redundancy (e.g., gemini's search-only nature is explained both in the description and schema), which slightly hurts parseability. It earns high marks for content but not for concise structure.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity — multiple backends, an opt-in configuration, CLI/OAuth requirements, and a refusal policy — the description covers all operational aspects an agent needs: prerequisites, model-specific behaviors, output format, disabled behavior, and safety restrictions. No output schema exists, but the description explicitly states the return shape, which is sufficient.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Although schema coverage is 100%, the description enriches parameter meaning substantially. It explains which model is the default (grok), why gemini is search-only (agy policy denies page fetch and aborts on denial), how `context` is meant to hold the artifact being researched, and when `trusted` is honored (log-only denylist only when ASK_FABLE_ALLOW_TRUSTED is set). This goes well beyond the schema's own parameter descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens by stating a precise verb+resource combination: an 'OPT-IN web-search / OSINT research agent' that runs a model with live web search and returns a sourced, cited answer. It explicitly distinguishes itself from every other ask_* tool by noting they are toolless and cannot browse, and enumerates concrete use cases (current facts, versions/pricing/releases, who/what-is, OSINT). This makes the tool's purpose unmistakable and clearly differentiated from its siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit when-to-use guidance: use for current/'latest' facts, version/pricing/release lookups, who/what-is research, and open-source intelligence. It also provides when-not-to-use and alternative selection: use grok or a Claude model when the task needs page content instead of gemini, and contrasts with all other toolless ask_* tools. The disabled-by-default note and required CLI/OAuth prerequisites further clarify invocation conditions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

code_indexA
DestructiveIdempotent

Build or refresh the local code+docs index for the configured project root, then search it with code_search. Walks the root (skipping .git, node_modules, virtualenvs, caches, binaries, oversize files and the same secret blocklist context_pack uses), splits files into overlapping line windows, and stores them in a per-project SQLite index OUTSIDE the repo. Incremental: unchanged files keep their embeddings. Embeddings are OPT-IN and FAIL-SAFE — hosts come from ASK_FABLE_EMBED_HOSTS (comma-separated, tried in order; unset = the LM Studio host), and when none answers the chunks are stored unembedded and code_search degrades to keyword ranking until a later run backfills. Read-only with respect to the repo; returns file/chunk/embedding counts.

ParametersJSON Schema
NameRequiredDescriptionDefault
rebuildNoRe-chunk and re-embed every file even when its content hash is unchanged (default false: incremental).

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description goes far beyond the annotations: it discloses the exact skip list (.git, node_modules, virtualenvs, binaries, oversize files, secret blocklist shared with context_pack), that the SQLite index lives OUTSIDE the repo, that embeddings are opt-in with fail-safe host fallback via ASK_FABLE_EMBED_HOSTS, the degraded keyword-ranking behavior, and that it returns file/chunk/embedding counts. It also reconciles destructiveHint=true by clarifying the tool is 'Read-only with respect to the repo' — the destructive action applies only to the index, which it explicitly says it refreshes.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but every sentence carries operational value for a complex tool: workflow, skip rules, storage location, incremental behavior, embedding fallback chain, environment variables, and safety guarantee. It is front-loaded with the primary purpose and the sibling link before detailing behavior.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with zero required parameters and no output schema, the description is exceptionally complete: it covers prerequisites (embedded host env var), failure modes (degraded keyword search), side effects (index refresh), scope (configured project root), and return value shape (counts). An agent can predict the tool's behavior across success and partial-failure scenarios without needing the output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% — the single `rebuild` parameter is already fully documented in the schema ('Re-chunk and re-embed every file even when its content hash is unchanged (default false: incremental)'). The description's mention of 'Incremental: unchanged files keep their embeddings' reinforces but does not meaningfully extend the schema. Baseline 3 is appropriate since the schema carries the semantic weight.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence names a specific verb ('Build or refresh') and resource ('local code+docs index'), and immediately names the downstream sibling tool `code_search`. This cleanly distinguishes it from the dozens of ask_*/context_* siblings in the tool list.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description establishes the workflow ('then search it with code_search') and explains when the `rebuild` flag is appropriate versus the default incremental run. It gives clear context for when to invoke the tool, though it never states explicit exclusions or alternative tools for the indexing task itself — which is reasonable since no sibling performs this role.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

configure_councilA
Idempotent

Save the user's chosen default council for ONE gateway so it sticks across sessions (written to ask_fable's config file, overriding the matching ASK_FABLE_*_COUNCIL env default). provider selects 'ollama', 'atlas', or 'openrouter'. Pass models as the model ids that ask_council(provider=…) should use by default (bare ids or provider-prefixed tokens). Atlas/OpenRouter also take synthesizer (the adjudicator; omit to keep the GPT-first ladder); ollama takes default_model (the single model ask_model(provider="ollama") uses when none is passed). Confirm the selection with the user first — ground it with list_models(provider=…). Returns the saved config and its file path.

ParametersJSON Schema
NameRequiredDescriptionDefault
modelsNoModel ids to persist as that provider's default council (bare ids, or provider-prefixed tokens). Ground the picks with `list_models(provider=…)` first.
providerYesWhich provider's council default to persist: 'ollama', 'atlas', or 'openrouter'.
synthesizerNoAtlas/OpenRouter only: the adjudicator for the panel ('codex'/'gpt', 'fable', a bare model id, or a provider token). Omit to keep the built-in GPT-first ladder.
default_modelNoOllama only: the single model `ask_model(provider="ollama")` uses when none is passed (e.g. 'gpt-oss:120b-cloud').

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

It explicitly discloses the persistence side effect: 'written to ask_fable's config file, overriding the matching ASK_FABLE_*_COUNCIL env default.' It also states the return value and file-path behavior. This adds meaningful behavioral context beyond the annotations, which only signal idempotence and non-read-only.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but front-loaded: the first clause gives purpose and side effect, and subsequent clauses organize provider-specific semantics. Some redundancy with the schema exists, but each sentence carries useful operational detail.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite having no output schema, the description covers the return value, file path, user-confirmation requirement, grounding step, persistence behavior, and provider-specific parameter applicability. An agent has enough to select and invoke this tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the schema already documents provider enums, model token forms, synthesizer omission behavior, and `ask_model` usage. The description largely restates this information, adding only marginal context such as 'that `ask_council(provider=…)` should use by default.'

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific action and resource: 'Save the user's chosen default council for ONE gateway so it sticks across sessions.' It also names related tools like `ask_council` and `list_models`, making it easy to distinguish this persistent-configuration tool from live query tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives clear context and a mandatory pre-step: 'Confirm the selection with the user first — ground it with `list_models(provider=…)`.' It also explains when each provider-specific parameter is applicable. It does not explicitly rule out sibling configuration tools like `configure_tracing` or `configure_disabled`, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

configure_disabledA
Idempotent

Turn oracles/providers OFF (or back on) at runtime — persisted to the config file, no restart. A disabled backend is dropped from every council/tier and its dedicated tool returns kind='disabled' (distinct from 'not configured'). Name an oracle key/alias ('grok', 'm3', 'opus48') or a whole provider ('atlas', 'openrouter', 'ollama', 'lmstudio'). Call with no args to see the current denylist. Config wins over the ASK_FABLE_DISABLED env var.

ParametersJSON Schema
NameRequiredDescriptionDefault
setNoREPLACE the whole denylist with exactly these tokens (wins over `disable`/`enable`). Pass [] to remove the config override; if an ASK_FABLE_DISABLED env var is set it then applies again (the result's `disabled` shows the effective list either way).
enableNoTokens to REMOVE from the denylist (re-enable).
disableNoTokens to ADD to the denylist. An oracle key or alias ('grok', 'codex', 'm3', 'opus48') disables that one; a provider name ('atlas', 'openrouter', 'ollama', 'lmstudio') disables all of its models at once. Disabled backends are dropped from every council and their dedicated tool returns kind='disabled'.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate this is a non-read-only, idempotent operation, and the description adds substantial behavioral detail: changes persist to the config file, no restart is needed, disabled backends disappear from every council/tier, and their tools return kind='disabled' versus 'not configured'. It also explains env var precedence and the effect of set=[], which goes well beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact, dense, and well ordered: core action first, followed by behavioral consequences, token syntax, no-args usage, and precedence rule. Every sentence contributes useful information; there is no filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite having no output schema, the description covers the essential return-related behavior: disabled backends return kind='disabled', and calling with no arguments shows the current denylist. It also covers persistence, env var interaction, and how providers vs individual keys are handled. No critical operational detail is missing for an agent to invoke this correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds practical meaning: examples of oracle keys/aliases and provider names, provider-level disable semantics, and the runtime persistence context. The schema already documents replace/add/remove semantics well; the description enriches it with concrete usage guidance without repeating the schema verbatim.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Turn oracles/providers OFF (or back on) at runtime.' It clearly distinguishes the tool's purpose from sibling tools by explaining the persisted denylist effect and the kind='disabled' behavior. It also covers the no-argument invocation for viewing the denylist, leaving no ambiguity about what the tool does.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear operational context: runtime persistence, no restart required, and precedence of config over the ASK_FABLE_DISABLED env var. It implies when to use this tool (managing disabled backends) but does not explicitly contrast it with alternatives like configure_council or unload_lms_model. That omission prevents a 5, but the context is strong.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

configure_tracingA
Idempotent

Toggle reasoning-trace capture at runtime, persisted across sessions (writes ask_fable's config file, which overrides the ASK_FABLE_TRACE_MODE / ASK_FABLE_STREAM_REASONING env defaults — no ~/.claude.json edit or restart needed; it applies on the next call). trace_mode='full' records redacted model reasoning into traces and trace bundles (and saves answer markdown); 'safe' withholds reasoning content while structural traces still record. stream_reasoning=true|false turns live thinking on the server console on or off. Pass either or both. Returns the effective settings and the config path.

ParametersJSON Schema
NameRequiredDescriptionDefault
trace_modeNo'full' captures redacted model reasoning into traces and trace bundles (and saves answer markdown); 'safe' withholds reasoning content while structural traces still record. Persisted; overrides ASK_FABLE_TRACE_MODE. Takes effect on the next call — no restart.
stream_reasoningNoStream model thinking live to the ask_fable console as calls run (true) or off (false). Persisted; overrides ASK_FABLE_STREAM_REASONING. Streams to the server's own console, not into this tool result.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Far exceeds the annotations (which only say not-read-only, idempotent, non-destructive). The description discloses the exact side effect (config file write), the precedence relationship with env vars, the timing ('applies on the next call'), and the distinct consequences of each mode including redaction and markdown saving.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action and effect, and the operational details (config precedence, no restart) follow logically. It is dense with long parentheticals and duplicates much of the schema's parameter text, which costs it a point.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Even without an output schema, the description states the return value ('the effective settings and the config path') and covers persistence, timing, and scope of effect. An agent has everything needed to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the enum is documented there, so the baseline is 3. The description adds the combinatorial rule 'Pass either or both' and reiterates the override behavior, which is meaningful beyond the schema but largely redundant with the per-parameter descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Toggle reasoning-trace capture at runtime') plus the persistence scope ('persisted across sessions'). It is clearly distinguishable from sibling read tools like trace_list and trace_get, since this one mutates configuration rather than reading traces.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives strong operational context: it writes the ask_fable config file, overrides the ASK_FABLE_TRACE_MODE / ASK_FABLE_STREAM_REASONING env defaults, requires no ~/.claude.json edit or restart, and applies on the next call. It does not name a competing tool to use instead, but no sibling offers this capability, so the missing exclusion is minor.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

contextA
DestructiveIdempotent

Change the shared context bus — dispatched by op. 'write' stores value under key (paste a big blob ONCE, then reference it via context_ref instead of re-pasting it every call); 'pack' reads the repo files named in paths (each path or path:START-END, relative to the configured project root) and stores the budgeted bundle under key; 'delete' removes key. Reusing a key overwrites it, and the store is shared by every agent on this server — read with context_read first. Destructive/overwriting.

ParametersJSON Schema
NameRequiredDescriptionDefault
opYes'write' stores `value` under `key`; 'pack' reads the repo files in `paths` and stores the bundle under `key`; 'delete' removes `key`.
keyYesThe context key (required for every op).
pathsNoop='pack': file specs relative to the configured project root, each a path or `path:START-END` (1-indexed inclusive).
valueNoop='write': the context to store — code, file contents, a stack trace, design notes. Paste it ONCE, then reference it by key via `context_ref`.
max_charsNoop='pack': optional cap on total packed characters (default ~24000).
descriptionNoop='write': optional one-line note about what this holds.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark destructiveHint true and readOnlyHint false, and the description reinforces this with 'Destructive/overwriting' and the overwrite-on-reuse warning. It adds valuable context beyond annotations: the store is shared across agents, pack produces a budgeted bundle, and reading with context_read first is recommended.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but front-loaded, opening with the resource and then detailing each operation in order. Some wording duplicates the schema and the final 'Destructive/overwriting' tag is redundant with annotations, but overall it is appropriately sized for a three-mode tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a three-operation tool with no output schema, the description covers the key behaviors: what each op does, path syntax, key reuse, overwrite semantics, and cross-agent sharing. It could have clarified return/confirmation behavior and per-op parameter exclusion, but those are minor given the schema and annotations.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all six parameters. The description mostly restates the op-specific behavior already present in the schema for value, paths, max_chars, and description, and adds no new parameter-level semantics beyond the global reuse and sharing warning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names the resource (shared context bus) and makes the generic verb 'Change' concrete by enumerating the three operations: write stores a value, pack bundles repo files, and delete removes a key. It also differentiates itself from the sibling context_read by instructing the agent to read with context_read first.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit usage guidance: paste a large blob once and reference it via context_ref instead of re-pasting it, use pack for repo files, and read with context_read before relying on shared content. It also warns that the store is shared by every agent and that reusing a key overwrites it, telling the agent when extra caution is needed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

context_readA
Read-onlyIdempotent

Read the shared context bus: pass key to get a stored blob back (value plus its size, age and description; not_found if unset), or OMIT key to LIST every stored key (size/age/description, never the full value). Read-only — use it to inspect a blob, or to discover what is already available to reference via context_ref before re-pasting.

ParametersJSON Schema
NameRequiredDescriptionDefault
keyNoKey to read back. Omit to LIST every stored key (with its size, age and description) — the discovery call before re-pasting context.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses exact behavior beyond annotations: `not_found` when a key is unset, metadata returned with each blob, and the important distinction that list mode never returns full values. This is especially valuable because there is no output schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two well-structured sentences deliver the mode distinction, return format, missing-key behavior, read-only guarantee, and a pointer to `context_ref`. No filler; information is front-loaded and every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite having no output schema, the description fully covers both invocation forms, the shape of returned data, the missing-key case, the read-only nature, and how the tool fits into the context-ref workflow. An agent has everything needed to invoke and interpret results correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already documents `key` and the omit-to-list behavior at 100% coverage, so the baseline applies. The description adds return-behavior context (size, age, description, not_found) but no new parameter constraints or format details, so it doesn't substantially exceed schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Read') and resource ('shared context bus'), then precisely distinguishes the two invocation modes: pass `key` to get a blob, or omit `key` to list stored keys. It also mentions `context_ref` as the referencing counterpart, which helps separate it from related tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly gives two concrete use cases: inspect a single blob, or discover available keys before re-pasting via `context_ref`. It doesn't enumerate exclusions or compare against sibling tools, but the usage context is clear enough for an agent to decide when to call it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

diagnoseA
Read-onlyIdempotent

Read-only health check of every reasoning backend — REACH FOR THIS when a council came back degraded, an oracle is unexpectedly missing, or you want to know what is actually wired up before relying on it. For each oracle it reports reachability, the resolved model, the configured timeout, the circuit-breaker gate (open / quota-held), and a fix: line for anything down, rolled up to ok / warning / error. It makes NO paid model call and NEVER perturbs state: it only checks a CLI's presence and --version, whether an API key is set, and the breaker's read-only snapshot. Cheap and safe to call speculatively.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide readOnlyHint, idempotentHint, and destructiveHint=false, but the description goes beyond them: it states 'makes NO paid model call and NEVER perturbs state' and details exactly which checks are performed ('CLI presence and --version, whether an API key is set, and the breaker's read-only snapshot'). This adds genuine behavioral context about side effects and cost, exceeding what the annotations alone provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three sentences: purpose and when-to-use, output summary, and safety constraints. It is front-loaded with 'Read-only health check', uses imperative 'REACH FOR THIS', and every clause serves a purpose. No filler, and the structure guides the agent from 'what' to 'when' to 'what it costs'.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a no-parameter, no-output-schema tool, the description fully covers behavior, side effects, and expected report contents (reachability, model, timeout, breaker gate, fix line, and rollup status). An agent knows exactly what it will get and what it costs, making it complete enough for correct invocation decisions.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema is empty with 0 parameters, so the baseline per the rubric is 4. The description appropriately focuses on tool behavior rather than parameter details, since there are no parameters to document. It adds no parameter semantics because there are none to describe.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'Read-only health check of every reasoning backend', a specific verb/resource pairing that clearly defines scope. It then lists concrete trigger conditions ('when a council came back degraded, an oracle is unexpectedly missing') which sharply distinguishes it from sibling ask_* and configure_* tools, and enumerates exactly what it reports (reachability, resolved model, timeout, circuit-breaker gate, fix line). This leaves no ambiguity about the tool's purpose.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly tells the agent when to reach for it: 'REACH FOR THIS when a council came back degraded...' and adds the wise precaution 'before relying on it'. It also clarifies the safety profile ('Cheap and safe to call speculatively') which informs usage frequency. While it doesn't name sibling tools by name, the explicit when-conditions are sufficient to route an agent correctly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

host_statusA
Read-onlyIdempotent

Read-only GPU and host status from the operator's Control panel (lmstudio.example.com): GPU utilization, VRAM used/total/free, temperature, fan and power, which processes hold VRAM, systemd service states, the models LM Studio has loaded, and any warnings. REACH FOR THIS when the user asks how the GPU/box is doing, or before offering a local-model decision that may not fit in memory (ask_lms already uses the same reading for its room check). Best-effort: an unreachable control page returns a status error, never a crash.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, and the description reinforces this with 'Read-only'. It additionally discloses the best-effort behavior: 'an unreachable control page returns a status error, never a crash.' This adds meaningful failure-mode context beyond the structured annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but well-organized: core purpose and metrics first, usage trigger second, and failure caveat last. Every sentence adds useful information, and there is no filler or repetition of schema contents.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Even without an output schema, the description lists all relevant data categories and the error behavior, making it clear what the agent can expect. The combination of usage context, sibling relationship, and failure semantics fully covers what an agent needs to invoke this zero-parameter read-only tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters and the schema has no properties, so there is no parameter burden for the description to carry. The baseline for zero-parameter tools is 4, and the description appropriately spends no space on parameter details.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description begins with a specific verb and resource: 'Read-only GPU and host status from the operator's Control panel'. It enumerates the exact metrics returned (GPU utilization, VRAM, temperature, fan, power, process holders, systemd states, loaded models, warnings), which leaves no ambiguity about what the tool does. It also distinguishes itself from sibling tools by explicitly referencing ask_lms and the local-model memory context.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description contains an explicit trigger: 'REACH FOR THIS when the user asks how the GPU/box is doing, or before offering a local-model decision that may not fit in memory.' It also names the relevant sibling (ask_lms) and clarifies its relationship, giving the agent a concrete routing rule rather than leaving usage to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_modelsA
Read-onlyIdempotent

List the available models for one gateway so you can offer a concrete choice before spending a call. provider selects the catalogue: 'ali' (Alibaba/Qwen reasoning models, plus the deepseek-/glm- and 'auto' the gateway fronts), 'atlas' (Atlas Cloud text models), 'openrouter' (~400 models from every major lab on one key), 'ollama' (the live ollama.com catalog plus locally-pulled models and the configured council), or 'lmstudio' (the operator's local LM Studio server — loaded/available models, context windows, and a VRAM fit classification). The Atlas and OpenRouter catalogues are free and need no key; pass task to rank a provider-diverse shortlist for a job, and interactive (default true) opens a native model picker on clients that support form elicitation. 'ali' takes all to include the non-reasoning audio/image models. Read-only.

ParametersJSON Schema
NameRequiredDescriptionDefault
allNoAli only: include the non-reasoning (audio/TTS/image) models too.
taskNoAtlas/OpenRouter only: an optional job to rank the catalogue for, e.g. 'debug a large Rust repository'.
limitNoAtlas/OpenRouter only: maximum task-matched models to offer.
refreshNoFetch the live catalog. When false, report only the configured defaults (no network).
providerYesWhich catalogue to list: 'ali' (Alibaba/Qwen reasoning), 'atlas' (Atlas Cloud text models), 'openrouter' (~400 models, one key), 'ollama' (cloud catalog + locally pulled + configured council), or 'lmstudio' (the local server: loaded/available models and VRAM fit).
interactiveNoAtlas/OpenRouter only: with a task, open a native model picker if the MCP client supports form elicitation.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark it read-only and idempotent, and the description goes well beyond them by disclosing network behavior ('refresh' fetch live vs configured defaults), interactive picker behavior, VRAM classification for lmstudio, and the no-key property for Atlas/OpenRouter. This adds substantial context beyond the structured hints.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but well organized: purpose first, then provider catalogue details, then parameter-specific qualifiers, ending with a one-word safety tag. Every sentence contributes differentiating behavior or usage context, and no space is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (six parameters, five enum values, no output schema), the description covers the important return-relevant details: what each provider offers, when network access is used, what task ranking does, and what the picker will do. An agent has enough to select parameters correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3; the description improves on that by explaining the meaning of ranking ('task'), the interactive picker, and the 'all' extension for Ali. It mostly reinforces the schema rather than adding wholly new semantics, but the additions are useful.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'List the available models for one gateway'. It further disambiguates itself by enumerating the five provider catalogues, so an agent can tell exactly what it does and how it differs from the sibling ask/configure tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear context ('before spending a call', 'offer a concrete choice') and explains provider-specific behaviors such as which catalogues are free or need no key. It does not explicitly state when not to use the tool or name alternative tools, but the guidance is strong enough for selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

reset_sessionA
DestructiveIdempotent

Dump (optionally to a file) and clear a Fable conversation session, so the next ask on that key starts a fresh topic.

ParametersJSON Schema
NameRequiredDescriptionDefault
saveNoWrite the transcript to a file before clearing.
modelNoWhich tool's conversation to clear: 'fable' for `ask`, 'opus5' (or 'opus') for `ask_opus5`. The two tools namespace their sessions separately, so the same key names two independent conversations.fable
sessionNoSession key to clear.default

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark destructiveHint=true and idempotentHint=true; the description adds context by disclosing the optional file dump and the effect on the next `ask`. It does not contradict the annotations, and the remaining details (file destination, irreversibility without save) are left to the schema/defaults.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence that front-loads the action and outcome with no filler. Every phrase earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The definition is largely complete for a low-complexity, fully optional-parameter tool: annotations cover safety, schema covers all parameters, and the description covers purpose and effect. It loses a point because the description itself scopes to 'Fable' and `ask` while the model parameter shows it also handles opus5/`ask_opus5`, and no return value/file-path behavior is mentioned in the absence of an output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents save, model, and session. The tool description only repeats 'optionally to a file' and 'on that key' without adding new parameter-level meaning; baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb+resource: 'Dump ... and clear a Fable conversation session', and explains the outcome ('the next `ask` on that key starts a fresh topic'). This clearly distinguishes reset_session from the ask_* and session_* siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description conveys when to use the tool: when you want to start a fresh topic for a given session key. The schema's model parameter description adds guidance for choosing between `ask` and `ask_opus5` namespaces, but the tool description itself does not explicitly state when not to use it or name alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

session_listA
Read-onlyIdempotent

COORDINATION — the operator dashboard. Lists ask_fable sessions across instances on this machine (opencode / Claude Code / salient windows) so you can see what other agents are asking the oracles. Each entry shows session key, agent_id, latest question, oracle, status, heartbeat age, and turn count. Defaults: THIS project only, and active_only: true (hide sessions with no heartbeat in ~5 min — the stale threshold). Pass active_only: false for retained history, all_projects: true for the whole machine. Use it to avoid duplicate work or watch the live fleet. Read-only, makes no model call. Visibility-only — never affects oracle answers; oracles only see what a calling agent explicitly passes in question/context.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
active_onlyNoOnly sessions with a recent heartbeat (not stale). Default true so the dashboard shows live work. Pass false to include retained history.
all_projectsNoShow sessions from ALL projects on this machine, not just the current one.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover readOnlyHint/idempotentHint/destructiveHint, so the description earns credit for what it adds: 'makes no model call', the ~5 min stale threshold behind the default, and the important visibility-only guarantee that sessions never affect oracle answers and oracles only see explicitly passed question/context. It does not disclose volume/truncation behavior, though limit=200 max suggests bounded output.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the 'COORDINATION — the operator dashboard' role, then scope, then defaults, then usage — a sensible ordering with no filler sentences. It is on the long side for a three-parameter list tool, and the read-only/model-call sentence partially restates the annotations.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description compensates by enumerating the returned fields per entry. Combined with default behavior, stale threshold, and the visibility guarantee, an agent has everything needed to call and interpret it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 67% and the description meaningfully supplements it: it states the defaults (this project, active_only:true) in one place and explains the ~5 minute stale threshold that the schema's active_only description only gestures at ('recent heartbeat'). It says nothing about `limit`, so it does not fully close the coverage gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource ('Lists ask_fable sessions across instances on this machine') and names the concrete instances (opencode / Claude Code / salient windows). The scope statement plus the enumerated entry fields ('session key, agent_id, latest question, oracle, status, heartbeat age, turn count') makes it clearly distinct from ask_* siblings and from session_peek/session_stats without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a clear use context ('Use it to avoid duplicate work or watch the live fleet') and states which flag selects which mode: active_only:false for retained history, all_projects:true for the whole machine. It stops short of an explicit when-not-to-use or a named alternative among siblings (session_peek, session_stats, trace_list), so a 4 rather than a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

session_peekA
Read-onlyIdempotent

COORDINATION — read the full turn history (every question and answer, in order) for one session, across instances. Use it to understand what an agent has learned in a session before joining the work, or to recover a finding another instance produced. Optionally scope to one agent_id. Returns the complete conversation bounded by retention. Read-only, makes no model call. Like session_list, this is visibility-only — it never feeds back into an oracle's context.

ParametersJSON Schema
NameRequiredDescriptionDefault
agent_idNoOptional: restrict to one agent's turns on that session.
session_keyYesThe session label to inspect.

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is covered. The description adds genuinely non-redundant context: results are 'bounded by retention', it 'makes no model call', and it 'never feeds back into an oracle's context' — the last point materially shapes how an agent should reason about using it.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the category ('COORDINATION'), then the core action, then use cases, then behavioral caveats. Three sentences with little waste, though the trailing session_list/oracle-context sentence is slightly tangential to invoking this specific tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, but the description compensates by stating what returns ('the complete conversation bounded by retention'), and the retention bound is an important completeness detail. For a 2-parameter read tool with full annotation coverage, nothing essential to correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both parameters are already documented in the schema. The description's 'Optionally scope to one agent_id' merely restates the schema's 'restrict to one agent's turns' without adding format, default, or edge-case detail. Baseline 3 applies when the schema carries the semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('read the full turn history ... for one session, across instances') and explicitly contrasts its visibility-only nature with the oracle-feeding siblings via the session_list comparison. An agent can distinguish it from session_list, context_read, and trace_get without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives two concrete use cases ('before joining the work' and 'to recover a finding another instance produced') that tell the agent when this tool is the right pick. It stops short of naming an explicit alternative tool to use instead (e.g. session_list vs context_read) or stating when not to use it, but the context is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

session_statsA
Read-onlyIdempotent

COORDINATION — aggregated oracle usage across ALL instances on this machine (unlike stats, which only sees the current instance's audit log). Turn counts (by status/oracle/agent) default to the last 24h (window_s: 86400); pass window_s: 0 for all retained history. Also returns fresh_sessions (heartbeat within the stale window) vs total_sessions, plus attributed_turns / unknown_turns. Defaults to this project; all_projects: true for the whole machine. Use it to answer 'which agents are burning the most oracle calls?' or 'how is the fleet doing today?'. Read-only, makes no model call.

ParametersJSON Schema
NameRequiredDescriptionDefault
window_sNoOnly count turns from the last N seconds. Default 86400 (24h). Pass 0 for all retained history.
all_projectsNoAggregate across all projects on this machine, not just the current one.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint/idempotent/destructive=false, so 'Read-only, makes no model call' largely restates structured data. However, the description adds real behavioral context the annotations don't cover: the default 24h window, the `window_s: 0` escape hatch, the all-projects scope, and the returned breakdowns (`fresh_sessions` vs `total_sessions`, `attributed_turns`/`unknown_turns`).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Dense but front-loaded: the coordination scope and the sibling distinction come first, then defaults, then returned fields, then use cases. Every clause carries information, though it is a long single paragraph rather than crisply segmented.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, and the description compensates by enumerating what the tool returns (turn counts by status/oracle/agent, fresh vs total sessions, attributed/unknown turns). Combined with the scope and window semantics, an agent has everything needed to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and both parameters are fully documented in the schema, including the `window_s: 0` semantics. The description's param notes largely duplicate the schema text, so this is the baseline 3 rather than added value.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource+scope ('aggregated oracle usage across ALL instances on this machine') and explicitly contrasts itself with the sibling `stats`, which only sees the current instance's audit log. An agent can distinguish the two without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

States when to use it (vs `stats`), names the concrete questions it answers ('which agents are burning the most oracle calls?', 'how is the fleet doing today?'), and gives the two modes via `all_projects`. Nothing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

statsA
Read-onlyIdempotent

Read-only usage/health stats aggregated from the ask_fable audit log — see how the tools are performing without spelunking JSONL. Buckets every recorded call over a time window ('1h' | '24h' | '7d' | 'all', default '24h') by 'model', 'session', or 'day', reporting calls / allowed / refused / errors, avg and p95 latency, and error_rate per bucket plus totals. Optional model / session filters narrow to one backend or workflow. Council/chain records also carry quorum, consensus, and synth_fallback in the log. Use it to answer things like 'is GLM erroring a lot today?' or 'how slow are councils this week?'. Makes no model call and is never cached.

ParametersJSON Schema
NameRequiredDescriptionDefault
byNoBucket key. 'model' attributes a call to the model that answered (a council to its synthesizer); 'provider' is per backend call — the only view that sees council/chain/debate members one by one, and what the circuit breaker shed (circuit_open); also 'tool', 'session', 'day', 'project', 'cache', 'mode'.model
modelNoOnly include records for this model label.
windowNoHow far back to aggregate: '1h', '24h', '7d', or 'all'.24h
sessionNoOnly include records for this session key.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover read-only, idempotent, non-destructive, closed-world behavior, and the description adds meaningful context beyond them: no model call is made, results are never cached, and council/chain records carry quorum/consensus/synth_fallback. It still doesn't say whether results are paginated or how stale the aggregation is, so it isn't exhaustive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads purpose, then window/by, then filters, then reporting fields, then examples. Every sentence carries information (what is aggregated, how it can be sliced, what is returned, what constraints apply) with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, and the description compensates by enumerating the returned metrics (calls/allowed/refused/errors, avg and p95 latency, error_rate, totals). Combined with the filter and window semantics, an agent has everything needed to call and interpret this tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the by enum's own description already explains provider vs model attribution, so the schema does the heavy lifting. The prose restates only three of the eight bucket keys ('model', 'session', 'day'), adding little syntax or semantics beyond the schema's own text.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: read-only usage/health stats aggregated from the ask_fable audit log, with named bucket dimensions (by) and time windows. The scope ('without spelunking JSONL') clearly separates it from the ask_* generation tools and trace/log inspectors.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete motivating questions ('is GLM erroring a lot today?', 'how slow are councils this week?') that make the intended use obvious. It does not, however, explicitly name an alternative or say when not to use it (e.g., vs session_stats), so it stops short of full routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

trace_getC
Read-onlyIdempotent

Read the ordered events and artifact references for one trace.

ParametersJSON Schema
NameRequiredDescriptionDefault
trace_idYes
max_charsNo
include_contentNo

TDQS

C2.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true and destructiveHint=false, so the safety profile is covered. The description adds that results are ordered and include artifact references, but says nothing about truncation via max_chars or what include_content gates.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no filler — appropriately terse. The terseness is a coverage problem rather than a structure problem, so it keeps a high score here.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, 0% parameter documentation, and no usage routing, the definition is too thin for a tool with two meaningful tuning parameters. The one sentence only partially signals what comes back.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% for three parameters, and the description names none of them. max_chars (truncation limits) and include_content (payload verbosity) are non-obvious and carry real behavioral consequences that go entirely undocumented.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb ('Read') plus a precise resource ('ordered events and artifact references for one trace'), which clearly separates it from trace_list. It does not name siblings explicitly, but the singular-trace scope is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use guidance and no mention of alternatives such as trace_list or session_peek. The agent must infer from the name alone that this is the drill-down companion to trace_list.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

trace_listC
Read-onlyIdempotent

List recent correlated tool traces without raw content.

ParametersJSON Schema
NameRequiredDescriptionDefault
toolNo
limitNo
beforeNo
statusNo
projectNo
sessionNo
providerNo

TDQS

C2.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false, and openWorldHint=false, so the safety profile is fully covered. The description adds one genuinely useful behavioral fact not in the annotations — that raw trace content is excluded from results — but says nothing about ordering, pagination behavior, or result size.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single tight sentence with no filler, and the scope qualifier is front-loaded. It is efficient, though its brevity is partly under-specification rather than disciplined compression.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Seven unlabeled optional parameters, no output schema, and no annotation gaps filled — an agent has no way to learn what 'project', 'session', or 'provider' accept or how paging works. For a filter-heavy list tool this is substantially incomplete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

All 7 parameters (tool, limit, before, status, project, session, provider) have 0% schema description coverage, so the description carries the full burden and largely fails it: not one filter, the limit cap, or the 'before' cursor is explained. Only the word 'recent' weakly hints at time-ordered retrieval.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('List') and resource ('correlated tool traces') plus a scope qualifier ('without raw content'), which distinguishes it meaningfully from trace_get's single-trace retrieval. It never names trace_get, so the differentiation is inferred rather than stated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this rather than trace_get, session_peek, or stats, and no prerequisites or filtering conditions are described. An agent must infer usage entirely from the name and sibling list.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

unload_lms_modelA
DestructiveIdempotent

Unload one model from the operator's LM Studio server to free memory. OPERATOR ACTION: never call this without an explicit request or confirmation from the user — it discards a resident model. Use list_lms_models to show what is loaded and how much each occupies, and note that a blocked ask_lms result carries an unload_offer naming exactly what is in the way. Refuses while the model has an ask_lms call in flight; waits for the unload to be confirmed and reports the bytes freed and what remains resident. Idempotent (unloading an unloaded model is a no-op).

ParametersJSON Schema
NameRequiredDescriptionDefault
modelYesThe loaded model key to unload (e.g. 'qwen3.8-27b-distill-q38'). Call `list_lms_models` first to show the operator what is loaded and how much each occupies.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark this destructive and idempotent, and the description reinforces and expands on both: it discards a resident model, refuses while an `ask_lms` call is in flight, waits for confirmation, and reports bytes freed plus what remains resident. There is no contradiction between description and annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but every sentence serves a purpose: operator warning first, then prerequisite, then in-flight refusal and result reporting, then idempotence. It is front-loaded with the most critical safety information and contains no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter destructive tool with no output schema, the description covers preconditions, refusal behavior, return information (bytes freed and resident models), and idempotence. Nothing an agent needs to invoke it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the schema already explains that `model` is a loaded model key with an example and a pointer to `list_lms_models`. The top-level description does not add substantially new parameter semantics, but it does not need to given full schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence uses a specific verb ('unload') and resource ('model from the operator's LM Studio server') with a clear goal ('free memory'). No sibling tool performs unloading, so there is no ambiguity about which tool to select.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says when not to call it: 'never call this without an explicit request or confirmation from the user' because it discards a resident model. It also names the prerequisite (`list_lms_models`), the blocked `ask_lms` signal (`unload_offer`), and the in-flight refusal condition.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 43 tool updatesv0.18.0
    • Changedask3 fields changed
      • changedInput schema / properties / context_ref / description
        Previous value: -"Key(s) of context previously saved with `context_write` to pull in and prepend to `context` — so you paste a big codebase context ONCE and reference it by key across many asks instead of re-pasting. Missing keys are reported, not fatal."New value: +"Key(s) of context previously saved with `context(op=\"write\", …)` to pull in and prepend to `context` — so you paste a big codebase context ONCE and reference it by key across many asks instead of re-pasting. Missing keys are reported, not fatal."
      • addedInput schema / properties / oracle
        Added value: +{
        +  "default": "fable",
        +  "description": "Which multi-turn model answers: 'fable' (default) or the Opus family — 'opus' tracks the newest Claude Opus, and 'opus5'/'opus55'/'opus48' name the same Opus session. Opus is roughly half Fable's price and faster, so prefer it for high-volume or long back-and-forth work. For a single-turn model use `ask_model(provider=…)`.",
        +  "enum": [
        +    "fable",
        +    "opus",
        +    "opus5",
        +    "opus55",
        +    "opus48",
        +    "claude-opus-4-8",
        +    "claude-opus-5",
        +    "claude-opus-5-5",
        +    "opus-4.8",
        +    "opus-48",
        +    "opus-5",
        +    "opus-5.5",
        +    "opus-55",
        +    "opus4.8",
        +    "opus5.5"
        +  ],
        +  "type": "string"
        +}
      • changedInput schema / properties / session / description
        Previous value: -"Conversation key. Reuse it to ask follow-ups (Fable keeps context); use a new key or reset=true to start a fresh topic."New value: +"Conversation key. Reuse it to ask follow-ups (the model keeps context); use a new key or reset=true to start a fresh topic. Fable and Opus sessions are namespaced separately, so the same key on each is two independent conversations."
    • Removedask_atlas
    • Removedask_atlas_council
    • Changedask_chain1 field changed
      • changedInput schema / properties / context_ref / description
        Previous value: -"Key(s) of context saved with `context_write` to pull in and prepend to `context`."New value: +"Key(s) of context saved with `context(op=\"write\", …)` to pull in and prepend to `context`."
    • Removedask_codex
    • Changedask_conference3 fields changed
      • addedInput schema / properties / attack_premise
        Added value: +{
        +  "default": true,
        +  "description": "After the blind round, name the premise every opening assumed and assign one participant to argue it is FALSE (two extra calls). This is the challenge nobody else will make, since agreeing on the premise is what lets the rest of the discussion happen. Needs 3+ seats and 2+ rounds; skipped otherwise.",
        +  "type": "boolean"
        +}
      • changedInput schema / properties / context_ref / description
        Previous value: -"Key(s) of context saved with `context_write` to pull in and prepend to `context` — paste a big context ONCE, reference it by key here. Missing keys are reported, not fatal."New value: +"Key(s) of context saved with `context(op=\"write\", …)` to pull in and prepend to `context` — paste a big context ONCE, reference it by key here. Missing keys are reported, not fatal."
      • changedInput schema / properties / models / items / anyOf
        Previous value: -[
        -  {
        -    "enum": [
        -      "fable",
        -      "fable51",
        -      "opus",
        -      "opus48",
        -      "sonnet",
        -      "deepseek",
        -      "minimax",
        -      "glm",
        -      "gemini",
        -      "codex",
        -      "grok",
        -      "kimi",
        -      "claude-fable-5-1",
        -      "claude-opus-4-8",
        -      "claude-opus-5",
        -      "claude-sonnet-5",
        -      "fable-5.1",
        -      "fable-51",
        -      "fable5.1",
        -      "gpt",
        -      "m3",
        -      "opus-4.8",
        -      "opus-48",
        -      "opus-5",
        -      "opus4.8",
        -      "opus5",
        -      "sonnet-5",
        -      "sonnet5",
        -      "xai",
        -      "twin",
        -      "twin flame",
        -      "twin flames",
        -      "twin-flame",
        -      "twin-flames",
        -      "twin_flame",
        -      "twin_flames",
        -      "twinflame",
        -      "twinflames",
        -      "twins"
        -    ],
        -    "type": "string"
        -  },
        -  {
        -    "pattern": "^ollama:.+",
        -    "type": "string"
        -  },
        -  {
        -    "pattern": "^atlas:.+",
        -    "type": "string"
        -  },
        -  {
        -    "pattern": "^openrouter:.+",
        -    "type": "string"
        -  },
        -  {
        -    "pattern": "^lmstudio:.+",
        -    "type": "string"
        -  }
        -]New value: +[
        +  {
        +    "enum": [
        +      "fable",
        +      "fable51",
        +      "opus",
        +      "opus55",
        +      "opus5",
        +      "opus48",
        +      "sonnet",
        +      "deepseek",
        +      "minimax",
        +      "glm",
        +      "gemini",
        +      "codex",
        +      "grok",
        +      "kimi",
        +      "claude-fable-5-1",
        +      "claude-opus-4-8",
        +      "claude-opus-5",
        +      "claude-opus-5-5",
        +      "claude-sonnet-5",
        +      "fable-5.1",
        +      "fable-51",
        +      "fable5.1",
        +      "gpt",
        +      "m3",
        +      "opus-4.8",
        +      "opus-48",
        +      "opus-5",
        +      "opus-5.5",
        +      "opus-55",
        +      "opus4.8",
        +      "opus5.5",
        +      "sonnet-5",
        +      "sonnet5",
        +      "xai",
        +      "twin",
        +      "twin flame",
        +      "twin flames",
        +      "twin-flame",
        +      "twin-flames",
        +      "twin_flame",
        +      "twin_flames",
        +      "twinflame",
        +      "twinflames",
        +      "twins"
        +    ],
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^ollama:.+",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^atlas:.+",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^openrouter:.+",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^lmstudio:.+",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^ali:.+",
        +    "type": "string"
        +  }
        +]
    • Changedask_council4 fields changed
      • changedInput schema / properties / context_ref / description
        Previous value: -"Key(s) of context saved with `context_write` to pull in and prepend to `context` — paste a big context ONCE, reference it by key here. Missing keys are reported, not fatal."New value: +"Key(s) of context saved with `context(op=\"write\", …)` to pull in and prepend to `context` — paste a big context ONCE, reference it by key here. Missing keys are reported, not fatal."
      • changedInput schema / properties / models / items / anyOf
        Previous value: -[
        -  {
        -    "enum": [
        -      "fable",
        -      "fable51",
        -      "opus",
        -      "opus48",
        -      "sonnet",
        -      "deepseek",
        -      "minimax",
        -      "glm",
        -      "gemini",
        -      "codex",
        -      "grok",
        -      "kimi",
        -      "claude-fable-5-1",
        -      "claude-opus-4-8",
        -      "claude-opus-5",
        -      "claude-sonnet-5",
        -      "fable-5.1",
        -      "fable-51",
        -      "fable5.1",
        -      "gpt",
        -      "m3",
        -      "opus-4.8",
        -      "opus-48",
        -      "opus-5",
        -      "opus4.8",
        -      "opus5",
        -      "sonnet-5",
        -      "sonnet5",
        -      "xai",
        -      "twin",
        -      "twin flame",
        -      "twin flames",
        -      "twin-flame",
        -      "twin-flames",
        -      "twin_flame",
        -      "twin_flames",
        -      "twinflame",
        -      "twinflames",
        -      "twins"
        -    ],
        -    "type": "string"
        -  },
        -  {
        -    "pattern": "^ollama:.+",
        -    "type": "string"
        -  },
        -  {
        -    "pattern": "^atlas:.+",
        -    "type": "string"
        -  },
        -  {
        -    "pattern": "^openrouter:.+",
        -    "type": "string"
        -  },
        -  {
        -    "pattern": "^lmstudio:.+",
        -    "type": "string"
        -  }
        -]New value: +[
        +  {
        +    "enum": [
        +      "fable",
        +      "fable51",
        +      "opus",
        +      "opus55",
        +      "opus5",
        +      "opus48",
        +      "sonnet",
        +      "deepseek",
        +      "minimax",
        +      "glm",
        +      "gemini",
        +      "codex",
        +      "grok",
        +      "kimi",
        +      "claude-fable-5-1",
        +      "claude-opus-4-8",
        +      "claude-opus-5",
        +      "claude-opus-5-5",
        +      "claude-sonnet-5",
        +      "fable-5.1",
        +      "fable-51",
        +      "fable5.1",
        +      "gpt",
        +      "m3",
        +      "opus-4.8",
        +      "opus-48",
        +      "opus-5",
        +      "opus-5.5",
        +      "opus-55",
        +      "opus4.8",
        +      "opus5.5",
        +      "sonnet-5",
        +      "sonnet5",
        +      "xai",
        +      "twin",
        +      "twin flame",
        +      "twin flames",
        +      "twin-flame",
        +      "twin-flames",
        +      "twin_flame",
        +      "twin_flames",
        +      "twinflame",
        +      "twinflames",
        +      "twins"
        +    ],
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^ollama:.+",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^atlas:.+",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^openrouter:.+",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^lmstudio:.+",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^ali:.+",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[^\\s:]+/[^\\s:]+$",
        +    "type": "string"
        +  }
        +]
      • addedInput schema / properties / provider
        Added value: +{
        +  "description": "Scope the council to ONE gateway: the default panel comes from that provider's configured set (for atlas/openrouter, else a live-catalog shortlist), members are its tokens, and the adjudicator follows that provider's ladder (GPT-first for atlas/openrouter; Fable otherwise). `lmstudio` runs the panel ONE AT A TIME (a single GPU serves one model at a time). An explicit `models` is honored within the chosen provider; `tier` is ignored when `provider` is set. Omit for a mixed council selected by `models`/`tier`.",
        +  "enum": [
        +    "ollama",
        +    "atlas",
        +    "openrouter",
        +    "lmstudio"
        +  ],
        +  "type": "string"
        +}
      • changedInput schema / properties / synthesizer / anyOf
        Previous value: -[
        -  {
        -    "enum": [
        -      "fable",
        -      "fable51",
        -      "opus",
        -      "opus48",
        -      "sonnet",
        -      "deepseek",
        -      "minimax",
        -      "glm",
        -      "gemini",
        -      "codex",
        -      "grok",
        -      "kimi",
        -      "claude-fable-5-1",
        -      "claude-opus-4-8",
        -      "claude-opus-5",
        -      "claude-sonnet-5",
        -      "fable-5.1",
        -      "fable-51",
        -      "fable5.1",
        -      "gpt",
        -      "m3",
        -      "opus-4.8",
        -      "opus-48",
        -      "opus-5",
        -      "opus4.8",
        -      "opus5",
        -      "sonnet-5",
        -      "sonnet5",
        -      "xai"
        -    ],
        -    "type": "string"
        -  },
        -  {
        -    "pattern": "^ollama:.+",
        -    "type": "string"
        -  },
        -  {
        -    "pattern": "^atlas:.+",
        -    "type": "string"
        -  },
        -  {
        -    "pattern": "^openrouter:.+",
        -    "type": "string"
        -  }
        -]New value: +[
        +  {
        +    "enum": [
        +      "fable",
        +      "fable51",
        +      "opus",
        +      "opus55",
        +      "opus5",
        +      "opus48",
        +      "sonnet",
        +      "deepseek",
        +      "minimax",
        +      "glm",
        +      "gemini",
        +      "codex",
        +      "grok",
        +      "kimi",
        +      "claude-fable-5-1",
        +      "claude-opus-4-8",
        +      "claude-opus-5",
        +      "claude-opus-5-5",
        +      "claude-sonnet-5",
        +      "fable-5.1",
        +      "fable-51",
        +      "fable5.1",
        +      "gpt",
        +      "m3",
        +      "opus-4.8",
        +      "opus-48",
        +      "opus-5",
        +      "opus-5.5",
        +      "opus-55",
        +      "opus4.8",
        +      "opus5.5",
        +      "sonnet-5",
        +      "sonnet5",
        +      "xai"
        +    ],
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^ollama:.+",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^atlas:.+",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^openrouter:.+",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^ali:.+",
        +    "type": "string"
        +  }
        +]
    • Changedask_debate1 field changed
      • changedInput schema / properties / context_ref / description
        Previous value: -"Key(s) of context saved with `context_write` to pull in and prepend to `context`."New value: +"Key(s) of context saved with `context(op=\"write\", …)` to pull in and prepend to `context`."
    • Removedask_deepseek
    • Changedask_falsify1 field changed
      • changedInput schema / properties / context_ref / description
        Previous value: -"Key(s) of context saved with `context_write` to pull in and prepend to `context`."New value: +"Key(s) of context saved with `context(op=\"write\", …)` to pull in and prepend to `context`."
    • Removedask_gemini
    • Removedask_glm
    • Removedask_grok
    • Removedask_kimi
    • Removedask_lms
    • Removedask_lms_council
    • Removedask_m3
    • Addedask_model
    • Removedask_ollama
    • Removedask_ollama_council
    • Removedask_openrouter
    • Removedask_openrouter_council
    • Removedask_opus5
    • Removedask_sonnet
    • Addedask_verify
    • Changedask_websearch1 field changed
      • changedInput schema / properties / context_ref / description
        Previous value: -"Key(s) of context saved with `context_write` to pull in and prepend to `context` — paste a big context ONCE, reference it by key here. Missing keys are reported, not fatal."New value: +"Key(s) of context saved with `context(op=\"write\", …)` to pull in and prepend to `context` — paste a big context ONCE, reference it by key here. Missing keys are reported, not fatal."
    • Removedconfigure_atlas_council
    • Addedconfigure_council
    • Addedconfigure_disabled
    • Removedconfigure_ollama_council
    • Removedconfigure_openrouter_council
    • Addedcontext
    • Removedcontext_delete
    • Removedcontext_list
    • Removedcontext_pack
    • Changedcontext_read2 fields changed
      • changedInput schema / properties / key / description
        Previous value: -"Key to read back."New value: +"Key to read back. Omit to LIST every stored key (with its size, age and description) — the discovery call before re-pasting context."
      • changedInput schema / required
        Previous value: -[
        -  "key"
        -]New value: +[]
    • Removedcontext_write
    • Removedlist_atlas_models
    • Removedlist_lms_models
    • Addedlist_models
    • Removedlist_ollama_models
    • Removedlist_openrouter_models
    • Changedreset_session1 field changed
      • changedInput schema / properties / model / enum
        Previous value: -[
        -  "fable",
        -  "opus5",
        -  "opus",
        -  "opus-5",
        -  "claude-opus-5"
        -]New value: +[
        +  "fable",
        +  "opus",
        +  "opus5",
        +  "opus55",
        +  "opus48",
        +  "claude-opus-4-8",
        +  "claude-opus-5",
        +  "claude-opus-5-5",
        +  "opus-4.8",
        +  "opus-48",
        +  "opus-5",
        +  "opus-5.5",
        +  "opus-55",
        +  "opus4.8",
        +  "opus5.5"
        +]
  2. 30 tool updatesv0.16.0
    • Changedask1 field changed
      • changedInput schema / properties / trusted / description
        Previous value: -"Operator-authorized. When true, the prohibited-use denylist runs in log-only mode: security vocabulary in the question is audited but does not block. Use for legitimate security-engineering work (PoC analysis, CVE research, binary hardening review) where the question genuinely needs security terms. Takes effect ONLY when the operator has set ASK_FABLE_ALLOW_TRUSTED (env or config); otherwise the flag is ignored and the denylist still applies."New value: +"Operator-authorized. When true, the prohibited-use denylist runs in log-only mode: security vocabulary in the question AND in `context` is audited but does not block. Use for legitimate security-engineering work (PoC analysis, CVE research, binary hardening review) where the ask genuinely needs security terms. Takes effect ONLY when the operator has set ASK_FABLE_ALLOW_TRUSTED (env or config); otherwise the flag is ignored and the denylist still applies."
    • Changedask_atlas1 field changed
      • addedInput schema / properties / trusted
        Added value: +{
        +  "default": false,
        +  "description": "Operator-authorized. When true, the prohibited-use denylist runs in log-only mode: security vocabulary in the question AND in `context` is audited but does not block. Use for legitimate security-engineering work (PoC analysis, CVE research, binary hardening review) where the ask genuinely needs security terms. Takes effect ONLY when the operator has set ASK_FABLE_ALLOW_TRUSTED (env or config); otherwise the flag is ignored and the denylist still applies.",
        +  "type": "boolean"
        +}
    • Changedask_atlas_council2 fields changed
      • changedInput schema / properties / synthesizer / anyOf
        Previous value: -[
        -  {
        -    "enum": [
        -      "fable",
        -      "fable51",
        -      "opus",
        -      "deepseek",
        -      "minimax",
        -      "glm",
        -      "gemini",
        -      "codex",
        -      "grok",
        -      "kimi",
        -      "claude-fable-5-1",
        -      "claude-opus-5",
        -      "fable-5.1",
        -      "fable-51",
        -      "fable5.1",
        -      "gpt",
        -      "m3",
        -      "opus-5",
        -      "opus5",
        -      "xai"
        -    ],
        -    "type": "string"
        -  },
        -  {
        -    "pattern": "^ollama:.+",
        -    "type": "string"
        -  },
        -  {
        -    "pattern": "^atlas:.+",
        -    "type": "string"
        -  },
        -  {
        -    "pattern": "^openrouter:.+",
        -    "type": "string"
        -  }
        -]New value: +[
        +  {
        +    "enum": [
        +      "fable",
        +      "fable51",
        +      "opus",
        +      "opus48",
        +      "sonnet",
        +      "deepseek",
        +      "minimax",
        +      "glm",
        +      "gemini",
        +      "codex",
        +      "grok",
        +      "kimi",
        +      "claude-fable-5-1",
        +      "claude-opus-4-8",
        +      "claude-opus-5",
        +      "claude-sonnet-5",
        +      "fable-5.1",
        +      "fable-51",
        +      "fable5.1",
        +      "gpt",
        +      "m3",
        +      "opus-4.8",
        +      "opus-48",
        +      "opus-5",
        +      "opus4.8",
        +      "opus5",
        +      "sonnet-5",
        +      "sonnet5",
        +      "xai"
        +    ],
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^ollama:.+",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^atlas:.+",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^openrouter:.+",
        +    "type": "string"
        +  }
        +]
      • addedInput schema / properties / trusted
        Added value: +{
        +  "default": false,
        +  "description": "Operator-authorized. When true, the prohibited-use denylist runs in log-only mode: security vocabulary in the question AND in `context` is audited but does not block. Use for legitimate security-engineering work (PoC analysis, CVE research, binary hardening review) where the ask genuinely needs security terms. Takes effect ONLY when the operator has set ASK_FABLE_ALLOW_TRUSTED (env or config); otherwise the flag is ignored and the denylist still applies.",
        +  "type": "boolean"
        +}
    • Changedask_chain1 field changed
      • addedInput schema / properties / trusted
        Added value: +{
        +  "default": false,
        +  "description": "Operator-authorized. When true, the prohibited-use denylist runs in log-only mode: security vocabulary in the question AND in `context` is audited but does not block. Use for legitimate security-engineering work (PoC analysis, CVE research, binary hardening review) where the ask genuinely needs security terms. Takes effect ONLY when the operator has set ASK_FABLE_ALLOW_TRUSTED (env or config); otherwise the flag is ignored and the denylist still applies.",
        +  "type": "boolean"
        +}
    • Changedask_codex1 field changed
      • addedInput schema / properties / trusted
        Added value: +{
        +  "default": false,
        +  "description": "Operator-authorized. When true, the prohibited-use denylist runs in log-only mode: security vocabulary in the question AND in `context` is audited but does not block. Use for legitimate security-engineering work (PoC analysis, CVE research, binary hardening review) where the ask genuinely needs security terms. Takes effect ONLY when the operator has set ASK_FABLE_ALLOW_TRUSTED (env or config); otherwise the flag is ignored and the denylist still applies.",
        +  "type": "boolean"
        +}
    • Changedask_conference2 fields changed
      • changedInput schema / properties / models / items / anyOf
        Previous value: -[
        -  {
        -    "enum": [
        -      "fable",
        -      "fable51",
        -      "opus",
        -      "deepseek",
        -      "minimax",
        -      "glm",
        -      "gemini",
        -      "codex",
        -      "grok",
        -      "kimi",
        -      "claude-fable-5-1",
        -      "claude-opus-5",
        -      "fable-5.1",
        -      "fable-51",
        -      "fable5.1",
        -      "gpt",
        -      "m3",
        -      "opus-5",
        -      "opus5",
        -      "xai",
        -      "twin",
        -      "twin flame",
        -      "twin flames",
        -      "twin-flame",
        -      "twin-flames",
        -      "twin_flame",
        -      "twin_flames",
        -      "twinflame",
        -      "twinflames",
        -      "twins"
        -    ],
        -    "type": "string"
        -  },
        -  {
        -    "pattern": "^ollama:.+",
        -    "type": "string"
        -  },
        -  {
        -    "pattern": "^atlas:.+",
        -    "type": "string"
        -  },
        -  {
        -    "pattern": "^openrouter:.+",
        -    "type": "string"
        -  }
        -]New value: +[
        +  {
        +    "enum": [
        +      "fable",
        +      "fable51",
        +      "opus",
        +      "opus48",
        +      "sonnet",
        +      "deepseek",
        +      "minimax",
        +      "glm",
        +      "gemini",
        +      "codex",
        +      "grok",
        +      "kimi",
        +      "claude-fable-5-1",
        +      "claude-opus-4-8",
        +      "claude-opus-5",
        +      "claude-sonnet-5",
        +      "fable-5.1",
        +      "fable-51",
        +      "fable5.1",
        +      "gpt",
        +      "m3",
        +      "opus-4.8",
        +      "opus-48",
        +      "opus-5",
        +      "opus4.8",
        +      "opus5",
        +      "sonnet-5",
        +      "sonnet5",
        +      "xai",
        +      "twin",
        +      "twin flame",
        +      "twin flames",
        +      "twin-flame",
        +      "twin-flames",
        +      "twin_flame",
        +      "twin_flames",
        +      "twinflame",
        +      "twinflames",
        +      "twins"
        +    ],
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^ollama:.+",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^atlas:.+",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^openrouter:.+",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^lmstudio:.+",
        +    "type": "string"
        +  }
        +]
      • addedInput schema / properties / trusted
        Added value: +{
        +  "default": false,
        +  "description": "Operator-authorized. When true, the prohibited-use denylist runs in log-only mode: security vocabulary in the question AND in `context` is audited but does not block. Use for legitimate security-engineering work (PoC analysis, CVE research, binary hardening review) where the ask genuinely needs security terms. Takes effect ONLY when the operator has set ASK_FABLE_ALLOW_TRUSTED (env or config); otherwise the flag is ignored and the denylist still applies.",
        +  "type": "boolean"
        +}
    • Changedask_council3 fields changed
      • changedInput schema / properties / models / items / anyOf
        Previous value: -[
        -  {
        -    "enum": [
        -      "fable",
        -      "fable51",
        -      "opus",
        -      "deepseek",
        -      "minimax",
        -      "glm",
        -      "gemini",
        -      "codex",
        -      "grok",
        -      "kimi",
        -      "claude-fable-5-1",
        -      "claude-opus-5",
        -      "fable-5.1",
        -      "fable-51",
        -      "fable5.1",
        -      "gpt",
        -      "m3",
        -      "opus-5",
        -      "opus5",
        -      "xai",
        -      "twin",
        -      "twin flame",
        -      "twin flames",
        -      "twin-flame",
        -      "twin-flames",
        -      "twin_flame",
        -      "twin_flames",
        -      "twinflame",
        -      "twinflames",
        -      "twins"
        -    ],
        -    "type": "string"
        -  },
        -  {
        -    "pattern": "^ollama:.+",
        -    "type": "string"
        -  },
        -  {
        -    "pattern": "^atlas:.+",
        -    "type": "string"
        -  },
        -  {
        -    "pattern": "^openrouter:.+",
        -    "type": "string"
        -  }
        -]New value: +[
        +  {
        +    "enum": [
        +      "fable",
        +      "fable51",
        +      "opus",
        +      "opus48",
        +      "sonnet",
        +      "deepseek",
        +      "minimax",
        +      "glm",
        +      "gemini",
        +      "codex",
        +      "grok",
        +      "kimi",
        +      "claude-fable-5-1",
        +      "claude-opus-4-8",
        +      "claude-opus-5",
        +      "claude-sonnet-5",
        +      "fable-5.1",
        +      "fable-51",
        +      "fable5.1",
        +      "gpt",
        +      "m3",
        +      "opus-4.8",
        +      "opus-48",
        +      "opus-5",
        +      "opus4.8",
        +      "opus5",
        +      "sonnet-5",
        +      "sonnet5",
        +      "xai",
        +      "twin",
        +      "twin flame",
        +      "twin flames",
        +      "twin-flame",
        +      "twin-flames",
        +      "twin_flame",
        +      "twin_flames",
        +      "twinflame",
        +      "twinflames",
        +      "twins"
        +    ],
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^ollama:.+",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^atlas:.+",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^openrouter:.+",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^lmstudio:.+",
        +    "type": "string"
        +  }
        +]
      • changedInput schema / properties / synthesizer / anyOf
        Previous value: -[
        -  {
        -    "enum": [
        -      "fable",
        -      "fable51",
        -      "opus",
        -      "deepseek",
        -      "minimax",
        -      "glm",
        -      "gemini",
        -      "codex",
        -      "grok",
        -      "kimi",
        -      "claude-fable-5-1",
        -      "claude-opus-5",
        -      "fable-5.1",
        -      "fable-51",
        -      "fable5.1",
        -      "gpt",
        -      "m3",
        -      "opus-5",
        -      "opus5",
        -      "xai"
        -    ],
        -    "type": "string"
        -  },
        -  {
        -    "pattern": "^ollama:.+",
        -    "type": "string"
        -  },
        -  {
        -    "pattern": "^atlas:.+",
        -    "type": "string"
        -  },
        -  {
        -    "pattern": "^openrouter:.+",
        -    "type": "string"
        -  }
        -]New value: +[
        +  {
        +    "enum": [
        +      "fable",
        +      "fable51",
        +      "opus",
        +      "opus48",
        +      "sonnet",
        +      "deepseek",
        +      "minimax",
        +      "glm",
        +      "gemini",
        +      "codex",
        +      "grok",
        +      "kimi",
        +      "claude-fable-5-1",
        +      "claude-opus-4-8",
        +      "claude-opus-5",
        +      "claude-sonnet-5",
        +      "fable-5.1",
        +      "fable-51",
        +      "fable5.1",
        +      "gpt",
        +      "m3",
        +      "opus-4.8",
        +      "opus-48",
        +      "opus-5",
        +      "opus4.8",
        +      "opus5",
        +      "sonnet-5",
        +      "sonnet5",
        +      "xai"
        +    ],
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^ollama:.+",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^atlas:.+",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^openrouter:.+",
        +    "type": "string"
        +  }
        +]
      • addedInput schema / properties / trusted
        Added value: +{
        +  "default": false,
        +  "description": "Operator-authorized. When true, the prohibited-use denylist runs in log-only mode: security vocabulary in the question AND in `context` is audited but does not block. Use for legitimate security-engineering work (PoC analysis, CVE research, binary hardening review) where the ask genuinely needs security terms. Takes effect ONLY when the operator has set ASK_FABLE_ALLOW_TRUSTED (env or config); otherwise the flag is ignored and the denylist still applies.",
        +  "type": "boolean"
        +}
    • Changedask_debate1 field changed
      • addedInput schema / properties / trusted
        Added value: +{
        +  "default": false,
        +  "description": "Operator-authorized. When true, the prohibited-use denylist runs in log-only mode: security vocabulary in the question AND in `context` is audited but does not block. Use for legitimate security-engineering work (PoC analysis, CVE research, binary hardening review) where the ask genuinely needs security terms. Takes effect ONLY when the operator has set ASK_FABLE_ALLOW_TRUSTED (env or config); otherwise the flag is ignored and the denylist still applies.",
        +  "type": "boolean"
        +}
    • Changedask_deepseek1 field changed
      • addedInput schema / properties / trusted
        Added value: +{
        +  "default": false,
        +  "description": "Operator-authorized. When true, the prohibited-use denylist runs in log-only mode: security vocabulary in the question AND in `context` is audited but does not block. Use for legitimate security-engineering work (PoC analysis, CVE research, binary hardening review) where the ask genuinely needs security terms. Takes effect ONLY when the operator has set ASK_FABLE_ALLOW_TRUSTED (env or config); otherwise the flag is ignored and the denylist still applies.",
        +  "type": "boolean"
        +}
    • Changedask_falsify1 field changed
      • addedInput schema / properties / trusted
        Added value: +{
        +  "default": false,
        +  "description": "Operator-authorized. When true, the prohibited-use denylist runs in log-only mode: security vocabulary in the question AND in `context` is audited but does not block. Use for legitimate security-engineering work (PoC analysis, CVE research, binary hardening review) where the ask genuinely needs security terms. Takes effect ONLY when the operator has set ASK_FABLE_ALLOW_TRUSTED (env or config); otherwise the flag is ignored and the denylist still applies.",
        +  "type": "boolean"
        +}
    • Changedask_gemini1 field changed
      • addedInput schema / properties / trusted
        Added value: +{
        +  "default": false,
        +  "description": "Operator-authorized. When true, the prohibited-use denylist runs in log-only mode: security vocabulary in the question AND in `context` is audited but does not block. Use for legitimate security-engineering work (PoC analysis, CVE research, binary hardening review) where the ask genuinely needs security terms. Takes effect ONLY when the operator has set ASK_FABLE_ALLOW_TRUSTED (env or config); otherwise the flag is ignored and the denylist still applies.",
        +  "type": "boolean"
        +}
    • Changedask_glm1 field changed
      • addedInput schema / properties / trusted
        Added value: +{
        +  "default": false,
        +  "description": "Operator-authorized. When true, the prohibited-use denylist runs in log-only mode: security vocabulary in the question AND in `context` is audited but does not block. Use for legitimate security-engineering work (PoC analysis, CVE research, binary hardening review) where the ask genuinely needs security terms. Takes effect ONLY when the operator has set ASK_FABLE_ALLOW_TRUSTED (env or config); otherwise the flag is ignored and the denylist still applies.",
        +  "type": "boolean"
        +}
    • Changedask_grok1 field changed
      • addedInput schema / properties / trusted
        Added value: +{
        +  "default": false,
        +  "description": "Operator-authorized. When true, the prohibited-use denylist runs in log-only mode: security vocabulary in the question AND in `context` is audited but does not block. Use for legitimate security-engineering work (PoC analysis, CVE research, binary hardening review) where the ask genuinely needs security terms. Takes effect ONLY when the operator has set ASK_FABLE_ALLOW_TRUSTED (env or config); otherwise the flag is ignored and the denylist still applies.",
        +  "type": "boolean"
        +}
    • Changedask_kimi1 field changed
      • addedInput schema / properties / trusted
        Added value: +{
        +  "default": false,
        +  "description": "Operator-authorized. When true, the prohibited-use denylist runs in log-only mode: security vocabulary in the question AND in `context` is audited but does not block. Use for legitimate security-engineering work (PoC analysis, CVE research, binary hardening review) where the ask genuinely needs security terms. Takes effect ONLY when the operator has set ASK_FABLE_ALLOW_TRUSTED (env or config); otherwise the flag is ignored and the denylist still applies.",
        +  "type": "boolean"
        +}
    • Addedask_lms
    • Addedask_lms_council
    • Changedask_m31 field changed
      • addedInput schema / properties / trusted
        Added value: +{
        +  "default": false,
        +  "description": "Operator-authorized. When true, the prohibited-use denylist runs in log-only mode: security vocabulary in the question AND in `context` is audited but does not block. Use for legitimate security-engineering work (PoC analysis, CVE research, binary hardening review) where the ask genuinely needs security terms. Takes effect ONLY when the operator has set ASK_FABLE_ALLOW_TRUSTED (env or config); otherwise the flag is ignored and the denylist still applies.",
        +  "type": "boolean"
        +}
    • Changedask_ollama1 field changed
      • addedInput schema / properties / trusted
        Added value: +{
        +  "default": false,
        +  "description": "Operator-authorized. When true, the prohibited-use denylist runs in log-only mode: security vocabulary in the question AND in `context` is audited but does not block. Use for legitimate security-engineering work (PoC analysis, CVE research, binary hardening review) where the ask genuinely needs security terms. Takes effect ONLY when the operator has set ASK_FABLE_ALLOW_TRUSTED (env or config); otherwise the flag is ignored and the denylist still applies.",
        +  "type": "boolean"
        +}
    • Changedask_ollama_council1 field changed
      • addedInput schema / properties / trusted
        Added value: +{
        +  "default": false,
        +  "description": "Operator-authorized. When true, the prohibited-use denylist runs in log-only mode: security vocabulary in the question AND in `context` is audited but does not block. Use for legitimate security-engineering work (PoC analysis, CVE research, binary hardening review) where the ask genuinely needs security terms. Takes effect ONLY when the operator has set ASK_FABLE_ALLOW_TRUSTED (env or config); otherwise the flag is ignored and the denylist still applies.",
        +  "type": "boolean"
        +}
    • Changedask_openrouter1 field changed
      • addedInput schema / properties / trusted
        Added value: +{
        +  "default": false,
        +  "description": "Operator-authorized. When true, the prohibited-use denylist runs in log-only mode: security vocabulary in the question AND in `context` is audited but does not block. Use for legitimate security-engineering work (PoC analysis, CVE research, binary hardening review) where the ask genuinely needs security terms. Takes effect ONLY when the operator has set ASK_FABLE_ALLOW_TRUSTED (env or config); otherwise the flag is ignored and the denylist still applies.",
        +  "type": "boolean"
        +}
    • Changedask_openrouter_council2 fields changed
      • changedInput schema / properties / synthesizer / anyOf
        Previous value: -[
        -  {
        -    "enum": [
        -      "fable",
        -      "fable51",
        -      "opus",
        -      "deepseek",
        -      "minimax",
        -      "glm",
        -      "gemini",
        -      "codex",
        -      "grok",
        -      "kimi",
        -      "claude-fable-5-1",
        -      "claude-opus-5",
        -      "fable-5.1",
        -      "fable-51",
        -      "fable5.1",
        -      "gpt",
        -      "m3",
        -      "opus-5",
        -      "opus5",
        -      "xai"
        -    ],
        -    "type": "string"
        -  },
        -  {
        -    "pattern": "^ollama:.+",
        -    "type": "string"
        -  },
        -  {
        -    "pattern": "^atlas:.+",
        -    "type": "string"
        -  },
        -  {
        -    "pattern": "^openrouter:.+",
        -    "type": "string"
        -  }
        -]New value: +[
        +  {
        +    "enum": [
        +      "fable",
        +      "fable51",
        +      "opus",
        +      "opus48",
        +      "sonnet",
        +      "deepseek",
        +      "minimax",
        +      "glm",
        +      "gemini",
        +      "codex",
        +      "grok",
        +      "kimi",
        +      "claude-fable-5-1",
        +      "claude-opus-4-8",
        +      "claude-opus-5",
        +      "claude-sonnet-5",
        +      "fable-5.1",
        +      "fable-51",
        +      "fable5.1",
        +      "gpt",
        +      "m3",
        +      "opus-4.8",
        +      "opus-48",
        +      "opus-5",
        +      "opus4.8",
        +      "opus5",
        +      "sonnet-5",
        +      "sonnet5",
        +      "xai"
        +    ],
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^ollama:.+",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^atlas:.+",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^openrouter:.+",
        +    "type": "string"
        +  }
        +]
      • addedInput schema / properties / trusted
        Added value: +{
        +  "default": false,
        +  "description": "Operator-authorized. When true, the prohibited-use denylist runs in log-only mode: security vocabulary in the question AND in `context` is audited but does not block. Use for legitimate security-engineering work (PoC analysis, CVE research, binary hardening review) where the ask genuinely needs security terms. Takes effect ONLY when the operator has set ASK_FABLE_ALLOW_TRUSTED (env or config); otherwise the flag is ignored and the denylist still applies.",
        +  "type": "boolean"
        +}
    • Changedask_opus51 field changed
      • changedInput schema / properties / trusted / description
        Previous value: -"Operator-authorized. When true, the prohibited-use denylist runs in log-only mode: security vocabulary in the question is audited but does not block. Use for legitimate security-engineering work (PoC analysis, CVE research, binary hardening review) where the question genuinely needs security terms. Takes effect ONLY when the operator has set ASK_FABLE_ALLOW_TRUSTED (env or config); otherwise the flag is ignored and the denylist still applies."New value: +"Operator-authorized. When true, the prohibited-use denylist runs in log-only mode: security vocabulary in the question AND in `context` is audited but does not block. Use for legitimate security-engineering work (PoC analysis, CVE research, binary hardening review) where the ask genuinely needs security terms. Takes effect ONLY when the operator has set ASK_FABLE_ALLOW_TRUSTED (env or config); otherwise the flag is ignored and the denylist still applies."
    • Addedask_sonnet
    • Addedask_websearch
    • Addedcode_index
    • Addedcode_search
    • Addeddiagnose
    • Addedhost_status
    • Addedlist_lms_models
    • Addedunload_lms_model
  3. 4 tool updatesv0.15.0
    • Changedask_atlas1 field changed
      • changedInput schema / properties / effort / description
        Previous value: -"Answer budget / reasoning depth (default 'deep' — max reasoning). 'quick' (~1k tokens, concise), 'standard' (~4k tokens), 'deep' (~16k tokens, opportunistically sends reasoning_effort:high). Atlas has no documented reasoning_effort, so effort maps to max_tokens + timeout + a prompt nudge."New value: +"Answer budget / reasoning depth (default 'deep' — max reasoning). 'quick' (~1k tokens, concise), 'standard' (~4k tokens), 'deep' (~16k tokens, opportunistically sends reasoning_effort:high). Atlas has no documented reasoning_effort, so effort maps to max_tokens + timeout + a prompt nudge. Atlas's gateway returns HTTP 504 for any request still running at ~242s, so a long 'deep' generation can fail outright; retry at 'standard'/'quick', or set config `atlas_max_tokens` / `atlas_timeout` (env ASK_FABLE_ATLAS_MAX_TOKENS / ASK_FABLE_ATLAS_TIMEOUT) to fit its cap and wall-clock to the window."
    • Changedask_atlas_council1 field changed
      • changedInput schema / properties / question / description
        Previous value: -"A specific software/engineering question to ask several Atlas Cloud models; the adjudicator (GPT-5.6 Sol by default) then synthesizes their answers into one."New value: +"A specific software/engineering question to ask several Atlas Cloud models; the adjudicator (GPT-5.6 Sol by default) then synthesizes their answers into one. Panelists use the configured Atlas effort and are subject to Atlas's ~242s gateway cutoff (HTTP 504 on longer generations) — lower `atlas_effort` or pin `atlas_max_tokens` / `atlas_timeout` when panels fail that way."
    • Addedask_falsify
    • Changedask_openrouter1 field changed
      • changedInput schema / properties / effort / description
        Previous value: -"Answer budget / reasoning depth (default 'deep' — max reasoning). 'quick' (~1k tokens, concise), 'standard' (~4k tokens), 'deep' (~16k tokens). Unlike Atlas, OpenRouter publishes each model's supported reasoning efforts, so 'deep' sends the highest effort the CHOSEN model actually accepts and omits the field entirely for non-reasoning models — no wasted probe request."New value: +"Answer budget / reasoning depth (default 'deep' — max reasoning). 'quick' (~1k tokens, concise), 'standard' (~4k tokens), 'deep' (~16k tokens). Unlike Atlas, OpenRouter publishes each model's supported reasoning efforts, so 'deep' sends the highest effort the CHOSEN model actually accepts and omits the field entirely for non-reasoning models — no wasted probe request. Also unlike Atlas, no fixed ~242s gateway cutoff was measured (a 16k-token non-streaming call returned in 314s), so long calls are bounded by the client timeout, not the gateway."
  4. 7 tool updatesv0.14.0
    • Changedask1 field changed
      • changedInput schema / properties / trusted / description
        Previous value: -"Operator-authorized. When true, the prohibited-use denylist runs in log-only mode: security vocabulary in the question is audited but does not block. Use for legitimate security-engineering work (PoC analysis, CVE research, binary hardening review) where the question genuinely needs security terms. The operator is responsible for authorizing this flag."New value: +"Operator-authorized. When true, the prohibited-use denylist runs in log-only mode: security vocabulary in the question is audited but does not block. Use for legitimate security-engineering work (PoC analysis, CVE research, binary hardening review) where the question genuinely needs security terms. Takes effect ONLY when the operator has set ASK_FABLE_ALLOW_TRUSTED (env or config); otherwise the flag is ignored and the denylist still applies."
    • Addedask_conference
    • Addedask_fable_help
    • Changedask_openrouter1 field changed
      • changedInput schema / properties / model / description
        Previous value: -"OpenRouter model id (e.g. 'anthropic/claude-fable-5.1', 'openai/gpt-5.6-sol', 'deepseek/deepseek-v4-pro', 'google/gemini-3.8-flash'). Omit to use the server's default. Call `list_openrouter_models` to see the live catalog with pricing and per-model reasoning support, then offer the user a selection menu."New value: +"OpenRouter model id (e.g. 'anthropic/claude-fable-5.1', 'openai/gpt-5.6-sol', 'deepseek/deepseek-v4.1-flash', 'google/gemini-3.8-flash'). Omit to use the server's default. Call `list_openrouter_models` to see the live catalog with pricing and per-model reasoning support, then offer the user a selection menu."
    • Changedask_openrouter_council1 field changed
      • changedInput schema / properties / models / description
        Previous value: -"OpenRouter model ids (e.g. ['anthropic/claude-fable-5.1', 'deepseek/deepseek-v4-pro']); an 'openrouter:' prefix is optional. Omit to use the configured set (configure_openrouter_council / ASK_FABLE_OPENROUTER_COUNCIL), else 3 featured catalog models, one per provider. A panel spanning several labs is the point — one key, genuinely different reasoners."New value: +"OpenRouter model ids (e.g. ['anthropic/claude-fable-5.1', 'deepseek/deepseek-v4.1-flash']); an 'openrouter:' prefix is optional. Omit to use the configured set (configure_openrouter_council / ASK_FABLE_OPENROUTER_COUNCIL), else 3 featured catalog models, one per provider. A panel spanning several labs is the point — one key, genuinely different reasoners."
    • Changedask_opus51 field changed
      • changedInput schema / properties / trusted / description
        Previous value: -"Operator-authorized. When true, the prohibited-use denylist runs in log-only mode: security vocabulary in the question is audited but does not block. Use for legitimate security-engineering work (PoC analysis, CVE research, binary hardening review) where the question genuinely needs security terms. The operator is responsible for authorizing this flag."New value: +"Operator-authorized. When true, the prohibited-use denylist runs in log-only mode: security vocabulary in the question is audited but does not block. Use for legitimate security-engineering work (PoC analysis, CVE research, binary hardening review) where the question genuinely needs security terms. Takes effect ONLY when the operator has set ASK_FABLE_ALLOW_TRUSTED (env or config); otherwise the flag is ignored and the denylist still applies."
    • Changedconfigure_openrouter_council1 field changed
      • changedInput schema / properties / models / description
        Previous value: -"OpenRouter model ids to persist as the default council (e.g. ['anthropic/claude-fable-5.1', 'openai/gpt-5.6-sol', 'deepseek/deepseek-v4-pro']). Call `list_openrouter_models` first."New value: +"OpenRouter model ids to persist as the default council (e.g. ['anthropic/claude-fable-5.1', 'openai/gpt-5.6-sol', 'deepseek/deepseek-v4.1-flash']). Call `list_openrouter_models` first."
  5. 37 tool updatesv0.12.0
    • First observedask
    • First observedask_atlas
    • First observedask_atlas_council
    • First observedask_chain
    • First observedask_codex
    • First observedask_council
    • First observedask_debate
    • First observedask_deepseek
    • First observedask_gemini
    • First observedask_glm
    • First observedask_grok
    • First observedask_kimi
    • First observedask_m3
    • First observedask_ollama
    • First observedask_ollama_council
    • First observedask_openrouter
    • First observedask_openrouter_council
    • First observedask_opus5
    • First observedconfigure_atlas_council
    • First observedconfigure_ollama_council
    • First observedconfigure_openrouter_council
    • First observedconfigure_tracing
    • First observedcontext_delete
    • First observedcontext_list
    • First observedcontext_pack
    • First observedcontext_read
    • First observedcontext_write
    • First observedlist_atlas_models
    • First observedlist_ollama_models
    • First observedlist_openrouter_models
    • First observedreset_session
    • First observedsession_list
    • First observedsession_peek
    • First observedsession_stats
    • First observedstats
    • First observedtrace_get
    • First observedtrace_list

TDQS

A3.9/5.0

Scored across 28 tools

Disambiguation4/5

The nine ask_* variants (ask, ask_model, ask_council, ask_chain, ask_debate, ask_falsify, ask_conference, ask_verify, ask_websearch) all route model reasoning, and some pairs like ask_council vs ask_conference could be confused at a glance. However, each tool's intended use is sharply delineated in its description, and non-ask tools such as context/context_read, session_list/session_peek, and trace_list/trace_get are cleanly separated.

Naming Consistency3/5

The server leans heavily on an ask_ prefix and several verb_noun names like list_models, reset_session, and code_search, giving a clear overall structure. But it mixes in bare one-word names (ask, context, diagnose, stats), noun-style labels (host_status), and a single context verb while its read counterpart is context_read, making the pattern inconsistent.

Tool Count3/5

At 28 tools, this sits above the 16–25 heavy range and includes a large family of reasoning modes that could plausibly be consolidated. The breadth is nevertheless justified by the server's expansive purpose—multi-model orchestration, provider configuration, context sharing, code indexing, tracing, session coordination, and observability—so the count feels earned rather than padded.

Completeness5/5

The tool surface fully covers the multi-model reasoning lifecycle: single and multi-model queries, adversarial verification, web research, session/context management, configurability, diagnostics, code search, tracing, and usage analytics. There are no obvious dead ends or missing operations for the stated scope.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers