{"name":"io.github.po4erk91/thread-keeper","slug":"po4erk91-thread-keeper","title":"thread-keeper","description":"Multi-agent shared brain across Claude, Codex, Antigravity, Gemini, Copilot, and VS Code.","url":"https://mcp.market/server/po4erk91-thread-keeper","rating":null,"grade":"A","score":92,"certified":false,"status":"active","category":"ai","tags":["ai"],"presence":{"score":37,"stars":12,"forks":4,"downloads_week":157,"last_push_at":"2026-09-27T04:22:13.000Z","license":"MIT"},"uptime":null,"claimed":false,"transport":"pypi","callable_via_gateway":false,"default_price_micros":0,"repository":"https://github.com/po4erk91/thread-keeper","website":null,"version":"0.13.1","remotes":[],"packages":[{"registryType":"pypi","identifier":"threadkeeper","version":"0.13.1","transport":{"type":"stdio"}}],"tools":[{"name":"accept_candidate","description":"Materialize candidate into its target table. target_kind overrides candidate's kind. thread_id optional.","write_action":false,"price_micros":0,"input_schema":null},{"name":"agent_memory_cleanup","description":"Trim ThreadKeeper memory and clean orphan/over-limit server processes.","write_action":false,"price_micros":0,"input_schema":null},{"name":"agent_status","description":"Show autonomous learning loops with state, backlog, last pass, and RSS.","write_action":false,"price_micros":0,"input_schema":null},{"name":"ask","description":"Send a question to a peer and wait synchronously for their answer.","write_action":true,"price_micros":0,"input_schema":null},{"name":"brief","description":"Compact Claude-native memory brief. CALL AT THE START OF EVERY CONVERSATION.","write_action":false,"price_micros":0,"input_schema":null},{"name":"broadcast","description":"Post a message visible to ALL concurrent claude conversations.","write_action":true,"price_micros":0,"input_schema":null},{"name":"candidate_review_run","description":"Fire one candidate-review pass.","write_action":true,"price_micros":0,"input_schema":null},{"name":"candidate_review_status","description":"Show candidate-reviewer configuration + last 5 passes + current pending queue size.","write_action":false,"price_micros":0,"input_schema":null},{"name":"claim_pickup","description":"Claim a thread for self-initiated work. Marks it claimed by my cid.","write_action":false,"price_micros":0,"input_schema":null},{"name":"consolidate","description":"Periodic memory hygiene. dry_run=True (default) reports only.","write_action":false,"price_micros":0,"input_schema":null},{"name":"context","description":"Runtime context: session id, age, semantic on/off, db path, thread counts.","write_action":false,"price_micros":0,"input_schema":null},{"name":"convene_panel","description":"Spawn a panel of independent agents to vote on a distillate or claim, filling the promotion quorum the way a second human otherwise would.","write_action":false,"price_micros":0,"input_schema":null},{"name":"core_get","description":"Return the full content of a single core-memory entry.","write_action":false,"price_micros":0,"input_schema":null},{"name":"core_list","description":"List all core-memory entries, ordered by priority DESC then key.","write_action":false,"price_micros":0,"input_schema":null},{"name":"core_remove","description":"Delete a core-memory entry by key.","write_action":true,"price_micros":0,"input_schema":null},{"name":"core_set","description":"Upsert a core-memory entry. ALWAYS shown in brief, sorted by priority DESC.","write_action":false,"price_micros":0,"input_schema":null},{"name":"curator_review","description":"Fire one curator pass.","write_action":false,"price_micros":0,"input_schema":null},{"name":"curator_review_status","description":"Show curator configuration + last 5 passes + latest REPORT path.","write_action":false,"price_micros":0,"input_schema":null},{"name":"curator_run","description":"Move stale agent-created skills to archive.","write_action":true,"price_micros":0,"input_schema":null},{"name":"dialectic_claim","description":"Register a new claim about the user. Optionally seed with first piece of evidence — pass the supporting (or contradicting) quote in `evidence` and set `evidence_kind` to 'support' (default) or 'contradict'.","write_action":false,"price_micros":0,"input_schema":null},{"name":"dialectic_evidence","description":"Attach evidence to a claim. `kind`: 'support' | 'contradict'.","write_action":false,"price_micros":0,"input_schema":null},{"name":"dialectic_mine_run","description":"Fire one mechanical capture pass now (force=True runs even when the miner daemon interval is 0).","write_action":true,"price_micros":0,"input_schema":null},{"name":"dialectic_mine_status","description":"Miner config + buffer sizes + last 5 capture passes.","write_action":false,"price_micros":0,"input_schema":null},{"name":"dialectic_observation_resolve","description":"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.","write_action":false,"price_micros":0,"input_schema":null},{"name":"dialectic_review","description":"List active claims filtered by confidence floor and optional domain. Retired/superseded claims are omitted.","write_action":false,"price_micros":0,"input_schema":null},{"name":"dialectic_supersede","description":"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).","write_action":false,"price_micros":0,"input_schema":null},{"name":"dialectic_synthesis","description":"Terse rendering of accumulated beliefs about the user, grouped by domain. Used as brief() input. Excludes low/disputed claims and non-active states. Returns at most 12 lines.","write_action":false,"price_micros":0,"input_schema":null},{"name":"dialectic_validate_run","description":"Fire one validator pass. dry_run shows pending count + would_spawn without spawning or advancing the cursor.","write_action":true,"price_micros":0,"input_schema":null},{"name":"dialectic_validate_status","description":"Validator config + pending observation count + last 5 passes.","write_action":false,"price_micros":0,"input_schema":null},{"name":"dialog_search","description":"Search ingested Claude Code transcripts.","write_action":false,"price_micros":0,"input_schema":null},{"name":"distill","description":"Mark content as worth carrying forward (distillation channel).","write_action":false,"price_micros":0,"input_schema":null},{"name":"evolve_apply","description":"Implement a PROMOTED + not-yet-applied format-evolution suggestion.","write_action":false,"price_micros":0,"input_schema":null},{"name":"evolve_apply_curator_report","description":"Apply a Curator advisory report using the existing evolve_applier role.","write_action":false,"price_micros":0,"input_schema":null},{"name":"evolve_apply_roadmap_issue","description":"Implement one open GitHub issue through the evolve_applier role.","write_action":false,"price_micros":0,"input_schema":null},{"name":"evolve_apply_status","description":"Show evolve-applier config + curator/evolve queues + running applier + the last 5 apply passes.","write_action":false,"price_micros":0,"input_schema":null},{"name":"evolve_mark_applied","description":"Mark a format-evolution suggestion as APPLIED — called by the evolve_applier child after it has opened the PR.","write_action":false,"price_micros":0,"input_schema":null},{"name":"evolve_mark_curator_report_applied","description":"Mark a Curator report as processed by the evolve_applier child.","write_action":false,"price_micros":0,"input_schema":null},{"name":"evolve_mark_roadmap_issue_applied","description":"Mark a roadmap issue as handed off — called by evolve_applier only after it has opened a real pull request for that issue.","write_action":false,"price_micros":0,"input_schema":null},{"name":"expand_concept","description":"Full description + triangulation_notes for one concept.","write_action":false,"price_micros":0,"input_schema":null},{"name":"export_distillates","description":"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: /tmp/thread-keeper-tasks/distillates.jsonl.","write_action":true,"price_micros":0,"input_schema":null},{"name":"extract_recent","description":"Scan recent dialog_messages and enqueue heuristic candidates.","write_action":false,"price_micros":0,"input_schema":null},{"name":"find_invariants","description":"Find recurring assistant-side patterns that survive prompt variance.","write_action":false,"price_micros":0,"input_schema":null},{"name":"find_missed_spawns","description":"Find assistant responses that decomposed into independent blocks but were answered linearly (no spawn() call nearby).","write_action":false,"price_micros":0,"input_schema":null},{"name":"inbox","description":"Read signals addressed to me (whispers + broadcasts).","write_action":false,"price_micros":0,"input_schema":null},{"name":"ingest","description":"Ingest new Claude Code transcripts. Auto-runs on session start; call manually for backfill or after long absence.","write_action":false,"price_micros":0,"input_schema":null},{"name":"lesson_append","description":"Materialize a class-level lesson into ~/.threadkeeper/lessons.md.","write_action":false,"price_micros":0,"input_schema":null},{"name":"lesson_get","description":"Return the full body of one lesson by slug. Useful when `lesson_list` surfaced something you want to read in full.","write_action":false,"price_micros":0,"input_schema":null},{"name":"lesson_list","description":"Compact listing of materialized lessons, newest first.","write_action":false,"price_micros":0,"input_schema":null},{"name":"lesson_remove","description":"Remove one materialized lesson section by slug.","write_action":true,"price_micros":0,"input_schema":null},{"name":"link","description":"Create a typed edge between two entities.","write_action":true,"price_micros":0,"input_schema":null},{"name":"list_concepts","description":"List registered concepts, filtered by minimum confidence.","write_action":false,"price_micros":0,"input_schema":null},{"name":"live_status","description":"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.","write_action":false,"price_micros":0,"input_schema":null},{"name":"memory_guard_check","description":"Run one memory-guard pass now.","write_action":true,"price_micros":0,"input_schema":null},{"name":"memory_guard_reclaim","description":"Unload thread-keeper model/caches now.","write_action":false,"price_micros":0,"input_schema":null},{"name":"memory_guard_status","description":"Show memory-guard thresholds and current thread-keeper RSS rows.","write_action":false,"price_micros":0,"input_schema":null},{"name":"mp_cleanup","description":"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.","write_action":true,"price_micros":0,"input_schema":null},{"name":"mp_dashboard","description":"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.","write_action":false,"price_micros":0,"input_schema":null},{"name":"mp_health","description":"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).","write_action":false,"price_micros":0,"input_schema":null},{"name":"neighbors","description":"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.","write_action":false,"price_micros":0,"input_schema":null},{"name":"note","description":"Add a note to a thread. Write terse, optimized for future-Claude.","write_action":false,"price_micros":0,"input_schema":null},{"name":"open_dialog_window","description":"Open a Terminal window that tails the live cross-session signal log.","write_action":false,"price_micros":0,"input_schema":null},{"name":"open_thread","description":"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.","write_action":false,"price_micros":0,"input_schema":null},{"name":"peers","description":"List concurrent claude conversations active in the last `window_min`.","write_action":false,"price_micros":0,"input_schema":null},{"name":"pending_distillates","description":"List distillates with vote_sum >= min_vote, not yet exported.","write_action":false,"price_micros":0,"input_schema":null},{"name":"pickup_candidates","description":"Surface unresolved threads that are stale and unclaimed — candidates for self-initiated pickup when context is free.","write_action":false,"price_micros":0,"input_schema":null},{"name":"presence","description":"List concurrent Claude sessions with heartbeats within threshold (default 5 min). Excludes self. Useful for understanding who else is currently active before making changes.","write_action":false,"price_micros":0,"input_schema":null},{"name":"record_attempt","description":"Record a self-test outcome. Updates reliability aggregates.","write_action":false,"price_micros":0,"input_schema":null},{"name":"register_concept","description":"Register a concept that lacks a precise human name.","write_action":false,"price_micros":0,"input_schema":null},{"name":"register_probe","description":"Register a self-test probe: a known weak-spot task with a verifier.","write_action":false,"price_micros":0,"input_schema":null},{"name":"reject_candidate","description":"Mark rejected. Reason appended to rationale for heuristic tuning.","write_action":false,"price_micros":0,"input_schema":null},{"name":"release_pickup","description":"Release a claim. Only the claimant can release.","write_action":false,"price_micros":0,"input_schema":null},{"name":"reliability_for","description":"Reliability stats for one category over a window.","write_action":false,"price_micros":0,"input_schema":null},{"name":"respond","description":"Answer a specific question (signals.id) with a directed whisper.","write_action":false,"price_micros":0,"input_schema":null},{"name":"review_candidates","description":"status ∈ {pending, accepted, rejected, all}. Newest first.","write_action":false,"price_micros":0,"input_schema":null},{"name":"review_thread","description":"Spawn a background review of a closed thread to extract memory/skills.","write_action":false,"price_micros":0,"input_schema":null},{"name":"run_probe","description":"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.","write_action":true,"price_micros":0,"input_schema":null},{"name":"search_via_parent","description":"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.","write_action":false,"price_micros":0,"input_schema":null},{"name":"session_end","description":"Mark current session ended with optional terse summary.","write_action":false,"price_micros":0,"input_schema":null},{"name":"shadow_review_run","description":"Fire one shadow-review pass.","write_action":true,"price_micros":0,"input_schema":null},{"name":"shadow_review_status","description":"Show shadow-review configuration + last 5 passes.","write_action":false,"price_micros":0,"input_schema":null},{"name":"skill_list","description":"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>","write_action":false,"price_micros":0,"input_schema":null},{"name":"skill_manage","description":"Create, edit, patch, or delete skills under the primary skills root.","write_action":true,"price_micros":0,"input_schema":null},{"name":"skill_record","description":"Record usage telemetry for a mirrored skill.","write_action":false,"price_micros":0,"input_schema":null},{"name":"spawn","description":"","write_action":false,"price_micros":0,"input_schema":null},{"name":"spawn_budget_set","description":"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.","write_action":false,"price_micros":0,"input_schema":null},{"name":"spawn_budget_status","description":"Report current spawn-budget usage: cap, used, free, plus per-running-task RSS. Used to decide whether another spawn() will be admitted.","write_action":false,"price_micros":0,"input_schema":null},{"name":"spawn_status","description":"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.","write_action":false,"price_micros":0,"input_schema":null},{"name":"style_set","description":"Set a stylistic running rule. Examples: lang=ru | prose=lean | allow=half-baked,weird | deny=sycophancy,headers","write_action":false,"price_micros":0,"input_schema":null},{"name":"tag_signal","description":"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).","write_action":false,"price_micros":0,"input_schema":null},{"name":"task_logs","description":"Read tail of a spawned task's captured stdout/stderr log.","write_action":false,"price_micros":0,"input_schema":null},{"name":"task_thread","description":"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.","write_action":false,"price_micros":0,"input_schema":null},{"name":"tasks","description":"List spawned tasks: id, pid, status, elapsed, spawned_cid (if linked), prompt prefix. Refreshes liveness and resolves spawned_cid lazily.","write_action":false,"price_micros":0,"input_schema":null},{"name":"tournament","description":"Spawn N children with different roles on the same prompt, then collect their answers via a tagged broadcast and return a comparison.","write_action":false,"price_micros":0,"input_schema":null},{"name":"unlink","description":"Remove an edge by id.","write_action":true,"price_micros":0,"input_schema":null},{"name":"verbatim_user","description":"Capture a user quote worth surfacing in future briefs. Use when the user's exact phrasing matters (sharp reframes, decisions, pushback).","write_action":false,"price_micros":0,"input_schema":null},{"name":"vote_distill","description":"Vote on a distillate, weight ∈ [-1, +1]. One vote per cid; re-voting overwrites your previous vote. Updates aggregate vote_sum/vote_count.","write_action":false,"price_micros":0,"input_schema":null},{"name":"wait","description":"Block until a new signal arrives for me or `timeout_s` elapses.","write_action":false,"price_micros":0,"input_schema":null},{"name":"weak_spots","description":"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).","write_action":false,"price_micros":0,"input_schema":null},{"name":"whisper","description":"Post a message visible only to the specified conversation_id.","write_action":true,"price_micros":0,"input_schema":null},{"name":"whoami","description":"Return this conversation's detected conversation_id + how we know.","write_action":false,"price_micros":0,"input_schema":null}],"scan":{"score":92,"grade":"A","scanned_at":"2026-09-27T05:27:33.548Z","report":{"scannerVersion":"0.1.9","scannedAt":"2026-09-27T05:27:33.541Z","components":{"code":{"score":25,"max":25,"notes":["82 source files scanned"]},"reliability":{"score":-1,"max":20,"notes":["no gateway calls yet and no remote to probe"]},"poisoning":{"score":-1,"max":15,"notes":["tools not inspected (local package is not executed); not counted"]},"auth":{"score":12,"max":15,"notes":["local package, no credentials required"]},"maintenance":{"score":15,"max":15,"notes":["last push 0 days ago"]},"identity":{"score":8,"max":10,"notes":["registry namespace matches repository owner","GitHub account older than a year"]}},"findings":[],"inputs":{"packages":[{"registryType":"pypi","identifier":"threadkeeper","version":"0.13.1","found":true,"weeklyDownloads":157,"license":"MIT","dependencyCount":15,"publishedAt":"2026-06-15T09:12:30.567703Z","repositoryUrl":"https://github.com/po4erk91/thread-keeper"}],"repo":{"found":true,"owner":"po4erk91","repo":"thread-keeper","archived":false,"pushedAt":"2026-09-27T04:22:13Z","stars":12,"forks":4,"openIssues":29,"ownerType":"User","ownerAvatarUrl":"https://avatars.githubusercontent.com/u/37811437?v=4","ownerCreatedAt":"2018-03-26T17:33:15Z","license":"MIT"},"icon":{"url":null,"source":"none"},"presence":{"stars":12,"forks":4,"downloadsWeek":157,"license":"MIT","lastPushAt":"2026-09-27T04:22:13.000Z","score":37}}}},"grade_history":[],"reviews":[]}