mnehmos.open5e.mcp
# mnehmos.open5e.mcp
> MCP server for [Open5e](https://open5e.com) - Query D&D 5e game data and contribute to the open-source database
[](./tests)
[](./LICENSE)
[](https://nodejs.org)
A dual-mode MCP server that provides:
- **Consumer Mode**: Query spells, monsters, items, conditions, and more from 22+ source books
- **Contributor Mode**: Validate entries, check for collisions, diff against live API, and generate PR-ready JSON
- **RAG Developer Chatbot**: Search and chat with Open5e repository documentation
## Features
| Category | Tools | What It Does |
|----------|-------|--------------|
| **Consumer** | 6 tools | Search, get, list, batch fetch D&D 5e content |
| **Contributor** | 5 tools | Validate schemas, check slugs, diff entries, generate PRs |
| **RAG** | 5 tools | Search repo docs, chat with AI about contributing |
| **Meta** | 3 tools | Health checks, list documents/endpoints |
## Installation
### npm
```bash
npm install -g mnehmos.open5e.mcp
```
### From Source
```bash
git clone https://github.com/Mnehmos/mnehmos.open5e.mcp.git
cd mnehmos.open5e.mcp
npm install
npm run build
```
### Claude Desktop Configuration
Add to your `claude_desktop_config.json`:
```json
{
"mcpServers": {
"mnehmos.open5e.mcp": {
"command": "node",
"args": ["path/to/mnehmos.open5e.mcp/dist/index.js"]
}
}
}
```
Or if installed globally:
```json
{
"mcpServers": {
"mnehmos.open5e.mcp": {
"command": "mnehmos-open5e-mcp"
}
}
}
```
## Quick Start
### Search for Spells
```
Search: "fireball"
→ Returns Fireball, Delayed Blast Fireball from multiple sources
```
### Get a Monster
```
Get: monsters/goblin
→ Full stat block with AC, HP, abilities, actions, environments
```
### Validate a Contribution
```
Validate: { name: "Custom Spell", level: 3, school: "Evocation", ... }
→ Errors for missing required fields
→ Suggestions for slug format
→ Warnings for unusual values
```
## Tool Reference
### Consumer Tools
#### `search`
Search across all Open5e resources with optional filters.
```typescript
search({
query: "fireball",
resource_type: "spells", // optional: spells, monsters, items, etc.
document_slug: "srd-2014", // optional: filter by source book
limit: 10 // optional: max results (default 20)
})
```
Returns results with `slug`, `key` (for v2 resources), `name`, `excerpt`, and `web_url`.
#### `get`
Fetch a single resource by slug. Auto-tries common document prefixes for v2 resources.
```typescript
// Simple slug - auto-discovers the full key
get({ resource_type: "spells", slug: "fireball" })
// → Finds srd-2024_fireball or srd-2014_fireball
// Full key - direct lookup
get({ resource_type: "spells", slug: "srd-2014_fireball" })
```
#### `list`
List resources with filters (pagination supported).
```typescript
list({
resource_type: "monsters",
cr: 3, // Challenge Rating
document_slug: "wotc-srd", // Source book
type: "Dragon", // Creature type
limit: 20,
offset: 0
})
list({
resource_type: "spells",
level: 3, // Spell level (0-9)
school: "Evocation", // Spell school
document_slug: "srd-2014"
})
```
#### `batch_get`
Fetch multiple resources in parallel (max 50).
```typescript
batch_get({
requests: [
{ resource_type: "monsters", slug: "goblin" },
{ resource_type: "monsters", slug: "kobold" },
{ resource_type: "conditions", slug: "blinded" }
]
})
```
#### `list_documents`
List all available source books.
```typescript
list_documents()
// → srd-2014, srd-2024, tob, tob2, tob3, a5e-ag, bfrd, etc.
```
#### `list_endpoints`
List all API endpoints with version info.
```typescript
list_endpoints()
// → spells (v2), monsters (v1), conditions (v2), etc.
```
### Contributor Tools
#### `validate_entry`
Validate a draft entry against Open5e schema.
```typescript
validate_entry({
resource_type: "spells",
data: {
name: "Test Spell",
slug: "test-spell",
level: 3,
school: "Evocation",
// ... other fields
},
strict: false // optional: fail on warnings
})
```
Returns:
- `valid`: boolean
- `errors`: Array of schema violations
- `warnings`: Unusual but valid values
- `suggestions`: Helpful hints (slug format, valid enums)
#### `check_slug`
Check if a slug exists or would collide.
```typescript
check_slug({
resource_type: "monsters",
slug: "goblin",
document_slug: "wotc-srd", // optional
original_slug: "goblin-old" // optional: detect mutations
})
```
Returns:
- `exists`: boolean
- `is_mutation`: boolean (slug changed from original)
- `collision_risk`: "none" | "same_document" | "different_document"
- `existing_entry`: Details if exists
#### `diff`
Compare a draft entry against the live API version.
```typescript
diff({
resource_type: "monsters",
slug: "goblin",
draft: {
name: "Goblin",
hit_points: 10, // Changed from 7
// ... partial or full entry
},
ignore_fields: ["page_no"] // optional
})
```
Returns field-by-field diff with `type`: "added" | "removed" | "modified".
#### `normalize`
Clean up and standardize entry data.
```typescript
normalize({
resource_type: "spells",
data: {
name: "test spell",
desc: "A spell with bad spacing.\n\nAnd extra newlines."
},
options: {
fix_whitespace: true,
fix_markdown: true,
standardize_names: true,
generate_slug: true
}
})
```
#### `generate_pr_json`
Generate PR-ready JSON with file path and checklist.
```typescript
generate_pr_json({
resource_type: "spells",
document_slug: "srd-2014",
operation: "add", // or "modify"
data: { /* validated entry */ }
})
```
Returns:
- `json_output`: Formatted JSON string
- `file_path`: Where to place the file (e.g., `data/srd-2014/spells/test-spell.json`)
- `validation`: Pre-flight validation results
- `checklist`: PR submission checklist
### RAG Tools
The RAG tools connect to the Open5e Developer Chatbot, which indexes the entire open5e-api and open5e (frontend) repositories.
#### `rag_health`
Check RAG service status.
```typescript
rag_health()
// → { healthy: true, chunks: 484, vectors: 484, sources: 214 }
```
#### `rag_stats`
Get index statistics.
```typescript
rag_stats()
// → Project info, chunk/vector counts, embedding status
```
#### `rag_sources`
List all indexed sources with GitHub URLs.
```typescript
rag_sources()
// → README.md, CONTRIBUTING.md, AGENTS.md, models/*.py, views/*.py, etc.
```
#### `rag_search`
Search repository documentation.
```typescript
rag_search({
query: "how to add a new monster",
mode: "hybrid", // semantic, keyword, or hybrid
top_k: 5
})
```
Returns chunks with scores, source URLs, and positions.
#### `rag_chat`
Chat with AI about Open5e development.
```typescript
rag_chat({
message: "How do I add a new monster to the Open5e database?",
history: [], // optional: conversation history
top_k: 5 // optional: context chunks
})
```
Returns detailed answer with source citations.
### Meta Tools
#### `health_check`
Check API connectivity and cache status.
```typescript
health_check()
// → { api_reachable: true, api_latency_ms: 628, cache_status: {...}, version: "0.1.0" }
```
## Available Source Books
| Slug | Name | Publisher |
|------|------|-----------|
| `srd-2014` | System Reference Document 5.1 | Wizards of the Coast |
| `srd-2024` | System Reference Document 5.2 | Wizards of the Coast |
| `tob` | Tome of Beasts | Kobold Press |
| `tob-2023` | Tome of Beasts (2023) | Kobold Press |
| `tob2` | Tome of Beasts 2 | Kobold Press |
| `tob3` | Tome of Beasts 3 | Kobold Press |
| `a5e-ag` | Adventurer's Guide (A5E) | EN Publishing |
| `a5e-mm` | Monstrous Menagerie (A5E) | EN Publishing |
| `bfrd` | Black Flag Reference Document | Kobold Press |
| `deepm` | Deep Magic | Kobold Press |
| ... | *22 total sources* | |
Use `list_documents()` for the complete list.
## Resource Types
| Type | API Version | Filters Available |
|------|-------------|-------------------|
| `spells` | v2 | level, school, document_slug |
| `monsters` | v1 | cr, type, document_slug |
| `conditions` | v2 | document_slug |
| `items` | v1 | document_slug |
| `magicitems` | v1 | document_slug |
| `weapons` | v2 | document_slug |
| `armor` | v2 | document_slug |
| `feats` | v2 | document_slug |
| `backgrounds` | v2 | document_slug |
| `races` | v2 | document_slug |
| `classes` | v1 | document_slug |
## Usage Patterns
### Game Master: Building an Encounter
```typescript
// Find CR 3 monsters from the SRD
const monsters = await list({
resource_type: "monsters",
cr: 3,
document_slug: "wotc-srd"
});
// Get full details for selected monsters
const details = await batch_get({
requests: monsters.results.slice(0, 5).map(m => ({
resource_type: "monsters",
slug: m.slug
}))
});
```
### Contributor: Adding a New Spell
```typescript
// 1. Draft the spell
const draft = {
name: "Arcane Bolt",
slug: "arcane-bolt",
level: 0,
school: "Evocation",
casting_time: "1 action",
range: "120 feet",
verbal: true,
somatic: true,
material: false,
concentration: false,
ritual: false,
duration: "Instantaneous",
desc: "You hurl a bolt of arcane energy at a creature...",
document__slug: "homebrew"
};
// 2. Validate
const validation = await validate_entry({
resource_type: "spells",
data: draft
});
// 3. Check for collisions
const slugCheck = await check_slug({
resource_type: "spells",
slug: "arcane-bolt"
});
// 4. Generate PR JSON
const prData = await generate_pr_json({
resource_type: "spells",
document_slug: "homebrew",
operation: "add",
data: draft
});
```
### Learning: Understanding the Codebase
```typescript
// Search for how monsters are modeled
const results = await rag_search({
query: "Monster model fields actions abilities",
top_k: 5
});
// Ask the chatbot
const answer = await rag_chat({
message: "What fields are required for a monster entry in v1?"
});
```
## Integration
### rpg-mcp
This server is designed to integrate with [rpg-mcp](https://github.com/Mnehmos/rpg-mcp) for live creature lookups during gameplay:
```typescript
// Replace hardcoded creature presets with Open5e lookups
const creature = await open5e.get({
resource_type: "monsters",
slug: "adult-red-dragon"
});
```
### Quest Keeper AI
Surface contributor workflows in the Quest Keeper AI frontend for community content creation.
## Development
### Setup
```bash
npm install
npm run build
```
### Testing
```bash
npm test # Run all tests
npm run test:watch # Watch mode
npm run test:coverage # Coverage report
```
### Scripts
| Command | Description |
|---------|-------------|
| `npm run build` | Compile TypeScript |
| `npm run dev` | Watch mode compilation |
| `npm start` | Run the server |
| `npm test` | Run tests |
| `npm run lint` | Lint source files |
| `npm run typecheck` | Type check without emit |
### Project Structure
```
src/
├── index.ts # MCP server entry point, tool registration
├── types.ts # Shared TypeScript types
├── api/ # Open5e API client
├── cache/ # Response caching
├── contributor/ # Validation, diff, PR generation
├── schema/ # Zod schemas for all resource types
└── utils/ # Helpers, slug handling
```
## API Reference
- **Open5e API**: https://api.open5e.com
- **API Documentation**: https://open5e.com/api-docs
- **GitHub Repository**: https://github.com/open5e/open5e-api
- **Discord**: https://discord.gg/9RNE2rY
## Contributing
1. Fork the repository
2. Create a feature branch
3. Run tests: `npm test`
4. Submit a pull request
## License
MIT © [Mnehmos](https://github.com/Mnehmos)
---
**Part of the Mnehmos MCP ecosystem**
- [mnehmos.ooda.mcp](https://github.com/Mnehmos/mnehmos.ooda.mcp) - File system and shell operations
- [mnehmos.synch.mcp](https://github.com/Mnehmos/mnehmos.synch.mcp) - Agent memory and handoffs
- [rpg-mcp](https://github.com/Mnehmos/rpg-mcp) - RPG game engine
TDQS
Scored across 18 tools
The generic retrieval tools get, list, and search have some conceptual overlap, but descriptions clarify slug-based lookup vs. type listing vs. cross-resource search. The rag_* group, contribution workflow tools, and metadata tools are clearly distinct from the core API tools.
The set mixes bare verbs (get, search, list, diff, normalize), verb_noun tools (health_check, list_documents, validate_entry, generate_pr_json), and a rag_ prefixed subgroup. The rag_* cluster is consistent, but the overall surface does not follow a single predictable convention.
At 18 tools, the server is slightly above the ideal range, but the tools are divided into three coherent clusters: core Open5e API access, contribution preparation, and RAG chatbot access. No cluster appears bloated for its purpose.
The surface covers read/search/list/batch access, document and endpoint discovery, contribution validation and normalization, PR JSON generation, and comprehensive RAG operations. Minor gaps include no direct document-content fetch and no actual PR submission tool, though generate_pr_json prepares the output.