Skip to main content
Glama

research-hub

A workspace on your computer for researchers to organize papers, evidence, and drafts, with AI-assisted proposals you review.

繁體中文 · Workspace guide · Setup guide · Developer architecture

PyPI Python 3.10+ MIT license

Why research-hub?

Research is spread across papers, notes, analysis, and manuscripts. A new paper can change a question; an updated file can make a conclusion or section worth revisiting. research-hub gives researchers and AI assistants a local workspace to record those connections, hand off tasks, and review proposals before accepting them.

  • Keep context: bring questions, sources, evidence, results, and manuscripts into one project rather than leaving them only in a conversation.

  • Track changes: register file paths and a file fingerprint (hash) to help detect changes, then inspect work that may need review when inputs change.

  • Keep decisions human: AI proposals require review; a local delivery requires separate approval.

Concept diagram: research questions connect literature, evidence, analysis, manuscript proposals, and human review; changed inputs return work for review.

Related MCP server: zotero-mcp-lite

Choose your starting path

Two starting paths: research with an available compatible AI host without Hub, or install Hub to view saved sources and proposals. Task handoff is optional. People review sources and evidence; saving is not reading or approval, and nothing is automatically published.

Use your existing AI host: You need working search/reading tools and the portable skill with its references. No Hub installation, Zotero, Obsidian, or NotebookLM is required. See skill loading and host support; Codex MCP is not release-verified.

First request: “Find papers on LLMs simulating human decisions. Include source links, relevance, versions, and actual reading limits.” Expect a source list in your host, with unknowns and unavailable tools/sources stated, not automatic full-text reading or a Hub save.

Use the Hub workspace: You need Python 3.10+, Git, and a local browser. Install and launch the tested demo below to inspect two seed references and their reading limits. Optional result saving and task handoff require a selected destination and authorization.

Install and get started

Try the local workspace

Choose this path for the Hub workspace. If you only want to try the older published literature dashboard, see the separate option below.

You need Python 3.10+ and Git. These commands install a specific source revision and create teaching fixtures in a new or empty workspace-demo directory. The source workspace is separate from the PyPI release: a package version does not establish that the installed wheel contains current source features.

git clone -c core.autocrlf=false https://github.com/WenyuChiou/research-hub.git
cd research-hub
git fetch origin 1f0726a7e92a1231e633963f17236a2f5c1eab8f
git checkout --detach 1f0726a7e92a1231e633963f17236a2f5c1eab8f

Choose the block for your system. They call the virtual environment's Python directly, without activation or changing PowerShell execution policy. Dependency installation needs network access.

macOS / Linux

python3 -m venv .venv
./.venv/bin/python -m pip install -e .
./.venv/bin/python -m research_hub project demo --root ./workspace-demo --json
./.venv/bin/python -m research_hub serve --workspace --root ./workspace-demo

Windows PowerShell

One Windows test environment using the earlier 14ddc070 source encountered WinError 5 during demo creation; its cause is not yet known. See verification and environment notes.

py -3 -m venv .venv
.\.venv\Scripts\python.exe -m pip install -e .
.\.venv\Scripts\python.exe -m research_hub project demo --root ./workspace-demo --json
.\.venv\Scripts\python.exe -m research_hub serve --workspace --root ./workspace-demo

First task: inspect a saved source and its reading limits.

  1. Open http://127.0.0.1:8765/app/ and, in Projects, choose DEMO: floating-point reading and review outline (review-demo).

  2. Open Literature, then select What Every Computer Scientist Should Know About Floating-Point Arithmetic.

  3. Expect two seed references in the list. The selected source shows DOI 10.1145/103162.103163, Unverified, Coverage unknown, and No summary saved. These are expected demo states: no source text was downloaded or summarized, and the supplied screening decisions are examples, not your review.

The other project, DEMO: three floating-point summation cases (summation-demo), contains numerical examples and a manuscript scaffold; its Literature list is empty. Both projects are account-free teaching inputs, not accepted research.

Keep the terminal running while using the workspace; stop it with Ctrl+C. To return later, run only the serve --workspace --root ./workspace-demo command above. Do not recreate the demo over saved work. If creation was interrupted, inspect the preserved partial directory and use another new or empty root for both creation and serving.

Demo creation, launch, and this bilingual first task were checked on Linux with Python 3.12.14 at source revision 1f0726a7; this does not verify Windows, macOS, or a fresh dependency installation. See the exact verification scope.

For your own files, go directly to bring your own project; the guide’s earlier installation pin is historical.

The PyPI package provides the older literature dashboard, not the newer source workspace. For an account-free sample, this separate virtual environment and empty root were tested on Linux with Python 3.12:

python3 -m venv .dashboard-venv
./.dashboard-venv/bin/python -m pip install research-hub-pipeline==1.2.0
mkdir -p "$HOME/research-hub-preview"
RESEARCH_HUB_ROOT="$HOME/research-hub-preview" ./.dashboard-venv/bin/research-hub dashboard --sample

Use a new or empty research-hub-preview directory under HOME: the command creates .research_hub and logs there. It prints the generated temporary HTML path; open that path in your browser. The bare dashboard --sample failed in a fresh HOME without the root setting; see verification notes for platform and browser limits. For real services, see setup, the dashboard tour, and first 10 minutes.

Work in the workspace

Historical workspace UI capture showing local demo project navigation and research records.

Historical demo capture, reviewed 2026-09-08; the current interface may differ.

Page

Example work

Overview

Review the research question, goal, and project context.

Literature

Collect sources and record reasons to include or exclude them.

Evidence

Link claims to sources and inspect unresolved support.

Design & results

Record methods, results, limitations, and supporting files.

Manuscript

Register Word, LaTeX, or Markdown and prepare outlines and revisions.

Review & delivery

Inspect proposals, record decisions, and prepare a local handoff.

Your editor remains responsible for changes to original files; the workspace registers their paths and hashes. A resolvable identifier does not prove a source supports a claim: check the evidence and scientific judgments yourself.

Discover literature

In a compatible AI tool (an AI host) that can load the research-hub skill and has search and reading tools, start with a concrete request, for example:

Find literature on LLMs simulating human decisions; include original links, relevance, versions, and limits on available full text.

Then ask to focus on economic decisions and compare human baselines and evaluation methods. Review the sources, reading coverage, and open questions before deciding what to do next. Search snippets are not full-text reading. This research approach can be used independently of Hub; Zotero, Obsidian, NotebookLM, and Hub storage are optional. The Hub visual workspace and saved-result view do require Hub.

The native reader can organize supplied research summaries, source indexes, and bibliographies, and attach a PDF explicitly supplied by the user. The PDF is copied unchanged for download; that does not mean it was parsed, translated, verified, or read in full. The reader can display caller-supplied translations alongside original observations, labeled unverified; it does not generate translations or verify their accuracy. See the native reader export guide for the supplied-translation format.

See AI Research Skills, the AI host support matrix, and MCP/REST integration. The optional saved-result contract describes what a Hub handoff stores and its platform boundaries.

Write, review, and deliver

Concept diagram: a researcher prepares a task, uses a portable AI handoff or a connected Codex prose worker, checks the proposal, and explicitly accepts or requests changes.

Mode

How it works

Portable handoff

Export a task to your AI host, then import prose and candidate file hashes. Export leaves the task waiting for the agent.

Connected Codex

An authenticated, compatible Codex CLI uses an explicitly trusted public writing bundle to produce prose; the result waits for human review.

The optional writing setup explains how to verify and configure the adapter. Connected Codex receives bounded text excerpts, not binary document contents. Use your editor for Word formatting, LaTeX compilation, and final document changes. Accepted proposals can be packaged into a local ZIP after separate approval; this does not authorize publication or cloud upload. Workspace approval does not automatically protect existing direct-write CLI, MCP, dashboard, or cloud tools. See boundaries and recovery.

