mcpField
Z
zotero-mcp-code

zotero-mcp-code

github.com/kerim生产力6284 次安装40 周前更新
代码仓库

关于 zotero-mcp-code

通过 Python 代码执行搜索 Zotero 文库的技能。它结合语义、关键词和标签搜索,并在代码中去重、排序和筛选,只将选定条目传入大模型上下文。

主要功能

  1. 01结合语义、关键词和标签搜索
  2. 02对结果去重并排序
  3. 03按类型、日期和标签筛选
  4. 04搜索作者和近期条目
  5. 05格式化包含摘要的结果

适用场景

  1. 01用不同拼写查找文献
  2. 02查找某作者近期论文
  3. 03按日期或条目类型缩小结果
  4. 04搜索大型文库并控制上下文

MCP 相关

该技能通过代码执行而非直接调用 MCP 来搜索 Zotero。它在代码中处理大量结果,再将选定结果传入上下文。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/kerim/zotero-code-execution --skill zotero-mcp-code

安装后在 Claude Code 中输入/zotero-mcp-code确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

QUICK_START.md
HONEST_STATUS.md
DEPLOYMENT_SUMMARY.md
LICENSE
IMPLEMENTATION_SUMMARY.md
README.md
.gitignore
README_LIBRARY.md
CLAUDE_INSTRUCTIONS.md
CLAUDE.md
setup.py
setup_paths.py
examples.py
zotero_lib.py
test_basic.py
test_real_performance.py
requirements.txt
skill/
README.md

详细介绍

Zotero MCP 代码执行技能

通过代码执行搜索 Zotero 文献库,实现安全、高效、全面的搜索。

🎯 核心概念

不要直接调用 MCP 工具(这会将所有结果加载到上下文中,并可能导致崩溃),而是编写 Python 代码,以便:

  1. 获取大型数据集(每种策略 50–100+ 个条目)
  2. 在代码执行环境中筛选并排序
  3. 仅将排名靠前的 N 个结果返回到上下文中

优点:

  • ✅ 无崩溃风险(大量数据留在代码中处理)
  • ✅ 自动执行多策略搜索
  • ✅ 自动去重
  • ✅ 自动排序
  • ✅ 只需调用一次函数,而非 5–10 次

⚠️ 重要注意事项

多词搜索

Zotero 会将多词查询视为 AND 条件!

❌ 错误: comprehensive_search("Atyal Atayal 泰雅族") → 找不到结果(需要匹配所有词) ✅ 正确: 分别搜索每个词并合并结果(参见下文模式 6)

适用多词 OR 搜索的情况:

  • 多种拼写方式(Atayal、Atyal)
  • 多种语言(Atayal、泰雅族)
  • 同义词(skill transfer、transfer of learning)
语义搜索状态

语义搜索现已正常运行(已于 2025-01-08 修复)。不过,你可能会在语义搜索引擎的输出中看到 404 错误消息;这些消息可以忽略,因为我们的封装器能够正确处理。

🚀 基本用法

对于 90% 的 Zotero 搜索,使用这个简单模式:

import sys
sys.path.append('/Users/niyaro/Documents/Code/zotero-code-execution')
import setup_paths

from zotero_lib import SearchOrchestrator, format_results

# Single comprehensive search
orchestrator = SearchOrchestrator()
results = orchestrator.comprehensive_search(
    "user's query here",
    max_results=20,  # Return top 20 most relevant
    use_semantic=True  # Semantic search now works correctly
)

# Format and display
print(format_results(results, include_abstracts=True))

此操作会自动:

  • 执行语义搜索(向量相似度)
  • 执行关键词搜索(qmode="everything" + "titleCreatorYear")
  • 执行基于标签的搜索
  • 总共获取 100+ 个条目
  • 对结果去重
  • 按相关性排序
  • 仅将排名靠前的 20 个结果返回到上下文中

📋 常见模式

模式 1:简单搜索(最常见)

用户询问:“查找有关具身认知的论文”

import sys
sys.path.append('/Users/niyaro/Documents/Code/zotero-code-execution')
import setup_paths
from zotero_lib import SearchOrchestrator, format_results

orchestrator = SearchOrchestrator()
results = orchestrator.comprehensive_search("embodied cognition", max_results=20)
print(format_results(results))
模式 2:筛选搜索

