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:readandresearch:readfor 90 days;--scopesand--daysask 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:
| Command | What it does |
|---|---|
oscr auth status | Who is signed in, where each credential is kept, whether it still works (--offline to ask nothing). |
oscr auth token --github|--oscr | Print the active token, for a script's environment. |
oscr auth switch | Make another signed-in account the active one. |
oscr auth refresh | Renew GitHub's token; approve the registry's again. |
oscr auth logout | Sign out: the registry's token revokes itself, both leave the keychain. |
oscr auth setup-git | Make 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:
| Command | What 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/NAME | The 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 formattinglists 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:
| Code | Meaning |
|---|---|
0 | Done. |
1 | An error. |
2 | A usage error (a wrong flag or argument). |
3 | A check failed (oscr check). |
4 | Sign-in needed. |
130 | Interrupted. |
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 checkandoscr traceread 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 proposewrites 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.