Optional integrations

  • Zotero: manage references; the connection requires an API key and library ID.

  • Obsidian: organize notes in a local vault, or begin with local files.

  • NotebookLM: create source-based briefings; it requires browser sign-in and a working session. See setup and troubleshooting.

  • AI hosts: connect through MCP/REST or portable skills; MCP requires the optional [mcp] extra.

Choose integrations as needed and run ./.venv/bin/python -m research_hub doctor (macOS/Linux) or .\.venv\Scripts\python.exe -m research_hub doctor (Windows PowerShell) to inspect them individually. Setup or installation does not itself verify a service. The setup guide covers extras and credentials; see also local file import, EZproxy, and the live smoke checklist.

The local workspace demo needs none of these credentials. Existing personas use optional extras: Researcher and Humanities [playwright,secrets]; Analyst and Internal KM [import,secrets].

Name

Required

Purpose

ZOTERO_API_KEY

Zotero only

Zotero API authentication

ZOTERO_LIBRARY_ID

Zotero only

Zotero library identifier

SEMANTIC_SCHOLAR_API_KEY

no

Optional search API key

SEMANTIC_SCHOLAR_RPS

no

Optional search request-rate override

TAVILY_API_KEY

no

Optional web search backend

BRAVE_API_KEY

no

Optional web search backend

Documentation and contributing

Available Tools

76 tools
add_paperC

Fetch a paper by DOI/arXiv ID and ingest it (one-shot).

Inputs: identifier (required), cluster, no_zotero, skip_verify. Returns: object

apply_cluster_summariesA

Persist a JSON payload of per-paper summaries (when LLM was invoked out-of-band) to Obsidian + Zotero. The payload shape matches the summarize_cluster prompt's expected output: {summaries: [...]}.

Inputs: cluster_slug (required), summaries_json (required). Returns: object

apply_crystalsC

Persist crystal answers to hub//crystals/.md.

Inputs: cluster_slug (required), crystals_json (required). Returns: object

apply_fit_check_to_labelsA

Convert fit-check sidecar decisions into paper labels. Persists fit_check_apply decisions before pruning. When to use: after accepted and rejected sidecars are written. When NOT to use: to score candidates; use fit_check_apply instead. Args: cluster_slug: cluster whose sidecars and notes are used. Returns: keys tagged, already, missing, error. Example: >>> apply_fit_check_to_labels("my-topic") {"tagged": ["paper-1"]}

Inputs: cluster_slug (required). Returns: object

apply_subtopic_assignmentsC

Write subtopics frontmatter to each paper note.

Inputs: cluster_slug (required), assignments (required). Returns: object

ask_clusterA

Answer a question about one cluster, dispatching to the source named by source / mode.

Single entrypoint for all cluster-question workflows. Replaces the deprecated aliases ask_cluster_notebooklm / read_briefing / brief_cluster (gated behind RESEARCH_HUB_MCP_INCLUDE_DEPRECATED=1, removed in v2.0.0). Routes the question through three internal paths: source='local' answers from cached crystals + memory only; source='notebooklm', mode='ask' opens NotebookLM via Playwright and asks live; source='notebooklm', mode='briefing' returns the last downloaded NotebookLM briefing markdown; source='notebooklm', mode='brief' runs the full bundle-upload-generate-download round-trip to refresh the briefing artifact.

When to use:

  • User asks a natural-language question about one cluster and you want the cheapest, fastest answer first (source='local').

  • User asks an ad-hoc question that requires fresh paper content retrieval (source='notebooklm', mode='ask').

  • User wants to read the existing brief text (mode='briefing').

  • User asks to regenerate the brief (mode='brief' with force_regenerate=True).

When NOT to use:

  • You want one specific crystal answer by slug; use read_crystal instead — it skips dispatch overhead.

  • You want to search across multiple clusters; use web_search or search_papers instead.

  • You want to inspect cluster memory directly (entities / claims / methods); use read_cluster_memory.

Inputs: cluster, question, source, detail, +6 more. Returns: object

autofill_applyA

