Skip to main content
Glama
notebook-dossier

notebook-dossier

by talenlin

notebook-dossier

NotebookLM Deep Research as an MCP server: start deep research, keep every source, verify each claim against the original text, compare viewpoints, and export a citation-grounded writing brief. Evidence-first knowledge groundwork for writers, analysts, and patent practitioners.

把 NotebookLM Deep Research 封装成 MCP,服务「写文章前的知识调研」:

研究主题 → 深度检索 → 保存完整来源 → 逐篇核验依据 → 比较共识与分歧 → 输出文章研究底稿。

现状

  • 已实现:MCP 服务器(10 个工具 dossier_*)、SQLite 任务存储、上游 notebooklm-mcp 适配器、逐来源证据卡、观点比较不变量、研究底稿导出。

  • 验证:tests/ 43 项通过(幂等启动、跳过续跑、任务租约与心跳、调用审计、导入对账、错误信封、导出守卫);stdio 冒烟 tools/list 通过;真实账号验收完成一轮(2026-10-16:deep 模式确认、46 来源发现、36 导入 + 9 对账未命中、4 来源 47 证据卡、限定来源问答,详见文末清单)。

Related MCP server: RECON

架构

AI 写作客户端(宿主 AI)
   │  MCP (stdio)
   ▼
notebook-dossier  ── SQLite(research_jobs/sources/evidence/comparisons/answers/tasks)
   │  MCP (stdio 子进程,版本固定)
   ▼
notebooklm-mcp-cli @ a277ce7 (0.15.5)  ── 登录/Profile 由其自行管理
   │  网页内部协议(非官方)
   ▼
NotebookLM Deep Research / 来源 / 聊天与引文

本服务只做「研究编排 + 证据整理 + 导出」;登录、NotebookLM 协议细节全部留在上游适配器。两侧数据目录互相隔离(见下)。

安装

uv sync                                  # 本服务依赖 + dev(pytest)
uv sync --extra upstream                 # 可选:安装固定版本上游(提供 notebooklm-mcp 命令)

上游登录(使用独立 Google 账号/Profile):

.venv\Scripts\nlm.exe login --profile research --storage protected   # 弹浏览器窗口,自己完成 Google 登录
.venv\Scripts\nlm.exe login --check                                  # 只检查当前登录是否有效
.venv\Scripts\nlm.exe doctor                                         # 出问题时诊断

MCP 客户端接入(stdio):

{
  "mcpServers": {
    "nlm-research": {
      "command": "uv",
      "args": ["--directory", "D:/OMP/app-dev/notebooklm", "run", "notebook-dossier"],
      "env": { "NLM_APP_DIR": "D:/OMP/app-dev/notebooklm/.nlm-app" }
    }
  }
}

OMP 挂载(实测)

OMP 的用户级配置在 ~/.omp/agent/mcp.json(mcpServers 里加条目后 /mcp reload)。本机已挂载 notebook-dossier(2026-10-16 由 nlm-research 改名):

"notebook-dossier": {
  "type": "stdio",
  "command": "D:\\OMP\\app-dev\\notebooklm\\.venv\\Scripts\\notebook-dossier.exe",
  "args": [],
  "env": {
    "NLM_APP_DIR": "D:\\OMP\\app-dev\\notebooklm\\.nlm-app",
    "NLM_UPSTREAM_COMMAND": "D:\\OMP\\app-dev\\notebooklm\\.venv\\Scripts\\notebooklm-mcp.exe"
  },
  "timeout": 600000
}

要点:timeout 必须大于导入/长问答耗时(OMP 默认 30 秒会截断 dossier_import 等调用);NLM_UPSTREAM_COMMAND 用绝对路径,否则 OMP 启动的子进程 PATH 里找不到上游命令。

配置(环境变量)

变量

默认

说明

NLM_APP_DIR

系统用户数据目录 notebook-dossier

任务库、研究产物、导出目录

NLM_UPSTREAM_COMMAND

notebooklm-mcp

上游 MCP 命令

NLM_UPSTREAM_ARGS

空

