MCP bridge to a running Mount & Blade II: Bannerlord campaign (read-only). Exposes game state as MCP tools via HTTP loopback.
Strong domain-specific tool set with clear, detailed descriptions (avg 180 chars) and well-structured schemas. All 12 tools have explicit input schemas with typed parameters. Naming is consistent (bannerlord_* prefix) and action-oriented. However, output schemas are not documented, LLMs cannot predict response structure for chaining. Parameter descriptions are thorough but some tools lack enum constraints (e.g., bannerlord_objects 'type' accepts free-form strings). Error handling is present in the ask() function but not surfaced in tool descriptions. No tool annotations (readOnlyHint, idempotentHint) despite all tools being read-only.
Registered campaign behaviours, grouped by mod. A behaviour that a mod defines but that is missing from this list never had AddBehavior called on it, so none of its events will ever fire - a mod can look loaded and healthy while doing nothing. Pass mission=true instead to list mission behaviours (only meaningful during a battle or scene).
Methods patched by more than one mod, riskiest first. 'High' risk means a prefix there can return false, which skips the original method AND every prefix behind it - the usual cause of one mod silently disabling another.
START HERE WHEN SOMETHING IS WRONG BUT YOU DO NOT KNOW WHERE. One sweep of the whole install, ranked by severity: - shadowed models: two mods replaced the same game model, so one of them silently does nothing - skipping-prefix conflicts: two mods patched a method and one can skip the original - inert mods: loaded but patched nothing and registered no behaviour Findings are a shortlist, not a verdict - many are deliberate. Takes a few seconds.
Search living heroes by name. Returns id, clan, faction, occupation, prisoner state.
Other mods' Mod Configuration Menu settings, read from the live instance rather than from disk. Useful because 'why is this mod not doing anything' is often a toggle that is off. Pass values=true to include the current value of every setting.
Output schemas not documented. LLMs cannot predict response structure (field names, types, nesting) for downstream tool chaining or data extraction. Responses are inferred from HTTP calls but never formally specified.
No tool annotations despite all tools being read-only. Missing readOnlyHint metadata prevents clients from optimizing caching, retry logic, and safety assumptions. Current spec (2026-07-28) expects tool annotations for all tools.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 57 | 2026-07-28+ | v2 |
DOSSIER on one mod: its assembly, everything it patched, which campaign behaviours it registered (and which it declared but never registered, so they never fire), and which game models it owns or LOST to another mod. 'modelsLost' is the interesting one - it means this mod's version of a model never runs because someone registered later. Accepts a MODULE name as well as an assembly name. When the module carries more than one assembly - the pattern total conversions use to bundle their dependencies - you get the module view instead: everything it brought and which parts are actually doing something. Then ask again with a single assembly name for its full dossier.
What mods ADDED, rather than what they do: the game's object registry - troops, items, cultures, clans, kingdoms, perks. Counting these from XML on disk is guesswork, because a malformed entry is simply absent from the registry with no error anywhere; this is what the game actually holds. type accepts an alias (troop, item, culture, clan, kingdom, hero, perk, trait, skill) or a full class name. Filter with q= on StringId or name. Pass count=true for just the numbers. Example: type='troop', q='retinues_custom' answers how many Retinues stubs exist.
The Harmony patch inventory: which methods are patched, by whom, and with what kind of patch. Filter by owner (a mod's harmony id) or by target (a type or method name). With no filter, returns a capped sample - prefer bannerlord_mod for one mod, or bannerlord_conflicts for trouble.
The player: hero, clan, kingdom, gold, party size, current settlement, map position, and captivity state (both the vanilla IsPrisoner flag and PlayerCaptivity.IsCaptive, which mods like Consequences of Crime drive separately).
Search settlements by name. Returns id, owner clan, faction and type.
Is a campaign loaded, and what is the in-game date and campaign id. Start here - most other tools need a loaded campaign. Also confirms the inspector is reachable at all.
Find types by name across every loaded assembly. This replaces hunting a mod's DLL down on disk: the loaded assemblies are the exact build that is running.
bannerlord_objects 'type' parameter accepts free-form strings but should be an enum. Current description lists aliases (troop, item, culture, etc.) but does not enforce them. LLMs may pass invalid types, causing silent failures.
Error handling guidance not surfaced in tool descriptions. The ask() function returns structured errors (error, likelyCause, detail) but tool descriptions do not document what errors are possible or how to recover. LLMs cannot plan recovery steps.
bannerlord_types has no input parameters documented. Description is vague ('Find types by name across every loaded assembly'). No 'name' or 'filter' parameter is visible in the schema, making the tool's actual interface unclear.