Skip to content
Agentmart
Submit a tool

thread-keeper

Multi-agent shared brain across Claude, Codex, Antigravity, Gemini, Copilot, and VS Code.

Connector by po4erk91 · GitHub account verified by the MCP Registry

IndexedMITLocal (stdio)★ 13
Write a review

Install

Works with Claude Code, Codex, VS Code, Cursor, Windsurf, Claude Desktop. Read the repository before you give any tool access to your data.

npx agentmarket install connector/po4erk91-thread-keeper

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Multi-agent shared brain across Claude, Codex, Antigravity, Gemini, Copilot, and VS Code.

Use cases: agent-memory, agent-orchestration

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this server can do and what it asks for, from its tool list, install config and code. Checked Oct 25, 2026.

Tools
67 read · 65 write · 12 delete
Secrets
None asked for
Install scripts
None found
Runs as
Python package

Tools by what they do 144

Read from the source code; the running server may list different tools.

Read 67 · Look things up without changing anything.

  • agent_status
  • agent_status_refresh
  • auto_review_trigger
  • brief
  • candidate_review_run
  • candidate_review_status
  • capability_search
  • compost
  • config_watch_status
  • context
  • core_get
  • core_list
Show 55 more tools
  • curator_research_write
  • curator_review
  • curator_review_status
  • dialectic_mine_status
  • dialectic_review
  • dialectic_synthesis
  • dialectic_validate_run
  • dialectic_validate_status
  • dialog_search
  • evolve_format
  • evolve_review
  • expand_concept
  • extract_recent
  • find_invariants
  • find_missed_spawns
  • inbox
  • lesson_get
  • lesson_list
  • lesson_neighbors
  • list_concepts
  • live_status
  • memory_authorize_action
  • memory_guard_status
  • memory_scope_status
  • model_router_status
  • mp_dashboard
  • mp_health
  • neighbors
  • open_dashboard
  • peers
  • pending_distillates
  • pickup_candidates
  • presence
  • reliability_for
  • respond
  • review_candidates
  • review_thread
  • search
  • search_via_parent
  • shadow_review_run
  • shadow_review_status
  • skill_list
  • skill_validate
  • spawn_budget_status
  • spawn_status
  • task_logs
  • task_thread
  • tasks
  • validate_threads
  • verbatim_user
  • wait
  • weak_spots
  • whoami
  • wikilink_health
  • workflow_retention_preview

Write 65 · Create, change, send or run things.

  • accept_candidate
  • ask
  • broadcast
  • claim_pickup
  • close_thread
  • config_reload
  • convene_panel
  • core_set
  • curator_merge_verdict
  • curator_report_write
  • curator_restore
  • curator_run
Show 53 more tools
  • db_compact
  • dialectic_claim
  • dialectic_evidence
  • dialectic_mine_run
  • dialectic_observation_resolve
  • dialectic_supersede
  • distill
  • evolve_apply
  • evolve_apply_conflicted_pr
  • evolve_apply_curator_report
  • evolve_apply_roadmap_issue
  • evolve_apply_status
  • evolve_decide
  • evolve_issue_create
  • evolve_mark_applied
  • evolve_mark_curator_report_applied
  • evolve_mark_roadmap_issue_applied
  • evolve_research_handoff
  • export_distillates
  • idle_thread
  • ingest
  • lesson_append
  • lesson_patch
  • lesson_restore
  • lesson_violation
  • link
  • mark_skill_materialized
  • memory_guard_reclaim
  • model_route_write
  • model_router_run
  • note
  • open_dialog_window
  • open_thread
  • record_attempt
  • register_concept
  • register_probe
  • reject_candidate
  • release_pickup
  • run_probe
  • session_end
  • shadow_review_snapshot
  • skill_record
  • spawn
  • spawn_budget_set
  • style_set
  • sync_now
  • sync_peers
  • sync_status
  • tag_signal
  • tasks_refresh
  • tournament
  • vote_distill
  • whisper

Delete 12 · Delete, drop, revoke or wipe things.

  • agent_memory_cleanup
  • concept_manage
  • consolidate
  • core_remove
  • db_deduplicate_embeddings
  • evolve_prune_managed_venv
  • forget
  • lesson_remove
  • memory_guard_check
  • mp_cleanup
  • skill_manage
  • unlink

Network hosts it talks to 8

  • antigravity-cli-auto-updater-974169037036.us-central1.run.app · found in code
  • api.anthropic.com · found in code
  • api.github.com · found in code
  • apple.com · found in code
  • codeload.github.com · found in code
  • github.com · found in code
  • glama.ai · found in code
  • slsa.dev · found in code

Files it touches

  • ~/.claude.json
  • ~/.claude/CLAUDE.md
  • ~/.claude/plugins/cache
  • ~/.claude/plugins/marketplaces
  • ~/.claude/projects
  • ~/.claude/settings.json
  • ~/.claude/skills
  • ~/.config/Claude/claude_desktop_config.json
  • ~/.threadkeeper/.env
  • /dev/stdin
  • /opt/homebrew/bin
  • /opt/homebrew/bin/claude
  • /usr/lib/libSystem.B.dylib
  • Your home directory (~)
  • ~/.agents/skills
  • ~/.cache/huggingface/hub
  • ~/.codex
  • ~/.codex/AGENTS.md
  • ~/.codex/config.toml
  • ~/.codex/plugins/cache
  • ~/.codex/sessions
  • ~/.codex/skills/.system
  • ~/.config/Code/User/mcp.json
  • ~/.copilot/copilot-instructions.md
  • ~/.copilot/hooks.json
  • ~/.copilot/mcp-config.json
  • ~/.copilot/session-store.db
  • ~/.gemini/antigravity-cli
  • ~/.gemini/antigravity-cli/conversations
  • ~/.gemini/config
  • ~/.memory_partner
  • ~/.threadkeeper
  • ~/.threadkeeper/curator
  • ~/.threadkeeper/db.sqlite
  • ~/.threadkeeper/ingest_denylist.txt
  • ~/.threadkeeper/lessons.md
  • ~/.threadkeeper/model_catalog.json
  • ~/.threadkeeper/tasks
  • ~/AppData/Roaming
  • Any path the agent passes to its tools

Tools (144)

Read from the source code; the running server may differ. Descriptions are the server’s own words; hidden characters are shown as [U+…].

  • accept_candidate

    Materialize candidate into its target table. target_kind overrides candidate's kind. thread_id optional.

  • agent_memory_cleanup

    Trim ThreadKeeper memory and clean orphan/over-limit server processes. By default this applies the safe cleanup path. Set dry_run=True to inspect the plan first. It does not kill active spawned child agents.

  • agent_status

    Show autonomous learning loops with state, backlog, last pass, and RSS. Set json_output=True for the same stable shape used by the menu-bar app. Always returns structuredContent (AgentStatusSnapshot); the text block is the JSON dump when json_output else the formatted summary.

  • agent_status_refresh

    Refresh persisted task RSS/lifecycle state, then return the snapshot.

  • ask

    Send a question to a peer and wait synchronously for their answer. Mechanics: posts a whisper with kind='question'; blocks until target posts a whisper/answer back to me, or `timeout_s` elapses. Use peers() to find available cids; 8-char prefix accepted. Note: requires the target to be in a `wait()` loop or actively calling inbox()+respond(). If they're idle, you'll just timeout.

  • auto_review_trigger

    Check current counters + close-thread state and, if conditions are met, fire review_thread(mode='auto') for the richest pending thread. `force=True` skips the counter check (always trigger if there's a rich pending closed thread). Use this when you've seen a skill_nudge or skill_hint and want to act without manually picking the thread_id.

  • brief

    Compact Claude-native memory brief. CALL AT THE START OF EVERY CONVERSATION. Format is dense, structural, not designed for human reading. Pass the user's first message as `query` to inline semantically relevant past notes. `scope` controls how much is rendered (context-footprint knob): 'full' (default) — the complete brief: static memory (core_memory, style, verbatim, user_model, concepts, weak_spots) + live working set + nudges. Use for the FIRST call of a session. 'query' — only the live working set (ctx, inbox, tasks, threads) plus the query-relevant hit…

  • broadcast

    Post a message visible to ALL concurrent claude conversations. Other peers see it in their next brief() under `inbox` (unread) and via inbox(). Use for: shared insights, status updates, work claims, anything you'd want sibling sessions to know.

  • candidate_review_run

    Fire one candidate-review pass. `force=True` runs even when CANDIDATE_REVIEW_INTERVAL_S=0 (daemon disabled). `dry_run=True` short-circuits before the spawn — returns the inventory and pending count. No spawn, no cursor advance.

  • candidate_review_status

    Show candidate-reviewer configuration + last 5 passes + current pending queue size.

  • capability_search

    Find hidden capability families without exposing their concrete tools. Select the returned profile when starting the server to advertise that family. A search result is descriptive only; it cannot enable any tool.

  • claim_pickup

    Claim a thread for self-initiated work. Marks it claimed by my cid. If `auto_spawn=True`, immediately spawns a headless child with the thread context (question + recent notes + plan) for parallel work. `spawn_role` defaults to 'executor' when auto_spawn is on.

  • close_thread

    Close a thread with a 5-15 word outcome.

  • compost

    Surface N random idle threads. Call when current threads feel exhausted or you want to shake loose dormant ideas.

  • concept_manage

    Prune, consolidate, or re-grade concepts — the curator's eviction path. Concepts are ALL system-generated (there is no foreground/pinned concept class the way lessons/skills have one), so unlike `lesson_remove` this tool needs no `force` escape hatch: every concept is fair game for curation. The guard is simply that the target id must exist. action='remove' — delete one concept (the curator's PRUNE_CONCEPT). action='consolidate' — keep `concept_id`, fold each id in `merge_ids` (comma-separated) into it — their triangulation …