上游命令参数(空格分隔)

NLM_PROFILE

上游保存的默认 profile

指定上游登录 profile(如 research)

NLM_QUERY_TIMEOUT

240

单次问答超时(秒)

NLM_SOURCE_WAIT_TIMEOUT

120

来源索引等待(秒)

NLM_IMPORT_TIMEOUT

300

导入超时(秒)

NLM_TASK_LEASE_SECONDS

120

任务租约:心跳超过该秒数才允许其他进程接管为 interrupted

NLM_ACTOR

pid:<pid>:<token>

审计表中的调用方标识(多宿主共库时建议在各宿主配置里命名)

账号 / profile 说明(实测)

  • 每个 profile 必须单独登录才可用:nlm.exe login --profile research --storage protected。

  • 未登录的 profile 会静默回退到默认账号会话(实测:NLM_PROFILE=research 未登录时 notebook_list 仍返回默认账号的笔记本)。因此换账号必须 nlm.exe login --check --profile <名> 验证,dossier_auth_status 也会把 auth_status != configured 判为未连接。

  • nlm doctor 提示的 nlm auth storage set protected 是建议项:把明文 cookie 迁入系统密钥库,执行后用 nlm login --check 确认,失效就重登。

  • nlm doctor 提示的 nlm setup add <client> 不需要执行:那是把原始上游 MCP 挂进 AI 工具;本项目要挂的是 notebook-dossier(见上方 stdio 配置)。

工具

工具

用途

dossier_auth_status

本地/在线登录状态(不返回凭据)与下一步动作

dossier_start

启动 Deep Research(web + deep),返回 research_id;request_key 幂等,同键不重复发起

dossier_status

查状态并同步完整报告与全量发现来源;返回 phase / elapsed_ms / sources_discovered / progress 与自适应轮询建议;wait_seconds>0 服务端长轮询(封顶 300s)

dossier_result

分页读取:findings / report / digest / evidence / comparisons / tasks / answers;findings 含 cite_map / citation_warnings / one_line_takeaway;report 按 cursor/max_chars 分页;digest 为提取式执行摘要(≤1500 字)

dossier_import

导入并逐来源记录映射;收尾自动对账(按 Notebook 实际来源清单回填漏配,auto_reconcile 报告结果);reconcile_only=True 单独对账;confirm_task_id 人工放行任务 ID 冲突

dossier_source_get

单来源元数据 + 索引文本摘录(含内容版本哈希、取得时间)

dossier_query

指定 source_ids 提问(软件强制来源范围,默认新会话);引文编号仅在本回答内有效

dossier_evidence

逐来源(单独会话)提取证据卡,短引文与原文比对;返回任务号;断点续跑:已有证据卡的 (来源, 问题) 组合自动跳过

dossier_compare

按共同问题比较观点,生成共识/差异/缺口;可并入宿主 AI 的比较草稿

dossier_export

导出研究底稿目录(manifest/报告/sources/evidence/viewpoints/writing-brief)

长时间工作(取证、比较)返回任务号,用 dossier_status / dossier_result(view="tasks") 读取进度。任务生命周期语义:

  • 后台任务存活于服务进程内,MCP 连接断开/进程退出即终止;已落库的成果不丢(证据卡逐条写入)。

  • 重放即恢复、不重复:dossier_evidence 按 (来源, 问题) 组合跳过已有证据卡;比较按问题替换空壳行;导入按状态跳过已导入。

  • 任务租约:任务带 owner_id + 心跳;新进程只接管心跳超过 NLM_TASK_LEASE_SECONDS 的任务,不会误杀兄弟进程(如 OMP 挂载与驱动脚本共用一个 NLM_APP_DIR)正在跑的任务。运行期间(含上游长查询)由心跳 ticker 自动续租;被接管的任务旧运行方不再写入,同一 (来源, 问题) 不会重复出卡。

  • 调用审计:每次工具调用写入 audit_log(actor、工具、参数摘要哈希、时间),多宿主互扰时可直接归因;参数正文与凭据不入库。

错误信封(机器可判)

