research-hub
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| BRAVE_API_KEY | No | Optional web search backend (alternative to DDG) | |
| TAVILY_API_KEY | No | Optional web search backend (alternative to DDG) | |
| ZOTERO_API_KEY | No | Zotero web API auth, required for paper ingestion | |
| ZOTERO_LIBRARY_ID | No | Zotero library identifier | |
| SEMANTIC_SCHOLAR_RPS | No | Optional Semantic Scholar request-per-second rate override | |
| SEMANTIC_SCHOLAR_API_KEY | No | Optional Semantic Scholar API key for higher rate limits |
Capabilities
Features and capabilities supported by this server
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
| logging | {} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| extensions | {
"io.modelcontextprotocol/ui": {}
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| web_searchA | General web search (blog posts / docs / news / GitHub READMEs). Use alongside auto_research_topic when the user's need extends beyond peer-reviewed papers and into official docs, engineering blogs, or news. |
| cluster_rebindA | Run the cluster-rebind workflow specified by Single entrypoint that consolidates four legacy rebind operations
(propose / apply / list_orphans / status) into one tool with an
When to use:
When NOT to use:
|
| build_citationC | Return an inline citation string for a paper. |
| list_quotesB | List captured quotes, optionally filtered by cluster. |
| capture_quoteC | Persist a quote to /.research_hub/quotes/.md. |
| compose_draftC | Assemble captured quotes into a markdown draft. |
| add_paperC | Fetch a paper by DOI/arXiv ID and ingest it (one-shot). |
| import_folder_toolC | Walk a local folder and ingest non-DOI files as document notes. |
| suggest_cluster_splitB | Analyze a cluster's citation graph and suggest sub-topic splits. |
| list_crystalsC | List all pre-computed crystal answers for a cluster. |
| read_crystalC | Read a specific crystal at the requested detail level. |
| emit_crystal_promptC | Emit the markdown prompt the calling AI should answer to generate crystals. |
| apply_crystalsC | Persist crystal answers to hub//crystals/.md. |
| summarize_clusterA | Generate per-paper Key Findings + Methodology + Relevance via LLM CLI. For each paper in Use when: user says "summarize this cluster's papers", "fill the TODO
Findings", or after 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 |
| 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
|
| check_crystal_stalenessC | Check how many crystals are stale (>10% cluster paper delta since generation). |
| read_cluster_memoryC | Read cluster memory. kind may be entities, claims, methods, or all. |
| 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
|
| 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. |
| 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. |
| search_papersC | Search for academic papers across multiple backends. |
| enrich_candidatesC | Resolve candidate identifiers to full paper records. |
| verify_paperB | Verify a paper exists via DOI, arXiv ID, or fuzzy title match. |
| suggest_integrationC | Suggest which cluster a paper belongs to and find related papers. |
| list_clustersA | List all topic clusters with their bindings. |
| show_clusterB | Show detailed info for a cluster including sync status. |
| export_citationC | Export citation in BibTeX, BibLaTeX, RIS, or CSL-JSON format. |
| get_referencesC | List papers cited by the given paper (its bibliography). |
| get_citationsA | List papers that cite the given paper (forward citations). Delegates to |
| run_doctorB | Run health checks on the research-hub installation. |
| get_config_infoA | Show current configuration paths and settings. |
| remove_paperB | Remove a paper from the vault, optionally deleting its Zotero item too. |
| mark_paperC | Update the reading status of a paper note. Delegates to |
| move_paperC | Move a paper note from its current cluster to another. Delegates to |
| search_vaultC | Search local vault notes by title or full text. |
| merge_clustersA | Merge all papers from one cluster into another, then delete the source. Delegates to |
| split_clusterB | Split a source cluster into a new cluster based on title keyword overlap. |
| get_topic_digestC | Return every paper in a cluster plus a markdown digest for overview writing. |
| write_topic_overviewC | Write a topic overview markdown file for a cluster. |
| read_topic_overviewA | Return the current topic overview markdown for a cluster, if present. |
| propose_subtopicsC | Build the Phase 1 sub-topic proposal prompt for an AI to consume. |
| emit_assignment_promptA | Build the topic-build Phase 2 (sub-topic assignment) LLM prompt. Part of the multi-phase |
| apply_subtopic_assignmentsC | Write subtopics frontmatter to each paper note. |
| build_topic_notesC | Generate topics/NN_.md files from paper frontmatter. |
| list_topic_notesC | List existing sub-topic notes for a cluster. |
| fit_check_promptC | Build the Gate 1 fit-check prompt for an AI to score. |
| fit_check_applyC | Consume AI scores, filter candidates, write rejected sidecar. |
| 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_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": "..."} |
| 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} |
| 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 |
| label_paperC | Set, add, or remove labels on a paper note. |
| list_papers_by_labelC | Return paper states for the cluster, optionally filtered by label. |
| prune_clusterA | Archive or delete paper notes in a cluster whose frontmatter carries Cluster cleanup operation that acts on the label sidecars written
by When to use:
When NOT to use:
|
| 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 |
| discover_newC | Run search + emit fit-check prompt, stashing state for discover_continue. |
| 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_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
When to use:
When NOT to use:
|
| discover_statusC | Return current discover state for a cluster. |
| discover_cleanC | Remove the discover stash directory for a cluster. |
| examples_listA | List bundled example clusters. |
| examples_showA | Return one bundled example cluster definition.
Inspects sample JSON before examples_copy.
When to use: before copying an example such as |
| examples_copyC | Copy an example into the user's cluster registry. |
| notebooklm_bundleC | Build a NotebookLM upload bundle for a cluster. |
| notebooklm_uploadC | Upload the latest cluster bundle to NotebookLM using the saved session. |
| notebooklm_generateC | Trigger NotebookLM artifact generation for a cluster notebook. |
| notebooklm_downloadC | Download the latest NotebookLM briefing artifact into the vault. |
| ask_clusterA | Answer a question about one cluster, dispatching to the source named by Single entrypoint for all cluster-question workflows. Replaces the
deprecated aliases When to use:
When NOT to use:
|
| sync_clusterC | Aggregate maintenance view: staleness + scope drift + vault health + recommendations. |
| compose_brief_draftC | Assemble a markdown draft from cluster quotes + overview + crystal TLDRs. |
| emit_cluster_baseC | Emit (or refresh) the .base dashboard file for a cluster. |
| auto_research_topicA | One-shot research pipeline: search + ingest + NotebookLM brief (+ optional crystals). Slugifies Use when: user says "research X for me" or "find papers on X". Returns |
| 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:
After presenting the plan + getting user confirmation, call auto_research_topic with the plan's suggested args. |
| cleanup_garbageA | Garbage-collect accumulated research-hub files (v0.46+). Pass Use when: user says "clean up", "free disk space", or "GC the vault". Returns |
| 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 |
| collect_to_clusterA | Unified ingest. Auto-routes by source shape: DOI/arXiv -> add_paper, folder -> import_folder, URL -> .url file + import. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/WenyuChiou/research-hub'
If you have feedback or need assistance with the MCP directory API, please join our Discord server