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

pure-llm-chess-mcp

v0.3.0

Published

An MCP intended to allow a purely LLM-based system to follow chess rules without external information such as Stockfish.

Readme

Pure LLM Chess MCP

An MCP intended to allow a purely LLM-based system to follow chess rules without external information such as Stockfish.

Requires Node.js 24 or newer.

npx -y pure-llm-chess-mcp

Or install the CLI globally:

npm install -g pure-llm-chess-mcp
pure-llm-chess-mcp

Connect

For a stdio MCP client, use npx:

{
  "mcpServers": {
    "chess": {
      "command": "npx",
      "args": ["-y", "pure-llm-chess-mcp"]
    }
  }
}

For Streamable HTTP:

npx -y pure-llm-chess-mcp --transport http --port 3000

Connect to http://127.0.0.1:3000/mcp. The plain HTTP MCP transport is loopback-only. Games live in memory until the process exits. Export JSON to save them.

Load a local rule plugin:

npx -y pure-llm-chess-mcp --plugin /absolute/path/to/variant.mjs

--plugin may be repeated. Plugins are trusted local JavaScript modules loaded at startup, with the same privileges as the server. The server does not execute code supplied through MCP or imported archives. See the plugin guide to load the included three-player hex example or write your own rules.

Manual TLS

Supply a PEM certificate chain and its unencrypted PEM private key:

npx -y pure-llm-chess-mcp --transport https --port 3000 \
  --tls-cert /path/to/fullchain.pem --tls-key /path/to/privkey.pem

The default endpoint is https://127.0.0.1:3000/mcp. The certificate must cover the hostname or IP used by the client, and its issuer must be trusted by that client. Certificates are read at startup; restart after replacing them.

To listen outside loopback, specify both the bind address and the certificate's hostname:

npx -y pure-llm-chess-mcp --transport https --host 0.0.0.0 \
  --domain chess.example.com --port 443 \
  --tls-cert /path/to/fullchain.pem --tls-key /path/to/privkey.pem

Connect to https://chess.example.com/mcp. When --domain is set, only that Host and, if present, Origin hostname is accepted.

Automatic HTTPS

The server obtains and renews certificates using ACME inside the Node process:

npx -y pure-llm-chess-mcp --auto-https chess.example.com \
  --acme-email [email protected]

Point the domain's DNS records at the server and make TCP port 80 reachable for HTTP-01 validation. By default the HTTPS endpoint is https://chess.example.com/mcp on port 443. The process must be able to bind both ports. Startup waits for a usable certificate; it fails if initial issuance fails.

Account keys and certificates are stored on disk and reused on restart. The server renews certificates after two thirds of their validity period and replaces the TLS context without restarting or losing games. Renewal errors retain the current certificate and retry after five minutes. SIGINT and SIGTERM stop both listeners and cancel any in-progress ACME request.

Storage is isolated by domain and ACME directory, so staging and production certificates cannot be confused. Private files use mode 0600; a lock prevents concurrent writers. An unclean termination may leave a .lock file containing the process ID. If startup reports a stale lock, confirm that process has stopped before removing the exact lock file shown in the error.

| Option | Default | Purpose | | --- | --- | --- | | --auto-https <domain> | none | Enable automatic HTTPS for one public DNS name | | --acme-email <email> | none | ACME account contact | | --https-dir <path> | $XDG_DATA_HOME/pure-llm-chess-mcp/https, or ~/.local/share/pure-llm-chess-mcp/https | Persistent certificate and account storage | | --host <address> | 0.0.0.0 in automatic mode | Bind address for both listeners | | --port <port> | 443 in automatic mode | HTTPS listener | | --http-port <port> | 80 | HTTP-01 challenge and GET/HEAD redirect listener | | --acme-staging | off | Use Let's Encrypt's staging CA; its certificates are not publicly trusted | | --acme-directory <url> | Let's Encrypt production | Custom ACME directory; cannot be combined with staging |

Preserve the storage directory across restarts. A custom HTTP listener port requires forwarding public TCP port 80 to it for validation. Clients must reach the configured HTTPS port. Only HTTP-01 is supported; wildcard certificates and DNS-01 are not supported. Automatic mode cannot be combined with manual TLS options or --domain.

The implementation uses acme-client for the ACME protocol. See Let's Encrypt's HTTP-01 requirements for deployment details. ACME directory URLs must use HTTPS; loopback HTTP URLs are accepted for local testing.

HTTPS encrypts traffic; it does not add client authentication or separate games by user. For a private deployment, restrict network access or put an authenticated gateway in front of the endpoint.

Codex

Register the npm package as a stdio server:

codex mcp add chess -- npx -y pure-llm-chess-mcp
codex mcp list

Start a new Codex session and use /mcp to check the connection. Codex starts the server automatically; Node.js 24 or newer and npx must be available on its PATH. Try: "Use the chess MCP to create a standard game and show the board with Unicode pieces."

Alternatively, add this to ~/.codex/config.toml, or .codex/config.toml for a trusted project:

[mcp_servers.chess]
command = "npx"
args = ["-y", "pure-llm-chess-mcp"]

For HTTP or HTTPS, start the server in a separate terminal, then register its URL instead of the stdio command:

codex mcp add chess --url http://127.0.0.1:3000/mcp

For HTTPS, use --url https://chess.example.com/mcp (including a port if nonstandard). Keep the server running while using Codex. Remove the registration with codex mcp remove chess.

See the official Codex MCP documentation for configuration details.

Tools

