Skip to main content
Glama
yipihey

SciX Client

by yipihey

scix-client

A Rust client for the SciX (formerly NASA ADS) API.

Four ways to use it:

Mode

What it does

Rust library (scix_client)

Async Rust crate — add to your Cargo.toml

Python library (scix_client)

Native Python module — pip install . via maturin

CLI (scix)

Command-line tool for your terminal

MCP server (scix serve)

Expose SciX tools to Claude, Cursor, Zed, etc.

One binary (scix) does everything. The MCP server is scix serve. Python bindings are auto-generated from the Rust types — zero extra maintenance.

Prerequisites

You need a SciX / ADS API token. Get one (free) at: https://ui.adsabs.harvard.edu/user/settings/token

Then export it:

export SCIX_API_TOKEN="your-token-here" # or, for backwards compatibility: export ADS_API_TOKEN="your-token-here"

Installation

CLI / MCP binary (from source)

cargo build --features cli --release cp target/release/scix ~/.local/bin/ # or anywhere on your PATH

As a Rust dependency

[dependencies] scix-client = { git = "https://github.com/yipihey/scix-client", version = "0.1" }

Python (via maturin)

cd scix-client pip install maturin maturin develop # install into current virtualenv for development # or maturin build --release # build a wheel in target/wheels/ pip install target/wheels/scix_client-*.whl

Requires Python 3.8+ and a Rust toolchain.


MCP Server Setup

scix serve speaks MCP (Model Context Protocol) over stdio, giving AI assistants direct access to the SciX API. It's the same scix binary — no separate install needed.

Claude Code (CLI)

claude mcp add scix -- /path/to/scix serve

Or add manually to ~/.claude/settings.json:

{ "mcpServers": { "scix": { "command": "/path/to/scix", "args": ["serve"], "env": { "SCIX_API_TOKEN": "your-token-here" } } } }

Claude Desktop

Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{ "mcpServers": { "scix": { "command": "/path/to/scix", "args": ["serve"], "env": { "SCIX_API_TOKEN": "your-token-here" } } } }

Cursor

In Cursor Settings > MCP, add:

{ "mcpServers": { "scix": { "command": "/path/to/scix", "args": ["serve"], "env": { "SCIX_API_TOKEN": "your-token-here" } } } }

Zed

In Zed settings (settings.json):

{ "context_servers": { "scix": { "command": { "path": "/path/to/scix", "args": ["serve"], "env": { "SCIX_API_TOKEN": "your-token-here" } } } } }

Verify it works

# Should print the tool list as JSON echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"0.1"}}} {"jsonrpc":"2.0","method":"notifications/initialized"} {"jsonrpc":"2.0","id":2,"method":"tools/list"}' | SCIX_API_TOKEN=your-token scix serve

Available MCP Tools

Tool

Description

scix_search

Full-text search with SciX query syntax

scix_bigquery

Search within a set of known bibcodes

scix_export

Export in 17 citation formats (BibTeX, RIS, AASTeX, ...)

scix_metrics

h-index, g-index, citation counts, indicators

scix_library

Create/list/edit/delete personal SciX libraries

scix_library_documents

Add/remove papers from libraries

scix_citation_helper

Find co-cited papers you might be missing

scix_network

Author collaboration & paper citation networks

scix_object_search

Resolve object names (M31, NGC 1234) via SIMBAD/NED

scix_resolve_reference

Convert free-text citations to bibcodes

scix_resolve_links

Resolve full-text, data, and reference links

MCP Resources

URI

Content

scix://fields

Searchable and returnable field names

scix://syntax

Query syntax quick reference


CLI Examples

All examples assume SCIX_API_TOKEN (or ADS_API_TOKEN) is set in your environment.

Searching