用户询问:“查找近期的机器学习期刊文章”

import sys
sys.path.append('/Users/niyaro/Documents/Code/zotero-code-execution')
import setup_paths
from zotero_lib import ZoteroLibrary, SearchOrchestrator, format_results

library = ZoteroLibrary()
orchestrator = SearchOrchestrator(library)

# Fetch broadly (safe - filtering happens in code)
items = library.search_items("machine learning", limit=100)

# Filter in code
filtered = orchestrator.filter_by_criteria(
    items,
    item_types=["journalArticle"],
    date_range=(2020, 2025)
)

print(format_results(filtered[:15]))
模式 3:作者搜索

用户询问:“我有哪些 Kahneman 的论文?”

import sys
sys.path.append('/Users/niyaro/Documents/Code/zotero-code-execution')
import setup_paths
from zotero_lib import ZoteroLibrary, format_results

library = ZoteroLibrary()
results = library.search_items(
    "Kahneman",
    qmode="titleCreatorYear",
    limit=50
)

# Sort by date
sorted_results = sorted(results, key=lambda x: x.date, reverse=True)
print(format_results(sorted_results))
模式 4:基于标签的搜索

用户询问:“显示带有‘learning’和‘cognition’标签的论文”

import sys
sys.path.append('/Users/niyaro/Documents/Code/zotero-code-execution')
import setup_paths
from zotero_lib import ZoteroLibrary, format_results

library = ZoteroLibrary()
results = library.search_by_tag(["learning", "cognition"], limit=50)
print(format_results(results[:20]))
模式 5:近期论文

用户询问:“我最近添加了什么?”

import sys
sys.path.append('/Users/niyaro/Documents/Code/zotero-code-execution')
import setup_paths
from zotero_lib import ZoteroLibrary, format_results

library = ZoteroLibrary()
results = library.get_recent(limit=20)
print(format_results(results))
模式 6:多词 OR 搜索(多种拼写方式/语言)

用户询问:“查找关于 Atyal 或泰雅族的论文”(不同拼写方式/语言)

重要: Zotero 会将多词查询视为 AND 条件。要执行 OR 搜索,请分别搜索每个词并合并结果。

import sys
sys.path.append('/Users/niyaro/Documents/Code/zotero-code-execution')
import setup_paths
from zotero_lib import SearchOrchestrator, format_results

orchestrator = SearchOrchestrator()

# Search each term separately
all_results = {}
for term in ['Atayal', '泰雅族']:
    results = orchestrator.comprehensive_search(term, max_results=50, use_semantic=True)
    for item in results:
        all_results[item.key] = item  # Deduplicate by key

# Re-rank combined results
ranked = orchestrator._rank_items(list(all_results.values()), 'Atayal 泰雅族')

# Optional: Filter for specific content
filtered = [item for item in ranked
            if any(term in (item.title + item.abstract).lower()
                   for term in ['atyal', 'atayal', '泰雅'])]

print(format_results(filtered[:25], include_abstracts=True))
模式 7:多主题 AND 搜索

用户询问:“查找同时涉及认知和学习的论文”

import sys
sys.path.append('/Users/niyaro/Documents/Code/zotero-code-execution')
import setup_paths
from zotero_lib import SearchOrchestrator, format_results

orchestrator = SearchOrchestrator()

# Search both topics
results1 = orchestrator.comprehensive_search("cognition", max_results=30)
results2 = orchestrator.comprehensive_search("learning", max_results=30)

# Find intersection
keys1 = {item.key for item in results1}
keys2 = {item.key for item in results2}
common_keys = keys1 & keys2

if common_keys:
    common_items = [item for item in results1 if item.key in common_keys]
    print("Papers about both topics:")
    print(format_results(common_items))
else:
    print("No papers found on both topics.")
    print("\nCognition results:")
    print(format_results(results1[:10]))
    print("\nLearning results:")
    print(format_results(results2[:10]))

🔧 高级用法

自定义筛选逻辑
import sys
sys.path.append('/Users/niyaro/Documents/Code/zotero-code-execution')
import setup_paths
from zotero_lib import ZoteroLibrary, SearchOrchestrator, format_results

library = ZoteroLibrary()
orchestrator = SearchOrchestrator(library)

