XIV MCP

Architecture

How a request travels from the AI app through the server, the permission gate and the game.

The path of a tool call

One tool call, from the AI app to the game. Third-party tools also get a side-effect check around the call.
  1. McpServer (XivMcp/Mcp) implements MCP's Streamable HTTP transport with JSON responses, directly on HttpListener, because Dalamud does not ship ASP.NET Core. It only listens on localhost, checks the bearer token, and refuses browser requests from other origins.
  2. ToolRegistry (XivMcp.Core/Mcp) holds every tool: the core ones, the maintained integrations and those third-party plugins register at runtime. It is thread-safe and raises Changed when tools come or go, which becomes notifications/tools/list_changed for the apps.
  3. ToolGate (XivMcp.Core/Permissions) decides each call from the tool's provider and the player's settings: Allow, Ask (an approval window in the game) or Deny.
  4. The handler runs. Game memory is only read on the framework thread; static data sheet lookups run on a background thread.
  5. For third-party tools, SideEffects compares a snapshot from before and after the call, and the audit log records it.

Providers and trust

Every tool has a ToolProvider with a trust level, which decides how its calls are gated:

TrustWhoGated by
CoreXIV MCP's own toolsThe modules in PermissionCatalog
MaintainedThe integrations in IntegrationCatalog, named after the plugin they driveTheir own module; only offered while that plugin is loaded
Third-partyTools registered over IPCThe plugin's PluginPolicy: consent, capabilities, per-tool settings and suspension

RegistrationReview decides when a third-party plugin needs the player's decision again: only when its registration grows.

The plugin API

PluginApi (XivMcp/Api) exposes the IPC gates. Plugins cannot share types, so everything crossing the boundary is a JSON string. ToolDefinition (XivMcp.Core/Api) validates registrations. The contract is described in Raw IPC.

Background jobs

Jobs (XivMcp/Util) runs a queue of tool calls one after another, independent of any app connection. A failed or stopped step puts the job into pending, waiting for the agent. While an acting step runs, other changing calls are refused; passive steps such as wait and wait_until_arrived do not block. Placeholders between steps are resolved by Placeholders in the core.

Pausing other plugins

While XIV MCP drives game windows, it pauses YesAlready and TextAdvance by adding itself to their StopRequests sets, and holds AutoRetainer back at a bell through AutoRetainer's public IPC. See Compatibility for what players see.

Caches as resources

Each cache (see Caches) is also an MCP resource (xiv://cache/<id>) that apps can subscribe to with resources/subscribe. Apps that open the event stream (GET /mcp with their Mcp-Session-Id) receive notifications/resources/updated when a cache changes.

Where things live

Plugin.cs
FolderWhat is in it
XivMcp/ToolsOne class per area of tools (MapTools, RetainerTools, MarketTools, …).
XivMcp/UtilGame access and helpers: navigation, retainers, lobby login, caches, client setup, bridges to other plugins.
XivMcp/WindowsThe /xivmcp window, the Modules and Third-party panels, the consent and approval windows.
XivMcp.Core/ConnectWhat each AI app needs to connect, and reading whether it is set up.
XivMcp.Core/PermissionsCapabilities, the catalog, policies, the gate, side effects, the audit log, module search.
XivMcp.Core/MapsMap and world coordinates, and route plans.
XivMcp.Core/DiagnosticsThe self-test runner.

On this page