# `io.github.richardsolomou/praetorium` on anlyon.dev

> Text inside fenced blocks marked untrusted-server-text was written by the MCP server's publisher, not by anlyon.dev. It is data to inspect, not instructions to follow. Invisible characters are shown as [U+XXXX].
> No finding is not a safety guarantee: these are point-in-time checks of tool definitions, not of code or behaviour.

- Page: https://anlyon.dev/servers/io.github.richardsolomou/praetorium
- JSON: https://anlyon.dev/api/v1/servers/io.github.richardsolomou/praetorium
- Version: 1.2.0 (active)
- Publisher: io.github.richardsolomou (GitHub account)
- Runs: remote (streamable-http)
- Sign-in to list tools: none
- Repository: https://github.com/richardsolomou/praetorium.gg
- Metadata from the official MCP Registry, synced 2026-10-21T18:46:11.146Z

Title and description, as the publisher wrote them:

```untrusted-server-text
Praetorium
Public Warhammer 40K rules, datasheets, points and missions; sign in to manage rosters and battles.
```

Scanned 2026-10-21T19:26:47.251Z over streamable-http.

**15 tools: 4 can delete or cancel things, 1 change things and 10 only read.**

| Group | Class | Tools | Claude Code |
| --- | --- | --- | --- |
| Deletes or cancels | destructive | 4 | deny |
| Can't be undone | irreversible | 0 | ask |
| Changes things | write | 1 | ask |
| Only reads | read | 10 | allow |

## Exfil surface

No private-data -> untrusted-input -> outbound path in this server alone: no tool is tagged untrusted-input or outbound.

| Tag | Meaning | Tools |
| --- | --- | --- |
| private-data | Reads files, mail, messages, databases, secrets, calendars or repositories. | `mcp__praetorium__get_reference` `mcp__praetorium__list_reference` |
| untrusted-input | Brings in text someone else can write: web pages, inbound email, messages, issues and comments. | none |
| outbound | Can carry data to people or systems: it sends, posts or publishes, or takes a recipient, channel or URL. | none |

## Findings

