Skip to main content
Glama

cozyvtt-mcp

cozyvtt-mcp MCP server – quality and maintenance score on Glama

English | 中文

MCP (Model Context Protocol) bridge for CozyVTT — the self-hosted, open-source virtual tabletop. It lets an AI agent join a campaign as DM/KP: narrate over chat, roll server-authoritative dice on the server, move tokens, switch maps, manage initiative, and settle character sheets.

Built for and tested with Hermes Agent, but works with any MCP client (stdio transport).

Upgrading

This README describes how to install and use the current release; the change history lives in CHANGELOG.md. Two migration points are worth knowing before you wire up a client:

  • Three tools were renamed in 0.3.0: campaign_status → campaign_get, initiative_state → initiative_read, token_hp → token_hp_update. No aliases are registered — update client tool selections. Old-to-new mapping.

  • chat_read paginates with limit/cursor (the offset argument was removed in 0.2.0).

The default tool set is every tool; optional presets are described under Tool sets.

Related MCP server: RPG Ledger MCP Server

Tool sets

The default is every tool. Optional registration-time filtering drops excluded tools from tools/list entirely; it changes nothing about how the remaining tools behave. Choose comma-separated presets (union); duplicates are accepted and all wins. The flag overrides COZYVTT_MCP_TOOLSETS. Empty values or unknown names fail with valid preset names and counts. --list-toolsets prints all memberships and the default, then exits successfully without connecting to CozyVTT.

Preset

Tools

Selection

play

20

campaign_get, chat_read, chat_send, creature_search, dice_roll, events_poll, initiative_manage, initiative_read, map_create, map_delete, map_list, map_switch, session_list, session_manage, session_notes_update, token_add, token_delete, token_hp_update, token_move, token_place_creature

docs

9

All document_* tools plus campaign_document_list

roster

7

All character_* tools

macros

4

All saved_roll_* tools

admin

1

campaign_transfer_dm

all (default)

41

Every tool

.venv/bin/python server.py --toolsets play,macros
COZYVTT_MCP_TOOLSETS=docs,roster .venv/bin/python server.py
.venv/bin/python server.py --list-toolsets

For an MCP client, append "--toolsets", "play" to its server args, or set COZYVTT_MCP_TOOLSETS in its server env.

Measured with .venv/bin/python scripts/measure_tool_budget.py (offline stdio). Bytes sum UTF-8 JSON tool definitions, excluding JSON-RPC envelope/list separators; tokens are estimates (bytes // 4), not tokenizer measurements.

Preset

JSON bytes

Estimated tokens

Savings vs all

play

30,925

7,731

48%

docs

13,418

3,354

77%

roster

9,152

2,288

85%

macros

4,664

1,166

92%

admin

1,199

299

98%

all

59,358

14,839

0%

The surface also includes map_create, map_delete, token_delete, and character_delete. Create maps from existing image assets; use map_switch before deleting the current map. token_delete removes a map token; token_hp_update changes sheet HP using a character ID. character_delete permanently deletes an owned sheet. Add roster or docs when a session needs those tools.

Compatibility

cozyvtt-mcp

CozyVTT

Notes

0.4.0

v1.2.2 / v1.4.0

Dual baseline. Tool-set presets plus map_create/map_delete/token_delete/character_delete. Offline contract suite 228/228; the Dockerfile was replayed inside the real python:3.12-slim rootfs (hash-checked layers) and boots with no environment set, listing 41 tools. No live campaign run, and no OCI image was built (no Docker daemon on the build host).

0.3.0

v1.2.2 / v1.4.0

Dual baseline. Parameter descriptions, MCP annotations, container image. Offline suite 176/176; image built and booted (37 tools, no environment). No live campaign run.

0.2.0

v1.2.2 / v1.4.0

Dual baseline: retain original tools; new REST routes degrade explicitly on old instances. Offline suite 176/176; live v1.4.0 smoke (read/write + Documents/Saved Rolls round-trips) passed 2026-09-17.

0.1.1

v1.2.2

Previous 20-tool release

The compatibility table describes supported contracts, not an inferred server version. New feature availability is unknown until established; an empty list or a business 404 is not evidence that the route is missing. See SPEC v2 for the complete 41-tool contract.

Features

41 tools returning {ok, data?, error?} for tool-body results. MCP argument validation remains handled by FastMCP:

  • Session/campaign: campaign_get (role and owner reported separately; new capability keys may be unknown), session_manage, session_list, session_notes_update, campaign_transfer_dm (owner reclaim uses the same tool), map_list, map_switch

  • Narration: chat_send (DM / PLAYER), chat_read

  • Dice: dice_roll (server-authoritative results; is_secret=true (wire field: secret) delivers to the roller and DMs on v1.4.0), events_poll (recent buffered dice events, not durable history; DICE_ROLL events are absent from chat history)

  • Tokens/maps: token_add (integer sizes 1..10), token_move, token_hp_update, token_place_creature, token_delete, map_create, map_delete, creature_search (SRD + custom library).

  • Combat: initiative_manage (add / remove / roll / set / reorder / start / next / end), initiative_read (note: CoC7e initiative is DEX-ordered, no roll — this is upstream rules behavior, and roll is gated accordingly)

  • Characters: character_list, character_get, character_create, character_delete, character_validate, character_update (rules math is done by the agent; the bridge just writes values)

  • Documents: document_upload, document_create, document_list, campaign_document_list, document_read, document_update, document_share, document_unshare, document_delete

  • Saved Rolls: saved_roll_list, saved_roll_create, saved_roll_update, saved_roll_delete (private to the current user and campaign; 50 macros per user/campaign, server-validated expressions). saved_roll_list returns complete macros — there is no saved_roll_get.

  • Hit Dice: character_hitdice_spend (DND_5E only; dispatches one spend without rolling dice or healing)

System gating

The bridge stays game-system agnostic, but a few capabilities only make sense under a specific rule system. Those are gated against the campaign's gameSystem (fetched once, cached; enum: DND_5E / PATHFINDER_2E / SHADOWRUN_6E / CALL_OF_CTHULHU_7E):

Capability

Allowed systems

Why

creature_search source=srd

DND_5E

The SRD library is seeded from Open5e — a D&D 5e data source

initiative_manage action=roll

DND_5E, PATHFINDER_2E, SHADOWRUN_6E

The server derives the initiative dice per system; CoC7e doesn't roll at all (DEX order)

character_hitdice_spend

DND_5E

Only the system gate is enforced locally. No reliable WS capability probe exists; dispatch always remains pending.

Gated calls return a clear {ok: false, error} explaining which systems are allowed, instead of emitting an event the server would ignore or misinterpret. Campaigns with no gameSystem set (flexible) fail closed. With no source specified, non-5e campaigns search only custom; 5e campaigns may search both sources. campaign_get().features reports the current campaign's available gated capabilities.

Architecture

MCP client (stdio)
  └─ server.py (FastMCP, lazy init, synchronous first-call self-check)
      ├─ auth.py        — rememberMe login, 10-min keepalive, 3-min re-login spacing, 429 backoff
      ├─ client.py      — REST wrapper: one 401→re-login→retry, 429 exponential backoff (1/2/4s, ≤3)
      ├─ ws_listener.py — socket.io listener, 500-event ring buffer, one reconnect worker
      └─ tools/         — 41 MCP tools (read/write, documents, campaign additions)

Design notes:

  • Dice discipline: rolls are generated and persisted by the server. Public results go to the table; reviewed v1.4.0 sends secret results to the roller and DMs. The bridge provides recent buffered events, not a durable roll-history query.

  • Rules live outside the bridge: skill checks, SAN loss, damage — computed by the agent/GM, the bridge only performs authoritative rolls and writes results. The bridge is game-system agnostic.

  • token_move uses REST PUT; the server checks DM/controlledBy permissions, and the bridge additionally rejects spectators. REST persistence does not imply a map.changed broadcast. map_switch saves through REST then explicitly dispatches map.change through WS; a WS failure preserves the successful REST result and never replays it.

Result and update contracts

  • dice_roll, chat_send, token_hp_update, initiative_manage, and character_hitdice_spend return sent: true, confirmed: false, status: "pending". Read business broadcasts and system.error with events_poll; do not blindly replay writes. Neither baseline provides correlated business ACKs. Dice may carry purpose and character_name (wire: characterName) for Custom Roll display. Hit Dice spend, rolling, and healing are separate operations, not a transaction; an old server may silently ignore the spend event.

  • events_poll returns the oldest unread events first. Save next_seq for the next since; latest_seq is its compatibility alias. high_water_seq is the buffer high-water mark, not a pagination cursor. Check gap, cursor_reset, has_more, connected, and authenticated.

  • character_update(character_id, data={"data": {"hp": {"current": 5}}}) recursively merges sheet fields before PUT. Unspecified fields survive; arrays/scalars replace values and null is explicit. Top-level fields are name, data, and tokenImageUrl. A process lock serializes updates from this bridge; concurrent browser saves still need upstream optimistic locking.

  • character_create creates the card, checks the roster, then assigns it only if not confirmed as assigned. If assignment fails, the error includes the created character ID: assign that card in the UI instead of creating another. CoC conditions/Mythos/spells/appearance/notes and DND legacy/new hit-dice fields survive character merges; Keeper notes are not private from campaign members.

  • session_manage uses REST. Pause/end resolve campaign.activeSession.id; start creates a session. End accepts notes (≤2000 characters, shared with the campaign) and save_state=true. Empty end notes do not clear old notes; use session_notes_update(session_id,notes="") to clear. session_list includes active sessions among the most recent 50.

  • Documents use scope USER (personal), CAMPAIGN, or GLOBAL. document_list filters the asset library; campaign_document_list discovers shared private documents too. Typed txt/md create/update is limited to 900 KiB UTF-8; file uploads use the instance limit (default 50 MiB). PDF content cannot be edited. Unsharing removes only one link and cannot revoke native/global access; shared:false indicates a native campaign document. Deleting removes the asset and all its links.

  • WS reconnects use fresh, URL-scoped Cookies and request current initiative state after campaign authentication. Use HTTPS for remote deployments.

  • chat_read paginates with limit + cursor: read the newest page first, then pass the returned pagination.nextCursor back as cursor, and stop when it is null. Instances without cursor metadata serve only the latest page and say so (This instance does not support reliable cursor pagination for history; only the latest page can be read.) instead of repeating it.

  • Raw document reads preserve MIME type and ETag. Text returns {mime_type,etag,content}; PDFs are written to the project's downloads/<document_id>.pdf and return {mime_type,etag,file_path,file_size}. Pass etag as If-None-Match; a 304 returns {not_modified:true} so the caller can reuse existing content. Downloads are Git-ignored and local copies survive upstream deletion.

  • REST 401 invalidates existing WS authentication and campaign caches; losing campaign membership cancels WS authentication rather than reconnect-looping. campaign_transfer_dm clears role and system caches, and the bridge buffers character.updated, campaign.dm.transferred, roster.updated, and dice.historyCleared for events_poll.

  • character_validate always includes validation_reliable:false: upstream v1.4.0 can discard validation failures and incorrectly report isValid:true; reliability on older servers is unknown.

  • initiative_read(refresh=true) requests fresh state and reports unknown on timeout; token positions are deterministic under REST.

  • Route-missing 404 — upstream message exactly The requested resource does not exist — returns This CozyVTT instance does not provide this feature; upgrade to a supported version and retry. Other 404s return Resource not found or inaccessible to the current account (HTTP 404): <upstream message>. Error data preserves the status and upstream detail. Uploading a DOCUMENT to an old upload route may return 400; that error is preserved without retrying with a different type or scope.

Requirements

  • Python ≥ 3.11

  • A CozyVTT v1.2.2 or v1.4.0 instance and a campaign where your account has the permissions required by the tools

  • uv (recommended) or pip

Install

git clone https://github.com/yanjingzhaisun/cozyvtt-mcp.git
cd cozyvtt-mcp
uv sync   # or: python -m venv .venv && .venv/bin/pip install fastmcp requests "python-socketio[client]" websocket-client

Docker (stdio)

docker build -t cozyvtt-mcp:0.4.0 .
docker run --rm -i --env-file /path/to/cozyvtt.env cozyvtt-mcp:0.4.0

Use -i to keep stdin open; MCP uses stdin/stdout, without a network port or TTY. The image installs only compatible, hash-checked runtime wheels from uv.lock, including fastmcp, requests, python-socketio[client], and websocket-client. No editable package install or dependency re-resolution is performed. Credentials are supplied at runtime. Without any COZYVTT variables, initialize and tools/list still work; only business tool calls initialize authentication. Mount upload files inside the container and pass those container paths to document_upload. Mount /app/downloads if binary downloads must survive container removal.

Wheel URLs come from the lock as direct links with sha256 hashes, so only the host serving those blobs is configurable. The default is the canonical CDN; builders in mainland China can use a mirror, which serves byte-identical files (the hashes still verify):

docker build --build-arg WHEEL_BASE=https://mirrors.aliyun.com/pypi/packages -t cozyvtt-mcp:0.4.0 .

scripts/docker_requirements.py --wheel-base "" keeps the lock file's own URLs.

Configuration

Environment variables (no secrets in the repo):

Var

Example

Notes

COZYVTT_URL

http://localhost:8899

Your instance URL

COZYVTT_EMAIL

dm@example.local

DM account

COZYVTT_PASSWORD

—

DM password

COZYVTT_CAMPAIGN_ID

uuid

Target campaign

Hermes Agent (config.yaml)

mcp_servers:
  cozyvtt:
    command: /path/to/cozyvtt-mcp/.venv/bin/python
    args: [/path/to/cozyvtt-mcp/server.py]
    env:
      COZYVTT_URL: "http://localhost:8899"
      COZYVTT_EMAIL: "dm@example.local"
      COZYVTT_PASSWORD: "<secret>"
      COZYVTT_CAMPAIGN_ID: "<campaign-uuid>"

Restart Hermes after registering (MCP servers are not hot-reloaded).

Generic MCP client

Any stdio-capable client: command = the venv python, args = server.py, env as above.

Testing

.venv/bin/python -m pytest

Read-only smoke test against a live instance:

COZYVTT_SMOKE=1 COZYVTT_URL=... COZYVTT_EMAIL=... COZYVTT_PASSWORD=... \
  COZYVTT_CAMPAIGN_ID=... .venv/bin/python scripts/smoke.py

(scripts/smoke_write.py writes chat, a public roll, and a secret roll — run it manually and only on a throwaway campaign. It checks sender and unique purpose; proving that players do not receive secret rolls additionally requires an independent player connection.)

Offline tests block TCP connections and include real FastMCP in-memory and stdio checks; they do not require campaign credentials. Live integration against a v1.4.0 instance was verified 2026-09-17 (read/write smoke plus Documents and Saved Rolls round-trips). The local venv used for verification runs Python 3.12.13; Python 3.13 remains unverified.

Troubleshooting

  • Logs: logs/cozyvtt-mcp.log (auth events, WS state, tool calls; never contains passwords)

  • Repeated 401: reviewed v1.4.0 limits failed credential attempts to 5 per 15 minutes/IP. Successful credential requests do not count there; older accounting is unverified. The bridge enforces a re-login interval of at least 3 minutes, including failed attempts; Retry-After may extend it.

  • events_poll empty: may mean no new events. Inspect connected, authenticated, last_error, and connection_error; the single WS worker retries disconnected or rejected connections. Initialization failures can be retried after a 180-second cooldown without restarting.

  • CoC7e initiative doesn't roll dice: upstream behavior — CoC7e initiative is DEX-ordered, no roll is produced

License

MIT (see LICENSE). CozyVTT itself is AGPLv3 — this project is an independent API client and contains no CozyVTT code.

Ecosystem

  • dnd5e-rules — deterministic D&D 5e rules calculations (pure functions, SRD 5.1 data under CC-BY-4.0). The rules layer we pair with this bridge: the server rolls the dice, the bridge carries them, this library does the math, the agent narrates.

Available Tools

41 tools
campaign_document_listCampaign Document ListA
Read-onlyIdempotent

List native and shared documents visible in the configured campaign. Use document_list for asset-library filters and document_read for content. Read-only for members. shared=false identifies a native document without a separate link to revoke; document_unshare cannot remove that source of access. Returns {ok:true,data} on success; tool-body failures return {ok:false,error} with optional diagnostic data. Argument-schema errors are MCP errors.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only, idempotent, and non-destructive behavior. The description adds valuable beyond-annotation context: 'Read-only for members,' the subtle shared=false native-document access nuance, and the return contract ({ok:true,data} vs {ok:false,error}). No contradictions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Each sentence earns its place: purpose, sibling routing, access implications, and error contract. The description is efficient and front-loaded with the core purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter read-only list tool with an output schema and strong annotations, the description covers purpose, alternatives, behavioral nuance, and error patterns. Nothing an agent needs to call this correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the schema fully describes the input surface. Baseline 4 applies; no parameter-specific semantics are needed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States exactly what the tool does: 'List native and shared documents visible in the configured campaign.' It also distinguishes itself from siblings by naming document_list and document_read for alternative purposes, making the tool's role clear and distinct.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit guidance: use document_list for asset-library filters and document_read for content. This tells an agent when not to use this tool, which is strong usage differentiation.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

campaign_getCampaign GetA
Read-onlyIdempotent

Read campaign identity, role, health, current map, and capability evidence. Use this for orientation; use map_list for all maps and session_list for sessions. Read-only for campaign members; /health reachability is not feature support, and unprobed capabilities remain unknown. Repeating reads does not change game state. Returns {ok:true,data} on success; tool-body failures return {ok:false,error} with optional diagnostic data. Argument-schema errors are MCP errors.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds meaningful behavioral context beyond the annotations: read-only access for campaign members, the caveat that /health reachability does not imply feature support, unknown unprobed capabilities, and idempotence via repeating reads not changing state. It also discloses return-shape and error-handling behavior, which annotations do not cover.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Every sentence earns its place: purpose, usage guidance, behavioral caveats, and failure semantics are all included without redundant padding. The key orientation purpose is front-loaded, and the caveats are grouped logically.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given zero parameters, rich annotations, and an output schema, the description fully covers what an agent needs to correctly select and invoke this tool. It explains orientation scope, sibling routing, membership permissions, idempotence, and error response behavior.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has 0 parameters and schema coverage is 100%, so there are no parameter semantics to explain. The description appropriately avoids fabricating parameter guidance, meeting the baseline for a no-parameter tool.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'Read' and the resource scope: campaign identity, role, health, current map, and capability evidence. It also distinguishes itself from map_list and session_list, making its purpose specific and unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly says 'Use this for orientation' and directs the agent to alternatives: 'use map_list for all maps and session_list for sessions.' This gives clear when-to-use guidance and names the sibling tools that handle related but different needs.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

campaign_transfer_dmCampaign Transfer DmA
Destructive

Transfer the campaign DM role to an existing member, or reclaim it as owner. Use campaign_get to inspect current role/ownership first. Upstream permits DM, owner, or admin; owner reclaim uses the owner's own ID. The old DM becomes PLAYER, ownerId stays unchanged, and local role/system caches are invalidated after success. Do not simulate this with separate role edits. Role changes and broadcasts are not guaranteed idempotent; inspect campaign_get before considering another transfer. Returns {ok:true,data} on success; tool-body failures return {ok:false,error} with optional diagnostic data. Argument-schema errors are MCP errors.

ParametersJSON Schema
NameRequiredDescriptionDefault
user_idYesExisting campaign member UUID to become DM; the owner passes their own user UUID to reclaim the role.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false, destructiveHint=true, and idempotentHint=false. The description adds specific behavioral context: 'The old DM becomes PLAYER, ownerId stays unchanged, and local role/system caches are invalidated after success.' It also warns 'Role changes and broadcasts are not guaranteed idempotent,' which aligns with the idempotentHint. This goes beyond the annotations by detailing the side effects. However, it does not state what permissions the caller must hold (e.g., must be admin/owner to transfer), which is a minor gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is about four sentences, each carrying distinct information: purpose, prerequisite, side effects, and return format. It is front-loaded with the action and includes a warning. No filler, but it could be slightly tightened (e.g., merging the return-format sentences). Still, every sentence earns its place, so a 4 is appropriate.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the purpose, prerequisites, side effects, non-idempotency, explicit do-not instructions, and return value format ({ok:true,data} vs {ok:false,error}). It also distinguishes tool-body failures from MCP argument errors. Given the tool's complexity and the existing output schema (which presumably defines the data structure), nothing essential is missing for an agent to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already provides 100% coverage with a clear description: 'Existing campaign member UUID to become DM; the owner passes their own user UUID to reclaim the role.' The description repeats the same idea ('owner reclaim uses the owner's own ID') but adds no new meaning. Per the rubric, when schema coverage is high, baseline is 3, and the description does not elevate it further.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action: 'Transfer the campaign DM role to an existing member, or reclaim it as owner.' It names the resource (campaign DM role) and the two modes, clearly distinguishing it from sibling tools like campaign_get (inspection) and character_update (different resource). The verb 'transfer' is precise and leaves no ambiguity about what the tool does.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly directs the agent to 'Use campaign_get to inspect current role/ownership first' and reiterates 'inspect campaign_get before considering another transfer.' It also provides an explicit negative: 'Do not simulate this with separate role edits.' This gives clear when-to-use and when-not-to-use guidance, plus a precondition that prevents misuse.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

character_createCharacter CreateA

Create a character sheet and ensure it appears in the current campaign roster. Use character_update for an existing sheet and token_add to place a linked token; creation does not place one. Campaign gameSystem determines the initial schema; upstream validates membership and sheet data. Do not trust character_validate as a save gate. After POST, the bridge reads the roster and assigns only if not found. This is not atomic or idempotent: assignment failure returns ok=false with the created character ID in data; missing ID means creation status is unknown. Inspect the roster/UI and recover the existing sheet instead of creating a duplicate. Returns {ok:true,data} on success; tool-body failures return {ok:false,error} with optional diagnostic data. Argument-schema errors are MCP errors.

ParametersJSON Schema
NameRequiredDescriptionDefault
dataNoOptional initial sheet-field object for the campaign system, not a nested request patch; null omits it and lets upstream choose defaults.
nameYesNew sheet display name, 1..200 characters; passed without trimming.
token_image_urlNoOptional artwork URL for the sheet; empty string omits it. This does not create a map token.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description goes well beyond the annotations: it discloses that the operation is not atomic or idempotent, explains the roster read-back and conditional assignment, details failure return shapes including ok=false with a created character ID, and notes when creation status is unknown. Annotations only carry high-level hints, so this behavioral detail is highly valuable.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core purpose and each subsequent sentence provides operationally relevant information about alternatives, failure modes, and recovery. It is long, but the density of caveats is justified for a create tool with non-idempotent behavior.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the full schema descriptions, annotations, and output schema, this description closes the remaining gaps: error contracts, non-idempotency, recovery advice, and the fact that campaign gameSystem determines the initial schema. Nothing an agent needs to invoke this tool correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the input schema already fully documents all three parameters: name length/trimming, data object semantics, and token_image_url default/omission. The description adds the gameSystem-dependent schema context, but parameter meaning is already carried by the schema, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states exactly what the tool does: it creates a new character sheet and ensures it appears in the current campaign roster. It explicitly contrasts with character_update for existing sheets and token_add for token placement, so an agent can distinguish this tool from its siblings immediately.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives direct routing guidance: use character_update for existing sheets and token_add for placing a linked token, and clarifies creation does not place one. It also warns not to trust character_validate as a save gate, providing concrete when-not-to-use guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

character_deleteCharacter DeleteA
DestructiveIdempotent

Delete a character sheet permanently (owner only). Use character_get to inspect the sheet first and character_update to edit it; use token_delete to remove only a placed map token. This deletes the sheet itself, not just its campaign assignment. DM authority alone does not grant deletion rights. It has no undo tool and does not remove map tokens. Repeating leaves the sheet absent but may return a not-found error. Returns upstream {message} in data; REST permission and resource errors retain diagnostics. Returns {ok:true,data} on success; tool-body failures return {ok:false,error} with optional diagnostic data. Argument-schema errors are MCP errors.

ParametersJSON Schema
NameRequiredDescriptionDefault
character_idYesCharacter sheet ID owned by the authenticated user; not a map token ID.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare destructiveHint=true, readOnlyHint=false, and idempotentHint=true, but the description adds crucial context: the deletion is permanent with no undo, it does not remove map tokens, re-invocation may return a not-found error, and the exact success/failure response shapes are specified. This exceeds what annotations alone provide and does not contradict them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is longer than average, but every sentence adds necessary operational context: scope, alternatives, side effects, repeat behavior, and error contract. It is front-loaded with the core purpose and then flows logically through exclusions and return behavior.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With one parameter, a rich output schema, and annotations covering safety and idempotency, the description still provides everything an agent needs: ownership requirements, no undo, no token removal, repeat behavior, and a precise success/error return contract. Nothing important is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already covers the single parameter at 100%, including that it must be a character sheet ID owned by the user, not a map token ID. The description reinforces this in prose but does not add substantially new parameter-level meaning beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb and resource: 'Delete a character sheet permanently (owner only).' It clearly distinguishes itself from sibling tools by noting it is different from token_delete and character_update, so an agent can correctly identify the operation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit when-to-use and when-not-to-use guidance, including 'use character_get to inspect the sheet first,' 'use token_delete to remove only a placed map token,' and the exclusion that 'DM authority alone does not grant deletion rights.' This fully routes the agent to the correct sibling alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

character_getCharacter GetA
Read-onlyIdempotent

Read a full character sheet by ID, preserving unknown fields. Use character_list to discover roster IDs and character_update to patch a sheet. Upstream allows the owner or campaign members to read; keeper data.notes are not private DM fields. Interpret data using the character's own gameSystem, preserving CoC fields and DND hitDice structures. Repeated reads do not alter the sheet. Returns {ok:true,data} on success; tool-body failures return {ok:false,error} with optional diagnostic data. Argument-schema errors are MCP errors.

ParametersJSON Schema
NameRequiredDescriptionDefault
character_idYesExisting character ID, normally discovered with character_list; the sheet may use its own gameSystem.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, openWorld, idempotent, and non-destructive hints, but the description adds meaningful context beyond them: preserving unknown fields, gameSystem-specific interpretation, visibility of keeper data.notes, repeated reads not altering the sheet, and the ok/error return envelope. This is substantial added behavioral detail with no contradiction.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense yet compact, with the primary action front-loaded and every sentence earning its place by adding routing, permission, data-interpretation, or error-handling context. There is no filler or repetition of annotation values.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With a single simple parameter, rich annotations, and a thorough description covering discovery, permissions, data semantics, idempotency, and failure modes, an agent has everything needed to select and invoke this tool correctly. The output schema also covers return-value structure, so nothing critical is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already documents character_id fully at 100% coverage. The description reinforces that the ID is discovered via character_list and that the sheet may use its own gameSystem, but it does not add significant new meaning beyond the schema's parameter description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Read a full character sheet by ID', which clearly states the operation. It also distinguishes itself from sibling tools by explicitly naming character_list for roster discovery and character_update for patching, so an agent can tell them apart.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It provides explicit routing guidance: 'Use character_list to discover roster IDs and character_update to patch a sheet.' It also gives access context by explaining who upstream allows to read, which helps an agent decide when this tool is appropriate.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

character_hitdice_spendCharacter Hitdice SpendA
Destructive

Spend one remaining use from a DND_5E character's Hit Dice pool through WS. Use character_get to inspect pools first; dice_roll and token_hp_update perform rolling and healing separately, with no shared transaction. Upstream requires the character owner or DM and campaign assignment. index selects an array entry, not a dice count. Repeating spends again. Only the system is gated locally: there is no reliable capability probe, and older servers may silently ignore this event. Returns sent:true,confirmed:false,status:"pending" inside data: dispatch is not a business ACK. Read events_poll for results/system.error and inspect state before further action; never blindly resend. Returns {ok:true,data} on success; tool-body failures return {ok:false,error} with optional diagnostic data. Argument-schema errors are MCP errors.

ParametersJSON Schema
NameRequiredDescriptionDefault
indexYesZero-based integer >=0 selecting an entry in sheet data.hitDice; inspect character_get for valid pools and remaining uses.
character_idYesCampaign-assigned DND_5E sheet ID whose Hit Dice pool is spent; not a map token ID.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark this as destructive and non-idempotent, and the description reinforces this with 'Repeating spends again' and 'older servers may silently ignore this event.' It also discloses the asynchronous dispatch contract ('sent:true, confirmed:false, status:pending') and warns that dispatch is not a business ACK, adding substantial behavioral context beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the primary action and usage guidance, and nearly every sentence earns its place given the destructive, async, non-idempotent nature of the tool. It is longer than average and contains a few dense caveats, but the length is justified by the operational risk and failure modes.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive, async, non-idempotent tool, the description covers prerequisites, return contract ({ok:true,data} vs {ok:false,error}), polling via events_poll, failure modes, and authorization requirements. Since an output schema exists, no additional return-value detail is needed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already documents both parameters comprehensively, so the baseline is 3. The description adds high-value disambiguation: index is 'an array entry, not a dice count' and character_id is a campaign-assigned sheet ID, 'not a map token ID', which meaningfully reduces common misuse.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Spend one remaining use from a DND_5E character's Hit Dice pool.' It also explicitly distinguishes this tool from character_get, dice_roll, and token_hp_update, so an agent can tell it apart from siblings without inspecting schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit when-to-use and when-not-to-use guidance: use character_get first to inspect pools, use dice_roll and token_hp_update for rolling and healing separately, and read events_poll for results instead of blindly resending. It also states the prerequisite that the caller must be the character owner or DM with campaign assignment.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

character_listCharacter ListA
Read-onlyIdempotent

List the configured campaign roster to discover character IDs and assignments. Use character_get for one full sheet or character_create to add a sheet. Read-only for campaign members; no creation or roster changes occur on repeat calls. Returns {ok:true,data} on success; tool-body failures return {ok:false,error} with optional diagnostic data. Argument-schema errors are MCP errors.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide readOnlyHint, idempotentHint, openWorldHint, and destructiveHint. The description adds valuable behavioral context beyond those: no creation or roster changes on repeat calls, the successful return shape {ok:true,data}, failure shape {ok:false,error}, and the distinction between tool-body failures and MCP argument-schema errors. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is four sentences and every sentence earns its place: what it does, sibling routing, idempotency/read-only guarantee, and return/error behavior. The primary purpose is front-loaded, and there is no redundant filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter list operation with rich annotations and an output schema, the description is complete. It covers the operation's scope, safety, idempotency, return format, error format, and the relationship to sibling tools—everything an agent needs to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the baseline is 4. The description adds no parameter details because none are needed; the schema already reflects an empty parameter set. There is no gap requiring compensation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource: "List the configured campaign roster to discover character IDs and assignments." It also differentiates itself from character_get and character_create, so an agent can distinguish it from close siblings without opening their schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says when to use this tool versus alternatives: "Use character_get for one full sheet or character_create to add a sheet." It also clarifies that the operation is read-only and safe on repeat calls, giving clear context for invocation.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

character_updateCharacter UpdateA
Destructive

Patch an existing sheet while preserving unspecified fields (owner or campaign DM). Use character_get first; use token_hp_update for a signed HP change and character_create for a new sheet. data is a request-field object, e.g. {"data":{"hp":{"current":5}}}. Only name/data/tokenImageUrl are allowed at the top level. Nested data dictionaries merge recursively after a GET; arrays/scalars replace whole values and null is an explicit value, not deletion. The caller calculates rules values using the sheet's own gameSystem. Updates are locked only within this process; concurrent browser saves may be lost. Reapplying values is stable absent concurrent edits, but upstream update side effects are not guaranteed idempotent. REST errors retain diagnostics. Returns {ok:true,data} on success; tool-body failures return {ok:false,error} with optional diagnostic data. Argument-schema errors are MCP errors.

ParametersJSON Schema
NameRequiredDescriptionDefault
dataYesNonempty request patch containing only name, data, tokenImageUrl. Sheet changes go inside data as an object; arrays replace, null is explicit.
character_idYesExisting sheet ID to modify; upstream enforces owner or campaign DM access.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already flag destructive and non-idempotent behavior, but the description adds substantial context: merge semantics, null-as-explicit-value, concurrency limits, potential loss of concurrent browser saves, and error/response shapes. This goes well beyond what annotations alone provide and does not contradict them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense and front-loaded with the main purpose, but it is long and somewhat repetitive with the schema's parameter descriptions. Every sentence adds real behavioral value, though restructuring into clearer sections would improve scannability.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutating patch tool with nested objects and concurrency caveats, the description is unusually complete: it covers access constraints, merge rules, idempotency, error behavior, and return shapes. The presence of an output schema further reduces the burden, so nothing essential is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds a concrete example, restricts top-level fields to name/data/tokenImageUrl, and clarifies nested merge behavior. This meaningfully supplements the schema even though the schema already carries solid parameter descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Patch an existing sheet while preserving unspecified fields.' It also distinguishes itself from siblings by explicitly routing to character_get, token_hp_update, and character_create, so an agent can tell this tool apart without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit when-to-use guidance: use character_get first, use token_hp_update for a signed HP change, and use character_create for a new sheet. It also clarifies caller responsibility for computing rule values, which helps the agent decide whether this is the right tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

character_validateCharacter ValidateA
Read-onlyIdempotent

Read upstream validation diagnostics for an owned character with a fixed gameSystem. Use character_get to inspect fields; do not use this as a reliable save gate. v1.4.0 ignores validation failures, so isValid=true does not prove validity; older-version reliability is unknown. Always adds validation_reliable=false and validation_note. Owner-only upstream read; repeating it does not repair or save data. Returns {ok:true,data} on success; tool-body failures return {ok:false,error} with optional diagnostic data. Argument-schema errors are MCP errors.

ParametersJSON Schema
NameRequiredDescriptionDefault
character_idYesExisting character ID owned by the authenticated user; fixed-system validation is required upstream.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already indicate read-only, idempotent, and non-destructive behavior, and the description adds valuable context beyond that: version-specific validation reliability, the guaranteed addition of validation_reliable and validation_note, and the exact success/error return shapes. There is no contradiction with the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with purpose and usage, then covers reliability caveats and return behavior. It is a bit dense, but every sentence earns its place by conveying risks and edge cases that an agent needs before calling.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter read-only tool with rich annotations and an output schema, the description is complete. It covers ownership, reliability caveats, success versus failure shapes, and MCP-level argument-schema errors, leaving no critical gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema fully documents character_id at 100% coverage, so the baseline is 3. The description reinforces that the character must be owned and that validation is fixed-system, but it does not add meaningfully new parameter-level semantics beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Read upstream validation diagnostics for an owned character.' It also distinguishes itself from character_get by explicitly routing field inspection to that sibling, so an agent can tell the tools apart.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit guidance: use character_get to inspect fields and do not rely on this tool as a save gate. It also clarifies that repeating the call does not repair or save data, which helps an agent decide when not to invoke it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

chat_readChat ReadA
Read-onlyIdempotent

Read persisted campaign messages with opaque cursor pagination. Use chat_read for narration history; use events_poll for dice results and live events. Read-only for campaign members. Start without a cursor, then pass nextCursor unchanged; stop at null. Older servers support only the latest page and reject cursor history. DICE_ROLL entries are excluded. Repeated reads do not consume messages. Returns {ok:true,data} on success; tool-body failures return {ok:false,error} with optional diagnostic data. Argument-schema errors are MCP errors.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoPage size, 1..100 messages; defaults to 20.
cursorNoOpaque pagination.nextCursor from the previous response; null starts with the latest page. Do not construct cursors or offsets.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/non-destructive, and the description adds actionable behavioral details: repeated reads do not consume messages, DICE_ROLL entries are excluded, older servers reject cursor history, and failure modes return ok:false. This goes well beyond the annotation hints.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but every sentence earns its place: purpose, routing, permissions, pagination procedure, server caveat, exclusions, idempotence, and error contract. The most critical usage guidance is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present and rich annotations, the description covers all operational essentials: pagination protocol, server compatibility, exclusions, and error format. Nothing an agent needs to invoke or interpret the tool correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description enriches the cursor parameter with lifecycle semantics ('pass nextCursor unchanged', 'stop at null', 'Do not construct cursors or offsets') and clarifies the limit's pagination role. Slight deduction because the limit parameter is not discussed beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource ('Read persisted campaign messages') and immediately distinguishes itself from events_poll. It also states exclusions (DICE_ROLL entries), leaving no ambiguity about what the tool returns.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes usage: 'Use chat_read for narration history; use events_poll for dice results and live events.' It also provides a clear pagination walkthrough (start without cursor, pass nextCursor unchanged, stop at null) and notes server compatibility caveats.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

chat_sendChat SendA

Post one campaign chat message as narration or player dialogue. Use chat_read to inspect history; use dice_roll for dice, not chat text pretending to be a roll. Authenticated campaign membership is required; type is a message category, not a role grant. Upstream campaign chat cooldown may reject messages. Creates a new message on each accepted send; do not retry blindly. Returns sent:true,confirmed:false,status:"pending" inside data: dispatch is not a business ACK. Read events_poll for results/system.error and inspect state before further action; never blindly resend. Returns {ok:true,data} on success; tool-body failures return {ok:false,error} with optional diagnostic data. Argument-schema errors are MCP errors.

ParametersJSON Schema
NameRequiredDescriptionDefault
typeNoMessage category: DM (default narration) or PLAYER. This does not change the authenticated role.DM
contentYesNonblank message text, at most 2000 characters; whitespace is preserved when sent.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only say this is a non-read, non-idempotent, non-destructive operation. The description adds crucial behavioral context beyond annotations: the send is asynchronous and returns sent:true with pending status, not a business ACK; cooldowns may reject; each accepted send creates a new message; and events_poll must be consulted for actual results. This substantially helps an agent avoid incorrect assumptions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense and front-loaded with purpose, then flows into usage, behavioral caveats, and return semantics. Minor redundancy exists between 'do not retry blindly' and 'never blindly resend', but overall every major sentence adds necessary information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutating, asynchronous tool with a small schema, the description covers purpose, alternatives, authentication, failure modes, async dispatch semantics, return envelope, and follow-up steps via events_poll. It is complete enough for an agent to invoke it correctly and interpret responses appropriately.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents both parameters well. The description reinforces that type is a category rather than a role grant, but this is already present in the schema's type description. No new parameter-level semantics are added beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Post one campaign chat message as narration or player dialogue.' It clearly differentiates itself from sibling tools by explicitly routing history inspection to chat_read and dice rolling to dice_roll.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit when-to-use guidance and names alternatives: use chat_read for history, use dice_roll for dice rather than sending text as a roll. It also warns against blind retries and directs follow-up through events_poll, giving an agent clear decision boundaries.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

dice_rollDice RollA

Roll server-authoritative dice and publish the result to the permitted audience. Use saved_roll_list for stored expressions; saving a macro does not execute it. Authenticated campaign users may roll. Public rolls broadcast to the campaign; v1.4.0 secret rolls go to the roller and DMs, not exclusively to DMs if a player rolls. Each send creates a new roll; never retry on missing results. Calls queue with a 2.1-second minimum between actual sends; upstream allows 30 rolls/minute/user. The bridge performs no random generation or rules calculations. Returns sent:true,confirmed:false,status:"pending" inside data: dispatch is not a business ACK. Read events_poll for results/system.error and inspect state before further action; never blindly resend. Returns {ok:true,data} on success; tool-body failures return {ok:false,error} with optional diagnostic data. Argument-schema errors are MCP errors.

ParametersJSON Schema
NameRequiredDescriptionDefault
purposeNoOptional broadcast label explaining the roll; empty string omits it, without changing dice calculation.
is_secretNoFalse publishes to the campaign; true requests secret delivery to the roller and DMs (wire field secret).
expressionYesServer-parsed dice expression, e.g. 1d20+5, 2d6, or 4d6kh3; invalid syntax is reported asynchronously.
character_nameNoOptional display attribution (wire characterName), not a character ID or permission credential; null omits it.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description richly discloses behaviors beyond annotations: server-authoritative generation, 2.1-second queueing, 30 rolls/minute rate limit, no random generation/rules calculation by the bridge, pending-not-ACK semantics, and error response shapes. It even warns against retrying on missing results. This goes well beyond the minimal annotation signals (readOnly=false, openWorld=true, idempotent=false) and contains no contradictions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but every sentence adds necessary context: core purpose first, then alternatives, then behavioral constraints, then error semantics. No filler or repetition. It is structured logically and front-loaded with the most critical information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with 4 params, 1 required, an output schema, and non-trivial queueing/error behavior, the description is complete. It covers who can use it, how to handle results asynchronously, rate limits, and exact success/failure response envelopes. Nothing critical is left to inference.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3. The description adds meaning beyond the schema by clarifying async invalid-syntax reporting for expression, explaining the audience implications of is_secret (especially the v1.4.0 nuance), and stating character_name is not a credential. These additions justify a score above baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb-resource-audience statement: 'Roll server-authoritative dice and publish the result to the permitted audience.' It also distinguishes itself from saved_roll_list (stored expressions don't execute), so an agent can immediately tell it apart from the sibling tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly names the alternative (saved_roll_list), states the precondition (authenticated campaign users), explains audience differences for public vs. secret rolls, and instructs the agent to poll events_poll for results and never blindly resend. This is clear when/when-not guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

document_createDocument CreateA

Create a new txt/md document from inline content through REST. Use document_upload for PDF or larger local files, and document_update to replace existing text. Name and description are trimmed; content preserves whitespace. USER is personal, CAMPAIGN requires its DM, and GLOBAL rights are enforced upstream. Each accepted call creates a separate asset. Content is capped at 900 KiB UTF-8; upstream JSON limits also apply. Upload/create share a default 30 requests/minute/user limit. Creation does not separately link a personal asset; use document_share for that. Returns {ok:true,data} on success; tool-body failures return {ok:false,error} with optional diagnostic data. Argument-schema errors are MCP errors.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesAsset title, trimmed to 1..200 characters.
scopeNoVisibility/ownership scope: USER (default personal), CAMPAIGN, or GLOBAL; upstream enforces creation rights. CAMPAIGN uses campaign_id.USER
formatYesText representation: txt or md; PDFs require document_upload.
contentYesComplete text, including empty text, at most 900 KiB UTF-8; rejects C0/DEL controls except TAB/LF/FF/CR.
campaign_idNoExplicit campaign ID; null uses the configured campaign when scope=CAMPAIGN, otherwise omits the field. If supplied, it is forwarded for any scope.
descriptionNoOptional metadata, trimmed to at most 1000 characters; null omits it.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate readOnlyHint=false and destructiveHint=false, but the description adds substantial behavioral context beyond them: whitespace preservation for content, trimming of name/description, scope-based permission enforcement (USER personal, CAMPAIGN requires DM, GLOBAL upstream), a 900 KiB UTF-8 cap, a shared rate limit of 30 requests/minute/user, and the return envelope shape. It also notes that each accepted call creates a separate asset. No annotation contradiction exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is longer than average, but every sentence carries operational value, including routing, limits, permissions, and response format. It is front-loaded with purpose and alternatives before diving into behavioral details. It could be slightly tightened, but it remains well-structured and free of filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite the tool's six parameters and rich schema, the description leaves no essential gap: it covers when to use it, alternatives, permissions by scope, size limits, rate limits, return behavior, and a pointer to document_share for linking. The presence of an output schema and detailed input schema further reduces the burden, and the description is more than sufficient for an agent to invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all six parameters. The description still adds semantic value by clarifying that 'Name and description are trimmed; content preserves whitespace' and that scope rights are enforced upstream. These nuances are not fully captured in the schema property descriptions, so the description meaningfully supplements the structured input definitions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Create a new txt/md document from inline content through REST.' It explicitly distinguishes itself from siblings by naming document_upload (PDF/larger local files) and document_update (replace existing text). An agent can immediately identify what this tool does and how it differs from alternative document tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit routing guidance: 'Use document_upload for PDF or larger local files, and document_update to replace existing text.' It also clarifies when document_share is needed ('Creation does not separately link a personal asset; use document_share for that'). This leaves no ambiguity about when to choose this tool over its siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

document_deleteDocument DeleteA
DestructiveIdempotent

Delete a document asset and all of its share links. Use document_unshare to remove only one campaign link and document_read to inspect content first. Upstream enforces uploader/DM/admin permissions according to scope. Deletion is destructive; local downloaded copies remain. Repeating leaves the asset absent but can return a not-found error. This tool does not offer an undo operation. Returns {ok:true,data} on success; tool-body failures return {ok:false,error} with optional diagnostic data. Argument-schema errors are MCP errors.

ParametersJSON Schema
NameRequiredDescriptionDefault
document_idYesDocument asset ID to remove globally, including all campaign sharing links; not a single link ID.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, idempotentHint=true, and readOnlyHint=false, but the description adds substantial context beyond them: local downloaded copies survive deletion, repeating the call is idempotent in effect yet may return a not-found error (clarifying the idempotentHint), there is no undo, and the return shape distinguishes success, tool-body failures, and MCP schema errors. This meaningfully enriches what the annotations alone convey and does not contradict them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but not bloated; each of its seven sentences earns its place (purpose, sibling routing, permissions, destructiveness, idempotency caveat, undo absence, return contract). The core purpose is front-loaded before caveats. It is slightly long, but for a destructive, irreversible operation the thoroughness is justified.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive tool with one parameter, the description is complete: it covers the action, cascade effect on share links, permission context, error/return contract, and irreversibility. The output schema exists and the description still explains the {ok:true,data} vs {ok:false,error} contract, which is more than sufficient for an agent to invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the schema already explains that document_id is a 'Document asset ID to remove globally, including all campaign sharing links; not a single link ID.' The description reinforces this via the document_unshare contrast but adds no new parameter-level detail beyond the schema. Baseline 3 is appropriate since the schema carries the full burden.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Delete a document asset and all of its share links.' It explicitly differentiates itself from document_unshare ('remove only one campaign link') and document_read ('inspect content first'), making the tool's scope unmistakable without needing to inspect siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit routing guidance: use document_unshare when only one campaign link must be removed, and use document_read to inspect content before deleting. It also states that permission enforcement is handled upstream. An agent knows exactly when to pick this tool over its siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

document_listDocument ListA
Read-onlyIdempotent

List document assets with scope, search, and page filters. Use campaign_document_list to discover personal documents shared into this campaign; use document_read for content. Read-only; upstream filters by access. USER restricts to personal assets (including an explicit current-user filter for admins); null scope leaves filtering to upstream. Repeated listing does not consume or modify assets. Returns {ok:true,data} on success; tool-body failures return {ok:false,error} with optional diagnostic data. Argument-schema errors are MCP errors.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNoOne-based page number, integer >=1; defaults to the first page.
limitNoAssets per page, integer 1..100; defaults to 50.
scopeNoOptional USER/CAMPAIGN/GLOBAL filter; null leaves scope unspecified. USER means current-user personal assets.
searchNoOptional search text passed upstream; null omits the filter, empty text is sent explicitly.
campaign_idNoExplicit campaign ID; null uses the configured campaign when scope=CAMPAIGN, otherwise omits the field. If supplied, it is forwarded for any scope.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint. The description adds valuable context beyond those: upstream filters by access, USER scope uses an explicit current-user filter for admins, repeated listing does not consume or modify assets, and success/failure return shapes are specified. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with purpose and filters, immediately followed by sibling routing, then behavioral notes and return/error semantics. Every sentence adds distinct value; there is no filler or repetition of schema content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 5-parameter read-only list tool with an output schema, the description is complete: it covers scope semantics, access filtering, idempotence, success shape, tool-body failure shape, and MCP-level argument errors. Nothing critical is missing for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds meaningful param nuance beyond the schema, particularly that USER restricts to personal assets with an explicit current-user filter for admins and that null scope leaves filtering to upstream. This clarifies behavior that raw schema descriptions only hint at.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with the specific verb 'List' and resource 'document assets', then names the exact filters (scope, search, page). It also explicitly distinguishes itself from campaign_document_list and document_read, so an agent can tell sibling tools apart immediately.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives clear routing guidance: use campaign_document_list to discover personal documents shared into the campaign, and use document_read for content. It also explains read-only access and upstream filtering, which helps the agent decide when this tool is appropriate versus alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

document_readDocument ReadA
Read-onlyIdempotent

Read an accessible document as text or a local binary download. Use document_list/campaign_document_list to discover IDs; use document_update to replace txt/md content. Upstream checks asset visibility, including shared access. Does not modify upstream data, but binary reads atomically replace downloads/.pdf (or .bin) locally; readOnlyHint refers to the upstream resource. Text returns mime_type/etag/content. Binary returns mime_type/etag/file_path/file_size, never inline bytes. Pass etag unchanged for a conditional read: 304 returns not_modified=true without content, so retain your cached copy. Repeated reads may refresh the local file. Returns {ok:true,data} on success; tool-body failures return {ok:false,error} with optional diagnostic data. Argument-schema errors are MCP errors.

ParametersJSON Schema
NameRequiredDescriptionDefault
etagNoPrevious response ETag, passed unchanged as If-None-Match; null requests content without a cache condition.
document_idYesDocument asset ID; only ASCII letters, digits, underscores, and hyphens are accepted because it also names a local file.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations carry readOnlyHint/idempotentHint, but the description adds crucial nuance: binary reads 'atomically replace downloads/<id>.pdf locally' while 'readOnlyHint refers to the upstream resource.' It also discloses upstream visibility checks, conditional-read semantics, and the {ok:false,error} failure envelope — all context the annotations alone do not provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded purpose, then usage, behavior, return modes, and error format in a logical order; every sentence carries information. Slightly longer than strictly necessary since the output schema already documents return fields, but the density is justified by the tool's two modes and local side effects.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the output schema covers return values and annotations cover safety hints, the description still supplies everything an agent needs: discovery flow, local file side-effect disclosure, conditional caching semantics, and the distinction between tool-body failures and MCP argument-schema errors. Nothing needed for correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3. The description adds genuine value by explaining the etag's behavioral consequence — '304 returns not_modified=true without content, so retain your cached copy' — which goes beyond the schema's request-side description of If-None-Match. It reinforces the mode-dependent return fields but leans partly on the output schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb and resource: 'Read an accessible document as text or a local binary download.' It also distinguishes itself from siblings by naming document_list/campaign_document_list for ID discovery and document_update for content replacement, so an agent can route correctly without opening other schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes the agent: 'Use document_list/campaign_document_list to discover IDs; use document_update to replace txt/md content.' It also explains when to use the etag parameter (conditional read with 304 handling) and how to interpret the not_modified response, leaving no ambiguity about invocation flow.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

document_shareDocument ShareA

Link a shareable document asset into the configured campaign (DM only). Use campaign_document_list to inspect existing links, or document_upload to create an asset first. Upstream validates asset ownership, UUID, and sharing rights. Sharing broadens access without copying the asset. Duplicate-link behavior is upstream-controlled; do not assume retries are idempotent. Use document_unshare to revoke this link, not document_delete, which removes the asset everywhere. Returns {ok:true,data} on success; tool-body failures return {ok:false,error} with optional diagnostic data. Argument-schema errors are MCP errors.

ParametersJSON Schema
NameRequiredDescriptionDefault
document_idYesShareable DOCUMENT asset UUID, not a local filename; must satisfy upstream ownership/scope checks.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark this as non-readonly, non-idempotent, and non-destructive, but the description goes further: it explains that sharing broadens access without copying, duplicate-link behavior is upstream-controlled, and retries cannot be assumed idempotent. It also documents success/error return shapes and MCP error behavior, adding real behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is moderately sized but front-loaded with the core purpose and then covers usage, behavioral caveats, and return formats in a logical order. Every sentence earns its place, though the return-format and MCP-error sentences add density.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter write operation with an output schema and rich annotations, the description covers the essential context: who may use it, what side effects occur, what makes it non-idempotent, how to undo it, and what response shape to expect. Nothing critical is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the parameter description already explains that document_id must be a shareable DOCUMENT asset UUID, not a filename, and must satisfy ownership checks. The tool description adds no additional parameter semantics, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific action ('link a shareable document asset into the configured campaign'), scopes it to DM only, and contrasts it with siblings like document_unshare and document_upload. This makes the tool’s role immediately distinguishable from other document and campaign tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit when/how guidance: use campaign_document_list to inspect existing links, document_upload to create an asset first, document_unshare to revoke, and explicitly warns against document_delete for this purpose. The DM-only restriction further clarifies appropriate invocation context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

document_unshareDocument UnshareA
DestructiveIdempotent

Remove one document share link from the configured campaign (DM only). Inspect campaign_document_list first: shared=false denotes a native document with no separate link to revoke. Use document_delete only to delete the asset everywhere. This leaves the asset, other links, local downloads, and GLOBAL/native read access intact. Repeating removes no additional link but may return a not-found error. Returns {ok:true,data} on success; tool-body failures return {ok:false,error} with optional diagnostic data. Argument-schema errors are MCP errors.

ParametersJSON Schema
NameRequiredDescriptionDefault
document_idYesDocument asset ID with an explicit share link in this campaign; native documents cannot be unshared this way.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Despite annotations already marking destructive and idempotent hints, the description adds meaningful specifics: what remains intact (asset, other links, local downloads, global access), that repeats may error, and the success/failure return shape. It clarifies the idempotency nuance rather than contradicting it.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but each sentence earns its place: purpose, prerequisites, alternatives, side-effect boundaries, idempotency behavior, and error modes. The most critical scoping information is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-param mutating tool, this description is exceptionally complete. It covers permission context, preconditions, alternative tool routing, side effects, repeat-call behavior, and return/error semantics without requiring the agent to infer anything important.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already fully documents document_id with a clear description, so the baseline is satisfied. The description adds extra value by explaining how to recognize invalid targets via shared=false in campaign_document_list, which helps the agent pick the correct ID.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Remove one document share link from the configured campaign (DM only).' It clearly differentiates from sibling document_delete by explaining that unshare only revokes one link while deletion removes the asset everywhere.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit when-to-use guidance: DM only, inspect campaign_document_list first, and avoid unsharing documents where shared=false. It also names document_delete as the correct alternative for full asset deletion.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

document_updateDocument UpdateA
Destructive

Replace an entire txt/md document's content (uploader/admin only). Use document_read first to avoid losing text; use document_create for a new asset or document_upload for PDF. This is replacement, not merge-patching, and cannot edit PDF content. Empty content clears the text. Repeated writes can update metadata or notifications; no full-operation idempotency is promised. Returns upstream REST data. Returns {ok:true,data} on success; tool-body failures return {ok:false,error} with optional diagnostic data. Argument-schema errors are MCP errors.

ParametersJSON Schema
NameRequiredDescriptionDefault
contentYesComplete text, including empty text, at most 900 KiB UTF-8; rejects C0/DEL controls except TAB/LF/FF/CR.
document_idYesExisting editable text document asset ID, not a share-link ID.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations (destructiveHint=true, idempotentHint=false), the description adds critical behavior: empty content clears the text, repeated writes are not fully idempotent and may update metadata/notifications, and it returns upstream REST data with a documented success/error envelope. This fully discloses the operation's safety and side-effect profile.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but every sentence earns its place: core action, prerequisite read, alternative tools, merge-vs-replace distinction, edge case (empty content), idempotency caveat, and return envelope. It is front-loaded with the main purpose and then proceeds logically through usage and behavior.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive update tool, the description covers prerequisites, alternatives, limitations (PDF), edge cases, idempotency, return format, and error semantics. Combined with an output schema and rich annotations, nothing essential is missing for an agent to invoke this tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already covers 100% of parameters with descriptions, so the baseline is 3. The description adds meaningful semantic context beyond the schema by explaining that empty content clears the text and restating that document_id must be an existing editable text document. This elevates it to a 4.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Replace an entire txt/md document's content'. It immediately differentiates itself from sibling tools by naming document_create, document_upload, and document_read, making clear what this tool is and is not for.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit guidance is provided: 'Use document_read first to avoid losing text; use document_create for a new asset or document_upload for PDF.' It also clarifies this is replacement, not merge-patching, and cannot edit PDF content, so an agent knows precisely when to select this tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

document_uploadDocument UploadA

Upload an existing local PDF/txt/md file as a document asset using multipart REST. Use document_create for inline text, or document_share to link an existing asset. Reads the MCP server/container filesystem; client-local paths must be mounted. Creates an asset on each accepted call, so retries may duplicate it. Scope controls access: CAMPAIGN requires that campaign's DM; other scope rights are upstream-enforced. The server checks signatures and its size cap (default 50 MiB), with a shared upload/create limit of 30/minute/user by default. A 400 is preserved without fallback upload. Returns {ok:true,data} on success; tool-body failures return {ok:false,error} with optional diagnostic data. Argument-schema errors are MCP errors.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoOptional asset display name; null omits it so upstream uses its upload default.
tagsNoOptional tag strings joined by commas for multipart upload; null omits tags, while [] sends an empty field.
scopeNoVisibility/ownership scope: USER (default personal), CAMPAIGN, or GLOBAL; upstream enforces creation rights. CAMPAIGN uses campaign_id.USER
file_pathYesExisting .pdf/.txt/.md path on the MCP server filesystem; ~ is expanded. Container users must mount the file.
campaign_idNoExplicit campaign ID; null uses the configured campaign when scope=CAMPAIGN, otherwise omits the field. If supplied, it is forwarded for any scope.
descriptionNoOptional asset metadata text; null omits it. Upstream validates upload metadata.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only mark side effects and idempotency; the description adds major operational detail: retries duplicate assets, CAMPAIGN scope requires the DM, signature/size-cap checks, default 30/min rate limit, 400 preservation, and exact success/failure response shapes. This is far beyond annotation coverage.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Though long, every sentence carries a distinct operational fact: purpose, alternatives, filesystem constraint, idempotency warning, access control, limits, error behavior, and return format. It is front-loaded with purpose and routing and contains no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutating, non-idempotent upload tool with 6 parameters, this description covers file source prerequisites, permissions, rate limits, duplication risk, return values, and error classification. Output schema exists and is further supplemented by explicit response documentation, so nothing an agent needs to invoke correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with rich parameter descriptions, so the baseline is 3. The description adds extra meaning for scope (CAMPAIGN requires that campaign's DM) and file_path (size cap and signature checks), justifying a small bump above baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence specifies the exact operation: uploading an existing local PDF/txt/md file as a document asset via multipart REST. It also differentiates from siblings by naming document_create for inline text and document_share for linking existing assets, so an agent can select the right tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit routing guidance: use document_create for inline text, document_share for linking existing assets, and this tool when uploading a file. It also states the filesystem prerequisite ('client-local paths must be mounted'), which is a clear when-not condition.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

events_pollEvents PollA
Read-onlyIdempotent

Read buffered campaign events and asynchronous write errors without consuming them. Use after WS writes; use chat_read for persisted chat history. May connect WS lazily, but does not change game state. Returns earliest seq > since first; advance using next_seq (latest_seq is its alias), not high_water_seq. Check gap for eviction from the 500-event buffer, cursor_reset after process restart, and has_more for pagination. Inspect system.error and relevant state to assess pending writes; broadcasts are not correlated ACKs. Buffered events remain available on connection failure, marked stale; this is not durable dice history. Repeated reads can include newly arriving events. Returns {ok:true,data} on success; tool-body failures return {ok:false,error} with optional diagnostic data. Argument-schema errors are MCP errors.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum events per page, 1..500; defaults to 100. Continue with next_seq when has_more is true.
sinceNoLast next_seq received, integer >=0; 0 starts at the oldest retained event. A cursor beyond this process resets to 0.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark this readOnly, idempotent, and non-destructive, and the description reinforces and enriches these with critical context: events are not consumed, connection may be lazy, game state is unchanged, buffer eviction is 500 events, cursor reset happens after process restart, and stale events remain available. This goes far beyond what annotations provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Although dense, every sentence carries distinct content—purpose, usage, cursor mechanics, buffer semantics, error behavior, and return shape. The most important behavioral facts are front-loaded, and no filler or repetition exists.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity, the description is remarkably complete: it covers consumption semantics, async error inspection, pagination, buffer eviction, connection failure behavior, non-durability, return shapes, failure modes, and MCP error handling. An agent has enough to call it correctly without additional context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, and the description adds valuable semantic detail beyond the schema: 'Returns earliest seq > since first', 'advance using next_seq (latest_seq is its alias), not high_water_seq', and explains gap, cursor_reset, and has_more. This meaningfully informs correct parameter use.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific action and resource: 'Read buffered campaign events and asynchronous write errors without consuming them.' It explicitly distinguishes itself from chat_read ('use chat_read for persisted chat history') and clearly describes the non-mutating nature of the tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives direct when-to-use guidance: 'Use after WS writes' and names the alternative for chat history ('use chat_read for persisted chat history'). It also explains cursor advancement, pagination, and buffer behavior, leaving little ambiguity about how the tool should be used.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

initiative_manageInitiative ManageA
Destructive

Modify campaign combatants, initiative values, order, or combat lifecycle. Use initiative_read for current state and events_poll for results/errors. Structural actions are DM-only; v1.4.0 also permits a controlling player to roll for an already added token before combat, subject to upstream checks. Older permission behavior is unverified. Actions may remove entries, clear state, reroll, or advance turns; the combined tool is not idempotent. add needs token_id/map_id; remove needs token_id; set needs token_id/map_id/value; reorder needs ordered_token_ids; start/next/end need only action. roll needs token_id and map_id and is gated to DND_5E/PATHFINDER_2E/SHADOWRUN_6E. The server derives system rolls; expression is a DM fallback, not a guaranteed override. CoC7e uses DEX ordering: use add/start or set. The dice_roll 2.1-second queue does not wrap initiative_manage; do not assume it throttles initiative rolls. Returns sent:true,confirmed:false,status:"pending" inside data: dispatch is not a business ACK. Read events_poll for results/system.error and inspect state before further action; never blindly resend. Returns {ok:true,data} on success; tool-body failures return {ok:false,error} with optional diagnostic data. Argument-schema errors are MCP errors.

ParametersJSON Schema
NameRequiredDescriptionDefault
valueNoManual initiative number required for set; null means unspecified. Other actions ignore it.
actionYesOne of add, remove, roll, set, reorder, start, next, end; case-insensitive. Determines required companion parameters.
map_idNoMap containing the token; required for add/roll/set, otherwise unused (empty default).
token_idNoToken to add/remove/roll/set; required for those actions. Empty default is appropriate for reorder/start/next/end.
expressionNoOptional roll fallback for a DM when system derivation has no value; empty uses the server default. Ignored outside roll.
character_nameNoOptional display label passed only for roll; empty omits it and does not affect permissions.
ordered_token_idsNoNonempty ordered list of combatant token IDs for reorder; overrides value ordering. Null is appropriate for other actions.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations, the description reveals important behaviors: actions may remove entries, clear state, reroll, or advance turns; the tool is not idempotent; dispatch returns a pending status rather than a business ACK; and errors may require reading events_poll. It also warns that older permission behavior is unverified and that the dice_roll queue does not throttle initiative rolls. This substantially exceeds what annotations alone provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but densely packed with necessary information: purpose, routing, permissions, per-action requirements, async behavior, and error contracts. Every section earns its place, and the most important scoping statement is front-loaded. No filler or tautology is present.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity—seven actions, async dispatch semantics, permission variations, system gating, and CoC7e specifics—the description covers all essential contexts. It explains return shapes, the need to poll events_poll, and how to interpret pending status. The output schema exists, and the description complements it by explaining business-level behavior rather than repeating structure.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Although the input schema already has 100% parameter coverage, the description adds a crucial action-to-parameter dependency matrix: add needs token_id/map_id, remove needs token_id, set needs token_id/map_id/value, reorder needs ordered_token_ids, and start/next/end need only action. It also clarifies that expression is a DM fallback rather than a guaranteed override, which is not obvious from the schema alone.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Modify campaign combatants, initiative values, order, or combat lifecycle.' It clearly distinguishes initiative_manage from initiative_read, which is the read-only counterpart, and lists the exact actions supported. An agent can immediately tell what this tool does and how it differs from siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit routing guidance: 'Use initiative_read for current state and events_poll for results/errors.' It also gives action-specific conditions, permission caveats, system gates for roll, and a CoC7e-specific recommendation to use add/start or set. This gives the agent clear when-to-use and when-not-to-use context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

initiative_readInitiative ReadA
Read-onlyIdempotent

Read initiative state without changing turn order or advancing combat. Use initiative_manage to modify combat and events_poll for broadcast history. Campaign members may read. By default, request a new WS state and wait up to two seconds; timeout returns state=null/stale=true, not proof that combat is inactive. refresh=false reads the current connection's cache and marks it stale. Repeated requests do not change initiative; WS authentication is still required. Returns {ok:true,data} on success; tool-body failures return {ok:false,error} with optional diagnostic data. Argument-schema errors are MCP errors.

ParametersJSON Schema
NameRequiredDescriptionDefault
refreshNoTrue requests and waits for fresh state; false uses cached state, which may be absent or stale.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description goes well beyond annotations by explaining WS refresh behavior, the two-second timeout, the meaning of stale=true, the difference between refresh=true and refresh=false, and that repeated requests do not change initiative. It also covers authentication requirements and error return shapes, providing rich behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured and front-loaded: purpose first, then alternatives, access, behavior details, and return contract. Every sentence adds value, and the length is appropriate for the complexity of the tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the presence of a rich output schema, comprehensive annotations, and a single parameter, the description covers all necessary contextual aspects: usage intent, sibling differentiation, access control, caching and timeout behavior, authentication, and error handling. Nothing important is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Although the schema already documents the refresh parameter with 100% coverage, the description adds crucial semantics: by default it requests a new WS state and waits up to two seconds, timeout yields state=null/stale=true, and refresh=false uses cached state and marks it stale. This meaningfully enhances the parameter's interpretation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Read initiative state'. It further clarifies the read-only nature by saying it does not change turn order or advance combat, and it names sibling tools (initiative_manage, events_poll) for comparison, making the tool's purpose unmistakable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit guidance is given: use initiative_manage to modify combat and events_poll for broadcast history. It also states that campaign members may read, providing access context. This clearly distinguishes when this tool should be selected over siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

map_createMap CreateA

Create a campaign map using existing image assets (DM only). Use map_list to inspect existing maps and map_switch to activate one; creation does not switch the current map. This creates a map with empty tokens and annotations, not an uploaded image. Upstream checks image access and normalizes asset URLs. Each accepted call creates another map; do not blindly retry an uncertain result. Returns upstream {map} in data without a broadcast receipt. REST validation and permission errors retain upstream diagnostics. Returns {ok:true,data} on success; tool-body failures return {ok:false,error} with optional diagnostic data. Argument-schema errors are MCP errors.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesNonblank display name for the new map; upstream trims it.
widthYesMap width as a positive integer, in grid units.
heightYesMap height as a positive integer, in grid units.
grid_sizeNoPositive integer pixels per grid square; defaults to 50.
image_urlYesExisting map image asset ID or URL; upstream checks asset access. No file upload.
spirit_layer_urlNoOptional existing spirit-layer image asset ID or URL; null omits it.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already flag non-readonly and non-idempotent behavior, and the description reinforces this by stating each accepted call creates another map. It adds meaningful behavioral detail not in annotations: empty tokens/annotations, no broadcast receipt, upstream asset access checks, URL normalization, and specific success/error return shapes. This is exactly the kind of supplementary transparency expected.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is longer than average but every sentence earns its place: role restriction, sibling routing, creation semantics, retry caution, return envelope, and error behavior. It is front-loaded with the core purpose and keeps related details grouped, though the error-handling section is slightly redundant with the trailing return-format note.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with 6 parameters and no ambiguity about its output schema, the description leaves little uncovered: it explains who may use it, how it relates to sibling tools, what side effects occur, how failures manifest, and what the response looks like. There is no missing information an agent would need to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 100% description coverage, so the baseline is 3. The description adds a small amount of parameter-relevant context (e.g., 'existing image assets', upstream checks on image access), but it does not substantially extend the schema's already-detailed parameter explanations. This is appropriate and not a deficiency.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action and resource ('Create a campaign map using existing image assets (DM only)'), and distinguishes the tool from siblings by noting that creation does not switch the current map, unlike map_switch. It also clarifies it is not an uploaded image, leaving no ambiguity about what tool to pick.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit usage context: DM-only, use map_list to inspect and map_switch to activate, and creation is not activation. It also warns against blind retries after uncertain failures, which is valuable operational guidance an agent needs to call the tool correctly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

map_deleteMap DeleteA
DestructiveIdempotent

Delete a campaign map and its stored tokens and map state (DM only). Use map_list to inspect maps first; use map_switch to select another current map before deletion. Upstream rejects deletion of the current map with HTTP 400. Use token_delete to remove only one token instead of the entire map. Deletion is destructive and has no undo tool. Repeating leaves the map absent but may return a not-found error. Returns upstream {message} in data without a broadcast receipt; REST permission and resource errors retain upstream diagnostics. Returns {ok:true,data} on success; tool-body failures return {ok:false,error} with optional diagnostic data. Argument-schema errors are MCP errors.

ParametersJSON Schema
NameRequiredDescriptionDefault
map_idYesMap ID in the configured campaign to delete; must not be the current map.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description goes well beyond the annotations: it discloses that deletion is destructive with no undo, that repeating the call may return a not-found error, that the current map cannot be deleted, and that success returns {ok:true,data} while failures return {ok:false,error}. It also explains the upstream response shape and error handling, which is valuable context not present in the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but well-organized: it front-loads the core action and constraints, then covers alternatives, error behavior, and return format. Every sentence adds information, though the length is slightly high for a single-parameter tool. Still, the density is justified by the destructive nature and error semantics.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive single-parameter tool, the description covers all essential context: prerequisites (map_list, map_switch), the current-map restriction, idempotency behavior, return shapes, and error handling. The output schema exists, so return values need not be detailed further. Nothing an agent needs to call this correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already documents map_id with 100% coverage, so the baseline is 3. The description adds the critical constraint that map_id must not be the current map, which is not in the schema description. This extra semantic guidance justifies a 4.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('delete') and resource ('campaign map'), and explicitly distinguishes itself from token_delete and map_switch. It also names the sibling map_list for inspection, making the tool's purpose and scope unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit when-to-use guidance: inspect with map_list first, use map_switch to select another current map before deletion, and use token_delete for single-token removal. It also warns that upstream rejects deletion of the current map with HTTP 400, which is a clear exclusion condition.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

map_listMap ListA
Read-onlyIdempotent

List maps accessible in the configured campaign to choose a map ID and inspect dimensions. Use map_switch to activate one; listing does not switch maps or place tokens. Read-only for campaign members; repeated calls leave game state unchanged. Returns {ok:true,data} on success; tool-body failures return {ok:false,error} with optional diagnostic data. Argument-schema errors are MCP errors.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and openWorldHint, but the description adds value by explicitly stating that repeated calls leave game state unchanged and that no map switching or token placement occurs. It also discloses the return envelope and failure semantics, providing useful behavioral context beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four concise sentences, each carrying distinct information: purpose, sibling distinction, read-only behavior, and return/error format. Information is front-loaded with the primary purpose first, and there is no redundant filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter, read-only list tool with an output schema, the description fully covers purpose, side effects, error behavior, and return shape. Nothing material is missing for an agent to correctly select and invoke this tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so there is no parameter documentation burden on the description. The description appropriately focuses on behavior and return values instead. The baseline of 4 is appropriate for a no-parameter tool.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'List maps accessible in the configured campaign'. It also names the concrete purpose of choosing a map ID and inspecting dimensions. It clearly distinguishes itself from map_switch, avoiding confusion with the closest sibling tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly directs users to map_switch for activation and clearly states that listing does not switch maps or place tokens. It also clarifies that the tool is read-only for campaign members. This provides strong when-to-use and when-not-to-use guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

map_switchMap SwitchA
Destructive

Set the current campaign map through REST, then notify via WS map.change (DM only). Use map_list to choose an existing map; token_move changes a token, not the active map. REST persistence and WS dispatch are separate: persisted=true does not prove clients received the change. A WS failure returns ok=false with data.persisted=true; do not replay or roll back the saved change. Broadcast receipt remains sent=true, confirmed=false,status="pending"; inspect events_poll for results/errors, not an ACK. Repeating may repeat notifications even when the current map is already correct. Returns {ok:true,data} on success; tool-body failures return {ok:false,error} with optional diagnostic data. Argument-schema errors are MCP errors.

ParametersJSON Schema
NameRequiredDescriptionDefault
map_idYesExisting map ID in the configured campaign, obtained from map_list; becomes the active map for the table.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate destructiveness and non-idempotence, but the description adds substantial behavioral context beyond them: REST persistence is decoupled from WS dispatch, persisted=true does not mean clients received the change, a WS failure returns ok=false with data.persisted=true, and repeat calls may generate repeated notifications. This is exactly the kind of nuance an agent needs to avoid incorrect rollback or retry behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but every sentence carries essential operational information: purpose, sibling differentiation, async behavior, failure semantics, retry guidance, and return shape. It is front-loaded with the core action and avoids filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with asynchronous side effects, destructive behavior, and non-idempotent semantics, the description covers all critical operational concerns: REST/WS separation, failure response shape, broadcast receipt status, retry consequences, and where to inspect results. The presence of an output schema means return value details are not required in the description, and it gives the agent enough context to call the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%: the map_id parameter already includes a clear description saying it must be an existing campaign map obtained from map_list and becomes the active map. The tool description reinforces this by referring to map_list as the source, but it does not materially add parameter semantics beyond what the schema already provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Set the current campaign map through REST, then notify via WS map.change (DM only).' It also distinguishes itself from closely related siblings by explicitly noting that map_list selects an existing map and token_move changes a token, not the active map.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage guidance is explicit and actionable: use map_list to choose an existing map, and use token_move when the intent is to change a token rather than the active map. It further instructs when not to replay or roll back saved changes, and directs the agent to events_poll for async results instead of treating an ACK as proof of delivery.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

saved_roll_createSaved Roll CreateA

Save a private dice-expression macro for the current user and campaign. Use dice_roll to execute an expression; use saved_roll_update to edit an existing macro without creating another. Members manage only their own macros. The server parses expressions and limits each user to 50 per campaign. Creation is serialized only within this process; each accepted call may create another macro. No dice are rolled and no campaign-visible message is sent by this tool. Returns {ok:true,data} on success; tool-body failures return {ok:false,error} with optional diagnostic data. Argument-schema errors are MCP errors.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesMacro display label, trimmed to 1..60 characters.
expressionYesSaved dice expression, trimmed to 1..200 characters; upstream parses it without rolling.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description goes well beyond the annotations by disclosing that no dice are rolled, no campaign-visible message is sent, the server enforces a 50-per-campaign limit, and creation is not globally serialized. These are important side-effect and concurrency traits not captured by readOnlyHint, idempotentHint, or destructiveHint alone.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is longer than minimal, but each sentence contributes useful context such as alternatives, side-effect behavior, limits, and return shape. It is front-loaded with the core purpose, though the concurrency and MCP-error details could be trimmed without losing essential guidance.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation tool with output schema, the description is complete: it states ownership, limits, side effects, return conventions, and error behavior. An agent has enough information to decide when to call it and what to expect.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the schema already documents both parameters with trimming constraints. The description reinforces that the expression is parsed without rolling, but it does not add meaning beyond what the schema provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource: 'Save a private dice-expression macro for the current user and campaign.' It also explicitly distinguishes itself from dice_roll and saved_roll_update, making the tool's purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It clearly tells the agent when to use this tool versus alternatives: use dice_roll to execute, use saved_roll_update to edit, and this tool to create. It also clarifies that members manage only their own macros, providing scoping guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

saved_roll_deleteSaved Roll DeleteA
DestructiveIdempotent

Delete your Saved Roll from the configured campaign. Use saved_roll_list to identify it or saved_roll_update to change it without deletion. Any member may delete their own macro; cross-user/cross-campaign access returns 404. Destructive to the macro only, not roll history. Repeating leaves it absent but may return a not-found error; it does not roll dice. Returns {ok:true,data} on success; tool-body failures return {ok:false,error} with optional diagnostic data. Argument-schema errors are MCP errors.

ParametersJSON Schema
NameRequiredDescriptionDefault
macro_idYesSaved Roll ID owned by the authenticated user in the configured campaign; other users/campaigns are inaccessible.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already signal destructive and idempotent behavior, and the description adds substantial context: deletion is limited to the macro only, roll history is unaffected, repeated invocation may yield a not-found error, and no dice are rolled. No contradiction with the annotations exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and every sentence adds value: action first, then alternatives, access constraints, destructive scope, idempotency behavior, and error/response format. No filler or redundant restatement of the tool name.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter deletion tool with an output schema and rich annotations, the description is fully adequate. It covers prerequisites, access boundaries, side effects, retry behavior, and return shapes, leaving no operational ambiguity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the macro_id parameter is already documented as owned by the authenticated user in the configured campaign. The description reinforces the ownership constraint but adds little beyond the schema, so baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States the specific action ('Delete'), resource ('your Saved Roll'), and scope ('configured campaign'). It is clearly distinguished from the sibling update/list operations by naming the deletion action and contrasting it with saved_roll_update.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes the agent to saved_roll_list for identification and saved_roll_update for alteration without deletion. It also clarifies ownership constraints, cross-user/cross-campaign 404 behavior, and repeated-deletion outcomes, giving clear when-to-use and retry guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

saved_roll_listSaved Roll ListA
Read-onlyIdempotent

List complete Saved Roll macros owned by the current user in this campaign. Use dice_roll with a returned expression to execute it, or saved_roll_update to edit. Read-only for campaign members; no individual get is needed and no dice are rolled. Repeating the list does not consume macros. Returns {ok:true,data} on success; tool-body failures return {ok:false,error} with optional diagnostic data. Argument-schema errors are MCP errors.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide readOnlyHint, openWorldHint, idempotentHint, and destructiveHint=false, and the description adds context that no dice are rolled, macros are not consumed, and no individual get is needed. It also discloses success and error return shapes. The description does not contradict annotations and adds meaningful behavioral detail beyond the structured fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is tightly written, with every sentence contributing: scope, usage pointers, read-only behavior, non-consumption, and return format. It is front-loaded with the core purpose and keeps alternatives and error handling to a short tail. No filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter read-only listing tool with a rich annotation set and output schema, the description is nearly complete. It covers purpose, follow-up actions, side-effect-free behavior, and error envelope. It does not enumerate exact response fields, but the presence of an output schema lessens that need; a short note on pagination or ordering would push it to a 5.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the schema carries no parameter burden. The description adds useful return and usage semantics: it explains what the list contains, what it does not do, and how the response is structured. This compensates adequately for the absence of parameter-level documentation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'List complete Saved Roll macros owned by the current user in this campaign.' It clearly distinguishes from sibling tools like saved_roll_create, saved_roll_update, and saved_roll_delete, and even directs users to dice_roll and saved_roll_update for follow-up actions. This is unambiguous and contextually grounded.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly explains when to use this tool: to list saved rolls, without needing an individual get, and without rolling dice. It also mentions that repeating the list does not consume macros and that it is read-only for campaign members. This provides clear usage context and effective routing relative to dice_roll and saved_roll_update.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

saved_roll_updateSaved Roll UpdateA
Destructive

Change the name or expression of your Saved Roll in this campaign. Use saved_roll_list to find its ID; use dice_roll to execute it. Supply at least one field; null leaves that field unchanged. Upstream validates expressions and enforces per-user/per-campaign ownership. Replacing values does not roll dice; repeated writes may change update metadata, so full-operation idempotency is not guaranteed. Returns {ok:true,data} on success; tool-body failures return {ok:false,error} with optional diagnostic data. Argument-schema errors are MCP errors.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoReplacement display label, trimmed to 1..60 characters; null preserves it. At least one of name/expression is required.
macro_idYesExisting Saved Roll ID owned by the current user in this campaign.
expressionNoReplacement expression, trimmed to 1..200 characters and parsed upstream; null preserves it. At least one field is required.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond annotations, it discloses that replacing values does not roll dice, that repeated writes may change update metadata and thus full idempotency is not guaranteed, and that upstream validates expressions and enforces ownership. It also explains the success/error return envelope, which is valuable context not present in the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but well-organized: action first, then sibling routing, then update semantics, then behavioral caveats, then return format. Every sentence earns its place and no unnecessary filler is present.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a partial-update mutation tool, this is complete: what it updates, how to find the target ID, what happens with nulls and multiple writes, ownership validation, and both success and failure response shapes. The presence of an output schema does not create a gap because the description covers the relevant behavior.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents name, macro_id, and expression meanings plus null-count semantics. The description adds the useful pointer to use saved_roll_list to find macro_id, but otherwise largely restates what the schema already covers.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Change') and names the exact resource and fields ('name or expression of your Saved Roll in this campaign'). It also distinguishes itself from related siblings by pointing to saved_roll_list for ID lookup and dice_roll for execution.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly tells the agent when to use this tool ('Change the name or expression') and names alternatives with their conditions: use saved_roll_list to find the ID and dice_roll to execute. It also clarifies the partial-update contract: supply at least one field, null leaves it unchanged.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

session_listSession ListA
Read-onlyIdempotent

List this campaign's latest 50 sessions in descending sessionNumber order, including active sessions. Use session_manage for lifecycle changes and session_notes_update for recaps. Read-only for members; notes are shared with all members, and repeated reads do not end or resume sessions. Returns {ok:true,data} on success; tool-body failures return {ok:false,error} with optional diagnostic data. Argument-schema errors are MCP errors.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only/idempotent/non-destructive, and the description adds concrete non-obvious behavior: notes are shared with all members and repeated reads do not end or resume sessions. It also discloses the success/error return envelope, going beyond the annotation hints.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Every sentence carries distinct information: scope, sibling routing, safe-read behavior, and failure semantics. There is no filler, and the most important functional scope is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With zero parameters and strong annotations plus an output schema, the description covers all remaining decision-relevant details: result ordering/count, active-session inclusion, shared notes, read-only guarantees, and MCP error behavior. Nothing essential is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the schema needs no help; the description's mention of the campaign scope is context rather than parameter documentation. Baseline 4 applies because there is no parameter burden to compensate for.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb-resource pair and exact scope: 'List this campaign's latest 50 sessions in descending sessionNumber order, including active sessions.' This leaves no ambiguity about what the tool returns and contrasts with sibling session tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly routes lifecycle changes to session_manage and recaps to session_notes_update, telling an agent when not to call this tool. It also clarifies that reads are safe and repeated reads have no lifecycle side effects, which is strong when-to-use guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

session_manageSession ManageA
Destructive

Start, pause, or end a campaign session through REST (DM only). Use session_list to inspect history and session_notes_update to edit or clear a recap without another lifecycle transition. start creates a session; pause/end resolve campaign.activeSession.id and fail if none exists. Lifecycle changes are not guaranteed idempotent: do not repeat start/end to repair notes. notes and save_state apply only to end; other actions reject nondefault values. End notes are campaign-wide, and empty text does not clear an existing recap. save_state requests the upstream end-of-session snapshot; it is not a bridge-side backup. Returns upstream REST data; it does not wait for a WS business ACK. Returns {ok:true,data} on success; tool-body failures return {ok:false,error} with optional diagnostic data. Argument-schema errors are MCP errors.

ParametersJSON Schema
NameRequiredDescriptionDefault
notesNoShared recap for end, at most 2000 characters; null omits it. Empty end text does not clear old notes; use session_notes_update.
actionYesLifecycle transition: start, pause, or end, case-insensitive. Pause/end target the currently active session.
save_stateNoTrue (default) requests saving state on end; false skips that snapshot. Must remain true for start/pause.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already say destructiveHint=true and idempotentHint=false, but the description goes further: it explains non-idempotency in practical terms, discloses that notes and save_state apply only to end, and clarifies that save_state is not a bridge-side backup. It also warns that empty end text does not clear an existing recap and that the tool does not wait for a WS business ACK. These are meaningful behavioral nuances beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but every sentence earns its place: purpose, sibling routing, lifecycle rules, notes/save_state constraints, and return format. It is front-loaded with the core action and ends with structured return behavior, with no fluff or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a non-idempotent, destructive, state-changing tool with conditional parameters, the description covers what is needed: when each action applies, what fails, how notes and save_state behave differently per action, return success/error shapes, and the DM-only restriction. The presence of an output schema means detailed return fields are not required, and the description still summarizes the success/error envelope.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, which establishes a baseline of 3. The description adds extra semantics beyond the schema: notes are 'campaign-wide', nondefault notes/save_state values are rejected for start/pause, and save_state requests an 'upstream' snapshot rather than a local backup. These details enhance understanding of all three parameters, so a score above baseline is warranted.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb-resource pair ('Start, pause, or end a campaign session') and immediately scopes the tool to 'REST (DM only)', which clearly distinguishes it from read-only or notes-related tools. It also explicitly names the two most relevant siblings (session_list and session_notes_update), so an agent can differentiate without inspecting schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly instructs when to use alternatives: 'Use session_list to inspect history and session_notes_update to edit or clear a recap without another lifecycle transition.' It also explains that pause/end fail if no active session exists, and warns against repeating start/end to repair notes because changes are not idempotent. This is concrete, actionable usage guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

session_notes_updateSession Notes UpdateA
Destructive

Replace a session's shared recap without another lifecycle transition (DM only). Use session_list to find the ID; use session_manage to start/pause/end instead. All campaign members can read notes. Empty text after upstream trimming clears the recap, unlike empty notes on session_manage end. Does not end the session or broadcast a recap event. Repeated writes may alter metadata, so full-operation idempotency is not guaranteed. Returns {ok:true,data} on success; tool-body failures return {ok:false,error} with optional diagnostic data. Argument-schema errors are MCP errors.

ParametersJSON Schema
NameRequiredDescriptionDefault
notesYesComplete replacement recap, at most 2000 characters before trimming; empty or whitespace-only text clears it upstream.
session_idYesExisting session ID in the configured campaign, obtained with session_list; need not be the active session.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already signal destructive and non-idempotent behavior, and the description adds meaningful details: repeated writes may alter metadata, empty text clears the recap, the tool does not end the session or broadcast a recap event, and it explains the distinction from session_manage. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Every sentence is informative and earns its place. The description front-loads the core purpose, then gives usage routing, behavioral caveats, and return/error semantics in a compact but complete block.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's destructive and non-idempotent nature, the description is remarkably complete: it covers lifecycle impact, permissions, ID discovery, clearing behavior, idempotency caveat, return shape on success, tool-body failures, and schema-error handling. Nothing essential is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds a useful edge-case nuance by explaining that empty text clears the recap 'unlike empty notes on session_manage end,' and it reinforces the complete-replacement semantics. This goes slightly beyond the schema, but most parameter meaning is already present there.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Replace a session's shared recap.' It also distinguishes itself from the lifecycle tool by saying 'without another lifecycle transition' and later 'Does not end the session or broadcast a recap event.' This clearly differentiates it from session_manage.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit direction: use session_list to find the ID, and use session_manage to start/pause/end instead. It also notes the DM-only restriction and clarifies that all campaign members can read notes, which helps an agent decide whether this tool is appropriate for the situation.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

token_addToken AddA

Create a manually configured token on a campaign map (DM only). Use token_place_creature for a library template's name/image, token_move for an existing token, and character_create when a new sheet is needed. This creates only a token; character_id optionally links an existing sheet. Position uses map units; upstream checks map bounds and layer. Width/height are integer sizes in 1..10. visible and controlled_by govern display/control subject to server permissions. REST returns persisted=true,broadcast_confirmed=false; inspect events_poll or the VTT for visibility, since persistence does not confirm a broadcast. Every accepted call creates another token, so repeated calls are not idempotent. Returns {ok:true,data} on success; tool-body failures return {ok:false,error} with optional diagnostic data. Argument-schema errors are MCP errors.

ParametersJSON Schema
NameRequiredDescriptionDefault
xYesHorizontal position in map units; upstream requires 0 <= x < map width.
yYesVertical position in map units; upstream requires 0 <= y < map height.
nameYesDisplay label for the new token; upstream requires nonempty text.
layerNoRendering layer: token (default) or spirit; upstream validates it and applies visibility rules.token
widthNoHorizontal token size in map units, integer 1..10; defaults to 1.
heightNoVertical token size in map units, integer 1..10; defaults to 1.
map_idYesDestination map ID in this campaign; discover it and its dimensions with map_list.
visibleNoTrue requests a visible token; false requests a hidden token. Layer and role may further restrict visibility.
image_urlYesToken artwork URL passed upstream; empty text is accepted as a placeholder by v1.4.0, with older behavior unverified.
character_idNoExisting sheet ID to link; empty string creates a token without a character link.
controlled_byNoUser ID allowed to control the token, subject to upstream checks; null omits explicit assignment.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate this is a non-readonly, non-idempotent operation, and the description builds on that with valuable nuance: persistence does not confirm broadcast, clients should inspect events_poll or the VTT for visibility, upstream validates bounds/layer, and server permissions can restrict visible/controlled_by. It also clearly flags non-idempotency for repeated calls.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but not bloated. It front-loads the core purpose and sibling routing before parameter behavior and return semantics. Each sentence contributes useful information, though a few points (width/height ranges, visible/controlled_by) restate schema details and could be trimmed without losing value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with 11 parameters, 5 required fields, an output schema, and asynchronous broadcast behavior, the description covers all essential context: DM-only access, tool alternatives, parameter semantics, validation behavior, non-idempotency, broadcast uncertainty, and error return conventions. Nothing needed for correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3; the description adds worthwhile operational context beyond the schema by noting position uses map units subject to upstream bounds/layer checks, width/height are 1..10 integers, and visible/controlled_by are subject to server permissions. It also clarifies that character_id optionally links an existing sheet.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb ('Create'), a precise object ('a manually configured token on a campaign map'), and adds a scope restriction ('DM only'). It explicitly distinguishes this tool from sibling tools token_place_creature, token_move, and character_create, making its purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit routing guidance: use token_place_creature when a library template's name/image is needed, token_move for an existing token, and character_create when a new sheet is needed. It also clarifies what this tool does NOT do ('This creates only a token'), which prevents misuse.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

token_deleteToken DeleteA
DestructiveIdempotent

Delete one token from a campaign map (DM only). Use token_move to reposition a token instead. Use token_hp_update for a signed sheet HP adjustment through WS: that tool takes a character ID, whereas this tool takes a map token ID. Deletion removes the placed token, not its linked character sheet or HP, and does not manage initiative entries. It is destructive and has no undo tool. Repeating leaves the token absent but may return a not-found error. Returns upstream {message} in data without a broadcast receipt; REST permission and resource errors retain upstream diagnostics. Returns {ok:true,data} on success; tool-body failures return {ok:false,error} with optional diagnostic data. Argument-schema errors are MCP errors.

ParametersJSON Schema
NameRequiredDescriptionDefault
map_idYesMap ID containing the token in the configured campaign.
token_idYesMap token ID to remove, not a character sheet ID.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate destructiveHint=true and idempotentHint=true, but the description adds valuable specifics: deletion is irreversible, repeated deletion may return a not-found error, the linked character sheet and HP are unaffected, and REST permission errors preserve upstream diagnostics. This goes well beyond the structured annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but well-organized, with the core purpose and alternatives first, followed by behavioral caveats and return semantics. The return/error breakdown is somewhat verbose but earned given the tool's destructive, no-undo nature and the need to distinguish tool-body failures from MCP errors.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description is complete for a destructive DM-only tool: it covers access restrictions, alternatives, side effects, idempotency behavior, no-undo consequences, and error/return semantics. An agent has enough information to decide when to invoke this tool and what to expect.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents map_id and token_id. The description adds important semantic context by emphasizing that the ID is a map token ID, not a character sheet ID, and by clarifying that deletion removes only the placed token, not the linked sheet or HP. This helps an agent understand the real meaning of the parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Delete one token from a campaign map (DM only).' It also explicitly distinguishes itself from token_move and token_hp_update by naming what each sibling does differently, so an agent can select this tool without ambiguity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit when-to-use and when-not-to-use guidance: use token_move for repositioning, use token_hp_update for HP changes, and states that token_delete takes a map token ID rather than a character ID. It also clarifies DM-only access and explains that initiative entries are not managed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

token_hp_updateToken Hp UpdateA
Destructive

Apply a signed HP delta to a character sheet through WS, not to a token ID. Use character_get to inspect HP or character_update for an absolute sheet patch. Upstream requires character ownership or DM authority and campaign assignment; its system-specific HP rules determine the result. Positive delta heals, negative delta damages. Repeating applies the delta again and is not idempotent. Returns sent:true,confirmed:false,status:"pending" inside data: dispatch is not a business ACK. Read events_poll for results/system.error and inspect state before further action; never blindly resend. Returns {ok:true,data} on success; tool-body failures return {ok:false,error} with optional diagnostic data. Argument-schema errors are MCP errors.

ParametersJSON Schema
NameRequiredDescriptionDefault
deltaYesSigned integer HP adjustment: positive heals, negative damages, zero requests no numerical change. Upstream applies system limits.
character_idYesCampaign-assigned character ID whose sheet HP is changed; do not pass a map token ID.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotation set already declares destructiveHint=true and idempotentHint=false, and the description enriches this by explaining the dispatch is not a business ACK ('sent:true,confirmed:false,status:"pending"'), instructing to poll events_poll for results, and detailing failure modes ({ok:false,error}). It also specifies that positive delta heals and negative damages, consistent with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Every sentence carries distinct information: purpose, alternatives, prerequisites, effect polarity, idempotency warning, async acknowledgment, failure contract. It is dense but not bloated, and key operational warnings are front-loaded after the purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutating async tool, it covers prerequisites, result interpretation, polling, error contracts, and non-idempotency. The presence of an output schema means return-value documentation is not required, but the description still adds the crucial 'pending is not an ACK' nuance, making it complete for an agent to act safely.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Input schema has 100% description coverage for both character_id and delta, including the signed integer semantics and 'do not pass a map token ID.' The description repeats the heal/damage polarity but adds no new parameter-level meaning beyond the schema, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb+resource: 'Apply a signed HP delta to a character sheet through WS, not to a token ID.' This unambiguously differentiates it from token-ID-targeted operations and from character_update's absolute patch, and it aligns with the tool name while correcting any misreading of 'token'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly directs to alternatives: 'Use character_get to inspect HP or character_update for an absolute sheet patch.' It also states prerequisite authority ('character ownership or DM authority and campaign assignment') and warns not to blindly resend because repeat applies the delta again, providing clear when-to/not-to guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

token_moveToken MoveA
Destructive

Set an existing token's absolute position through REST. Use token_add to create a token or map_switch to change the active map. The bridge rejects SPECTATOR/unknown roles; upstream requires DM or the controlling player. The same coordinates produce the same position, but repeated writes may produce notifications. Returns persisted=true,broadcast_confirmed=false; REST does not itself emit map.changed. Inspect events_poll or the VTT before assuming others saw the move; this result is not a correlated broadcast ACK. Returns {ok:true,data} on success; tool-body failures return {ok:false,error} with optional diagnostic data. Argument-schema errors are MCP errors.

ParametersJSON Schema
NameRequiredDescriptionDefault
xYesAbsolute horizontal position in map units; upstream requires 0 <= x < map width.
yYesAbsolute vertical position in map units; upstream requires 0 <= y < map height.
map_idYesMap ID containing the existing token, not necessarily the active map.
token_idYesExisting token ID on that map; this is not a character or creature ID.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description goes well beyond the annotations (destructiveHint=true, idempotentHint=false) by disclosing role-rejection behavior, repeated-write notification side effects, persisted=true/broadcast_confirmed=false semantics, the fact that REST does not emit map.changed, and the recommendation to inspect events_poll before assuming others saw the move. It also documents the success/error envelope. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the purpose, then flows logically through alternatives, role constraints, behavioral semantics, and error format. It is dense but nearly every sentence earns its place; only the broadcast caveat is stated twice ('REST does not itself emit map.changed' and 'this result is not a correlated broadcast ACK'), a minor redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive, non-idempotent mutation with four required parameters, the description covers everything needed for correct invocation: role/auth prerequisites, determinism of coordinates, notification side effects, verification guidance via events_poll, and the full success/failure return envelope. The existing output schema relieves the description of return-value duty, but the description exceeds even that bar.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. All four parameters (x, y, map_id, token_id) already have rich schema descriptions including coordinate ranges and the map/token scoping. The tool description reinforces 'absolute position' but adds little parameter-level meaning beyond what the schema already provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence, 'Set an existing token's absolute position through REST,' names a specific verb, resource, and scope in one clear statement. It also differentiates itself from token_add (creation) and map_switch (changing active map), so an agent can distinguish it from the most confusable siblings without opening their schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly routes to alternatives: 'Use token_add to create a token or map_switch to change the active map.' It also states when the tool cannot be used, noting the bridge rejects SPECTATOR/unknown roles and upstream requires DM or the controlling player. These are concrete, actionable conditions for invocation.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

token_place_creatureToken Place CreatureA

Create a visible 1x1 token from a library template's name and image (DM only). Use creature_search to obtain a template ID; use token_add for custom size, layer, controller, visibility, or a character link. This reads the template and copies only name/image into a token: it does not create a sheet or copy creature stats. Fails before creation if no usable image exists. Position must be within the map. Each accepted call creates another token. Returns upstream REST data without a broadcast receipt; use events_poll or the VTT to inspect subsequent visibility. Returns {ok:true,data} on success; tool-body failures return {ok:false,error} with optional diagnostic data. Argument-schema errors are MCP errors.

ParametersJSON Schema
NameRequiredDescriptionDefault
xYesHorizontal position in map units; upstream requires 0 <= x < map width.
yYesVertical position in map units; upstream requires 0 <= y < map height.
map_idYesDestination map ID in this campaign; discover dimensions through map_list.
creature_idYesLibrary template ID from creature_search; the template must have a usable imageUrl, tokenImageUrl, or image.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already flag mutation and non-idempotency, but the description goes beyond them by disclosing that only name/image are copied, no sheet or creature stats are created, and each accepted call creates another token. It also reveals the response lacks a broadcast receipt and directs to events_poll or the VTT for visibility inspection, providing useful operational context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense and front-loaded with the primary purpose, then flows naturally into usage guidance, behavioral limitations, failure modes, and response format. Every sentence contributes a distinct piece of information, with no redundancy or filler, and the structure makes the tool's edge cases clear.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the DM-only restriction, sibling tool routing, non-idempotent behavior, failure conditions, response format, and how to verify side effects via events_poll or the VTT. Combined with a complete input schema and an output schema, it leaves no critical gap for an agent to call and interpret the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already describes all four parameters in full (100% coverage), so the description doesn't need to add much. It reinforces constraints like position within the map and usable image requirements, but offers no new parameter-level meaning beyond what the schema already states. The baseline of 3 applies because the schema carries the semantic load.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action and resource: 'Create a visible 1x1 token from a library template's name and image (DM only).' It also distinguishes itself from closely related siblings by explicitly routing creature_search for template lookup and token_add for custom size/layer/controller/visibility/character links, so an agent can clearly tell when this tool applies.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly names the alternative tools and the conditions that select between them: creature_search for obtaining a template ID and token_add for custom token attributes. It also adds DM-only availability and defines failure conditions (no usable image, out-of-map position), giving agents a clear decision procedure.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 4 tool updatesv0.4.0
    • Addedcharacter_delete
    • Addedmap_create
    • Addedmap_delete
    • Addedtoken_delete
  2. 38 tool updatesv0.3.0
    • Addedcampaign_document_list
    • Addedcampaign_get
    • Removedcampaign_status
    • Addedcampaign_transfer_dm
    • Changedcharacter_create3 fields changed
      • addedInput schema / properties / data / description
        Added value: +"Optional initial sheet-field object for the campaign system, not a nested request patch; null omits it and lets upstream choose defaults."
      • addedInput schema / properties / name / description
        Added value: +"New sheet display name, 1..200 characters; passed without trimming."
      • addedInput schema / properties / token_image_url / description
        Added value: +"Optional artwork URL for the sheet; empty string omits it. This does not create a map token."
    • Changedcharacter_get1 field changed
      • addedInput schema / properties / character_id / description
        Added value: +"Existing character ID, normally discovered with character_list; the sheet may use its own gameSystem."
    • Addedcharacter_hitdice_spend
    • Changedcharacter_update2 fields changed
      • addedInput schema / properties / character_id / description
        Added value: +"Existing sheet ID to modify; upstream enforces owner or campaign DM access."
      • addedInput schema / properties / data / description
        Added value: +"Nonempty request patch containing only name, data, tokenImageUrl. Sheet changes go inside data as an object; arrays replace, null is explicit."
    • Changedcharacter_validate1 field changed
      • addedInput schema / properties / character_id / description
        Added value: +"Existing character ID owned by the authenticated user; fixed-system validation is required upstream."
    • Changedchat_read3 fields changed
      • addedInput schema / properties / cursor
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Opaque pagination.nextCursor from the previous response; null starts with the latest page. Do not construct cursors or offsets."
        +}
      • addedInput schema / properties / limit / description
        Added value: +"Page size, 1..100 messages; defaults to 20."
      • removedInput schema / properties / offset
        Removed value: -{
        -  "default": 0,
        -  "type": "integer"
        -}
    • Changedchat_send2 fields changed
      • addedInput schema / properties / content / description
        Added value: +"Nonblank message text, at most 2000 characters; whitespace is preserved when sent."
      • addedInput schema / properties / type / description
        Added value: +"Message category: DM (default narration) or PLAYER. This does not change the authenticated role."
    • Changedcreature_search5 fields changed
      • addedInput schema / properties / cr / description
        Added value: +"Challenge-rating filter passed as text, for example 1/2 or 3; empty omits it. Applicability is upstream-defined."
      • addedInput schema / properties / limit / description
        Added value: +"Requested page size, normally 1..100; defaults to 20. Values above 100 are capped; other validation is upstream."
      • addedInput schema / properties / offset / description
        Added value: +"Number of search results to skip, normally >=0; defaults to 0. Forwarded without local range validation."
      • addedInput schema / properties / search / description
        Added value: +"Name/search filter passed upstream; empty string omits the filter."
      • addedInput schema / properties / source / description
        Added value: +"srd or custom (case-insensitive); empty chooses both for DND_5E and custom for other or flexible campaigns."
    • Changeddice_roll4 fields changed
      • addedInput schema / properties / character_name
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Optional display attribution (wire characterName), not a character ID or permission credential; null omits it."
        +}
      • addedInput schema / properties / expression / description
        Added value: +"Server-parsed dice expression, e.g. 1d20+5, 2d6, or 4d6kh3; invalid syntax is reported asynchronously."
      • addedInput schema / properties / is_secret / description
        Added value: +"False publishes to the campaign; true requests secret delivery to the roller and DMs (wire field secret)."
      • addedInput schema / properties / purpose / description
        Added value: +"Optional broadcast label explaining the roll; empty string omits it, without changing dice calculation."
    • Addeddocument_create
    • Addeddocument_delete
    • Addeddocument_list
    • Addeddocument_read
    • Addeddocument_share
    • Addeddocument_unshare
    • Addeddocument_update
    • Addeddocument_upload
    • Changedevents_poll2 fields changed
      • addedInput schema / properties / limit / description
        Added value: +"Maximum events per page, 1..500; defaults to 100. Continue with next_seq when has_more is true."
      • addedInput schema / properties / since / description
        Added value: +"Last next_seq received, integer >=0; 0 starts at the oldest retained event. A cursor beyond this process resets to 0."
    • Changedinitiative_manage7 fields changed
      • addedInput schema / properties / action / description
        Added value: +"One of add, remove, roll, set, reorder, start, next, end; case-insensitive. Determines required companion parameters."
      • addedInput schema / properties / character_name / description
        Added value: +"Optional display label passed only for roll; empty omits it and does not affect permissions."
      • addedInput schema / properties / expression / description
        Added value: +"Optional roll fallback for a DM when system derivation has no value; empty uses the server default. Ignored outside roll."
      • addedInput schema / properties / map_id / description
        Added value: +"Map containing the token; required for add/roll/set, otherwise unused (empty default)."
      • addedInput schema / properties / ordered_token_ids / description
        Added value: +"Nonempty ordered list of combatant token IDs for reorder; overrides value ordering. Null is appropriate for other actions."
      • addedInput schema / properties / token_id / description
        Added value: +"Token to add/remove/roll/set; required for those actions. Empty default is appropriate for reorder/start/next/end."
      • addedInput schema / properties / value / description
        Added value: +"Manual initiative number required for set; null means unspecified. Other actions ignore it."
    • Addedinitiative_read
    • Removedinitiative_state
    • Changedmap_switch1 field changed
      • addedInput schema / properties / map_id / description
        Added value: +"Existing map ID in the configured campaign, obtained from map_list; becomes the active map for the table."
    • Addedsaved_roll_create
    • Addedsaved_roll_delete
    • Addedsaved_roll_list
    • Addedsaved_roll_update
    • Addedsession_list
    • Changedsession_manage3 fields changed
      • addedInput schema / properties / action / description
        Added value: +"Lifecycle transition: start, pause, or end, case-insensitive. Pause/end target the currently active session."
      • addedInput schema / properties / notes
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Shared recap for end, at most 2000 characters; null omits it. Empty end text does not clear old notes; use session_notes_update."
        +}
      • addedInput schema / properties / save_state
        Added value: +{
        +  "default": true,
        +  "description": "True (default) requests saving state on end; false skips that snapshot. Must remain true for start/pause.",
        +  "type": "boolean"
        +}
    • Addedsession_notes_update
    • Changedtoken_add13 fields changed
      • addedInput schema / properties / character_id / description
        Added value: +"Existing sheet ID to link; empty string creates a token without a character link."
      • addedInput schema / properties / controlled_by
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "User ID allowed to control the token, subject to upstream checks; null omits explicit assignment."
        +}
      • addedInput schema / properties / height / description
        Added value: +"Vertical token size in map units, integer 1..10; defaults to 1."
      • changedInput schema / properties / height / type
        Previous value: -"number"New value: +"integer"
      • addedInput schema / properties / image_url / description
        Added value: +"Token artwork URL passed upstream; empty text is accepted as a placeholder by v1.4.0, with older behavior unverified."
      • addedInput schema / properties / layer / description
        Added value: +"Rendering layer: token (default) or spirit; upstream validates it and applies visibility rules."
      • addedInput schema / properties / map_id / description
        Added value: +"Destination map ID in this campaign; discover it and its dimensions with map_list."
      • addedInput schema / properties / name / description
        Added value: +"Display label for the new token; upstream requires nonempty text."
      • addedInput schema / properties / visible / description
        Added value: +"True requests a visible token; false requests a hidden token. Layer and role may further restrict visibility."
      • addedInput schema / properties / width / description
        Added value: +"Horizontal token size in map units, integer 1..10; defaults to 1."
      • changedInput schema / properties / width / type
        Previous value: -"number"New value: +"integer"
      • addedInput schema / properties / x / description
        Added value: +"Horizontal position in map units; upstream requires 0 <= x < map width."
      • addedInput schema / properties / y / description
        Added value: +"Vertical position in map units; upstream requires 0 <= y < map height."
    • Removedtoken_hp
    • Addedtoken_hp_update
    • Changedtoken_move4 fields changed
      • addedInput schema / properties / map_id / description
        Added value: +"Map ID containing the existing token, not necessarily the active map."
      • addedInput schema / properties / token_id / description
        Added value: +"Existing token ID on that map; this is not a character or creature ID."
      • addedInput schema / properties / x / description
        Added value: +"Absolute horizontal position in map units; upstream requires 0 <= x < map width."
      • addedInput schema / properties / y / description
        Added value: +"Absolute vertical position in map units; upstream requires 0 <= y < map height."
    • Changedtoken_place_creature4 fields changed
      • addedInput schema / properties / creature_id / description
        Added value: +"Library template ID from creature_search; the template must have a usable imageUrl, tokenImageUrl, or image."
      • addedInput schema / properties / map_id / description
        Added value: +"Destination map ID in this campaign; discover dimensions through map_list."
      • addedInput schema / properties / x / description
        Added value: +"Horizontal position in map units; upstream requires 0 <= x < map width."
      • addedInput schema / properties / y / description
        Added value: +"Vertical position in map units; upstream requires 0 <= y < map height."
  3. 1 tool updatev0.1.1
    • Changeddice_roll1 field changed
      • addedInput schema / properties / purpose
        Added value: +{
        +  "default": "",
        +  "type": "string"
        +}
  4. 20 tool updatesv0.1.0
    • First observedcampaign_status
    • First observedcharacter_create
    • First observedcharacter_get
    • First observedcharacter_list
    • First observedcharacter_update
    • First observedcharacter_validate
    • First observedchat_read
    • First observedchat_send
    • First observedcreature_search
    • First observeddice_roll
    • First observedevents_poll
    • First observedinitiative_manage
    • First observedinitiative_state
    • First observedmap_list
    • First observedmap_switch
    • First observedsession_manage
    • First observedtoken_add
    • First observedtoken_hp
    • First observedtoken_move
    • First observedtoken_place_creature