# Basic search scix search "dark matter" # Search by author scix search 'author:"Einstein"' # Author + year range scix search 'author:"Weinberg" year:[1965 TO 1975]' # First-author search, most cited first scix search 'first_author:"Perlmutter" supernova' --sort "citation_count desc" # Title search scix search 'title:"cosmological constant problem"' # Abstract search scix search 'abs:"gravitational waves" year:2016' # Combine fields with boolean operators scix search 'author:"Hawking" AND title:"black hole" AND year:[1970 TO 1980]' # Refereed papers only scix search 'author:"Witten" property:refereed' --rows 20 # Papers about an astronomical object scix search 'object:"Crab Nebula" year:[2020 TO 2025]' # Search by journal (bibstem) scix search 'bibstem:ApJ year:2024 title:"exoplanet atmosphere"' # Search by DOI scix search 'doi:"10.1103/PhysRevLett.116.061102"' # Search by arXiv ID scix search 'identifier:arXiv:1602.03837' # Search by ORCID scix search 'orcid:0000-0002-1825-0097' # Open access papers only scix search 'title:"machine learning" AND property:openaccess year:2024' # Get more results scix search "galaxy clusters weak lensing" --rows 50 # Output as JSON (for scripting) scix search 'author:"Planck Collaboration" year:2018' --output json # Custom fields scix search 'author:"Einstein" year:1905' --fields "bibcode,title,citation_count"

Exporting citations

# BibTeX (default) scix export 2023ApJ...123..456A # Multiple papers scix export 2023ApJ...123..456A 2024MNRAS.789..012B 1998AJ....116.1009R # Different formats scix export 2023ApJ...123..456A --format bibtex scix export 2023ApJ...123..456A --format aastex scix export 2023ApJ...123..456A --format mnras scix export 2023ApJ...123..456A --format ris scix export 2023ApJ...123..456A --format ieee scix export 2023ApJ...123..456A --format endnote # Save to file scix export 2023ApJ...123..456A 2024MNRAS.789..012B --format bibtex > refs.bib # Pipe a search into an export (with jq) scix search 'author:"Einstein" year:1905' --output json \ | jq -r '.papers[].bibcode' \ | xargs scix export --format bibtex

References and citations

# Papers referenced by a paper scix refs 2023ApJ...123..456A # Papers that cite a paper scix cites 2023ApJ...123..456A # Show more results scix refs 1998AJ....116.1009R --rows 100 # Similar papers (content-based) scix similar 2023ApJ...123..456A # JSON output for further processing scix cites 2023ApJ...123..456A --output json | jq '.papers | length'

Citation metrics

# Metrics for one paper scix metrics 2023ApJ...123..456A # Metrics for a set of papers (h-index, g-index, etc.) scix metrics 2023ApJ...123..456A 2024MNRAS.789..012B 1998AJ....116.1009R

Sample output:

{ "basic_stats": { "total": { "number_of_papers": 3, "total_citations": 5821 } }, "indicators": { "h": 3, "g": 3, "i10": 3, "tori": 142.7 } }

Resolving references

# Free-text reference to bibcode scix resolve "Einstein 1905 Annalen der Physik 17 891" # Multiple references scix resolve \ "Perlmutter et al. 1999 ApJ 517 565" \ "Riess et al. 1998 AJ 116 1009" # JSON output scix resolve "Weinberg 1989 Rev Mod Phys 61 1" --output json

Astronomical objects

# Find papers about an object scix objects "M31" # Multiple objects scix objects "M31" "NGC 1234" "Crab Nebula"
# All links for a paper (full-text, data, etc.) scix links 2023ApJ...123..456A # Specific link type scix links 2023ApJ...123..456A --link-type esource scix links 2023ApJ...123..456A --link-type data

Library management

# List your libraries scix libraries list # Get library details (includes bibcodes) scix libraries get abc123def # Create a library scix libraries create "My Reading List" --description "Papers to read this week" # Create a public library scix libraries create "Dark Energy Review" --description "Key papers" --public # Delete a library scix libraries delete abc123def # JSON output scix libraries list --output json

MCP server

# Start MCP server (reads JSON-RPC from stdin, writes to stdout) scix serve

This is the same entry point used by Claude, Cursor, Zed, etc. (see MCP Server Setup above).


Library Usage (Rust)

