Read-only MCP server for inspecting Stardew Valley save files: save parser, Stardew Wiki verification, and 17 calculators across 40 tools.
Project description
sdv-mcp
I recently got into the game with my wife and noticed I was spending more time reading the Stardew Wiki rather than playing, so I made this to answer the questions I had. This is a read-only MCP server that reads a Stardew Valley save and answers questions about it. It includes 40 tools, and also allows Stardew Wiki search through MediaWiki API. I made this with mainly vanilla in mind, so YMMV with mods.
This MCP is read-only and should not cause any issues, but safety first is always the best approach! Use a save copy first, not an original. Stardew Valley makes a one-night-before backup automatically, denoted by the sufix _old in the filename.
Requirements
- Python 3.10+
pip install -r requirements.txt(just themcpSDK; wiki client uses stdliburllib)
Keep the four modules in the same folder — the server imports the others from its own dir.
Install into a client
Recommended: uvx (auto-download, npx-style)
Needs uv. uvx clones/builds/caches the repo and runs it — no manual install, no venv:
{
"mcpServers": {
"sdv-mcp": {
"command": "uvx",
"args": [
"--from", "git+https://github.com/vehemont/sdv-mcp",
"sdv-mcp",
"--save-dir", "C:/Users/you/AppData/Roaming/StardewValley/Saves/FarmName_123456"
]
}
}
}
Pin a version with git+https://github.com/vehemont/sdv-mcp@v0.1.0. Once it's on
PyPI this collapses to "args": ["sdv-mcp", "--save-dir", "..."].
Alternative: run a local checkout
{
"mcpServers": {
"sdv-mcp": {
"command": "python",
"args": [
"/path/to/sdv-mcp/sdv_mcp_server.py",
"--save-dir", "C:/Users/you/AppData/Roaming/StardewValley/Saves/FarmName_123456"
]
}
}
}
macOS/Linux use python3; pip install -r requirements.txt first.
Either way: runs on stdio. Point --save-dir at your save FOLDER (main file
auto-located) or --save at the file; skip both and it auto-discovers.
Picking a save
Precedence for which save a tool reads:
- An explicit
save_pathon the tool call (a save file or a save folder). - The save configured at server startup —
--save-dir DIR/--save FILE, or theSDV_SAVE_DIR/SDV_SAVE_PATHenv var. Set this once in the MCP config and you never passsave_pathagain. A CLI flag overrides the env var. - Auto-discovery (Windows
%APPDATA%\StardewValley\Saves, macOS/Linux~/.config- Application Support, Steam Proton). One save = used; several = call
list_savesand pass the path.
- Application Support, Steam Proton). One save = used; several = call
Either a folder (.../Saves/FarmName_123456) or the file
(.../Saves/FarmName_123456/FarmName_123456) works everywhere a save is accepted —
given a folder, the main save file is auto-located (ignores _old backups and
SaveGameInfo).
Env-var config example (instead of the CLI flag):
"env": { "SDV_SAVE_DIR": "C:/Users/you/AppData/Roaming/StardewValley/Saves/FarmName_123456" }
``
## Disabling tools
Any tool you consider cheating/unfair can be turned off so the model never sees it.
Two knobs, both settable as a CLI arg (wins) or an env var:
- **Denylist** — `--disable-tools a,b,c` or `SDV_DISABLE_TOOLS=a,b,c`. Serves everything except those.
- **Allowlist** — `--enable-tools a,b,c` or `SDV_ENABLE_TOOLS=a,b,c`. Serves *only* those (disable is applied after).
```json
{
"mcpServers": {
"sdv-mcp": {
"command": "python",
"args": [
"/path/to/sdv-mcp/sdv_mcp_server.py",
"--save-dir", "C:/Users/you/AppData/Roaming/StardewValley/Saves/FarmName_123456",
"--disable-tools", "find_item,missing_museum,perfection"
]
}
}
}
Tools (40)
Save state
| Tool | What |
|---|---|
list_saves |
Discovered saves (farm + path) |
overview |
Date, players, shared money, lifetime earnings, deepest mine, version |
players |
Per-player levels, XP, XP-to-next, professions, spouse, backpack, house |
community_center |
Rooms done/left, incomplete bundles + exact items needed, Vault status |
museum |
Donations / 95 + next milestone (60 = Rusty Key) |
monster_goals |
Guild eradication goals: kills vs target + reward |
friendships |
Villager hearts/points + spouse, per player |
player_tools |
Each player's tools + upgrade tier |
wallet |
Keys/special items (Rusty Key, Skull Key, Club Card, ...) |
feed |
Animals, silo hay, fiber, days of feed covered (+ fiber-as-grass-starters) |
full_report |
All of the above in one shot |
Inventory + location
| Tool | What |
|---|---|
inventory |
Backpacks + chests. full=True = all items; by_container=True = per-chest |
processing |
Held crops grouped fruit/veg/special by the save's own item category |
chests |
Every container: type (Chest/Stone/Big/special), map + tile, color, contents |
find_item |
Where is X? Searches backpacks, chests, machine outputs. Map + tile + color |
net_worth |
Gold + sellable value of everything held (from each item's own price) |
Planning + completion
| Tool | What |
|---|---|
can_complete_now |
CC bundles you could finish from what's in your chests right now |
missing_museum |
Undonated minerals + artifacts, with where they drop |
perfection |
Real weighted Perfection %: 11 categories, each with have/total + earned % |
daily_briefing |
Morning digest: luck, birthdays, festivals, machines/crops ready, pets due |
gift_helper |
Birthdays (from save) + your hearts + loved gifts, flags what you already hold |
ready_to_collect |
Machines with product ready + crops ready to harvest |
fish_available |
Fish catchable now (season/weather/time), only_uncaught filters |
mods |
Detect mods; list what couldn't map to vanilla (modded ids, unmapped bundle/museum) |
Calculators (save + verified game formulas)
| Tool | What |
|---|---|
skill_xp_forecast |
Actions to hit a target skill level (farming XP formula) |
fishing_xp_forecast |
Catches to a target fishing level (difficulty/perfect/treasure/legendary) |
processing_planner |
Kegs/jars to clear the crop backlog in N days + est. gross gold |
processing_value |
Raw vs wine/juice vs jelly/pickle for a crop (Tiller/Artisan/quality aware) |
crop_planner |
Crops that mature in the window + profit/tile (quality_weighted optional) |
crop_quality_odds |
Gold/silver/normal/iridium % from farming level + fertilizer + food buff |
sprinkler_plan |
Sprinklers + materials for N tiles, and whether your bars can build them |
fish_pond_forecast |
Days to fill a pond to capacity + roe notes |
friendship_forecast |
Loved gifts + weeks to a target heart level |
animal_product_quality |
Iridium/gold/silver produce odds per animal (friendship + mood + prof) |
animal_product_value |
Raw (Rancher) vs processed (Artisan) value of milk/egg/wool |
list_buffs |
Food buffs that raise a skill level (Farmer's Lunch +3, Trout Soup +1) |
Wiki verification (live)
| Tool | What |
|---|---|
wiki_search |
Search the Stardew Valley Wiki (titles + snippets) |
wiki_page |
A page (or one section) as clean text — to verify facts / pull context |
wiki_infobox |
A page's infobox as structured fields (price/season/location) |
villager_schedule |
A villager's wiki schedule + your save's date/weather/hearts |
How the model reads the output
Inputs have per-parameter descriptions and enums for constrained args (quality = normal/silver/gold/iridium, artisan = auto/true/false, etc.). The 11 calculator tools also declare an output schema (field names + types) so the shape is known up front. MCP output schemas can't carry field descriptions, so every result also has a note with units/formulas/caveats — read it. Unit conventions in key names: *_pct = percent, *_gold = gold, *_days/days_* = days, *_xp = XP.
Mods
Item classification (keg fruit/veg) is data-driven from each item's own <category> in the save, so vanilla content of any version is covered automatically. Modded items get detected (namespaced ids with a dot) and excluded from vanilla-reference totals but reported by name/qty — see mods and processing.modded_items_excluded. Bundle structure is read from the save, so overhaul/remix CCs parse; modded item names the parser can't resolve show as #id. Full modded-name resolution (loading Data/Objects + the Mods folder) is intentionally not built yet.
Verified, not guessed
The calculator constants were checked against the wiki, not pulled from memory: crop quality formula + multipliers (iridium 2x / gold 1.5x / silver 1.25x), farming + fishing XP formulas, Tiller +10% / Rancher +20% / Artisan +40%, keg/jar multipliers, sprinkler recipes, fish-pond reproduction, Perfection weights, animal-product prices. Reference tables (crops, prices, fish difficulty) live at the top of sdv_calc.py and sdv_parser.py — extend them, or cross-check anything with the wiki_* tools.
Releasing
CI publishes to PyPI on a version tag via Trusted Publishing (OIDC - no tokens). One-time setup on PyPI: your account -> Publishing -> add a pending publisher:
- PyPI project:
sdv-mcpOwner:vehemontRepo:sdv-mcp - Workflow:
publish.ymlEnvironment:pypi
Then, per release:
# bump version in pyproject.toml, commit, then:
git tag v0.1.0 && git push --tags
.github/workflows/publish.yml builds, smoke-tests the wheel, and publishes.
First release without waiting on CI (uses your PyPI token):
uv build && uv publish # prompts for token, or set UV_PUBLISH_TOKEN
Packaging
pyproject.toml makes this a real package: uv build produces a wheel, and the sdv-mcp console script maps to sdv_mcp_server:main. Publish with uv publish.
Files
sdv_parser.py— the read-only save parser (ElementTree)sdv_wiki.py— MediaWiki Action API client (api.php; the wiki's rest.php returns empty, so Action API it is), cached + rate-limitedsdv_calc.py— the calculators + reference tablessdv_mcp_server.py— the 40 tools
Known limits
- Vanilla + whatever this wiki documents. Modded content lives on separate wikis.
- Full Shipment / missing-recipes by name aren't built yet —
perfectiongives the counts. - Wiki tools need outbound network. The save tools don't.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sdv_mcp-0.1.0.tar.gz.
File metadata
- Download URL: sdv_mcp-0.1.0.tar.gz
- Upload date:
- Size: 48.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ec92e837b32e6dc9c6c64510782b5641646bfa1cd797b77c6b2bf7ab157f63f5
|
|
| MD5 |
678f85fb1296a5fffe9aa89da4400c95
|
|
| BLAKE2b-256 |
37148842dea86b7778e55c902cf2597344b9b3c968b7af98c8ac820b2fb8451a
|
Provenance
The following attestation bundles were made for sdv_mcp-0.1.0.tar.gz:
Publisher:
publish.yml on vehemont/sdv-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sdv_mcp-0.1.0.tar.gz -
Subject digest:
ec92e837b32e6dc9c6c64510782b5641646bfa1cd797b77c6b2bf7ab157f63f5 - Sigstore transparency entry: 2168194603
- Sigstore integration time:
-
Permalink:
vehemont/sdv-mcp@9511d4af2d9f8d421ef4151f672df3d366c44c24 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/vehemont
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9511d4af2d9f8d421ef4151f672df3d366c44c24 -
Trigger Event:
push
-
Statement type:
File details
Details for the file sdv_mcp-0.1.0-py3-none-any.whl.
File metadata
- Download URL: sdv_mcp-0.1.0-py3-none-any.whl
- Upload date:
- Size: 46.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
455ca0b446bc9d9063fb3a78602d2fc6ef1a3dfdb5bb13a899a71d4c9315910a
|
|
| MD5 |
da92b8c09105fd82f45aa31433716c9c
|
|
| BLAKE2b-256 |
ccb8babf16a08c77edcb9272ad2f98c473035f5d2e95705195a292eb54a95299
|
Provenance
The following attestation bundles were made for sdv_mcp-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on vehemont/sdv-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sdv_mcp-0.1.0-py3-none-any.whl -
Subject digest:
455ca0b446bc9d9063fb3a78602d2fc6ef1a3dfdb5bb13a899a71d4c9315910a - Sigstore transparency entry: 2168194702
- Sigstore integration time:
-
Permalink:
vehemont/sdv-mcp@9511d4af2d9f8d421ef4151f672df3d366c44c24 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/vehemont
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9511d4af2d9f8d421ef4151f672df3d366c44c24 -
Trigger Event:
push
-
Statement type: