Skip to main content

A Python client for The Mana World, exposed as an MCP server so an AI agent can play the game.

Project description

tmw-mcp

A Python client for The Mana World (a tmwAthena-based MMORPG) exposed as an MCP server. Point any MCP-capable AI agent at it and the agent can log in, walk around, fight, trade, and talk to NPCs.

The bot also runs as an interactive CLI for humans, and ships with an optional browser dashboard.

Please follow the server rules

The Mana World's game rules explicitly forbid AFK botting. Treat this MCP server as an attended assistant: stay at the keyboard while your character is logged in, prompt the bot to respond to chat and GMs in a timely way, and disconnect before stepping away. Running it unattended may get your account banned.

Install

pip install tmw-mcp

The only third-party dependency is mcp. Game data (maps, items, monsters, sprites) is fetched on first login from the server's update host and cached under ~/.cache/tmw-mcp/; nothing to clone or unpack.

Register an account

tmw-mcp-register --user MyAccount --char-name MyCharacter

This writes a credentials.json (chmod 600, owner read/write only) in the current directory. Treat it like any other secret. tmw-mcp looks for it in its own current working directory by default, so the simplest setup is to run the host from this same directory; otherwise point at the file explicitly with TMW_CREDENTIALS_FILE (covered below).

Using an existing account

If you already have a TMW account and character, you can skip tmw-mcp-register and write credentials.json by hand. The full shape is:

{
  "server": "server.themanaworld.org",
  "port": 6901,
  "username": "MyAccount",
  "password": "hunter2",
  "char_name": "MyCharacter"
}

Only username and password are required; the rest fall back to the defaults shown above. char_name picks which character on the account to log in as; omit it to use the account's first character. Remember to chmod 600 credentials.json so it's owner-only, and keep it out of git.

Use it from an MCP client

Recommended: Claude Code

Claude Code is the only MCP host today that wakes the agent on notifications/claude/channel messages, which is how the bot surfaces chat, NPC dialog, combat damage, death, map changes, and the ferry-bell effect in real time. Without that, the bot only acts when you prompt it, which is fine for short tasks but turns the game into "ask the bot what's happening" instead of "the bot tells you." If you have a choice, use this one.

claude mcp add tmw -- tmw-mcp      # writes .mcp.json in the current project
                                   # (or add -s user for ~/.claude.json)

Equivalent in JSON, drop into .mcp.json at your project root by hand:

{
  "mcpServers": {
    "tmw": {
      "command": "tmw-mcp"
    }
  }
}

Verify with claude mcp list; remove with claude mcp remove tmw.

The reactive-wakeup channel is gated behind a Claude Code dev flag. Launch claude with --dangerously-load-development-channels server:tmw so the host actually subscribes to notifications/claude/channel from this server; without the flag every other tool still works, you just don't get the wake-up on in-game events.

Other hosts (no wake-ups)

The tool surface is identical across hosts; what you lose without Claude Code is just the wake-up channel, every tmw tool itself works the same. Pick whichever fits your workflow.

Claude Desktop, Cursor, Cline. Same mcpServers shape as Claude Code, just in a different config file:

{ "mcpServers": { "tmw": { "command": "tmw-mcp" } } }
Host Config path
Claude Desktop ~/Library/Application Support/Claude/claude_desktop_config.json (macOS), %APPDATA%\Claude\claude_desktop_config.json (Windows)
Cursor ~/.cursor/mcp.json (user) or .cursor/mcp.json (workspace)
Cline cline_mcp_settings.json (open via "Cline: MCP Servers" command in VS Code, or under ~/.cline/data/settings/ for the Cline CLI)

VS Code Copilot extension. Different schema (servers not mcpServers, explicit type: "stdio"). Drop into .vscode/mcp.json at the workspace root (or use "MCP: Open User Configuration"):

{ "servers": { "tmw": { "type": "stdio", "command": "tmw-mcp" } } }

Switch Copilot Chat from "Ask" to "Agent" mode; MCP tools only show up there.

Copilot CLI and Codex CLI. Same mcp add shape as Claude Code's:

copilot mcp add tmw -- tmw-mcp   # writes ~/.copilot/mcp-config.json
codex mcp add tmw -- tmw-mcp     # writes a block into ~/.codex/config.toml

Verify with <host> mcp list; remove with <host> mcp remove tmw. If tmw-mcp isn't on PATH (e.g. it's only in a specific venv), use the absolute path after the --.

When credentials.json isn't in the host's cwd

Claude Code, Cursor, Cline, and VS Code Copilot launch tmw-mcp with the workspace as cwd, so a credentials.json at the workspace root is found automatically. The CLI hosts (Claude Code CLI, Copilot CLI, Codex CLI) inherit your terminal's cwd. If neither lines up with where credentials.json lives (Claude Desktop on macOS, for instance), pass an absolute path via TMW_CREDENTIALS_FILE:

{
  "mcpServers": {
    "tmw": {
      "command": "tmw-mcp",
      "env": {
        "TMW_CREDENTIALS_FILE": "/home/you/credentials.json"
      }
    }
  }
}

For the CLI hosts: claude mcp add -e TMW_CREDENTIALS_FILE=/home/you/credentials.json tmw -- tmw-mcp (and --env instead of -e for copilot / codex).

Without a credentials file

If you'd rather not have a credentials.json on disk at all, pass TMW_USERNAME, TMW_PASSWORD, and TMW_CHAR_NAME in the host's env block directly. Mind that those secrets then live inside each host's config file, which is usually plaintext and sometimes inside a workspace dir that's easy to commit by accident.

