Skip to main content
Glama

ask-fable

Request-level policy compliance does not imply workflow-level capability containment.

A small, portable, installable MCP server that lets coding agents request guarded code and architecture reasoning from Fable (the newest claude-fable-*), Claude Opus 5 (claude-opus-5), MiniMax (MiniMax-M3), Gemini, Codex, GLM, DeepSeek, and Ollama Cloud models. It can ask one backend, synthesize a parallel council, run an ordered chain, or stage a structured 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. 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) / ask_opus5 (Opus 5)

Compare independent answers in parallel

ask_council

Draft, critique, then decide in order

ask_chain

Stress-test a high-impact decision

ask_debate

Select a task-matched Atlas Cloud model

list_atlas_modelsask_atlas

Atlas council with GPT-5.6 Sol adjudicating

ask_atlas_council

Reuse large code context without pasting it again

context_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 four 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

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, MiniMax, Gemini, Codex, Grok, GLM, DeepSeek, Ollama, and Atlas Cloud. Unavailable council members are reported and skipped instead of failing the whole request.

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 buscontext_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 / context_list / context_delete 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.

  • 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. 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.

  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; the guard scans the question, not the context.

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 with Claude Code, 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 Claude Code

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"]). Restart Claude Code; all 37 mcp__ask_fable__* tools become available to the client. 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.

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

Using opencode? The docs/OPENCODE.md guide walks through the full setup — the exact schema-valid MCP block, optional API keys, the restart-to-load behavior, and troubleshooting. The snippet below is the minimal registration.

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

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 37 MCP tools. You only need to remember four entry points: ask, ask_council, ask_chain, and ask_debate. Everything else selects a specific backend, manages reusable context, or inspects what happened.

Quick menu: CLAUDE.md lists all 37 tools grouped by purpose (core reasoning · single models · context bus · ops & observability), one line each — a fast lookup without the full prose below.

Goal

Start with

Escalate when

Solve or debug one problem

ask (Fable) or ask_opus5 (Claude Opus 5 — ~half the price, faster)

use context_ref for large reusable context

Get one alternate opinion

ask_m3, ask_deepseek, ask_glm (cheap direct APIs first), ask_gemini, ask_codex, ask_grok, ask_kimi, ask_ollama, ask_atlas, or ask_openrouter (~400 models, one key)

use a council when you need comparison

Pick an Atlas model for a task

list_atlas_models(task="…")

call ask_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_atlas_council

pin the panel with configure_atlas_council

Make a contentious decision

ask_debate

keep the scope narrow; it is the most expensive mode

Inspect what happened

trace_list then trace_get

enable full mode only when redacted content is needed

The four reasoning functions

Function

Mental model

Runs

Returns

ask / ask_opus5

One expert with memory

One Fable / Opus 5 call

Answer, sidecar, follow-up hints

ask_council

Independent panel, then synthesis

Parallel + synthesis

Merged answer, sources, consensus

ask_chain

Draft → critique → decision

Sequential

Final answer, stages, recommendation drift

ask_debate

Claim → challenge → ruling

Sequential, adversarial

Ruling, claim ledger, resolution

Start with ask. Choose a council when independence matters, a chain when order matters, and a debate only when the disagreement itself needs to be tested.

The sections below are the exhaustive reference. For a guided walkthrough with copyable examples, use the setup and usage guide.

Single-model reasoning

  • ask(question, context="", context_ref=None, session="default", reset=false) — guarded reasoning from Fable. Reuse the same session key for follow-ups (Fable keeps context server-side); a new key or reset=true starts a fresh topic. Pass context_ref (a key or list of keys stored with context_write) to pull big context in by reference instead of re-pasting. The result carries a sidecar; when the model wants more it returns a followup telling you what to paste and to re-ask on the same session (with likely_already_pasted flagging what's probably already there). All ask tools accept context and context_ref.

  • ask_opus5(question, context="", context_ref=None, session="default", reset=false) — the same tool on Claude Opus 5 (claude-opus-5): identical arguments, identical result shape, same multi-turn session/reset model, same Claude Code OAuth session (no API key, nothing extra to configure). Opus 5 is roughly half Fable's price and faster, so prefer it for high-volume or long back-and-forth work and keep ask for the hardest calls; running both on one question is a cheap two-model cross-check. Sessions are namespaced per tool — the same key on ask and ask_opus5 is two independent conversations, and reset_session(session, model="opus5") clears this one. Opus 5 is also the opus token (aliases opus5, opus-5) in every multi-model mode: council member or synthesizer, chain stage, debate proposer/opponent/adjudicator.

  • ask_m3(question, context="") — the same guarded reasoning from MiniMax (MiniMax-M3) on its own, independent of Fable. Single-turn. Returns {"status":"ok","model":"MiniMax-M3","answer":...}.

  • ask_glm(question, context="") — the same guarded reasoning from GLM (glm-5.2) on its own, via Z.ai's Anthropic-compatible endpoint. Single-turn. Requires ASK_FABLE_GLM_API_KEY on the server (returns {"status":"error","kind":"not_configured",...} otherwise). Returns {"status":"ok","model":"glm-5.2","answer":...}.

  • ask_deepseek(question, context="") — the same guarded reasoning from DeepSeek (deepseek-v4-pro) on its own, via DeepSeek's Anthropic-compatible endpoint. Cheap direct API — prefer it over pricier cloud models for a quick independent opinion. Single-turn. Requires ASK_FABLE_DEEPSEEK_API_KEY on the server (returns {"status":"error","kind":"not_configured",...} otherwise). Returns {"status":"ok","model":"deepseek-v4-pro","answer":...}.

  • ask_gemini(question, context="") — the same guarded reasoning from Google Gemini (Gemini 3.1 Pro (High)) on its own, via the already-authenticated local agy CLI (no API key set by the server — like mmx). Single-turn. Requires the agy CLI installed and signed in (returns {"status":"error","kind":"binary_missing",...} otherwise). Returns {"status":"ok","model":"Gemini 3.1 Pro (High)","answer":...}.

  • ask_codex(question, context="") — the same guarded reasoning from OpenAI (gpt-5.6-sol) on its own, via the already-authenticated local codex CLI in non-interactive codex exec mode (no API key set by the server — like mmx/agy). Runs hermetically and read-only — it can't see your repo, so put the code it needs in context. Single-turn. Requires the codex CLI installed and logged in (returns {"status":"error","kind":"binary_missing",...} otherwise). Returns {"status":"ok","model":"gpt-5.6-sol","answer":...}.

  • ask_grok(question, context="", effort=None) — guarded, single-turn reasoning from Grok (grok-4.6) through the already-authenticated local grok CLI. The default low reasoning effort keeps context-heavy turns bounded; override it with effort or ASK_FABLE_GROK_REASONING. Requires the grok CLI installed and logged in (returns {"status":"error","kind":"binary_missing",...} otherwise). Returns {"status":"ok","model":"grok-4.6","answer":...}.

  • ask_kimi(question, context="", effort=None) — guarded, single-turn reasoning from Kimi (kimi-code/k3) through the local kimi CLI on your Kimi Code subscription, sandboxed to pure text reasoning (no tools, no filesystem). Prefer it over ask_atlas with moonshotai/kimi-*: same model family, no Atlas key, no per-token billing. The CLI passes the prompt as one argv value, which the kernel caps near 131k bytes, so an oversized prompt is refused with {"status":"error","kind":"context_too_large",...} pointing at the HTTP route. Returns {"status":"ok","model":"kimi-code/k3","answer":...}.

  • ask_atlas(question, context="", model=None, effort=None) — guarded, single-turn reasoning from an Atlas Cloud text model (for example xai/grok-4.6 or openai/gpt-5.6-sol) over the OpenAI /v1/chat/completions shape. Supports quick, standard, and deep effort. It needs ASK_FABLE_ATLAS_API_KEY or ATLASCLOUD_API_KEY, except xai/grok-* models route to the authenticated local grok CLI when present. Returns {"status":"ok","model":"...","answer":...}.

  • ask_openrouter(question, context="", model=None, effort=None) — guarded, single-turn reasoning from any of ~400 OpenRouter models (Anthropic, OpenAI, Google, DeepSeek, Meta, Qwen, Moonshot, xAI, Mistral, …) behind one API key. The catch-all for a model with no dedicated tool, and the cheapest way to compare labs without configuring each provider. Call list_openrouter_models first — the catalog is free. Needs ASK_FABLE_OPENROUTER_API_KEY (or OPENROUTER_API_KEY); Grok and Kimi ids reroute to the local grok/kimi CLIs when installed. Unlike Atlas, effort is clamped to what the chosen model actually supports — OpenRouter publishes each model's reasoning efforts, so there is no wasted probe request. The result reports the call's real dollar cost.

  • list_openrouter_models(refresh=true, task="", limit=5, interactive=true) — the live OpenRouter catalog with price per million, context window and per-model reasoning support. Free (no key). task="…" ranks a provider-diverse shortlist from the catalog's own fields — reasoning support, context, price, release date — so a model released today ranks correctly with no change here. A task mentioning cheap/fast/high-volume flips the ranking toward the cheap and free tiers.

  • ask_openrouter_council(question, models=[], synthesizer=None) — a cross-lab panel on one key, with the same GPT-first adjudicator ladder as ask_atlas_council. configure_openrouter_council persists your panel.

  • list_atlas_models(refresh=true, task="", limit=5, interactive=true) — fetch the free live Atlas text-model catalog. With task, it ranks a provider-diverse shortlist from the catalog's capability profiles, tags, context window, latency, and pricing. On MCP clients that support form elicitation it opens a native model + effort picker; otherwise it returns the same choices under picker for the host to render. An accepted native choice is returned as selection: {action:"accept", model, effort}. limit is 2–8 (default 5); refresh:false makes no network call and returns only effort choices. The ranking is live metadata-based guidance, not an independent benchmark.

    You can simply ask your agent: “Give me the best Atlas models for debugging a large Rust repository.” It should call list_atlas_models(task="debugging a large Rust repository"), show the picker, and pass the accepted model and effort to ask_atlas.

Multi-model reasoning

  • ask_council(question, context="", models=["fable","minimax"]) — ask several models the same question in parallel, then have Fable synthesize their answers into one merged answer (reconciling conflicts on the merits). The payload also returns each oracle's raw answer under sources. Single-turn. Degrades to whichever oracle(s) answered, and only refuses/errors when none do. models picks from fable (the newest Fable), fable51 (claude-fable-5-1, pinned), opus (claude-opus-5, same OAuth session as Fable — always available), minimax (MiniMax-M3, via the mmx CLI), gemini (Gemini 3.1 Pro, via the agy CLI), codex (GPT-5.6 Sol, via the codex CLI), glm (GLM-5.2, via Z.ai's Anthropic endpoint), and deepseek (deepseek-v4-pro, via DeepSeek's Anthropic endpoint) — e.g. models=["fable","opus","minimax","gemini","codex","glm","deepseek"] for a seven-model council. gemini needs the local agy CLI; glm and deepseek require API keys configured on the server (below); an unconfigured or unreachable oracle is reported in sources and skipped, never fatal. No provider keys are set by the server itself — each bridge reuses env config or an already-authenticated CLI/session. You can also add Ollama Cloud models as ollama:<model> tokens — e.g. models=["fable","ollama:qwen3-coder:480b-cloud","ollama:nemotron-3-ultra:cloud"] (reached via your local ollama daemon by default — no key). Atlas Cloud models work the same way with atlas:<model-id> tokens in councils, chains, and debates. For a task-matched multi-model call, call list_atlas_models(task="review a risky database migration") first, then use returned IDs such as models=["fable","atlas:deepseek-ai/deepseek-v4-pro","atlas:zai-org/glm-5.2"]. One models entry can be the group token twin — the twin flames — which expands to both Anthropic reasoners at once, fable + opus. Both ride the same OAuth session as ask/ask_opus5, so models=["twin"] is a dual Fable/Opus 5 invocation that needs no provider keys at all — the cheapest real second opinion available — and models=["twin","minimax"] adds a third voice to it. twins, twin flames, twin-flame and twin_flames all name the same pair. A group only makes sense where a list of models is taken; a single-model slot (synthesizer, and the debate roles) rejects it with a bad_args error rather than silently keeping just Fable. Instead of listing models, pass a named tier: "default" (fable+minimax, +deepseek when ASK_FABLE_DEEPSEEK_API_KEY is set — cheap direct models are preferred and consulted first) · "twin" (the twin flames, fable+opus) · "middle" (+opus+glm+gemini+codex+grok+kimi, cheap-first order) · "full" (+the configured Ollama Cloud models). An explicit models list overrides tier. The result adds 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 synthesizer sees the panel anonymized (Expert A/B, Fable last) so it can't favor its own answer — on a material split it's told to pick a side, not average.

  • ask_chain(question, context="", pipeline="m3 > glm > deepseek > fable") — the sequential counterpart to ask_council: thread a question through an ordered pipeline (a pipeline string split on >, or an ordered models array), each stage refining the last. 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 anonymized as peers. Order matters and repeats are allowed (fable > glm > fable = draft → critique → re-decide; alias m3 = minimax). The twin group token expands in place to two stages, fable then opus — so m3 > twin is a cheap draft finished by both Anthropic reasoners in turn. A stage that refuses/errors is skipped (recorded) and the chain continues; if the final stage fails, Fable synthesizes the survivors. The result adds a recommendation_drift trail + 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. Best for cost-tiered escalation (a cheap/fast model drafts, Fable finalizes) and explicit draft → red-team → decide pipelines; costs more latency than a council (stages run in sequence, not parallel), so reserve it for when the ordered refinement is the point.

  • ask_debate(question, context="", proposer="fable", opponent="minimax", adjudicator="fable", rounds=1) — the adversarial counterpart: pit two models AGAINST each other, then have a fresh anonymized third model adjudicate. The proposer commits to a position decomposed into load-bearing claims; the opponent must dispose of each claim (concede, or contest with a concrete failure scenario); the proposer revises under fire; the adjudicator rules on the merits. Pick the pair (e.g. opponent="codex" for Fable vs GPT-5.6 Sol, or opponent="glm") and, if you want someone other than Fable ruling, the judge (adjudicator="opus" for Claude Opus 5) — keep it off the debating pair so the ruling stays third-party. rounds=2 adds a rebuttal pass. The outcome is decided server-side from the ledger, surfaced as debate.resolution: 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). Also returns recommendation_drift, decisive_argument, and low_effort_opposition. Degrades to a single-critic pass if the opponent is unconfigured. The most expensive mode (up to four sequential calls), so reserve it for a genuinely contentious, hard-to-reverse decision. Aliases: m3 = minimax, gpt = codex, opus5 = opus.

  • ask_ollama(question, context="", model=...) — guarded reasoning from a single Ollama Cloud model on its own. model is a cloud model id (e.g. kimi-k2.7-code:cloud, gpt-oss:120b-cloud, deepseek-v3.2:cloud); omit it to use ASK_FABLE_OLLAMA_MODEL. Single-turn. Reached via your local ollama daemon by default (needs ollama signin; no API key) — point ASK_FABLE_OLLAMA_BASE_URL at https://ollama.com (+ key) for direct cloud.

  • ask_ollama_council(question, context="", models=[...]) — fan a question out to several Ollama Cloud models (an ollama: prefix on each id is optional), then have Fable synthesize their answers into one — same contract as ask_council, but the council is Ollama-only. Omit models to use the server's configured set (the config file or ASK_FABLE_OLLAMA_COUNCIL, default: minimax-m3:cloud, glm-5.2:cloud, nemotron-3-ultra:cloud, qwen3-coder:480b-cloud, kimi-k2.7-code:cloud, deepseek-v4-pro:cloud, gpt-oss:120b-cloud — kept lean; the 675b/397b generalists are left out so the parallel council stays fast, add them per call if you want them).

  • ask_atlas_council(question, context="", models=[...], synthesizer=...) — the Atlas-only council with GPT-5.6 Sol as the default adjudicator. Fans the question out to several Atlas Cloud models (an atlas: prefix on each id is optional), then the adjudicator reconciles them: the local codex CLI (GPT-5.6 Sol, no Atlas tokens) when installed → Atlas-hosted openai/gpt-5.6-sol → Fable. Omit models to use the configured set (configure_atlas_council / ASK_FABLE_ATLAS_COUNCIL), else 3 featured catalog models (one per provider). xai/grok-* members reroute to the local grok CLI keylessly; anything else needs the Atlas API key. The result's synthesis block reports which adjudicator actually ran (and any fallback). The same synthesizer parameter also works on plain ask_council.