所有错误统一返回:{status:"error", code, error, hint?, uncertain, retry_safe, recovery_tool?, ...}

code

含义

调用方动作

not_found

research/source ID 不存在

按 recovery_tool 重建/查询

invalid_args

参数非法

修正参数

precondition_failed

前置条件未满足(未导入/缺 notebook_id)

按 recovery_tool 补前置步骤

source_scope

来源超出强制范围

只用本研究已导入来源

task_id_conflict

任务 ID 语义存疑,导入暂停

人工核对后 confirm_task_id 放行(retry_safe:false)

mode_mismatch

非 deep 模式启动,拒绝静默降级

核对账号能力,勿当 deep 结果使用

result_uncertain

结果不确定(可能已生效)

先对账(reconcile_only),勿直接重放

provider_error

上游调用失败/无最终回答

视 retry_safe 决定

export_refused

导出触发凭据/内容守卫

修正数据后重试

任务 ID 归一化:一研究一 Notebook,「本 Notebook 内完成态 + 有报告」时任务 ID 表示形式变化(base64 型 vs UUID 型)自动采纳并在 task_id_note 留痕;完成态无报告等语义存疑情形才保留 task_id_conflict 守门。

报告质量与可观测性

  1. 引用一致性校验:报告 [cite: N] 论断中的案号/法条号/判例报告号/日期/数字与被引来源做实体级比对,输出 citation_warnings(claim / source_says / severity)。两层:findings 同步后用来源标题先查案号/法条类高价值实体(零成本);原文预取后对全文重算。只抓编号级错配,不冒充语义核验;来源无文本记 unverifiable,不谎报通过。

  2. 进度可见:phase(researching → awaiting_import → fetching_texts → analyzing → comparing → ready)、elapsed_ms、sources_discovered、自适应 suggested_next_poll_seconds(20s→45s→90s);dossier_status(wait_seconds=N) 长轮询把 N 次轮询压成 1 次调用。

  3. 中间态可读:findings 返回 cite_map(cite 编号 → 稳定 source_id,报告自身不占引用位)与 cite_map_basis(validated/ambiguous/assumed:用实体命中率对编号假设自检,不给假确定性);每来源 one_line_takeaway(提取式,导入取原文后才有)。

  4. 结果体积:view=report 按 cursor(字符偏移)+ max_chars 分页并给章节清单;view=digest 提取式执行摘要(开篇综述 + 结论段 + 高被引来源 + 告警统计,≤1500 字);findings/report 均带 next_action 提示 dossier_export。

软件强制的证据规则

以下不是提示词愿望,而是代码不变量(compare.py):

  1. 仅未提及 ≠ 反对:存在 not_mentioned 陈述时,contradicts 自动降级为 not_mentioned 并留校验记录。

  2. 冲突必须双方原文:contradicts 需要 ≥2 个不同来源的原文引文匹配,否则降级为 unknown。

  3. 转载合并计:同 provenance_group(同规范 URL 或同内容哈希)的支持合并计 1 份独立支持。

  4. 报告不重复计证据:机器生成的研究报告与其依据的网页来源不算两份独立证据。

  5. 元数据不补齐:作者/日期等拿不到就留 null/未知,不由模型编造。

  6. 引文编号按回答隔离:长期标识用 research_id:answer_seq#编号 关联稳定 source/evidence ID。

验证状态分层记录:quote_matched(原文摘录已匹配)≠ analyst_confirmed(原文支持该解释,人工确认)≠ independent_corroboration(独立证据互证)。

导出目录

<export_root>/<research_id>/
  manifest.json          主题、任务、覆盖统计(discovered/selected/imported/ready/readable/analyzed/verified)、文件 sha256
  notebooklm-report.md   完整原始研究报告(机器生成,单独标记)
  sources.json           发现/选择/导入/读取状态、去重映射、内容版本(不含正文)
  evidence.json          逐来源主张与原文支撑(含适用条件、局限、验证状态)
  viewpoints.md          共识、差异、原因与证据缺口
  writing-brief.md       五部分:知识框架 / 逐来源支撑表 / 观点差异 / 可写角度 / 待核验项

