familiar-vtt 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/publish.yml +23 -0
- package/.mcp.json +11 -0
- package/ARCHITECTURE.md +320 -0
- package/BUSINESS.md +547 -0
- package/CLAUDE.md +118 -0
- package/COMMUNITY_RESEARCH.md +225 -0
- package/LICENSE +21 -0
- package/TOOLS_REFERENCE.md +224 -0
- package/dist/module/main.js +1016 -0
- package/dist/module/main.js.map +7 -0
- package/dist/server/server/config.d.ts +22 -0
- package/dist/server/server/config.js +33 -0
- package/dist/server/server/config.js.map +1 -0
- package/dist/server/server/connector.d.ts +26 -0
- package/dist/server/server/connector.js +179 -0
- package/dist/server/server/connector.js.map +1 -0
- package/dist/server/server/http-transport.d.ts +10 -0
- package/dist/server/server/http-transport.js +43 -0
- package/dist/server/server/http-transport.js.map +1 -0
- package/dist/server/server/index.d.ts +2 -0
- package/dist/server/server/index.js +59 -0
- package/dist/server/server/index.js.map +1 -0
- package/dist/server/server/logger.d.ts +6 -0
- package/dist/server/server/logger.js +14 -0
- package/dist/server/server/logger.js.map +1 -0
- package/dist/server/server/tools/bundles.d.ts +56 -0
- package/dist/server/server/tools/bundles.js +187 -0
- package/dist/server/server/tools/bundles.js.map +1 -0
- package/dist/server/server/tools/canvas-environment.d.ts +3 -0
- package/dist/server/server/tools/canvas-environment.js +151 -0
- package/dist/server/server/tools/canvas-environment.js.map +1 -0
- package/dist/server/server/tools/canvas.d.ts +3 -0
- package/dist/server/server/tools/canvas.js +134 -0
- package/dist/server/server/tools/canvas.js.map +1 -0
- package/dist/server/server/tools/cards.d.ts +3 -0
- package/dist/server/server/tools/cards.js +35 -0
- package/dist/server/server/tools/cards.js.map +1 -0
- package/dist/server/server/tools/characters.d.ts +3 -0
- package/dist/server/server/tools/characters.js +115 -0
- package/dist/server/server/tools/characters.js.map +1 -0
- package/dist/server/server/tools/chat.d.ts +3 -0
- package/dist/server/server/tools/chat.js +23 -0
- package/dist/server/server/tools/chat.js.map +1 -0
- package/dist/server/server/tools/combat.d.ts +3 -0
- package/dist/server/server/tools/combat.js +38 -0
- package/dist/server/server/tools/combat.js.map +1 -0
- package/dist/server/server/tools/compendium.d.ts +3 -0
- package/dist/server/server/tools/compendium.js +33 -0
- package/dist/server/server/tools/compendium.js.map +1 -0
- package/dist/server/server/tools/dice.d.ts +3 -0
- package/dist/server/server/tools/dice.js +12 -0
- package/dist/server/server/tools/dice.js.map +1 -0
- package/dist/server/server/tools/effects.d.ts +3 -0
- package/dist/server/server/tools/effects.js +54 -0
- package/dist/server/server/tools/effects.js.map +1 -0
- package/dist/server/server/tools/ember-events.d.ts +3 -0
- package/dist/server/server/tools/ember-events.js +34 -0
- package/dist/server/server/tools/ember-events.js.map +1 -0
- package/dist/server/server/tools/folders.d.ts +3 -0
- package/dist/server/server/tools/folders.js +30 -0
- package/dist/server/server/tools/folders.js.map +1 -0
- package/dist/server/server/tools/helpers.d.ts +10 -0
- package/dist/server/server/tools/helpers.js +13 -0
- package/dist/server/server/tools/helpers.js.map +1 -0
- package/dist/server/server/tools/items.d.ts +3 -0
- package/dist/server/server/tools/items.js +23 -0
- package/dist/server/server/tools/items.js.map +1 -0
- package/dist/server/server/tools/journals.d.ts +3 -0
- package/dist/server/server/tools/journals.js +71 -0
- package/dist/server/server/tools/journals.js.map +1 -0
- package/dist/server/server/tools/macros.d.ts +3 -0
- package/dist/server/server/tools/macros.js +32 -0
- package/dist/server/server/tools/macros.js.map +1 -0
- package/dist/server/server/tools/playlists.d.ts +3 -0
- package/dist/server/server/tools/playlists.js +39 -0
- package/dist/server/server/tools/playlists.js.map +1 -0
- package/dist/server/server/tools/regions.d.ts +3 -0
- package/dist/server/server/tools/regions.js +65 -0
- package/dist/server/server/tools/regions.js.map +1 -0
- package/dist/server/server/tools/registry.d.ts +11 -0
- package/dist/server/server/tools/registry.js +73 -0
- package/dist/server/server/tools/registry.js.map +1 -0
- package/dist/server/server/tools/scenes.d.ts +3 -0
- package/dist/server/server/tools/scenes.js +142 -0
- package/dist/server/server/tools/scenes.js.map +1 -0
- package/dist/server/server/tools/tables.d.ts +3 -0
- package/dist/server/server/tools/tables.js +22 -0
- package/dist/server/server/tools/tables.js.map +1 -0
- package/dist/server/server/tools/world.d.ts +3 -0
- package/dist/server/server/tools/world.js +26 -0
- package/dist/server/server/tools/world.js.map +1 -0
- package/dist/server/shared/constants.d.ts +16 -0
- package/dist/server/shared/constants.js +17 -0
- package/dist/server/shared/constants.js.map +1 -0
- package/dist/server/shared/html.d.ts +4 -0
- package/dist/server/shared/html.js +9 -0
- package/dist/server/shared/html.js.map +1 -0
- package/dist/server/shared/protocol.d.ts +184 -0
- package/dist/server/shared/protocol.js +58 -0
- package/dist/server/shared/protocol.js.map +1 -0
- package/dist/server/shared/types.d.ts +21 -0
- package/dist/server/shared/types.js +2 -0
- package/dist/server/shared/types.js.map +1 -0
- package/module.json +21 -0
- package/package.json +81 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
name: Publish to npm
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch: # Manual trigger from GitHub UI
|
|
5
|
+
|
|
6
|
+
jobs:
|
|
7
|
+
publish:
|
|
8
|
+
runs-on: ubuntu-latest
|
|
9
|
+
steps:
|
|
10
|
+
- uses: actions/checkout@v4
|
|
11
|
+
|
|
12
|
+
- uses: actions/setup-node@v4
|
|
13
|
+
with:
|
|
14
|
+
node-version: 20
|
|
15
|
+
registry-url: https://registry.npmjs.org
|
|
16
|
+
|
|
17
|
+
- run: npm ci
|
|
18
|
+
|
|
19
|
+
- run: npm run build
|
|
20
|
+
|
|
21
|
+
- run: npm publish --access public
|
|
22
|
+
env:
|
|
23
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
package/.mcp.json
ADDED
package/ARCHITECTURE.md
ADDED
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
# Familiar Architecture
|
|
2
|
+
|
|
3
|
+
Technical architecture documentation for the Familiar project.
|
|
4
|
+
|
|
5
|
+
## Design Principles
|
|
6
|
+
|
|
7
|
+
- **Single process** — one Node.js process, stdio transport for MCP, WebSocket to Foundry. No wrapper/backend split.
|
|
8
|
+
- **System-agnostic core** — most tools work with any Foundry game system. Character formatting is D&D 5e for now, pluggable later.
|
|
9
|
+
- **Integrate, don't rebuild** — use existing modules (Sequencer, Token Magic FX, etc.) via their APIs instead of reimplementing visual features.
|
|
10
|
+
- **Full AI control** — every action a human DM can do in Foundry, the AI should be able to do via tools.
|
|
11
|
+
- **Build → test → iterate** — implement one tool, test it live, fix issues, move on.
|
|
12
|
+
- **Type-safe routing** — discriminated unions and exhaustive switches, not string-based dispatch.
|
|
13
|
+
- **Modular tools** — each tool domain in its own file with a clean registration pattern.
|
|
14
|
+
- **Minimal dependencies** — `@modelcontextprotocol/sdk`, `ws`, `zod`, `pino`. That's it.
|
|
15
|
+
|
|
16
|
+
## Architecture Overview
|
|
17
|
+
|
|
18
|
+
### Current Architecture (MCP)
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
Claude (or any MCP client)
|
|
22
|
+
↓ stdio (MCP protocol)
|
|
23
|
+
MCP Server (single Node.js process)
|
|
24
|
+
↓ WebSocket (localhost)
|
|
25
|
+
Foundry VTT Module (browser-side bridge)
|
|
26
|
+
↓ Foundry API
|
|
27
|
+
Game World (actors, scenes, items, journals)
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Future Architecture (Built-in, Plug & Play)
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
Foundry Module (browser)
|
|
34
|
+
├── Built-in LLM client (calls AI provider API directly)
|
|
35
|
+
├── Tool execution (same 124 tools, runs in browser)
|
|
36
|
+
├── Chat UI in Foundry sidebar
|
|
37
|
+
└── Foundry API
|
|
38
|
+
Game World
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The future architecture eliminates the MCP server entirely. The Foundry module talks directly to the AI provider API. No Node.js, no separate process, no MCP config. Everything lives inside the Foundry module.
|
|
42
|
+
|
|
43
|
+
**Both architectures will be supported** — MCP for power users who want Claude Code/Cursor integration, built-in for everyone else.
|
|
44
|
+
|
|
45
|
+
## Two Components
|
|
46
|
+
|
|
47
|
+
### 1. MCP Server (`src/server/`)
|
|
48
|
+
|
|
49
|
+
Node.js process that:
|
|
50
|
+
- Exposes MCP tools via stdio transport
|
|
51
|
+
- Runs a WebSocket server (port 3005) waiting for the Foundry module to connect
|
|
52
|
+
- Translates MCP tool calls → WebSocket queries → Foundry responses → MCP results
|
|
53
|
+
|
|
54
|
+
### 2. Foundry Module (`src/module/`)
|
|
55
|
+
|
|
56
|
+
Browser-side Foundry VTT module that:
|
|
57
|
+
- Connects to the MCP server's WebSocket on world load
|
|
58
|
+
- Receives queries and executes them against the Foundry API (`game.actors`, `game.scenes`, etc.)
|
|
59
|
+
- Returns structured results back over WebSocket
|
|
60
|
+
- GM-only access (non-GM users are silently ignored)
|
|
61
|
+
|
|
62
|
+
## Shared Code (`src/shared/`)
|
|
63
|
+
|
|
64
|
+
- `protocol.ts` — Zod-validated WebSocket message schemas (query, response, ping/pong)
|
|
65
|
+
- `types.ts` — Shared TypeScript interfaces
|
|
66
|
+
- `constants.ts` — Module ID, ports, timeouts
|
|
67
|
+
|
|
68
|
+
## Project Structure
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
familiar/
|
|
72
|
+
├── src/
|
|
73
|
+
│ ├── server/ # MCP server (Node.js)
|
|
74
|
+
│ │ ├── index.ts # Entry point: stdio transport + WebSocket server
|
|
75
|
+
│ │ ├── config.ts # Zod-validated env config
|
|
76
|
+
│ │ ├── connector.ts # WebSocket server ↔ Foundry module
|
|
77
|
+
│ │ ├── logger.ts # Pino logger (stderr)
|
|
78
|
+
│ │ └── tools/ # MCP tool implementations
|
|
79
|
+
│ │ ├── registry.ts # Tool registration & routing
|
|
80
|
+
│ │ ├── characters.ts # Character read/write tools (14 tools)
|
|
81
|
+
│ │ ├── combat.ts # Initiative, conditions, HP tracking (8 tools)
|
|
82
|
+
│ │ ├── scenes.ts # Scene, token, weather, screen tools (17 tools)
|
|
83
|
+
│ │ ├── canvas.ts # Templates, tiles, drawings (12 tools)
|
|
84
|
+
│ │ ├── canvas-environment.ts # Walls, lights, sounds, notes, doors (18 tools)
|
|
85
|
+
│ │ ├── compendium.ts # Compendium search & lookup (4 tools)
|
|
86
|
+
│ │ ├── dice.ts # Dice rolling (1 tool)
|
|
87
|
+
│ │ ├── journals.ts # Journal & quest tools (9 tools)
|
|
88
|
+
│ │ ├── chat.ts # Chat messages (2 tools)
|
|
89
|
+
│ │ ├── playlists.ts # Music & playlist control (6 tools)
|
|
90
|
+
│ │ ├── tables.ts # Rollable tables (3 tools)
|
|
91
|
+
│ │ ├── cards.ts # Card stacks & decks (5 tools)
|
|
92
|
+
│ │ ├── macros.ts # Macro CRUD & execution (4 tools)
|
|
93
|
+
│ │ ├── effects.ts # Active effect CRUD (4 tools)
|
|
94
|
+
│ │ ├── items.ts # Standalone item CRUD (2 tools)
|
|
95
|
+
│ │ ├── folders.ts # Folder management (3 tools)
|
|
96
|
+
│ │ ├── regions.ts # Region/trigger zones (3 tools)
|
|
97
|
+
│ │ ├── ember-events.ts # Ember campaign event tools (5 tools)
|
|
98
|
+
│ │ ├── helpers.ts # Shared tool helper utilities
|
|
99
|
+
│ │ └── world.ts # World info, pause & time (4 tools)
|
|
100
|
+
│ ├── module/ # Foundry VTT module (browser)
|
|
101
|
+
│ │ ├── main.ts # Module entry, lifecycle hooks, settings registration
|
|
102
|
+
│ │ ├── connection.ts # WebSocket client with reconnection
|
|
103
|
+
│ │ ├── query-handler.ts # Query routing → data access
|
|
104
|
+
│ │ ├── query-handlers-sidebar.ts # Sidebar query handlers (chat, playlists, tables, cards, macros)
|
|
105
|
+
│ │ ├── settings-app.ts # AI Provider Settings UI (ApplicationV2)
|
|
106
|
+
│ │ ├── providers.ts # AI provider definitions (16 chat, 4 voice, 5 image)
|
|
107
|
+
│ │ ├── ai/ # Built-in LLM client (browser-side)
|
|
108
|
+
│ │ │ ├── llm-client.ts # Provider-agnostic LLM client with tool calling loop
|
|
109
|
+
│ │ │ ├── tool-definitions.ts # All 124 tools in OpenAI function-calling format
|
|
110
|
+
│ │ │ ├── streaming.ts # SSE parser for ReadableStream
|
|
111
|
+
│ │ │ ├── anthropic-adapter.ts # Anthropic Messages API ↔ OpenAI format adapter
|
|
112
|
+
│ │ │ └── types.ts # Chat message, tool call, streaming types
|
|
113
|
+
│ │ ├── types/ # Foundry VTT type declarations
|
|
114
|
+
│ │ │ ├── foundry.d.ts # Core Foundry API types
|
|
115
|
+
│ │ │ ├── foundry-appv2.d.ts # ApplicationV2 type declarations
|
|
116
|
+
│ │ │ ├── foundry-canvas.d.ts # Canvas layer types
|
|
117
|
+
│ │ │ ├── foundry-combat.d.ts # Combat system types
|
|
118
|
+
│ │ │ └── foundry-sidebar.d.ts # Sidebar & UI types
|
|
119
|
+
│ │ └── data/ # Foundry API data access
|
|
120
|
+
│ │ ├── characters.ts # Actor queries & mutations
|
|
121
|
+
│ │ ├── scenes.ts # Scene, token & weather queries
|
|
122
|
+
│ │ ├── canvas.ts # Templates, tiles, drawings
|
|
123
|
+
│ │ ├── canvas-environment.ts # Walls, lights, sounds, notes, doors
|
|
124
|
+
│ │ ├── compendium.ts # Pack search & lookup
|
|
125
|
+
│ │ ├── dice.ts # Roll execution
|
|
126
|
+
│ │ ├── journals.ts # Journal CRUD
|
|
127
|
+
│ │ ├── chat.ts # Chat message access
|
|
128
|
+
│ │ ├── playlists.ts # Playlist & track control
|
|
129
|
+
│ │ ├── tables.ts # Rollable table queries
|
|
130
|
+
│ │ ├── cards.ts # Card stack operations
|
|
131
|
+
│ │ ├── macros.ts # Macro CRUD & execution
|
|
132
|
+
│ │ ├── effects.ts # Active effect CRUD
|
|
133
|
+
│ │ ├── items.ts # Standalone item CRUD
|
|
134
|
+
│ │ ├── folders.ts # Folder management
|
|
135
|
+
│ │ ├── regions.ts # Region/trigger zones
|
|
136
|
+
│ │ ├── ember-events.ts # Ember campaign event handlers
|
|
137
|
+
│ │ ├── world.ts # World info, time & pause
|
|
138
|
+
│ │ └── screen.ts # Screenshot capture
|
|
139
|
+
│ └── shared/ # Shared types & protocol
|
|
140
|
+
│ ├── protocol.ts # WebSocket message schemas (Zod)
|
|
141
|
+
│ ├── types.ts # Shared interfaces
|
|
142
|
+
│ └── constants.ts # IDs, ports, timeouts
|
|
143
|
+
├── tests/ # Vitest tests
|
|
144
|
+
├── dist/ # Build output
|
|
145
|
+
│ ├── server/ # Compiled MCP server
|
|
146
|
+
│ └── module/ # Bundled Foundry module (esbuild)
|
|
147
|
+
├── package.json
|
|
148
|
+
├── tsconfig.json
|
|
149
|
+
├── tsconfig.server.json # Server TypeScript config (Node.js)
|
|
150
|
+
├── tsconfig.module.json # Module TypeScript config (browser)
|
|
151
|
+
├── eslint.config.ts
|
|
152
|
+
├── vitest.config.ts
|
|
153
|
+
└── CLAUDE.md # Project instructions
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Query Methods
|
|
157
|
+
|
|
158
|
+
The WebSocket protocol uses method-based routing. Each method maps to a Foundry API operation. There are 124 methods total — the module-side handlers are organized by domain in `src/module/data/`. Key examples:
|
|
159
|
+
|
|
160
|
+
| Domain | Methods | Module Handler |
|
|
161
|
+
|--------|---------|---------------|
|
|
162
|
+
| World & System | `get-world-info`, `toggle-pause`, `get-time`, `advance-time` | `data/world.ts` |
|
|
163
|
+
| Characters | `get-character`, `list-characters`, `update-character`, etc. | `data/characters.ts` |
|
|
164
|
+
| Scenes & Tokens | `get-current-scene`, `move-token`, `create-tokens`, `set-weather`, `pan-canvas`, etc. | `data/scenes.ts` |
|
|
165
|
+
| Combat | `start-combat`, `roll-initiative`, `toggle-condition`, etc. | `data/combat.ts` |
|
|
166
|
+
| Canvas | `create-template`, `create-tile`, `create-drawing`, etc. | `data/canvas.ts` |
|
|
167
|
+
| Environment | `create-walls`, `create-light`, `toggle-door`, etc. | `data/canvas-environment.ts` |
|
|
168
|
+
| Compendium | `search-compendium`, `get-compendium-entry`, etc. | `data/compendium.ts` |
|
|
169
|
+
| Journals | `list-journals`, `search-journals`, `get-journal`, etc. | `data/journals.ts` |
|
|
170
|
+
| Chat | `send-chat-message`, `get-recent-messages` | `data/chat.ts` |
|
|
171
|
+
| Playlists | `play-playlist`, `play-track`, `stop-all-playlists`, etc. | `data/playlists.ts` |
|
|
172
|
+
| Tables | `list-rollable-tables`, `roll-table`, etc. | `data/tables.ts` |
|
|
173
|
+
| Cards | `list-card-stacks`, `draw-cards`, `shuffle-deck`, etc. | `data/cards.ts` |
|
|
174
|
+
| Macros | `list-macros`, `create-macro`, `execute-macro`, `delete-macro` | `data/macros.ts` |
|
|
175
|
+
| Active Effects | `list-effects`, `create-effect`, `update-effect`, `delete-effect` | `data/effects.ts` |
|
|
176
|
+
| Items | `create-item`, `delete-item` | `data/items.ts` |
|
|
177
|
+
| Folders | `list-folders`, `create-folder`, `delete-folder` | `data/folders.ts` |
|
|
178
|
+
| Regions | `list-regions`, `create-region`, `delete-regions` | `data/regions.ts` |
|
|
179
|
+
| Ember Events | `list-events`, `get-event`, `begin-event`, `complete-event`, `set-event-outcome` | `data/ember-events.ts` |
|
|
180
|
+
| Dice | `roll-dice` | `data/dice.ts` |
|
|
181
|
+
| Screen | `capture-screen` | `data/screen.ts` |
|
|
182
|
+
|
|
183
|
+
## Tool Registration Pattern
|
|
184
|
+
|
|
185
|
+
Tools use a typed registry pattern, not string-based dispatch:
|
|
186
|
+
|
|
187
|
+
```typescript
|
|
188
|
+
// src/server/tools/registry.ts
|
|
189
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
190
|
+
import { z } from 'zod';
|
|
191
|
+
import type { FoundryConnector } from '../connector.js';
|
|
192
|
+
|
|
193
|
+
export type ToolRegistrar = (server: McpServer, connector: FoundryConnector) => void;
|
|
194
|
+
|
|
195
|
+
// Each tool file exports a registrar
|
|
196
|
+
// src/server/tools/characters.ts
|
|
197
|
+
export const registerCharacterTools: ToolRegistrar = (server, connector) => {
|
|
198
|
+
server.tool(
|
|
199
|
+
'get-character',
|
|
200
|
+
'Get a character sheet by name or Foundry ID',
|
|
201
|
+
{ identifier: z.string().describe('Character name or Foundry actor ID') },
|
|
202
|
+
async ({ identifier }) => {
|
|
203
|
+
const response = await connector.query('get-character', { identifier });
|
|
204
|
+
return {
|
|
205
|
+
content: [{ type: 'text', text: JSON.stringify(response.result, null, 2) }],
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
);
|
|
209
|
+
// ... more character tools
|
|
210
|
+
};
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
## Configuration
|
|
214
|
+
|
|
215
|
+
### Environment Variables (MCP Server)
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
FAMILIAR_WS_PORT=3005 # WebSocket port (default: 3005)
|
|
219
|
+
FAMILIAR_LOG_LEVEL=info # Log level: fatal|error|warn|info|debug|trace
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Claude Code MCP Config (`.mcp.json` or Claude Desktop config)
|
|
223
|
+
|
|
224
|
+
```json
|
|
225
|
+
{
|
|
226
|
+
"mcpServers": {
|
|
227
|
+
"familiar": {
|
|
228
|
+
"command": "node",
|
|
229
|
+
"args": ["dist/server/index.js"],
|
|
230
|
+
"env": {
|
|
231
|
+
"FAMILIAR_WS_PORT": "3005"
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### Foundry Module Installation
|
|
239
|
+
|
|
240
|
+
Copy `dist/module/` to Foundry's `Data/modules/familiar/` directory along with `module.json`.
|
|
241
|
+
|
|
242
|
+
## Foundry Module Details
|
|
243
|
+
|
|
244
|
+
### Module Manifest (`module.json`)
|
|
245
|
+
|
|
246
|
+
```json
|
|
247
|
+
{
|
|
248
|
+
"id": "familiar",
|
|
249
|
+
"title": "Familiar",
|
|
250
|
+
"description": "Your AI familiar for Foundry VTT — AI DM assistant",
|
|
251
|
+
"version": "0.1.0",
|
|
252
|
+
"compatibility": {
|
|
253
|
+
"minimum": "12",
|
|
254
|
+
"verified": "13"
|
|
255
|
+
},
|
|
256
|
+
"authors": [{ "name": "Ryan Jansen" }],
|
|
257
|
+
"esmodules": ["main.js"],
|
|
258
|
+
"socket": true
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Module Lifecycle
|
|
263
|
+
|
|
264
|
+
1. `Hooks.once('init')` — Register module settings:
|
|
265
|
+
- MCP connection settings (port, auto-connect) — `config: true` (shown in default settings)
|
|
266
|
+
- AI provider settings (provider, API key, model, temperature, etc.) — `config: false` (custom UI via `registerMenu`)
|
|
267
|
+
2. `Hooks.once('ready')` — If GM + auto-connect enabled → connect WebSocket to MCP server
|
|
268
|
+
3. On WebSocket message → parse with Zod schema → route to handler → execute Foundry API → send response
|
|
269
|
+
4. On disconnect → exponential backoff reconnect (up to 5 attempts)
|
|
270
|
+
|
|
271
|
+
### Security
|
|
272
|
+
|
|
273
|
+
- **GM-only**: All queries require `game.user.isGM` — non-GM users are silently ignored
|
|
274
|
+
- **Write protection**: Destructive operations (delete, update) check permissions before execution
|
|
275
|
+
- **No remote access**: WebSocket listens on localhost only by default
|
|
276
|
+
|
|
277
|
+
## D&D 5e (2024) Specifics
|
|
278
|
+
|
|
279
|
+
### Character Data Mapping
|
|
280
|
+
|
|
281
|
+
The module translates Foundry's D&D 5e system data (`system.abilities`, `system.attributes`, etc.) into a clean, readable format for AI consumption:
|
|
282
|
+
|
|
283
|
+
- **Abilities**: STR/DEX/CON/INT/WIS/CHA with scores, modifiers, saves
|
|
284
|
+
- **HP**: Current, max, temp
|
|
285
|
+
- **AC**: Total with breakdown
|
|
286
|
+
- **Skills**: All skills with modifiers, proficiency, expertise
|
|
287
|
+
- **Spells**: By level, with slots remaining, prepared status
|
|
288
|
+
- **Items**: Inventory with attunement, equipped status, quantity
|
|
289
|
+
- **Features**: Class features, racial traits, feats
|
|
290
|
+
|
|
291
|
+
### Compendium Packs
|
|
292
|
+
|
|
293
|
+
D&D 5e provides compendium packs for:
|
|
294
|
+
- `dnd5e.monsters` — Creature stat blocks
|
|
295
|
+
- `dnd5e.items` — Equipment, weapons, armor
|
|
296
|
+
- `dnd5e.spells` — All spells
|
|
297
|
+
- `dnd5e.classfeatures` — Class features
|
|
298
|
+
- `dnd5e.races` — Ancestries/races
|
|
299
|
+
|
|
300
|
+
The `search-compendium` tool searches across packs by name. The `get-compendium-entry` tool returns the full entry with all fields.
|
|
301
|
+
|
|
302
|
+
## Dependencies
|
|
303
|
+
|
|
304
|
+
### Runtime
|
|
305
|
+
|
|
306
|
+
- `@modelcontextprotocol/sdk` — MCP protocol implementation
|
|
307
|
+
- `ws` — WebSocket server (lightweight, no socket.io overhead)
|
|
308
|
+
- `zod` — Schema validation for config & protocol
|
|
309
|
+
- `pino` — Fast structured logging
|
|
310
|
+
|
|
311
|
+
### Dev
|
|
312
|
+
|
|
313
|
+
- `typescript`, `tsx` — TypeScript toolchain
|
|
314
|
+
- `esbuild` — Fast bundler for Foundry module
|
|
315
|
+
- `eslint` + plugins — Linting (security, sonarjs, unicorn, etc.)
|
|
316
|
+
- `prettier` — Formatting
|
|
317
|
+
- `vitest` — Testing
|
|
318
|
+
- `husky` + `lint-staged` — Pre-commit hooks
|
|
319
|
+
- `commitlint` — Conventional commit enforcement
|
|
320
|
+
- `knip` — Dead code detection
|