Apply AI-authored autofill sections to paper notes. Consumes autofill_emit JSON and updates notes. When to use: after an AI returns summaries for an autofill prompt. When NOT to use: to generate prompts; use autofill_emit instead. Args: cluster_slug: cluster to update; scored: list or {"papers": [...]}. Returns: keys cluster_slug, candidate_count, filled, skipped, missing, error. Example: >>> autofill_apply("my-topic", {"papers": [{"slug": "paper-1"}]}) {"cluster_slug": "my-topic", "filled": []}

Inputs: cluster_slug (required), scored (required). Returns: object

autofill_emitA

Build an autofill prompt for paper notes with TODO bodies. Emits the JSON prompt for autofill_apply. When to use: after ingest creates notes with abstracts but TODO content. When NOT to use: to write AI output; use autofill_apply instead. Args: cluster_slug: cluster whose notes are scanned for TODO placeholders. Returns: keys prompt, paper_count, error. Example: >>> autofill_emit("my-topic") {"paper_count": 3}

Inputs: cluster_slug (required). Returns: object

auto_research_topicA

One-shot research pipeline: search + ingest + NotebookLM brief (+ optional crystals).

Slugifies topic into a cluster (or reuses cluster_slug), searches arXiv + Semantic Scholar, ingests papers into Zotero + Obsidian, then bundles + uploads + generates + downloads a NotebookLM brief. With do_crystals=True and a detected supported LLM CLI on PATH, also generates and applies the canonical Q&A crystals so the cluster is fully ready for read_crystal() queries.

Use when: user says "research X for me" or "find papers on X".

Returns {ok, cluster_slug, papers_ingested, notebook_url, brief_path, total_duration_sec, error}.

Inputs: topic (required), cluster_slug, cluster_name, max_papers, +10 more. Returns: object

build_citationC

Return an inline citation string for a paper.

Inputs: doi_or_slug (required), style. Returns: object

build_topic_notesC

Generate topics/NN_.md files from paper frontmatter.

Inputs: cluster_slug (required). Returns: object

capture_quoteC

Persist a quote to /.research_hub/quotes/.md.

Inputs: slug (required), page (required), text (required), context. Returns: object

check_crystal_stalenessC

Check how many crystals are stale (>10% cluster paper delta since generation).

Inputs: cluster_slug (required). Returns: object

cleanup_garbageA

Garbage-collect accumulated research-hub files (v0.46+).

Pass everything=True for the common case (bundles + debug logs + artifacts). Default mode lists candidates without deleting; pass apply=True to actually remove.

Use when: user says "clean up", "free disk space", or "GC the vault".

Returns {ok, total_bytes, files_deleted, dirs_deleted, candidates}.

Inputs: bundles, debug_logs, artifacts, everything, +4 more. Returns: object

cluster_rebindA

Run the cluster-rebind workflow specified by action.

Single entrypoint that consolidates four legacy rebind operations (propose / apply / list_orphans / status) into one tool with an action discriminator. Replaces the deprecated aliases propose_cluster_rebind / apply_cluster_rebind / list_orphan_papers / summarize_rebind_status, which are gated behind RESEARCH_HUB_MCP_INCLUDE_DEPRECATED=1 and slated for removal in v2.0.0.

When to use:

  • After ingest leaves orphan paper notes that don't match any active cluster, and you want to plan moves before touching files.

  • After a manual cluster rename, when existing paper notes still reference the old slug.

  • Periodic vault hygiene: surface stuck or low-confidence orphans via action='status'.

When NOT to use:

  • You want to delete clusters wholesale, not rebind their papers; use research-hub clusters delete (CLI) instead.

  • You want to archive papers carrying a label; use prune_cluster instead.

Inputs: action, cluster_slug, report_path, dry_run, +2 more. Returns: object

collect_to_clusterA

Unified ingest. Auto-routes by source shape: DOI/arXiv -> add_paper, folder -> import_folder, URL -> .url file + import.

Inputs: source (required), cluster_slug (required), skip_verify, no_zotero, +1 more. Returns: object

compose_brief_draftC

Assemble a markdown draft from cluster quotes + overview + crystal TLDRs.

