OSCR

The command line (oscr)

oscr is OSCR's command line for researchers. From your terminal it links your repository to its paper, checks it the way the registry checks it, traces its lines to the paper's Methods, cites it, and works with its GitHub repository (the registry's view first). It is free and open (Apache-2.0), needs only Python and git, and never asks for, shows or keeps an email address.

What it is

The tool is for anyone who publishes research code: it brings OSCR's own checks, citations and tracing maps to where you work. It talks to GitHub directly with your own GitHub token(the registry never sees it) and to the registry with the registry's token, and for every action it shows the registry's own page first, GitHub's address only when the registry cannot show the thing. It uses the standard library only: once Python is there, nothing else is installed. The package on PyPI is openscicode; the command you type is oscr.

Install

With pipx (recommended: it gives the tool an environment of its own):

pipx install openscicode
oscr --version

Or with plain pip, or with uv:

pip install openscicode
# or
uv tool install openscicode

You need Python 3.10 or later and git. There is no other dependency. The short name oscr is already taken on PyPI by an unrelated project, so the distribution is called openscicode (it matches this site's domain); the command stays oscr. Every command has --help with examples, and oscr help <topic> opens the manual's topics (formatting, exit-codes, environment, repository, auth, safety, mcp).

Sign in

Reading the registry needs no account. Signing in lets you act as yourself: link a paper, open a research issue, create a repository. One command signs you in to both GitHub and the registry, each approved in your browser:

oscr auth login                  # GitHub, then the registry (both approved in your browser)
oscr auth login --github         # only GitHub
oscr auth login --oscr --scopes repos:read,research:write --days 90

Two credentials are obtained, by two separate device flows:

GitHub, through GitHub's own device flow
The tool asks GitHub directly, with the registry's GitHub App's public client id. You type the code on GitHub's page. Your GitHub token goes from GitHub to your keychain and never reaches the registry. It lives 8 hours; oscr auth refresh --github, or any command once it expired, renews it.
The registry, through its own device-code flow
The terminal prints the registry's approval page and an 8-letter code. On the page, signed in with ORCID, GitHub or Google, you type that code, read what the token may do and for how long, and approve or refuse. By default the token may repos:read and research:read for 90 days; --scopes and --days ask for others.

Both are kept only in your system's keychain: the macOS login keychain, or the Linux Secret Service (GNOME Keyring, KWallet) through secret-tool; a plain file only when you ask (--insecure-storage), with a warning each time. The rest of the auth commands:

CommandWhat it does
oscr auth statusWho is signed in, where each credential is kept, whether it still works (--offline to ask nothing).
oscr auth token --github|--oscrPrint the active token, for a script's environment.
oscr auth switchMake another signed-in account the active one.
oscr auth refreshRenew GitHub's token; approve the registry's again.
oscr auth logoutSign out: the registry's token revokes itself, both leave the keychain.
oscr auth setup-gitMake the tool git's credential helper, for GitHub's host only.

In a CI job, the environment variables OSCR_TOKEN (the registry's) and OSCR_GITHUB_TOKEN or GH_TOKEN (GitHub's) win over the keychain, so no browser is needed.

Checking, citing and tracing your code

These read your files as text and never run your code; git runs with its hooks off. oscr check runs the same seven checks the registry runs on a pull request: a licence, an environment file, the paper's DOI, CITATION.cff, the tracing maps' files, files over 50 MiB, and a README that says how to run the code.

oscr check                       # the registry's checks at HEAD
oscr check --base main           # the change from main, as the registry checks a pull request
oscr check --rev v1.0 --json conclusion,findings
oscr check --offline             # ask the registry nothing

oscr cite builds the citation the site shows, from CITATION.cff (or codemeta.json), in APA and BibTeX:

oscr cite                        # APA and BibTeX
oscr cite --format bibtex >> refs.bib
oscr cite --software             # the software itself, not the paper the file prefers
oscr cite --release v1.2.0       # that version, with the DOI its release notes name
oscr cite --swhid                # the commit's Software Heritage identifiers

oscr trace works with the tracing maps that tie a paper's Methods paragraphs to lines of its code at a pinned commit. check finds each link's lines again at another commit the way the site's reader does (the same lines, the nearest copy, else the map's symbol):

oscr trace list                  # the maps the registry holds for this repository
oscr trace check                 # their lines at HEAD: same, moved, changed, gone
oscr trace check --commit v2.0 --paper 10.1234/abcd
oscr trace propose 10.1234/abcd analysis/filter.py:10-24=3 --section "Methods"

trace propose builds a map from lines you select (PATH:START-END, PATH#LSTART-LEND or a GitHub permalink, with =N for the paper's paragraph), each link with its GitHub and registry permalinks. The registry does not yet receive proposed maps from the command line (see What is coming): keep the file with your code, or cite its links in a research issue.

Linking a repository to its paper

oscr paper link 10.1234/abcd     # attach this repository to its paper
oscr paper list                  # the papers the registry links to it

paper link goes through the site's own write path: it opens the registry's page pre-filled, where you confirm and GitHub authorizes that one action as you. --no-browser prints the address instead.

Making a repository and sending it to GitHub

A common path for a researcher: make a public repository, link it to its paper, and work on it. Create it on GitHub (private ones are refused by design), then clone and push with ordinary git:

oscr repo create eeg-analysis --license mit --gitignore Python --add-readme --paper 10.1234/abcd --clone
cd eeg-analysis
# ... add your code ...
git add -A && git commit -m "First analysis"
git push                         # git pushes straight to GitHub with your own token

Pushing is plain git over HTTPS to GitHub; oscr auth setup-git lets git use the GitHub token the tool already holds, so you are not asked for a password. The other repository commands:

CommandWhat it does
oscr repo view [OWNER/NAME] [--web]The registry's view (linked or not, papers, maps), then GitHub's facts.
oscr repo clone OWNER/NAME [DIR]git clone, straight from GitHub, hooks off (a fork gets its upstream remote).
oscr repo list [OWNER]Your public repositories, and whether the registry links each.
oscr repo sync [OWNER/NAME]Fast-forward this clone's branch, or a fork on GitHub from its parent.
oscr repo set-default OWNER/NAMEThe repository this clone's commands go to.

Pull requests, issues and releases

oscr pr create --title "Fix the band-pass filter" --body "As in Methods 2.3" --push
oscr pr list
oscr pr view 12 --web            # its page on the registry
oscr pr checkout 12              # check its head out here (hooks off)

pr create runs the registry's checks on the change here, first. Issues are GitHub's, or the registry's own research issues (a mismatch, a code error, a reproduction), which need the research:write scope:

oscr issue create --title "The filter differs from Methods" \
  --research mismatch --paper 10.1234/abcd --path a.py --lines 10-24 --paragraph 3
oscr issue list --assignee @me
oscr issue close 4 --reason not_planned
oscr release create v1.0.0 --generate-notes
oscr release list
oscr release view v1.0.0 --web

Tie a release to the paper's version on its registry page. @me stands for your GitHub login.

Search, browse and the API

oscr search "band power"                       # the registry's search
oscr search eeg --type repositories
oscr search filter --github code               # GitHub's own search, for what only it indexes
oscr browse analysis/filter.py:10              # open the registry's page of those lines
oscr browse 12                                 # an issue or pull request
oscr browse --checks                           # a commit's checks (the registry's, your CI, the statuses)
oscr browse src/a.py --blame                   # GitHub's blame page (the registry has none)
oscr api /user                                 # a raw request to the registry's API
oscr api --github /repos/lab/eeg/releases --jq ".[].tag_name"

oscr api calls the registry's API at /api/forge/v1 (or GitHub's with --github) and prints the JSON answer; -f k=v adds a field, -X POSTchanges the method, --jq filters the result. The free, keyless read API is documented on its own: see the public API guide.

Your CI runs

oscr run list                    # the latest GitHub Actions runs, summarized
oscr run view 123456             # one run: its jobs, the steps that failed, its checks on the registry
oscr workflow list               # the repository's workflows and their state

Output, scripting and exit codes

In a terminal the tool prints aligned columns cut to the width, with colour; in a pipeit prints one tab-separated line per item, nothing cut, no colour, so it is easy to read from a script. Three flags reshape the output:

--json FIELDS
Print the named comma-separated fields as JSON (alone, it lists the fields a command offers).
--jq EXPR (or -q)
Filter with a subset of jq (paths, |, ,, //, comparisons, select, map, length, keys, sort_by, test).
--template TMPL (or -t)
Render with a subset of Go's templates (range, if, json, join, truncate, timeago, tablerow). oscr help formatting lists them all.

Colour obeys NO_COLOR, --color never and CLICOLOR_FORCE=1; oscr config set accessible_colors true uses bold and underline and a word, never red against green. Every text from the network is cleaned before it is shown (control and bidirectional escape sequences made inert), and email addresses become [email hidden], as on the site. The exit codes:

CodeMeaning
0Done.
1An error.
2A usage error (a wrong flag or argument).
3A check failed (oscr check).
4Sign-in needed.
130Interrupted.

The MCP server, for an assistant

oscr mcp serve speaks JSON-RPC 2.0 over standard input and output (the Model Context Protocol) and offers the read commands as tools for an assistant: repo_view, paper_list, check, cite, trace_list, trace_check, issue_list, issue_view, pr_list, pr_view, release_list, run_list and search. Each runs with your settings and credentials and answers its JSON. None writes, opens a browser or asks a question. oscr mcp tools lists them.

{"mcpServers": {"oscr": {"command": "oscr", "args": ["mcp", "serve"]}}}

Settings, aliases and completion

oscr config list                 # every setting, its value and what it does
oscr config set git_protocol ssh
oscr config set host example.org # another deployment of the registry
oscr alias set co "pr checkout"  # then: oscr co 12 (aliases never run a shell)
eval "$(oscr completion bash)"   # also zsh and fish

What it never does

  • It never runs your code. oscr check and oscr trace read files as text from git's object store; git always runs with its hooks off. The only programs the tool starts are git, the keychain's own, and your browser and editor.
  • It never keeps your token anywhere but the keychain (a plain file only when you ask, with a warning). A token is never printed, not even with --debug.
  • It never asks for, shows or keeps an email address. Your commits' address is your own git configuration, never read or changed.
  • It never sends your GitHub token to the registry. GitHub's side talks to GitHub; the registry's side talks to the registry.

What is coming

These are planned and are not available yet; the tool does not pretend they are:

  • Sending a proposed tracing map to the registry for an author's review (today oscr trace propose writes a file you keep).
  • More repository and collaboration verbs: repo fork, archive, rename, delete; reviewing or merging a pull request; editing, commenting on or reopening an issue; uploading or downloading a release's assets; discussions and projects.
  • The full jq and Go template languages (variables, reduce, assignment), Markdown rendered in the terminal, and a pager.

More

The public read API the tool builds on is documented at the API guide; its overview is at the API page. The source, the issue tracker and the full command reference are in the project on GitHub: https://github.com/NeuraCrypt/OSCR.