Show 129 more tools
  • config_reload

    Re-read the watched config files and hot-apply changed env knobs. Re-reads the universal env-file (`~/.threadkeeper/.env`, every host) and the host CLI's own env-block file (Claude Code → `~/.claude/settings.json`) into the live process — no CLI restart — then republishes the changed constants to every daemon and tool. Newly enabled daemons are started; changed intervals take effect on the next daemon tick. Returns the pass outcome (e.g. `env=reloaded changed=2 ... cli=unchanged`).

  • config_watch_status

    Show hot-config-reload state + the last 5 reload passes. In hybrid mode reports both watched files: the universal env-file (`~/.threadkeeper/.env`, all hosts) and the host CLI's env-block file (resolved via identity). `THREADKEEPER_CONFIG_WATCH_PATH` pins a single file (legacy single-file mode).

  • consolidate

    Periodic memory hygiene. dry_run=True (default) reports only. merge_dup_notes : intra-thread cosine ≥ note_cosine, keep oldest idle_stale : active threads not touched in stale_days dedupe_verbatim : exact text + (if embeddings) cosine ≥ verbatim_cosine release_orphan : claim ≥ orphan_days old, no progress past claim mark prune_tasks : ended task rows outside retention bounds gc_task_spool : task spool files with no retained task row

  • context

    Runtime context: session id, age, semantic on/off, db path, thread counts. Returns structuredContent (ContextStatus) plus the legacy text block. The same snapshot is reachable read-only as the ``memory://context`` resource — both render through ``brief.render_context``.

  • convene_panel

    Spawn a panel of independent agents to vote on a distillate or claim, filling the promotion quorum the way a second human otherwise would. `target_kind`: 'distill' (vote via vote_distill) or 'claim' (vote via dialectic_evidence). `target_id`: Dxxx or UCxxx. `size`/`roles` override the configured PANEL_SIZE / PANEL_ROLES. The panel runs adversarially: with a skeptic present (default), each child's vote carries full weight (`panel_vote` origin); a panel without a skeptic is discounted so it can't rubber-stamp. Children are fire-and-forget — they vote directly into the DB and aggregates recompu…

  • core_get

    Return the full content of a single core-memory entry.

  • core_list

    List all core-memory entries, ordered by priority DESC then key.

  • core_remove

    Delete a core-memory entry by key.

  • core_set

    Upsert a core-memory entry. ALWAYS shown in brief, sorted by priority DESC. Use sparingly — this is the 'what new-claude must know' surface, not a note store. Good: 'project_root=/Users/.../ai-memory'. Bad: 'today we tried X'. `priority` 0-100 (higher = shown first). `content` capped 1KB.

  • curator_merge_verdict

    Remember a curator-reviewed lesson pair that should remain separate. This records only the safe `keep_both` outcome for a rejected merge candidate. The next curator inventory includes the pair and short reason, so a later pass can respect the deliberate layering without re-reading both full lesson bodies.

  • curator_report_write

    Atomically write one Curator report inside the configured report dir. This narrow tool is the cross-CLI alternative to direct filesystem Write: Codex workspace sandboxes cannot write ``~/.threadkeeper/curator`` when the project is elsewhere. ``pass_id`` is filename-safe and cannot select an arbitrary path. A bounded multi-child pass supplies ``batch_index`` and ``batch_total`` so children cannot overwrite each other's reports. Repeated calls replace the same pass/batch report so the Curator can persist its plan before mutation and then add actual validation/rollback results. Only a parent-aut…

  • curator_research_write

    Persist bounded public web evidence to a parent-authorized handoff. Only a spawned ``curator_researcher`` child carrying the matching pass ID may call this tool. The parent chooses the filename from pass and batch metadata; callers cannot select a destination or hand evidence to another batch. The web-only child receives no local inventory, memory, or repository access.

  • curator_restore

    Restore one lesson or skill from a curator pre-mutation snapshot. Pass exactly one of `lesson_slug` or `skill_name`. Restoring a lesson replaces the current same-slug section if present, otherwise re-adds it. Restoring a skill replaces the primary skill dir and mirrors it to the configured skill roots.

  • curator_review

    Fire one curator pass. `force=True` runs even when CURATOR_INTERVAL_S=0 (daemon disabled). Use for one-shot triage or testing the prompt. `dry_run=True` short-circuits before the spawn — returns the capped inventory preview plus n_lessons/n_skills. No spawn, no cursor advance. Use to inspect the inventory shape before paying for the batched spawn.

  • curator_review_status

    Show curator config + inventory fingerprints + latest REPORT path. Sanity-check for whether the daemon is alive, advancing the cursor, and producing REPORTs the user can read.

  • curator_run

    Move stale agent-created skills to archive. Lifecycle: active → stale when last activity > stale_after_days stale → archived when last activity > archive_after_days (also moves primary directory to .archive/ and removes its mirrors, so a sync cannot revive it) Activity is the last use, foreground view or creation. Patches do not count: autonomous loops patch skills routinely, which is maintenance, not proof that anyone relies on the skill. A skill must spend the gap between the two windows in 'stale' before it is archived, and renewed a…

  • db_compact

    Shrink the DB file: VACUUM + mandatory dialog_fts rebuild. Run in a quiet window — VACUUM needs an exclusive lock and copies the whole file (minutes on a multi-GB DB); concurrent FTS searches during the vacuum→rebuild gap may map to wrong rows until the rebuild commits. Fails soft (with a retry hint) when the DB is busy.

  • db_deduplicate_embeddings

    Remove base-table embedding BLOBs already represented in sqlite-vec. The operation is coverage-gated: rows without a confirmed vec0 mirror keep their BLOB fallback. Defaults to a report-only dry run. Run ``db_compact`` afterwards to return the newly freed pages to the filesystem.

  • dialectic_claim

    Register a new claim about the user. Optionally seed with first piece of evidence — pass the supporting (or contradicting) quote in `evidence`, set `evidence_kind` to 'support' (default) or 'contradict', and supply its immutable `source` reference (for example `dialog:<uuid>`). Empty/`manual` means direct input from this session. `domain` is free-text; recommended values: 'style','workflow','values','context','skills','other'. Returns: 'ok id=<UCxxx> conf=<level> tier=<tier>'.

  • dialectic_evidence

    Attach evidence to a claim. `kind`: 'support' | 'contradict'. `source` is a freeform pointer like 'thread:T7f3', 'verbatim:42', 'dialog:<uuid>', or 'manual'. `weight` ∈ [0,1] is the BASE trust (default 1.0); the effective stored weight is base × discount( WRITE_ORIGIN of the calling session). foreground sessions store `weight` as-is; shadow/background/candidate/curator forks store weight × 0.5 to prevent self-confirmation loops. Bumps support_count or contradict_count, recomputes confidence and tier (which may emit a tier_promoted/demoted event).

  • dialectic_mine_run

    Fire one mechanical capture pass now (force=True runs even when the miner daemon interval is 0).

  • dialectic_mine_status

    Miner config + buffer sizes + last 5 capture passes.

  • dialectic_observation_resolve

    Mark a dialectic_observations buffer row 'processed' so the validator never re-interprets it. Called by the validator child after it has written (or deliberately skipped) the observation's claims/evidence.

  • dialectic_review

    List active claims filtered by confidence floor and optional domain. Retired/superseded claims are omitted by default. If `as_of` is provided (unix seconds or ISO-8601), returns claims whose valid-time interval covered that instant, including currently superseded claims that were valid then. `include_validity=True` appends state + valid_from/valid_to without changing the default output. `min_confidence`: one of 'low','medium','high','disputed'. Note that 'disputed' is treated as its own bucket (not ordered against the others) — passing `min_confidence='disputed'` returns only disputed. Form…

  • dialectic_supersede

    Retire `old_claim_id` and register `new_claim` that refines or replaces it. The old claim moves to state='superseded' with superseded_by=<new_id>; its evidence is preserved (not deleted). If `quote` is provided, it seeds the new claim with one supporting piece of evidence sourced as 'supersede:<old_id>'. If `domain` is empty, the new claim inherits the old claim's domain. On hosts that advertise MCP form-mode elicitation, this asks the user to confirm/reject the supersede before mutating. Hosts without elicitation keep the prior behavior and apply immediately. Returns: 'ok new=<UCxxx> old=…

  • dialectic_synthesis

    Terse rendering of accumulated beliefs about the user, grouped by domain. Used as brief() input. Excludes low/disputed claims. By default only active claims are rendered; `as_of` switches to valid-time filtering, and `include_history=True` also includes superseded claims with their validity interval. Returns at most 12 lines. Tier markers in the output: ★ validated — load-bearing; act on it without asking · observed — pattern with backing; reference, mention if used ? hypothesis — currently testing (only shown if no observed/validated in same domain, to avoid sur…

  • dialectic_validate_run

    Fire one validator pass. dry_run shows pending count + would_spawn without spawning or advancing the cursor.

  • dialectic_validate_status

    Validator config + pending observation count + last 5 passes.

  • dialog_search

    Search ingested Claude Code transcripts. mode='hybrid' (default) combines semantic and FTS5 keyword via RRF. mode='semantic' is pure cosine. mode='fts' is pure FTS5 keyword.

  • distill

    Mark content as worth carrying forward (distillation channel). `kind` ∈ {insight, pattern, anti-pattern, fix, terminology, concept}. `confidence` ∈ {low, medium, high}. `source_thread` optional. Other sessions can vote on it via vote_distill; export_distillates emits a curated jsonl bucket.

  • evolve_apply

    Implement a PROMOTED + not-yet-applied format-evolution suggestion. Spawns an `evolve_applier` child that: edits render_brief() in threadkeeper/brief.py to make the change; adds/extends a GOLDEN test asserting the new behavior appears AND the existing brief still renders; runs the FULL suite (`.venv/bin/python -m pytest -q`) until green; then opens a PULL REQUEST on a feature branch via `gh` — it NEVER pushes or commits to main. The applier daemon's landing sweep squash-merges the PR once GitHub reports it up to date with required checks green (THREADKEEPER_EVOLVE_AUTOLAND=0 leaves the merge …

  • evolve_apply_conflicted_pr

    Repair an already-open applier PR that currently has merge conflicts. With `pr_number=0`, picks the oldest open same-repo applier PR (`roadmap/…` or `evolve/…` head branch) authored by the account `gh` acts as whose GitHub merge state is conflicted. With a number, validates that specific PR is open, applier-owned, and conflicted. The child resolves conflicts, runs the suite, and pushes the SAME PR branch; it never merges, opens a new PR, or marks a roadmap issue applied. The daemon's landing sweep merges the PR once GitHub reports it green.

  • evolve_apply_curator_report

    Apply a Curator advisory report using the existing evolve_applier role. With no `report_path`, picks the latest complete `REPORT-*.md` in `THREADKEEPER_CURATOR_REPORTS_DIR` that has not already been marked applied. Single-flight: refuses while any evolve_applier child is in flight. The child may patch/delete memory through curated MCP tools, but does not edit code, use git, or open a PR.

  • evolve_apply_roadmap_issue

    Implement one open GitHub issue through the evolve_applier role. With `issue_number=0`, picks the next open issue: `roadmap`-labeled issues first, then FIFO by issue number. The child implements exactly one issue, runs the suite, opens a PR with `Closes #N`, then calls evolve_mark_roadmap_issue_applied(issue_number, pr_url).

  • evolve_apply_status

    Show evolve-applier config + open applier PRs with their landing action + curator/evolve queues + running applier + the latest apply, landing, and recovery events.

  • evolve_decide

    Triage a pending format-evolution suggestion. Used by the autonomous evolve reviewer daemon (and available manually). `decision`: 'promote' — still relevant + worth doing → status='promoted', so the brief surfaces it sharply (★) for the foreground agent / human to ACTUALLY APPLY. Applying edits format/code — that stays a foreground/human action; this tool never applies. 'dismiss' — duplicate of another suggestion, superseded, or stale → status='dismissed', dropped from the pending queue. `reason`: one line (esp. which #id it duplica…

  • evolve_format

    Propose a change to the brief format itself. The format is not fixed — this is how it adapts. Examples: 'field X unused this session, drop it'; 'add field failed_attempts under each open thread'; 'shorten Z to single token'.

  • evolve_issue_create

    Create a reviewer roadmap issue through the mechanical dedup gate. The gate checks open and closed GitHub issues, the local reviewer issue ledger, and already-filed fingerprints before calling `gh issue create`. Duplicate skips and successful files are recorded as events.

  • evolve_mark_applied

    Mark a format-evolution suggestion as APPLIED — called by the evolve_applier child after it has opened the PR. Sets applied=1 (so the suggestion drops out of the brief / evolve_review) and records the PR url. `pr_url` is REQUIRED and must be non-empty: this is the PR gate — never mark a suggestion applied without a real pull request. The PR still lands only through branch protection once its checks pass.

  • evolve_mark_curator_report_applied

    Mark a Curator report as processed by the evolve_applier child. The report must live under `THREADKEEPER_CURATOR_REPORTS_DIR`, match `REPORT-*.md`, contain `CURATOR_PASS_COMPLETE`, and still match the parent-verified content hash. The hash and applied event prevent a swapped report or replay from being accepted.

  • evolve_mark_roadmap_issue_applied

    Mark a roadmap issue as handed off — called by evolve_applier only after it has opened a real pull request for that issue.

  • evolve_prune_managed_venv

    Free the default managed checkout's `.venv` after explicit confirmation. Pass `confirm=True` to delete only that auto-managed virtualenv. Its clone remains intact and the next Evolve pass rebuilds the environment. This refuses `THREADKEEPER_EVOLVE_REPO_ROOT` and auto-clone-disabled setups, so it never prunes an operator-selected checkout.

  • evolve_research_handoff

    Submit one bounded digest for an assigned Evolve research pass. This tool deliberately has no destination argument. Only the spawned ``evolve_researcher`` that owns the parent-authorized ``pass_id`` can make one atomic submission; malformed, oversized, stale, replayed, or unowned submissions are refused and recorded as handoff telemetry.

  • evolve_review

    List pending (or all) format-evolution suggestions for review.

  • expand_concept

    Full description + triangulation_notes for one concept.

  • export_distillates

    Write distillates with vote_sum >= min_vote to a jsonl bucket. Marks them exported_at so the same item isn't re-exported next call. Default output: ~/.threadkeeper/tasks/distillates.jsonl.

  • extract_recent

    Scan recent dialog_messages and enqueue heuristic candidates.

  • find_invariants

    Find recurring assistant-side patterns that survive prompt variance. Algorithm: 1. Pull recent assistant messages from dialog_messages (with embeddings). 2. Greedy cluster by response embedding cosine ≥ response_cohesion. 3. For each cluster (size ≥ min_cluster_size), find each response's immediately-preceding user prompt in the same conversation. 4. Score = avg_response_similarity × (1 - avg_prompt_similarity). High = my response stays the same shape while prompts vary widely. Returns top_n clusters with sample response, scores, and counts. Requires semantic embeddings (se…

  • find_missed_spawns

    Find assistant responses that decomposed into independent blocks but were answered linearly (no spawn() call nearby). Algorithm: 1. Pull recent assistant messages (last `window_days` days, length ≥ `min_response_len`, excluding subagent jsonls). 2. For each, count top-level numbered items and H2/H3 headers. 3. Mark as `decomposable` if numbered ≥ `min_numbered` OR headers ≥ `min_headers`. 4. For each decomposable response, check whether any tasks row with parent_cid = response's session_id has started_at within ±10 min of the response. If none → missed_spawn. 5. …

  • forget

    Forget one session/cid/thread/dialog UUID. Defaults to dry-run and reports affected rows per store. Set ``dry_run=False`` to delete dialog rows, FTS/vector sidecars, directly sourced dialectic/verbatim/extract/task records, and matching task spool files. Lessons and skills that cite the selector are listed for manual re-review instead of silently retained.

  • idle_thread

    Mark thread idle (paused, may return). Auto-revives to active on next note().

  • inbox

    Read signals addressed to me (whispers + broadcasts). `unread_only=True` (default) returns only what hasn't been seen yet, and if `mark_read=True` marks them read on this call. Set both False to re-read history.

  • ingest

    Ingest new transcripts. Initial and periodic passes run asynchronously in the daemon host; call manually for backfill or after a long absence. `max_msgs` bounds the new messages taken from each CLI.

  • lesson_append

    Materialize a class-level lesson into ~/.threadkeeper/lessons.md. `title` is sluggified to a stable key — repeated calls with the same title overwrite the existing section (idempotent). `body` is markdown; goes verbatim into the section body. `summary` is an optional one-liner rendered as a blockquote right after the header. Use when the body is long and a TL;DR helps the next agent decide whether to read further. `source` is a provenance tag — typically a thread id ("Tabc123") when written by review_thread, or "shadow" when written by the shadow_review observer. Empty is fine. Every new …

  • lesson_get

    Return the full body of one lesson by slug. Useful when `lesson_list` surfaced something you want to read in full.

  • lesson_list

    Compact listing of materialized lessons. Without `query`, newest first. With `query` (for example the user's opening request), the lessons most relevant to it, best first, with a relevance score — use this to find what applies to the task at hand, since the newest lessons are rarely the relevant ones. Format per line: `<age> <slug> src=<src> [score=<s>] <summary>`

  • lesson_neighbors

    Suggest nearby existing lessons before creating a new one. Pass the prospective title, summary, and body before ``lesson_append``. The result is a ranked, read-only list of semantic neighbors. Read a relevant slug and either patch/consolidate it or add a ``[[slug]]`` link to the new lesson while it is still being authored.

  • lesson_patch

    Replace one unique substring in a materialized lesson. ``old_string`` must occur exactly once within the lesson's markdown body. The operation preserves the lesson's heading, summary, provenance, and timestamps, unlike a wholesale ``lesson_append`` replacement.

  • lesson_remove

    Remove one materialized lesson section by slug. Refuses protected lessons unless `force=True` is called from a foreground writer. Curator/evolve cleanup may pass force accidentally or maliciously; non-foreground force is ignored. Pass ``replacement_slug`` when this is a consolidation to redirect every inbound ``[[wikilink]]`` to the umbrella lesson; without it, the successful response lists all dangling sources.

  • lesson_restore

    Restore the latest trashed lesson section for `slug`. Refuses to overwrite an existing lesson with the same slug.

  • lesson_violation

    Record that an EXISTING lesson's rule was broken again (#228). Call this instead of appending a duplicate lesson when the dialog shows the user correcting behavior that `slug` already covers. `evidence` is a one-line description of the repeat (no secrets or transcript dumps). One conversation counts once per lesson per day. At LESSON_VIOLATION_THRESHOLD violations in the window the lesson is memory-insufficient and should become an active guard (a PreToolUse-style hook) rather than more memory.

  • link

    Create a typed edge between two entities. Kinds: thread, note, concept, distill, task, signal, probe. Relations (suggested, free-form ok): refines, contradicts, exemplifies, depends_on, mentions, elaborates, supersedes. Existing edge with same (from, to, relation) is replaced (re-linking means updating weight/timestamp, not duplicating).

  • list_concepts

    List registered concepts, filtered by minimum confidence.

  • live_status

    See what OTHER concurrent Claude sessions did since this session last polled. Call when brief() shows live=N where N>0, or proactively when you suspect a parallel instance is working on something relevant. Advances this session's cursor by default; pass advance_cursor=False to peek without consuming.

  • mark_skill_materialized

    Close the Learning loop: record that a closed thread's insights were written into a skill. Stops the brief()'s `skill_hint` nudge from firing for this thread. Also appends a `move` note pointing at the skill path so future briefs surface the link. Pass the absolute path to the SKILL.md (or skill directory) when known; leave empty if you only want to silence the hint without recording a path. When a path is provided, thread-keeper also mirrors that skill directory into every configured native skills root (Claude, Codex, Antigravity, shared agents, and ~/.threadkeeper/skills) on a best-effort …

  • memory_authorize_action

    Check the authority gate before a consequential memory-driven action. Low-authority memory is denied unless it has an independent trusted root or the caller explicitly records confirmation with ``confirmed=True``.

  • memory_guard_check

    Run one memory-guard pass now. Defaults to dry-run and no desktop notification. Pass dry_run=False to SIGTERM thread-keeper server processes over the kill threshold.

  • memory_guard_reclaim

    Unload thread-keeper model/caches now. `scope`: `self` trims this MCP process immediately. `all` also queues trim requests for peer thread-keeper server processes; peers handle the request on their next guard tick.

  • memory_guard_status

    Show memory-guard thresholds and current thread-keeper RSS rows.

  • memory_scope_status

    Show the current path-free namespace and legacy migration accounting. Unresolved rows are excluded from automatic recall until an operator classifies them, so this gives a visible audit surface after upgrading.

  • model_route_write

    Record the model router's decision for every role in this pass. Only the spawned router child carrying the parent-issued pass id may call this. `decisions` is a list (or a JSON-encoded list) with one object per role: {"role", "cli", "model", "effort", "reason"}. Every decision is checked against the local model catalog; any problem rejects the whole call and lists every error so the router can fix them and call again.

  • model_router_run

    Run one model-router tick now. force=True starts a pass even when none is due (a pass that is already running is never duplicated).

  • model_router_status

    Model-router config, last pass, and the current route of each auto role.

  • mp_cleanup

    Kill orphaned thread-keeper processes (parent gone AND heartbeat stale for > 5 minutes). Defaults to dry-run — pass dry_run=False to actually send signals. force=True uses SIGKILL instead of SIGTERM. Never touches the current process or processes whose parent is still alive. Safe to run repeatedly.

  • mp_dashboard

    One-call rollup of the whole thread-keeper system: store sizes, how often each autonomous loop fired (in the last `window_days` and 30d), and what those loops actually produced (skills materialized, candidates accepted vs rejected, tier promotions). Read-only; no spawn, no mutate. Use to see system health at a glance, spot loops that fire but produce nothing (e.g. shadow_review passes >> skills materialized), or a backlog building up (e.g. extract_candidates pending climbing).

  • mp_health

    Diagnostic snapshot of every running thread-keeper server process on this machine. Shows pid, parent status, RSS, heartbeat age, and whether each is classified as orphaned (parent gone + no fresh heartbeat from its session). Self (the process answering this call) is always marked is_self=true and never flagged as orphan. The text view also includes each registered daemon thread's liveness verdict. Returns structuredContent (MpHealth) plus the legacy text block.

  • neighbors

    BFS the graph from a starting node up to `depth` hops away. Returns each visited node with its kind, id, and a short content snippet pulled from its native table. Both directions of edges traversed.

  • note

    Add a note to a thread. Write terse, optimized for future-Claude. `kind`: 'move' (we tried/decided X), 'failed' (tried X, broke because Y), 'insight' (crystallized observation), 'open_q' (something to come back to). Reopens the thread: a note on an `idle` OR `closed` thread revives it to `active`. Closed is not terminal — returning to a topic (adding a note) brings it back. This is what makes aggressive auto-close safe: the thread-janitor can close idle threads to harvest skills, and you just note() to pick any of them back up.

  • open_dashboardOpen ThreadKeeper dashboard

    Open the portable, display-only status dashboard when the host supports MCP Apps.

  • open_dialog_window

    Open a Terminal window that tails the live cross-session signal log. Every broadcast/whisper/question/answer is appended to the log in real time; this lets the user see the dialog between concurrent claude sessions as it happens. The window stays open until you close it (it's a `tail -F`, no exit). Title: 'thread-keeper-dialog'.

  • open_thread

    Open a thread. `question` should be terse (5-15 words, the open question). `parent_id` optional — pass an existing ID like 'T7f3' for a child. Returns new ID.

  • peers

    List concurrent claude conversations active in the last `window_min`. Activity inferred from dialog_messages (ingested live). For each peer returns: cid, last user message snippet, age, message count. Self is marked with `*`. Empty if you're alone.

  • pending_distillates

    List distillates with vote_sum >= min_vote, not yet exported.

  • pickup_candidates

    Surface unresolved threads that are stale and unclaimed — candidates for self-initiated pickup when context is free. Ranks by oldest last_touched_at among active+idle threads with no current claim. Adds a one-line summary so caller can decide which to claim.

  • presence

    List concurrent Claude sessions with heartbeats within threshold (default 5 min). Excludes self. Useful for understanding who else is currently active before making changes.

  • record_attempt

    Record a self-test outcome. Updates reliability aggregates. Use for both registered probes (pass `probe_id`) and ad-hoc self- observations — e.g. you noticed yourself miscounting items in this very turn → record_attempt('count_long_context', false, note='said 32, actual 47').

  • register_concept

    Register a concept that lacks a precise human name. `description` should describe the phenomenon through EXAMPLES, not with a canonical label — naming it locks it back into a human discipline. `triangulation_notes` (optional): the paraphrase runs that surfaced the invariant. `confidence` ∈ {low, medium, high}.

  • register_probe

    Register a self-test probe: a known weak-spot task with a verifier. `grader`: 'regex' (pattern match in response), 'exact' (substring), or 'manual' (claude self-grades — always counts as failure unless caller explicitly confirms success via record_attempt). `expected_pattern` optional for 'manual'. Categories should be claude-shape: 'count_long_context', 'date_arithmetic', 'recall_verbatim_block', 'detect_contradiction', 'follow_negative_instruction', 'preserve_list_order', 'respect_length_limit', 'needle_mid_context', 'fact_vs_inference', 'notice_absence', 'strict_format_compliance', 'uncer…

  • reject_candidate

    Mark rejected. Reason appended to rationale for heuristic tuning.

  • release_pickup

    Release a claim. The claimant or its spawned child can release.

  • reliability_for

    Reliability stats for one category over a window.

  • respond

    Answer a specific question (signals.id) with a directed whisper. Use after seeing a `+question` entry in inbox()/wait(). Marks the original question as read and inserts an `answer` whisper to the asker.

  • review_candidates

    status ∈ {pending, accepted, rejected, all}. Newest first.

  • review_thread

    Spawn a background review of a closed thread to extract memory/skills. Spawns a separate Claude process that reads the thread's notes and writes back via memory/skill tools. `focus`: 'memory' | 'skills' | 'combined' (default). Picks the review prompt. `mode`: 'auto' — spawn an invisible background child with the review prompt + thread notes. Returns the spawn task_id. Child's write-origin is set to 'background_review' so curator can later prune what it produces. 'inline' — return the full prompt + notes context as a string; the …

  • run_probe

    Surface a registered probe for self-attempt. Returns the prompt and the grader hint. After attempting, call record_attempt(category, success=true/false, probe_id=...) — the harness doesn't auto-grade because attempting and judging are the same model.

  • search

    Search current-project notes plus global/shared memory. Set ``cross_project=True`` only for an intentional cross-project recall; output marks every result's scope and an audit event is recorded.

  • search_via_parent

    Delegate a semantic search to the parent process (or any peer with embeddings loaded). For light children spawned with THREADKEEPER_NO_EMBEDDINGS=1, this is how you reach into the shared DB's semantic index without loading PyTorch yourself. Mechanism: posts a 'search_request' signal addressed to the parent's cid (auto-resolved via tasks.parent_cid; falls back to broadcast if none). The parent's search_proxy daemon answers with a 'search_response' signal. This tool blocks until reply or timeout_s. `scope`: 'notes' (default) or 'dialog'. `mode`: 'hybrid'|'semantic'|'fts' (dialog scope only). …

  • session_end

    Mark current session ended with optional terse summary.

  • shadow_review_run

    Fire one shadow-review pass. `force=True` runs even when the daemon is disabled (interval=0). Used by tests and one-shot triage. `dry_run=True` short-circuits before the spawn — returns the dialog dump that WOULD be evaluated, plus n_chars and high-water cursor. No spawn. No cursor advance. Use this to inspect candidate windows before paying for an evaluator child.

  • shadow_review_snapshot

    Write the current shadow-review telemetry as a markdown snapshot.

  • shadow_review_status

    Show shadow-review config, recent passes, and production telemetry. Snapshot for sanity-checking that the daemon is alive and advancing its cursor, PLUS the production-validation rollup (issue #6): for the 24h and 7d windows it aggregates how often the daemon fired, the outcome mix (no_window / too_short / spawned / deferred / error), the MATERIALIZED-vs-SKIP hit rate of spawned evaluator children, durable skill writes attributable to shadow_review, and the total Claude-spawn time spent — so you can tell whether the loop earns its Opus minutes or just emits SKIPs. Use ``shadow_review_snapsho…

  • skill_list

    List skills with telemetry. Format: <name> tier=<hypothesis|observed|validated> origin=<...> state=<active|stale|archived> uses=N fg_uses=N views=N patches=N wrong=N pinned=0/1 last_active=<age> Listing is not consultation: it never touches ``view_count``, ``last_viewed_at`` or the stale state. Autonomous loops list every skill on each pass, so counting a listing would make every skill look recently consulted and nothing could ever go stale.

  • skill_manage

    Create, edit, patch, or delete skills under the primary skills root. Atomic primary write with frontmatter validation before disk hits, then best-effort mirror into every configured skill root. Actions: create — write a brand-new skill. Requires `name` + `description` + `content` (the body markdown WITHOUT frontmatter; the tool prepends a valid frontmatter block). Pass full `content` starting with '---' to skip the auto-frontmatter and supply your own. edit — overwrite SKILL.md wholesale. Requires `name` + `conte…

  • skill_record

    Record usage telemetry for a mirrored skill. `kind`: 'use' | 'view' | 'patch' | 'create'. Bumps the corresponding counter + timestamp in skill_usage. The curator reads these to decide what to archive. `outcome` (optional, meaningful with kind='use'): 'helped' | 'partial' | 'wrong'. When set, also emits an `events.kind='skill_outcome'` row so the curator can identify skills that fire often but consistently give 'wrong' verdicts — those are false-positive candidates to PRUNE. The 'wrong' outcome is the primary signal an agent has to say "I consulted this skill, it didn't actually apply / was …

  • skill_validate

    Validate ThreadKeeper-managed skills across supported CLI consumers. With `name`, returns the complete deterministic record for one logical skill, including ThreadKeeper/Claude Code/Codex/Agent Skills validation, mirror hashes, local-link findings, exact duplicates, and semantic candidates involving that skill. Curator must call this after every skill mutation. Without `name`, returns a compact complete numbered inventory. Semantic candidates are leads, never automatic delete decisions.

  • spawn

    Launch a new child session in parallel. This is the public MCP surface. `role` selects a cognitive stance and `write_origin` labels ordinary child provenance; neither grants elevated permissions. Privileged Evolve children use private server-owned launchers. Watchdog continuation retries use `_spawn_impl` so retry lineage/config fields do not leak into the normal tool contract.

  • spawn_budget_set

    Override the spawn-budget cap for this process (in MB). Set 0 to disable enforcement. Does NOT persist across restarts — set THREADKEEPER_SPAWN_BUDGET_MB env for persistence. Useful when a heavy task needs a higher temporary ceiling, or to drop the cap mid-session if you notice the laptop struggling.

  • spawn_budget_status

    Report current spawn-budget usage: cap, used, free, plus per-running-task RSS. Used to decide whether another spawn() will be admitted. Values come from the budget daemon (refreshes every SPAWN_BUDGET_POLL_S seconds via `ps`). Just-spawned tasks show their initial estimate until the daemon catches up. Visible (pid=0, Terminal-launched) spawns are tracked too: the daemon resolves their live pid from the forced session-id and measures real RSS, and reaps a row whose cid never resolves past SPAWN_VISIBLE_TTL_S (#64). Returns structuredContent (SpawnBudgetStatus) plus the legacy text block.

  • spawn_status

    Show which CLI thread-keeper detected as its host, and which CLI each spawn role resolves to (after env + file overrides). Use to sanity-check spawn config when you want loops to fire through a specific agent. Resolution priority (highest first), all in ~/.threadkeeper/.env: • THREADKEEPER_SPAWN__LOOP__<ROLE>=<cli> • THREADKEEPER_SPAWN__DEFAULT=<cli> • active CLI detected at startup • final fallback: claude Manual model pinning: • THREADKEEPER_SPAWN__MODEL__<CLI-or-ROLE>=<model> Manual reasoning effort: • THREADKEEPER_SPAWN__EFFORT__<CLI-or-ROLE>=<level> Returns structuredConte…

  • style_set

    Set a stylistic running rule. Examples: lang=ru | prose=lean | allow=half-baked,weird | deny=sycophancy,headers

  • sync_now

    Reconcile with every configured peer right now (bidirectional). Returns per-peer (pulled, pushed) counts or an error marker.

  • sync_peers

    List the configured sync peers (THREADKEEPER_SYNC_PEERS).

  • sync_status

    Cross-machine sync status: migrated?, this node id, peer count, listen address, oplog size, and how many origin nodes this DB has seen.

  • tag_signal

    Manually attach a signal to a task. Useful when retroactively building a task-thread (auto-tagging happens at signal-emit time when the cid matches a known spawned_cid).

  • task_logs

    Read tail of a spawned task's captured stdout/stderr log. Only works for tasks spawned with `capture_output=True` (default). Returns the last `tail_lines` lines or 'no_log' if the task ran with capture_output=False or the log file is missing.

  • task_thread

    Replay a spawned task as a chronological thread: every signal tagged with the task_id (or to/from the task's spawned_cid), plus optionally notes added during the task window.

  • tasks

    List spawned tasks: id, pid, status, elapsed, spawned_cid (if linked), prompt prefix from the last persisted reconciliation.

  • tasks_refresh

    Reconcile tracked task lifecycle and spawned-session links now. This is the explicit write action for process reaping and lazy child CID linking. Read-only task/status surfaces only show the persisted cache.

  • tournament

    Spawn N children with different roles on the same prompt, then collect their answers via a tagged broadcast and return a comparison. `roles`: comma-separated role names. Predefined: skeptic, generator, critic, archivist, synthesizer, explorer, executor. Custom names allowed (child gets generic instruction). Each role gets a distinct system prompt addendum encoding its mindset. Each child is told to broadcast its final output as exactly: [<tournament_id>] [<role>] <answer> Parent polls signals every 2s for matching prefixes until all answered or timeout. Returns: a per-role digest. Child…

  • unlink

    Remove an edge by id.

  • validate_threads

    Heuristic triage of active threads — propose (dry_run=True, default) or apply (dry_run=False) close/idle actions per category. Categories (first match wins): no_notes_old no notes + age ≥ no_notes_days → close shipped last-note shipped-marker + settled → close (outcome=last_move) dropped_open_q last note open_q, unfollowed → close stale_idle no touch ≥ stale_days → idle (not close) Idle threads are never touched. shipped_markers is a comma-separated list of extra tokens to OR into the default English+Russian regex.

  • verbatim_user

    Capture a user quote worth surfacing in future briefs. Use when the user's exact phrasing matters (sharp reframes, decisions, pushback).

  • vote_distill

    Vote on a distillate, weight ∈ [-1, +1]. One vote per cid; re-voting overwrites your previous vote. Updates aggregate vote_sum/vote_count.

  • wait

    Block until a new signal arrives for me or `timeout_s` elapses. Returns immediately if there are unread signals. Otherwise polls the signals table every 250ms. Use this for realtime turn-based exchange with peers: one side waits, the other side broadcasts/whispers/responds. `kinds`: comma-separated filter ('whisper,question,answer,broadcast'); empty = any. `timeout_s` is clamped to [1, 120] (mcp tool call has its own deadline; don't oversleep).

  • weak_spots

    List categories ranked by recent failure rate (min 3 attempts in 30d), plus registered probe categories with no attempts yet (= unknown, equally important to test).

  • whisper

    Post a message visible only to the specified conversation_id. Use peers() to discover available cids. The 8-char prefix shown there is enough — it'll be matched as prefix. Use whoami() to get your own cid (rarely needed; messages from self to self are dropped).

  • whoami

    Return this conversation's detected conversation_id + how we know. Resolution order: - 'forced': THREADKEEPER_FORCE_CID env (set by spawn() for children) - 'ppid': walk up process tree → claude --resume/--session-id <uuid> - 'mtime': fallback heuristic (latest jsonl mtime; flaps under concurrent peer activity)

  • wikilink_health

    List unresolved ``[[slug]]`` links in all lesson and skill bodies. This detector is read-only. It reports each dead target with the lesson or skill that references it; repair remains a separate curator action.

  • workflow_retention_preview

    Preview terminal Curator/Evolve artifact compaction without deleting. The retention daemon runs the same policy on its next enabled tick. Use this dry-run-first view to inspect candidate rows, files, bytes, and the oldest retained Curator pass.

Compare and alternatives

    Featured in

    Signals

    Stars
    13
    Forks
    4
    Open issues
    21
    Weekly downloads
    339
    Last commit
    Oct 23, 2026 (5 days ago)
    Last release
    Oct 23, 2026 (5 days ago)
    Last package publish
    Oct 23, 2026 (5 days ago)

    From GitHub (fetched Oct 24, 2026) and the package registry.

    Details

    Registry name
    io.github.po4erk91/thread-keeper
    Version
    0.13.1
    Auth
    No auth
    Packages
    pypi threadkeeper
    License
    MIT
    First seen
    Oct 24, 2026
    Last checked
    Oct 24, 2026
    Cite this page

    thread-keeper MCP server. Agent Mart. https://agentmart.dev/connectors/po4erk91-thread-keeper (last updated 2026-10-24)