Paradox脚本MCP服务器
面向AI助手的快速、令牌高效的Paradox脚本探索
这是什么?
Paradox游戏脚本是以纯文本编写的,这意味着你可以让像Claude Code这样的编码机器人读取并探索它们,以自动调查事件触发条件等事情。
然而,游戏脚本文件往往相当大,因此直接将它们提供给编码机器人会很快耗尽你的上下文。(与许多悖论游戏一样,资源枯竭意味着死亡。)
此MCP允许您从Paradox脚本中仅提取符号(如事件ID),或仅加载特定符号指示的块。
它可以从MCP兼容的客户端使用,如Claude、Claude Code、gemini cli(未测试)等。
示例:调查一项成就
HOI4 achievement "No One Crosses the Finnish Line" investigation
这是一个使用此MCP调查HOI4成就的真实对话示例”没有人越过芬兰线".
______________________________________________________________________
\>请调查如何实现“没有人越过芬兰线”。
● 我将初始化游戏目录并在成就文件中搜索成就。
init_game("/path/to/Hearts of Iron IV")
→ "Initialized: /path/to/Hearts of Iron IV"
list_symbols("common/achievements.txt")
→ block: no_one_crosses_the_finnish_line (id=185)
block: finnish_him (id=114)
...● 发现成就 no_one_crosses_the_finnish_line让我查查它的细节。get_structure("common/achievements.txt", "no_one_crosses_the_finnish_line")
→ no_one_crosses_the_finnish_line:
possible: [block] (4 keys)
id: 185
happened: [block] (2 keys)● 我看得出来possible(解锁条件)和happened(完工条件)块。让我逐一调查。
get_structure("common/achievements.txt", "no_one_crosses_the_finnish_line", "possible")
→ no_one_crosses_the_finnish_line.possible:
is_ironman: [True, difficulty, >, ...] (7 items)
has_any_custom_difficulty_setting: no
game_rules_allow_achievements: yes
tag: "FIN"
get_structure("common/achievements.txt", "no_one_crosses_the_finnish_line", "happened")
→ no_one_crosses_the_finnish_line.happened:
NOT: [block list] (2 items)
tag: [FIN, date, >, ...] (4 items)● 让我更深入地了解NOT条件和标签块。
get_structure("common/achievements.txt", "no_one_crosses_the_finnish_line", "happened.NOT")
→ no_one_crosses_the_finnish_line.happened.NOT:
[0]:
has_global_flag: "achievement_fin_has_lost_one_starting_core"
[1]:
FIN:
has_completed_focus:
[0]: "FIN_right_wing_policies"
[1]: "FIN_suomalainen_sosialismi"
SOV:
has_completed_focus: "SOV_beaten_but_not_defeated"
get_structure("common/achievements.txt", "no_one_crosses_the_finnish_line", "happened.tag")
→ no_one_crosses_the_finnish_line.happened.tag:
[0]: "FIN"
[1]: "date"
[2]: ">"
[3]: "1944.09.19"● 成就“没有人越过芬兰线”要求: 解锁条件: - 作为播放 芬兰(FIN) - 铁人模式 启用 - 没有自定义难度设置 - 成就游戏规则已启用 竣工条件: 1. 永远不要失去任何初始核心状态 (全球旗帜achievement_fin_has_lost_one_starting_core不得设置) 1. 生存至1944年9月19日之后 (这个日期是指历史上结束继续战争的莫斯科停战) 1. 不要完成以下重点 (限制路线): -FIN_right_wing_policies(右翼政策) -FIN_suomalainen_sosialismi(芬兰社会主义) - 苏联一定没有完成SOV_beaten_but_not_defeated(被击败但未被击败)
______________________________________________________________________
\>怎么样 achievement_fin_has_lost_one_starting_core 设置?● 让我在所有脚本文件中搜索此标志的设置位置。
search_references("achievement_fin_has_lost_one_starting_core", include_lines=True)
→ Found in 2 file(s):
common/achievements.txt
L4693: NOT = { has_global_flag = achievement_fin_has_lost_one_starting_core }
common/on_actions/09_aat_on_actions.txt
L1699: set_global_flag = achievement_fin_has_lost_one_starting_core● 它已经设置好了 09_aat_on_actions.txt 第1699行。让我找出属于哪个符号。find_symbol_at_line("common/on_actions/09_aat_on_actions.txt", 1699)
→ symbol: on_actions
type: on_actions
lines: L2-L4046
use: get_structure(file_path, "on_actions")
get_structure("common/on_actions/09_aat_on_actions.txt", "on_actions", "on_state_control_changed.effect")
→ on_actions.on_state_control_changed.effect:
[0]:
if:
limit:
is_in_array:
array: "FIN.core_states_at_game_start"
value: "FROM.FROM"
set_global_flag: "achievement_fin_has_lost_one_starting_core"● 旗帜是如何设置的: 国旗achievement_fin_has_lost_one_starting_core设定在on_state_control_changed(当状态控制改变时)在以下条件下: -FIN.core_states_at_game_start=比赛开始时芬兰的核心国家名单 -FROM.FROM=控制权发生变化的状态 这意味着标志已设置 芬兰任何一个初始核心国家落入敌人控制之下的那一刻. 对成就的影响: 一旦芬兰的任何一个起始核心国家(大陆或卡累利阿)被敌人占领,即使重新夺回,国旗也会保持不变,使 成就完成不可能. 需要一个不因苏联入侵而失去领土的完美防御。
支持的游戏
| 游戏 | Game_type |
|---|---|
| 🪖 铁之心IV | hoi4 |
| ⭐️ Stellaris | stellaris |
| 🧭 欧罗巴环球V | eu5 |
用法
对于用户
1.安装uv
curl -LsSf https://astral.sh/uv/install.sh | sh2.配置Claude/Claude代码
添加到您的客户 .mcp.json:
{
"mcpServers": {
"paradox-script": {
"command": "uvx",
"args": [
"--from",
"git+https://github.com/106-/paradox-script-mcp",
"paradox-script-mcp"
]
}
}
}重新启动客户端-- uvx 将自动启动服务器。无需手动安装。
注: paradox脚本解析器是一个自定义解析器,并不支持所有paradox脚本语法。某些脚本可能无法正确解析。
对于开发者
# Install for development
uv pip install -e .
# Run with hot reload (streamable-http, port 8000)
make serve
# Run tests
make test使用时 make serve,配置 .mcp.json 如:
{
"mcpServers": {
"paradox-script": {
"type": "streamable-http",
"url": "http://localhost:8000/mcp"
}
}
}MCP工具
init_game
使用游戏目录路径进行初始化。必须先打电话。
init_game("/path/to/Hearts of Iron IV")
→ "Initialized: /path/to/Hearts of Iron IV"list_目录
列出脚本目录及其用途。
list_directories()
→ common/national_focus/ -> National focus trees
common/decisions/ -> Decisions
common/ideas/ -> National spirits, ministers, companies
events/ -> Events
...列表文件
列出目录中的.txt文件。使用此功能在调用之前查找文件名 list_symbols 或 get_structure.
list_files("common/national_focus")
→ afghanistan.txt
argentina.txt
australia.txt
austria.txt
...搜索参考
在所有游戏脚本文件中搜索字符串。使用此选项可查找标记、事件ID或任何其他字符串的引用位置。
search_references("achievement_fin_has_lost_one_starting_core")
→ Found in 2 file(s):
common/achievements.txt
common/on_actions/09_aat_on_actions.txt集 include_lines=True 还要返回匹配的行号和内容:
search_references("CZE_capitulated_germany", include_lines=True)
→ Found in 2 file(s):
common/achievements.txt
L7784: has_country_flag = CZE_capitulated_germany
common/on_actions/15_mun_on_actions.txt
L114: CZE = { set_country_flag = CZE_capitulated_germany }find_symbol_at_line
找出哪个符号包含给定的行号。使用此后 search_references 返回一个行号以标识所属符号。
如果该行指向任何块外的注释或空白行,则返回最接近的符号(带 note: 现场)。
find_symbol_at_line("common/on_actions/15_mun_on_actions.txt", 114)
→ symbol: on_actions
type: on_actions
lines: L1-L466
use: get_structure(file_path, "on_actions")find_symbol_at_line("events/MUN_Czechoslovakia.txt", 3030)
→ symbol: MUN_czech.1034
container: country_event
lines: L2928-L3192
use: get_structure(file_path, "MUN_czech.1034")# Comment line — falls back to nearest symbol
find_symbol_at_line("events/shroud_events.txt", 8213)
→ symbol: shroud.4135
container: country_event
lines: L8214-L8325
note: nearest symbol (line 8213 is outside any block)
use: get_structure(file_path, "shroud.4135")列表_符号
列出文件中的符号(仅限顶级)。 使用 get_structure 查看子元素。
list_symbols("common/national_focus/japan.txt")
→ focus: JAP_the_unthinkable_option (x=12, y=0)
focus: JAP_approach_the_young_officers (y=1)
...
focus_tree: japan_wtt_focusget_structure
显示符号结构(仅按键,无完整内容)。
get_structure("common/national_focus/japan.txt", "JAP_the_unthinkable_option")
→ JAP_the_unthinkable_option:
id: "JAP_the_unthinkable_option"
icon: "GFX_goal_generic_political_reform"
prerequisite: [block] (1 keys)
completion_reward: [block] (8 keys)get_structure(导航嵌套块)
get_structure(
"common/national_focus/japan.txt",
"JAP_the_unthinkable_option",
"completion_reward.hidden_effect"
)
→ JAP_the_unthinkable_option.completion_reward.hidden_effect:
add_stability: 0.05
add_political_power: 120get_structure_by_id
直接通过符号的ID获取符号的结构,而不知道它位于哪个文件中。当您发现以下引用时很有用 country_event = { id = shroud.4135 } 并想直接跳到它的定义。
在内部,它结合了快速文本搜索(缩小候选文件的范围)和解析(确认定义),因此即使在像Stellaris这样的大型游戏中也能高效运行。
get_structure_by_id("shroud.4135")
→ # found in: events/shroud_events.txt
shroud.4135:
is_triggered_only: "yes"
picture_event_data: [block] (2 keys)
desc: "shroud.4135.desc"
...支持 key_path 与...相同 get_structure:
get_structure_by_id("shroud.4135", key_path="option.0")
→ # found in: events/shroud_events.txt
shroud.4135.option.0:
name: "shroud.4135.a"
accept_end_of_the_cycle: "yes"
...使用 glob_pattern 缩小搜索范围以提高速度:
get_structure_by_id("shroud.4135", glob_pattern="events/**/*.txt")添加对其他游戏的支持
要添加对新游戏的支持,您需要 src/paradox_script_mcp/knowledge/{game_type}/directories.yml 列出游戏脚本目录及其用途的文件。
使用 /generate-knowledge 技能(克劳德代码)
如果你使用的是Claude Code,内置 /generate-knowledge skill可以扫描游戏目录并自动生成YAML。
/generate-knowledge 示例:
/generate-knowledge eu4 "/path/to/Europa Universalis IV"
/generate-knowledge ck3 "/path/to/Crusader Kings III"技能扫描游戏目录、样本 .txt 每个子目录中的文件,并写入 src/paradox_script_mcp/knowledge/{game_type}/directories.yml 每个目录都有一行描述。非脚本目录(gfx, interface, music等等)被自动跳过。
手册
您还可以在以下位置手动创建YAML src/paradox_script_mcp/knowledge/{game_type}/directories.yml:
# {game_type} Directory Knowledge
directories:
some/path:
description: Brief purpose in English
another/path:
description: Brief purpose in English项目结构
paradox-script-mcp/
├── pyproject.toml
└── src/paradox_script_mcp/
├── __init__.py
├── server.py # MCP server entry point
├── core/
│ └── game.py # Game path management
├── knowledge/
│ └── directory_map.py # HOI4 directory knowledge
└── tools/
├── explore.py # list_directories, list_files
├── search.py # search_references
├── symbols.py # list_symbols, find_symbol_at_line
└── structure.py # get_structure, get_structure_by_id