| Tool | Arguments | Result | | --- | --- | --- | | list_variants | none | Rule IDs, versions, descriptions, schemas, supported formats | | new_game | variant="standard", options={} | New game and state | | get_state | game_id, ascii=false, unicode=false | Current state; optional ascii string with ASCII or Unicode pieces | | play_move | game_id, move, allow_illegal=false | legal, applied, reason, resulting state | | edit_board | game_id, changes, optional turn, rule_state | Updated state | | import_game | format, data, variant="standard" for FEN, optional options for FEN/PGN | A new game | | export_game | game_id, format | {format, data} |

Built-in variant IDs are standard, chess960, antichess, atomic, crazyhouse, horde, kingofthehill, racingkings, and threecheck. Chess960 accepts options.index from 0 to 959 (default 518).

Standard moves use UCI coordinates, such as e2e4 and e7e8q. Inspect list_variants for each variant's move schema. The hex example uses objects such as {"from":"-2,0","to":"-1,0"}.

An edit maps cells to a piece or null:

{
  "game_id": "<game-id>",
  "changes": {
    "e1": null,
    "e4": {"kind": "queen", "owner": "white"}
  },
  "turn": "black"
}

State includes cell IDs, a pieces map, registered players, turn, variant-specific rule_state, valid, issues, check, outcome, claimable_draws, and a revision. Normal chess pieces use pawn, knight, bishop, rook, queen, and king; owners are white and black.

get_state with ascii=true adds a board like this without replacing structured state:

8  r n b q k b n r
7  p p p p p p p p
6  . . . . . . . .
5  . . . . . . . .
4  . . . . . . . .
3  . . . . . . . .
2  P P P P P P P P
1  R N B Q K B N R

   a b c d e f g h

Set unicode=true to use Unicode chess pieces (♔♕♖♗♘♙ and ♚♛♜♝♞♟). This also requests board output, so ascii=true is optional. The rendered text remains in the ascii response field; coordinates and empty cells are unchanged. Plugins that do not implement Unicode rendering keep their ASCII output.

{"game_id": "<game-id>", "unicode": true}

Legality and editing

A rejected move leaves the game unchanged. legal is true or false for valid positions and null when rules cannot evaluate the position. applied independently reports whether the board changed.

With allow_illegal=true, legal moves still follow all normal rules. Otherwise the server relocates the source piece, overwrites the destination (including friendly pieces and kings), and advances the current turn. It does not infer illegal castling, en passant, or promotion effects. Empty sources, nonexistent cells, and identical source/destination remain errors. Use edit_board for creation, deletion, replacement, and compound edits.

Forced changes reset the repetition segment. Built-in chess variants also clear castling rights, en passant, and the halfmove counter. Edits preserve the turn unless explicitly changed and may explicitly replace rule_state. Historical events remain in JSON archives.

Rule-invalid boards, including boards with missing kings, remain editable and printable. Structurally invalid data, such as unknown cells or piece kinds, is rejected. Failed operations do not publish partial state changes.

The reserved object key and cell ID __proto__ are rejected explicitly, including inside nested JSON data. The same text is allowed as an ordinary string value.

Standard automatic outcomes include checkmate, stalemate, insufficient material, fivefold repetition, and the 75-move rule. Claimable threefold/50-move draws are reported; claim and resignation tools are not included.

Import and export

  • JSON is the full-fidelity format: format version, exact variant ID/version, options, metadata, initial state, applied events, and final state. Imports replay events and compare the resulting state. The same plugin version must already be installed. Code is never embedded or loaded from an archive.
  • FEN exchanges a current position, without history. A syntactically valid but rule-invalid position can be imported. Specify variant when importing a nonstandard position.
  • PGN exchanges a single game's headers, mainline, and result for supported variants. Comments, annotations/NAGs, variations, and multiple games are rejected. Games with edits or actual forced moves require JSON. A PGN Variant header selects the rule set.

PGN headers require string values without control characters and valid tag names. JSON metadata that cannot be represented is rejected on PGN export rather than discarded. Position and variant headers are derived from the actual game state. Standard aliases such as normal, classical, and wild/0 are accepted; an exact installed plugin ID takes precedence over an alias.

A new game ID is assigned on every import. Input/output is data, not server filesystem paths. No file is read or written through these tools. Unsupported formats fail explicitly instead of dropping information.

For FEN/PGN imports, pass any creation options required by the selected variant in options. They are validated, passed to the plugin's importer, and preserved in JSON exports. JSON imports restore their archived options and reject an options override.

Accepted FEN promoted-piece markers (~) survive unrelated moves and follow the marked piece when it moves; captures remove them. This changes replay semantics outside Crazyhouse, so those built-in adapters now use version 2. Their version 1 JSON archives are rejected with VERSION_MISMATCH rather than silently replayed with different state. Crazyhouse remains version 1.

PGN declarations such as resignation or an agreed draw are preserved as terminal results, even when the board itself is not terminal. Such declarations are recorded in JSON history. Forced moves and edits clear the declaration and resume from the changed position; a declared result contradicting a rules-based outcome is rejected.

Archive replay rejects another terminal result declaration unless an intervening edit or forced move has cleared the previous one.

Development

From a source checkout:

npm ci
npm run check
npm test
npm start

npm test builds the project before running the tests. TLS tests require openssl to generate temporary certificates. Use npm run build to build without testing.

npm pack builds automatically before creating the package. The package includes the runtime, type declarations, example plugin, documentation, license, and TypeScript source; tests and local workspace files are excluded.

The implementation separates the game service, rule adapters, and MCP transports. See the plugin contract and the hex example for nonrectangular boards, new pieces, and multiplayer rules.

Dependency versions are pinned in package-lock.json.

License

Licensed under the GNU Affero General Public License v3.0 only (AGPL-3.0-only). See LICENSE.

chessops is licensed separately under GPL-3.0-or-later.