# Share a secret from the command line with one command

> Pipe a file, the clipboard, or a generated password into npx and get an encrypted one-time link. Share a secret from the command line, nothing to install.

Source: https://evergist.com/blog/share-secrets-from-the-terminal/
Published: 2026-09-30

**Short answer:** pipe the secret into `npx -y evergist create --views 1 --expires 1h`. The command encrypts on your machine, uploads ciphertext, and prints a link that opens once. It needs Node.js 20 or newer and nothing else, and the secret never has to appear in your shell history.

## How do I share a secret from the terminal without a browser?

Give `create` a file or pipe text into it. It prints a link, and the person on the other end opens the link in a browser or reads it with the same CLI.

```sh
# From a file
npx -y evergist create deploy-key.pem --views 1 --expires 1h

# From stdin
./print-token.sh | npx -y evergist create --views 1 --expires 1h
```

`npx -y` downloads the [`evergist` package](https://www.npmjs.com/package/evergist) on first use and runs it. The output looks like this:

```text
https://evergist.com/g/K61kFEBcg76B#<key>

expires:      2026-09-30T10:07:18.810Z
views:        1
delete token: <token>
```

The part after `#` is the 256-bit key. It stays on your machine and in the link. Our server gets the ciphertext and a hash of an access token, and can't decrypt either. The full scheme is in [how the encryption works](https://evergist.com/security/#the-encryption-scheme).

The flags for `create`:

| Flag | Meaning |
|---|---|
| `-e, --expires <time>` | `10m`, `1h`, `1d`, `7d`, `30d`, or a number of seconds. Default `1d`, max `30d` |
| `-v, --views <n>` | Delete after this many reads, 1 to 1000. Default is no limit until expiry |
| `-p, --password <password>` | Require a password as well as the link. `EVERGIST_PASSWORD` does the same |
| `-g, --generate-password` | Generate a password and print it next to the link |
| `--json` | Print JSON |

A note holds up to 512 KiB of UTF-8 text. It's text only, so base64 a binary file first.

## How do I keep the secret out of shell history?

Never type the value. Your shell saves the commands you type, so `echo "hunter2" | npx -y evergist create` leaves `hunter2` in the history file. Pipe from something that already holds the secret.

From the clipboard:

```sh
# macOS
pbpaste | npx -y evergist create --views 1 --expires 1h

# Linux, Wayland
wl-paste | npx -y evergist create --views 1 --expires 1h

# Linux, X11
xclip -selection clipboard -o | npx -y evergist create --views 1 --expires 1h
```

From a password generator, when you're setting a new credential and handing it over in one go:

```sh
pw=$(npx -y evergist password)
# set $pw wherever it belongs, then:
printf '%s' "$pw" | npx -y evergist create --views 1 --expires 1h
unset pw
```

`evergist password` prints a generated password. `openssl rand -base64 24` or your own generator works the same way. `printf '%s'` matters because the note stores exactly the bytes it receives, and `echo` adds a newline the recipient may paste into a login form.

The same rule applies to `--password`. A password typed after `-p` lands in history and in the process list. Use `-g` to have the CLI generate one, or read it into the environment without echo:

```sh
read -rs EVERGIST_PASSWORD && export EVERGIST_PASSWORD
npx -y evergist read "https://evergist.com/g/<id>#<key>"
```

Send the password through a different channel than the link.

## How do I use it in a script?

Add `--json` and read the fields you need.

```sh
printf '%s' "$TOKEN" | npx -y evergist create --views 1 --expires 1h --json
```

```json
{
  "id": "K61kFEBcg76B",
  "url": "https://evergist.com/g/K61kFEBcg76B#<key>",
  "expiresAt": "2026-09-30T10:07:18.810Z",
  "maxViews": 1,
  "deleteToken": "<token>",
  "passwordProtected": false
}
```

With `-g` the JSON also has `password`. To pull out the link with `jq`:

```sh
link=$(printf '%s' "$TOKEN" | npx -y evergist create --views 1 --expires 1h --json | jq -r .url)
```

The CLI exits non-zero and writes `evergist: <reason>` to stderr on any failure, so a script can stop on a failed create. In a pipeline like the one above, the shell reports the exit status of `jq`, the last command, so use `set -euo pipefail` in Bash to make the failed create fail the pipeline. [Send a secret from CI to a person](https://evergist.com/blog/send-a-secret-from-ci-to-a-person/) builds a full GitHub Actions step on top of this.

## How do I check whether a note was read, or take it back?

`status` shows expiry and views left without using a view. `delete` removes the note.

```sh
npx -y evergist status "https://evergist.com/g/<id>#<key>"
```

```text
expires:  2026-09-30T10:07:18.810Z
views:    1 of 1 left
password: no
```

Once a one-view note has been read, the same command exits 1:

```text
evergist: Gist not found. It expired, reached its view limit, was deleted, or the link key is wrong.
```

A script can poll that to see whether the note is still there. "Not found" doesn't prove the recipient read it. It can also mean the note expired, someone deleted it, ten wrong passwords wiped it, or the link is wrong. `status --json` returns `viewsRemaining`, `maxViews`, `expiresAt`, and `password`.

To delete a note you sent by mistake:

```sh
# With the link
npx -y evergist delete "https://evergist.com/g/<id>#<key>"

# With the id and the delete token from create
npx -y evergist delete K61kFEBcg76B --token "$DELETE_TOKEN"
```

Keep the delete token to yourself. It deletes the note without the link.

## How does the recipient read it?

In a browser, or with `read`, which prints the text to stdout and uses one view.

```sh
npx -y evergist read "https://evergist.com/g/<id>#<key>" > secret.txt
```

Quote the link so the shell passes it through untouched. When that was the last view, the CLI says so on stderr, which keeps the redirected file clean. A recipient without Node can use the [Python reader](https://evergist.com/examples/evergist_read.py), about 30 lines written against the published scheme.

## Can I pin the CLI instead of trusting npx?

Yes. The CLI is one file with no dependencies, served at [evergist.com/cli/evergist.mjs](https://evergist.com/cli/evergist.mjs). Download it, read it, record its checksum, and run that copy.

```sh
curl -fsSLO https://evergist.com/cli/evergist.mjs
shasum -a 256 evergist.mjs
node evergist.mjs create secret.txt --views 1 --expires 1h
```

Commit the file or the checksum to your tooling repo and the code that touches your secrets only changes when you change it. The lighter option is pinning the npm version with `npx -y evergist@1.0.0`. If the npm registry is blocked, `npx -y https://evergist.com/cli/evergist.tgz` runs the same package from our domain.

## Does the CLI encrypt locally or send plaintext to the server?

It encrypts locally with AES-256-GCM. The API has no endpoint that takes plaintext and encrypts it for you. It stores whatever bytes a client uploads as ciphertext, so the encrypting is the client's job, and the CLI does it before upload. You can check this in the single file above or against the [REST API docs](https://evergist.com/docs/api/). [Why the note API has no plaintext endpoint](https://evergist.com/blog/self-destructing-note-api/) explains the design.

Not every one-time secret tool works this way. Onetime Secret encrypts on its server with a key from the server's config, per its own [encryption audit document](https://github.com/onetimesecret/onetimesecret/blob/main/docs/architecture/encryption-at-rest-dpa-audit.md), so its server receives your text before encrypting it. Before you pipe a secret into any CLI, find out which side encrypts. [Private note sharing compared](https://evergist.com/blog/private-note-sharing-compared/) covers eight tools on that question.

## What this doesn't do

- Anyone who gets the full link before your recipient can read the note. One view and a short expiry limit the window. They don't close it.
- Notes last 30 days at most. Keep long-lived secrets in a password manager or a secrets manager.
- It holds text up to 512 KiB. No file attachments.

## Questions

### How do I pipe a password into a one-time link?

Run `printf '%s' "$PASSWORD" | npx -y evergist create --views 1 --expires 1h`. The variable expands inside your shell, so the value doesn't show up in the process list, and `--views 1` deletes the note after the first read.

### Is there anything to install?

No. `npx -y evergist` fetches the package when you run it and needs Node.js 20 or newer. If you use it often, `npm install -g evergist` gives you a plain `evergist` command, and the single-file `evergist.mjs` runs with `node` alone.

### Can I check a link without burning it?

Yes. `npx -y evergist status "<link>"` reports expiry, views left, and whether a password is set. It doesn't count as a view. The browser also waits for a click on "Open the note" before it spends a view on a view-limited note.

### Can an AI agent run these commands?

Yes, the same commands work from an agent's shell, and `npx -y evergist mcp` runs a local MCP server with the same four operations. An agent that reads a note does see the value. The [agent guide](https://evergist.com/agents/) covers the setup.

## Next steps

- Agent instructions, with every command: https://evergist.com/SKILL.md
- MCP server, CLI, and REST API setup: https://evergist.com/agents.md
