Skip to main content
Glama

sims4-tc-mcp

Disclaimer: This is a vibecoded project

A Model Context Protocol server for building, inspecting, packaging and debugging script mods (.ts4script) and total conversions for The Sims 4.

Point any MCP-capable agent (OpenCode, Claude Desktop, Cursor, …) at it and it can hash resources, read/write .package files, search vanilla tuning, validate Python 3.7 for the game's interpreter, patch catalog flags, package .ts4script zips, and parse lastException tracebacks.

Built on the official mcp Python SDK, lxml, pydantic v2 and SQLite FTS5.

Features

Subsystem

What it does

crypto/fnv.py

FNV-1 24/32/64 hashing, lowercase normalization, high-bit toggling

dbpf/

DBPF 2.1 .package reader/writer, index v3, constant-encoding flags, ZLIB fallback

stbl/

STBL v5 codec + one-shot 18-locale dictionaries

tdesc/

.tdesc schema parser, SQLite cache, XML skeletons

simdata/

0x545AC67A v0x101 codec + curated XML→SimData compilers (Trait, Buff, Aspiration)

tuning/

FTS5 vanilla tuning index + reverse-reference dependency graph

pyengine/

Decompiled game Python index, Python 3.7.0 AST gatekeeper, pyc-3394 headers, injectors, .ts4script packager

catalog/

CASP 0x034AEECB / COBJ 0x319E4F1D / OBJD 0xC0DB5AE7 flag patchers + batch overrides

live_bridge/

In-game TCP bridge generator, outbound client, lastException diagnostics

Related MCP server: paradox-toolkit

Requirements

  • Python 3.11+ (the package pins 3.12 through uv)

  • uv

  • Linux or macOS; the stdio server also runs on Windows, the auto-setup helpers are POSIX-oriented (systemd/desktop launcher)

Install

git clone https://github.com/SomeoneToldJotaroDolphins-AreGood/sims4-tc-mcp.git
cd sims4-tc-mcp
uv sync

Run the test suite (107 tests):

uv run pytest

One-click setup

sims4-tc-mcp-setup finds your game folder, creates a bearer token, writes a config file, and starts the server — no environment variables needed:

uv run sims4-tc-mcp-setup --tui      # interactive menu (recommended)
uv run sims4-tc-mcp-setup --auto     # zero questions, background service
uv run sims4-tc-mcp-setup --status   # what was detected / is it running?
uv run sims4-tc-mcp-setup --launcher # add a desktop icon that opens the TUI

The TUI shows detected paths, lets you start the server in the foreground or as a systemd user service, change the port, and print a ready-to-paste client config.

Auto-detected game folders:

Installation

User folder

Steam Play / Proton

