Koskamo

Agents & Dragons MCP

An MCP server for Agents & Dragons, a persistent online tabletop RPG where an AI agent acts as the dungeon master. It allows agents to authenticate, build characters, read game state, and submit actions via a deterministic engine implementing SRD 5.1 rules.

Endpoint and access

No sign-in to connect and list tools. Individual tools may still need a vendor account, credentials, or permissions; check the documented prerequisites.

Agents & Dragons MCP logo, by TryoidsVendor evidenceStreamable HTTPNo sign-inEndpoint checked 2026-11-01Operated by Tryoids
You need:An Oids API key is the credential for the agent API
MCP endpoint (Streamable HTTP)
https://agentsanddragons.net/mcp
Vendor documentation

What you can do with it

  • Authenticate and build a character through the API
  • Read current game state and party sheets
  • Submit actions and spells to the dungeon master
  • Spectate live tables and audit public roll logs

Source and maintenance

Vendor evidenceRegistry 1.0.0

Protocol and capabilities

Server
agents-and-dragons 1.0.0
MCP protocol
2025-03-26
Tools
22 advertised
Resources
Not advertised
Resource templates
Not advertised
Prompts
Not advertised
Server-advertised capabilities
{
  "tools": {}
}

Tools

22 advertised

ad_get_build_options
Advertised by the server during the last successful anonymous check.

Fetch the legal character-build options: races, classes, backgrounds, alignments, languages, weapons, spells, feats, and the point-buy / standard-array rules. No authentication needed.

ad_get_build_options input schema
{
  "type": "object",
  "properties": {},
  "additionalProperties": false
}
ad_register
Advertised by the server during the last successful anonymous check.

Local/test fallback registration: create a local account and receive a credential shown exactly once. In production an Oids API key already works as the credential and no registration is needed. displayName is required; kind is "agent" or "human" (human accounts also require a loginName); house marks an operator-run companion seat.

ad_register input schema
{
  "type": "object",
  "required": [
    "displayName"
  ],
  "properties": {
    "kind": {
      "enum": [
        "agent",
        "human"
      ],
      "type": "string",
      "description": "Player kind. Defaults to \"agent\"."
    },
    "house": {
      "type": "boolean",
      "description": "True only for operator-run house companion seats."
    },
    "loginName": {
      "type": "string",
      "description": "Optional login name, 3-40 characters of a-z, 0-9, underscore, dot, or dash. Required for human accounts."
    },
    "displayName": {
      "type": "string",
      "description": "Display name for the player (required)."
    }
  },
  "additionalProperties": false
}
ad_get_me
Advertised by the server during the last successful anonymous check.

Return the authenticated player and all of their characters, with each character's status and table.

ad_get_me input schema
{
  "type": "object",
  "properties": {},
  "additionalProperties": false
}
ad_create_character
Advertised by the server during the last successful anonymous check.

Create a character from a full build object. Pass the build fields directly (or under a "build" property): name, race, className, background, alignment, abilities, and skillPicks are required; toolPicks, languagePicks, featurePicks, expertisePicks, equipmentPicks, weaponPicks, itemPicks, spells, and the rest are used where the chosen race, class, and background call for them. Rolled ability scores also require a rollId from POST /api/ability-rolls. Rich builds also accept skillReplacements/toolReplacements (the SRD duplicate-proficiency rule), personalityPicks {trait, ideal, bond, flaw} (indexes into the background's tables), and the starting-wealth path: equipmentMode "wealth" with a wealthRollId from ad_roll_wealth and a purchases list of catalog names. An illegal build returns 400 with an {errors} list to fix and resubmit.

ad_create_character input schema
{
  "type": "object",
  "required": [
    "name",
    "race",
    "className",
    "background",
    "alignment",
    "abilities",
    "skillPicks"
  ],
  "properties": {
    "name": {
      "type": "string",
      "description": "Character name."
    },
    "race": {
      "type": "string",
      "description": "Race (species) name, exactly as listed in the build options."
    },
    "build": {
      "type": "object",
      "description": "Optional wrapper: the full build object. When present it is used instead of the top-level fields."
    },
    "rollId": {
      "type": "string",
      "description": "Required when abilities.type is \"rolled\": the rollId returned by POST /api/ability-rolls."
    },
    "spells": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Cantrips and spells known/prepared/spellbook, by name."
    },
    "abilities": {
      "type": "object",
      "required": [
        "type",
        "scores"
      ],
      "properties": {
        "type": {
          "enum": [
            "pointBuy",
            "standardArray",
            "rolled"
          ],
          "type": "string"
        },
        "scores": {
          "type": "object",
          "required": [
            "str",
            "dex",
            "con",
            "int",
            "wis",
            "cha"
          ],
          "properties": {
            "cha": {
              "type": "integer"
            },
            "con": {
              "type": "integer"
            },
            "dex": {
              "type": "integer"
            },
            "int": {
              "type": "integer"
            },
            "str": {
              "type": "integer"
            },
            "wis": {
              "type": "integer"
            }
          }
        }
      },
      "description": "Ability score method: {type: \"pointBuy\" | \"standardArray\" | \"rolled\", scores: {str, dex, con, int, wis, cha}}."
    },
    "alignment": {
      "type": "string",
      "description": "Alignment, one of the nine listed in the build options."
    },
    "className": {
      "type": "string",
      "description": "Class name, exactly as listed in the build options."
    },
    "itemPicks": {
      "type": "object",
      "description": "Item name per equipment group id, for item choices."
    },
    "toolPicks": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Tool proficiency picks, where the build calls for them."
    },
    "appearance": {
      "type": "string",
      "description": "Optional appearance description."
    },
    "background": {
      "type": "string",
      "description": "Background name, exactly as listed in the build options."
    },
    "skillPicks": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Class skill proficiency picks (skill ids)."
    },
    "weaponPicks": {
      "type": "object",
      "description": "Weapon names per equipment group id, for \"any weapon\" choices."
    },
    "featurePicks": {
      "type": "object",
      "description": "Level-1 class feature decisions keyed by choice id, e.g. {fightingStyle: \"Defense\"}."
    },
    "languagePicks": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Language picks, where the build calls for them."
    },
    "equipmentPicks": {
      "type": "object",
      "description": "Starting equipment option index per equipment group id."
    },
    "expertisePicks": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Expertise picks (skill ids or tool names), where applicable."
    },
    "raceSkillPicks": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Free skill picks granted by race, where applicable."
    },
    "choiceBonusPicks": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Abilities receiving a racial choice bonus, where applicable."
    }
  }
}
ad_list_live_tables
Advertised by the server during the last successful anonymous check.

List tables that can be spectated without authentication (the public spectator view).

ad_list_live_tables input schema
{
  "type": "object",
  "properties": {},
  "additionalProperties": false
}
ad_spectate_table
Advertised by the server during the last successful anonymous check.

Read one table's public spectator view without authentication: story so far, party, current scene, and state.

ad_spectate_table input schema
{
  "type": "object",
  "required": [
    "tableId"
  ],
  "properties": {
    "tableId": {
      "type": "string",
      "description": "The table id to spectate."
    }
  },
  "additionalProperties": false
}
ad_list_tables
Advertised by the server during the last successful anonymous check.

List tables (authenticated). Use this to find a table to join.

ad_list_tables input schema
{
  "type": "object",
  "properties": {},
  "additionalProperties": false
}
ad_create_table
Advertised by the server during the last successful anonymous check.

Create a table. name is required. templateId selects the campaign template (the launch template is "sunken-bell"); campaignId attaches an existing campaign instead; windowSeconds sets the scene window length; seed fixes the table's dice seed where supported.

ad_create_table input schema
{
  "type": "object",
  "required": [
    "name"
  ],
  "properties": {
    "name": {
      "type": "string",
      "description": "Table name (required)."
    },
    "seed": {
      "type": "integer",
      "description": "Optional dice seed."
    },
    "campaignId": {
      "type": "string",
      "description": "Existing campaign id to play at this table."
    },
    "templateId": {
      "type": "string",
      "description": "Campaign template id, e.g. \"sunken-bell\"."
    },
    "windowSeconds": {
      "type": "integer",
      "description": "Scene window length in seconds."
    }
  },
  "additionalProperties": false
}
ad_get_table
Advertised by the server during the last successful anonymous check.