# Fetch large dataset
items = library.search_items("neural networks", limit=100)

# Custom filtering
recent_with_doi = [
    item for item in items
    if item.doi and item.date and int(item.date[:4]) >= 2020
]

print(format_results(recent_with_doi[:15]))
多角度自定义搜索
import sys
sys.path.append('/Users/niyaro/Documents/Code/zotero-code-execution')
import setup_paths
from zotero_lib import ZoteroLibrary, SearchOrchestrator, format_results

library = ZoteroLibrary()
orchestrator = SearchOrchestrator(library)

all_results = set()

# Multiple search angles
queries = [
    "skill transfer",
    "transfer of learning",
    "generalization of skills"
]

for query in queries:
    results = library.search_items(query, limit=30)
    all_results.update(results)

# Rank combined results
ranked = orchestrator._rank_items(list(all_results), "skill transfer")
print(format_results(ranked[:20]))
迭代优化
import sys
sys.path.append('/Users/niyaro/Documents/Code/zotero-code-execution')
import setup_paths
from zotero_lib import ZoteroLibrary, SearchOrchestrator, format_results

library = ZoteroLibrary()
orchestrator = SearchOrchestrator(library)

# Initial search
initial = library.search_items("memory", limit=50)

# Analyze tags
tag_freq = {}
for item in initial:
    for tag in item.tags:
        tag_freq[tag] = tag_freq.get(tag, 0) + 1

# Find most common tag
if tag_freq:
    most_common_tag = max(tag_freq, key=tag_freq.get)

    # Refine search
    refined = orchestrator.filter_by_criteria(
        initial,
        required_tags=[most_common_tag]
    )

    print(f"Papers with most common tag '{most_common_tag}':")
    print(format_results(refined))

📚 API 参考

SearchOrchestrator

用于自动搜索的主要类。

comprehensive_search(query, max_results=20, use_semantic=True, use_keyword=True, use_tags=True, search_limit_per_strategy=50)

执行多策略搜索,并自动去重和排序。

参数:

  • query(str):搜索查询
  • max_results(int):要返回的最大结果数(默认值:20)
  • use_semantic(bool):是否使用语义搜索(默认值:True)
  • use_keyword(bool):是否使用关键词搜索(默认值:True)
  • use_tags(bool):是否使用标签搜索(默认值:True)
  • search_limit_per_strategy(int):每种策略获取的条目数(默认值:50)

返回: ZoteroItem 对象列表

filter_by_criteria(items, item_types=None, date_range=None, required_tags=None, excluded_tags=None)

根据各种条件筛选条目。

参数:

  • items(list):要筛选的条目
  • item_types(list):允许的条目类型(例如,["journalArticle"])
  • date_range(tuple):(最小年份,最大年份)
  • required_tags(list):必须存在的标签
  • excluded_tags(list):不得存在的标签

返回: 筛选后的 ZoteroItem 对象列表

ZoteroLibrary

Zotero 的底层接口。

search_items(query, qmode="titleCreatorYear", item_type="-attachment", limit=100, tag=None)

基本关键词搜索。

semantic_search(query, limit=100, search_type="hybrid")

语义/向量搜索。

search_by_tag(tags, item_type="-attachment", limit=100)

按标签搜索。

get_recent(limit=50)

获取最近添加的条目。

get_tags()

获取知识库中的所有标签。

format_results(items, include_abstracts=True, max_abstract_length=300)

将条目格式化为 Markdown。

⚙️ 配置

默认参数

适用于大多数搜索的良好默认值:

orchestrator.comprehensive_search(
    query,
    max_results=20,              # Top 20 results
    search_limit_per_strategy=50 # Fetch 50 per strategy
)
调整搜索深度

适用于快速搜索(结果较少、速度较快):

results = orchestrator.comprehensive_search(
    query,
    max_results=10,
    search_limit_per_strategy=20
)

适用于深入搜索(结果更全面):

results = orchestrator.comprehensive_search(
    query,
    max_results=30,
    search_limit_per_strategy=100
)

🔍 工作原理

背后的处理过程

