Perspicacité exposes 27 tools via the Model Context Protocol at
http://localhost:5468/mcp (streamable-HTTP transport, port from config.yml).
To connect from Claude Code:
{
"mcpServers": {
"perspicacite": {
"type": "http",
"url": "http://localhost:5468/mcp"
}
}
}For other MCP clients (Mimosa-AI, SmolAgents, Cursor), use the same URL.
Search academic databases (requires SciLEx).
Parameters:
query(str) — search querymax_results(int, default 10) — maximum papers to returnmin_year(int, optional) — year lower boundmax_year(int, optional) — year upper boundarticle_type(str, optional) — e.g.,"journal-article"databases(list[str], optional) — which SciLEx databases to search
Returns: JSON array of paper objects.
Fetch the full text and sections for a paper by DOI.
Parameters:
doi(str) — the DOI
Returns: {doi, title, content_type, full_text, sections, references, ...}
Extract cited references from a paper.
Parameters:
doi(str)
Returns: list of reference objects with titles, DOIs, and years.
Score a list of candidate papers for relevance to a query.
Parameters:
query(str)papers(list) — candidate paper objectsmethod(str, default"bm25") —"bm25"or"llm"threshold(float, default 0.3) — minimum score
Returns: filtered + scored list.
List all KBs with paper counts, embedding model, and creation time.
Parameters: none.
Create a new knowledge base.
Parameters:
name(str)description(str, optional)
Permanently delete a KB (metadata + Chroma collection).
Parameters:
kb_name(str)
Add papers to a KB with auto-download and indexing.
Parameters:
kb_name(str)papers(list) — paper objects with at leasttitleanddoi
Bulk-add papers to a KB from a list of DOIs (max 200 per call).
Parameters:
kb_name(str)dois(list[str])
Semantic + BM25 hybrid search within a KB.
Parameters:
kb_name(str)query(str)top_k(int, default 10)
Returns: list of matching chunks with paper metadata and scores.
Score all KBs for relevance to a query and return a ranked list. Use for
introspection or to pass kb_names to generate_report without running synthesis.
Parameters:
query(str)method(str, default"bm25") —"bm25"or"llm"top_k(int, default 3)
Ingest local PDFs or documents from a server-side path.
Parameters:
kb_name(str)path(str) — must be under alocal_docs.allowed_rootsentry
Synthesize a research report using RAG.
Parameters:
query(str)kb_name(str, optional) — use"auto"for routingkb_names(list[str], optional) — multi-KB alternativemode(str, default"basic") — RAG mode
Returns: {answer, sources, mode, latency_ms, provenance}
Search SciLEx, filter, screen, fetch PDFs, and ingest into a KB in one call.
Parameters:
query(str)kb_name(str) — new or existing KB namemax_results(int, default 10)min_year(int, optional)min_citations(int, optional)screen_method(str, optional) —"bm25"or"llm"screen_threshold(float, default 0.3)
Grow a KB by following citation links from its existing papers.
Parameters:
kb_name(str)direction(str, default"both") —"forward","backward", or"both"max_per_seed(int, default 50)min_year(int, optional)min_citations(int, optional)screen_method(str, optional)screen_threshold(float, default 0.3)
Update citation metadata for papers already in a KB without adding new papers.
Parameters:
kb_name(str)
Build a capsule for a single paper (figures, references, code, SI).
Parameters:
paper_id(str) — DOI, PMID, or internal UUIDkb_name(str)force(bool, default false) — rebuild if capsule already exists
Build capsules for all papers in a KB (idempotent).
Parameters:
kb_name(str)force(bool, default false)
Fetch external resources (GitHub, Zenodo, Crossref) for a paper.
Parameters:
paper_id(str)kb_name(str)
Download Supplementary Information files for a paper.
Parameters:
paper_id(str)kb_name(str)
Export a KB as BibTeX or Obsidian vault.
Parameters:
kb_name(str)format(str) —"bibtex"or"obsidian-vault"with_pdfs(bool, default false)
Push papers to Zotero by DOI list, with optional PDF and SI attachment.
Parameters:
dois(list[str])attach_pdf(bool, default false)attach_supplementary(bool, default false)
Build one KB per Zotero top-level collection.
Parameters:
library_id(str, optional) — override config default
import httpx
# Initialize session
r = httpx.post("http://localhost:5468/mcp", json={
"jsonrpc": "2.0", "id": 1, "method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {},
"clientInfo": {"name": "my-agent", "version": "1.0"}
}
}, headers={"Content-Type": "application/json", "Accept": "application/json, text/event-stream"})
session_id = r.headers["mcp-session-id"]
# Call a tool
r = httpx.post("http://localhost:5468/mcp", json={
"jsonrpc": "2.0", "id": 2, "method": "tools/call",
"params": {
"name": "search_knowledge_base",
"arguments": {"kb_name": "my-kb", "query": "diamond magnetometry", "top_k": 5}
}
}, headers={
"Content-Type": "application/json",
"Accept": "application/json, text/event-stream",
"Mcp-Session-Id": session_id
})List all Zotero library collections as a nested tree.
Parameters:
library_id(str, optional) — override configured library_idinclude_subcollections(bool, default true) — return nested tree
Returns: {collections: [{id, name, parent_id, item_count, subcollections}], library_id, library_type}
Cache: 1-hour in-memory cache keyed on (library_id, library_type).
Errors: ZOTERO_NOT_CONFIGURED, ZOTERO_AUTH_FAILED, ZOTERO_RATE_LIMITED, LIBRARY_NOT_FOUND
Return papers in a collection with metadata and per-paper license classification.
Parameters:
collection_id(str) — Zotero collection keylibrary_id(str, optional)include_abstract(bool, default true)limit(int, default 200, max 500)cursor(str, optional) — pagination token from previous call'snext_cursor
Returns: {collection_id, items: [{zotero_key, doi, title, authors, year, abstract, item_type, tags, license: {spdx, classification, policy, source}, has_attachments}], total, next_cursor}
License policy: classification=permissive → policy=verbatim (text may be copied verbatim); classification=closed|unknown → policy=reflavor (must paraphrase).
License resolution chain: Crossref → OpenAlex → Zotero tags → heuristic (is_oa flag).
Errors: ZOTERO_NOT_CONFIGURED, ZOTERO_AUTH_FAILED, ZOTERO_RATE_LIMITED, COLLECTION_NOT_FOUND, INVALID_CURSOR
Return ordered file access options for a single paper. Local paths come first (Perspicacité's PDF cache and capsule supplementary-file storage); remote URLs follow.
Parameters:
doi(str, optional) — the paper's DOIzotero_key(str, optional) — Zotero item key; use when DOI is ambiguouslibrary_id(str, optional)
Exactly one of doi or zotero_key must be provided.
Returns: {doi, zotero_key, license: {...}, resources: [{role, filename, access: [{type, path|url, via?}]}], notes: [str]}
role values: fulltext_pdf, supplementary, note. Access type: local (on-disk path) or remote (URL + via label: publisher, doi_resolver).
Errors: ZOTERO_NOT_CONFIGURED, ZOTERO_AUTH_FAILED, ZOTERO_RATE_LIMITED, PAPER_NOT_FOUND, AMBIGUOUS_DOI
Ingest a Zotero collection into a Perspicacité KB. Returns immediately with a job_id when running under the full web server (poll poll_url for SSE completion events); runs inline in MCP-only mode.
Parameters:
collection_id(str) — Zotero collection keykb_name(str, optional) — KB name; defaults to sanitized collection namelibrary_id(str, optional)force_reingest(bool, default false) — re-embed already-indexed papers
Returns (async mode): {job_id, kb_name, collection_id, item_count, status: "running", poll_url}
Returns (inline mode): {per_kb: [...]}
After the job completes, use search_knowledge_base or generate_report with the returned kb_name.
Errors: ZOTERO_NOT_CONFIGURED, ZOTERO_AUTH_FAILED, ZOTERO_RATE_LIMITED, COLLECTION_NOT_FOUND
- reference/rest-api.md — REST equivalents
- reference/cli.md — CLI equivalents
- concepts/rag-modes.md — mode selection for
generate_report - concepts/citation-graph.md — how
expand_kb_via_citationsworks