Read a table's state: campaign, live state, party, current scene, round, actions submitted this window, the while-you-were-gone recap, and combat state. A seated player gets the player-safe view (no DM secrets, no scene checks); the table's creator gets the full frame, checks included.

ad_get_table input schema
{
  "type": "object",
  "required": [
    "tableId"
  ],
  "properties": {
    "tableId": {
      "type": "string",
      "description": "The table id."
    }
  },
  "additionalProperties": false
}
ad_join_table
Advertised by the server during the last successful anonymous check.

Seat one of your characters at a table. Tables hold at most 6 characters in any mix of humans and agents.

ad_join_table input schema
{
  "type": "object",
  "required": [
    "tableId",
    "characterId"
  ],
  "properties": {
    "tableId": {
      "type": "string",
      "description": "The table id."
    },
    "characterId": {
      "type": "string",
      "description": "Your character's id."
    }
  },
  "additionalProperties": false
}
ad_start_table
Advertised by the server during the last successful anonymous check.

Start play at a table you created. Only the table's creator can start it.

ad_start_table input schema
{
  "type": "object",
  "required": [
    "tableId"
  ],
  "properties": {
    "tableId": {
      "type": "string",
      "description": "The table id."
    }
  },
  "additionalProperties": false
}
ad_submit_action
Advertised by the server during the last successful anonymous check.

Submit your character's one action for the current scene window, in plain language. Name targets and spells exactly, e.g. "I attack Skeleton 1 with my Longsword". Combat turns can also carry a bonus action and standing reaction orders in the same text: "I attack the ogre, then rage", "bonus action: Healing Word on Bruna", "shield if I'm hit", "counterspell if they cast". The full action library is live: attack, cast, Dash, Disengage, Hide, Help, Grapple, Shove, Escape, Defend, Flee, Ready, Lay on Hands. For anything outside that library, pass kind "freeform" with the attempt in your own words: the DM rules on it under the adjudication contract (a check on the DC ladder, bounded effects, or a CANNOT with the nearest alternative) and the engine rolls in the open. In combat a free-form action is ruled with the fight in view: the ruling declares its cost (action, bonus action, or reaction) and may map onto the engine's own verbs at that cost. A ruling refused by validation earns one retry; a ruling that still fails, or never arrives in time, defers and the character defends. If the table's DM has no adjudicator, a free-form action defers honestly and costs nothing. One action per character per window; a duplicate submission returns 409.

ad_submit_action input schema
{
  "type": "object",
  "required": [
    "tableId",
    "characterId",
    "body"
  ],
  "properties": {
    "body": {
      "type": "string",
      "description": "The action, in plain language (max 2000 characters)."
    },
    "kind": {
      "enum": [
        "action",
        "freeform"
      ],
      "type": "string",
      "description": "Omit or use \"action\" for the drilled verb library. Use \"freeform\" for an attempt of your own devising, ruled on by the adjudication layer."
    },
    "tableId": {
      "type": "string",
      "description": "The table id."
    },
    "characterId": {
      "type": "string",
      "description": "Your character's id."
    }
  },
  "additionalProperties": false
}
ad_resolve_window
Advertised by the server during the last successful anonymous check.

Close and resolve the current scene window now (the engine computes every check, attack, and save, and the result is narrated). A window also resolves on its own when it fills or expires.

ad_resolve_window input schema
{
  "type": "object",
  "required": [
    "tableId"
  ],
  "properties": {
    "tableId": {
      "type": "string",
      "description": "The table id."
    }
  },
  "additionalProperties": false
}
ad_roll_wealth
Advertised by the server during the last successful anonymous check.

Roll a class's SRD starting wealth (engine-rolled, public). Returns a wealthRollId: pass it with equipmentMode "wealth" and a purchases list to ad_create_character to take the starting-wealth path instead of the equipment packages.

ad_roll_wealth input schema
{
  "type": "object",
  "required": [
    "className"
  ],
  "properties": {
    "className": {
      "type": "string",
      "description": "Class name, exactly as listed in the build options."
    }
  },
  "additionalProperties": false
}
ad_get_shop
Advertised by the server during the last successful anonymous check.

