npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@agntn/ciphers

v0.1.4

Published

Unified educational and puzzle cipher library for agents

Readme

@agntn/ciphers

18 classical ciphers behind one small local API and CLI. Everything runs locally. No HTTP, no API keys, just text transformations for learning and puzzles.

Ciphers

| Cipher | Family | Self-inverse | Options | | -------------- | --------------------------- | :----------: | ------------------------------------------ | | caesar | substitution-shift | ✗ | --shift (1-25, default 3) | | rot13 | substitution-shift | ✓ | - | | rot47 | substitution-shift | ✓ | - | | atbash | substitution-reflection | ✓ | - | | vigenere | polyalphabetic | ✗ | --key (required) | | trithemius | polyalphabetic | ✗ | - | | alberti | polyalphabetic | ✗ | --key, --period (both required) | | rail-fence | transposition | ✗ | --rails (default 3) | | affine | substitution-multiplicative | ✗ | --a (multiplier), --b (shift) | | playfair | digraph | ✗ | --key (required) | | polybius | fractionation | ✗ | --key (optional) | | morse | fractionation | ✗ | - | | bacon | fractionation | ✗ | - | | tap-code | fractionation | ✗ | - | | columnar | transposition | ✗ | --key (required) | | adfgvx | fractionation | ✗ | --key (optional) | | bifid | fractionation | ✗ | --key (optional), --period (default 5) | | enigma | rotor | ✓ | --positions, --rings, --plugboard |

alberti uses a simplified keyed disk, not a full historical simulation. The inner disk rotates one position after every period Latin letters, which keeps results reproducible.

CLI

ciphers encode caesar "ATTACK AT DAWN" --shift 3     # DWWDFN DW GDZQ
ciphers decode atbash "ZGGZXP ZG WZDM"                # ATTACK AT DAWN
ciphers brute "KHOOR"                                  # shift=3 → HELLO
ciphers frequency "DWWDFN DW GDZQ" --lang en          # histogram
ciphers ciphers -v                                     # full list with options
ciphers info vigenere                                  # cipher details
ciphers encode morse "SOS"                             # ... --- ...
ciphers encode bacon "SECRET"                          # ABBAB AABAA ...
ciphers encode tap-code "HELP"                         # 2 3 1 5 3 1 3 5
ciphers encode columnar "ATTACK" --key KEY             # TCAATK
ciphers encode adfgvx "HELLO"                          # DDAVDXDXFF
ciphers encode bifid "TEST" --key EXAMPLE              # OSUT
ciphers encode enigma "AAAAA"                          # BDZGO

Library

import '@agntn/ciphers'
import { create, resolveCipher, getOpt } from '@agntn/ciphers'

// Cipher names match exactly
const caesar = create('caesar')
const result = caesar.encode('HELLO', { shift: 5 })
// result.text === 'MJQQT'

// Each cipher keeps its own options
const cipher = resolveCipher('vigenere')
const encoded = cipher.encode('SECRET', { key: 'KEY' })

// Self-inverse ciphers use the same transformation both ways
const rot13 = create('rot13')
rot13.decode(rot13.encode('HELLO').text).text === 'HELLO' // true

Every built-in cipher is a concrete class extending the exported abstract Cipher. Custom ciphers stay boring: extend Cipher and register the constructor with register(name, CipherClass). create() caches one instance per name.

OMP and Pi Extensions

Both integrations expose the same four local tools. Agents get the same API instead of another wrapper to learn:

  • cipher_encode: encode text with any cipher
  • cipher_decode: decode text with any cipher
  • cipher_brute_caesar: try all 25 Caesar shifts
  • cipher_frequency: inspect letter frequency

MCP Server

The package exposes the same four local tools through an MCP server over stdio:

ciphers mcp

For clients that accept JSON server configuration:

{
  "mcpServers": {
    "ciphers": {
      "command": "ciphers",
      "args": ["mcp"]
    }
  }
}

The server validates each tool call's arguments against its published JSON Schema. It runs entirely locally and does not require network access or credentials.

Install

pnpm install
pnpm build

Test

pnpm test

License

MIT