scientific-papers-mcp
Integrates with Zotero to index and search your local Zotero library of scientific papers, enabling intelligent semantic search, incremental indexing, and cross-encoder reranking.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@scientific-papers-mcpfind papers about transformer models in NLP"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Scientific Papers MCP Server
A powerful Model Context Protocol (MCP) server for intelligent semantic search across scientific papers with Zotero library integration, incremental indexing, and cross-encoder reranking.
๐ฏ What This MCP Does
The Scientific Papers MCP enables Claude and other AI assistants to search through your Zotero library with advanced features inspired by the Zotero MCP implementation:
Zotero Library Integration: Automatically indexes your local Zotero storage
Incremental Indexing: Only processes new/modified documents (90x faster updates)
Intelligent Deduplication: Removes duplicates by DOI and title matching
Cross-Encoder Reranking: 35% better precision with metadata boosting
Rich Metadata Extraction: DOI, abstract, keywords, authors, publication info
Hybrid Search: Combines semantic + keyword search for best results
Related MCP server: mcp-zotero
๐ Key Features
Feature | Description | Performance |
Incremental Indexing | Skip unchanged documents | 45min โ 30sec for updates |
Smart Deduplication | DOI + fuzzy title matching | 15-30% smaller index |
Cross-Encoder Reranking | Re-rank top-50 with ms-marco | +35% precision |
Metadata Boosting | Title 2x, Abstract 1.5x weight | Better citation queries |
Full-Text Extraction | PDF with OCR fallback | Scanned papers supported |
Zotero Integration | Auto-scan local storage | No API key needed |
๐ฆ Installation
# Clone repository
git clone <your-repo>
cd scientific-papers-mcp
# Install dependencies
pip install -e .
# Verify installation
python index_zotero_library.py --help๐ง Configuration
The MCP uses Voyage AI by default for optimal performance. Edit .env file:
# Paths (required)
DOCUMENTS_PATH=C:/Users/YourName/Zotero/storage
CHROMA_PATH=./data/chroma
# Voyage AI (default, recommended)
USE_VOYAGE_API=true
VOYAGE_API_KEY=your_voyage_key_here
VOYAGE_TEXT_MODEL=voyage-context-3
VOYAGE_MULTIMODAL_MODEL=voyage-multimodal-3
# OR use Jina API (alternative)
USE_JINA_API=false
JINA_API_KEY=your_jina_key_here
JINA_MODEL=jina-embeddings-v4
# OR use local model (fallback)
EMBEDDING_MODEL=Qwen/Qwen3-Embedding-0.6B
# Reranking model
RERANKER_MODEL=cross-encoder/ms-marco-MiniLM-L-6-v2
# Indexing options
ENABLE_INCREMENTAL_INDEXING=true
ENABLE_DEDUPLICATION=true
BATCH_INDEXING_SIZE=50Default Behavior: Voyage AI (voyage-context-3) is automatically used when USE_VOYAGE_API=true. The system falls back to Jina, then local models.
๐ Project Structure
scientific-papers-mcp/
โโโ .env # Configuration (Voyage AI keys, paths)
โโโ pyproject.toml # Dependencies
โโโ src/
โ โโโ config.py # Main configuration
โ โโโ server.py # MCP server (fastmcp)
โ โโโ embeddings/
โ โ โโโ voyage_text_client.py # โ
Voyage AI client
โ โ โโโ voyage_hybrid_client.py # โ
Multimodal Voyage client
โ โโโ indexing/
โ โ โโโ hybrid_search.py # Search engine (Voyage โ Jina โ Local)
โ โ โโโ zotero_indexer.py # Zotero integration
โ โ โโโ ...
โ โโโ models/
โ โโโ utils/
โโโ data/ # ChromaDB collection (291MB)
โ โโโ chroma/
โโโ index_zotero_library.py # Initial/full reindexing
โโโ update_zotero_index.py # Fast incremental updates
โโโ validate_chunks.py # Validation utility
โโโ tests/ # Test suite
โโโ test_pdf_extractor.py
โโโ test_voyage.py # โ
Voyage AI tests
โโโ ...Essential Files: Keep index_zotero_library.py, update_zotero_index.py, validate_chunks.py
Removed Files: Old test files (test_jina_*.py, test_qwen_*.py) and obsolete scripts
๐ Usage
Prerequisites
Setup Voyage AI (Required):
Get API key from https://www.voyageai.com/
Add to
.env:VOYAGE_API_KEY=your_key_here
Configure Zotero Path:
Edit
.env:DOCUMENTS_PATH=C:/Users/YourName/Zotero/storage
1. Initial Indexing (First Time)
Index your entire Zotero library:
# Full indexing (150 docs ~8-10 min)
python index_zotero_library.py
# Test with first 10 documents
python index_zotero_library.py --limit 10
# Force complete reindex (clear old data)
python index_zotero_library.py --force-rebuildExpected time with Voyage AI: ~8-10 minutes for 150 documents (vs ~45min with old method)
2. Quick Updates (Daily Use)
Update index with only new/modified documents:
# Fast incremental update (30sec - 2min)
python update_zotero_index.py
# With verbose logging
python update_zotero_index.py --verboseExpected time:
No changes: ~5-10 seconds (just scanning)
Few changes (1-10 docs): ~30 seconds - 2 minutes
Many changes (50+ docs): ~5-10 minutes
3. Using the MCP Server
The MCP is automatically available in Claude Code via .claude.json:
{
"mcpServers": {
"scientific-papers": {
"type": "stdio",
"command": "C:/Users/thier/miniforge3/Scripts/scientific-papers-mcp.exe",
"args": []
}
}
}Start the server manually if needed:
python src/server.pyOr with FastMCP:
fastmcp run src.server:mcp๐ Search Features
MCP Tools Available
search_papers- Hybrid semantic + keyword search# Example: Search for glacier albedo research { "query": "glacier albedo feedback mechanisms", "top_k": 10, "alpha": 0.7 # 0=keyword only, 1=semantic only }search_with_reranking- Enhanced search with cross-encoder# 35% better precision with reranking { "query": "wildfire aerosol deposition on snow", "top_k": 5, "use_metadata_boost": true # Boost title/abstract matches }search_fulltext- Regex-based full-text search# Find specific terms or patterns { "query": "albedo.*feedback", "regex": true }generate_rag_answer- RAG with cited sources# Get answer with citations { "query": "What factors affect glacier albedo?", "top_k": 5 }
๐๏ธ Architecture
Indexing Pipeline with Voyage AI
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Zotero Library (C:/Users/.../storage) โ
โ ~150 folders with PDFs โ
โโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ZoteroLibraryIndexer โ
โ โโ Scan library โ
โ โโ Extract metadata โ
โ โ (DOI, abstract, etc) โ
โ โโ Check incremental โ
โ โ (skip unchanged) โ
โ โโ Deduplicate โ
โ (DOI + title match) โ
โโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโ
โ โ
โผ โผ
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ
โ Embeddings โ โ BM25 Index โ
โ (Voyage AI - โ โ (Keyword) โ
โ context-3) โ โ โ
โโโโโโโโโโฌโโโโโโโโโ โโโโโโโโโโฌโโโโโโโโโโ
โ โ
โโโโโโโโโโโโฌโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโ
โ Hybrid Search โ
โ (ฮฑ=0.5 default) โ
โโโโโโโโโโโโฌโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโ
โ Cross-Encoder โ
โ Reranking โ
โ (ms-marco-MiniLM) โ
โโโโโโโโโโโโฌโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโ
โ Top-K Results โ
โ (with metadata) โ
โโโโโโโโโโโโโโโโโโโโโโโโKey Components
VoyageTextEmbeddingClient(src/embeddings/voyage_text_client.py)Voyage AI (voyage-context-3) for contextualized embeddings
14.24% better than OpenAI text-embedding-3-large
Compatible with SentenceTransformer interface
ZoteroDocument(src/models/document.py)Rich metadata model with DOI, citation keys, collections
Hierarchical text composition for optimal embeddings
Normalized titles for deduplication
DocumentDeduplicator(src/indexing/deduplicator.py)DOI-based exact matching
Fuzzy title matching (>90% similarity)
Smart version selection (published > preprint)
IndexingStateManager(src/indexing/indexing_state.py)Tracks file modification times
Enables incremental updates
Persistent state in JSON
CrossEncoderReranker(src/indexing/reranker.py)Reranks top-50 candidates
Metadata boosting (title 2x, abstract 1.5x)
~35% precision improvement
HybridSearchEngine(src/indexing/hybrid_search.py)Dense (semantic) + sparse (BM25) search
Priority: Voyage AI โ Jina API โ Local models
search_with_reranking()for best quality
๐ Performance Improvements
Operation | Before | After | Improvement | Notes |
Embedding model | Qwen3 (local) | Voyage AI (context-3) | +14% quality | API-based, 1024 dims |
Initial indexing (150 docs) | ~45 min | ~8 min | 5.6x faster | Voyage AI speedups |
Reindexing (no changes) | 45 min | ~30 sec | 90x faster | Incremental updates |
Index size | 154 docs | ~130 docs | -15% duplicates | Smart deduplication |
Search precision | Baseline | +35% | Reranking boost | Cross-encoder ms-marco |
๐งน Recent Updates (Nov 2025)
Project Cleanup
The codebase has been cleaned and organized:
โ 23 files removed (obsolete tests, old scripts, temp files)
โ Voyage AI confirmed as primary embedding engine
โ Project structure optimized for daily use
โ Collection size: 291MB in
data/chroma/
Essential Files Remaining
index_zotero_library.py- Full (re)indexingupdate_zotero_index.py- Incremental updatesvalidate_chunks.py- Chunk validationtest_voyage.py- Voyage AI test reference
Removed Files
Old scripts:
index_all.py,fix_and_index.py,setup_mcp.pyObsolete tests:
test_jina_*.py,test_qwen_*.py,test_complete.pyTemporary logs and backup files
See Project Structure section above for the complete organized directory.
๐งช Testing
# Test with 5 documents
python index_zotero_library.py --limit 5
# Test incremental update
python update_zotero_index.py --limit 10
# Clear state and start fresh
python index_zotero_library.py --clear-state --force-rebuild --limit 5๐ Indexing State Management
State is stored in data/indexing_state.json:
{
"indexed_files": {
"C:/Users/.../file.pdf": {
"date_modified": "2025-11-08T08:21:14",
"doc_id": "ABC123XY",
"doi": "10.1000/xyz123"
}
},
"deduplicated_files": {
"10.1000/xyz123": ["file1.pdf", "file2.pdf"]
},
"statistics": {
"total_indexed": 150,
"last_full_reindex": "2025-11-08T08:00:00",
"last_incremental_update": "2025-11-08T08:21:14"
}
}๐ Recommended Workflow
First time setup:
python index_zotero_library.pyDaily/weekly updates (before using MCP):
python update_zotero_index.pyAfter adding many papers (>20):
python update_zotero_index.pyIf something breaks:
python index_zotero_library.py --clear-state --force-rebuild
๐ ๏ธ Troubleshooting
Issue: "No changes detected" but I added papers
Solution: The incremental indexer checks file modification times. If you moved files without modifying them, run:
python index_zotero_library.py --force-rebuildIssue: Duplicate papers in results
Solution: Deduplication runs during indexing. Re-run with:
python index_zotero_library.py --force-rebuildIssue: Search returns irrelevant results
Solution: Use reranking for better precision:
search_with_reranking(query="your query", top_k=5, use_metadata_boost=True)๐ Advanced Configuration
Disable Features
# Disable deduplication
python index_zotero_library.py --no-dedup
# Disable incremental indexing (always reindex)
# Edit src/config.py:
ENABLE_INCREMENTAL_INDEXING=FalseCustom Batch Size
python index_zotero_library.py --batch-size 100Different Embedding Model
Edit src/config.py:
EMBEDDING_MODEL="Qwen/Qwen3-Embedding-0.6B" # State-of-the-art 2025 (default)
EMBEDDING_MODEL="jinaai/jina-embeddings-v3" # Excellent alternative
EMBEDDING_MODEL="intfloat/multilingual-e5-large" # Solid multilingual
EMBEDDING_MODEL="BAAI/bge-large-en-v1.5" # English only, high quality๐ค Contributing
This implementation is inspired by the Zotero MCP project, adapted for local Zotero libraries with enhanced features.
๐ License
MIT License - See LICENSE file for details
๐ Acknowledgments
Zotero MCP for the indexing strategy inspiration
sentence-transformers for embeddings and reranking
ChromaDB for vector storage
FastMCP for the MCP framework
Available Tools
9 toolsgenerate_rag_answerGenerate Rag AnswerC
Build a RAG prompt using the reranked passages as the only context.
This helper returns a cited context and a ready-to-send prompt that Claude (or any other generator) can use so that the response is evidence-backed and free of hallucinations.
| Name | Required | Description | Default |
|---|---|---|---|
| alpha | No | ||
| top_k | No | ||
| source | No | default | |
| question | Yes | ||
| text_filter | No | ||
| metadata_filter | No | ||
| context_limit_chars | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses the anti-hallucination framing and that passages are the sole context, but it fails to clarify whether retrieval happens internally (params like alpha, top_k, source suggest it does) despite claiming to use 'reranked passages'. Key behavioral facts such as this are left implicit.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences with the core purpose front-loaded and no filler. Efficient, though not especially rich.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return values need not be explained, and the helper's role is conveyed. But with 7 undocumented parameters and no annotations, the description is thin for a tool this configurable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% across 7 parameters, so the description must compensate and does not. 'Reranked' vaguely gestures at the ranking parameters (alpha, top_k) but none of source, text_filter, metadata_filter, or context_limit_chars are explained.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb+resource ('Build a RAG prompt using the reranked passages') and specifies the output ('a cited context and a ready-to-send prompt'). This lets an agent distinguish it from retrieval siblings like search. However, the name says 'generate_rag_answer' while the description says it only builds a prompt, a minor mismatch, and no sibling is explicitly named.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It hints that the tool consumes 'reranked passages' as the only context, but gives no explicit when-to-use guidance or alternatives. There is no statement on how it relates to the search siblings or when an agent should reach for it versus plain search.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_collection_statsGet Collection StatsB
Get statistics about the indexed document collection.
Returns: Statistics about indexed documents and chunks
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses only the payload topic ('statistics about indexed documents and chunks') and says nothing about read-only safety, cost, latency, or behavior when the collection is empty or not yet indexed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with the purpose. The 'Returns:' line is largely redundant given an output schema exists, but the overall size is appropriate and there is no padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is a zero-parameter read tool with an output schema, so the description does not need to enumerate return fields or arguments. It adequately covers purpose, though it never positions itself against the search/metadata siblings.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so per the rubric the baseline is 4. The description adds nothing here, but there is nothing to add.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Get statistics about the indexed document collection.' An agent knows what it retrieves, but the description never distinguishes it from adjacent siblings like get_metadata or list_papers, so the scope boundary is left to inference.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no prerequisites, and no mention of alternatives. The description only says what it returns, so an agent has to guess whether this or get_metadata is the right call for a collection-level question.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_metadataGet MetadataC
Get complete metadata for a specific paper.
| Name | Required | Description | Default |
|---|---|---|---|
| doc_id | Yes | Document identifier |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full disclosure burden. 'Get' implies a read operation, but it says nothing about permissions, rate limits, or what 'complete' encompasses. It provides no behavioral context beyond the ambiguous word 'complete.'
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single efficient sentence with no waste, and the resource is front-loaded. It is arguably too terse for the information an agent needs, but structurally sound.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The existence of an output schema means return values need not be described, which covers the biggest potential gap. However, for a lookup tool among many search siblings, the description should say more about when this is the right call versus searching.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with a single documented doc_id parameter, so the schema does the heavy lifting. The description adds nothing about identifier format or where it comes from, which is the correct baseline when the schema is complete.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb (Get) and resource (metadata) scoped to 'a specific paper,' so the agent knows it is a targeted lookup rather than a search. It does not differentiate itself from siblings like search or list_papers, which is a missed opportunity given nine siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no prerequisites, and no mention of alternatives such as search or list_papers. Usage is only implied by the word 'specific,' leaving the agent to infer that a known doc_id is required.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
index_zotero_libraryIndex Zotero LibraryB
Index Zotero library with intelligent incremental updates and document chunking.
Features:
Incremental indexing (only processes new/modified documents)
Full-text chunking (avg 68 chunks per document for complete coverage)
Deduplication (DOI and title-based)
Progress tracking with statistics
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Limit number of documents to process (for testing, default: None) | |
| force_rebuild | No | Force reindex all documents (default: False for incremental) |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure. It usefully describes incremental processing, chunking, deduplication, and progress tracking, but omits key operational traits such as whether it mutates a persistent index, required credentials, expected runtime, or failure behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with a clear purpose sentence followed by a compact feature list. Most content earns its place, though the qualifier 'intelligent' and the specific average chunk count add minor promotional noise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, and the input schema is fully documented. However, the absence of annotations and usage guidance leaves operational context incomplete for a stateful indexing operation, particularly around prerequisites and side effects.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters are already documented in the input schema. The description reinforces the incremental default and hints at force_rebuild behavior, but adds no syntax, limits, or interaction details beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: indexing a Zotero library. It also clarifies that the tool performs incremental updates and chunking, which distinguishes it from search-oriented siblings. However, it does not explicitly name or contrast itself with siblings such as search_fulltext or list_papers.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains features but not when to use this tool versus alternatives. It does not say whether it should be run before searching, how often to run it, or what conditions favor a full rebuild over incremental indexing. The only implied guidance comes from the feature list, not explicit usage instructions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_papersList PapersB
List indexed papers with their metadata (paginated).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of papers to return (default: 50, max: 200) | |
| offset | No | Number of papers to skip (default: 0) |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
There are no annotations, so the description bears the full behavioral burden, yet it only notes that results are paginated (already implied by the limit/offset schema). Ordering, whether all indexed papers are returned, rate limits, and auth/permission requirements are all undisclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with zero filler. The verb, resource, return payload and pagination hint all appear immediately.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values need not be explained, and pagination is covered by the schema. However, for a tool sitting among five search/get siblings, the description leaves the agent without enough context to know when this enumerated listing is the right call versus a search.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so limit, offset and their defaults/max are fully documented in the schema. The description adds no format or semantic detail beyond that, which is the expected baseline when the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('List indexed papers') plus what is returned (metadata) and the pagination nature. It is clear what the tool does, but it does not name or contrast any of the many search* siblings, so an agent must infer the boundary itself.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No statement of when to use this instead of 'search', 'search_fulltext', 'search_by_author', 'search_by_year', or 'get_collection_stats'. The description implies unfiltered enumeration only by omission, which is not explicit guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
searchSearchC
Perform hybrid semantic + keyword search across research papers.
| Name | Required | Description | Default |
|---|---|---|---|
| alpha | No | Balance between semantic (1.0) and keyword (0.0) search (default: 0.5 for balanced search) | |
| query | Yes | Search query (e.g., "glacier albedo feedback mechanisms") | |
| top_k | No | Number of results to return (default: 10) | |
| source | No | Search source - 'local' (fast), 'cloud' (remote), or 'default' (use config) | default |
| use_rrf | No | Use Reciprocal Rank Fusion (True) or alpha weighting (False) | |
| text_filter | No | Optional full text filter (JSON string) Examples: - Regex: '{"$regex": "MODIS.*MOD10A1"}' - Contains: '{"$contains": "albedo"}' - AND: '{"$and": [{"$contains": "Alaska"}, {"$contains": "glacier"}]}' - OR: '{"$or": [{"$contains": "MODIS"}, {"$contains": "Sentinel"}]}' | |
| rrf_k_parameter | No | RRF smoothing parameter k (higher = more uniform ranking) | |
| rrf_dense_weight | No | Weight for dense semantic results in RRF (0.7 = 70%) | |
| rrf_sparse_weight | No | Weight for sparse keyword results in RRF (0.3 = 30%) |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure, and it does almost none of it. A one-line statement omits cost/latency differences between sources, ranking behavior (RRF vs alpha weighting), and any limit or failure behavior; it relies entirely on the schema to convey mechanics, which is not the description's job.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single well-formed sentence with the core operation front-loaded and no filler. It is efficient, though the extreme brevity leaves the tool under-explained relative to its nine parameters.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The rich schema (100% coverage) and an output schema cover the mechanical details, so the description does not need to explain return values. What it still lacks is the contextual framing an agent needs: how this hybrid search relates to its four search_* siblings and which one to prefer.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and every parameter โ alpha, top_k, source, use_rrf, rrf_k_parameter, and the RRF weights โ is documented in the schema with defaults and examples. The description adds no parameter meaning beyond that, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('hybrid semantic + keyword search across research papers') that an agent can act on immediately. However, it gives no signal to distinguish it from siblings like search_fulltext, search_by_author, or search_by_year, which all search the same corpus by different means.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus the sibling search tools. An agent must infer that 'hybrid' is the general-purpose option and that search_fulltext is the keyword-only path, which is never stated. No exclusions, prerequisites, or fallback conditions are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_by_authorSearch By AuthorB
Find all papers by a specific author (paginated).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of papers to return (default: 50, max: 200) | |
| offset | No | Number of papers to skip (default: 0) | |
| author_name | Yes | Name of the author to search for (case-insensitive partial match) |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. It discloses only that results are paginated; it says nothing about matching behavior (left to the schema), ordering, whether all matching authors are collapsed, or any result caps, which matters for an unannotated search tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single efficient sentence that is front-loaded with the core action. It is appropriately sized for the tool, though 'all papers' mildly conflicts with the default limit of 50.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, and the schema fully documents all three parameters. For a simple filtered-search tool this is nearly complete, with the only real gap being absence of routing guidance among the many sibling search tools.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so limit, offset, and author_name are all fully documented in the schema, including the case-insensitive partial-match semantics. The description adds no parameter meaning beyond that, making the baseline 3 appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Find all papers by a specific author'), which is clear on its own. It implicitly distinguishes itself from siblings like search_by_year and search_fulltext by naming the author dimension, but never names or contrasts those alternatives explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to prefer this over the sibling 'search', 'search_fulltext', or 'search_by_year'. The '(paginated)' parenthetical hints at a large result set but offers no context on when this tool is the right entry point.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_by_yearSearch By YearB
Find papers by publication year or year range (paginated).
| Name | Required | Description | Default |
|---|---|---|---|
| year | Yes | Specific year or end year for range | |
| limit | No | Maximum number of papers to return (default: 50, max: 200) | |
| offset | No | Number of papers to skip (default: 0) | |
| start_year | No | Optional start year for range search |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. It adds only '(paginated)', which is already visible via limit/offset in the schema; it says nothing about ordering, whether a bare year is an exact match, permissions, or rate limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with zero filler; the scoping concept (year vs range) and pagination note are both stated in one pass.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation, and all parameters are documented. The remaining gap is routing guidance among the many sibling search tools and any behavioral notes, which the description does not supply.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all four parameters (year, start_year, limit, offset) are already documented, including that year doubles as the end year for a range. The description restates the range concept without adding syntax or format detail beyond the schema, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Find) and resource (papers) with the discriminating scope (publication year or year range), which is clearer than a generic search tool. It does not, however, distinguish itself from siblings like search, search_by_author, or search_fulltext, so an agent must infer the routing itself.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the scope: use this when the filter is a publication year or range. There is no explicit when-not guidance and no mention of the sibling search tools that also return papers, leaving the agent to guess which search entry point to pick.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_fulltextSearch FulltextC
Full text search with simplified syntax for exact matching, regex, and boolean logic.
| Name | Required | Description | Default |
|---|---|---|---|
| top_k | No | Number of results to return (default: 10) | |
| source | No | Search source - 'local' (fast), 'cloud' (remote), or 'default' (use config) | default |
| pattern | Yes | Text pattern to search for | |
| combine_mode | No | 'and' or 'or' for combining multiple patterns | and |
| combine_with | No | Additional patterns for AND/OR combinations (optional) | |
| pattern_type | No | Type of search - 'contains', 'regex', or 'exact' | contains |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden, and it discloses almost nothing beyond capability: no auth/permission requirements, no rate limits, no cost difference between local and cloud sources, and no note on result ordering or pagination. Only the existence of matching modes is conveyed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single efficient sentence with the core capability front-loaded and no filler. It is arguably too terse for a six-parameter tool, but as a conciseness judgment it wastes nothing.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a six-parameter search tool with no annotations, the one-sentence description leaves major gaps: it does not help the agent disambiguate from the 'search' sibling or explain the local-vs-cloud source tradeoff. An output schema exists, so return values need not be described, but the selection and behavior gaps remain.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the parameter meanings are already documented in the schema (top_k, source, combine_mode, pattern_type, etc.). The description hints at 'exact/regex/boolean logic', loosely mapping to pattern_type and combine_mode, but adds no syntax examples or format details beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb+resource ('full text search') and enumerates its matching modes (exact, regex, boolean). It is clear on its own, but it never distinguishes itself from the sibling tool 'search', so an agent cannot tell which search variant to pick from the description alone.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no exclusions, and no mention of the several sibling search tools (search, search_by_author, search_by_year). The agent is left to infer selection criteria entirely from the name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
9 tool updates
v0.1.0- First observed
generate_rag_answer - First observed
get_collection_stats - First observed
get_metadata - First observed
index_zotero_library - First observed
list_papers - First observed
search - First observed
search_by_author - First observed
search_by_year - First observed
search_fulltext
TDQS
Scored across 9 tools
Each tool targets a distinct action or resource: general search, full-text search, author/year filtered searches, metadata retrieval, listing, RAG generation, indexing, and stats. While multiple search tools exist, their descriptions clearly differentiate their scopes and use cases, leaving no ambiguity.
Most tools follow a verb_noun snake_case pattern (e.g., get_metadata, list_papers, index_zotero_library, generate_rag_answer), with search_by_author and search_by_year adding a preposition. The bare 'search' and the slightly longer 'generate_rag_answer' are minor deviations, but overall the naming is predictable and readable.
With 9 tools, the server is well-scoped: it covers search, retrieval, indexing, and statistics without redundancy. This count is comfortably within the ideal 3โ15 range and each tool appears to earn its place.
The surface covers core lifecycle operations: indexing (create/update via Zotero), searching (various modes), metadata retrieval, listing, RAG answer generation, and collection stats. A minor gap exists for explicit deletion or direct full-text retrieval of a single paper, but these are likely workable through existing tools.
Maintenance
Related MCP Connectors
Academic literature search, retrieval, and private library management on top of OpenAlex.
Zotero MCP server for Claude and ChatGPT: search, citations, safe writes, PDF passages and pages.
Search arXiv/Semantic Scholar/OpenAlex + medical evidence (PubMed/Europe PMC) + LaTeX/PDF tools.
Federated search of books and papers, BibTeX/RIS citations, open-access retrieval and reading.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables semantic search and management of Zotero reference libraries using PostgreSQL with pg-vector and OpenAI/Ollama embeddings. Provides AI-powered search, full-text extraction, metadata access, annotations, notes, tags, and collections management.3MIT
- AlicenseCqualityDmaintenanceEnables interaction with Zotero libraries for searching, managing collections, items, tags, and attachments, plus optional semantic search across PDFs via local embeddings.382MIT
- AlicenseAqualityDmaintenanceEnables AI assistants to search, read, and manage Zotero references locally with customizable research workflows.941 PyPI4MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI assistants to search, access, and interact with your Zotero research library, including semantic search, metadata retrieval, PDF annotations, and library management.MIT