PrivateNote CLI
Zero-footprint secrets in scripts, pipes, and CI — encrypted locally before anything reaches the network.
On this page
Who this is for
Use the CLI when the secret already lives in a file, password manager, or pipeline output and you need a shareable link without pasting into chat or email.
The tool reads from stdin or a file path, encrypts with AES-256-GCM on your machine, uploads only ciphertext, and prints a URL with the decryption key in the fragment.
Notes created this way are tracked as creationSource: cli in analytics.
Install
Requires Node.js 18+. Works on macOS, Linux, and Windows.
# Run once without installing npx privatenote-cli --expire 1h --output-url-only # Or install globally (adds the `privatenote` command) npm install -g privatenote-cli # Pipe a secret in scripts cat secret.txt | privatenote --expire 1h --output-url-only # Local self-host / wrangler dev (HTTP API — dev only) echo "secret" | privatenote --insecure --api-base-url http://localhost:8787 --output-url-only
Try it live
Run the same flow as the CLI in your browser: encrypt locally, upload ciphertext, print a URL with the key in the fragment.
Live demo — creates a real note on privatenote.ai. Use a throwaway secret, not production credentials.
echo 'sk-live-demo-replace-me' | npx privatenote-cli --expire 1h --output-url-onlyhttps://privatenote.ai/note/…#…
Security architecture
Plaintext never leaves your machine unencrypted. The share URL carries the decryption key in its #fragment, which browsers and HTTP clients do not send to servers.
When stdout is not a TTY (piped or captured), the CLI refuses to print a link unless you pass --output-url-only or --force-stdout — this prevents accidental leaks into CI logs.
Encrypt locally
AES-256-GCM on your device — browser, editor, terminal, or MCP process.
Upload ciphertext
Only encrypted bytes and note metadata (expiry, burn-after-reading) reach the server.
Key in #fragment
The decryption key stays in the URL hash. Browsers do not send fragments in HTTP requests.
privatenote.ai/note/…#key
HTTPS required for remote API origins; pass --insecure only for local http:// dev (e.g. wrangler dev on :8787).
PRIVATENOTE_ALLOWED_HOSTS pins API hostnames when using a custom API base URL.
Response shape validation and reserved note ID checks before upload.
Prefer redirecting output to a chmod 600 file instead of echoing URLs.
Flags and environment variables
| Name | Description |
|---|---|
| --expire 15m|1h|24h|7d | Note lifetime (default: 24h) |
| --burn / --no-burn | Destroy after first view (default: burn) |
| --title <text> | Optional title prepended to content |
| --json | Print { secureUrl, expiresAt, burnAfterReading } |
| --output-url-only | URL-only output; safe for piped stdout in scripts |
| --force-stdout | Allow output when stdout is not a terminal (use with --json in CI) |
| --api-base-url <url> | Override API origin (HTTPS; use with --insecure for local http://) |
| --insecure | Allow http:// API origins — local dev only, never in production |
| PRIVATENOTE_API_BASE_URL | Default API base URL |
| PRIVATENOTE_WEB_ORIGIN | Share-link origin (defaults to API origin) |
| PRIVATENOTE_ALLOWED_HOSTS | Comma-separated hostname allowlist |
Related integrations
VS Code, Cursor & Codex IDE
The primary developer entry point — compose, configure, and share without switching context.
View docsMCP server for AI agents
Let agents hand off secrets securely — encryption runs locally in the MCP process.
View docsOpenAI Codex plugin
MCP plus skills for Codex CLI and IDE — same repository as this site.
View docsChrome extension
Encrypt selected text in the browser without opening privatenote.ai — same client-side flow, fewer context switches.
View docsPrivateNote CLI
Zero-footprint secrets in scripts, pipes, and CI — encrypted locally before anything reaches the network.