Inputs: cluster_slug (required), outline, max_quotes. Returns: object

compose_draftC

Assemble captured quotes into a markdown draft.

Inputs: cluster_slug (required), outline, quote_slugs, style, +1 more. Returns: object

discover_cleanC

Remove the discover stash directory for a cluster.

Inputs: cluster_slug (required). Returns: object

discover_continueA

Apply fit-check scores from an AI judge and produce a papers_input.json ready for ingest.

Second half of the interactive discovery flow. The user runs discover_new first (which emits a search-results stash + a scoring prompt), pastes the prompt into an AI of choice, then feeds the AI's scored output back through this tool. The scored candidates are filtered by threshold and written to papers_input.json in the cluster's discover-stash directory, ready for the standard ingest pipeline (research-hub auto or research-hub clusters ingest).

When to use:

  • You have a JSON list of fit-check scores from an AI judge and want to admit only the high-confidence candidates into the vault.

  • You're running the two-phase discovery flow because the topic boundaries are fuzzy and you want a human / AI in the loop on which papers belong.

When NOT to use:

  • You haven't run discover_new yet — there's no stash to apply scores against. Run discover_new first.

  • You already have a fully-resolved list of DOIs to ingest; skip discovery and call add_paper per item, or auto_research_topic for the one-shot path.

  • You want to re-score an EXISTING ingested cluster's papers; use fit_check_emit + fit_check_apply (the post-ingest re-scoring path).

Inputs: cluster_slug (required), scored (required), threshold, auto_threshold. Returns: object

discover_newC

Run search + emit fit-check prompt, stashing state for discover_continue.

Inputs: cluster_slug (required), query (required), year_from, year_to, +16 more. Returns: object

discover_statusC

Return current discover state for a cluster.

Inputs: cluster_slug (required). Returns: object

discover_variantsA

Emit a query-variation prompt for discovery search. Generates alternate discover_new queries. When to use: before discovery when the seed query is narrow. When NOT to use: to run search; use discover_new instead. Args: cluster_slug: context; query: seed query; count: variant target. Returns: keys prompt, target_count, error. Example: >>> discover_variants("my-topic", "LLM agents", count=4) {"target_count": 4, "prompt": "..."}

Inputs: cluster_slug (required), query (required), count. Returns: object

download_artifactsA

Download a generated NotebookLM briefing back to the vault.

Opens the cluster's NotebookLM notebook using the saved local session, extracts the latest briefing summary text, and saves it under <vault>/.research_hub/artifacts/<cluster_slug>/brief-<UTC>.txt. The cluster's nlm_cache.json entry is updated with the new path.

Inputs: cluster_slug (required), artifact_type, headless. Returns: object

emit_assignment_promptA

Build the topic-build Phase 2 (sub-topic assignment) LLM prompt.

Part of the multi-phase topic build flow: Phase 1 proposes sub-topics for a cluster; Phase 2 (this tool) emits the prompt that asks an LLM to assign each paper to one of those sub-topics.

Inputs: cluster_slug (required), subtopics (required). Returns: object

emit_cluster_baseC

Emit (or refresh) the .base dashboard file for a cluster.

Inputs: cluster_slug (required), force. Returns: object

emit_crystal_promptC

Emit the markdown prompt the calling AI should answer to generate crystals.

Inputs: cluster_slug (required), question_slugs. Returns: object

enrich_candidatesC

Resolve candidate identifiers to full paper records.

Inputs: candidates (required), backends. Returns: result

examples_copyC

Copy an example into the user's cluster registry.

Inputs: name (required), cluster_slug. Returns: object

examples_listA

List bundled example clusters.

Inputs: no named parameters. Returns: result

examples_showA

Return one bundled example cluster definition. Inspects sample JSON before examples_copy. When to use: before copying an example such as cs_swe. When NOT to use: to list names; use examples_list instead. Args: name: bundled example id, such as cs_swe or bio_protein. Returns: keys name, slug, field, query, definition, year_from, year_to, min_citations, sample_dois, description, error. Example: >>> examples_show("cs_swe") {"slug": "llm-agents-software-engineering"}

