franchise-mcp-server
by seanpdwyer7
README.md
# franchise-mcp-server
An MCP (Model Context Protocol) server that lets LLMs read and edit **Madden NFL
franchise saves** and **EA SPORTS College Football dynasty saves (CFB 27+)**. It
wraps [bep713/madden-franchise](https://github.com/bep713/madden-franchise) — the
community-standard parser behind tools like Franchise Editor — and exposes its
full capability as a set of well-guarded tools. It also reaches the **Frostbite
game-asset layer** (textures/meshes/tuning inside the game files) via a headless
Frosty sidecar — see [Frostbite game-asset layer](#frostbite-game-asset-layer-frosty_-tools).
Supported games (inherited from the library): Madden 19–27, College Football 27+.
Both franchise saves and FTC (franchise-common) game-data files open.
```
┌────────────┐ MCP (stdio) ┌─────────────────────┐ ┌──────────────────┐
│ LLM client │ ◄─────────────────► │ franchise-mcp-server │ ◄────► │ madden-franchise │ ◄── CAREER-* / DYNASTY-* files
└────────────┘ └─────────────────────┘ └──────────────────┘
```
## Layout
```
franchise-mcp-server/
├── src/ TypeScript source
│ ├── index.ts server + tool registrations
│ ├── session.ts open-file sessions, table resolution, field loading
│ ├── serialize.ts field value ⇄ JSON conversion, validation, pagination
│ ├── types.ts structural types for the library
│ └── constants.ts
├── dist/ built JS (entry: dist/index.js)
├── tests/smoke-test.mjs end-to-end test (drives the server over stdio)
└── skills/franchise-editor/ ← docs for LLM agents
├── SKILL.md main skill (workflow + safety rules)
└── references/
├── domain-model.md file anatomy, references, free-lists
├── workflows.md step-by-step recipes
├── cfb-notes.md CFB 27 dynasty specifics
└── library-api.md building apps on the library directly
```
## Setup
Requires **Node.js >= 22.19.0**.
This server depends on madden-franchise via `file:../madden-franchise` — clone it
as a **sibling directory** (the repo version includes CFB 27 support that is
ahead of the npm release):
```bash
# 1. Clone both repos side by side
git clone https://github.com/bep713/madden-franchise.git
git clone https://github.com/<you>/franchise-mcp-server.git
# 2. Build the library
cd madden-franchise && npm install && npm run build
# 3. Build the server
cd ../franchise-mcp-server && npm install && npm run build
# 4. Smoke test against bundled CFB 27 test data (uses a copy!)
cp ../madden-franchise/tests/data/DYNASTY-27COMPRESS /tmp/DYNASTY-TEST
node tests/smoke-test.mjs /tmp/DYNASTY-TEST
```
### Register with Claude Code (project `.mcp.json`)
```json
{
"mcpServers": {
"franchise": {
"command": "node",
"args": ["<absolute-path-to>/franchise-mcp-server/dist/index.js"]
}
}
}
```
### Register with Claude Desktop (`claude_desktop_config.json`)
```json
{
"mcpServers": {
"franchise": {
"command": "node",
"args": ["<absolute-path-to>/franchise-mcp-server/dist/index.js"]
}
}
}
```
Give the agent the `skills/franchise-editor/` folder (Claude Code discovers it
from `.claude/skills/`; other agents can be pointed at SKILL.md directly).
## Tool catalog
### File lifecycle
| Tool | Purpose |
|---|---|
| `franchise_open` | Open a CAREER-*/DYNASTY-* file into a session. Options: `auto_unempty` (needed to add rows), `game_year_override`, `game_type_override`. Returns game/schema info. |
| `franchise_save` | Persist changes — overwrite, or `output_path` to save-as. Nothing is written to disk without this. |
| `franchise_close` | Close a session, discarding unsaved changes. |
| `franchise_list_open_files` | Sessions + which tables have unsaved changes. |
### Discovery
| Tool | Purpose |
|---|---|
| `franchise_list_tables` | Browse/filter the ~2,000+ tables (name, uniqueId, record count, capacity, isArray). |
| `franchise_get_table_schema` | Field definitions: type, min/max, maxLength, enum members, reference-ness, storage section. |
### Reading
| Tool | Purpose |
|---|---|
| `franchise_read_records` | Paginated row reads with field selection; `row_indices` for specific rows; array tables return ordered reference lists. |
| `franchise_get_record` | Every field of one row, field-paginated (Player has ~300 fields). |
| `franchise_search_records` | Find rows by field conditions (`eq/neq/contains/gt/gte/lt/lte`), e.g. player by name. |
### Writing
| Tool | Purpose |
|---|---|
| `franchise_edit_records` | Batch field edits with validation: range-checked ints, length-checked strings, enum-name checking, references as `{tableId,row}`/`{tableUniqueId,row}`/null, JSON blobs (CharacterVisuals). Echoes old→new values. Blocks writes to empty records unless `auto_unempty`. |
### References & row lifecycle
| Tool | Purpose |
|---|---|
| `franchise_resolve_reference` | Decode 32-bit refs (binary string, asset id, or tableId+row) to table name/uniqueId/row. |
| `franchise_find_references_to_record` | Which tables point at a record (run before removing/repurposing anything). |
| `franchise_get_empty_records` | Free-list state: `nextRecordToUse`, empty-row chain — the safe way to add rows. |
| `franchise_recalculate_empty_records` | Rebuild the free-list after bulk operations. |
## Bundled full CFB 27 schema
CFB save headers only declare one of the game's three schema namespaces, so
stock schema selection leaves key tables (notably **Team**) schema-less. This
server bundles the full combined schema (`data/schemas/CFB27_809_0.gz`,
major 809) and auto-applies it to college saves — unlocking real field names
for team identity, the native Media/Coaches/CFP polls, prestige, and records.
Schema extraction method credit:
[brooksg357-a11y/cfb27-dynasty-modding](https://github.com/brooksg357-a11y/cfb27-dynasty-modding).
## Design notes
- **Validation-first writes.** The underlying library bit-packs values and will
silently wrap out-of-range ints and corrupt free-lists if misused; this server
rejects out-of-range/oversized/invalid-enum writes and empty-record writes
with errors that state the valid values.
- **Stable identity.** Tools push agents toward `table_unique_id` (stable across
files and game years) over file-specific `tableId`s and ambiguous names.
- **Context-efficient.** Everything is paginated and field-selectable;
responses over ~25k chars truncate with explicit `truncated_by_size` +
`next_offset` metadata.
- **Edit-safe partial reads.** Field lists load incrementally; pending edits are
flushed to the table buffer before any re-read, so partial reads never lose
unsaved changes.
- **Sessions.** Multiple files can be open at once (e.g. copy data between a
Madden franchise and a CFB dynasty, or between a save and its backup).
## Known table uniqueIds
| Table | uniqueId | Verified |
|---|---|---|
| Player | `1612938518` | Madden 25/26, CFB 27 |
| CharacterVisuals | `1429178382` | CFB 27 |
Everything else: discover per-file with `franchise_list_tables` (name collisions
are common — eight tables named `Team` exist in CFB 27; pick by record count).
## Draft class files (CAREERDRAFT-*)
Three additional tools read and write Madden 25/26 shareable draft class
files directly (the CAREERDRAFT-* files the game imports/exports), separate
from franchise saves:
- **draftclass_read** — header + paginated prospects (~90 friendly fields
each: names, all ratings, draft round/pick, dev trait, body type,
portrait/commentary ids, college, full visuals JSON)
- **draftclass_get_prospect** — one prospect, everything, optional visuals
- **draftclass_edit_prospects** — apply field edits and write the file back
(auto-backup when overwriting in place)
Powered by [madden-draft-class-tools](https://github.com/WiiExpertise/madden-draft-class-tools)
by **WiiExpertise** (GPL-3.0) — all credit for the CAREERDRAFT format work.
## Frostbite game-asset layer (`frosty_*` tools)
Everything above edits **save files**. Four more tools reach the **game's own
Frostbite asset database** — the EBX objects, textures, meshes and gameplay
tuning inside CFB 27 / Madden 26 themselves — by driving MMC/Frosty's
`FrostySdk` **headlessly**. Proven on a real CFB 27 install: **1,012,545 assets**
loaded, searched, and read into typed JSON.
- **frosty_info** — profile + total asset count
- **frosty_search_assets** — find assets by name (optional type filter)
- **frosty_list_types** — distinct asset types with counts (discovery)
- **frosty_read_asset** — one asset → full typed JSON tree
These are **opt-in**: set `FROSTY_MMC_PATH` to your MMC/Frosty editor folder
(after building the sidecar there — see [`frosty-cli/`](frosty-cli/)). Unset, the
tools error with a hint and the save tools are unaffected. The server keeps one
long-lived sidecar per game, so the first call loads the asset DB (~20s) and the
rest are instant.
```
┌────────────┐ MCP ┌─────────────────────┐ stdin/stdout ┌──────────────┐
│ LLM client │ ◄─────► │ franchise-mcp-server │ ◄──────────────► │ frosty-cli.exe│ ◄── CFB27 / M26 game data
└────────────┘ └─────────────────────┘ (headless SDK) └──────────────┘
```
What's in there: gameplay/sim tunables live under `AttribSys/data/**`. Note that
**recruiting / NIL / dynasty logic is compiled, not in the asset layer** — the
asset DB only holds recruiting UI icons and cutscenes, so recruiting changes must
go through the save-file (`franchise_*`) tools. Read is proven; writing `.fbmod`
files is the next step. Build + boot recipe + honesty notes: [`frosty-cli/README.md`](frosty-cli/README.md).
## License
MIT (the wrapped madden-franchise library is MIT by matthewpanetta/bep713).
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessSyncing