-
Notifications
You must be signed in to change notification settings - Fork 0
Installation
Not sure which Claude you have? If you use Claude in a browser or a desktop application, this
is your section. If you type claude into a terminal, skip to
Claude Code.
-
Download the server you want. Each link saves the file straight to your computer:
Server What it does Download scholar-nulissearch literature, verify citations scholar-nulis-0.8.0.mcpb zotero-nulisread your own Zotero library zotero-nulis-0.7.0.mcpb scr-toolkit-nulisdeterministic scoping-review checks scr-toolkit-nulis-2.0.0.mcpb -
Double-click the file. Claude Desktop opens an install window. (Alternative: Settings → Extensions, then drag the file in.)
-
Fill in the configuration fields if you need them — all optional for
scholar-nulis, andscr-toolkit-nulishas none at all. -
Click Install, then quit Claude Desktop completely and reopen it.
Closing the window is not enough; servers are only re-read when the application actually restarts. On macOS, make sure the icon is gone from the Dock (⌘Q).
Nothing needs to be installed first. Claude Desktop ships its own Node.js.
Every tool name now begins with nulis_ — nulis_search_arxiv,
nulis_zotero_search_items, nulis_pdf_integrity, and so on. This is a breaking change,
and it exists because Claude Desktop presents tool names flat: there is no per-server
namespace like Claude Code's mcp__scholar__. Two extensions that both register
search_arxiv therefore collide, and which one wins is not predictable. Measured on one
real machine, this repo's servers shared nine tool names with unrelated MCP servers
already installed; after the prefix, zero.
You do not need to change how you talk to Claude — it reads the tool list itself. Only scripts or written instructions that name a tool literally need updating.
These servers were previously called scholar-paper-search, zotero-mcp, and
scr-toolkit. Claude Desktop identifies an extension by the name in its manifest, so a
renamed server is a different extension as far as it is concerned — installing the new
one does not replace the old one, and you will end up with both, exposing duplicate tools.
Remove the old entries first in Settings → Extensions, then install these. The
suffix exists precisely to stop this kind of ambiguity: scholar is a common enough name
that a second, unrelated MCP server may well already be using it.
git clone https://github.com/nulis-not-just-writing/mcp-writing-toolkit.git
cd mcp-writing-toolkit
# scholar
cd scholar-nulis && npm install && npm run build && cd ..
claude mcp add scholar -- node "$PWD/scholar-nulis/dist/index.js"
# zotero
cd zotero-nulis && npm install && npm run build && cd ..
claude mcp add zotero -- node "$PWD/zotero-nulis/dist/index.js"
# scr-toolkit-nulis — no dependencies, so no npm install and no build
claude mcp add scr-toolkit -- node "$PWD/scr-toolkit-nulis/server/index.js"To pass configuration, use -e before --:
claude mcp add scholar \
-e CONTACT_EMAIL=you@university.edu \
-e SCOPUS_API_KEY=xxxxx \
-- node "$PWD/scholar-nulis/dist/index.js"Check the result with /mcp inside a Claude Code session.
scr-toolkit-nulis has no configuration fields at all — install and use. The other two read
theirs only from environment variables; in Claude Desktop, manifest.json populates
them from the extension form, so you never touch them.
There is no .env file. No server here reads one. If you find older instructions
telling you to copy .env.example, they belong to the previous Python-based pack and no
longer apply.
| Field / variable | Required | Effect when set |
|---|---|---|
CONTACT_EMAIL |
no | Joins the Crossref & OpenAlex polite pool (higher quota) and adds the Unpaywall route for open-access lookup, which additionally reports each PDF's licence. Any working address; no registration. |
S2_API_KEY |
no | Raises the Semantic Scholar rate limit. Free at semanticscholar.org/product/api. |
DOWNLOAD_DIR |
no | Where PDFs are stored. If empty: ~/Downloads, then the system temp folder if ~/Downloads is not writable. |
SCOPUS_API_KEY |
no | Switches on nulis_search_scopus, nulis_scopus_abstract, nulis_scopus_export_csv, nulis_elsevier_status. |
SCIENCEDIRECT_API_KEY |
no | Switches on nulis_sciencedirect_fulltext. Leave empty if your Scopus key already covers it. |
ELSEVIER_INSTTOKEN |
no | Institutional token from your librarian or licence admin. Needed only when off-campus access is refused with 401/403. |
Elsevier keys are free to register with an institutional account at dev.elsevier.com. The quota is tied to your campus subscription.
| Field / variable | Required | Effect |
|---|---|---|
ZOTERO_LOCAL |
no |
true is the default — talks to the Zotero app on this computer. |
ZOTERO_API_KEY |
Web API mode | Key from zotero.org/settings/keys. |
ZOTERO_LIBRARY_ID |
Web API mode | Your user ID, on the same page. |
ZOTERO_LIBRARY_TYPE |
Web API mode |
user or group. |
Local mode needs one step inside Zotero: open Zotero → Settings → Advanced → tick "Allow other applications on this computer to communicate with Zotero". Without it the server will report that Zotero is unreachable.
The Zotero application must be running when a tool is called.
Fields marked sensitive in the extension window are stored by Claude Desktop in your operating system keychain, not as plain text.
If you build the variant bundle with an embedded key for a team
(scholar-nulis/build-team-bundle.sh), remember that the resulting file carries that key
inside its manifest. That bundle must never be uploaded anywhere public; this repo's
.gitignore already refuses it through the *-api.mcpb pattern, and build-mcpb.sh
refuses to publish any bundle whose manifest carries a literal key.
./build-mcpb.sh # all three
./build-mcpb.sh zotero-nulis # just oneOutput goes to dist/<name>-<version>.mcpb. The script stops and deletes any bundle
that fails a gate — a broken bundle left lying in dist/ will eventually be distributed by
accident.
The gates:
- The
manifest.jsonversion must matchpackage.json(for servers that have one). - The version the server announces over an MCP handshake must match its manifest. This gate runs the packed server and asks it directly — a version hardcoded in source is exactly the kind of drift a file-level check misses, and it really did happen to all three servers in this repo.
-
NOTICE.mdmust be inside the bundle — attribution for bundled libraries has to travel with every copy, and a.mcpbdownloaded on its own does not carry the repo. - No
node_modules/,src/,.env, or junk files. - No literal credential values in
mcp_config.env.
Servers without a package.json (like scr-toolkit-nulis) are packed as-is with no build step;
the gate then confirms the entry_point named in the manifest actually exists.
← Back · scholar · zotero · scr-toolkit · FAQ
Knowledge unshared dies. Knowledge shared keeps living.
It grows in hands you will never meet and is carried on in work you will never read — and what never stops living never stops returning to you.
Mubaroq ADB · Akademi Digital Bandung | RPI Institute · mubaroq@digitalbdg.ac.id
Mirror of docs/ — do not edit here; edit in the repository. ·
Cerminan docs/, jangan disunting di sini. · CC BY-NC 4.0
Start
Servers
More