~/.steam/steam/steamapps/compatdata/1222670/pfx/drive_c/users/*/Documents/Electronic Arts/The Sims 4

Steam (Flatpak)

~/.var/app/com.valvesoftware.Steam/.local/share/Steam/.../1222670/...

EA app / native

~/.local/share/feral-interactive/TheSims4/VFS/Prefs/Electronic Arts/The Sims 4

Wine / Lutris

~/Games/*/drive_c/users/*/Documents/Electronic Arts/The Sims 4

Native Windows-style

~/Documents/Electronic Arts/The Sims 4

It also picks up ~/sims4/extracted/tuning, ~/sims4/extracted/tdesc and ~/sims4/decompiled when they exist. Anything missing can be overridden with --user-dir/--mods-dir/--tuning-dir/--tdesc-dir/--scripts-dir.

Settings live in ~/.config/sims4-tc-mcp/config.json (mode 0600) with the token in ~/.config/sims4-tc-mcp/token. Environment variables still take precedence, so containers and CI keep working.

Manual run

stdio (the default; what desktop MCP clients spawn):

uv run sims4-tc-mcp

Nothing is printed — stdio is a silent JSON-RPC pipe. To poke at it:

uv run mcp dev src/sims4_mcp/server.py

HTTP (for remote clients):

SIMS4_MCP_TRANSPORT=streamable-http \
SIMS4_MCP_HOST=0.0.0.0 \
SIMS4_MCP_PORT=7348 \
SIMS4_MCP_AUTH_TOKEN="$(openssl rand -hex 24)" \
uv run sims4-tc-mcp

Binding any non-loopback interface without SIMS4_MCP_AUTH_TOKEN refuses to start. Loopback binds may run token-less.

Configuration

All paths are optional. Without game files the server still works; tools that need an index report unconfigured with a hint instead of failing.

Variable

Purpose

SIMS4_USER_DIR

…/Documents/Electronic Arts/The Sims 4 (default guess used if unset)

SIMS4_MODS_DIR

Mods folder — default source_dir for catalog overrides

SIMS4_EXTRACTED_TUNING_DIR

Extracted Maxis XML tuning (Sims 4 Studio / Lot51) for FTS + graph

SIMS4_TDESC_DIR

Extracted .tdesc schema files

SIMS4_DECOMPILED_SCRIPTS_DIR

Decompiled game Python (base, core, simulation, protocolbuffers)

SIMS4_MCP_CACHE_DIR

SQLite cache root (default ~/.cache/sims4-tc-mcp)

SIMS4_MCP_TRANSPORT

stdio (default), streamable-http or sse

SIMS4_MCP_HOST / SIMS4_MCP_PORT

HTTP bind (default 127.0.0.1:7348)

SIMS4_MCP_AUTH_TOKEN

Bearer token; required for any non-loopback bind

SIMS4_MCP_CONFIG

Config file override (default ~/.config/sims4-tc-mcp/config.json)

Build the indexes once the data is available:

// tools: rebuild_indexes(tuning=true, python_api=true, tdesc=true, force=false)

Remote use (game PC → laptop)

Run the server where the game and its files live, connect from anywhere on the LAN:

# on the game machine
uv run sims4-tc-mcp-setup --tui     # option 2 installs + starts the service

Then open the port on that machine (Fedora example):

sudo firewall-cmd --add-port=7348/tcp --permanent && sudo firewall-cmd --reload

The token is plain HTTP on the LAN; use an SSH tunnel if you cross untrusted networks:

ssh -L 7348:127.0.0.1:7348 user@game-pc

OpenCode configuration

opencode.jsonc (project root or ~/.config/opencode/opencode.jsonc). Servers go under mcp.servers:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "servers": {
      // local stdio variant (server on the same machine)
      "sims4-tc-mcp": {
        "type": "local",
        "command": ["uv", "run", "--directory", "/path/to/sims4-tc-mcp", "sims4-tc-mcp"],
        "environment": {
          "SIMS4_USER_DIR": "~/Documents/Electronic Arts/The Sims 4",
          "SIMS4_MODS_DIR": "~/Documents/Electronic Arts/The Sims 4/Mods"
        }
      },
      // remote variant (server on the game PC)
      "sims4-tc-mcp-remote": {
        "type": "remote",
        "url": "http://192.168.1.50:7348/mcp",
        "headers": { "Authorization": "Bearer <token>" },
        "timeout": { "startup": 15000 }
      }
    }
  }
}

uv run sims4-tc-mcp-setup --print-client-config prints exactly this block with your detected address and token filled in.

Tools

Tool

Description

hash_fnv(text, bits, high_bit)

Hex / decimal / TGI representations

inspect_package(package_path)

TGI list with types, sizes, names, decoded metadata

extract_package_resource(package_path, tgi, output_path?)

Decodes XML, STBL, SimData, catalog resources

build_package(output, project_dir)

Compiles tuning XML + STBL dicts + binaries (+ auto-SimData)

create_stbl_dictionary(strings, base_name, generate_all_locales)

Writes all 18 locale STBLs, returns 0x keys

query_tdesc_schema(class_name)

Schema fields, export modes, starter XML

search_vanilla_tuning(query, class_filter, limit)

FTS5 search

read_vanilla_tuning(instance_id)

Full XML

get_tuning_dependency_graph(instance_id, direction, depth)

Reverse-reference BFS

compile_tuning_with_simdata(xml_content, output_dir)

Validates XML and emits companion SimData

search_game_python_api(query)

Classes, methods, signatures, docstrings

generate_runtime_tuning_hook(hook_type, config_json)

Gatekeeper-checked injection/strip code

validate_and_build_ts4script(source_dir, output_path)

3.7 AST checks + deterministic zip

batch_create_catalog_overrides(resource_type, filter_query, …)

CASP/COBJ/OBJD override package

analyze_last_exception(sims4_docs_dir?)

Structured tracebacks cross-referenced with indexes

bridge_send_command(host, port, command, …)

Live hot-reload / telemetry client

rebuild_indexes(…)

Maintenance for all three SQLite indexes

Resources: sims4://config, sims4://indexes. Prompt: total_conversion_workflow.

Project layout

project/
  tuning/*.xml          # tuning documents (i:id or s=/n=)
  *.stbl.json           # {"base_name": "...", "locales": {...}}
  bin/*.bin + *.tgi     # raw binary resources with TGI sidecars
build_package("/path/MyMod.package", "/path/project")

Notes & limitations

  • SimData format is community RE'd and table-specific; the codec is generic and round-trip safe, while XML auto-compilation supports the registry in simdata/compilers.py (extend with register()).

  • .pyc files: only 16-byte CPython 3.7 headers (magic 3394) can be produced on a newer host. .ts4script ships .py source, which the game compiles itself — that is the supported path.

  • Catalog flags: CASP AllowForRandom uses the officially documented partFlags bit 2. COBJ flag-word semantics are partially undocumented; the patcher exposes configurable word/bit targets (CASP conventions by default) and preserves every other byte.

  • Live bridge binds loopback only and requires a shared token; exec is disabled unless explicitly allowed on both sides.

Development

uv sync
uv run pytest -q              # 107 tests
uv run pytest -v tests/test_dbpf.py

Coverage: FNV known answers, DBPF round-trips across flag combinations, STBL v5 + 18 locales, SimData codec + compilers, tuning FTS + graph, gatekeeper matrices, pyc headers, injector templates, packager, CASP/COBJ/OBJD patching, HTTP transport + bearer auth, setup detection, and every MCP tool (in-process client included).

Security

The HTTP transport exposes file-reading and file-writing tools. It requires a bearer token for every request and refuses to bind a non-loopback interface without one. Never commit the token (.gitignore covers the common names).

Please report vulnerabilities privately — see SECURITY.md.

License

MIT — see LICENSE.

Disclaimer

Not affiliated with or endorsed by Electronic Arts, Maxis, or Mod The Sims. The Sims is a trademark of Electronic Arts Inc. This project ships no game assets; you need your own legally installed copy of the game.

Available Tools

17 tools
analyze_last_exceptionB

Parse the newest lastException/lastUIException/lastCrash file and cross-reference it with the game Python and tuning indexes.

Inputs: sims4_docs_dir.

batch_create_catalog_overridesC

Bulk-patch CASP/COBJ/OBJD catalog flags into an override package.

When no sources are given, ``SIMS4_MODS_DIR`` is scanned.

Inputs: filter_query (required), resource_type (required), output_package (required), disable_random_spawn (required), +3 more.

bridge_send_commandC

Send a command to a running game via the live bridge .ts4script.

Inputs: host (required), port (required), command (required), token, +2 more.

build_packageB

Compile a project dir (XML + .stbl.json + .bin/.tgi) into a package.

Tuning XML gets companion SimData automatically when its class needs client-binary data.

Inputs: project_dir (required), output_package_path (required).

compile_tuning_with_simdataC

Validate tuning XML and compile matching 0x545AC67A SimData.

Inputs: output_dir (required), xml_content (required).

create_stbl_dictionaryC

Hash string references and write STBL resources (all 18 locales).

Each item: {"key": "mod:thing.name", "text": "Display Name",
"locale": "en_us"} (locale optional).

Inputs: strings (required), base_name (required), output_dir, generate_all_locales.

extract_package_resourceC

Extract one resource by TGI and decode it (XML/STBL/SimData/catalog).

Inputs: tgi (required), package_path (required), output_path.

generate_runtime_tuning_hookC

Generate Python 3.7 injection/stripping code for runtime hooks.

hook_type: add_interaction | remove_interaction |
add_autonomy_commodity | start_buff | filter_super_affordances.

Inputs: hook_type (required), config_json (required).

get_tuning_dependency_graphC

Cross-tuning reference graph (what depends on / is used by a tuning).

Inputs: instance_id (required), depth, direction.

hash_fnvA

Hash a string with FNV-1 (Sims 4 resource/tuning convention).

Returns decimal, hex and TGI-instance representations.  STBL keys use
bits=32, high_bit=True; custom tuning instances use bits=64.

Inputs: text (required), bits, high_bit.

inspect_packageC

List every TGI entry in a .package with type, sizes and metadata.

Inputs: package_path (required).

query_tdesc_schemaC

Return the tunable schema + starter XML for a tuning class.

Inputs: class_name (required).

read_vanilla_tuningC

Return the complete XML of an indexed vanilla tuning.

Inputs: instance_id (required).

rebuild_indexesC

(Re)build the vanilla tuning, game Python and TDESC indexes.

Inputs: force, tdesc, tuning, python_api.

search_game_python_apiC

Search decompiled Maxis Python classes, methods and docstrings.

Inputs: query (required), limit.

search_vanilla_tuningC

Full-text search over the indexed Maxis tuning XML database.

Inputs: query (required), limit, class_filter.

validate_and_build_ts4scriptC

Run the Python 3.7 AST gatekeeper then bundle a .ts4script zip.

Inputs: source_dir (required), output_path (required), strict, module_name.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    B3/5.0

    Scored across 17 tools

    Disambiguation4/5

    Most tools map to a unique resource+action (package inspect/extract/build, tuning search/read, STBL creation, script build, live bridge, exception analysis). A few boundaries blur: `build_package` already handles .stbl.json while `create_stbl_dictionary` also writes STBL resources, and `compile_tuning_with_simdata` overlaps conceptually with package building and `query_tdesc_schema`'s starter XML. `hash_fnv` also partially duplicates the hashing inside `create_stbl_dictionary`, but descriptions make the intended split workable.

    Naming Consistency4/5

    Nearly all tools follow a snake_case verb_noun pattern (inspect_package, build_package, search_vanilla_tuning, validate_and_build_ts4script). The main deviation is `bridge_send_command`, which uses noun_verb ordering, plus the short `hash_fnv` which names the algorithm rather than a clear object. Still highly readable and predictable overall.

    Tool Count4/5

    At 17 tools this is on the heavy side, but the surface spans genuinely different workflows (package I/O, tuning index/search, STBL, SimData compile, Python API exploration, live bridge, crash triage). Each tool appears to earn its place rather than being a near-duplicate, though a few could conceivably be folded together.

    Completeness4/5

    The modding lifecycle is well covered: index building, vanilla tuning discovery, schema lookup, XML validation, SimData compile, STBL creation, package build/extract, script bundling, and crash analysis. Gaps remain around mutating existing packages (only inspect/extract, no add/remove/replace resource), and `bridge_send_command` has no companion for reading bridge responses, which limits round-trip debugging.

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables MCP clients to research game mods by searching documentation and definitions, inspecting dependencies and playsets, validating saved files with structural and Tiger checks, and preparing or editing mod content with preview and write controls. It also supports starting or previewing the game through a local stdio connection.
      8 npm
      GPL 3.0
    • A
      license
      B
      quality
      C
      maintenance
      Enables MCP clients to explore a local War Selection installation by reading mod code, game JSON data, logs, and Lua API indexes, while also linting mods, parsing Lua log errors, diffing mod and game versions, generating scaffolds, and watching logs in real time.
      26
      MIT
    • A
      license
      Not graded
      quality
      C
      maintenance
      An MCP toolkit that gives coding agents bounded, provenance-backed evidence about Minecraft projects, including declared project facts, version-aware mapping and source references, and classified build or runtime diagnostics. It also exposes opt-in tools for permitted Gradle tasks, bounded client launches, and configured external providers, with modular skills for Java, client, server, Mixin debugging, and anti-cheat compatibility work.
      11
      MIT