Mjcheetham.Otp 0.2.0

dotnet add package Mjcheetham.Otp --version 0.2.0
                    
NuGet\Install-Package Mjcheetham.Otp -Version 0.2.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Mjcheetham.Otp" Version="0.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Mjcheetham.Otp" Version="0.2.0" />
                    
Directory.Packages.props
<PackageReference Include="Mjcheetham.Otp" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Mjcheetham.Otp --version 0.2.0
                    
#r "nuget: Mjcheetham.Otp, 0.2.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Mjcheetham.Otp@0.2.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Mjcheetham.Otp&version=0.2.0
                    
Install as a Cake Addin
#tool nuget:?package=Mjcheetham.Otp&version=0.2.0
                    
Install as a Cake Tool

otp

build Mjcheetham.Otp.Tool Mjcheetham.Otp

Create and manage one-time passwords (TOTP and HOTP) from the command line — plus a small .NET library to do the same in your own apps.

otp generates the same time-based (TOTP) and counter-based (HOTP) one-time passwords used by authenticator apps. It stores your accounts locally, prints current codes, and imports/exports the standard otpauth:// format — including scannable QR codes.

Features

  • TOTP & HOTPRFC 6238 time-based and RFC 4226 counter-based codes.
  • Hash-agile — SHA-1, SHA-256, and SHA-512, with configurable digit count and time period.
  • Import & export — read and write otpauth:// URIs and render QR codes.
  • Interactive or scriptable — guided prompts on a terminal; --format json or -z (NUL-delimited) for scripts.
  • Secure storage — accounts kept in your OS keychain by default (macOS Keychain, Windows Credential Manager, or Linux Secret Service), or a plaintext file; selectable with otp config.
  • Two distribution channels — a cross-platform dotnet tool and self-contained native binaries.
  • Reusable library — the Mjcheetham.Otp package exposes the same engine.

Install

As a .NET tool

Requires the .NET SDK:

dotnet tool install --global Mjcheetham.Otp.Tool

Invoke it as otp, and update with dotnet tool update --global Mjcheetham.Otp.Tool.

As a native binary (no .NET required)

Download the archive for your platform from the latest release, extract it, and put otp on your PATH. Binaries are published for:

OS Architectures
Linux x64, arm64, arm
macOS x64 (Intel), arm64 (Apple silicon)
Windows x64, arm64

Quick start

# Add a time-based (TOTP) account from its Base32 secret
otp add github --secret JBSWY3DPEHPK3PXP --issuer GitHub

# ...or import an otpauth:// URI (e.g. decoded from a QR code)
otp add --uri "otpauth://totp/GitHub:me@example.com?secret=JBSWY3DPEHPK3PXP&issuer=GitHub"

# ...or just run `add` on a terminal for guided prompts
otp add

# Generate the current code ('code' is an alias for 'get')
otp get github
otp code github

# List, inspect (secret masked by default), and remove
otp list
otp show github
otp remove github

Usage

Run otp --help or otp <command> --help for full details; otp --version prints the version.

Command Aliases Description
add Add an account from options, an otpauth:// URI, or interactively.
get code Generate the current code for a stored account.
list ls List stored accounts.
show Show an account's details, otpauth:// URI, or QR code.
remove rm Remove a stored account.
config View and edit configuration (e.g. the storage backend).

add

otp add <name> [options]
otp add --uri <otpauth://...>
otp add --interactive
Option Description Default
<name> Label to store the account under (unless --uri).
--secret, -s Shared secret, Base32-encoded (unless --uri).
--type, -t totp (time-based) or hotp (counter-based). totp
--issuer Issuer / provider name.
--digits, -d Number of digits in the code. 6
--period, -p Time step in seconds (TOTP only). 30
--counter, -c Initial counter value (HOTP only). 0
--algorithm, -a sha1, sha256, or sha512. sha1
--uri Import from an otpauth:// URI (excludes the options above).
--interactive, -i Prompt for each field.

Running otp add with no arguments on an interactive terminal starts the guided prompts automatically.

get (alias code)

otp get <name> [--counter <n>] [--format text|json|nul] [-z]

Prints the current code. For TOTP accounts the human view also shows how long the code stays valid. --counter generates a single HOTP code at a specific counter without advancing the stored value.

list (alias ls)

otp list [--type totp|hotp] [--format text|json|nul] [-z]

show

otp show <name> [--show-secret] [--uri | --qr] [--format text|json|nul] [-z]

The secret is masked (••••••••) by default.

Option Description
--show-secret Reveal the secret (and the secret embedded in the URI).
--uri Print only the otpauth:// URI (contains the secret — for backup).
--qr Print the otpauth:// URI as a QR code to scan into another app.

remove (alias rm)

otp remove <name> [--yes]

Prompts for confirmation on a terminal; pass --yes/-y to skip (required when input is not a terminal).

Output formats

Commands that emit data (get, list, show) accept --format/-f:

  • text — human-readable (default), coloured when the terminal supports it.
  • json — a single compact JSON value, ideal for jq and friends.
  • nul — NUL-delimited records in the style of git … -z; -z is shorthand.
otp show github --format json | jq .type
otp list -z | xargs -0 -n1 otp get

Storage

otp keeps your accounts in one of several backends:

Backend Where
auto (default) The current OS's native store below, otherwise plaintext.
keychain macOS Keychain.
wincred Windows Credential Manager.
secretservice Linux Secret Service (GNOME Keyring, KWallet, …) via libsecret.
plaintext A single JSON file (see below).

Choose one with otp config:

otp config set store.backend keychain    # auto | plaintext | keychain | wincred | secretservice

The plaintext backend keeps accounts in a single JSON file:

  • Default: ~/.otp/store.json — the directory is created 0700, the file 0600.
  • Override the location with the OTP_STORE environment variable.

The plaintext backend stores secrets unencrypted. Rely on filesystem permissions (as otp does) and/or full-disk encryption, or use one of the native keychain backends.

Switching backends does not move existing accounts between them.

Configuration

Configuration lives in ~/.otp/config.json (override with OTP_CONFIG). Manage it with otp config:

otp config list                        # show configured values
otp config get store.backend           # print a value (defaults to 'auto')
otp config set store.backend keychain  # set a value
otp config unset store.backend         # revert to the default
otp config edit                        # open the file in $VISUAL / $EDITOR
Key Values Default
store.backend auto, plaintext, keychain, wincred, secretservice auto

Environment variables

Variable Effect
OTP_STORE_BACKEND Storage backend override (takes precedence over the config).
OTP_CONFIG Path to the config file (default ~/.otp/config.json).
OTP_STORE Path to the plaintext store file (default ~/.otp/store.json).
NO_COLOR Disable coloured output.
NO_ANSI Disable ANSI escape sequences entirely.

Library

Install the Mjcheetham.Otp package to generate codes in your own .NET app:

dotnet add package Mjcheetham.Otp
using Mjcheetham.Otp;

// Build a TOTP from a Base32 secret and generate the current code.
byte[] secret = Base32.Decode("JBSWY3DPEHPK3PXP");
var totp = new TimeBasedOtp("GitHub", secret, period: 30, digits: 6, algorithm: OtpAlgorithm.Sha1);
string code = totp.GetCode();

// Counter-based (HOTP): generate the code for a specific counter.
var hotp = new HmacOtp("Backup", secret);
string next = hotp.GetCode(counter: 42);

// Parse and format the standard otpauth:// URI.
IOneTimePassword imported = OtpAuthUri.Parse(
    "otpauth://totp/GitHub:me@example.com?secret=JBSWY3DPEHPK3PXP&issuer=GitHub");
string uri = OtpAuthUri.Format(imported);

// Persist accounts in the same file store the CLI uses.
IOtpStore store = new FileOtpStore(FileOtpStore.GetDefaultPath());
await store.AddAsync(totp);

The library targets .NET 10, is trim-/AOT-compatible, and ships a .snupkg symbol package.

Building from source

Requires the .NET SDK pinned in global.json.

dotnet build                              # build the solution
dotnet run --project src/otp -- --help    # run the CLI
dotnet publish src/otp -c Release -r <rid>  # native AOT binary for a runtime

The root VERSION file is the single source of truth for the major.minor.patch number: local builds report <VERSION>-dev+<sha>, and a release is cut by pushing a tag that matches VERSION.

Standards

License

MIT © Matthew John Cheetham

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.2.0 90 7/5/2026
0.1.0 93 7/3/2026