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

stockfish-mcp

v1.0.0

Published

MCP server that gives an LLM the best move for a chess position (FEN or PGN) via Stockfish.

Readme

stockfish-mcp

A tiny, opinionated Model Context Protocol server that gives an LLM the best move for any chess position — powered by Stockfish.

Hand it a position as FEN or PGN (or nothing, for the starting position) and it returns the best move, the engine's evaluation, and — optionally — the predicted best line, as clean structured JSON. One tool. One call. No UCI knowledge required.

{
  "turn": "black",
  "bestmove": { "uci": "f6e4", "san": "Nxe4" },
  "ponder":   { "uci": "d2d4", "san": "d4" },
  "score": { "type": "cp", "value": -371, "perspective": "side to move" },
  "evaluation": "White is better (+3.71)",
  "fen": "r1bqk2r/ppp2ppp/2np1n2/P3p3/1PB1P3/5N2/2PP1PPP/RNBQ1RK1 b kq - 0 7"
}

Requirements

  • Node.js ≥ 18
  • Stockfish installed and on your PATH (or point STOCKFISH_PATH at the binary). This project does not bundle Stockfish.

Install Stockfish:

# Debian / Ubuntu
sudo apt install stockfish

# macOS (Homebrew)
brew install stockfish

# or download a binary from https://stockfishchess.org/download/

Usage

With any MCP client (Claude Desktop, etc.)

Add to your client's MCP config:

{
  "mcpServers": {
    "stockfish": {
      "command": "npx",
      "args": ["-y", "stockfish-mcp"]
    }
  }
}

Or run it from a local checkout:

{
  "mcpServers": {
    "stockfish": {
      "command": "node",
      "args": ["/path/to/stockfish-mcp/index.mjs"]
    }
  }
}

From the command line (manual testing)

npm install
npm start          # speaks MCP over stdio
npm test           # end-to-end smoke test (needs stockfish installed)

The analyze tool

| Parameter | Type | Default | Description | | ------------- | ------- | ------- | ----------- | | position | string | start position | A FEN string or PGN/move list. Omit for the starting position. | | depth | integer | 18 | Search depth in plies. Higher = stronger but slower. | | movetime | integer | — | If given, search this many milliseconds instead of a fixed depth. | | includeLine | boolean | false | Include the engine's predicted best line (PV) in SAN. |

Response

| Field | Description | | ------------ | ----------- | | turn | "white" or "black" — side to move in the given position. | | bestmove | { uci, san } — the best move (null if the position is already terminal). | | ponder | { uci, san } or null — the reply the engine expects. | | score | { type: "cp" \| "mate", value, perspective: "side to move" } — raw engine score. | | evaluation | Human-readable, White-perspective summary, e.g. "White is better (+3.71)", "Mate in 1 for Black", "roughly equal". | | fen | The FEN actually analyzed (after PGN conversion / normalization). | | line | (only with includeLine) Numbered SAN principal variation, truncated with …. |

Examples

FEN (black to move):

// analyze({ "position": "r1bqk2r/ppp2ppp/2np1n2/P3p3/2B1P3/5N2/2PP1PPP/RNBQ1RK1 b kq - 0 7", "depth": 14 })
{
  "turn": "black",
  "bestmove": { "uci": "f6e4", "san": "Nxe4" },
  "ponder": { "uci": "d2d4", "san": "d4" },
  "evaluation": "White is better (+3.71)"
}

PGN:

// analyze({ "position": "1. e4 e5 2. Nf3 Nc6 3. Bb5 a6", "depth": 12 })
{
  "turn": "white",
  "bestmove": { "uci": "b5c6", "san": "Bxc6" },
  "ponder": { "uci": "d7c6", "san": "dxc6" },
  "evaluation": "White is better (+0.36)"
}

Best line + mate detection:

// analyze({ "position": "6k1/5ppp/8/8/8/8/8/R6K w - - 0 1", "includeLine": true })
{
  "turn": "white",
  "bestmove": { "uci": "a1a8", "san": "Ra8#" },
  "evaluation": "Mate in 1 for White",
  "line": "1. Ra8#"
}

Configuration

Environment variables:

| Variable | Default | Description | | ------------------------- | ----------- | ----------- | | STOCKFISH_PATH | stockfish | Path to the Stockfish binary. | | STOCKFISH_TIMEOUT_MS | 60000 | Per-search safety timeout, in milliseconds. | | STOCKFISH_DEFAULT_DEPTH | 18 | Search depth used when the caller omits depth. |

Example:

{
  "mcpServers": {
    "stockfish": {
      "command": "npx",
      "args": ["-y", "stockfish-mcp"],
      "env": { "STOCKFISH_PATH": "/usr/games/stockfish", "STOCKFISH_DEFAULT_DEPTH": "20" }
    }
  }
}

How it works

The server spawns a fresh stockfish process for each analyze call, sends position fen … followed by go depth N (or go movetime N), reads the engine's info lines to capture the latest score and principal variation, and resolves on bestmove. Moves are converted to SAN with chess.js, which also handles PGN→FEN conversion and FEN validation.

Two UCI subtleties worth noting (both handled here): go is asynchronous, so stdin is left open and no quit is sent before the search finishes — closing the pipe would abort it. And score cp/score mate are reported from the side-to-move's perspective, so we flip them when Black is to move to produce a consistent White-perspective evaluation.

AI usage in this project

Entirely written by Qwen3.8-Preview-Max

License

MIT.

A note on Stockfish: Stockfish itself is licensed GPL-3.0. This project does not include, link against, modify, or distribute Stockfish — it only spawns a Stockfish binary that you install separately and communicates with it over the public UCI protocol via a pipe. The two are separate programs, so this wrapper is independently licensed under MIT. You are responsible for obtaining Stockfish and complying with its license.