Self-restart via restart

tmw-mcp is fronted by a thin stdio shim that owns the actual game-client daemon as a subprocess. Calling the restart tool sends a clean quit to the map server, waits for the server's account-online entry to clear, and respawns the daemon, all without dropping the MCP session. The standard MCP tools/listChanged notification fires after the restart so any host re-syncs. It pairs especially well with Claude Code, where the conversation context survives the restart and you get a tight "fix bug, restart, verify" loop in one session.

Configuration

Variable Meaning
TMW_USERNAME Account name
TMW_PASSWORD Account password
TMW_CHAR_NAME Character name. If omitted, the account's first character is used.
TMW_SERVER Login server. Accepts host or host:port. Default server.themanaworld.org:6901.
TMW_PORT Override port only. Default 6901.
TMW_WORLD World name (blank for default).
TMW_DASHBOARD_PORT Bind the browser dashboard on 127.0.0.1:PORT. Off by default.
TMW_CLIENT_DATA Skip the update-host download and read game data from this directory instead. Dev-only convenience for iterating on local TMX / item XML edits.
TMW_CREDENTIALS_FILE Absolute path to a credentials.json. Useful when your MCP host runs tmw-mcp from a cwd that doesn't contain one.

Precedence: explicit CLI flags > env vars > credentials.json > built-in defaults. TMW_CREDENTIALS_FILE, if set, picks which credentials.json gets read; per-field env vars (TMW_USERNAME etc.) still override whatever's in the file.

Browser dashboard

Set TMW_DASHBOARD_PORT=8765 (or pass --dashboard-port 8765 to any CLI entry) and open http://127.0.0.1:8765/. The dashboard shows a live tile map (collision grid, beings, floor items, walk path, hunt zone, aggro discs), HP/SP/EXP bars, hunt status, NPC dialog state, inventory, and a chat tail. Localhost-only, no auth, no extra dependencies (stdlib HTTP + SSE + vanilla JS).

Where things live

Kind Path
Downloaded game data ${XDG_CACHE_HOME:-~/.cache}/tmw-mcp/
Logs and session state ${XDG_STATE_HOME:-~/.local/state}/tmw-mcp/
Credentials file ./credentials.json in your cwd (chmod 600, gitignored)

Console scripts

pip install creates four entry points:

Command What it runs
tmw-mcp Self-restartable MCP stdio entry point. This is what MCP clients should call.
tmw-mcp-server The daemon itself, useful for standalone testing.
tmw-mcp-cli Interactive REPL for humans.
tmw-mcp-register Create an account on the server.

The same modules also work via python -m tmw_mcp.mcp_shim etc, so you don't need to install to try them.

Running from source

git clone https://git.sr.ht/~thorbjorn/tmw-mcp
cd tmw-mcp
python3 -m venv .venv
.venv/bin/pip install -e .
.venv/bin/python -m unittest discover   # from repo root; 66 tests

Game data (maps, items, monsters) is fetched from the server's update host on first login and cached under ~/.cache/tmw-mcp/, so a checkout is all you need to run the tests and the CLI. If you want to iterate on local TMX or item XML changes, point TMW_CLIENT_DATA at a directory that mirrors the same layout and the downloader is bypassed.

How it works

The TMW protocol is binary, little-endian, over TCP. Three servers in sequence: login (default 6901), character (6122), map (5122). After a successful login the server emits a SMSG_UPDATE_HOST (0x0063) packet pointing at a small resources.xml manifest of ZIP files; the client downloads, hash-verifies (adler32), and presents them as a read-only overlay used for map collision, item names, and monster names.

The active code path is tmw_mcp.mcp_shim (the console-script tmw-mcp), a thin stdio proxy that owns a daemon subprocess running tmw_mcp.mcp_server. The shim survives daemon restarts; the daemon owns the actual game connection. Inside the daemon, a single GameClient (tmw_mcp.game) walks the login handshake and dispatches packets, while a thin MCP layer exposes every action as an MCP tool under the tmw namespace.

Game data layout, packet definitions, and the NPC dialog state machine are documented in CLAUDE.md.

License

MIT. See LICENSE.

The Mana World itself is GPL'd content maintained by its community; this client is independent original work that speaks the same wire protocol.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tmw_mcp-0.1.2.tar.gz (126.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tmw_mcp-0.1.2-py3-none-any.whl (104.7 kB view details)

Uploaded Python 3

File details

Details for the file tmw_mcp-0.1.2.tar.gz.

File metadata

  • Download URL: tmw_mcp-0.1.2.tar.gz
  • Upload date:
  • Size: 126.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for tmw_mcp-0.1.2.tar.gz
Algorithm Hash digest
SHA256 70a2a3092e43ca83db53e21bb4a23a93ea83043cb940b513f0b28cdf3d25d03d
MD5 2d47f4e035b6214183ab6e1aff9b838c
BLAKE2b-256 aa3c43b958b3573ac51b653e56e0ee50b9c450791a0d5b79e8ac463b55d47c56

See more details on using hashes here.

File details

Details for the file tmw_mcp-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: tmw_mcp-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 104.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for tmw_mcp-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 68a3b9e76b971b06d648ab3792d6ab060411c6b3fe5fd065edc5e790f67c9054
MD5 5334c663462f23bae21461f1f6ba0877
BLAKE2b-256 637293e03b693e87b4c58dd840097f09b05c79282b6dd7cd8cb2c412151a7af5

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page