Atlas / MCP servers / introfini / ZotSeek

ZotSeekBLOCK

mcp/introfini/zotseek

AI semantic search for Zotero, with a built-in MCP server for AI agents (Claude Code, Codex). Find papers by meaning. 100% local and private.

Verdict
BLOCK
Grade
D
Trust score
69 /100
Exposed tools
3 3r · 0w · 0d
Transport
—
License
—
Stars
219
01

Overview

From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.

Find similar papers by meaning, not just keywords. 100% local, no data leaves your machine. Now with a built-in MCP server for AI agents.

Status: ✅ Stable release · Zotero 8, 9 & 10 · Transformers.js running locally New: 🤖 MCP server built in — Claude Code, Codex, and any MCP client can search your library and cite papers with links that open straight to the matched PDF page. Fully local, read-only, opt-in. Set it up in one line → New from the same author: 🔎 **citefact** — audit your manuscript against your Zotero library: citations exist, quotes are verbatim, claims are supported.

Features

  • 🔒 100% Local - No data sent to cloud, works completely offline
  • 🧠 True Semantic Search - Find papers by meaning, not just keywords
  • 🤖 AI Agent Access (MCP) - Let Claude Code and other MCP clients search your library, fully local and opt-in (docs)
  • 🔍 Find Similar Documents - Right-click any paper → discover related research
  • 📖 Search from PDF Selection - Select text while reading → right-click → find documents about that concept
  • 🔎 Natural Language Search - Search with queries like "machine learning in healthcare"
  • 🔀 Multi-Query Search - Combine up to 4 queries with AND/OR logic to find topic intersections
  • 📝 Your Notes, Searched Too - Optionally index the text of notes attached to an item, so what you wrote is findable alongside the paper itself; off by default, and existing items are back-filled on demand
  • 🕘 Recent Searches - The search window remembers your last 10 queries, so you can go back to a phrasing that worked; clear the list from the dropdown at any time
  • 🔗 Hybrid Search - Combines AI and keyword search, with the keyword half reading PDF text and note content, not
Read from source at commit 51c2ed268e21OBSERVED · 2026-10-06
02

Connect

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.

claude-code
claude mcp add zotseek -- npx -y [email protected]
claude-desktop
{
  "mcpServers": {
    "zotseek": {
      "command": "npx",
      "args": [
        "-y",
        "[email protected]"
      ]
    }
  }
}
03

Exposed tools (3)

3 read · 0 write · 0 destructive.

ToolRiskDescription
find_similarreadFind papers similar to a known library item, using its stored
index_statusreadReport ZotSeek index status: number of indexed papers, total chunks,
searchreadSemantic search over the user
04

Trust audit

BLOCKgrade D · trust 69/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.

LayerWhat it checksResult
L0Provenance & inventoryPASS
L1Static analysis of the codeFAIL
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfacePASS
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
declared (7 observation(s))
Network
declared (9 observation(s))
Shell
declared (6 observation(s))
Dependencies
not all pinned
Secrets in source
none-found

Findings (17)

HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
content/wasm/ort-wasm-simd-threaded.jsep.mjs:80
function Ec(a){return Sd(b=>{a().then(b)})}function Lb(a){a>>>=0;return Ec(async()=>{var b=await W(a);return X(b)})}var Xd=[];function Mb(a,b,c,d){c>>>=0;d>>>=0;a=Xd[a>>>0];b=W(b>>>0);return a(null,b,
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
MEDIUMNetwork egress · net.beacon_words · CWE-200, CWE-319
src/dev/suites/task-37a-model-registry.ts:36
assertTrue(!isAllowedHfPath('evil/exfiltrator'), 'should reject non-registry hfPath');
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
content/preferences.xhtml:231
<html:input type="text" id="zotseek-server-url" placeholder="http://127.0.0.1:1234" style="width: 220px;" />
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
src/core/model-registry.ts:24
baseUrl?: string;          // e.g. 'http://127.0.0.1:1234' (loopback enforced at request time)
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
src/dev/suites/mcp-server.ts:313
const resp = await fetch(`http://127.0.0.1:${port}/zotseek/mcp`, {
LOWInventory / provenance · inv.no_license · CWE-1104
Why it matters. no LICENSE file and no repo licence
Fix. add a licence
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
src/dev/suites/mcp-server.ts:11
import { handleMcpRequest } from '../../server/mcp-endpoint';
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
src/dev/suites/mcp-server.ts:12
import { handleSearchRequest, handleStatsRequest } from '../../server/rest-endpoints';
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
src/dev/suites/mcp-server.ts:13
import { handleOpenRequest, parseOpenParams, buildZoteroUri } from '../../server/open-endpoint';
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
src/dev/suites/mcp-server.ts:14
import { registerEndpoints, isRegistered, unregisterEndpoints } from '../../server/server-manager';
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
src/dev/suites/mcp-server.ts:15
import { searchEngine } from '../../core/search-engine';
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
README.md:395
2. In Zotero, go to **Settings → ZotSeek → Local inference server** and enter the server URL, e.g. `http://127.0.0.1:1234`.
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
README.md:403
2. In **Settings → ZotSeek → Local inference server**, enter `http://127.0.0.1:11434`.
LOWObfuscation / stealth · obf.decode_call · CWE-506, CWE-94
src/core/vector-store-sqlite.ts:1645
const binary = atob(data);
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
package.json
@huggingface/transformers, zotero-plugin-toolkit, @types/node, archiver, bumpp, esbuild, typescript
Why it matters. 7 dependency range(s) float
Fix. pin exact versions or ship a lockfile
INFOInventory / provenance · inv.oversize · CWE-1104
content/wasm/ort-wasm-simd-threaded.jsep.wasm
content/wasm/ort-wasm-simd-threaded.jsep.wasm
Why it matters. 21596019 bytes not read
INFOPrompt injection · prompt.persistence · CWE-94, CWE-1427
docs/DEVELOPMENT.md:998
# Add to ~/.zshrc or ~/.bashrc
Why it matters. instructs the agent to persist itself in the user's environment

Gates applied: no_behavioural_pass, no_license.

Audited 2026-10-06 · audit v0.4.1 · source sha 51c2ed268e21full audit observations/trust-audit/mcp-server/introfini__zotseek.json · Report an issue / request a re-scan
05

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-10-0651c2ed268e21BLOCKD69first audit
06

Questions

What is the ZotSeek MCP server?

AI semantic search for Zotero, with a built-in MCP server for AI agents (Claude Code, Codex). Find papers by meaning. 100% local and private.

What tools does ZotSeek expose?

3 in total: 3 read-only, 0 that write, and 0 that can delete or overwrite. Every one is listed on this page with its risk.

Is ZotSeek safe to connect to an agent?

No — not without reading the findings first. The audit graded it D (69/100) and found 1 critical or high issue in the source. Each one is listed on this page with the file and line it is on.

What credentials does ZotSeek need?

No credential environment variables were found in its source, so it appears to need none.

How current is this page?

The grade is for one exact copy of the source (51c2ed268e21), read on 2026-10-06. The repository is watched and re-audited when it changes.

Advertisement