eve-fit-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@eve-fit-mcpbuild and validate a shield Drake fit for L4 missions"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
eve-fit-mcp
An MCP server for EVE Online ship fitting. Through it, an AI assistant can search items, build and validate fits, compute Pyfa-parity statistics, compare alternatives, run what-if scenarios, and let a batch-evaluating optimiser suggest modules.
It is engine-agnostic. Numbers come from any engine that implements the stateless
eve-dogma contract:
engine F (eve-fit, Rust, the mainline engine from EX-CT/eve-dogma; native
build of crate eve-cli at the commit pinned in engines.lock, LGPL-3.0-or-later) by default, or any
other contract engine via EVE_DOGMA_BIN: the older eve-dogma-f (eve-dogma-lab), eve-dogma-rs (eve-dogma,
variant A, frozen), the Go variant C, and so on. The engine runs
behind a pluggable adapter:
adapter | how | when |
| one long-running | desktop agents, servers |
| spawns | debugging, engines without |
| a remote engine server: | shared engine for several MCP instances, engine on another host |
The server also builds its own index of the same dataset-<build>.json.gz. It answers search, show-info,
ship layouts, skill trees, compatible charges and optimiser candidates, so none of that depends on engine
extras.
Transports: stdio, and Streamable HTTP (--http; stateless, POST /mcp, GET /healthz).
Tools
tool | what it does |
| ships/modules/charges/drones/fighters/implants/boosters/subsystems/skills by name, English or Chinese, with jargon ( |
| show-info: named attributes with units, effects, required skills (incl. prerequisites), compatible charges, other items in the same group, ship layout |
| slots, hardpoints, rig size, CPU/PG/calibration, drone bay, hull traits (role and per-skill bonus lines, en/zh), plus the empty hull's computed stats with skills |
| skill presets, pirate implant sets (from the dataset), incoming damage profiles, target profiles, metric keys |
| EFT / DNA / lenient JSON → strict contract FitRequest, every item named, |
| EFT (Pyfa-exact, from the engine), DNA, multibuy, JSON |
| violations with module names and fix hints, resource usage, missing skills |
| full stats: compact summary + named metrics, or |
| many fits in one engine call (docs/23 BatchRequest → BatchResponse, passed through): |
| 2–20 fits in one batch → metric × fit table with deltas and the best fit per metric |
| add/remove/replace modules, state, ammo, skills, drones, implants, boosters, profiles, options → deltas per scenario |
| ranks every compatible module for a slot (fill it, or replace module i) by a goal ( |
| for each weapon type in the fit, ranks every compatible charge by a goal ( |
| rank single-type drone flights within bandwidth, bay and the Drones skill; usable drones first, with missing skills |
| graph data: metrics vs target signature / target velocity / skill level / projected distance, in one batch |
| greedy local search: fill free slots, then apply the best swap until nothing improves. Takes budget, constraints, |
| every skill the fit needs, prerequisites included, and what the character lacks |
| applied DPS vs frigate…structure targets and EHP vs EM/thermal/…/NPC damage profiles in one batch |
| engine, adapter, dataset build/sha256, and whether engine and index use the same dataset |
| the in-game market tree: roots, a group by id / name / |
| the engine's graphs (Pyfa graph set: DPS/volley vs range, applied DPS vs target speed/signature, cap, speed/distance vs time, warp, EHP/RPS, lock time …) with their axes, defaults and whether they need a target |
| one graph for a fit: |
| prices for types by id or name, from ESI (universe average) or Fuzzwork (trade-hub sell/buy), with source and age |
| load / update the engine's injected price file (docs/23 file layer, = |
| Pyfa-style price panel. With a docs/23 engine the engine prices the fit: the MCP injects the market table (+ your own |
Fit inputs are the same for every fit tool. Give exactly one of eft, dna or fit (contract
FitRequest; names are accepted wherever ids are, e.g. "modules": ["200mm AutoCannon II, EMP S"]).
Optional extras: skills (0–5, all_4, or {default_level, levels: {"Gunnery": 4}}; default all V),
damage_profile, target_profile, implant_set.
Resources:
eve://dataset/metaeve://schema/fit-request,eve://schema/fit-statseve://presets,eve://jargon,eve://metricseve://guide/fittingeve://type/{id},eve://ship/{id}/layout,eve://ship/{id}/modules/{slot}eve://prices/sources
Prompts: fit_for_role, review_fit, explain_stat, compare_options.
JSON Schemas of all tool inputs are in schemas/tools/ (npm run schemas regenerates them
from the live server). The contract schemas are in schemas/fit-request.schema.json / fit-stats.schema.json.
Related MCP server: worldbrain-mcp
Quick install (release package)
Every v* tag publishes a GitHub Release with a prebuilt npm
tarball (eve-fit-mcp.tgz, plus SHA256SUMS). Nothing is published to the npm registry. Install the package
straight from the release.
Dataset: download the latest
dataset-*.json.gzfrom EX-CT/eve-sde-pipeline releases:gh release download -R EX-CT/eve-sde-pipeline -p 'dataset-*.json.gz'. The release'smanifest.jsonnames the file and its SHA-256.Engine: the default is
eve-fit(engine F) onPATH. F compiles the dataset into the binary, so build it with the same file you give the MCP (stable Rust; the commit is the one inengines.lock):EVE_DOGMA_DATASET=/path/to/dataset.json.gz cargo install --locked \ --git https://github.com/EX-CT/eve-dogma --rev 8bde0ba83c19c31267c88ae1b572b2baab2f3b0b eve-cli # installs eve-fitAny other contract engine works through
EVE_DOGMA_BIN, e.g. eve-dogma-rs (variant A, frozen):cargo install --git https://github.com/EX-CT/eve-dogma-rsandEVE_DOGMA_BIN=eve-dogma.Add the server to your client. Replace
/path/to/dataset.json.gzwith the file from step 2.Cursor (one click):
then edit
EVE_DOGMA_DATASETin the install dialog.Claude Code:
claude mcp add eve-fit -e EVE_DOGMA_DATASET=/path/to/dataset.json.gz -- npx -y --package=https://github.com/EX-CT/eve-fit-mcp/releases/latest/download/eve-fit-mcp.tgz eve-fit-mcpVS Code:
code --add-mcp '{"name":"eve-fit","command":"npx","args":["-y","--package=https://github.com/EX-CT/eve-fit-mcp/releases/latest/download/eve-fit-mcp.tgz","eve-fit-mcp"],"env":{"EVE_DOGMA_DATASET":"/path/to/dataset.json.gz"}}'Claude Desktop / any
mcpServersJSON:{ "mcpServers": { "eve-fit": { "command": "npx", "args": ["-y", "--package=https://github.com/EX-CT/eve-fit-mcp/releases/latest/download/eve-fit-mcp.tgz", "eve-fit-mcp"], "env": { "EVE_DOGMA_DATASET": "/path/to/dataset.json.gz" } } } }
To pin a version, replace latest/download/eve-fit-mcp.tgz with e.g. download/v0.4.2/eve-fit-mcp-0.4.2.tgz. To install
globally, run npm install -g https://github.com/EX-CT/eve-fit-mcp/releases/latest/download/eve-fit-mcp.tgz and use "command": "eve-fit-mcp". Check the install with
npx -y --package=https://github.com/EX-CT/eve-fit-mcp/releases/latest/download/eve-fit-mcp.tgz eve-fit-mcp --help.
Install from source
git clone https://github.com/EX-CT/eve-fit-mcp && cd eve-fit-mcp
npm ci && npm run build
# the default engine, F (eve-fit from EX-CT/eve-dogma; pinned commit in engines.lock, see "Quick install" step 2),
# or any contract engine via EVE_DOGMA_BIN (eve-dogma-rs, variant C, ...)
# a dataset: dataset-<build>.json.gz from the EX-CT/eve-sde-pipeline releasesConfiguration (environment)
variable | default | meaning |
| (required) | dataset used by the engine and the search index (also needed with |
|
| engine binary (F by default; e.g. |
|
|
|
| – | engine base URL for |
|
| rpc command template |
|
| cli templates |
|
| rpc engine processes |
|
| per engine call |
|
| skill level when a fit gives none (engines alone default to 0) |
|
| candidate budget per suggest call (optimise: 4×, capped at 1600) |
|
| calc results cached in memory by exact request ( |
|
| for |
| loopback + bind host | extra |
|
|
|
|
| Fuzzwork trade hub: |
|
| price cache directory; |
|
| price cache lifetime (ESI: its |
| – | injected price file loaded into the engine at start: path / URL of an eve-price-snapshot v1 or |
|
| releases used by |
| – |
|
| names this project | User-Agent for ESI / Fuzzwork; add your contact (ESI etiquette) |
| public endpoints | override the price endpoints (mirrors, tests) |
The templates make any engine pluggable. For example, eve-dogma-rs (variant A): EVE_DOGMA_BIN=/path/eve-dogma;
variant C (Go): EVE_DOGMA_BIN=/path/eve-dogma-go (same CLI shape; its serve mode adds a response memo). F (eve-fit, and the older eve-dogma-f)
accepts and ignores --dataset (its dataset is compiled in), so the default templates work for all of them.
Claude Desktop
~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json:
{
"mcpServers": {
"eve-fit": {
"command": "node",
"args": ["/path/to/eve-fit-mcp/dist/main.js"],
"env": {
"EVE_DOGMA_BIN": "/path/to/.cargo/bin/eve-fit",
"EVE_DOGMA_DATASET": "/path/to/dataset-3569502.json.gz"
}
}
}
}Cursor
~/.cursor/mcp.json (or .cursor/mcp.json in a project):
{
"mcpServers": {
"eve-fit": {
"command": "node",
"args": ["/path/to/eve-fit-mcp/dist/main.js"],
"env": {
"EVE_DOGMA_BIN": "/path/to/eve-fit",
"EVE_DOGMA_DATASET": "/path/to/dataset-3569502.json.gz",
"EVE_FIT_WORKERS": "2"
}
}
}
}Over HTTP: run EVE_DOGMA_BIN=… EVE_DOGMA_DATASET=… node dist/main.js --http --port 8765 and point the client
at http://127.0.0.1:8765/mcp (Cursor: {"url": "http://127.0.0.1:8765/mcp"}). The server binds to localhost
by default and has no authentication. Put a reverse proxy with auth in front before exposing it.
Prices
Prices are computed by the engine (EX-CT/eve-fit-docs docs/22 / docs/23): price_overrides by type / market group
(with children) / group / category, fixed (0 = self-built) or multiplier; precedence variant overrides > request overrides >
injected prices (prices.isk) > the engine's market snapshot (Jita 4-4 sell band rule, made by
EX-CT/eve-market-prices). The MCP only resolves names to ids and passes the
fields through (compute_fit, compute_batch, price_fit); it does no pricing math once the engine returns a price block.
price_fit injects the live market table, so the engine's embedded snapshot (eve-dogma 8bde0ba+: jita44-20261003T063856Z)
only fills items without a market price (use_snapshot: false leaves them unpriced); every line names its source.
Every engine result carries provenance (docs/22 §2.3: sde_build, sde_hash, sde_source, price_source
request / file / snapshot / none, snapshot_time, price_snapshot_id, price_hash, engine). compute_fit
returns it in the summary and as a detail=full section, compute_batch at the top level and per result (and in its
table header), price_fit next to the price block.
Price data layers (docs/23 §5): request price_overrides > request prices.isk > the injected price file
(load_prices / EVE_FIT_PRICES, the engine's --prices FILE / RPC prices_load) > the engine's embedded snapshot.
load_prices {source: "latest"} updates to the newest daily eve-market-prices snapshot without a new engine release.
Errors from the engine keep their contract code verbatim (Error: UNKNOWN_TYPE: …, BAD_PRICE_OVERRIDE, BATCH_TOO_LARGE, …);
input errors found by the MCP itself are BAD_REQUEST. The tool result also carries the engine's error object as
structuredContent.error with all its fields (e.g. BATCH_TOO_LARGE count / limit).
get_prices and price_fit are the only tools that use the network, and only when they are called.
source | endpoint | price |
| CCP ESI |
|
|
| hub sell 5th percentile (and buy 95th percentile) |
Prices are cached in memory and on disk (prices-<source>-<system>.json) for EVE_FIT_PRICE_TTL_S. On a network
error the cache is used whatever its age, and with EVE_FIT_OFFLINE=1 nothing is fetched; both cases say so in the
answer (stale, age_s). Prices are indicative only: market data lags, and averages are not what you pay in a hub.
Attribution: EVE Online market data comes from CCP's ESI under the CCP Developer License; EVE Online and all related marks are property of CCP hf. Trade-hub aggregates are provided by Steve Ronuken's Fuzzwork; please keep request volume low (this server batches one request per lookup and caches).
Example
"Here's my Rifter (EFT …). What's the best low slot for more DPS without losing cap stability?"
The assistant calls suggest_modules with
{eft, replace_index: 1, goal: "dps", constraints: {min: {cap_stability: 0}}}. Every compatible low-slot
module is computed in one batch, and the reply is a ranked table:
| # | module | Δ dps | cpu left | pg left |
|---|---------------------------------|-------|----------|---------|
| 1 | Tobias' Modified Gyrostabilizer | 9.2 | -27.75 | 1.34 |
…Development
npm test # builds, then runs unit tests and integration tests that spawn the real engine on the real dataset
npm run schemas # regenerate schemas/tools/*.jsonTests find the engine and dataset through EVE_DOGMA_DATASET, EVE_DOGMA_BIN (default engine: F; set it to
eve-dogma-rs or another engine to test that one) and EVE_DOGMA_GO_BIN (variant C). Without them, they look for
sibling checkouts under EVE_FIT_DEV_ROOT, which defaults to the parent directory of this repo:
data/dataset-3569502.json.gz, eve-dogma/target/release/eve-fit (else lab-f/variant-f/target/release/eve-dogma-f) and
lab-c/variant-c/bin/eve-dogma-go.
Suites whose engine or dataset is missing are skipped. CI's test job runs the unit tests (Node 20 and 22); its
engine job builds F (eve-fit) from engines.lock on the latest SDE-pipeline dataset and runs the integration suites
against it (only the variant C suites skip there). They cover:
every tool, resource and prompt;
EFT/DNA/JSON equivalence;
the cli adapter, the worker pool, the http adapter (against
eve-dogma-go serve-http), and variant C as the engine (identical numbers and identical EFT export);a bad engine binary;
Streamable HTTP;
engine values through
compute_fit(src/test/stats.test.ts, Pyfa-backed numbers) and validation (src/test/validation.test.ts, benchval_*cases).
Every test title starts with a stable id (mcp.<file>.<slug>); docs/test-ids.md lists them with
the docs/19 inventory items each covers (python3 tools/test-ids.py regenerates it).
mcp-bench. tools/mcp-dogma-bench.py replays eve-dogma-bench cases through the MCP (stdio, compute_fit detail:"full") and scores them with the bench tolerances: core (339), ext (Pyfa stats-ext suite), effects (2378 per-effect
micro-fits; must equal the engine run directly) and cap (150). CI's engine job runs all four at the bench commits in
engines.lock and fails below the engine's own score.
python3 tools/mcp-dogma-bench.py run --bench ../eve-dogma-bench --cap-bench ../eve-dogma-bench-cap --suite core,ext,effects,cap --out mcp-bench.jsonDesign notes
Stateless. Every call carries the whole fit. Notes say what was assumed (e.g. skills).
request_hashis the sha256 of the canonical normalised request.Engine vs index. The engine owns every number. The index only answers "what exists" and filters optimiser candidates statically (slot, ship restrictions, rig size, hardpoints). Engine violations have the final word.
Optimiser budget. When a slot has more candidates than the budget allows,
suggest_modulesfirst evaluates one representative per group (the T2 item, else the highest meta), then every variant of the best 6 groups.NPC damage profiles are rounded community figures, marked approximate. Target profiles are typical hull sizes.
Licence
MIT. EVE Online data © CCP hf., used under the CCP developer licence.
This server cannot be deployed
Maintenance
Related MCP Connectors
Persistent memory, hybrid search and a goal graph for AI agents, over stdio or remote HTTP.
AI Reasoning Cache & Consensus Layer with 11 MCP tools via Streamable HTTP.
Build, validate, deploy — HTTP APIs, cron jobs, webhooks and MCP tools — from your AI client.
Query, browse, and automate OmegaAI workspaces from any MCP client. Streamable HTTP with OAuth 2.0.
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables AI assistants to manage Docker containers, execute commands inside them, and inspect container information through a minimalist set of tools supporting both stdio and HTTP transports.3109 npm1MIT
- AlicenseNot gradedqualityFmaintenanceEnables AI agents to perform auditable A* reasoning, import world graphs, incorporate physical carrier constraints, and maintain a learning knowledge base through a zero-dependency local MCP stdio service.MIT
- AlicenseAqualityBmaintenanceEnables AI agents to perform exact, reproducible mechanical computation — text diffing, hashing, JSON querying, calendar arithmetic, deadline-bounded regex extraction, CSV parsing, similarity scoring, unit and base conversion — instead of relying on probabilistic guessing. Runs dependency-free, read-only and offline over stdio, with schema validation and hard caps on every operation so no call can hang the client.1539 npmMIT
- FlicenseBqualityBmaintenanceEnables an AI assistant to read and manage a local project-management database over stdio: listing and creating projects, tasks, expenses, chats and people, and pulling money, margin, deadline and overdue summaries. It runs on the same service layer and SQLite file as the bundled web UI, so figures shown to the assistant and to the human always agree.14-