TDQS

A4.1/5.0

Scored across 41 tools

Disambiguation3/5

The tools are mostly distinct in their core purposes, but some confusion arises between document_list and campaign_document_list, document_share vs document_unshare, and token_hp_update vs character_update for HP. Also, saved_roll_list and saved_roll_create are clearly different, but the direct relationship between them and dice_roll is described.

Naming Consistency4/5

Most tools follow a clear verb_noun pattern (e.g., character_get, character_create, document_update, session_manage). However, there are a few deviations like 'campaign_document_list' which is a resource-specific variant, and 'token_place_creature' which is descriptive but less consistent with the simple verb_noun pattern.

Tool Count1/5

The server has 41 tools, which is far beyond the typical well-scoped range. While each tool has a specific purpose, the sheer number suggests an overly granular surface that could overwhelm an agent's decision-making. The count is appropriate for a complex VTT but still excessive for coherence.

Completeness4/5

The server covers CRUD for characters, maps, tokens, documents, sessions, saved rolls, and initiative, as well as cron-like operations (chat, dice, events). Some notable gaps include lack of a token_get/token_list to inspect individual tokens, and no direct way to view all saved rolls other than list, but the core lifecycle is covered.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    A
    maintenance
    Connects Claude Desktop to Foundry VTT for AI-powered campaign management, enabling natural language interaction with game data including quest creation, character management, compendium searches, and dice rolling. Provides 20 MCP tools for seamless integration between Claude and your tabletop RPG sessions.
    72
    -
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables AI assistants to act as RPG Game Masters by managing campaign state including characters, inventory, quests, and logs through MCP tools. Supports campaign mutations and provides both MCP and HTTP API access to RPG session data.
    2
    -
  • F
    license
    Not graded
    quality
    Not graded
    maintenance
    Integrates with FoundryVTT tabletop gaming sessions, allowing AI assistants to query game data, roll dice, generate content (NPCs, loot, encounters), manage combat, and provide tactical suggestions through natural language.
    9 npm
    -