use scix_client::SciXClient; #[tokio::main] async fn main() -> scix_client::error::Result<()> { let client = SciXClient::from_env()?; let results = client.search("author:\"Einstein\" year:1905", 10).await?; for paper in &results.papers { println!("{} ({}) — {} citations", paper.title, paper.year.unwrap_or(0), paper.citation_count.unwrap_or(0), ); } Ok(()) }

Query builder

use scix_client::{SciXClient, QueryBuilder}; let query = QueryBuilder::new() .first_author("Weinberg") .and() .title("cosmological constant") .and() .property("refereed") .build(); // → first_author:"Weinberg" AND title:"cosmological constant" AND property:refereed let results = client.search(&query, 20).await?;

Export BibTeX

let bibtex = client.export_bibtex(&["2023ApJ...123..456A", "1998AJ....116.1009R"]).await?; println!("{}", bibtex); // Other formats use scix_client::ExportFormat; let ris = client.export(&["2023ApJ...123..456A"], ExportFormat::Ris, None).await?;

References and citations

let refs = client.references("2023ApJ...123..456A", 50).await?; let cites = client.citations("2023ApJ...123..456A", 50).await?; let similar = client.similar("2023ApJ...123..456A", 10).await?;

Metrics

let metrics = client.metrics(&["2023ApJ...123..456A"]).await?; if let Some(indicators) = &metrics.indicators { println!("h-index: {:?}", indicators.h); }

Custom base URL (for testing)

let client = SciXClient::new("my-token") .with_base_url("https://api.scixplorer.org/v1");

Library Usage (Python)

The Python module is auto-generated from the Rust crate via PyO3 + maturin. All types, fields, and methods are derived directly from the Rust source — no separate Python code to maintain.

import scix_client # Create client (reads SCIX_API_TOKEN or ADS_API_TOKEN env var) client = scix_client.SciXClient() # or: client = scix_client.SciXClient("your-token") results = client.search('author:"Einstein" year:1905', rows=10) for paper in results.papers: print(f"{paper.title} ({paper.year}) — {paper.citation_count} citations") for author in paper.authors: print(f" {author.display_name()}") print(f"Total: {results.num_found} papers found")

Query builder

q = scix_client.QueryBuilder() q.author("Weinberg") q.and_() q.title("cosmological constant") q.and_() q.property("refereed") results = client.search(q.build(), rows=20) # Static constructors q = scix_client.QueryBuilder.citations_of("2023ApJ...123..456A") results = client.search(q.build(), rows=100)

Export citations

# BibTeX (default) bibtex = client.export_bibtex(["2023ApJ...123..456A", "1998AJ....116.1009R"]) print(bibtex) # Other formats ris = client.export(["2023ApJ...123..456A"], format=scix_client.ExportFormat.Ris)

References, citations, and metrics

refs = client.references("2023ApJ...123..456A", rows=50) cites = client.citations("2023ApJ...123..456A", rows=50) similar = client.similar("2023ApJ...123..456A") metrics = client.metrics(["2023ApJ...123..456A"]) if metrics.indicators: print(f"h-index: {metrics.indicators.h}") print(f"g-index: {metrics.indicators.g}")

Libraries

# List your libraries for lib in client.list_libraries(): print(f"{lib.name}: {lib.num_documents} papers") # Create a library lib = client.create_library("My Reading List", description="Papers to read") client.add_documents(lib.id, ["2023ApJ...123..456A"])

Reference and object resolution

# Resolve free-text references resolved = client.resolve_references([ "Einstein 1905 Annalen der Physik 17 891", "Perlmutter et al. 1999 ApJ 517 565", ]) for ref in resolved: print(f"{ref.reference} → {ref.bibcode}") # Resolve astronomical objects (returns dict) objects = client.resolve_objects(["M31", "Crab Nebula"])

Sort control

sort = scix_client.Sort.citation_count_desc() results = client.search_with_options("dark matter", sort=sort, rows=20)

Available types

All types are auto-exposed with read-only field access:

Python class

Key fields

SciXClient

search(), export(), metrics(), ...

QueryBuilder

author(), title(), year(), build(), ...

Paper