导出前执行凭据扫描(cookie/token/authorization 等键或行即中止);导出物不含 Cookie、令牌、浏览器 Profile。

已知边界

  • NotebookLM 个人版网页协议非官方,方法 ID/响应结构随时可能变;失败时错误带修复提示,不静默降级(如 deep → fast 会直接报错)。

  • 导入映射(上游返回 → 本地来源)可能漏配(URL/标题字段不齐)导致 import_uncertain;用 reconcile_only=True 对账回填,实测有效(39/45 全量命中)。

  • 上游研究任务 ID 在运行中会变化(base64 型 ↔ UUID 型):「同 Notebook 完成态 + 有报告」自动归一化(task_id_note 留痕),仅语义存疑时才 task_id_conflict + confirm_task_id 人工放行(两种路径均实测过)。

  • NLM_UPSTREAM_COMMAND 必须是绝对路径:PATH 解析可能命中另一份安装(实测那份读不到受保护凭据,报 "No authentication found")。

  • Deep Research 当前要求账号年满 18 岁,来源额度不足时可能只导入部分;import_uncertain 表示结果不确定,需对账。

  • URL 来源只抓页面文本(无图片/嵌入视频/子页面);索引文本是导入时快照,不等于网页当前全文。

  • 转载识别是近似:同规范 URL / 同内容哈希归并;不同转载 URL 的同稿无法自动识别,可在 sources.json 人工改 provenance_group。

  • fastmcp 4 客户端与上游(较旧 SDK)握手时,上游 stderr 会打印 server/discover 校验告警;工具调用不受影响。

  • 可选后端(Gemini API Deep Research、NotebookLM Enterprise API)未接入;需要时另做 provider。

  • cite 编号语义由上游生成且未文档化:cite_map 基于「报告自身不占引用位」假设并用实体命中率自检,cite_map_basis 如实标注 validated/ambiguous/assumed。

  • 引用校验为编号/数字级,抓不到不带数字的语义歪曲(判例要旨张冠李戴但无编号时无告警);unverifiable 表示来源文本不可得,绝非「校验通过」。

  • deep research 进行中上游不暴露已发现来源数:sources_discovered 在完成时准确(或透传上游 sources_found),研究中只有 phase 可见。

  • one_line_takeaway 与 digest 均为提取式(原文首句 / 开篇+结论段拼接),不是模型重写摘要。

测试与验收

uv run pytest          # 43 项离线测试

Available Tools

10 tools
dossier_auth_statusDossier Auth StatusB

查询 NotebookLM 上游的本地登录与在线状态(不返回任何凭据)。

Inputs: profile. Returns: object

dossier_compareDossier CompareA

按共同问题比较各来源观点,生成共识/差异/缺口(后台任务,返回任务号)。

软件强制规则:仅未提及≠反对;冲突结论必须有双方原文引文;转载合并计、报告不重复计证据。 statements 可传宿主 AI 已形成的比较草稿(HostStatementInput schema),与 NotebookLM 比较结果合并校验。

Inputs: questions (required), research_id (required), statements. Returns: object

dossier_evidenceDossier EvidenceB

逐来源生成证据卡(每来源单独会话、只依据该来源),返回任务号。

证据卡含主张、依据类型、短引文、定位、适用条件、局限与验证状态;短引文会与来源原文比对。

Inputs: source_ids (required), research_id (required), questions. Returns: object

dossier_exportDossier ExportB

导出文章研究底稿目录:manifest / 报告 / sources / evidence / viewpoints / writing-brief。

导出物不含 Cookie、令牌或浏览器 Profile;每个重要判断关联来源与证据 ID。

Inputs: research_id (required), angles, output_dir. Returns: object

dossier_importDossier ImportC

把选中的发现来源导入 NotebookLM,并逐个记录导入映射与不确定结果。

Inputs: research_id (required), candidate_ids, reconcile_only, confirm_task_id, +1 more. Returns: object

dossier_queryDossier QueryA