调用 comprehensive_search("embodied cognition", max_results=20) 时:

  1. 语义搜索(如果已启用):

    • 搜索“embodied cognition”(混合模式)→ 50 个条目
    • 搜索“embodied cognition”(向量模式)→ 50 个条目
  2. 关键词搜索(如果已启用):

    • 使用 qmode="everything" 搜索 → 50 个条目
    • 使用 qmode="titleCreatorYear" 搜索 → 50 个条目
  3. 标签搜索(如果已启用):

    • 从查询中提取单词
    • 在知识库中查找匹配的标签
    • 按匹配的标签搜索 → 50 个条目
  4. 处理:

    • 合并所有结果(约 250 个条目)
    • 使用条目键去重(约 120 个不重复条目)
    • 按相关性得分排序
    • 返回前 20 个
  5. 上下文:

    • 只有最终的 20 个条目会传入大模型上下文
    • 所有处理都在代码执行环境中进行
这样做的好处

旧方法(直接调用 MCP):

# 5+ function calls, all results to context
results1 = zotero_semantic_search("query", limit=10)  # Crash risk if > 15
results2 = zotero_search_items("query", limit=10)
# ... manual deduplication, no ranking
# All items (50+) load into context

新方法(代码执行):

# 1 function call, only top results to context
results = orchestrator.comprehensive_search("query", max_results=20)
# Fetches 250+ items, processes in code, returns top 20

🛠️ 错误处理

务必处理可能出现的错误:

import sys
sys.path.append('/Users/niyaro/Documents/Code/zotero-code-execution')
import setup_paths
from zotero_lib import SearchOrchestrator, format_results

orchestrator = SearchOrchestrator()

try:
    results = orchestrator.comprehensive_search("query", max_results=20)

    if results:
        print(format_results(results))
    else:
        print("No results found. Try a broader search term.")

except Exception as e:
    print(f"Search failed: {e}")
    print("Please check your Zotero MCP configuration.")

📖 示例

请参阅 /Users/niyaro/Documents/Code/zotero-code-execution/examples.py,其中包含 8 个完整的可运行示例。

🎓 快速参考

任务代码
基本搜索orchestrator.comprehensive_search(query, max_results=20)
按类型筛选orchestrator.filter_by_criteria(items, item_types=["journalArticle"])
按日期筛选orchestrator.filter_by_criteria(items, date_range=(2020, 2025))
搜索作者library.search_items(author, qmode="titleCreatorYear", limit=50)
按标签搜索library.search_by_tag([tags], limit=50)
最近的条目library.get_recent(limit=20)
格式化输出format_results(items, include_abstracts=True)

💡 提示

  1. 从简单开始:大多数查询使用 comprehensive_search()
  2. 调整深度:使用 search_limit_per_strategy 控制搜索的全面程度
  3. 之后再筛选:先广泛获取结果,再在代码中筛选
  4. 自定义逻辑:使用 Python 进行复杂筛选
  5. 检查错误:务必使用 try/except 包裹

📁 文档

  • 快速入门:/Users/niyaro/Documents/Code/zotero-code-execution/QUICK_START.md
  • 完整文档:/Users/niyaro/Documents/Code/zotero-code-execution/README.md
  • 示例:/Users/niyaro/Documents/Code/zotero-code-execution/examples.py
  • 状态:/Users/niyaro/Documents/Code/zotero-code-execution/HONEST_STATUS.md

⚠️ 重要说明

  • 这里使用代码执行,而非直接调用 MCP
  • 大型数据集在代码中处理,从而保持上下文精简
  • 语义搜索可能不可用(此时会退回到关键词搜索)
  • 结果会自动去重并排序
  • 可以安全地使用较大的限制值(100+),因为筛选是在代码中进行的

🔄 从 zotero-mcp 迁移

旧方法:

# Multiple manual MCP calls
results1 = zotero_semantic_search("query", limit=10)
results2 = zotero_search_items("query", limit=10)
# Manual deduplication...

新方法:

# One function call with code execution
import sys
sys.path.append('/Users/niyaro/Documents/Code/zotero-code-execution')
import setup_paths
from zotero_lib import SearchOrchestrator, format_results

orchestrator = SearchOrchestrator()
results = orchestrator.comprehensive_search("query", max_results=20)
print(format_results(results))

请记住: 此技能使用代码执行来安全处理大型搜索。实现代码位于 /Users/niyaro/Documents/Code/zotero-code-execution/。

评论

支持 Markdown