Setup and reusable context

  • list_ollama_models(refresh=true) — discover what's actually available for the council: the live ollama.com catalog (GLM, MiniMax-M3, Qwen, Kimi, DeepSeek, Nemotron, Mistral, gpt-oss, …) as daemon-ready ids, the models already pulled locally, and the currently-configured council. Read-only.

  • configure_ollama_council(models=[...], default_model=...)save a chosen Ollama council so it sticks across sessions. Writes ask_fable's config file (${XDG_CONFIG_HOME:-~/.config}/ask_fable/config.json), which overrides the ASK_FABLE_OLLAMA_* env defaults. Bare names are normalized (minimax-m3minimax-m3:cloud); an ollama: prefix is optional. Together these two tools let an agent, the first time you want an Ollama council, offer to set it up — list the options, ask which you want, and persist your pick — instead of you hand-editing env vars.

  • configure_atlas_council(models=[...], synthesizer=...)save a chosen Atlas council (and optionally its adjudicator) so it sticks across sessions. Writes the same config file (atlas_council / atlas_synthesizer keys), which overrides the ASK_FABLE_ATLAS_COUNCIL / ASK_FABLE_ATLAS_SYNTHESIZER env defaults. An atlas: prefix is optional; aliases resolve (gpt persists as codex, a bare openai/gpt-5.6-sol as atlas:openai/gpt-5.6-sol). Ground the picks with list_atlas_models first.

  • configure_tracing(trace_mode="safe"|"full", stream_reasoning=true|false) — toggle reasoning-trace capture at runtime, persisted to the same config file. trace_mode="full" records redacted model reasoning into traces / trace bundles (and saves answer markdown); stream_reasoning streams model thinking live to the server console. Both override the ASK_FABLE_TRACE_MODE / ASK_FABLE_STREAM_REASONING env defaults and apply on the next call — no ~/.claude.json edit or restart. Pass either or both.

  • context_write(key, value, description="") — the context bus: store a chunk of context (code, a stack trace, design notes) under a stable key, then reference it via context_ref on any ask tool instead of re-pasting. Shared by every agent on the server (a sibling agent can read it); reusing a key overwrites. A durable best-effort SQLite store (${XDG_STATE_HOME}/ask_fable/context.db, override with ASK_FABLE_CONTEXT_PATH).

  • context_read(key) / context_list() / context_delete(key) — read back a stored blob (+ size/age/description), list what's stored (keys + metadata, never the full values), or delete one. context_list is the way to discover what's already available before re-pasting.

  • reset_session(session="default", model="fable", save=true) — dump the transcript (each turn's Q/A and any provider reasoning captured for that turn) to ${XDG_STATE_HOME}/ask_fable/sessions/<key>-<ts>.md (when save) and clear it. model selects which tool's conversation to clear — "fable" for ask, "opus5" for ask_opus5 (they namespace sessions separately).

Operations and observability

  • stats(window="24h", by="model", model=..., session=...) — read-only usage/health stats aggregated from the audit log (rotations included): per-bucket calls / allowed / refused / errors, avg + p95 latency, and error rate, plus totals. window is 1h/24h/7d/all; by buckets per model (a council counts under its synthesizer), provider (per backend call — the only view that sees council/chain/debate members one by one), tool, session, day, project, cache, or mode; the optional filters narrow to one backend or workflow. Calls the circuit breaker shed are reported as circuit_open, not as errors or latency. Council/chain audit records also carry quorum/consensus/synth_fallback, so you can see degradation trends ("have my councils been running 1-of-5 all day?") — no model call, never cached.

  • trace_list(limit=20, tool=..., status=..., provider=..., session=..., project=..., before=...) — list recent schema-v2 request traces without raw content. Filter by request or provider metadata and page with before.

  • trace_get(trace_id, include_content=false, max_chars=4000) — read one ordered event timeline and its artifact references. In full mode, include_content=true returns a redacted, bounded excerpt of that trace's bundle.

Cross-instance session hub

The hub is a local coordination dashboard, not a second form of model memory. Every successful ask that passes the tool-level cache is mirrored after its oracle result is available. That result can still come from an underlying per-oracle cache. Use a meaningful shared session label when several local agents are working the same decision, then inspect that work without re-running it:

ask({ "question": "Which migration path is safest?", "context": "…", "session": "db-migration" })

session_list({})                              // live sessions in this project
session_peek({ "session_key": "db-migration" }) // retained Q/A turns across agents
session_stats({ "window_s": 86400 })          // 24-hour totals by oracle, agent, status
  • session_list(all_projects=false, active_only=true, limit=50) lists one row per (session_key, agent_id), newest first. It is scoped to the current project by default; all_projects:true exposes every project recorded by this local database. active_only:true hides sessions whose heartbeat is older than five minutes (tune with ASK_FABLE_HUB_STALE_SECONDS); pass false to include retained history. limit is 1–200.

  • session_peek(session_key, agent_id=None) returns the full retained question and answer history in chronological order. It intentionally spans projects for a matching session label; pass agent_id to narrow it. Choose labels that do not collide across sensitive work, and do not use this tool where you are not permitted to read the local user’s other project data.

  • session_stats(all_projects=false, window_s=86400) aggregates turns by oracle, agent, and status across MCP instances. It is project-scoped by default; window_s:0 includes all retained turn history. Its session totals are not restricted to that time window.

The hub is deliberately visibility-only: it is never read by ask, councils, chains, or debates; it cannot resume Fable's per-process SessionStore; and refused/error turns are not mirrored. It therefore cannot feed another agent’s history back into an oracle answer automatically. An agent can still explicitly read a hub turn and relay it in a later prompt. It retains complete questions and answers, plus session, agent, project, oracle, status, timing, and an SDK session identifier when supplied. It does not separately store the supplied context, although a response can echo it. Treat its database as sensitive. The default path is ${XDG_STATE_HOME:-~/.local/state}/ask_fable/hub.db (new files are owner-only 0600, SQLite WAL, per-operation connections). It is machine-local unless you deliberately set ASK_FABLE_HUB_PATH to shared storage.

For ask_council, ask_chain, ask_debate, ask_ollama_council, and ask_atlas_council, session is a hub coordination key, not a Fable multi-turn session; if omitted it defaults to the tool name. Hub retention is a best-effort row cap, not a deletion schedule: the default 10,000 stored turns are swept oldest-first roughly every 100 writes. Disabling the hub stops future reads and writes but does not delete already stored data.

Configure the Ollama council

You never have to hand-edit env vars to choose your Ollama council — the agent can set it up for you. The first time you want an Ollama council (or any time you say "configure ask_fable" / "set up the council"), the server's instructions prompt the agent to:

  1. call list_ollama_models — which returns the live ollama.com catalog, the models already pulled locally, and the currently-configured council:

    { "status": "ok", "reachable": true,
      "available_cloud": ["deepseek-v4-pro:cloud", "glm-5.2:cloud", "minimax-m3:cloud",
                           "mistral-large-3:675b-cloud", "nemotron-3-ultra:cloud",
                           "qwen3-coder:480b-cloud", "..."],
      "pulled_local": ["gpt-oss:120b-cloud"],
      "configured_council": ["minimax-m3:cloud", "glm-5.2:cloud", "..."],
      "config_file": "~/.config/ask_fable/config.json" }
  2. ask you which of those you want, then call configure_ollama_council with:

    {
      "models": [
        "minimax-m3",
        "glm-5.2",
        "qwen3-coder:480b-cloud",
        "deepseek-v4-pro"
      ],
      "default_model": "gpt-oss:120b-cloud"
    }

The choice is written to ${XDG_CONFIG_HOME:-~/.config}/ask_fable/config.json ({"ollama_council": [...], "ollama_model": "..."}) and overrides the ASK_FABLE_OLLAMA_COUNCIL / ASK_FABLE_OLLAMA_MODEL env vars — so it persists across sessions and every later ask_ollama_council (and the full tier) uses it. Precedence, highest first: config file → env var → built-in default.

Observability and response shape

Every MCP call receives a correlated trace_id. Safe mode (the default) writes schema-v2 metadata only: no raw prompt or answer is included in that trace. The separate legacy audit log can store raw values only when its explicit ASK_FABLE_AUDIT_RAW switch is enabled. Full mode writes a redacted, size-capped trace bundle under ${XDG_STATE_HOME}/ask_fable/traces/; it may include provider-emitted reasoning and tool activity when available. trace_list finds recent calls and trace_get reads a timeline or a bounded bundle excerpt.

Answer Markdown is separate: ASK_FABLE_SAVE=1 saves every successful answer under ${XDG_STATE_HOME}/ask_fable/answers/ (override with ASK_FABLE_OUTPUT_DIR), ASK_FABLE_SAVE=0 disables it, and an unset setting saves only in full trace mode. Its path is returned as "saved". Saved files include a ## Thinking section only when a provider emitted reasoning. This is independent of reset_session dumps.

Response contract

Every tool returns one JSON object. A successful answer looks like this:

{
  "status": "ok",
  "answer": "…",
  "sidecar": {
    "recommendation": "apply",
    "confidence": "high",
    "needs_context": []
  },
  "trace_id": "…",
  "telemetry": { "status": "ok" }
}

sidecar is {recommendation, confidence, needs_context} (null when the model emitted no parseable one). When the model wants more it also carries "followup":{"needs_context":[...],"how":...,"likely_already_pasted":[...]}, and a stuck re-ask loop terminates with "status":"context_exhausted" (+ best-effort answer; tune the cap with ASK_FABLE_MAX_NEEDS_CONTEXT, default 2). Any context_ref keys used are echoed as "context_ref_resolved":[...] / "context_ref_missing":[...]; an all-missing ref with no other context returns "status":"needs_context" (+ a did_you_mean suggestion) without calling the model.

Councils add "mode":"council", "synthesizer", "sources" (each entry with that model's recommendation), the "consensus"/"material_disagreement" signal, plus a small envelope so you can tell whether the council degraded: "quorum":"N/M" (answered / asked), "effective_models":[...], "degraded":bool, "confidence":"high|medium|low", and "recommended_next_action":... — a 1/M quorum is one opinion, not consensus.

Chains (ask_chain) add "mode":"chain", the "pipeline" (ordered model labels), "answered_by", a lean "stages" list (each with stage/model/role/status/ recommendation/confidence), the "recommendation_drift" trail + "material_drift" flag, and "answered":N/"requested":M; a "fallback" note appears when a failed final stage was reconciled by Fable.

Debates (ask_debate) add "mode":"debate", "answered_by", a lean "turns" list (each with role/model/status/recommendation/confidence), and a "debate" block: "pairing", "rounds", "resolution" (conceded/converged/adjudicated/stalemate/ degraded_single_critic), "contested_claims_remaining", "recommendation_drift", "low_effort_opposition", "material_disagreement", and "decisive_argument" (the adjudicator's quoted pivot). The full transcript goes to the saved markdown file, not the inline reply. Shares the ASK_FABLE_CHAIN_TIMEOUT wall-clock bound.

Failure responses are structured too:

{ "status": "refused", "stage": "guard", "reason": "…" }
{ "status": "error", "kind": "timeout", "detail": "…" }

Caching

The single-shot tools (ask_m3/ask_glm/ask_deepseek/ask_gemini/ask_codex/ask_grok/ask_kimi/ask_ollama/ask_atlas/ask_openrouter), the councils, and ask_chain (keyed on the ordered pipeline) cache successful answers keyed on hash(tool + models + normalized question + context). An exact re-ask within the freshness window returns instantly with "cached":true, "cache_age_s":N, and a duplicate-nudge "note" — so a local agent's edit/verify re-ask loop doesn't pay for the model every time. ask (multi-turn) is never cached. Tune with ASK_FABLE_CACHE_TTL (seconds, default 3600) or disable with ASK_FABLE_CACHE=0.

Console progress

All ask tools print a tidy, TTY-colored trace of what's happening — guard result, each model being asked, elapsed time, reasoning excerpts, and the synthesis step — to stderr (Claude Code surfaces this in its MCP logs / claude --debug; in a terminal it prints live). stdout is reserved for the JSON-RPC protocol. Silence it with ASK_FABLE_QUIET=1; hide just the model reasoning with ASK_FABLE_SHOW_REASONING=0. Stream Fable's reasoning live (block by block, as it arrives) with ASK_FABLE_STREAM_REASONING=1 instead of one post-hoc excerpt — Fable only, since the other backends don't stream. To surface a reasoning excerpt inline in the tool result (so it shows in the Claude Code conversation, not just the stderr trace), set ASK_FABLE_RETURN_THINKING=1, capped by ASK_FABLE_THINKING_CHARS (default 4000). Full trace bundles are written only in full trace mode; answer Markdown follows the ASK_FABLE_SAVE policy described above.

Backend setup

For ask_council's MiniMax oracle, install the MiniMax mmx CLI and log in once (mmx auth login) — the server sets no key, it reuses that session exactly as the Fable bridge reuses Claude Code's OAuth. ask-fable always passes --model MiniMax-M3 explicitly, but the mmx CLI's own default is older (MiniMax-M2.7); standardize it once with mmx config set --key default_text_model --value MiniMax-M3 so ad-hoc mmx calls match. The Gemini oracle works the same way: install the agy CLI and sign in once — the server sets no key and reuses that session. ask-fable calls it in non-interactive print mode (agy --model "Gemini 3.1 Pro (High)" -p "<prompt>") and reads the plain-text answer from stdout. Pick a different agy model (run agy models to list them) with ASK_FABLE_GEMINI_MODEL. The Codex oracle works the same way: install OpenAI's codex CLI and run codex login once — the server sets no key and reuses that session. ask-fable calls it non-interactively (codex exec) with a hermetic, read-only invocation (--ignore-user-config --sandbox read-only), so the operator's own ~/.codex/config.toml and hooks can't change the answer and it can't touch the repo. Pick a different model with ASK_FABLE_CODEX_MODEL and its reasoning effort with ASK_FABLE_CODEX_REASONING (default high). The Ollama Cloud oracles work the same way: install ollama, run ollama signin once, and the local daemon proxies :cloud models — no API key needed (this is the default; ASK_FABLE_OLLAMA_BASE_URL=http://localhost:11434). To hit ollama.com directly instead, set ASK_FABLE_OLLAMA_BASE_URL=https://ollama.com and an ASK_FABLE_OLLAMA_API_KEY. The GLM and DeepSeek oracles are Anthropic-Messages-compatible HTTP endpoints, while Atlas uses the OpenAI chat shape; enable them by putting their keys in the server's registration env (in ~/.claude.json, kept out of the repo), e.g.:

{ "mcpServers": { "ask_fable": { "command": "ask-fable", "env": {
  "ASK_FABLE_GLM_API_KEY": "<z.ai key>",
  "ASK_FABLE_DEEPSEEK_API_KEY": "<deepseek key>",
  "ASK_FABLE_ATLAS_API_KEY": "<Atlas Cloud key>"
} } } }

Configuration reference

Most installations only need a registered Fable bridge. Configure an optional backend, persistence, or trace limit only when you need it; the full reference is grouped below for operators.

Var

Default

Meaning

ASK_FABLE_MIN_LEN / ASK_FABLE_MAX_LEN

3 / 65536

question length bounds

ASK_FABLE_MAX_CONTEXT_LEN

off (unbounded)

optional context cap; any value is floored to 512,000 chars

ASK_FABLE_TIMEOUT

240

per-turn wall-clock seconds

ASK_FABLE_MAX_NEEDS_CONTEXT

2

consecutive needs_more_context turns on a session before ask returns context_exhausted (0 = stop after the first)

ASK_FABLE_USE_CLI

off

force the claude CLI bridge instead of the SDK

ASK_FABLE_FABLE_MODEL

unset (ladder)

pin the exact Fable id for ask and the fable oracle, skipping the newest-first ladder (claude-fable-5-1claude-fable-5). A pinned call never falls back — if that id can't run, the turn fails and says so

ASK_FABLE_CLAUDE_CLI

unset (auto)

pin the Claude Code binary the Agent SDK spawns. By default the SDK prefers the copy vendored inside claude-agent-sdk, which can be months behind the one on your PATH and too old for a newly released model; the bridge hands it the PATH binary instead when that one is strictly newer

ASK_FABLE_MINIMAX_MODEL

MiniMax-M3

model id for the ask_council MiniMax oracle

ASK_FABLE_GEMINI_MODEL

Gemini 3.1 Pro (High)

agy model name for the ask_gemini tool / gemini council oracle (run agy models to list; via the agy CLI)

ASK_FABLE_GEMINI_TIMEOUT

falls back to ASK_FABLE_TIMEOUT, else 240

per-turn seconds for the agy/Gemini oracle specifically — cap this agentic CLI without lowering the global timeout. On timeout the whole agy process group is SIGKILLed (it spawns children), so a slow turn can't hang the call or leak orphans

ASK_FABLE_CODEX_MODEL

gpt-5.6-sol

model id for the ask_codex tool / codex council oracle (via the codex CLI)

ASK_FABLE_CODEX_REASONING

high

reasoning effort passed to codex exec (model_reasoning_effort)

ASK_FABLE_CODEX_TIMEOUT

falls back to ASK_FABLE_TIMEOUT, else 240

per-turn seconds for the codex oracle specifically. On timeout the whole codex process group is SIGKILLed (it spawns children), so a slow turn can't hang the call or leak orphans

ASK_FABLE_GROK_MODEL / ASK_FABLE_GROK_REASONING / ASK_FABLE_GROK_TIMEOUT

grok-4.6 / low / falls back to ASK_FABLE_TIMEOUT

local grok CLI settings. quick, standard, and deep effort presets map to low reasoning to keep context-heavy turns bounded; set ASK_FABLE_GROK_REASONING explicitly for Grok-native medium/high

ASK_FABLE_KIMI_MODEL / ASK_FABLE_KIMI_EFFORT / ASK_FABLE_KIMI_TIMEOUT / ASK_FABLE_KIMI_HOME

kimi-code/k3 / high / falls back to ASK_FABLE_TIMEOUT / ~/.kimi-code

local kimi CLI settings. Effort accepts low/high/max plus the quick/standard/deep presets. The prompt travels as one argv value, so prompts above ~120k bytes are refused with context_too_large — use ask_atlas with moonshotai/kimi-k3 for bigger context

ASK_FABLE_CLI_MAX_PARALLEL

2

maximum concurrent local CLI processes per binary (claude, mmx, grok, codex, agy, kimi); 0 or negative disables this gate and 1 serializes each CLI family. The queue wait counts against the call's own timeout, so a call parked behind busy slots fails as a timeout instead of waiting unboundedly

ASK_FABLE_GLM_API_KEY

Z.ai key that enables the glm council oracle (unset = oracle unavailable)

ASK_FABLE_GLM_BASE_URL / _MODEL

https://api.z.ai/api/anthropic / glm-5.2

GLM endpoint + model

ASK_FABLE_DEEPSEEK_API_KEY

DeepSeek key that enables the deepseek council oracle

ASK_FABLE_DEEPSEEK_BASE_URL / _MODEL

https://api.deepseek.com/anthropic / deepseek-v4-pro

DeepSeek endpoint + model

ASK_FABLE_ATLAS_API_KEY / ATLASCLOUD_API_KEY

Atlas Cloud key for HTTP ask_atlas and atlas:<model-id> calls (either name is accepted); local xai/grok-* routes reuse the authenticated grok CLI

ASK_FABLE_ATLAS_BASE_URL

https://api.atlascloud.ai

Atlas Cloud API base URL; override only with a trusted compatible endpoint because it receives the bearer key and request content

ASK_FABLE_ATLAS_MODEL

xai/grok-4.6

default model for ask_atlas when no model is passed

ASK_FABLE_OPENROUTER_API_KEY / OPENROUTER_API_KEY

OpenRouter key for ask_openrouter, ask_openrouter_council and openrouter:<model-id> tokens (either name is accepted; the catalog needs no key)

ASK_FABLE_OPENROUTER_MODEL

deepseek/deepseek-v4-pro

default model for ask_openrouter when none is passed

ASK_FABLE_OPENROUTER_COUNCIL / _SYNTHESIZER / _EFFORT

default panel, adjudicator and effort for ask_openrouter_council (config keys openrouter_council / openrouter_synthesizer / openrouter_effort win)

ASK_FABLE_ATLAS_EFFORT / ASK_FABLE_EFFORT

deep

default Atlas effort (quick, standard, or deep); atlas_effort / effort in the config file override environment values

ASK_FABLE_ATLAS_COUNCIL

default members for ask_atlas_council (comma/space list of Atlas model ids; config file atlas_council overrides); unset → 3 featured catalog models

ASK_FABLE_ATLAS_SYNTHESIZER

adjudicator for ask_atlas_council (any council token; config file atlas_synthesizer overrides); unset → local codex CLI → atlas:openai/gpt-5.6-solfable

ASK_FABLE_OLLAMA_API_KEY

only for a remote endpoint (ollama.com); the default local daemon needs no key

ASK_FABLE_OLLAMA_BASE_URL

http://localhost:11434

Ollama endpoint (POSTs /api/chat). Default is the local daemon, which proxies :cloud models via ollama signin; set https://ollama.com (+ key) for direct cloud

ASK_FABLE_OLLAMA_MODEL

gpt-oss:120b-cloud

default model for ask_ollama when none is passed (config file ollama_model overrides)

ASK_FABLE_OLLAMA_COUNCIL

minimax-m3:cloud, glm-5.2:cloud, nemotron-3-ultra:cloud, qwen3-coder:480b-cloud, kimi-k2.7-code:cloud, deepseek-v4-pro:cloud, gpt-oss:120b-cloud

models for the full tier + default ask_ollama_council (comma/space list; config file ollama_council overrides)

ASK_FABLE_CONFIG_FILE

${XDG_CONFIG_HOME:-~/.config}/ask_fable/config.json

tool-writable config (ollama_council, ollama_model via configure_ollama_council; atlas_council, atlas_synthesizer via configure_atlas_council; ASK_FABLE_TRACE_MODE, ASK_FABLE_STREAM_REASONING via configure_tracing); overrides the matching env vars

ASK_FABLE_OLLAMA_CATALOG_URL

https://ollama.com

where list_ollama_models fetches the cloud catalog (/api/tags)

ASK_FABLE_MAX_TOKENS

65536

max output tokens for GLM/DeepSeek, Ollama (num_predict), and MiniMax (--max-tokens); Fable uses the model default

ASK_FABLE_QUIET

off

silence the stderr progress/reasoning trace

ASK_FABLE_SHOW_REASONING

on

show model reasoning excerpts in the trace

ASK_FABLE_STREAM_REASONING

off

live-stream Fable's reasoning block-by-block to the stderr trace as it arrives (Fable only; other backends don't stream)

ASK_FABLE_RETURN_THINKING

off

attach a capped reasoning excerpt (thinking) to the tool result body so it renders inline in the client

ASK_FABLE_THINKING_CHARS

4000

cap for the ASK_FABLE_RETURN_THINKING excerpt

ASK_FABLE_DENYLIST_FILE

extra denylist terms (one per line) for the fallback

ASK_FABLE_ALLOWLIST_FILE

benign phrases (one per line) neutralized before matching, to rescue false positives like request payload; rescues only the exact phrase

ASK_FABLE_PROJECT_ROOT

project root that context_pack may read from; unset disables context_pack (returns not_configured). Reads never escape this root

ASK_FABLE_PACK_MAX_CHARS

24000

default total-character budget for a context_pack bundle (over-budget specs are reported in skipped, never truncated)

ASK_FABLE_PACK_MAX_FILES

32

max files admitted in one context_pack

ASK_FABLE_PACK_MAX_FILE_BYTES

1000000

per-file read cap for context_pack (a whole file over this is skipped too_large; a line-range is capped on bytes collected)

ASK_FABLE_AUDIT_PATH

$XDG_STATE_HOME/ask_fable/decisions.jsonl

audit log

ASK_FABLE_AUDIT_RAW

off

store raw questions (and raw context unless overridden); otherwise store SHA-256 metadata only

ASK_FABLE_AUDIT_RAW_CONTEXT

follows ASK_FABLE_AUDIT_RAW

split switch for context_raw only — set 0 with AUDIT_RAW=1 to keep raw questions for debugging while context (the larger proprietary-code / secret-bearing surface) stays hashed-only

ASK_FABLE_CACHE

on

cache successful single-shot/council answers to spare re-ask loops; set 0 to disable

ASK_FABLE_CACHE_TTL

3600

cache freshness window in seconds

ASK_FABLE_CACHE_PATH

$XDG_STATE_HOME/ask_fable/cache.db

SQLite cache location

ASK_FABLE_CACHE_MAX_ROWS

10000

row cap for the answer cache — a periodic sweep (every ~100 writes) deletes TTL-expired rows and trims to 90% of the cap, oldest first

ASK_FABLE_CIRCUIT_BREAKER

on

per-oracle circuit breaker: a chronically-failing backend is auto-skipped in council/chain fan-out (reported as circuit_open in sources, like not_configured); cache hits are still served. Never trips on refused or on config states (not_configured). Set 0 to disable

ASK_FABLE_BREAKER_WINDOW

20

last N outcomes tracked per oracle

ASK_FABLE_BREAKER_THRESHOLD

0.5

error rate over the window that opens the breaker (min 5 samples)

ASK_FABLE_BREAKER_COOLDOWN

300

seconds an open breaker waits before allowing a half-open probe; a probe success closes it and clears the window

ASK_FABLE_CONTEXT_PATH

$XDG_STATE_HOME/ask_fable/context.db

SQLite store for the context bus (context_write/context_ref)

ASK_FABLE_HUB

on

set 0, false, no, or off to disable the cross-instance session hub entirely

ASK_FABLE_HUB_PATH

$XDG_STATE_HOME/ask_fable/hub.db

local SQLite hub database; point it at shared storage only when every reader is trusted

ASK_FABLE_HUB_MAX_ROWS

10000

total retained hub-turn cap; a periodic oldest-first sweep trims history toward 90% of the cap

ASK_FABLE_HUB_STALE_SECONDS

300

heartbeat age after which session_list considers a session stale

ASK_FABLE_HUB_PREVIEW_CHARS

160

maximum last_question preview length returned by session_list

ASK_FABLE_AGENT_ID

inferred from the MCP client

explicit hub attribution label; use it to distinguish local windows/agents when client metadata is not unique

ASK_FABLE_TRACE_MODE

safe

safe stores correlated metadata only; full additionally stores redacted, size-capped trace bundles and answer Markdown

ASK_FABLE_TRACE_DIR

$XDG_STATE_HOME/ask_fable/traces

directory for full-mode trace bundles

ASK_FABLE_TRACE_MAX_CONTENT_BYTES

104857600 (100 MiB)

maximum captured content per full trace bundle; truncation is recorded

ASK_FABLE_TRACE_MAX_EVENT_BYTES

1048576 (1 MiB)

maximum JSONL event-line size accepted while reading traces; oversized lines are discarded safely

ASK_FABLE_TRACE_QUERY_MAX_EVENTS / ASK_FABLE_TRACE_QUERY_MAX_BYTES

100000 / 52428800 (50 MiB)

upper bounds for one trace_list or trace_get scan

ASK_FABLE_PROJECT_ID

derived from the working directory

stable project label stored with each trace; set explicitly to correlate calls across working directories

ASK_FABLE_SAVE

unset

explicit 1 persists answer Markdown and explicit 0 disables it; when unset, Markdown is written only in full trace mode

ASK_FABLE_OUTPUT_DIR

$XDG_STATE_HOME/ask_fable/answers

where saved answers are written (0600 files, 0700 dir)

ASK_FABLE_MAX_ANSWERS

0 (unlimited)

retention cap on saved answer Markdown files; only files ask-fable itself wrote (its own filename shape) are ever pruned. The default answers dir is shared per user — a cap set by one agent prunes the shared archive for all agents/projects

ASK_FABLE_MAX_SESSIONS

0 (unlimited)

retention cap on session transcript dumps; same ownership filter and shared-dir caveat as ASK_FABLE_MAX_ANSWERS

ASK_FABLE_COUNCIL_TIMEOUT

ASK_FABLE_TIMEOUT + 120

hard upper bound (sec) on ask_council wall time — bounds the worst case where a backend swallows its own inner timeout. Oracles that already answered are preserved and synthesized; still-running ones are cancelled and shown as kind:"timeout" in sources. Only an all-timeout council surfaces status:"error", kind:"timeout"

ASK_FABLE_CHAIN_TIMEOUT

max(600, n × ASK_FABLE_TIMEOUT) (min 10)

hard upper bound (sec) on ask_chain wall time (the chain is sequential, so the default scales with the number of stages). Surfaces as status:"error", kind:"timeout" with the partial stages[] collected so far

ASK_FABLE_MAX_PARALLEL

6

semaphore size for council fan-out — bounds simultaneous sockets on the full tier so a 12-model fan-out can't exhaust ulimit -n

ASK_FABLE_AUDIT_MAX_BYTES

52428800 (50 MB)

size cap for the audit log; rotated to decisions.<timestamp>.<seq>.jsonl when exceeded

ASK_FABLE_AUDIT_BACKUPS

unlimited

optional cap on rotated audit segments; set 0 to discard the active segment on rotation

Default-created persisted state (cache, context bus, hub, audit log, saved answers, session dumps, and full-trace bundles) is written to a per-user state dir, with newly created files mode 0600 and parent dirs mode 0700. SQLite stores (cache.db, context.db, hub.db) use WAL journal mode for crash safety. Markdown dumps (saved answers, session transcripts) and the separately located config file go through an atomic tempfile + os.replace + fsync so a crash mid-write can never leave a partial or empty file on disk.

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 / opencode.md (agents re-read those). Copy this block:

## Using ask_fable (external reasoning)

<p align="center">
  <img src="images/ai_council_new.jpg" alt="Abstract representation of multiple AI minds converging">
</p>

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_write` it once and pass `context_ref=<key>` — don't re-paste each time.

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 Claude Code / opencode skills that drive these tools (copy or symlink into ~/.claude/skills/):

  • 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              # 777 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.

Review records

Notable design/quality reviews — several run by dogfooding ask_fable's own oracle tools on this codebase — are recorded under docs/reviews/:

  • Council consensus, request guard & context store (2026-07-12) — coverage-aware council consensus (consensus_votes), the denylist inflection fix, and context-store error visibility, cross-checked by a 6-model council. Also carries the assessment (and corrected bibliography) of the software-decomposition essay that study was based on.

License

MIT

More decision-flow diagrams

The diagrams below zoom in on individual orchestration modes. For the current end-to-end system and request lifecycle, use the two diagrams in How it works; these lower-level charts are implementation aids.

High-Level System Poster

An uber-dense view capturing the entire Fable Council landscape — from multi-modal query ingestion through adversarial arenas, all piped through glowing pathways.

1. The Core Ask Path

The fundamental pathway for asking a single model. Notice how the query is checked against the internal guard rails and SQLite context references before any model inference occurs.

2. Council Fan-out & Synthesis

When parallel multi-model validation is needed, the ask_council mode spins up asynchronous calls to N oracles, parses valid responses, strips their identity (Expert A, Expert B), and tasks Fable with synthesizing an objective outcome.

3. Sequential Chain Logic

For problems that require iterative refinement (Draft → Critique → Decide), the pipeline sequentially routes responses, tracking output drift and handling stage skips gracefully on model failure.

4. Adversarial Debate Mode

The most intense workflow pairs a Proposer and Opponent in multi-round debate. It forces position revision under fire before an anonymized Fable adjudicator evaluates the ledger and resolves the outcome on its merits.

5. Triple-Layer Safeguards

Security runs before the prompt touches the network. This involves sanity length bounds, allow-list phrase neutralization, denylist checking, and an initial model scope-enforcement query.

Available Tools

37 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. ask_opus5 is this same tool on Claude Opus 5 — cheaper and faster; use it for high-volume or long back-and-forth work and keep ask for the hardest calls. Ask the Fable 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.
contextNoOptional code snippets, file paths, or structural context.
sessionNoConversation key. Reuse it to ask follow-ups (Fable keeps context); use a new key or reset=true to start a fresh topic.default
trustedNoOperator-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.
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_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.9/5.0
Behavior5/5

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

With zero annotations, the description carries the full burden and delivers abundantly: the model 'has NO tools and CANNOT open files, so a bare file path is useless to it'; latency is stated ('Answers usually take 1-3 minutes'); refusal scope is enumerated (offensive-security and biology/medicine refused, while security code and CS are in-scope); and the response protocol is disclosed (sidecar, followup, context_exhausted status semantics).

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 (~300 words), but the density is largely justified by the tool's complexity: no annotations, no output schema, 6 params, and a nuanced interaction protocol. It is front-loaded with the default-move directive, though there is some redundancy in 'don't wait to be told and don't wait until you're stuck' immediately followed by the same idea in the next sentence.

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 high-complexity tool with no annotations and no output schema, the description covers everything an agent needs: triggers, scope exclusions, context-passing rules, session semantics, latency, refusal boundaries, and the full response/followup protocol including `sidecar` and `context_exhausted`. The only aspects it omits (trusted, reset) are fully documented in the schema.

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%, but the description adds operational meaning the schemacannot: for context it mandates 'ALWAYS paste the real code... plus any error or failing test'; for question it prescribes 'ONE specific decision... or ONE generative prompt'; for session it explains multi-turn reuse; for context_ref it explains the paste-once-reference-many pattern tied to `context_write`. Only trusted and reset are left to the already-detailed 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?

Spells out a specific verb+resource+domain: 'Ask the Fable 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.' It also distinguishes itself from a large sibling family by declaring itself the 'DEFAULT MOVE' and explicitly naming ask_opus5 as a different-capability variant.

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?

Gives explicit when-to-use triggers ('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') and precise routing: 'use ask_opus5... for high-volume or long back-and-forth work and keep ask for the hardest calls.' It also states when to stop using the tool entirely via the `context_exhausted` status: 'stop re-asking and use your own judgment.'

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

ask_atlasA

Ask a single Atlas Cloud text model — on its own — 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. Pass model to pick from 60+ models (e.g. 'xai/grok-4.6', 'openai/gpt-5.6-sol', 'anthropic/claude-opus-4.8', 'deepseek-ai/deepseek-v4-pro'); omit it to use the default. Pass effort (quick/standard/deep; default deep — max reasoning) to set the answer budget. REACH FOR THIS the first time an Atlas model is wanted: call list_atlas_models(task=<the user's job>); use an accepted native selection when one is returned, or render its structured picker fallback, then call ask_atlas with the selected model and effort (the catalog endpoint is free — no tokens charged). PREFER ask_grok (local grok CLI) over Atlas for xAI Grok models when the binary is installed — ask_atlas with xai/grok-* auto-routes to the local CLI when available. Other Atlas models remain HTTP. Atlas models are ALSO reachable in ask_council / ask_chain / ask_debate as dynamic atlas:<model> tokens, e.g. 'atlas:xai/grok-4.6' (Grok tokens prefer the local CLI when present). OpenRouter models join the same way as 'openrouter:'. Single-turn. Needs ASK_FABLE_ATLAS_API_KEY (or the ATLASCLOUD_API_KEY the Atlas Cloud MCP server already uses) for non-Grok models. 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.

ParametersJSON Schema
NameRequiredDescriptionDefault
modelNoAtlas Cloud model id (e.g. 'xai/grok-4.6', 'openai/gpt-5.6-sol', 'anthropic/claude-opus-4.8'). Omit to use the server's default. Call `list_atlas_models` to see the live catalog with pricing, then offer the user a selection menu.
effortNoAnswer 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.deep
contextNoOptional code snippets, file paths, or structural context.
questionYesA specific software/engineering question to ask an Atlas Cloud text model.
context_refNoKey(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.

TDQS

A4.9/5.0
Behavior5/5

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

With no annotations provided, the description carries the full burden, and it delivers: it discloses single-turn behavior, API key requirements (ASK_FABLE_ATLAS_API_KEY or ATLASCLOUD_API_KEY), local-CLI auto-routing for Grok models, HTTP for others, free model-catalog calls, and refusal domains. It also states that broad conceptual engineering questions are fine while offensive-security and non-software domain asks are refused.

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 the length is largely justified by the tool's routing complexity, auth requirements, and sibling relationships. Core purpose is front-loaded and each sentence carries distinct operational information; however, the density and extended routing details make it slightly harder to scan quickly.

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 and five parameters to contextualize, the description is operationally complete: it covers model selection flow, effort behavior, context usage, auth requirements, cross-tool token syntax, refusal policies, and single-turn semantics. An agent gets enough guidance to invoke the tool correctly and route around alternatives.

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%, but the description adds substantial meaning beyond the schema: it gives concrete model examples, explains the effort parameter's token-budget and reasoning_effort mapping, clarifies the default when model is omitted, and advises passing context for questions about existing code. This exceeds the baseline expected from schema-only documentation.

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, resource, and scope: 'Ask a single Atlas Cloud text model — on its own — to reason about the SOFTWARE/ENGINEERING work you're doing.' It also names the behavioral boundary that separates it from siblings like ask_council, ask_chain, and ask_debate ('single', 'on its own'), making the tool's identity clear.

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, actionable routing: 'REACH FOR THIS the first time an Atlas model is wanted: call list_atlas_models... then call ask_atlas', and it explicitly prefers ask_grok for Grok models when the local CLI exists. It also clarifies when to use sibling multi-model tools via dynamic atlas:<model> tokens, providing both positive and negative selection criteria.

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

ask_atlas_councilA

DIRECTIONAL — the Atlas-only counterpart to ask_council, with GPT-5.6 Sol as the default adjudicator: reserve it for a contentious or hard-to-reverse decision you want several Atlas Cloud models to cross-check, not for routine questions (default to ask; at most one council call per problem, and check quorum/degraded in the result). Ask several Atlas Cloud models the same SOFTWARE/ENGINEERING question at once, then get back one answer the adjudicator synthesizes by reconciling all of them (each raw answer is also returned under sources). The adjudicator defaults GPT-first: the local codex CLI (GPT-5.6 Sol, no Atlas tokens) when installed, else Atlas-hosted 'openai/gpt-5.6-sol', else Fable — override with synthesizer (any council token) or persist a choice with configure_atlas_council; the result's synthesis block reports what actually adjudicated. Pass models as a list of Atlas model ids (e.g. ['zai-org/glm-5.2','deepseek-ai/deepseek-v4-pro', 'moonshotai/kimi-k2']; an 'atlas:' prefix is optional). Omit models to use the configured set (configure_atlas_council / ASK_FABLE_ATLAS_COUNCIL), else 3 featured catalog models, one per provider. Needs ASK_FABLE_ATLAS_API_KEY (or the ATLASCLOUD_API_KEY the Atlas Cloud MCP server already uses); xai/grok-* members reroute to the local grok CLI when installed, no key needed. Use ask_council instead to mix Atlas models with Fable/MiniMax/GLM/DeepSeek in one council. 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
modelsNoAtlas Cloud model ids (e.g. ['zai-org/glm-5.2', 'deepseek-ai/deepseek-v4-pro']); an 'atlas:' prefix is optional. Omit to use the configured set (configure_atlas_council / ASK_FABLE_ATLAS_COUNCIL), else 3 featured catalog models, one per provider. Requires an Atlas API key on the server (xai/grok-* members can reroute to the local grok CLI without one).
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.
questionYesA specific software/engineering question to ask several Atlas Cloud models; the adjudicator (GPT-5.6 Sol by default) then synthesizes their answers into one.
context_refNoKey(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.
synthesizerNoModel that reconciles the panel answers into one. Default ladder: the local codex CLI (GPT-5.6 Sol) when installed → 'atlas:openai/gpt-5.6-sol' when Atlas is configured → 'fable'. Falls back to Fable when the pick is unavailable or fails (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?

With no annotations provided, the description carries the full behavioral disclosure burden and delivers: the adjudicator default ladder (local codex CLI → atlas:openai/gpt-5.6-sol → Fable), a fallback disclosure ('Falls back to Fable when the pick is unavailable or fails'), result-structure hints (`sources`, `synthesis`, `quorum`/`degraded`), authentication requirements, and the grok-to-local-CLI rerouting. It even flags the refusal scope, so an agent can predict failures before invoking.

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 nearly every clause adds information — routing, defaults, auth, failover, scope. It front-loads the pivotal usage constraint ('reserve it for... not for routine questions'), though it packs a lot into run-on parentheticals that would be easier to parse as shorter sentences.

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 6-parameter, annotation-free tool with no output schema, the description covers the full decision-relevant surface: when to choose it, how invocation behaves (synthesis, sources, fallback), how to set models, what auth is needed, and what is refused. It also names the sibling for mixed-provider councils, giving an agent the complete routing picture. The only minor gap is the meaning of `quorum`/`degraded`, but checking them is already flagged.

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 baseline is 3. The description adds genuine value beyond the schema: a concrete example model-id list, the default composition ('3 featured catalog models, one per provider'), the optional 'atlas:' prefix, and the practical note that synthesizer can override with 'any council token'. These enrich the models and synthesizer semantics rather than merely repeating the schema.

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 a specific verb-resource pair: 'Ask several Atlas Cloud models the same SOFTWARE/ENGINEERING question at once, then get back one answer the adjudicator synthesizes.' It immediately distinguishes itself from its closest sibling ('the Atlas-only counterpart to ask_council') and states the exact question scope, including what is refused.

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 when-to-use guidance ('reserve it for a contentious or hard-to-reverse decision'), an explicit when-not-to ('not for routine questions (default to ask)'), a hard constraint ('at most one council call per problem'), and names the routing alternative for mixed-provider councils ('Use ask_council instead to mix Atlas models with Fable/MiniMax/GLM/DeepSeek'). This is textbook conditional routing guidance.

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.
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_write` to pull in and prepend to `context`.

TDQS

A4.9/5.0
Behavior5/5

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

With no annotations provided, the description carries the full burden, and it delivers thoroughly: it explains the sequential stage mechanics, the anti-anchoring critique step, mid-chain failure skipping, final-stage fallback to Fable, the recommendation_drift/material_drift output signals, and the default pipeline when none is given. This is exactly the behavioral context an agent needs beyond structured fields.

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?

Although long, the description is front-loaded with the core distinction, then flows naturally through mechanism, use cases, trade-offs, edge cases, aliases, and defaults. Every sentence carries distinct information — the ideation note, failure behavior, drift signals, and twin expansion are all non-redundant. Given zero annotations, the length is justified and well-structured.

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 6 parameters, no annotations, and no output schema, the description covers the full calling context: what it does, when to use it, expected cost/latency, failure behavior, result signals, aliases, default pipeline, and scope restrictions. An agent would know how to invoke it correctly and interpret the outcome at a sufficient level. The only minor omission is a full return-shape description, but the drift signals are mentioned, and the schema-less context makes this adequate.

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 each parameter already has a detailed description, so the baseline is 3. The tool description adds value beyond the schema by giving a concrete pipeline example ('m3 > glm > deepseek > fable'), clarifying the default pipeline ('minimax > fable'), and explaining why order matters semantically (draft → critique → decide). It does not dwell on context/context_ref, but the schema already covers those sufficiently.

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 line 'DIRECTIONAL, SEQUENTIAL — the relay counterpart to ask_council' immediately names the verb, resource, and mode, and the next sentence draws an explicit contrast with ask_council ('parallel vs ordered pipeline', 'what's true?' vs 'make this answer better'). A reader can distinguish it from siblings instantly, without opening any 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 explicitly states 'Best for two things a council can't do: cost-tiered escalation ... and explicit draft → red-team → decide pipelines' and also warns 'Costs MORE latency than a council ... so reserve it for when the ordered refinement is the point.' It even gives scope exclusions ('direct offensive-security asks and non-software domain knowledge... refused'), giving an agent clear selection criteria versus ask_council and other siblings.

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

ask_codexA

Ask OpenAI's model (GPT-5.6 Sol, via the local codex CLI in non-interactive codex exec mode) — 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. 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. Runs hermetically and read-only (it can't see or touch your repo — put the code it needs in context). Single-turn. Requires the codex CLI installed and logged in on the server (reported as binary_missing otherwise). 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. Use ask for Fable, ask_m3 for MiniMax, ask_gemini for Gemini, ask_glm for GLM, or ask_council to ask several and get a synthesized answer.

ParametersJSON Schema
NameRequiredDescriptionDefault
contextNoOptional code snippets, file paths, or structural context.
questionYesA specific software/engineering question to ask Codex (GPT-5.6 Sol) on its own.
context_refNoKey(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.

TDQS

A4.8/5.0
Behavior5/5

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

No annotations are provided, so the description carries full burden. It discloses hermetic and read-only operation ('can't see or touch your repo'), single-turn behavior, the binary_missing error condition, and refusal boundaries for offensive-security and non-software domains. This is exemplary transparency for a tool with zero 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 front-loaded with the core purpose and every sentence adds functional or routing information. It loses a point due to slight redundancy: `ask_council` appears twice in the alternatives list, and the final enumeration of siblings is lengthy relative to what the sibling list already provides.

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 no output schema and no annotations, the description covers purpose, prerequisites, error mode, behavioral limits, scope restrictions, and context usage. Nothing an agent needs to decide whether to call this tool or how to pass the required parameters is missing. The only absence is an explicit return format, but for an ask-style tool that is sufficiently implied.

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 description coverage is 100%, so the baseline is 3. The description adds usage meaning beyond the schema by explaining the `context` parameter's purpose ('put the code it needs in `context`') and clarifying what kinds of `question` are acceptable ('Broad and conceptual engineering questions... are fine'). It doesn't redundantly repeat schema text, and `context_ref` is already well documented in the schema.

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 verb and resource: 'Ask OpenAI's model (GPT-5.6 Sol, via the local codex CLI...)' and enumerates the scope: reasoning about code structure, data/control flow, architecture, and design trade-offs. It distinguishes itself from siblings by explicitly naming alternates at the end, so an agent can tell it apart.

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: 'add a snippet or file path in `context` when the question is about existing code' and routes to alternatives: 'Use `ask` for Fable's built-in ChatGPT, `ask_chain`/`ask_debate` for multi-step reasoning, `ask_council` for broader advisor groups...' It also states prerequisites: 'Requires the `codex` CLI installed and logged in on the server.'

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-v4-pro) 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 Claude Opus 5 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 5 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). 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' = Claude Opus 5, '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.
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_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.9/5.0
Behavior5/5

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

With no annotations provided, the description carries the full behavioral burden, and it delivers comprehensively. It discloses that the tool is slow/heavy, that `quorum`/`degraded` in the result may indicate a 1-of-N answer is only one opinion, that raw answers are returned under `sources`, that panel answers are anonymized to blunt self-preference bias, and that the synthesizer falls back to Fable when unavailable or failing. It also surfaces non-fatal failure modes: unconfigured models are 'reported and skipped, not fatal', and unreachable Ollama daemons are 'reported+skipped'. This is far beyond what the schema or 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 but front-loaded with purpose and usage, then progressively details model selection, tiers, result signals, and synthesizer behavior — a sensible structure for a genuinely complex tool. However, there is clear redundancy: the 'twin flames' expansion is explained multiple times (in the main body, in the models parameter semantics, and echoed in tier semantics), and the model list/alias explanations overlap heavily with the already-100%-covered input schema. It earns most of its sentences, but some trimming would improve signal density.

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 7 parameters, no annotations, and no output schema, the description is remarkably complete. It explains the result shape (consensus signal, `material_disagreement`, `sources` entries with per-model `recommendation`, and a `synthesis` block reporting what actually ran), covers edge cases (unconfigured models skipped, Ollama unreachable, synthesizer fallback), and delineates the domain scope including refusals. An agent has enough information to invoke the tool correctly, interpret its results, and recover from failures without external documentation.

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?

Even though schema description coverage is 100% and the baseline is 3, the description adds substantial meaning beyond the schema. It explains model aliases and semantic subtleties ('fable' tracks newest automatically vs 'fable51' pins the version; 'twin' expands to both reasoners on one OAuth session), clarifies provider prerequisites ('gemini'/'codex'/'grok'/'kimi' need local CLIs; 'glm'/'deepseek' need API keys), details the `tier` presets ('middle' adds opus+glm+etc., cheap models first), and documents synthesizer fallback behavior. This materially improves an agent's ability to choose correct parameter values.

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 clear directive: 'reserve this for a genuinely contentious or HARD-TO-REVERSE decision' and immediately names the resource (a council of models) and the action (asking several models, synthesizing one answer). It explicitly differentiates from 'ask' by stating it is 'slower and heavier' and for multi-opinion cross-checking rather than routine questions. This is a specific verb+resource+scope definition that tells an agent exactly what the tool is for and what it is not for.

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 provides explicit when-to-use guidance ('genuinely contentious or HARD-TO-REVERSE decision', 'divergent brainstorming'), explicit when-not-to-use guidance ('DON'T reach for it on routine questions — default to ask'), and even a dosage constraint ('use at most one council call per problem'). It also names the sibling alternative directly ('default to `ask`') and clarifies scope boundaries relative to `ask` ('Same scope as `ask`; direct offensive-security asks... are refused').

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.
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_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?

With no annotations provided, the description carries the full behavioral burden and does so thoroughly. It discloses the deterministic resolution values ('conceded', 'converged', 'adjudicated', 'stalemate'), the confidence downgrade on stalemate, the cost of up to four sequential model calls, the degradation to a single-critic pass when opponent is unconfigured, and refusal scope for offensive security and non-software domains.

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 every clause earns its place given the tool's complexity. It is front-loaded with the directional/adversarial core and the sibling comparison before diving into parameters. It could be more scannable with bullet points, but the density of high-signal information justifies the length.

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 an 8-parameter tool with no output schema, the description is complete: it explains workflow, model role selection, defaults, aliases, outcome vocabulary, cost, fallback behavior, and allowed/refused domains. An agent has everything it needs to invoke ask_debate correctly and interpret its resolution, with no missing structural information.

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 genuine value over the schema: concrete model choices (proposer='fable', opponent='codex', adjudicator='opus'), alias resolution ('m3'=minimax, 'gpt'=codex, 'opus5'=opus), the strategic advice to keep the adjudicator off the debating pair, and the meaning of rounds. This goes beyond restating parameter types.

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, vivid verb phrase — 'pit two models AGAINST each other over a structured claims ledger, then have a fresh third model adjudicate' — and names the exact workflow (propose, refute, revise, rule). It explicitly contrasts with ask_council and ask_chain, so an agent can immediately tell this tool apart from its closest 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?

It says precisely when to use it: 'Reserve it for a genuinely contentious, hard-to-reverse SOFTWARE decision' with examples like concurrency soundness or approach X vs Y, and when not to use it: 'not for questions with a clear answer.' It also names alternatives (ask_council, ask_chain) and warns this is the most expensive mode, to be used sparingly, plus scope refusals.

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

ask_deepseekA

Ask the DeepSeek model (deepseek-v4-pro, via DeepSeek's Anthropic-compatible endpoint) — 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. Cheap direct API — prefer it (like ask_m3/ask_glm) over pricier cloud models for a quick independent opinion. 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. Single-turn. Requires ASK_FABLE_DEEPSEEK_API_KEY configured on the server (reported as not_configured otherwise). 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. Use ask for Fable, ask_m3 for MiniMax, ask_glm for GLM, or ask_council to ask several and get a synthesized answer.

ParametersJSON Schema
NameRequiredDescriptionDefault
contextNoOptional code snippets, file paths, or structural context.
questionYesA specific software/engineering question to ask DeepSeek (deepseek-v4-pro) on its own.
context_refNoKey(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.

TDQS

A4.6/5.0
Behavior4/5

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

With no annotations provided, the description carries the full disclosure burden and largely succeeds: it reveals the single-turn nature, the ASK_FABLE_DEEPSEEK_API_KEY prerequisite with its not_configured failure mode, refusal categories, and in-scope domains. It stops short of describing the response payload on success or refusal, but the key behavioral gotchas are disclosed.

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?

Though longer than the calibration ideal, every sentence earns its place: model identity, scope, cost preference, config prerequisite, refusal policy, and sibling routing. It is front-loaded with the core purpose and contains no filler or repetition of schema content.

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 3-parameter, no-output-schema, no-annotation tool, this description is nearly complete: what to ask, how to pass context, config requirements, refusals, and routing to siblings. The only minor gap is expected response behavior on refusal or misconfiguration, but for a simple ask tool the primary answer shape is self-evident.

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, and the description adds genuine value by clarifying model identity for the question parameter and instructing when to populate context ('add a snippet or file path in context when the question is about existing code'). context_ref is fully served by the schema, so no further elaboration is needed.

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 verb+resource: 'Ask the DeepSeek model (deepseek-v4-pro...)' and a clear engineering scope — code structure, flow, architecture, design trade-offs. It explicitly distinguishes itself from Fable and names the model, making it unmistakable against the large ask_* sibling family.

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?

Provides explicit when-to-use guidance ('Cheap direct API — prefer it... for a quick independent opinion'), when-not-to-use conditions (offensive-security and non-software domains are refused), and named alternatives ('Use ask for Fable, ask_m3 for MiniMax, ask_glm for GLM, or ask_council...'). 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_geminiA

Ask Google's Gemini model (Gemini 3.1 Pro, via the local agy CLI) — 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. 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. Single-turn. Requires the agy CLI installed and signed in on the server (reported as binary_missing otherwise). 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. Use ask for Fable, ask_m3 for MiniMax, ask_glm for GLM, or ask_council to ask several and get a synthesized answer.

ParametersJSON Schema
NameRequiredDescriptionDefault
contextNoOptional code snippets, file paths, or structural context.
questionYesA specific software/engineering question to ask Gemini (Gemini 3.1 Pro) on its own.
context_refNoKey(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.

TDQS

A4.8/5.0
Behavior5/5

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

With no annotations, the description carries the full behavioral burden and it delivers: single-turn semantics, the binary_missing failure mode when the agy CLI is unavailable, and explicit refusals for offensive-security and non-software domains. It even clarifies in-scope domains (neuroscience, cognitive science, AI/ML, CS) so the agent can distinguish refusals from valid questions.

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 front-loaded with purpose, then usage, then failure/refusal behavior, then sibling routing — no redundant filler. Each sentence contributes distinct decision-relevant information for an agent choosing and invoking the 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 single-turn LLM query tool with no output schema, the description covers needed dependencies, refusals, and scope, and the schema covers parameter semantics. The only minor gap is that it never names the response shape, but that is reasonably inferable and partially disclosed through the binary_missing error mention.

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 already documents all three parameters at 100% coverage, including the context_ref key behavior. The tool description adds marginal value by advising to place a snippet or file path in context when a question references existing code and by emphasizing the question must be software/engineering-specific.

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 first clause names a specific verb ('Ask'), a specific model ('Gemini 3.1 Pro'), and the invocation path ('local agy CLI'), and narrows the subject to software/engineering work. It also distinguishes itself from Fable-bound siblings and from the other ask_* tools by listing the exact kinds of questions it handles.

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 the tool (broad/conceptual software engineering questions, brainstorming), when to include context (questions about existing code), and which alternatives to use instead (ask for Fable, ask_m3, ask_glm, ask_council). It also lists refusal categories, so an agent can avoid out-of-scope asks.

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

ask_glmA

Ask the GLM 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. 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. Single-turn. Served by Z.ai's Anthropic-compatible endpoint (GLM-5.2) when ASK_FABLE_GLM_API_KEY is set; otherwise it falls back to Atlas-hosted GLM-5.3 on the Atlas key, and is only reported as not_configured when neither is available. 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. Use ask for Fable, ask_m3 for MiniMax, or ask_council to ask several and get a synthesized answer.

ParametersJSON Schema
NameRequiredDescriptionDefault
contextNoOptional code snippets, file paths, or structural context.
questionYesA specific software/engineering question to ask GLM (GLM-5.2) on its own.
context_refNoKey(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.

TDQS

A4.7/5.0
Behavior5/5

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

No annotations are provided, so the description carries the full burden. It discloses single-turn behavior, the backend model and fallback behavior (GLM-5.2 via Z.ai when the key is set, otherwise Atlas-hosted GLM-5.3), not_configured reporting, and the refusal policy for offensive-security and non-software domains. This is strong behavioral disclosure beyond what a name or schema alone would convey.

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 core purpose is front-loaded and the description is well organized, but the backend/endpoint sentence is more implementation detail than an agent strictly needs for selection or invocation. Still, every sentence serves a real purpose given the configuration, refusal, and alternative-routing details it covers.

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?

Given there is no output schema, the description still provides the essential information needed to call the tool correctly: what to ask, how to provide context, what is refused, and which sibling tools to use instead. It leaves the exact return shape implicit and does not explicitly distinguish ask_glm from every model-specific sibling, but these are minor gaps.

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 description coverage is 100%, so the baseline is 3. The description adds value by instructing users to include a snippet or file path in context for questions about existing code and by clarifying that broad/conceptual engineering questions are acceptable. It does not add much on context_ref beyond what the schema already documents.

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 starts with a specific verb-resource-scope statement: 'Ask the GLM model — on its own, independent of Fable — to reason about the SOFTWARE/ENGINEERING work you're doing.' It enumerates concrete topics such as code structure, data/control flow, architecture, and design trade-offs. It also distinguishes itself from siblings by explicitly saying 'Use ask for Fable, ask_m3 for MiniMax, or ask_council.'

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 explicitly states when the tool is appropriate: software/engineering reasoning, broad conceptual questions, and existing-code questions with a snippet or file path in context. It names alternatives directly — ask for Fable, ask_m3 for MiniMax, ask_council for synthesized multi-model answers — and establishes exclusions such as offensive-security asks and non-software domain knowledge.

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

ask_grokA

Ask xAI's Grok model (grok-4.6 by default, via the local grok CLI in single-turn -p mode) — 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. PREFER THIS over ask_atlas with xai/grok-* whenever the grok binary is installed (uses your grok login session; no Atlas API key). Runs hermetically (tools disabled; put the code it needs in context). Single-turn. Requires the grok CLI installed and logged in on the server (reported as binary_missing otherwise). Broad and conceptual engineering questions (including brainstorming/ideas for future code) are fine. 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. Use ask for Fable, or ask_council with model token grok to include Grok in a multi-model panel.

ParametersJSON Schema
NameRequiredDescriptionDefault
contextNoOptional code snippets, file paths, or structural context.
questionYesA specific software/engineering question to ask Grok (grok-4.6) on its own via the local `grok` CLI.
context_refNoKey(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.

TDQS

A4.4/5.0
Behavior5/5

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

With no annotations, the description fully discloses behavior: single-turn, local grok CLI, grok-4.6 by default, hermetic execution with tools disabled, use of the grok login session, and the binary_missing failure mode. It also explains the tool's scope limitations, which is valuable context beyond the schema.

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 dense and information-rich, but it is somewhat run-on and contains redundancy: 'single-turn' appears twice, and various parentheticals are stacked. The final sentence about refused domains trails off, making the structure feel less polished than it could be.

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 tool with no annotations and no output schema, the description covers the key operational context: prerequisites, failure behavior, execution mode, and scope. The only minor gap is the lack of detail about the response format, and the incomplete final sentence leaves the refusal list slightly ambiguous.

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 baseline is 3. The description adds some extra meaning by saying 'put the code it needs in context' and characterizing the question as a 'specific software/engineering question,' but it does not substantially elaborate on the parameters beyond what the schema already provides.

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 clearly states this tool asks xAI's Grok model to reason about software/engineering work, listing concrete topics like code structure, data flow, and architecture. It also explicitly distinguishes itself from ask_atlas and from Fable by saying it is 'on its own, independent of Fable'.

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 an explicit preference rule: 'PREFER THIS over ask_atlas with xai/grok-* whenever the grok binary is installed.' It also states what kinds of questions are fine (broad engineering questions) and what is not (offensive security, non-software knowledge), and notes the prerequisite that the grok CLI must be installed and logged in.

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

ask_kimiA

Ask Moonshot's Kimi model (kimi-code/k3 by default, via the local kimi CLI in single-turn mode) — 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. PREFER THIS over ask_atlas with moonshotai/kimi-* whenever the kimi binary is installed: it runs on your Kimi Code subscription instead of per-token Atlas billing. NOTE the context caveat: k3 is a 1M-context model, but this CLI takes the prompt as a single argv value, which the kernel caps near 131k bytes — larger prompts are refused with a pointer to ask_atlas ('moonshotai/kimi-k3'), which has no such limit. The turn is sandboxed to pure text reasoning — the model has NO filesystem or tool access, so put the real code in context. Single-turn. Requires the kimi CLI on PATH and a completed kimi login (reported as binary_missing / not_configured otherwise). 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. Use ask for Fable, ask_m3 for MiniMax, or ask_council to ask several and get a synthesized answer.

ParametersJSON Schema
NameRequiredDescriptionDefault
contextNoOptional code snippets, file paths, or structural context.
questionYesA specific software/engineering question to ask Kimi (kimi-code/k3) on its own via the local `kimi` CLI.
context_refNoKey(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.

TDQS

A4.7/5.0
Behavior5/5

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

No annotations are present, so the description carries the full burden — and it delivers: single-turn mode, sandboxed pure-text reasoning with no filesystem/tool access, the 131k-byte argv cap with refusal behavior, prerequisite `kimi` CLI + `kimi login` with error states, and explicit refusal boundaries (offensive security, biology/medicine refused; neuroscience, cognitive science, AI/ML, CS in-scope). This is unusually thorough behavioral disclosure.

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 front-loaded: purpose first, then routing preference, then caveats, sandbox, prerequisites, refusals, alternatives — each sentence earns its place given the zero-annotation environment. However, the dense em-dash and parenthetical asides make parsing harder than necessary, so it falls just short of top marks.

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?

With no annotations and no output schema, the description must be self-sufficient, and it covers nearly everything: purpose, alternatives, prerequisites, error states, size limits, refusal boundaries, and cost implications. It does not explicitly describe the return value format, though 'sandboxed to pure text reasoning' strongly implies a text answer — a minor gap for an otherwise complete definition.

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 by explaining why `context` matters ('the model has NO filesystem or tool access, so put the real code in `context`') and by tying the `question` parameter to the argv size cap. This goes one step beyond the schema's own documentation.

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 a specific verb ('Ask'), a specific resource (Moonshot's Kimi model kimi-code/k3 via the local `kimi` CLI), and the scope (SOFTWARE/ENGINEERING work: code structure, functionality, data/control flow, architecture). It distinguises from sibling tools by adding 'on its own, independent of Fable' and explicitly contrasts itself with `ask_atlas`, `ask`, `ask_m3`, and `ask_council'.

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?

Gives explicit when-to-use: 'PREFER THIS over `ask_atlas`... whenever the `kimi` binary is installed', with the billing rationale. Gives when-not-to-use: prompts over the 131k-byte argv cap should be routed to `ask_atlas`. Also names the siblings for other purposes: 'Use `ask` for Fable, `ask_m3` for MiniMax, or `ask_council` to ask several'.

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

ask_m3A

Ask the MiniMax model (MiniMax-M3) — 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. 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. Single-turn. 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. Use ask for Fable, or ask_council to ask both and get a synthesized answer.

ParametersJSON Schema
NameRequiredDescriptionDefault
contextNoOptional code snippets, file paths, or structural context.
questionYesA specific software/engineering question to ask MiniMax (MiniMax-M3) on its own.
context_refNoKey(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.

TDQS

A4.7/5.0
Behavior4/5

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

With no annotations provided, the description carries the behavioral disclosure burden. It does so well by stating the tool is single-turn, independent of Fable, and has specific refusal categories. It also clarifies in-scope domains (neuroscience, cognitive science, AI/ML, CS). Minor gaps remain, such as whether the model has access to conversation history, but the description provides meaningful behavioral 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 dense but efficient, packing purpose, scope, exclusions, limitations, and alternatives into a few sentences. Each sentence earns its place, and the most important information—what the tool does—is front-loaded.

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 model-ask tool with three parameters and a fully described schema, the description covers the essential contextual information: the model's identity and scope, refusals, single-turn behavior, how to provide context, and how to choose an alternative tool. Nothing critical is missing for an agent 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%, so the baseline is 3. The description adds value by explaining when and how to use the `context` parameter: add a snippet or file path when the question is about existing code. It does not explicitly discuss `context_ref`, but the schema already documents it, so the description's additional guidance lifts this slightly above baseline.

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 clearly identifies the resource (MiniMax-M3 model) and the action (ask it to reason about software/engineering work), listing concrete topics like code structure, data flow, routing, and design trade-offs. It also distinguishes this tool from siblings by stating it is 'independent of Fable' and that `ask` is for Fable and `ask_council` is for both.

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 this tool for broad, conceptual engineering questions, and add context when asking about existing code. It also states exclusions (offensive security, non-software domains like biology/medicine) and names alternatives: `ask` for Fable and `ask_council` for both.

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

ask_ollamaA

Ask a single Ollama Cloud model — on its own — 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. Pass model to pick a cloud model (e.g. 'kimi-k2.7-code:cloud', 'gpt-oss:120b-cloud', 'deepseek-v3.2:cloud'); omit it to use the server's default. Reached via a local signed-in ollama daemon by default (no API key needed). Single-turn. 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. Use ask_council to mix Ollama models with Fable.

ParametersJSON Schema
NameRequiredDescriptionDefault
modelNoOllama Cloud model id (e.g. 'kimi-k2.7-code:cloud', 'gpt-oss:120b-cloud'). Omit to use the server's ASK_FABLE_OLLAMA_MODEL default.
contextNoOptional code snippets, file paths, or structural context.
questionYesA specific software/engineering question to ask a single Ollama Cloud model.
context_refNoKey(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.

TDQS

A4.5/5.0
Behavior4/5

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

With no annotations, the description carries the full behavioral burden. It discloses several non-obvious traits: operation is single-turn, reached via a local signed-in ollama daemon with no API key, model default behavior, and refusal categories. This goes well beyond the schema, though it stops short of describing output format or side effects, so a 4 is appropriate.

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 lengthy but each clause earns its place: scope, model selection, transport, turn semantics, acceptable topics, refusals, and an alternative. It is front-loaded with the primary purpose. Slight verbosity in the refusal list prevents a 5, but the structure is logical and 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 Q&A tool with no output schema, the description covers nearly everything an agent needs: allowed questions, refused categories, context parameter usage, model selection, and the council alternative. It doesn't describe the response shape or error behavior, but those are not critical for invoking a single-turn question tool. The large sibling set is handled by explicit differentiation from ask_council.

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 description coverage is 100%, so the baseline is 3. The description adds real value by giving concrete model id examples, explaining when to use `context` ('add a snippet or file path... when the question is about existing code'), and clarifying the default behavior when `model` is omitted. This lifts it above the baseline.

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: 'Ask a single Ollama Cloud model — on its own — to reason about the SOFTWARE/ENGINEERING work.' It clearly enumerates the topics (code structure, data/control flow, architecture, design trade-offs) and contrasts with ask_council, so an agent can distinguish it from siblings without inspecting 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?

The description provides explicit when-to-use guidance: broad conceptual engineering questions are fine, while offensive-security and non-software domain questions are refused. It also tells the agent to add context for existing-code questions and points to an alternative tool ('Use ask_council to mix Ollama models with Fable'), covering both positive and negative cases.

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

ask_ollama_councilA

DIRECTIONAL — the Ollama-only counterpart to ask_council: reserve it for a contentious or hard-to-reverse decision you want several cloud models to cross-check, not for routine questions (default to ask; at most one council call per problem, and check quorum/degraded in the result). Ask several Ollama Cloud models the same SOFTWARE/ENGINEERING question at once, then get back one answer that Fable synthesizes by reconciling all of them (each raw answer is also returned under sources). Pass models as a list of cloud model ids (e.g. ['qwen3-coder:480b-cloud', 'nemotron-3-ultra:cloud','kimi-k2.7-code:cloud']); an 'ollama:' prefix is optional. Omit models to use the server's configured set (ASK_FABLE_OLLAMA_COUNCIL). Reached via a local signed-in ollama daemon by default (no API key needed). Use ask_council instead to mix Ollama models with Fable/MiniMax/GLM/DeepSeek in one council. 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
modelsNoOllama Cloud model ids (e.g. ['kimi-k2.7-code:cloud', 'gpt-oss:120b-cloud']); an 'ollama:' prefix is optional. Omit to use the server's configured set (ASK_FABLE_OLLAMA_COUNCIL). Requires ASK_FABLE_OLLAMA_API_KEY on the server.
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.
questionYesA specific software/engineering question to ask several Ollama Cloud models; Fable then synthesizes their answers into one.
context_refNoKey(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.

TDQS

A4.4/5.0
Behavior4/5

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

With no annotations provided, the description carries the full burden and discloses several behaviors: it synthesizes one answer while returning raw answers under `sources`, calls optional `quorum`/`degraded` result fields, uses a local signed-in `ollama` daemon by default (no API key needed), and notes that model configuration falls back to ASK_FABLE_OLLAMA_COUNCIL. Minor gaps remain (e.g., no mention of error handling if no models are available or daemon is down), but the description is unusually transparent for a tool with no 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 dense and information-rich, but it is a long, single run-on block with many stacked clauses and parenthetical asides (e.g., the broad scope/refusals list is packed into the tail). The most critical routing information ('DIRECTIONAL', 'counterpart to ask_council', 'default to ask') is front-loaded, which is good, but the overall structure would benefit from splitting scope/refusal rules from invocation details. It earns a 3 — content is all relevant, but readability suffers.

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 complex tool with 5 parameters and no output schema, the description covers invocation modes (explicit model list vs. server default), auth expectations (local signed-in daemon, no API key needed), scope rules (what is in/out of scope), and output behavior (synthesized answer plus `sources`). It lacks a note on the shape of the synthesized answer beyond 'one answer' and doesn't explain what happens if models are invalid or unreachable, but the high schema coverage and rich routing details make it largely complete for an agent to decide whether and how to call it.

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 description coverage is 100%, so the baseline is 3. The description adds value beyond the schema by giving concrete example model ids, clarifying the optional 'ollama:' prefix, and explicitly stating the effect of omitting `models` (server-configured set). It also explains the `sources` relationship to the `question` parameter's output. This extra context justifies a 4 rather than a baseline 3.

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 clear verb+resource ('Ask several Ollama Cloud models the same SOFTWARE/ENGINEERING question at once') and immediately differentiates itself from the sibling `ask_council` by stating it is the Ollama-only counterpart. It also clarifies scope (broad engineering questions, with explicit refusals), making the tool's identity 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?

Provides explicit when-to-use guidance: 'reserve it for a contentious or hard-to-reverse decision', 'not for routine questions (default to `ask`)', 'at most one council call per problem'. It also names both alternatives (`ask` and `ask_council`) and distinguishes when to choose each, which is exactly the routing help an agent needs.

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

ask_openrouterA

Ask ONE model on OpenRouter — a single gateway fronting ~400 models from every major lab (Anthropic, OpenAI, Google, DeepSeek, Meta, Qwen, Moonshot, xAI, Mistral, …) behind one API key. Use it to reach a model this server has no dedicated tool for, or to compare the same question across labs without configuring each provider separately. Guarded and single-turn, same scope rules as every other ask tool. PICK A MODEL FIRST: call list_openrouter_models(task='…') — the catalog is free and needs no key — then offer the user the ranked shortlist with its prices before spending anything. Omitting model uses the server default. effort is quick/standard/deep (default deep); because OpenRouter publishes each model's supported reasoning efforts, deep asks for the most the chosen model actually supports instead of guessing. COST: this bills the operator's OpenRouter credit per token, and the result reports the real dollar cost of the call. Prefer a dedicated tool when one exists for the same model — ask / ask_opus5 (Claude on the operator's OAuth session, no per-token cost), ask_grok, ask_kimi, ask_deepseek. Grok and Kimi ids are rerouted to those local CLIs automatically when they are installed. Any model here also works in ask_council, ask_chain, and ask_debate as an 'openrouter:' token.

ParametersJSON Schema
NameRequiredDescriptionDefault
modelNoOpenRouter 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.
effortNoAnswer 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.deep
contextNoOptional code snippets, file paths, or structural context.
questionYesA specific software/engineering question to ask an OpenRouter model.
context_refNoKey(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.

TDQS

A4.9/5.0
Behavior5/5

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

No annotations are provided, so the description carries the full transparency burden. It discloses that the call bills the operator's OpenRouter credit per token, that the result reports real dollar cost, that the tool is guarded and single-turn, and how effort and default model selection behave.

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 densely informative; every sentence contributes purpose, workflow, cost, or redirection. It is front-loaded with the core function before diving into model selection and billing details, and there is 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?

Despite having no output schema, the description covers return-cost reporting, billing, defaults, model selection prerequisites, and explicit alternatives among siblings. For a pay-per-token tool with many similar ask siblings, this is a complete operational picture.

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%, establishing a baseline of 3, but the description adds meaningful parameter context: model selection should come from the live catalog with pricing, effort adapts to the chosen model's supported reasoning levels, and context_ref pulls saved context by key. This goes beyond the schema's own 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: 'Ask ONE model on OpenRouter', and clarifies it is a gateway to ~400 models from multiple labs. It explicitly differentiates from sibling ask tools by naming use cases: reaching models without a dedicated tool and comparing the same question across labs.

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?

Provides explicit when-to-use and when-not-to-use guidance: prefer dedicated tools like ask or ask_opus5 when one exists for the same model. It also gives a concrete workflow — call list_openrouter_models first, offer the ranked shortlist, then ask — and notes rerouting behavior for Grok and Kimi.

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

ask_openrouter_councilA

Ask SEVERAL OpenRouter models the same question in parallel, then have an adjudicator reconcile their answers into one. The point is cross-LAB diversity on a single API key: a panel of Claude + GPT + Gemini + DeepSeek disagrees in more useful ways than three models from one vendor, and you configure none of them separately. Same fan-out/synthesis contract and consensus signal as ask_council. models takes OpenRouter ids (the 'openrouter:' prefix is optional); omit it to use the configured set (configure_openrouter_council), else 3 featured catalog models, one per provider. The adjudicator defaults GPT-first: the local codex CLI when installed, else OpenRouter-hosted GPT-5.6 Sol, else Fable. COST: this is N billed calls plus a synthesis — reserve it for a contentious, hard-to-reverse decision, exactly as with ask_council. Grok and Kimi members reroute to the local CLIs when installed.

ParametersJSON Schema
NameRequiredDescriptionDefault
modelsNoOpenRouter 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.
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.
questionYesA specific software/engineering question to ask several OpenRouter models; the adjudicator (GPT-5.6 Sol by default) then synthesizes their answers into one.
context_refNoKey(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.
synthesizerNoModel that reconciles the panel answers into one. Default ladder: the local codex CLI (GPT-5.6 Sol) when installed → 'openrouter:openai/gpt-5.6-sol' when OpenRouter is configured → 'fable'.

TDQS

A4.3/5.0
Behavior5/5

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

With no annotations, the description carries the full disclosure burden, and it rises to the task. It discloses the billing cost (N billed calls plus synthesis), parallel fan-out, the adjudicator default ladder ('the local `codex` CLI when installed, else OpenRouter-hosted GPT-5.6 Sol, else Fable'), the models omission fallback (configured set or 3 featured catalog models), and the Grok/Kimi reroute to local CLIs. This is substantive behavioral context well beyond what the schema alone provides.

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 core action is front-loaded in the first sentence and subsequent sentences efficiently add cost, default, fallback, and routing context without fluff. However, the synthesizer ladder and `models` omission behavior are repeated nearly verbatim from the schema, so a couple of sententes are slightly redundant. Overall it is dense and well-organized, but not every sentence strictly 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?

For a 6-param tool with no output schema and no annotations, the description covers purpose, cost, defaults, fallbacks, and configuration entry points. It references the fan-out/synthesis contract and `consensus` signal indirectly through `ask_council` rather than defining the return format, and it does not explain failure behavior when OpenRouter is not configured or when no models resolve. These are modest gaps for a tool of this complexity, so a 4 is appropriate.

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% with already-rich parameter text, so the baseline is 3. The description mostly restates schema content for `models` and `synthesizer` ('omit it to use the configured set...', 'adjudicator defaults GPT-first...'), adding little parameter-level meaning beyond the schema. The genuinely new details (cross-lab diversity rationale, Grok/Kimi reroute) are behavioral rather than parameter-semantic, so the description does not raise the score above baseline.

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: 'Ask SEVERAL OpenRouter models the same question in parallel, then have an adjudicator reconcile their answers into one.' It clearly differentiates this tool from the sibling `ask_council` by naming it ('Same fan-out/synthesis contract and `consensus` signal as `ask_council`') and from single-model `ask_openrouter` by emphasizing cross-lab diversity on a single API key. The purpose is unambiguous and distinct from the large sibling set.

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 provides explicit use-case context and a cost-based gate: 'COST: this is N billed calls plus a synthesis — reserve it for a contentious, hard-to-reverse decision, exactly as with `ask_council`.' It also names the configuration alternative (`configure_openrouter_council`) and explains the fallback behavior when `models` is omitted. However, it does not explicitly state when NOT to use it (e.g., 'prefer `ask_openrouter` for a single quick answer'), so it stops short of a full 5.

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

ask_opus5A

The same guarded, multi-turn reasoning as ask, but on Claude Opus 5 (claude-opus-5) instead of Fable — identical arguments, identical result shape (sidecar, followup, context_exhausted), same session/reset conversation model. Reach for it exactly where you'd reach for ask: before guessing at unfamiliar code, when weighing a design trade-off, or to sanity-check a plan or diff. WHICH ONE: Opus 5 is roughly half Fable's price and noticeably faster, so prefer it for high-volume or latency-sensitive reasoning and for long back-and-forth sessions; keep ask (Fable) for the hardest, most consequential single calls. Running BOTH on the same question is a cheap two-model cross-check without paying for a full council. Sessions are namespaced per tool: the same session key on ask and ask_opus5 is two independent conversations (use reset_session(model='opus5') to clear this one). The model has NO tools and CANNOT open files — paste the real code into context (or point at it with context_ref). Same scope as ask: broad and conceptual engineering questions, including brainstorming and ideas for future code, are fine; refused only for 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). Opus 5 also works as the opus token in every multi-model mode — ask_council member or synthesizer, ask_chain stage, ask_debate proposer/opponent/adjudicator.

ParametersJSON Schema
NameRequiredDescriptionDefault
resetNoDump+clear this session before asking, starting a fresh conversation.
contextNoOptional code snippets, file paths, or structural context.
sessionNoConversation key. Reuse it to ask follow-ups (Opus 5 keeps context); use a new key or reset=true to start a fresh topic. Opus sessions are namespaced separately from `ask`'s Fable sessions, so the same key on both tools is two independent conversations.default
trustedNoOperator-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.
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_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.7/5.0
Behavior5/5

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

With no annotations provided, the description carries the full behavioral burden. It discloses the result shape (sidecar, followup, context_exhausted), the session/reset model, per-tool session namespacing, the model's lack of tools and file access, the refusal scope, and the tool's role in multi-model modes. This is substantial behavioral context beyond the schema.

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 well-organized into clear sections (purpose, when-to-use, sessions, limitations, scope, multi-model role). Almost every sentence earns its place, though 'same as ask' is repeated a couple times and the wall of text could be tightened slightly.

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?

Given the complexity of the tool, the description covers most invocation-relevant context: when to use it, model limitations, session behavior, refusals, and multi-model integration. However, with no output schema, the result-shape terms like `sidecar` and `context_exhausted` are named but not explained, which is a minor completeness gap.

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 value beyond the schema by advising to paste real code into `context` or use `context_ref`, explaining that sessions are namespaced per tool, and noting arguments are identical to `ask`. This helps the agent use parameters more effectively.

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 precise purpose: the same multi-turn reasoning as `ask` but on Claude Opus 5, with identical arguments and result shape. It clearly differentiates the tool from its sibling `ask` by model choice and explicitly names that sibling.

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 'Reach for it exactly where you'd reach for ask' and provides a 'WHICH ONE' section comparing Opus 5 vs Fable on price, speed, and consequence. It also suggests running both as a cross-check, giving clear routing guidance relative to alternatives.

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

configure_atlas_councilA

Save the user's chosen Atlas Cloud council (and optionally its adjudicator) so it sticks across sessions (written to ask_fable's config file, which overrides the ASK_FABLE_ATLAS_COUNCIL / ASK_FABLE_ATLAS_SYNTHESIZER env defaults). Pass models as the list of Atlas model ids ask_atlas_council should use by default (e.g. ['zai-org/glm-5.2','deepseek-ai/deepseek-v4-pro', 'moonshotai/kimi-k2']; an 'atlas:' prefix is optional). Optionally set synthesizer ('gpt' = the local GPT-5.6 Sol CLI, 'openai/gpt-5.6-sol' = the Atlas-hosted one, 'fable', …); omit it to keep the built-in ladder (local codex CLI → Atlas-hosted GPT-5.6 Sol → Fable). Confirm the selection with the user first — call list_atlas_models to ground it in the live catalog. Returns the saved config and its file path.

ParametersJSON Schema
NameRequiredDescriptionDefault
modelsNoAtlas Cloud model ids for the council (e.g. ['zai-org/glm-5.2','deepseek-ai/deepseek-v4-pro','moonshotai/kimi-k2']). An 'atlas:' prefix is optional. This becomes ask_atlas_council's default, persisted across sessions. Ground the picks with list_atlas_models first.
synthesizerNoOptional: the model ask_atlas_council uses to reconcile the panel (e.g. 'gpt' for the local GPT-5.6 Sol CLI, 'openai/gpt-5.6-sol' for the Atlas-hosted one, or 'fable'). Omit to keep the built-in ladder: local codex CLI → Atlas-hosted GPT-5.6 Sol → Fable.

TDQS

A4.1/5.0
Behavior4/5

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

With no annotations, the description carries the disclosure burden, and it does well: it discloses a persistent write to ask_fable's config file, the env vars it overrides, the meanings of synthesizer values ('gpt' = local CLI, 'openai/gpt-5.6-sol' = Atlas-hosted, 'fable'), the built-in ladder on ommission, and the return value (saved config and file path). Minor gaps: it doesn't state whether an existing config is overwiritten or what happens if called with no arguments.

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 front-loaded with the core purpose, then organized into parameter meaning, usage prerequisite, and return value. It is dense with parentheticals but every clause adds necessary information for a tool without annotations or output schema. Slightly long, yet 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 2-parameter, no-annotation, no-output-schema tool, the description covers the essential ground: what is saved, where it's written, what it overrides, how each parameter behaves, the omission fallback, and the return value. Missing edge-case details like overwrite semantics or validation of model ids are minor and don't impair correct invocation.

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 the schema already explains that models becomes ask_atlas_council's default persisted across sessions, that 'atlas:' is optional, and that omitting synthesizer keeps the built-in ladder. The description adds concrete examples and reiterates these semantics, but adds little beyond the schema. 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 is specific: it 'Save[s] the user's chosen Atlas Cloud council (and optionally its adjudicator) so it sticks across sessions', clearly identifying the resource (Atlas council config) and the operation (persist). It is unambiguously distinct from sibling tools like configure_openrouter_council or configure_ollama_council, and from ask_atlas_council which consults rather than configures.

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 provides clear when-to-use context: persist across sessions, override ASK_FABLE_ATLAS_COUNCIL / ASK_FABLE_ATLAS_SYNTHESIZER defaults. It also gives a concrete precondition—'Confirm the selection with the user first — call list_atlas_models to ground it in the live catalog.' It lacks explicit 'when not to use' exclusions or named alternatives, relying on the tool name for sibling routing.

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

configure_ollama_councilA

Save the user's chosen Ollama Cloud council so it sticks across sessions (written to ask_fable's config file, which overrides the ASK_FABLE_OLLAMA_* env defaults). Pass models as the list of cloud model ids to use for ask_ollama_council and the full tier (e.g. ['minimax-m3:cloud', 'glm-5.2:cloud', 'qwen3-coder:480b-cloud']; an 'ollama:' prefix is optional and a bare name like 'minimax-m3' is normalized to 'minimax-m3:cloud'). Optionally set default_model for the single-model ask_ollama tool. Confirm the selection with the user first — call list_ollama_models to ground it in what's actually available. Returns the saved config and its file path.

ParametersJSON Schema
NameRequiredDescriptionDefault
modelsNoOllama Cloud model ids for the council (e.g. ['minimax-m3:cloud','glm-5.2:cloud','qwen3-coder:480b-cloud']). An 'ollama:' prefix is optional; a bare name like 'minimax-m3' is normalized to 'minimax-m3:cloud'. This becomes ask_ollama_council's default and the `full` tier's Ollama members, persisted across sessions.
default_modelNoOptional: the single model `ask_ollama` uses when none is passed (e.g. 'gpt-oss:120b-cloud').

TDQS

A4.5/5.0
Behavior5/5

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

With no annotations provided, the description carries the full disclosure burden and does so admirably. It states the side effect (writes to config file), precedence behavior (overrides ASK_FABLE_OLLAMA_* env defaults), persistence scope (across sessions), input normalization ('ollama:' prefix optional, bare names normalized to ':cloud'), and the return value (saved config and file path). This fully informs an agent of the persistent-mutation nature of the call.

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 earns its place: purpose, parameter details, normalization rule, optional parameter, user-confirmation workflow, and return value. It front-loads the primary purpose before diving into specifics, and the structure follows a logical flow from what it does to how to use it to what it returns.

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 config-persistence tool with no annotations and no output schema, the description covers everything an agent needs: preconditions (confirm with user, call list_ollama_models), side effects (config file write, env override), parameter semantics, normalization behavior, and return value (config file path). No critical operational detail is left implicit.

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 baseline is 3. The description's parameter explanations largely restate the schema text (list of cloud model ids, normalization, default_model for ask_ollama). It does add a concrete example array and ties the parameters to downstream tool behavior, but it doesn't significantly extend semantic understanding beyond what the schema already provides.

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, actionable purpose: 'Save the user's chosen Ollama Cloud council so it sticks across sessions.' It names the exact resource (Ollama Cloud council), the mechanism (written to ask_fable's config file), and the effect (persists, overrides env defaults). It also clearly distinguishes itself from sibling configure_atlas_council and configure_openrouter_council by scoping to Ollama Cloud while referencing the dependent ask_ollama_council and ask_ollama 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?

The description provides explicit operational guidance: confirm with the user first and call list_ollama_models to ground the selection in available models. It also explains how the parameters map to downstream tools (ask_ollama_council, full tier, ask_ollama). It stops short of explicitly stating when not to use this tool versus the config alternatives, but the Ollama Cloud naming and list_ollama_models call make the intended context clear.

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

configure_openrouter_councilA

Persist the default panel for ask_openrouter_council (and optionally its adjudicator) to the server's config file, so the choice survives restarts without anyone hand-editing an env var. Pass models (OpenRouter ids) and/or synthesizer (any council token, or a bare OpenRouter id). Call list_openrouter_models first and let the user pick — this writes a durable default on their behalf, so it should reflect their choice, not yours.

ParametersJSON Schema
NameRequiredDescriptionDefault
modelsNoOpenRouter 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.
synthesizerNoModel that adjudicates the panel — any council token ('codex'/'gpt', 'fable', 'openrouter:<model-id>') or a bare OpenRouter id.

TDQS

A4.2/5.0
Behavior4/5

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

With no annotations provided, the description carries the full behavioral burden and it delivers: it discloses a durable config-file mutation ('writes a durable default on their behalf', 'survives restarts'). It stops short of mentioning whether existing defaults are overwritten/merged or what the tool returns, so it isn't a 5, but the persistence side effect is clearly communicated.

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 sentences with no filler: the first states purpose and persistence mechanics, the second condenses parameters and the user-choice workflow. Every sentence earns its place and the key action is front-loaded.

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 tool with two optional parameters and no output schema, the description covers the workflow (list first, let user pick), the parameters, and the side effect. Minor gaps remain — behavior on an empty call and overwrite/merge semantics — but they don't block correct invocation.

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%, so the schema already documents both parameters with examples and prerequisites. The description adds the 'and/or' optionality and calls synthesizer the 'adjudicator', which slightly clarifies relationship but doesn't add material meaning beyond the schema.

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 ('Persist') and resource ('default panel for ask_openrouter_council ... to the server's config file') with a stated outcome ('survives restarts'). Distinguishes from configure_ollama_council and configure_atlas_council by explicitly referencing ask_openrouter_council and naming the prerequisite list_openrouter_models.

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?

Provides an explicit pre-step ('Call list_openrouter_models first') and a clear decision rule ('should reflect their choice, not yours'). It also implicitly contrasts with hand-editing an env var. It doesn't explicitly name alternative configure_* tools, but the OpenRouter-specific resource makes the intended target clear.

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

configure_tracingA

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.1/5.0
Behavior5/5

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

With no annotations provided, the description carries full disclosure burden and succeeds. It reveals the side effect of writing ask_fable's config file, persistence across sessions, overrides of environment defaults, the fact that changes apply on the next call, and the behavioral difference between 'full' and 'safe' trace modes. It also discloses that stream_reasoning goes to the server console rather than the tool result.

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 definition is information-dense and front-loaded with the core action in the first phrase. Each clause adds useful detail, but the opening sentence is long and packs multiple ideas (persistence, config file override, no restart, next-call timing) into one parenthetical-heavy statement. Still, nothing 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?

For a config-mutation tool with no annotations and no output schema, the description is remarkably complete. It explains persistence, override behavior, timing, both modes for trace_mode, the effect of stream_reasoning, and explicitly states the return value (effective settings and config path). An agent has enough to use 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%, so the baseline is 3. The description repeats and slightly expands on the schema's parameter descriptions (e.g., 'full' records redacted reasoning, 'safe' withholds content), but does not add substantially new semantic meaning beyond what the input schema already states.

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 starts with a specific verb+resource: 'Toggle reasoning-trace capture at runtime', which clearly states the action and target. It clarifies what the tool is for, but does not explicitly contrast itself with sibling tools like trace_get or trace_list, so it misses the top bar for sibling differentiation.

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 context: it is a runtime toggle that persists, overrides env defaults, requires no ~/.claude.json edit or restart, and applies on the next call. It also says 'Pass either or both' to guide invocation. It does not explicitly state when to prefer this over read-only trace tools, so it stops short of full 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.

context_deleteA

Delete a stored context by key (housekeeping once a blob is no longer needed). Returns whether a row was removed.

ParametersJSON Schema
NameRequiredDescriptionDefault
keyYesKey to delete.

TDQS

A4.1/5.0
Behavior3/5

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

With no annotations, the description carries the disclosure burden. It explicitly states the destructive action and that the tool returns whether a row was removed, which is useful. However, it does not mention permanence, irreversibility, or any potential side effects on related stored contexts or packs.

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 sentences with no redundancy; the core action, the usage rationale, and the return behavior are all covered. The parenthetical is compact and 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?

For a single-parameter deletion tool with no output schema, the description covers the action, the reason to use it, the key parameter, and the return value. Nothing essential is missing for an agent 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 description coverage is 100%, so the parameter is already documented ('Key to delete'). The description adds little beyond restating that deletion happens by key, which is expected given the high baseline 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 description states a specific verb ('Delete'), a resource ('a stored context'), and the means ('by key'), which fully identifies the operation. The parenthetical 'housekeeping once a blob is no longer needed' adds a clear purpose and helps distinguish it from sibling read/write 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?

The phrase 'housekeeping once a blob is no longer needed' gives a clear condition for when this tool is appropriate. It does not explicitly name alternatives or exclusions, but the usage context is easy to infer from the deletion intent.

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

context_listA

List what's in the shared context store — each key with its size, age, and description (never the full value). Read-only. Reach for this to discover what context is already available to reference via context_ref before re-pasting.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.7/5.0
Behavior5/5

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

With no annotations provided, the description carries the full burden, and it fulfills it well. It explicitly states the operation is read-only and discloses that full values are never returned, which is a meaningful behavioral guarantee that prevents an agent from expecting content leaks.

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 sentences with no wasted words. The action and resource are front-loaded, the return format is compactly summarized, the safety constraint is explicit, and the usage scenario is included in a natural way.

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, read-only listing tool, this description covers naming, output scope, constraints, and use case. An agent has everything needed to decide when to call it and what to expect.

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 has zero parameters and the schema is fully covered, so there is nothing for the description to add. Per the baseline for zero-parameter tools, this is appropriate.

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 a specific verb ('List'), a specific resource ('shared context store'), and enumerates exactly what is returned (key, size, age, description). It also explicitly excludes full values, which distinguishes it from context_read. This leaves 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 an explicit use case: discover available context before re-pasting and reference via `context_ref`. It does not explicitly state when to use context_read instead, but the statement 'never the full value' gives a strong implicit contrast with the read sibling.

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

context_packA

Point, don't paste. The reasoning models can't see your repo, but THIS server runs locally next to it — so instead of hand-pasting code, NAME the files (and optional line ranges) you want and let the server read them, apply a character budget, and store the bundle on the context bus under key. Then pass context_ref='<key>' on ask / councils exactly as usual. Each spec is path or path:START-END (1-indexed inclusive), relative to the configured project root; reads never escape that root, and .git//.env* are refused. Requires an operator-configured project root (config project_root or the ASK_FABLE_PROJECT_ROOT env var) — returns not_configured if unset. Over-budget or unreadable specs are reported in skipped with a reason and complete:false; nothing is silently truncated, and if nothing can be packed the store is left untouched.

ParametersJSON Schema
NameRequiredDescriptionDefault
keyYesStable key to store the packed bundle under; then pass context_ref='<key>' on `ask`. Reusing a key overwrites it.
pathsYesFile specs to read from the configured project root — each a path relative to that root, optionally with a 1-indexed inclusive line range as `path:START-END` (e.g. 'src/app/db.py' or 'src/app/db.py:40-80').
max_charsNoOptional cap on total packed characters (default ~24000). Files that don't fit are reported in `skipped`, never silently truncated.

TDQS

A4.7/5.0
Behavior5/5

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

With no annotations provided, the description carries the full behavioral burden and does so thoroughly. It discloses the security boundary ('reads never escape that root'), the hard refusal of `.git/`/`.env*`, the `not_configured` failure mode, the `skipped` reporting mechanism with reasons and `complete:false`, the no-silent-truncation guarantee, and the untouched-store guarantee when nothing can be packed. This is model-friendly and trust-building.

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 distinct information: the core value proposition, the usage pattern, the spec syntax, the safety boundary, the configuration prerequisite, and failure semantics. It is front-loaded with 'Point, don't paste' and flows logically from motivation to mechanics to edge cases. 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?

For a tool with no annotations and no output schema, this description is complete. It tells the agent what inputs are expected, how to form paths, what happens on configuration failure, how partial failures are surfaced, and how the result is consumed by sibling tools. The only minor omission is the exact success return shape, but the 'skipped/complete' references make the contract understandable.

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 raises it by adding meaning beyond the schema. It specifies the default character budget (~24000), the project-root configuration requirement (config or env var), and the semantics of spec formats. These details help an agent pick good values and anticipate failure without needing extra research.

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 memorable, specific framing — 'Point, don't paste' — and then states the exact function: name files and optional line ranges, have the server read them, apply a character budget, and store the bundle under `key` on the context bus. It clearly distinguishes this from the ask/council siblings by explaining that the context_ref from this tool is then passed to them.

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 explicitly tells the agent when to use the tool: instead of hand-pasting code when the repo isn't visible to the model, with the local server reading files. It also explains the follow-up flow — pass `context_ref='<key>'` on `ask`/councils. It does not explicitly contrast with context_write/context_read siblings, but the 'don't paste' instruction strongly implies the file-based use case.

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

context_readA

Read back context previously saved with context_write, by key. Returns the stored value plus its size, age, and description; not_found if the key isn't set. Use it to inspect a shared blob, or to consume context another agent wrote.

ParametersJSON Schema
NameRequiredDescriptionDefault
keyYesKey to read back.

TDQS

A4.7/5.0
Behavior5/5

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

With no annotations, the description carries the full behavioral burden. It discloses the return payload (stored value, size, age, description) and the not_found behavior for missing keys, which is strong transparency for a simple read operation.

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?

Three sentences with no filler. The core action, return value, error case, and intended use are all packed in efficiently, and the most important information is front-loaded.

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-parameter, no-output-schema read tool, this description is complete. It covers what it reads, how to reference it, what is returned, what happens on failure, and why an agent would use it.

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 schema explains the key parameter minimally, but the description adds meaningful context: the key refers to something saved with context_write, and reads of unset keys return not_found. This adds value beyond the schema even though schema coverage is already 100%.

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 reads back context by key, referencing context_write as the complementary write operation. It also clarifies the difference from pure key listing by saying it returns the stored value plus metadata, so an agent can distinguish it from context_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?

Explicitly says when to use it: to inspect a shared blob or consume context another agent wrote. It does not name alternatives like context_list or context_delete for exclusion, but the intended use cases are clear enough for selection.

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

context_writeA

Store a chunk of context (code, file contents, a stack trace, design notes) under a stable key so you paste it ONCE and reuse it. Then pass context_ref='<key>' on ask to pull it in instead of re-pasting the same code into every call — the big lever against the re-paste tax, since the model can't see your repo. The store is shared by every agent on this server, so a sibling agent can context_read what you wrote. Reusing a key overwrites it. Give a one-line description so it shows usefully in context_list.

ParametersJSON Schema
NameRequiredDescriptionDefault
keyYesStable key to store this context under (e.g. 'repo:auth', 'ticket-431/stacktrace'). Reusing a key overwrites it.
valueYesThe context to store — code, file contents, a stack trace, design notes. Paste it ONCE here, then reference it by key via `context_ref` on `ask`.
descriptionNoOptional one-line note about what this holds (shown in context_list).

TDQS

A4.3/5.0
Behavior4/5

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

With no annotations provided, the description carries the full burden, and it does well by disclosing that the store is shared server-wide, reusing a key overwrites the previous value, and the optional description surfaces in context_list. It does not cover retention limits or what the tool returns on success, but the key side effects are transparent.

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 front-loaded with the core action and uses its four sentences efficiently; every sentence adds useful operational context. The motivational 're-paste tax' phrase is slightly embellished, and 'paste it ONCE' is repeated in spirit later, but the overall structure remains tight and readable.

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 simple three-parameter write operation with full schema coverage and no output schema, the description covers the key operational facts: shared store, overwrite behavior, usage with ask, and visibility in context_list. It does not specify return values or error behavior, but those are not critical for correctly invoking this tool.

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 meaningful guidance beyond the schema: it gives key-naming conventions, reinforces the overwrite semantics, explains how value is consumed via context_ref, and clarifies that description is used for display in context_list. This elevates it above the baseline.

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 ('Store') with a clear resource ('a chunk of context') and concrete examples (code, file contents, stack trace, design notes). It distinguishes this write tool from siblings by referencing context_read and context_ref, so an agent can tell at a glance that this is the write-side counterpart.

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 an explicit use case: store context once and reuse it via context_ref on ask instead of re-pasting code. It also mentions that sibling agents can context_read what was written, which helps clarify the relationship to related tools. However, it does not state explicit exclusions or when to prefer context_delete/context_pack.

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

list_atlas_modelsA

RECOMMEND AND PICK an Atlas Cloud text model. When the user asks for the best Atlas model(s) for a job, pass that job as task; the tool ranks the live catalog and opens a native model + effort selection popup when the MCP client supports form elicitation, with a structured picker fallback otherwise. Returns the live catalog (no auth needed; free, no tokens charged) as a ready-to-render menu: task-ranked recommendations, featured (~8 curated models, HOT/NEW-tagged, one per provider), the full menu (each with model_id, label, cost_note like '$2/$6 per M', provider, tags, context length, latency), and effort_choices (quick/standard/deep). REACH FOR THIS the first time an Atlas model is wanted. If selection.action is accept, call ask_atlas with the selected model and effort; if native elicitation is unavailable, show picker with the host's selection UI. Read-only.

ParametersJSON Schema
NameRequiredDescriptionDefault
taskNoOptional job to rank the live Atlas catalog for, such as 'debug a large Rust repository' or 'cheap low-latency support chat'.
limitNoMaximum task-matched models to offer.
refreshNoFetch the live Atlas Cloud text-model catalog (no auth needed). When false, only report the effort choices (no network).
interactiveNoWhen a task is supplied, open a native model + effort picker if the MCP client supports form elicitation; otherwise return picker JSON.

TDQS

A4.6/5.0
Behavior5/5

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

With no annotations, the description carries the full burden and does so thoroughly: it discloses read-only behavior, no auth needed, free/no tokens charged, native popup side effects, a structured fallback, and the no-network refresh=false behavior. This is strong behavioral disclosure for a tool with zero annotation support.

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, but almost every clause earns its place because there is no output schema and no annotations to fall back on. It front-loads the core purpose and workflow before the return-format detail. Stylistically it is a bit overloaded with all-caps emphasis, which 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 tool with no output schema and no annotations, this description is exceptionally complete: it covers return payload shape, cost/auth implications, task ranking, interactive behavior, fallback handling, and the next tool to call. Nothing critical for an agent to use it correctly is missing.

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 extra practical meaning by explaining that `task` drives ranking, that native elicitation is tied to `interactive`, and that `refresh=false` means no network. It doesn't radically expand on the schema, but it does connect parameters to real usage scenarios.

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+resource pair ('RECOMMEND AND PICK an Atlas Cloud text model') and clearly explains the ranking, picker, and catalog-listing behaviors. It differentiates from siblings by scoping to Atlas and explicitly pointing to ask_atlas for the follow-up accept action.

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 an explicit trigger: 'REACH FOR THIS the first time an Atlas model is wanted' and explains when a task should be passed. It also routes the follow-up to ask_atlas, but it does not explicitly mention exclusions for the sibling Ollama/OpenRouter model-list tools, so the when-not-to-use guidance is only implicit.

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

list_ollama_modelsA

List the Ollama Cloud models available to put in the council, so you can offer the user a real, concrete choice instead of guessing. Returns the live ollama.com catalog (GLM, MiniMax-M3, Qwen, Kimi, DeepSeek, Nemotron, Mistral, gpt-oss, …) as daemon-ready ids, the models already pulled locally (certain to run right now), and the council that's currently configured. REACH FOR THIS the first time an Ollama council is wanted or when the user asks to configure ask_fable: call this, show the options, ask which they want, then persist the choice with configure_ollama_council. Read-only.

ParametersJSON Schema
NameRequiredDescriptionDefault
refreshNoFetch the live ollama.com catalog + locally-pulled models. When false, only report the currently-configured council (no network).

TDQS

A4.5/5.0
Behavior5/5

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

With no annotations provided, the description carries the full disclosure burden. It clearly states 'Read-only', explains that it fetches the live ollama.com catalog, notes that local models are certain to run, and describes outputs as daemon-ready ids. This goes well beyond a generic 'list' statement and covers the main behavioral and safety expectations.

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?

Three dense sentences front-load the purpose, then describe outputs, then give the workflow. The illustrative list of model names and the rationale 'instead of guessing' add useful context without padding, and the 'Read-only' note is efficiently placed.

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-optional-parameter, read-only tool with no output schema, this description is complete enough: it covers when to use it, what it returns, why it matters, and the follow-up action. An agent can correctly invoke it and interpret the result categories without additional guessing.

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 the input schema already documents the refresh parameter's true/false behavior in detail. The description adds no meaningful parameter semantics beyond mentioning live versus currently-configured data, so the baseline of 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?

States a specific action ('List') and resource ('Ollama Cloud models available to put in the council'), and further specifies that it returns the live catalog, locally pulled models, and the currently configured council. The 'Ollama' and 'council' specifics clearly distinguish it from sibling listers like list_openrouter_models and list_atlas_models.

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 an explicit trigger ('first time an Ollama council is wanted' or 'user asks to configure ask_fable') and a concrete workflow: call, show options, ask, then persist with configure_ollama_council. It does not explicitly name alternative list_*_model tools or state when not to use them, but the Ollama-specific condition makes routing fairly unambiguous.

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

list_openrouter_modelsA

List the live OpenRouter catalog — ~400 models with price per million tokens, context window, and which reasoning efforts each one accepts. FREE: the catalog endpoint needs no API key and costs nothing, so call it before ask_openrouter rather than guessing a model id. Pass task='…' to rank a provider-diverse shortlist for that job; ranking reads the catalog's own fields (reasoning support, context length, price, release date), so a model released today ranks correctly with no update here. A task mentioning cheap/fast/high-volume flips the ranking toward the cheap and free tiers; otherwise it leads with capable models. Show the user the shortlist with prices and let them choose — do not silently pick an expensive model on their behalf.

ParametersJSON Schema
NameRequiredDescriptionDefault
taskNoOptional job to rank the live catalog for, such as 'debug a large Rust repository' or 'cheap high-volume summarizing'. Ranking uses the catalog's own data (reasoning support, context length, price, release date) rather than a hand-maintained list of model families.
limitNoMaximum task-matched models to offer.
refreshNoFetch the live OpenRouter catalog (no auth needed). When false, only report the effort choices (no network).
interactiveNoWhen a task is supplied, open a native model + effort picker if the MCP client supports form elicitation; otherwise return picker JSON.

TDQS

A4.5/5.0
Behavior5/5

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

With no annotations, the description carries the full burden and meets it: it discloses that the endpoint needs no API key and costs nothing, that ranking reads the catalog's own live fields so newly released models rank correctly, that cheap/fast/high-volume keywords flip tier preference, and that the tool must surface a price-annotated shortlist rather than silently pick an expensive model. This is far richer behavioral disclosure than the schema alone provides.

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?

Five dense sentences, all earning their place, with the core purpose front-loaded before the ranking and UX guidance. It is longer than minimal but every clause adds operational value; nothing reads as filler or repetition of the schema.

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 tool with no annotations and no output schema, the description covers a lot: returned fields, authentication/cost, ranking mechanics, keyword behavior, and user-presentation policy. The remaining gaps are minor — the exact response shape and failure behavior for the network fetch are left implicit — but nothing an agent needs to call it safely or correctly is missing.

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%, setting a baseline of 3. The description adds real meaning beyond the schema for the task parameter — explaining that ranking uses the catalog's own data and that keyword mentions of cheap/fast/high-volume redirect the ranking — and for interactive via the 'show the user and let them choose' guardrail. limit and refresh gain little beyond their schema text, so the bonus is partial.

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 a specific verb and resource — 'List the live OpenRouter catalog' — and enumerates exactly what is included (~400 models, price per million tokens, context window, reasoning efforts). It is instantly distinguishable from list_ollama_models and list_atlas_models by naming the OpenRouter source, and from ask_openrouter by the explicit 'call it before' instruction.

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 says when to invoke it: 'call it before ask_openrouter rather than guessing a model id,' naming the sibling and the rationale. It also explains when the optional task-ranking path applies and how task phrasing alters results. It does not explicitly state when-not-to-use cases, but the primary alternative is named and the ordering is clear.

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

reset_sessionA

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.3/5.0
Behavior4/5

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

With no annotations provided, the description carries the full behavioral burden. It discloses that the tool performs two actions—optionally dumping the transcript to a file and clearing the session—and communicates the side effect on subsequent `ask` calls. This is sufficient transparency for a destructive operation, though it does not mention irreversibility or any return value.

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 a single, well-structured sentence where the core action and its consequence are front-loaded. Every phrase earns its place: the optional file dump, the clear action, and the resulting fresh topic all fit naturally without 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?

For a simple, parameterless-required destructive tool with fully described parameters in the schema, the description is complete enough for correct invocation. It explains the tool's purpose, effect, and the optional save behavior; no output schema is expected for such a side-effect-oriented operation, and the context signals indicate no hidden complexity.

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 top-level description adds no parameter details beyond the input schema, and every parameter in the schema already has a clear, semantically rich description, including defaults and the model namespacing behavior. With 100% schema coverage, the description need not compensate, so the baseline score of 3 is appropriate.

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 verb-resource pair ('dump and clear a Fable conversation session') and explicitly explains the intended effect ('so the next `ask` on that key starts a fresh topic'). This clearly distinguishes it from sibling tools like `session_list` or `session_peek`, which inspect rather than mutate, and `context_delete`, which targets context entries rather than conversation sessions.

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 context for when to use the tool: before the next `ask` on a session key when you want a fresh topic. It does not explicitly name alternatives or list exclusion criteria, but the purpose and trigger condition are stated without ambiguity, so an agent can infer the appropriate usage scenario.

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

session_listA

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.5/5.0
Behavior4/5

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

With no annotations provided, the description carries the full burden of safety disclosure, and it does this well: it states 'Read-only, makes no model call' and clarifies that it is 'Visibility-only — never affects oracle answers; oracles only see what a calling agent explicitly passes'. It also defines the internal staleness heuristic (~5 min heartbeat threshold) that shapes the `active_only` default. Minor deduction: it does not describe the exact output list ordering or whether entries are capped by `limit` before or after filtering, but those are less critical for selection and invocation.

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 purposeful; every sentence adds behavioral or selection-relevant information. The opening word 'COORDINATION' acts as a category cue and front-loads the purpose. Minor deduction: the last sentence about visibility is slightly repetitive with the earlier 'Read-only, makes no model call' claim, so it could be tightened. Overall it is well under the length where an agent's attention starts to degrade.

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 zero-required-parameter list tool with no output schema, the description is nearly complete: it names the dashboard's purpose, what fields appear in entries, the defaults, the override flags, the staleness meaning, and the non-interference guarantee. The main gap is a lack of detail about pagination or truncation behavior (does `limit` default to 50 and cap at 200 in a simple head or does it page?), and it does not mention whether the ordering is by heartbeat recency. Still, an agent could confidently select and invoke it without further clarification.

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 description coverage is 67%: `active_only` and `all_projects` already have descriptions in the schema, while `limit` has only its default/min/max. The tool description adds the crucial semantics for the two booleans — e.g., that `active_only: false` yields 'retained history' and that `all_projects: true` means 'whole machine' — and it explains the default hint 'so the dashboard shows live work'. This is strong beyond-schema value. Deduct one point because the description does not add detail about `limit`'s effect beyond the schema's numeric bounds.

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 clear label ('COORDINATION — the operator dashboard') and states the specific verb+resource: lists ask_fable sessions across instances. It details exactly what each entry contains (session key, agent_id, latest question, oracle, status, heartbeat age, turn count), which strongly distinguishes it from siblings like session_stats, session_peek, and reset_session. An agent can immediately tell this is a read-only monitoring tool rather than a per-session query or mutation.

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 defaults ('THIS project only', `active_only: true`) and explains when to flip them: pass `active_only: false` for retained history and `all_projects: true` for the whole machine. It also gives a concrete use case ('avoid duplicate work or watch the live fleet'), which helps an agent decide between this and session_peek or session_stats. This fully satisfies when-to-use guidance within the sibling set.

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

session_peekA

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.4/5.0
Behavior5/5

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

With no annotations, the description carries full responsibility for disclosing behavior. It explicitly states read-only, makes no model call, returns conversation bounded by retention, and never feeds back into an oracle's context.

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 longer than the minimum but every sentence earns its place: coordination context, use cases, optional filtering, read-only behavior, retention bound, and comparison to session_list. It is front-loaded with the core action and not redundant.

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 simple read-only tool with only two parameters and no output schema, the description fully covers what is returned (ordered full turn history), the retention bound, and the absence of side effects. An agent has enough information to call it safely and understand the result.

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 the description's mention of 'Optionally scope to one agent_id' mostly restates the schema's own parameter description. It adds no new format, constraint, or semantic detail beyond what the schema already provides.

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, with scope 'across instances.' It also distinguishes itself from session_list by calling out visibility-only behavior, so an agent can tell them apart.

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 explicit use cases: understand what an agent learned before joining work, or recover a finding another instance produced. It clearly says it is visibility-only and never feeds back into an oracle's context, though it does not explicitly contrast with session_list or context_read.

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

session_statsA

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.8/5.0
Behavior5/5

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

No annotations exist, so the description must carry the full burden. It discloses that the tool is read-only, makes no model call, aggregates across all instances, defaults to a 24-hour window, supports full-history via window_s:0, and returns specific metrics. This is excellent behavioral disclosure.

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 every sentence carries useful information: scope, sibling distinction, time window, returned fields, project scoping, example use cases, and safety. The 'COORDINATION' prefix is slightly unnecessary but not harmful.

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 read-only statistics tool with no output schema, the description covers parameters, semantics, return fields, default behavior, project/machine scope, and use cases. Nothing important for correct invocation is missing.

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 practical context by explaining what window_s:0 means, what all_projects:true does, and how defaults apply to project scope, going slightly beyond the schema field 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?

Description clearly states a specific verb and resource: aggregated oracle usage across ALL instances on the machine. It also explicitly contrasts with the sibling `stats` tool, so an agent can distinguish them immediately.

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?

Provides explicit when-to-use guidance with example questions like 'which agents are burning the most oracle calls?' and 'how is the fleet doing today?'. It also names the alternative `stats` and explains the scoping condition that selects one over the other.

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

statsA

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.4/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does so well: it declares read-only semantics, no model call, no caching, and per-view behavior nuances (provider view sees council members individually and circuit_open sheds). Minor omissions like empty-window behavior and bucket ordering prevent a 5, but the safety and side-effect profile is fully disclosed.

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?

Five dense sentences, front-loaded with the core purpose before any detail. Every clause earns its place: scope, bucketing/aggregates, filters, council-record extras, example queries, and the no-call/no-cache guarantee — no filler or repetition of schema content.

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?

Given there is no output schema, the description compensates by naming the returned metrics (calls/allowed/refused/errors, avg and p95 latency, error_rate, totals, plus quorum/consensus/synth_fallback), which is the critical missing piece. It covers defaults, filters, and view semantics; the only gaps are the exact JSON response shape and bucket limits/ordering, which are minor for a read-only stats tool.

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% with genuinely descriptive parameter docs, so the baseline is 3. The description adds interpretive value beyond the schema by explaining that model/session filters 'narrow to one backend or workflow' and by listing the metrics produced per bucket, which gives the agent a mental model of what bucketing by each key yields.

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 first clause states a specific verb and resource: "Read-only usage/health stats aggregated from the ask_fable audit log." It further distinguishes itself from the large ask_*/list_*/trace_* sibling family by framing itself as the performance-monitoring tool ('see how the tools are performing without spelunking JSONL'), which no sibling claims.

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?

Concrete example questions ('is GLM erroring a lot today?', 'how slow are councils this week?') tell an agent exactly what kinds of queries route here, and 'makes no model call and is never cached' clarifies when it's safe/appropriate to invoke. It does not explicitly name exclusions or alternatives (e.g., session_stats for per-session detail), so it stops short of full when-not-to-use guidance.

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

trace_getB

Read the ordered events and artifact references for one trace.

ParametersJSON Schema
NameRequiredDescriptionDefault
trace_idYes
max_charsNo
include_contentNo

TDQS

B3.3/5.0
Behavior3/5

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

With no annotations, the description carries the load, and it does disclose the read-only nature and the ordered structure of the returned data. However, it does not explain truncation behavior, content inclusion, or what the response looks like beyond the high-level output.

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 a single well-formed, front-loaded sentence with no filler or redundancy. Every word contributes to identifying the tool's core purpose.

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?

The tool has no output schema and no annotations, so the description should explain more of the invocation context. It identifies what is returned but omits how max_chars affects the result, when include_content should be true, and what 'artifact references' concretely include.

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%, so the description should compensate, but it only implies trace_id via 'one trace'. max_chars and include_content are left entirely unexplained, and the description adds no semantic detail beyond what the parameter names already suggest.

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 verb ('Read') and a precise resource ('ordered events and artifact references for one trace'). It distinguishes trace_get from sibling tools like trace_list by emphasizing a single trace and its ordered event/artifact content.

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 guidance is given about when to use trace_get instead of trace_list, context_read, or session_peek. The description implies use for reading a trace's details, but it never states selection criteria, exclusions, or alternatives.

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

trace_listB

List recent correlated tool traces without raw content.

ParametersJSON Schema
NameRequiredDescriptionDefault
toolNo
limitNo
beforeNo
statusNo
projectNo
sessionNo
providerNo

TDQS

B3.2/5.0
Behavior3/5

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

With no annotations provided, the description carries the full burden. It discloses the basic read-only nature ('List'), the recency scope, and the 'without raw content' return limitation, but it leaves key behavioral aspects unexplained such as how 'correlated' is defined, ordering, pagination, and what fields are actually returned.

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 an efficient single sentence with a front-loaded verb and no filler. It is appropriately compact, though the brevity contributes to the lack of parameter and behavioral context.

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?

For a tool with 7 optional parameters, no annotations, and no output schema, this description is too thin. It supports a default unfiltered call but leaves nearly all filtering semantics, result shape, and correlation meaning to the agent's inference.

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

Parameters1/5

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

Schema description coverage is 0% across 7 parameters, and the description provides no parameter-level meaning. An agent cannot tell what 'before' refers to, what status values are accepted, or how 'session'/'provider' filter the correlated traces. The description adds no value beyond the bare parameter names.

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 ('List') on a clear resource ('recent correlated tool traces') and explicitly notes the absence of raw content, which distinguishes it from sibling trace_get. Even without naming the sibling, the 'without raw content' qualifier tells an agent this is the metadata-oriented list counterpart.

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

Usage Guidelines3/5

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

The description implies this tool is for browsing recent trace metadata rather than retrieving full trace content, but it does not explicitly state when to prefer this over trace_get or other trace-related tools. There is no explicit when-not-to-use guidance or alternative routing.

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. Dates show when Glama detected each change.

  1. 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
Disambiguation3/5

The ask_* family — ask, ask_opus5, ask_m3, ask_glm, ask_deepseek, ask_gemini, ask_codex, ask_grok, ask_kimi, ask_ollama, ask_atlas, ask_openrouter — all share the same core purpose (single-model engineering reasoning) and differ mainly by backend, so an agent must read provider/credential details to choose correctly. Council variants and context/session/trace groups are more distinct, and the lengthy descriptions rescue most ambiguity, but the overlaps are real.

Naming Consistency4/5

Naming is strongly family-consistent: ask_<model>, ask_<provider>_council, context_<verb>, session_<verb>, trace_<verb>, list_<provider>_models, configure_<provider>_council. Minor deviations like bare 'ask', 'stats', 'reset_session', and 'context_pack' break the pattern slightly, but there is no style mixing and conventions are predictable within each subfamily.

Tool Count2/5

37 tools is well into the 'too many' band, largely because the same capability (ask one model, or ask a council) is reimplemented per provider instead of parameterized — 10+ single-model ask tools and 4 council tools carry heavy redundancy. Each tool is individually defensible, but the set is bloated and imposes a large navigation burden on agents.

Completeness5/5

The tool surface is thorough for its domain: single and multi-model asking modes (council, chain, debate), full context-store CRUD plus file packing, session listing/peeking/stats/reset, trace retrieval and runtime configuration, usage statistics, live model catalogs, and council configuration persistence. There are no obvious dead ends or missing lifecycle operations.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/baggybin/ask-fable'

If you have feedback or need assistance with the MCP directory API, please join our Discord server