bibcode, title, authors, year, doi, arxiv_id, ...

Author

name, family_name, given_name, display_name()

SearchResponse

papers, num_found

ExportFormat

BibTeX, Ris, AasTex, ... (17 formats)

Metrics

basic_stats, citation_stats, indicators

Indicators

h, g, i10, i100, m, tori, riq, read10

Sort

field, direction

Library

id, name, description, num_documents


Query Syntax Quick Reference

Pattern

Meaning

author:"Einstein"

Author search

first_author:"Einstein"

First author only

title:"dark matter"

Title words

abs:"gravitational waves"

Abstract words

full:"spectroscopy"

Full text

year:2023

Exact year

year:[2020 TO 2023]

Year range

bibcode:2023ApJ...

Bibcode

doi:"10.1234/..."

DOI

identifier:arXiv:2301.12345

arXiv ID

bibstem:ApJ

Journal abbreviation

object:"M31"

Astronomical object

orcid:0000-0002-...

ORCID identifier

property:refereed

Refereed papers

property:openaccess

Open access

doctype:article

Document type

Boolean operators: AND, OR, NOT, parentheses for grouping Functional operators: citations(bibcode:X), references(bibcode:X), similar(bibcode:X), trending(bibcode:X) Wildcards: author:"Eins*", title:galax?

Sort options: date desc (default), citation_count desc, score desc, read_count desc


Export Formats

Format

Flag

Description

bibtex

--format bibtex

BibTeX (default)

bibtexabs

--format bibtexabs

BibTeX with abstracts

aastex

--format aastex

AAS journals (ApJ, AJ, etc.)

icarus

--format icarus

Icarus journal

mnras

--format mnras

MNRAS journal

soph

--format soph

Solar Physics journal

ris

--format ris

RIS (Reference Manager)

endnote

--format endnote

EndNote

medlars

--format medlars

MEDLARS/PubMed

ieee

--format ieee

IEEE

csl

--format csl

CSL-JSON

dcxml

--format dcxml

Dublin Core XML

refxml

--format refxml

Reference XML

refabsxml

--format refabsxml

Ref + Abstract XML

votable

--format votable

VOTable

rss

--format rss

RSS feed

custom

--format custom

Custom format


Rate Limiting

The SciX API allows 5,000 requests/day and 5 requests/second. scix-client handles rate limiting automatically:

  • A token-bucket rate limiter enforces 5 req/s locally

  • Rate limit headers (x-ratelimit-remaining, x-ratelimit-reset) are respected

  • If rate-limited (HTTP 429), the error includes the retry-after duration


Architecture

┌──────────────────────────────────────────────┐ │ scix binary │ ← Single binary │ ┌────────────┐ ┌────────────┐ │ │ │ CLI (clap) │ │ MCP server │ │ scix search … / scix serve │ └────────────┘ └────────────┘ │ ├──────────────────────────────────────────────┤ │ Python bindings (PyO3) │ ← import scix_client │ ┌───────────────┐ ┌────────────────────┐ │ │ │ PySciXClient │ │ PyQueryBuilder │ │ Auto-generated from │ │ (sync wrapper)│ │ (mutation wrapper) │ │ Rust types via #[pyclass] │ └───────────────┘ └────────────────────┘ │ ├──────────────────────────────────────────────┤ │ scix_client Rust library │ ← Async Rust API │ ┌───────────┐ ┌──────────────┐ │ │ │ SciXClient│ │ QueryBuilder │ │ │ └───────────┘ └──────────────┘ │ │ ┌──────────┐ ┌──────────────┐ │ │ │ Parser │ │ Rate Limiter │ │ │ └──────────┘ └──────────────┘ │ ├──────────────────────────────────────────────┤ │ reqwest + tokio │ ← HTTP + async runtime └──────────────────────────────────────────────┘ │ ▼ SciX API (api.adsabs.harvard.edu/v1)

License

MIT

-
security - not tested
A
license - permissive license
-
quality - not tested

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/yipihey/scix-client'

If you have feedback or need assistance with the MCP directory API, please join our Discord server