向 NotebookLM 提问;来源集合由软件强制限定(默认新会话,逐来源取证只传一个来源)。

返回回答与可核验引用;引文编号仅在本回答内有效(citation_key 形如 research:answer_seq#n)。

Inputs: question (required), source_ids (required), research_id (required), question_id, +1 more. Returns: object

dossier_resultDossier ResultA

分页读取研究结果。view: findings | report | digest | evidence | comparisons | tasks | answers。

findings 为完整发现来源(含 cite_map、citation_warnings、逐来源提取式摘要); report 为报告全文分页(cursor=字符偏移、max_chars=窗口); digest 为提取式执行摘要(≤1500 字 + 高被引来源清单); include_report_text 仅作用于 findings 视图的报告内嵌(旧口径,建议改用 view='report')。

Inputs: research_id (required), view, limit, cursor, +2 more. Returns: object

dossier_source_getDossier Source GetB

取得单个来源的元数据与索引文本摘录(含内容版本哈希与取得时间)。

来源元数据缺失的字段保持 null/未知,不从模型补齐。

Inputs: source_id (required), research_id (required), limit, offset. Returns: object

dossier_startDossier StartA

启动一次 NotebookLM Deep Research(web + deep),立即返回 research_id。

每个独立主题一个研究 Notebook。request_key 用于幂等:同键重复调用返回已有任务,不会重复发起研究。

Inputs: topic (required), scope, title, request_key. Returns: object

dossier_statusDossier StatusA

查询研究任务状态,并同步完整报告与发现来源清单。

完成时会保存 compact=False 的完整结果;来源统计与发现/导入不是同一指标。 返回 phase/elapsed_ms/sources_discovered 与自适应 suggested_next_poll_seconds。

Inputs: research_id (required), wait_seconds. Returns: object

Tool Schema Changelog

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

Loading tool schema changelog…

    TDQS

    A3.5/5.0

    Scored across 10 tools

    Disambiguation4/5

    Most tools target distinct actions: start/status/result/query/import/export/source_get are clearly separable. The fuzziest boundary is between the analysis-producing trio (dossier_compare, dossier_evidence, dossier_query) and the ability to read those same artifacts via dossier_result's views (evidence/comparisons/answers), which requires careful reading of which tool creates versus just retrieves them.

    Naming Consistency4/5

    Strong, predictable snake_case with a uniform 'dossier_' prefix across all ten tools. Minor inconsistency in that several are noun-only state/artifact tools (dossier_status, dossier_result, dossier_auth_status) while others use verbs (dossier_start, dossier_query, dossier_export), but the pattern remains readable.

    Tool Count5/5

    Ten tools is well within the ideal range and each maps to a distinct step in the research lifecycle: launch, poll, read, ask, compare, evidence, import, export, inspect source, check auth. No obvious redundancy or padding in the surface.

    Completeness4/5

    Covers the full lifecycle from dossier_start through status/result, downstream analysis (query/compare/evidence), source inspection, import, and export, with good idempotency hints (request_key). Gaps exist: no way to list or enumerate existing research tasks/notebooks, and no cancel/delete/retry operation, so an agent that loses a research_id has a dead end.

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • F
      license
      Not graded
      quality
      D
      maintenance
      Enables multi-source research with YouTube, papers, and podcasts, scoring for substance and credibility, and creating NotebookLM notebooks with knowledge graph and feedback loop.
      -
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables AI agents to drive Google NotebookLM notebooks as a deep-research workspace: ingesting local PDFs and YouTube videos, cross-checking sources for contradictions, identifying knowledge gaps, generating audio overviews, and exporting Markdown dossiers with BibTeX and APA bibliographies. It operates over the Model Context Protocol inside Google Antigravity IDE, with browser-session authentication handled automatically.
      MIT
    • A
      license
      B
      quality
      B
      maintenance
      Enables latency-conscious, auditable deep research by delegating bounded semantic judgments to the calling client LLM while the server owns retrieval, durable state, evidence integrity, citation auditing, and deterministic quality gates.
      20
      MIT