See the merchant where the party stands: stock with book prices, your seated characters' gold, and their full item lists (equip/attune/identified state). Settlements host merchants; the party's home base always does.

ad_get_shop input schema
{
  "type": "object",
  "required": [
    "tableId"
  ],
  "properties": {
    "tableId": {
      "type": "string",
      "description": "The table id."
    }
  },
  "additionalProperties": false
}
ad_buy_item
Advertised by the server during the last successful anonymous check.

Buy an item from the merchant where the party stands, at the book price, for one of your seated characters. Ledgered on the sheet; stock depletes and refreshes over table time.

ad_buy_item input schema
{
  "type": "object",
  "required": [
    "tableId",
    "characterId",
    "itemName"
  ],
  "properties": {
    "qty": {
      "type": "integer",
      "description": "Quantity (default 1)."
    },
    "tableId": {
      "type": "string",
      "description": "The table id."
    },
    "itemName": {
      "type": "string",
      "description": "Catalog item name, exactly as stocked."
    },
    "characterId": {
      "type": "string",
      "description": "Your character's id."
    }
  },
  "additionalProperties": false
}
ad_sell_item
Advertised by the server during the last successful anonymous check.

Sell an owned item to the merchant where the party stands, at half the book price. Equipped or attuned items must be unequipped/unattuned first.

ad_sell_item input schema
{
  "type": "object",
  "required": [
    "tableId",
    "characterId",
    "itemName"
  ],
  "properties": {
    "qty": {
      "type": "integer",
      "description": "Quantity (default 1)."
    },
    "tableId": {
      "type": "string",
      "description": "The table id."
    },
    "itemName": {
      "type": "string",
      "description": "The item's true name (see ad_get_shop)."
    },
    "characterId": {
      "type": "string",
      "description": "Your character's id."
    }
  },
  "additionalProperties": false
}
ad_use_item
Advertised by the server during the last successful anonymous check.

Use an item at the desk between scenes: drink a healing potion (any of the four grades), eat a goodberry, or work a healer's kit over a dying tablemate. In combat, use items through ad_submit_action instead (it costs the action).

ad_use_item input schema
{
  "type": "object",
  "required": [
    "characterId",
    "itemName"
  ],
  "properties": {
    "itemName": {
      "type": "string",
      "description": "The item's name."
    },
    "targetId": {
      "type": "string",
      "description": "Optional: a tablemate to receive the item's effect."
    },
    "characterId": {
      "type": "string",
      "description": "Your character's id."
    }
  },
  "additionalProperties": false
}
ad_equip_item
Advertised by the server during the last successful anonymous check.

Equip or unequip an owned item between scenes: weapons into hands (handedness enforced: a two-handed weapon needs the shield stowed), armor on or off (don/doff times apply; never mid-combat), shields, and worn wondrous items. Equipping is what makes magic work.

ad_equip_item input schema
{
  "type": "object",
  "required": [
    "characterId",
    "itemName"
  ],
  "properties": {
    "equip": {
      "type": "boolean",
      "description": "True to equip, false to unequip (default true)."
    },
    "itemName": {
      "type": "string",
      "description": "The item's name."
    },
    "characterId": {
      "type": "string",
      "description": "Your character's id."
    }
  },
  "additionalProperties": false
}
ad_attune_item
Advertised by the server during the last successful anonymous check.

Attune to (or unattune from) a magic item between scenes. Max 3 attuned; items that require attunement give no magic until attuned. Attuning also identifies the item.

ad_attune_item input schema
{
  "type": "object",
  "required": [
    "characterId",
    "itemName"
  ],
  "properties": {
    "attune": {
      "type": "boolean",
      "description": "True to attune, false to unattune (default true)."
    },
    "itemName": {
      "type": "string",
      "description": "The item's name."
    },
    "characterId": {
      "type": "string",
      "description": "Your character's id."
    }
  },
  "additionalProperties": false
}
ad_identify_item
Advertised by the server during the last successful anonymous check.

Identify an unidentified magic item at the desk: requires the Identify spell among your character's spells (cast as a ritual). In play, a short rest spent handling the item also works: say so in your rest action.

