XIV MCP

Raw IPC

The Dalamud IPC gates behind the client, for plugins that do not use XivMcpClient.cs.

For plugins that do not use XivMcpClient.cs.

  • XIV MCP's gates are named XivMcp.<Gate>. Yours are named <InternalName>.XivMcp.<Gate>.
  • XIV MCP's gates reply with {"ok": true, …} or {"ok": false, "error": "…"} and never throw into your plugin.
  • owner is your IDalamudPluginInterface.InternalName. Registering from your constructor is fine.

Gates XIV MCP provides

GateSignatureReturns / does
ApiVersionFunc<int>2
IsReadyFunc<bool>True while loaded
ListCapabilitiesFunc<string>{"capabilities":[{"id","risk","title","description","default"}]}
RegisterToolFunc<string owner, string definitionJson, string>{"name","enabled","awaitingConsent","state","capabilities":[{"id","mode"}]}
UnregisterToolFunc<string owner, string name, string>{"removed": bool}
UnregisterAllFunc<string owner, string>{"removed": count}
GetStatusFunc<string owner, string>{"state","canRun","suspendReason","tools":[{"name","mode","own"}],"capabilities":[{"id","mode"}],"dependencies":[…]}
DeclareDependenciesFunc<string owner, string json, string>Declares the tools your jobs use (see below); returns {"dependencies":[…]}
CheckPermissionFunc<string owner, string capability, string>{"mode":"allow"|"ask"|"deny","enabled","suspended","state"}
RequestApprovalFunc<string callId, string requestJson, string>Request {"capability","summary"}; returns {"approvalId","state"}
GetApprovalFunc<string approvalId, string>{"state":"pending"|"approved"|"denied"}
CompleteCallFunc<string callId, string resultJson, string>Finishes a pending call
FailCallFunc<string callId, string message, string>Fails a pending call
ReportProgressFunc<string callId, string text, string>Adds a job log line
StartJobFunc<string owner, string jobJson, string>Job {"name","steps":[{"id","tool","args","note"}]}; returns {"job":{…}}
GetJobFunc<string id, string>{"job"}
ListJobsFunc<string owner, string>{"jobs"}: the jobs your plugin started
PauseJob / ResumeJob / CancelJobFunc<string id, string>Job control
Ready / DisposingmessagesRegister on Ready; stop running calls on Disposing

state is one of undecided, kept_disabled, enabled, awaiting_consent or suspended.

Tool definition

{
  "name": "myplugin_restock",
  "description": "Buys what your list is short of from the nearest vendor.",
  "inputSchema": { "type": "object", "properties": {} },
  "readOnly": false,
  "destructive": false,
  "capabilities": ["move_character", "game_ui", "spend_gil"]
}

capabilities is required unless readOnly. readOnly and destructive cannot both be true, and unknown capability ids are rejected.

Dependencies

The declaration replaces the previous one; {"tools": []} clears it.

{
  "tools": [
    { "tool": "navigate_to" },
    {
      "tool": "otherplugin_announce",
      "plugin": "OtherPlugin",
      "name": "Other Plugin",
      "repo": "https://example.com/repo.json",
      "minVersion": "1.2.0"
    }
  ]
}

A built-in tool is named alone; naming a plugin for one is refused. Any other tool needs plugin, name, repo (an https:// URL, or "official") and minVersion. At most 64 tools.

Each entry of dependencies in the reply and in GetStatus:

{
  "tool": "navigate_to",
  "plugin": null,
  "state": "ok",
  "message": "Ready. Without vnavmesh: XIV MCP puts a flag on …",
  "install": [
    {
      "plugin": "vnavmesh", "name": "vnavmesh",
      "repo": "https://puni.sh/api/repository/veyn",
      "needed": false, "installed": false, "outdated": false,
      "reason": "Walks there for you.",
      "without": "XIV MCP puts a flag on your map and waits …"
    }
  ]
}

state is one of the dependency states. install lists the plugins to install, enable or update. needed: true is a plugin an integration tool cannot run without (state is then needs_plugin); needed: false is one an XIV MCP core tool can use, with without saying what XIV MCP does instead.

Gates your plugin provides

GateSignatureDoes
<InternalName>.XivMcp.InvokeFunc<string callId, string tool, string argsJson, string>Runs a tool on the framework thread, after the permission checks. Reply with {"result": …}, {"error": "…"} or {"pending": true}; finish a pending call with CompleteCall / FailCall.
<InternalName>.XivMcp.CancelAction<string callId>Optional: stop a pending call.

CompleteCall and RequestApproval may be called from inside Invoke, before you reply.

A call that takes a minute

A long-running call over raw IPC. The approval and the cancel only happen when they are needed.

CompleteCall takes the result itself, not wrapped in {"result": …}. The approval request is {"capability": "spend_gil", "summary": "Repair for 3,200 gil"}.

XIV MCP sets no time limit of its own on pending calls. When an AI app calls your tool directly, the app's own time limit applies, often a minute; when it gives up, you get Cancel. Approval windows decline after two minutes, and after a Cancel XIV MCP waits up to two minutes for your CompleteCall or FailCall.

On this page