Content
# scholar-paper-cli
[](https://github.com/TudeOrangBiasa/scholar-paper-cli/actions/workflows/ci.yml)
spm — CLI for Semantic Scholar. 15 commands, persistent SQLite cache, offline fallback, multilingual semantic search.
Pairs with the `writing-for-agents` skill for hackathon, proposal, thesis, and article workflows.
## Features
- 15 commands: paper/author search, details, citations, references, recommendations, related, session tracking, BibTeX export
- Persistent SQLite cache with 30-day TTL. Repeat queries cost zero.
- Offline fallback: when Semantic Scholar is unreachable, return cached data with offline flag.
- Multilingual semantic search via `intfloat/multilingual-e5-small` (100+ languages including Indonesian).
- Portable CLI: JSON on stdout, pipeable, scriptable, works in any agent that can run bash and in a plain terminal.
## Install
Requires Python 3.13 and uv.
```bash
git clone https://github.com/TudeOrangBiasa/scholar-paper-cli
cd scholar-paper-cli
uv sync
# The embedding model is not bundled. Download once (~135MB) for --embed/related:
# See models/README.md for details
```
## Run
```bash
spm --help
spm search "quantum entanglement" --limit 2
```
Every command prints a JSON `{"data": ..., "meta": ...}` envelope on stdout. Errors print `{"error": {"type", "message"}}` with a non-zero exit code.
## Skills
Install the bundled skills via the Vercel skills CLI:
```bash
npx skills add https://github.com/TudeOrangBiasa/scholar-paper-cli -s spm -s writing-for-agents -g --copy
```
- `spm` (`skills/spm/SKILL.md`): teaches the CLI, commands, output contract, caching, embeddings
- `writing-for-agents` (`skills/writing-for-agents/SKILL.md`): reference for writing agent-facing docs
The skill documents every command, the output contract, caching semantics, embeddings, and workflow recipes.
## Commands (15)
| Command | Flags (defaults) | Description |
|---------|------------------|-------------|
| `spm search <query>` | `--limit` (10), `--offset` (0) | Search papers by query |
| `spm paper <id>` | `--embed` | Get paper by ID, persists + embeds |
| `spm citations <id>` | `--limit` (100), `--offset` (0) | Papers that cite this paper |
| `spm references <id>` | `--limit` (100), `--offset` (0) | Papers referenced by this paper |
| `spm author-search <query>` | `--limit` (10), `--offset` (0) | Search authors by name |
| `spm author <id>` | — | Get author by ID, persists |
| `spm author-top <id>` | `--limit` (10) | Top papers by citation count |
| `spm author-duplicates <query>` | `--limit` (50), `--threshold` (0.8) | Group authors by name similarity |
| `spm consolidate <canonical> <dup>...` | — | Merge duplicate authors in storage |
| `spm recommend <id>` | `--limit` (100) | SS API recommendations |
| `spm related <id>` | `--k` (10) | Local KNN via semantic embeddings |
| `spm session add <session> <id>` | — | Track paper in working session |
| `spm session list <session>` | — | List papers in session |
| `spm session remove <session> <id>` | — | Remove paper from session |
| `spm bibtex <session>` | — | Export session as BibTeX |
Every command returns a `ToolResponse` with `data` and `meta` (cache metadata: source, cached, offline, fetched_at, ttl_until).
## Configuration
See [docs/CONFIGURATION.md](docs/CONFIGURATION.md) for all `SPM_*` environment variables.
## Command call flow
A command follows this sequence:
1. **Shell/agent** runs `spm <command>`.
2. **cli.py** parses args and assembles state (cache dir, SQLite, API client, optional embedder).
3. **Tool function** composes `CachedSemanticScholarClient` + storage CRUD + (optionally) embedder.
4. **Cache check**: fresh hit returns cached data. Stale or miss triggers step 5.
5. **API call** (if online): SS API via rate-limited, circuit-broken, offline-aware client.
6. **Persist**: paper, author, citation, session rows written to SQLite. Embedding stored in `embeddings_vec`.
7. **Wrap**: response enveloped as `ToolResponse[data, meta]`, printed as JSON on stdout.
See [PHILOSOPHY.md](PHILOSOPHY.md) for why the project is designed this way, and [docs/PLAN.md](docs/PLAN.md) for the original plan.
## Development
```bash
uv run pytest # all tests
uv run ruff check # lint
uv run ty check # type check
uv run ruff format # auto-format
```
See [docs/PLAN.md](docs/PLAN.md) for the full plan, [docs/WORKFLOW.md](docs/WORKFLOW.md) for document-writing integration, [docs/CONFIGURATION.md](docs/CONFIGURATION.md) for env vars.
## Status
v0.1.0 feature-complete. 14 of 14 planned issues done. Security review applied: 0 CRITICAL, 0 HIGH, 0 MEDIUM.
Future work is open-ended. See [docs/PLAN.md](docs/PLAN.md) for the original plan and the one deferred item: cross-encoder rerank (v3 in the plan, blocked by bundle size and missing Indonesian benchmark for any small multilingual cross-encoder).
## Acknowledgments
- **Semantic Scholar** (Allen AI) for the Graph API and the public dataset of ~200M academic papers.
- **[akapet00/semantic-scholar-mcp](https://github.com/akapet00/semantic-scholar-mcp)** for the upstream reference. The 15 command set mirrors the original 15 tools.
- **argparse (stdlib)** for the CLI interface.
- Open source libraries: Pydantic, httpx, sqlite-vec, ONNX Runtime, tokenizers, pytest, ruff, ty.
- Embedding model: [intfloat/multilingual-e5-small](https://huggingface.co/intfloat/multilingual-e5-small) (MIT license).
## How to contribute
See [CONTRIBUTING.md](CONTRIBUTING.md) for the full guide: working rules, coding standards, and the pull request format.
1. Check [docs/PLAN.md](docs/PLAN.md) for the project plan and any open work.
2. Read [AGENTS.md](AGENTS.md) and [CONTRIBUTING.md](CONTRIBUTING.md) for conventions (TDD, ponytail, anti-AI-slop rules).
3. Open an issue describing the change.
4. Write tests first, then minimum code, then open a PR using [the template](.github/PULL_REQUEST_TEMPLATE.md). Title format: `type(scope): short description` (e.g. `feat(api): add batch search endpoint`).
5. All four gates must pass before the PR merges: `uv run pytest`, `uv run ruff check src tests`, `uv run ty check src tests`, `uv run ruff format --check src tests`.
## License
MIT. See [LICENSE](LICENSE).
Connection Info
You Might Also Like
Filesystem
Node.js MCP Server for filesystem operations with dynamic access control.
Fetch
Retrieve and process content from web pages by converting HTML into markdown format.
Agent-Reach
Give your AI agent eyes to see the entire internet. Read & search Twitter,...
Context 7
Context7 MCP provides up-to-date code documentation for any prompt.
context7-mcp
Context7 MCP Server provides natural language access to documentation for...
mempalace
The highest-scoring AI memory system ever benchmarked. And it's free.