Inputs: name (required). Returns: object

export_citationC

Export citation in BibTeX, BibLaTeX, RIS, or CSL-JSON format.

Inputs: identifier, cluster, format. Returns: result

fit_check_applyC

Consume AI scores, filter candidates, write rejected sidecar.

Inputs: cluster_slug (required), candidates (required), scores (required), threshold. Returns: object

fit_check_auditA

Parse the latest NotebookLM briefing for off-topic flags. Audits briefing text before fit_check_drift. When to use: after NotebookLM flags papers. When NOT to use: to emit scoring prompts; use fit_check_emit instead. Args: cluster_slug: cluster whose briefing is audited. Returns: keys ok, cluster_slug, flagged, reason, error. Example: >>> fit_check_audit("my-topic") {"ok": True, "flagged": [...]}

Inputs: cluster_slug (required). Returns: object

fit_check_driftA

Emit a drift-check prompt for the current cluster overview. Re-scores papers after fit_check_audit. When to use: when an overview changed and papers may not fit. When NOT to use: to apply scores; use fit_check_apply instead. Args: cluster_slug: cluster; threshold: accepted score cutoff, default 3. Returns: keys cluster_slug, paper_count, threshold, prompt, error. Example: >>> fit_check_drift("my-topic", threshold=3) {"cluster_slug": "my-topic", "prompt": "..."}

Inputs: cluster_slug (required), threshold. Returns: object

fit_check_promptC

Build the Gate 1 fit-check prompt for an AI to score.

Inputs: cluster_slug (required), candidates (required), definition. Returns: object

generate_dashboardA

Generate a personal HTML dashboard for the vault.

Returns the path to the generated file. Open it in a browser to see cluster overview, paper counts, reading status breakdown, and NotebookLM links.

Inputs: no named parameters. Returns: object

get_citationsA

List papers that cite the given paper (forward citations).

Delegates to research_hub.citation_graph.CitationGraphClient (Semantic Scholar Graph API).

Inputs: identifier (required), limit. Returns: result

get_config_infoA

Show current configuration paths and settings.

Inputs: no named parameters. Returns: object

get_referencesC

List papers cited by the given paper (its bibliography).

Inputs: identifier (required), limit. Returns: result

get_topic_digestC

Return every paper in a cluster plus a markdown digest for overview writing.

Inputs: cluster_slug (required). Returns: object

import_folder_toolC

Walk a local folder and ingest non-DOI files as document notes.

Inputs: folder (required), cluster_slug (required), dry_run. Returns: object

label_paperC

Set, add, or remove labels on a paper note.

Inputs: slug (required), labels, add, remove, +2 more. Returns: object

list_clustersA

List all topic clusters with their bindings.

Inputs: no named parameters. Returns: result

list_crystalsC

List all pre-computed crystal answers for a cluster.

Inputs: cluster_slug (required). Returns: object

list_papers_by_labelC

Return paper states for the cluster, optionally filtered by label.

Inputs: cluster_slug (required), label, label_not. Returns: result

list_quotesB

List captured quotes, optionally filtered by cluster.

Inputs: cluster_slug. Returns: object

list_topic_notesC

List existing sub-topic notes for a cluster.

Inputs: cluster_slug (required). Returns: object

mark_paperC

Update the reading status of a paper note.

Delegates to research_hub.operations.mark_paper.

Inputs: slug (required), status (required). Returns: object

merge_clustersA

Merge all papers from one cluster into another, then delete the source.

Delegates to research_hub.clusters.ClusterRegistry.merge.

Inputs: source (required), into (required). Returns: object

move_paperC

Move a paper note from its current cluster to another.

Delegates to research_hub.operations.move_paper.

Inputs: slug (required), to_cluster (required). Returns: object

notebooklm_bundleC

Build a NotebookLM upload bundle for a cluster.

Inputs: cluster_slug (required), download_pdfs. Returns: object

notebooklm_downloadC

Download the latest NotebookLM briefing artifact into the vault.

Inputs: cluster_slug (required), artifact_type, headless. Returns: object

notebooklm_generateC

Trigger NotebookLM artifact generation for a cluster notebook.

Inputs: cluster_slug (required), artifact_type, headless. Returns: object

notebooklm_uploadC

Upload the latest cluster bundle to NotebookLM using the saved session.

Inputs: cluster_slug (required), dry_run, headless, create_if_missing. Returns: object

plan_research_workflowA

Convert a freeform user intent into a structured research plan.

Call this BEFORE auto_research_topic when the user's request is vague, ambitious, or could collide with an existing cluster. Returns a suggested topic + search depth + NLM/crystals choices + clarifying questions for you to confirm with the user.

Use when the user says things like: "I want to learn about X" "research X for my dissertation" "find recent papers on X" "ingest X but skip NotebookLM"

The plan includes:

  • intent_summary: rephrased one-line restatement (confirm with user)

  • suggested_topic / cluster_slug

  • suggested_max_papers (auto-tuned: 25 for thesis, 8 default, etc.)

  • suggested_do_nlm / do_crystals (with detected CLI awareness)

  • existing_cluster_match: warns if a similar cluster already exists

  • clarifying_questions: ask these BEFORE calling auto_research_topic

  • next_call: ready-to-execute auto_research_topic args after confirmation

  • estimated_duration_sec: rough time estimate

After presenting the plan + getting user confirmation, call auto_research_topic with the plan's suggested args.

Inputs: user_intent (required). Returns: object

propose_research_setupA

Propose names for a new research collection without creating anything.

Use this BEFORE creating clusters/collections/notebooks. Show the suggestions to the user and ask them to confirm or override each name. Only after the user agrees should you call the create tools.

Inputs: topic (required). Returns: object

propose_subtopicsC

Build the Phase 1 sub-topic proposal prompt for an AI to consume.

Inputs: cluster_slug (required), target_count. Returns: object

prune_clusterA

Archive or delete paper notes in a cluster whose frontmatter carries label.

Cluster cleanup operation that acts on the label sidecars written by apply_fit_check_to_labels (e.g. deprecated, off_topic, low_relevance). Moves matching paper notes to the cluster's _archive/ subfolder by default, or deletes them outright if delete=True. Pairs with apply_fit_check_to_labels as a two-step "decide → act" workflow: that tool labels papers based on fit-check sidecars; this tool acts on the labels.

When to use:

  • After running apply_fit_check_to_labels (or manually labelling papers), you want to physically move the off-topic notes out of the active cluster folder.

  • You want to keep an audit trail (default archive=True) so the moves are reversible.

When NOT to use:

  • You want to ADD labels, not act on them; use apply_fit_check_to_labels instead.

  • You want to delete the entire cluster (not just labelled papers); use research-hub clusters delete (CLI) instead.

  • You want to rebind orphans to a different cluster, not archive them; use cluster_rebind instead.

Inputs: cluster_slug (required), label, archive, delete, +1 more. Returns: object

read_cluster_memoryC

Read cluster memory. kind may be entities, claims, methods, or all.

Inputs: cluster (required), kind, min_confidence. Returns: object

read_crystalC

Read a specific crystal at the requested detail level.

Inputs: cluster_slug (required), crystal_slug (required), level. Returns: object

read_topic_overviewA

Return the current topic overview markdown for a cluster, if present.

Inputs: cluster_slug (required). Returns: object

remove_paperB

Remove a paper from the vault, optionally deleting its Zotero item too.

Inputs: identifier (required), include_zotero, dry_run. Returns: object

run_doctorB

Run health checks on the research-hub installation.

Inputs: no named parameters. Returns: result

search_papersC

Search for academic papers across multiple backends.

Inputs: query (required), limit, verify, year_from, +9 more. Returns: result

search_vaultC

Search local vault notes by title or full text.

Inputs: query (required), cluster, status, full_text. Returns: result

show_clusterB

Show detailed info for a cluster including sync status.