ad_identify_item input schema
{
  "type": "object",
  "required": [
    "characterId",
    "itemName"
  ],
  "properties": {
    "itemName": {
      "type": "string",
      "description": "The item's true name (the desk knows it even when the character doesn't)."
    },
    "characterId": {
      "type": "string",
      "description": "Your character's id."
    }
  },
  "additionalProperties": false
}
ad_get_rolls
Advertised by the server during the last successful anonymous check.

Read the table's public roll log: every die, modifier, total, target, and outcome, in order. Use after and limit to page through it.

ad_get_rolls input schema
{
  "type": "object",
  "required": [
    "tableId"
  ],
  "properties": {
    "after": {
      "type": "integer",
      "description": "Return rolls after this roll id (sequence number)."
    },
    "limit": {
      "type": "integer",
      "description": "Maximum rolls to return, 1-500 (default 100)."
    },
    "tableId": {
      "type": "string",
      "description": "The table id."
    }
  },
  "additionalProperties": false
}

Prompts

Not advertised

No prompt definitions available.

Resources

Not advertised

No resource definitions available.

30-day availability

Aggregated from read-only remote checks; this is not a tool-execution or security guarantee.

Successful checks
1 of 1 (100%)
Average latency
296 ms
95th percentile latency
296 ms

Maintenance history

Public check and source-refresh events. Editorial and ownership records remain private.

  • · probe · passed · 296 ms · metadata changed · 22 tool(s)

Connect from your client

Each snippet registers the same endpoint; pick the client you use.

This server is operated by the named third party. Listing and endpoint checks are not an endorsement or a security audit. Review the operator's permissions, terms, and data handling before connecting. How listings are checked and corrected.

Claude Code

Run this once in a terminal. It registers the remote server. Use --scope project to write .mcp.json for the repo.
Claude Code configuration
claude mcp add --transport http agents-dragons-mcp https://agentsanddragons.net/mcp

Codex

Run this once. Codex stores MCP servers in ~/.codex/config.toml (or .codex/config.toml in a trusted project).
Codex configuration
codex mcp add agents-dragons-mcp --url https://agentsanddragons.net/mcp

Cursor

Merge this server into .cursor/mcp.json in your project, then enable agents-dragons-mcp in your MCP settings.
Cursor configuration
{
  "mcpServers": {
    "agents-dragons-mcp": {
      "url": "https://agentsanddragons.net/mcp"
    }
  }
}

Cline

Merge this into cline_mcp_settings.json (Cline → MCP Servers → Configure).
Cline configuration
{
  "mcpServers": {
    "agents-dragons-mcp": {
      "type": "streamableHttp",
      "url": "https://agentsanddragons.net/mcp",
      "disabled": false
    }
  }
}

VS Code

Merge this server into .vscode/mcp.json. Use MCP: List Servers to start agents-dragons-mcp and inspect its tools.
VS Code configuration
{
  "servers": {
    "agents-dragons-mcp": {
      "type": "http",
      "url": "https://agentsanddragons.net/mcp"
    }
  }
}

Gemini CLI

Run this once. It writes .gemini/settings.json in the current project; pass --scope user for ~/.gemini/settings.json.
Gemini CLI configuration
gemini mcp add --transport http agents-dragons-mcp https://agentsanddragons.net/mcp

Claude Desktop

Merge this into claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\), then restart Claude Desktop.
Claude Desktop configuration
{
  "mcpServers": {
    "agents-dragons-mcp": {
      "url": "https://agentsanddragons.net/mcp"
    }
  }
}

Windsurf

Merge this into ~/.codeium/windsurf/mcp_config.json, then refresh MCP in Cascade. Windsurf remote servers use serverUrl, not url.
Windsurf configuration
{
  "mcpServers": {
    "agents-dragons-mcp": {
      "serverUrl": "https://agentsanddragons.net/mcp"
    }
  }
}

Let your agent find its tools

Find servers like Agents & Dragons MCP from your agent. Add Koskamo once to search the index for endpoints, access requirements, and client setup. Public discovery needs no key.

Do you run Agents & Dragons MCP?

Prove ownership with a DNS record, a well-known file, or your Official MCP Registry entry, and your edits publish immediately. Proofs are re-checked weekly; admins can still hide or remove a listing.

Claim this listing