Research HubBLOCK
AI-operable research workspace for Zotero, Obsidian, and NotebookLM. Use any two, or all three, through CLI, MCP, REST, and dashboard.
Overview
From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.
A local workspace connecting literature, research artifacts, and manuscripts through traceable work.
繁體中文 · Workspace guide · Existing setup · Developer architecture
[](https://pypi.org/project/research-hub-pipeline/) [](pyproject.toml) [](LICENSE)
Workspace preview — unmerged and unreleased. The six-page workspace below is proposed in research-hub PR #135. PyPI 1.2.0 does not include it. Use the pinned preview installation below, or try the published literature dashboard.Why this exists
Research crosses files and tools: a paper informs a question, an analysis changes a result, and a manuscript needs revision. Keep those connections visible when you or an AI assistant picks up the next task.
Start with local files. Connect Zotero for references, Obsidian for notes, and NotebookLM for source-based briefings when needed. Empirical studies and literature reviews share the workspace.
What you work with
b6e57d4fa690OBSERVED · 2026-10-08Connect
Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.
claude mcp add research-hub-pipeline -- None research-hub-pipeline==1.2.0
Exposed tools (44)
31 read · 13 write · 0 destructive.
| Tool | Risk | Description |
|---|---|---|
add_paper | write | Fetch a paper by DOI/arXiv ID and ingest it (one-shot). |
apply_cluster_summaries | write | Persist a JSON payload of per-paper summaries (when LLM was invoked |
apply_crystals | write | Persist crystal answers to hub/<cluster>/crystals/<slug>.md. |
ask_cluster | read | Answer a question about one cluster, dispatching to the source named by ``source`` / ``mode``. |
auto_research_topic | read | One-shot research pipeline: search + ingest + NotebookLM brief (+ optional crystals). |
build_citation | read | Return an inline citation string for a paper. |
capture_quote | read | Persist a quote to <vault>/.research_hub/quotes/<slug>.md. |
check_crystal_staleness | read | Check how many crystals are stale (>10% cluster paper delta since generation). |
cleanup_garbage | read | Garbage-collect accumulated research-hub files (v0.46+). |
cluster_prisma | read | PRISMA screening-provenance counts for a cluster: identified / deduped / |
cluster_rebind | write | Run the cluster-rebind workflow specified by ``action``. |
collect_to_cluster | read | Unified ingest. Auto-routes by source shape: DOI/arXiv -> add_paper, folder -> import_folder, URL -> .url file + import. |
compose_brief_draft | read | Assemble a markdown draft from cluster quotes + overview + crystal TLDRs. |
compose_draft | read | Assemble captured quotes into a markdown draft. |
download_artifacts | read | Download a generated NotebookLM briefing back to the vault. |
emit_cluster_base | read | Emit (or refresh) the .base dashboard file for a cluster. |
emit_crystal_prompt | read | Emit the markdown prompt the calling AI should answer to generate crystals. |
generate_dashboard | read | Generate a personal HTML dashboard for the vault. |
import_folder_tool | write | Walk a local folder and ingest non-DOI files as document notes. |
list_crystals | read | List all pre-computed crystal answers for a cluster. |
list_quotes | read | List captured quotes, optionally filtered by cluster. |
notebooklm_bundle | write | Build a NotebookLM upload bundle for a cluster. |
notebooklm_download | read | Download the latest NotebookLM briefing artifact into the vault. |
notebooklm_generate | write | Trigger NotebookLM artifact generation for a cluster notebook. |
notebooklm_upload | write | Upload the latest cluster bundle to NotebookLM using the saved session. |
plan_research_workflow | read | Convert a freeform user intent into a structured research plan. |
propose_research_setup | read | Propose names for a new research collection without creating anything. |
read_cluster_memory | read | Read cluster memory. kind may be entities, claims, methods, or all. |
read_crystal | read | Read a specific crystal at the requested detail level. |
suggest_cluster_split | read | Analyze a cluster |
summarize_cluster | read | Generate per-paper Key Findings + Methodology + Relevance via LLM CLI. |
sync_cluster | write | Aggregate maintenance view: staleness + scope drift + vault health + recommendations. |
tidy_vault | read | One-shot vault maintenance: doctor autofix + dedup rebuild + bases refresh + cleanup preview. |
web_search | read | General web search (blog posts / docs / news / GitHub READMEs). |
workflow_decide | read | Record an exact human accept, decline, revise, or cancel decision. |
workflow_initialize | read | Initialize deterministic workflow state 1.1; performs no external writes. |
workflow_migrate | write | Dry-run a v1.0-to-v1.1 migration, or atomically apply it with backup. |
workflow_resume | read | Resume only when policy, retry, terminal, and external-action guards allow it. |
workflow_status | read | Return validated workflow status and recovery state. |
workflow_validate | read | Validate v1.0 or v1.1 state without mutating it. |
workspace_action | write | Prepare/show/decide/execute/reconcile a local accepted-proposal delivery. |
workspace_manuscript | read | Bind/state/audit the explicitly configured public writing bundle. |
workspace_project | write | Project create/demo/list/show/register/record/search via the shared workspace service. |
workspace_task | write | Durable task create/list/show/run/handoff/import/cancel/recover/decide. |
Trust audit
BLOCKgrade F · trust 56/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | FAIL |
| L2 | Instruction surface (what it tells the agent) | FAIL |
| L3 | Class-specific surface | PASS |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- declared (6 observation(s))
- Network
- declared (8 observation(s))
- Shell
- declared (2 observation(s))
- Dependencies
- pinned
- Secrets in source
- none-found
Findings (25)
dossier = yaml.load(dossier_text, Loader=_UniqueLoader)
results["first_ingest_rc"] = pipeline.run_pipeline(papers_json=path, cluster_slug="native-review", query="initial, query", verify=False)
pipeline.run_pipeline(papers_json=path, cluster_slug="native-review", query='follow-up, "citation"', verify=False)
pipeline.run_pipeline(papers_json=path, cluster_slug="native-review", query='follow-up, "citation"', verify=False)
- Don't tell the user to ignore NLM. Tell them which parts to trust and
- Don't tell the user to ignore NLM. Tell them which parts to trust and
return importlib.import_module(name) is not None
doctor-output.txt
init-output.txt
.last-update.json
return hashlib.sha1(f"{kind}:{identifier}".encode("utf-8")).hexdigest()return hashlib.sha1(f"{kind}:{identifier}".encode("utf-8")).hexdigest()unsafe["slug"] = "../../outside"
status, payload = _post(artifact_server.port, "/artifact-delete?path=../../etc/passwd")
("slug", "../../outside"), ("slug", "nested/paper"), ("slug", "nested\\paper"),("slug", 12), ("sub_category", "../../outside"), ("sub_category", "/outside"),expected = f"brief_archive_path: ../../.research_hub/artifacts/alpha/{report.artifact_path.name}"`http://127.0.0.1:8765/` (live, when `serve --dashboard` is
Open [the local workspace](http://127.0.0.1:8765/app/). The demo needs no account and contains a small numerical summation example and a literature-review fixture. These are teaching inputs, not model
開啟[本機工作區](http://127.0.0.1:8765/app/)。示範不需要帳號,包含小型數值加總範例與文獻回顧測試資料。這些是教學輸入,並非模型產生的研究發現。
dashboard server listening on http://127.0.0.1:18765/
$ curl http://127.0.0.1:18765/healthz
rc = run_pipeline(dry_run=False, cluster_slug="stress", verify=False)
assert pipeline.run_pipeline(dry_run=False, cluster_slug="stress", verify=False) == 0
maturity audit flagged: the institutional-access credential path and the
Gates applied: instruction_override, no_behavioural_pass.
b6e57d4fa690full audit observations/trust-audit/mcp-server/wenyuchiou__research-hub-1.json · Report an issue / request a re-scanAudit history
Every audit this server has had. A grade with a past is a grade somebody is still checking.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-08 | b6e57d4fa690 | BLOCK | F | 56 | first audit |
Questions
What is the Research Hub MCP server?
AI-operable research workspace for Zotero, Obsidian, and NotebookLM. Use any two, or all three, through CLI, MCP, REST, and dashboard.
What tools does Research Hub expose?
44 in total: 31 read-only, 13 that write, and 0 that can delete or overwrite. Every one is listed on this page with its risk.
Is Research Hub safe to connect to an agent?
No — not without reading the findings first. The audit graded it F (56/100) and found 6 critical or high issues in the source. Each one is listed on this page with the file and line it is on.
What credentials does Research Hub need?
It reads BRAVE_SEARCH_API_KEY, GOOGLE_CSE_API_KEY, RESEARCH_HUB_API_TOKEN, TAVILY_API_KEY and ZOTERO_API_KEY from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.
How does Research Hub run?
It speaks stdio, so it runs as a local process your client starts. It is published on npm as research-hub-workspace at 0.0.0.
How current is this page?
The grade is for one exact copy of the source (b6e57d4fa690), read on 2026-10-08. The repository is watched and re-audited when it changes.