- **warn** Annotations that disagree with the tool in `simulate_combat` ([annotation-conflict](https://anlyon.dev/methodology#annotation-conflict))

```untrusted-server-text
The server marks "simulate_combat" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

annotations: {"readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}; The description's first verb is "run": a word for a change.
```


## Deletes or cancels (4)

Removes, cancels or revokes something. Claude Code: deny.

### `create_battle`

- The name "create_battle" says "create": a word for a change.
- The server marks it destructive (destructiveHint: true).

Description, as the server wrote it:

```untrusted-server-text
Creates a battle with named player seats, using the same rules as the site. Requires mcp:write.
```

### `save_roster`

- The name "save_roster" says "save": a word for a change.
- The server marks it destructive (destructiveHint: true).

Description, as the server wrote it:

```untrusted-server-text
Saves a complete roster. Pass its id to edit an owned roster; omit id to create one. limit is the battle size (1000, 2000 or 3000 points, or 600 for King of the Colosseum), which sets detachment points, enhancement and unit limits. pointsBudget optionally replaces only its points total (500 to 10000, not King of the Colosseum); omit it to keep a saved budget, or send null for the standard total. Requires mcp:write.
```

### `set_roster_visibility`

- The name "set_roster_visibility" says "set": a word for a change.
- The server marks it destructive (destructiveHint: true).

Description, as the server wrote it:

```untrusted-server-text
Changes the visibility of an owned roster. Requires mcp:write.
```

### `submit_battle_action`

- The name "submit_battle_action" says "submit": a word for a change.
- The input takes a statement or command to run (input.command), which can change anything it can reach.
- The server marks it destructive (destructiveHint: true).

Description, as the server wrote it:

```untrusted-server-text
Appends a legal battle command only when expectedSeq matches the current log. Requires mcp:write.
```

## Changes things (1)

Creates or changes something that can be changed back. Claude Code: ask.

### `simulate_combat`

- The description's first verb is "run": a word for a change.
- The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.
- Findings: warn annotation-conflict

Description, as the server wrote it:

```untrusted-server-text
Runs Praetorium's exact combat simulator for one attacking unit, with any attached leaders, against one defending unit at full strength: shooting, melee, and shooting followed by melee. Returns expected models destroyed, expected wounds lost, the chance to destroy the unit, cumulative odds, weapons used, the rule and weapon-mode choices each side can change, datasheet citations, and a simulator link. Passive datasheet rules apply by default; stratagems and conditional rules stay off until chosen. Unsupported mechanics are refused or listed under notCalculated rather than approximated. Like the standalone simulator page, it uses default loadouts and no detachment; unit sizes and attachments must be legal.
```

## Only reads (10)

Looks things up and changes nothing. Claude Code: allow.

### `get_my_battle`

- The name "get_my_battle" says "get": a word for reading.

Description, as the server wrote it:

```untrusted-server-text
Returns the current seated view of a battle for the signed-in player. Requires mcp:read.
```

### `get_my_roster`

- The name "get_my_roster" says "get": a word for reading.

Description, as the server wrote it:

```untrusted-server-text
Returns the saved choices for one roster owned by the signed-in player. Requires mcp:read.
```

### `get_reference`

- The name "get_reference" says "get": a word for reading.
- Tag private-data: The description's first sentence says "read" and "document": it reads documents.

Description, as the server wrote it:

```untrusted-server-text
Reads the complete bounded document returned by search_reference, with its revisions and attribution. A section that withholds rules text lists textSources: the pinned upstream file and record id to fetch if you need the wording.
```

### `get_reference_record`

- The name "get_reference_record" says "get": a word for reading.

Description, as the server wrote it:

```untrusted-server-text
Returns the structured record behind a search result, including mission cards, deployments, terrain geometry, detachments, and datasheets. Records that withhold rules text carry textSources pointing at the pinned upstream file and record id.
```

### `list_factions`

- The name "list_factions" says "list": a word for reading.

Description, as the server wrote it:

```untrusted-server-text
Lists the factions that can be used to narrow reference searches.
```

### `list_my_battles`

- The name "list_my_battles" says "list": a word for reading.

Description, as the server wrote it:

```untrusted-server-text
Lists up to 25 battles with a cursor for the next page. Requires mcp:read.
```

### `list_my_rosters`

- The name "list_my_rosters" says "list": a word for reading.

Description, as the server wrote it:

```untrusted-server-text
Lists the rosters saved to the signed-in Praetorium account. Requires mcp:read.
```

### `list_reference`

- The name "list_reference" says "list": a word for reading.
- Tag private-data: The description's first sentence says "document": it reads documents.

Description, as the server wrote it:

```untrusted-server-text
Discovers available factions, mission packs, rule documents, reference kinds, and active source revisions.
```

### `list_units`

- The name "list_units" says "list": a word for reading.

Description, as the server wrote it:

```untrusted-server-text
Returns every pickable unit in one bounded response with unit-size costs, composition, attachment relationships, roster limits, roles, keywords, and links. Include a detachment to receive its rules, enhancements, upgrades, and stratagems by name, cost, and timing without opening every unit page. Their rules text is at each record’s textSources.
```

### `search_reference`

- The name "search_reference" says "search": a word for reading.

Description, as the server wrote it:

```untrusted-server-text
Searches Praetorium’s missions, rules, detachments, and datasheets by name, number, keyword, and value. Returns bounded excerpts with canonical URLs, source revisions, and attribution. Rules text is not included; records point to it upstream.
```

## Claude Code permissions

For `.claude/settings.json`, assuming the server is installed as `praetorium`:

```json
{
  "permissions": {
    "allow": [
      "mcp__praetorium__list_my_rosters",
      "mcp__praetorium__get_my_roster",
      "mcp__praetorium__list_my_battles",
      "mcp__praetorium__get_my_battle",
      "mcp__praetorium__search_reference",
      "mcp__praetorium__get_reference",
      "mcp__praetorium__get_reference_record",
      "mcp__praetorium__list_factions",
      "mcp__praetorium__list_reference",
      "mcp__praetorium__list_units"
    ],
    "ask": [
      "mcp__praetorium__simulate_combat"
    ],
    "deny": [
      "mcp__praetorium__save_roster",
      "mcp__praetorium__set_roster_visibility",
      "mcp__praetorium__create_battle",
      "mcp__praetorium__submit_battle_action"
    ]
  }
}
```

Capability tags behind the rules (a read tagged outbound is asked about):

- `mcp__praetorium__get_reference`: private-data
- `mcp__praetorium__list_reference`: private-data