Inputs: slug (required). Returns: object

split_clusterB

Split a source cluster into a new cluster based on title keyword overlap.

Inputs: source (required), query (required), new_name (required). Returns: object

suggest_cluster_splitB

Analyze a cluster's citation graph and suggest sub-topic splits.

Inputs: cluster_slug (required), min_community_size, max_communities. Returns: object

suggest_integrationC

Suggest which cluster a paper belongs to and find related papers.

Inputs: identifier (required), top_clusters, top_related. Returns: object

summarize_clusterA

Generate per-paper Key Findings + Methodology + Relevance via LLM CLI.

For each paper in cluster_slug, builds a prompt from the abstract and invokes the detected LLM CLI (claude, codex, or gemini — pass llm_cli to override). With apply=False (default), returns the parsed JSON without writing. With apply=True, writes back to BOTH the Obsidian markdown blocks and the Zotero child note for each paper.

Use when: user says "summarize this cluster's papers", "fill the TODO Findings", or after auto ingest before scanning the vault.

No LLM CLI on PATH: prompt is saved to artifacts//summarize-prompt.md; user can pipe it through their LLM and re-run with --apply (CLI) or pass the parsed payload to the apply_cluster_summaries MCP tool below.

Returns {cluster_slug, ok, error, cli_used, prompt_path, apply_result}.

Inputs: cluster_slug (required), llm_cli, apply, write_zotero, +1 more. Returns: object

sync_clusterC

Aggregate maintenance view: staleness + scope drift + vault health + recommendations.

Inputs: cluster_slug (required). Returns: object

tidy_vaultA

One-shot vault maintenance: doctor autofix + dedup rebuild + bases refresh + cleanup preview.

Each sub-step is non-fatal — failures logged but don't abort the others.

Use when: user says "tidy", "maintenance", "vault health check".

Returns {ok, steps, total_duration_sec, cleanup_preview_bytes}.

Inputs: apply_cleanup. Returns: object

verify_paperB

Verify a paper exists via DOI, arXiv ID, or fuzzy title match.

Inputs: doi, arxiv_id, title, authors, +1 more. Returns: object

write_topic_overviewC

Write a topic overview markdown file for a cluster.

Inputs: cluster_slug (required), markdown (required), overwrite. Returns: object

Tool Schema Changelog

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

Loading tool schema changelog…

    TDQS

    B3.2/5.0

    Scored across 76 tools

    Disambiguation5/5

    Every tool has a clearly distinct purpose, with detailed descriptions that explicitly state when and when not to use each tool, eliminating ambiguity even among closely related functions like fit_check variants.

    Naming Consistency5/5

    All tool names follow a consistent snake_case verb_noun pattern, with predictable prefixes like 'discover_', 'fit_check_', 'notebooklm_', etc., making it easy for an agent to infer behavior from the name.

    Tool Count2/5

    76 tools is far beyond the typical well-scoped range; the server appears to cover a broad domain but could benefit from consolidation, as many tools are highly specialized (e.g., individual discover_* steps) and may overwhelm agents.

    Completeness4/5

    The tool set covers the full research workflow from discovery and ingest to analysis, labeling, cleanup, and dashboard generation. Minor gaps exist (e.g., no direct tool for deleting a cluster, relying on CLI), but core operations are well-covered.

    Maintenance

    ActivityActive
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      B
      quality
      C
      maintenance
      Your AI's research copilot. Searches 6 academic databases, downloads real PDFs, reads them cover to cover, extracts evidence, renders figures, syncs to Zotero.
      16
      16
      MIT
    • A
      license
      Not graded
      quality
      D
      maintenance
      Enables natural language interaction with Zotero libraries, allowing users to search, retrieve, and update papers and metadata via AI assistants like Claude and Gemini.
      1
      GPL 2.0
    • F
      license
      Not graded
      quality
      D
      maintenance
      Aggregates academic paper search from multiple databases (OpenAlex, Semantic Scholar, etc.) with PDF storage and full-text search capabilities.
      1
      -