run-dmcp 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/LICENSE +22 -0
- package/README.md +79 -0
- package/dist/__tests__/engineVocabulary.test.d.ts +1 -0
- package/dist/__tests__/engineVocabulary.test.js +147 -0
- package/dist/db/__tests__/connection.test.d.ts +1 -0
- package/dist/db/__tests__/connection.test.js +72 -0
- package/dist/db/__tests__/testDb.d.ts +33 -0
- package/dist/db/__tests__/testDb.js +41 -0
- package/dist/db/connection.d.ts +22 -0
- package/dist/db/connection.js +107 -0
- package/dist/db/schema.d.ts +1 -0
- package/dist/db/schema.js +725 -0
- package/dist/events/emitter.d.ts +22 -0
- package/dist/events/emitter.js +71 -0
- package/dist/http/server.d.ts +3 -0
- package/dist/http/server.js +649 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +92 -0
- package/dist/register/abilities.d.ts +2 -0
- package/dist/register/abilities.js +165 -0
- package/dist/register/audio.d.ts +2 -0
- package/dist/register/audio.js +326 -0
- package/dist/register/batch.d.ts +2 -0
- package/dist/register/batch.js +343 -0
- package/dist/register/character.d.ts +2 -0
- package/dist/register/character.js +324 -0
- package/dist/register/combat.d.ts +2 -0
- package/dist/register/combat.js +207 -0
- package/dist/register/core.d.ts +2 -0
- package/dist/register/core.js +1040 -0
- package/dist/register/display.d.ts +2 -0
- package/dist/register/display.js +263 -0
- package/dist/register/factions.d.ts +2 -0
- package/dist/register/factions.js +186 -0
- package/dist/register/images.d.ts +2 -0
- package/dist/register/images.js +400 -0
- package/dist/register/inventory.d.ts +2 -0
- package/dist/register/inventory.js +115 -0
- package/dist/register/mcp-prompts.d.ts +2 -0
- package/dist/register/mcp-prompts.js +684 -0
- package/dist/register/mcp-resources.d.ts +2 -0
- package/dist/register/mcp-resources.js +335 -0
- package/dist/register/narrative.d.ts +2 -0
- package/dist/register/narrative.js +242 -0
- package/dist/register/notes.d.ts +2 -0
- package/dist/register/notes.js +170 -0
- package/dist/register/pause.d.ts +2 -0
- package/dist/register/pause.js +580 -0
- package/dist/register/quests.d.ts +2 -0
- package/dist/register/quests.js +118 -0
- package/dist/register/relationships.d.ts +2 -0
- package/dist/register/relationships.js +147 -0
- package/dist/register/resources.d.ts +2 -0
- package/dist/register/resources.js +277 -0
- package/dist/register/secrets.d.ts +2 -0
- package/dist/register/secrets.js +192 -0
- package/dist/register/status.d.ts +2 -0
- package/dist/register/status.js +130 -0
- package/dist/register/tables.d.ts +2 -0
- package/dist/register/tables.js +146 -0
- package/dist/register/tags.d.ts +2 -0
- package/dist/register/tags.js +114 -0
- package/dist/register/time.d.ts +2 -0
- package/dist/register/time.js +281 -0
- package/dist/register/world.d.ts +2 -0
- package/dist/register/world.js +127 -0
- package/dist/schemas/index.d.ts +921 -0
- package/dist/schemas/index.js +121 -0
- package/dist/test-setup.d.ts +1 -0
- package/dist/test-setup.js +13 -0
- package/dist/tools/__tests__/audio.test.d.ts +1 -0
- package/dist/tools/__tests__/audio.test.js +59 -0
- package/dist/tools/__tests__/conserved.test.d.ts +1 -0
- package/dist/tools/__tests__/conserved.test.js +488 -0
- package/dist/tools/__tests__/constraint.test.d.ts +1 -0
- package/dist/tools/__tests__/constraint.test.js +212 -0
- package/dist/tools/__tests__/expiry-consequences.test.d.ts +1 -0
- package/dist/tools/__tests__/expiry-consequences.test.js +110 -0
- package/dist/tools/__tests__/images.test.d.ts +1 -0
- package/dist/tools/__tests__/images.test.js +59 -0
- package/dist/tools/__tests__/relationship.test.d.ts +1 -0
- package/dist/tools/__tests__/relationship.test.js +132 -0
- package/dist/tools/__tests__/resource-constraints.test.d.ts +1 -0
- package/dist/tools/__tests__/resource-constraints.test.js +131 -0
- package/dist/tools/__tests__/resource.test.d.ts +1 -0
- package/dist/tools/__tests__/resource.test.js +190 -0
- package/dist/tools/__tests__/time.test.d.ts +1 -0
- package/dist/tools/__tests__/time.test.js +404 -0
- package/dist/tools/__tests__/timers.test.d.ts +1 -0
- package/dist/tools/__tests__/timers.test.js +426 -0
- package/dist/tools/__tests__/world.test.d.ts +1 -0
- package/dist/tools/__tests__/world.test.js +70 -0
- package/dist/tools/ability.d.ts +48 -0
- package/dist/tools/ability.js +238 -0
- package/dist/tools/audio.d.ts +24 -0
- package/dist/tools/audio.js +365 -0
- package/dist/tools/character.d.ts +70 -0
- package/dist/tools/character.js +309 -0
- package/dist/tools/combat.d.ts +13 -0
- package/dist/tools/combat.js +195 -0
- package/dist/tools/constraint.d.ts +132 -0
- package/dist/tools/constraint.js +269 -0
- package/dist/tools/dice.d.ts +23 -0
- package/dist/tools/dice.js +111 -0
- package/dist/tools/display.d.ts +120 -0
- package/dist/tools/display.js +528 -0
- package/dist/tools/faction.d.ts +61 -0
- package/dist/tools/faction.js +269 -0
- package/dist/tools/game.d.ts +96 -0
- package/dist/tools/game.js +526 -0
- package/dist/tools/image-prompt.d.ts +49 -0
- package/dist/tools/image-prompt.js +479 -0
- package/dist/tools/images.d.ts +47 -0
- package/dist/tools/images.js +449 -0
- package/dist/tools/inventory.d.ts +20 -0
- package/dist/tools/inventory.js +145 -0
- package/dist/tools/narrative.d.ts +58 -0
- package/dist/tools/narrative.js +237 -0
- package/dist/tools/notes.d.ts +41 -0
- package/dist/tools/notes.js +220 -0
- package/dist/tools/pause.d.ts +110 -0
- package/dist/tools/pause.js +1254 -0
- package/dist/tools/quest.d.ts +34 -0
- package/dist/tools/quest.js +164 -0
- package/dist/tools/relationship.d.ts +74 -0
- package/dist/tools/relationship.js +324 -0
- package/dist/tools/resource.d.ts +93 -0
- package/dist/tools/resource.js +374 -0
- package/dist/tools/rules.d.ts +4 -0
- package/dist/tools/rules.js +30 -0
- package/dist/tools/secrets.d.ts +49 -0
- package/dist/tools/secrets.js +195 -0
- package/dist/tools/status.d.ts +36 -0
- package/dist/tools/status.js +218 -0
- package/dist/tools/tables.d.ts +33 -0
- package/dist/tools/tables.js +209 -0
- package/dist/tools/tags.d.ts +52 -0
- package/dist/tools/tags.js +176 -0
- package/dist/tools/time.d.ts +33 -0
- package/dist/tools/time.js +276 -0
- package/dist/tools/timers.d.ts +41 -0
- package/dist/tools/timers.js +215 -0
- package/dist/tools/world.d.ts +78 -0
- package/dist/tools/world.js +331 -0
- package/dist/types/index.d.ts +969 -0
- package/dist/types/index.js +1 -0
- package/dist/utils/__tests__/json.test.d.ts +1 -0
- package/dist/utils/__tests__/json.test.js +55 -0
- package/dist/utils/__tests__/validation.test.d.ts +1 -0
- package/dist/utils/__tests__/validation.test.js +90 -0
- package/dist/utils/errors.d.ts +44 -0
- package/dist/utils/errors.js +121 -0
- package/dist/utils/json.d.ts +9 -0
- package/dist/utils/json.js +23 -0
- package/dist/utils/logger.d.ts +7 -0
- package/dist/utils/logger.js +50 -0
- package/dist/utils/output-schemas.d.ts +594 -0
- package/dist/utils/output-schemas.js +331 -0
- package/dist/utils/tool-annotations.d.ts +147 -0
- package/dist/utils/tool-annotations.js +98 -0
- package/dist/utils/validation.d.ts +34 -0
- package/dist/utils/validation.js +52 -0
- package/dist/utils/verbosity.d.ts +57 -0
- package/dist/utils/verbosity.js +67 -0
- package/dist/utils/webui.d.ts +20 -0
- package/dist/utils/webui.js +35 -0
- package/package.json +75 -0
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Shared output schemas for MCP tools.
|
|
4
|
+
* These enable clients to validate structured outputs from tools.
|
|
5
|
+
*/
|
|
6
|
+
// ============================================================================
|
|
7
|
+
// COMMON RESPONSE PATTERNS
|
|
8
|
+
// ============================================================================
|
|
9
|
+
/** Simple success/failure response */
|
|
10
|
+
export const successResponseSchema = {
|
|
11
|
+
success: z.boolean(),
|
|
12
|
+
message: z.string().optional(),
|
|
13
|
+
};
|
|
14
|
+
/** Simple text result */
|
|
15
|
+
export const textResultSchema = {
|
|
16
|
+
result: z.string(),
|
|
17
|
+
};
|
|
18
|
+
/** Entity deleted response */
|
|
19
|
+
export const deletedResponseSchema = {
|
|
20
|
+
deleted: z.boolean(),
|
|
21
|
+
id: z.string().optional(),
|
|
22
|
+
};
|
|
23
|
+
/** List response with count */
|
|
24
|
+
export const listResponseSchema = (itemSchema) => ({
|
|
25
|
+
items: z.array(itemSchema),
|
|
26
|
+
count: z.number(),
|
|
27
|
+
});
|
|
28
|
+
// ============================================================================
|
|
29
|
+
// GAME SCHEMAS
|
|
30
|
+
// ============================================================================
|
|
31
|
+
export const gameOutputSchema = {
|
|
32
|
+
id: z.string(),
|
|
33
|
+
name: z.string(),
|
|
34
|
+
setting: z.string(),
|
|
35
|
+
style: z.string(),
|
|
36
|
+
createdAt: z.string(),
|
|
37
|
+
updatedAt: z.string(),
|
|
38
|
+
webUi: z.object({
|
|
39
|
+
url: z.string(),
|
|
40
|
+
message: z.string(),
|
|
41
|
+
}).optional(),
|
|
42
|
+
};
|
|
43
|
+
export const gameStateOutputSchema = {
|
|
44
|
+
game: z.object({
|
|
45
|
+
id: z.string(),
|
|
46
|
+
name: z.string(),
|
|
47
|
+
setting: z.string(),
|
|
48
|
+
style: z.string(),
|
|
49
|
+
}),
|
|
50
|
+
characterCount: z.number(),
|
|
51
|
+
locationCount: z.number(),
|
|
52
|
+
activeQuests: z.number(),
|
|
53
|
+
activeCombat: z.boolean(),
|
|
54
|
+
};
|
|
55
|
+
export const gameMenuOutputSchema = {
|
|
56
|
+
hasExistingGames: z.boolean(),
|
|
57
|
+
games: z.array(z.object({
|
|
58
|
+
id: z.string(),
|
|
59
|
+
name: z.string(),
|
|
60
|
+
setting: z.string(),
|
|
61
|
+
style: z.string(),
|
|
62
|
+
createdAt: z.string(),
|
|
63
|
+
updatedAt: z.string(),
|
|
64
|
+
webUiUrl: z.string().optional(),
|
|
65
|
+
})),
|
|
66
|
+
instruction: z.string(),
|
|
67
|
+
webUi: z.object({
|
|
68
|
+
baseUrl: z.string(),
|
|
69
|
+
message: z.string(),
|
|
70
|
+
}).optional(),
|
|
71
|
+
};
|
|
72
|
+
// ============================================================================
|
|
73
|
+
// CHARACTER SCHEMAS
|
|
74
|
+
// ============================================================================
|
|
75
|
+
export const characterStatusSchema = z.object({
|
|
76
|
+
health: z.number(),
|
|
77
|
+
maxHealth: z.number(),
|
|
78
|
+
conditions: z.array(z.string()),
|
|
79
|
+
experience: z.number(),
|
|
80
|
+
level: z.number(),
|
|
81
|
+
});
|
|
82
|
+
export const characterOutputSchema = {
|
|
83
|
+
id: z.string(),
|
|
84
|
+
gameId: z.string(),
|
|
85
|
+
name: z.string(),
|
|
86
|
+
isPlayer: z.boolean(),
|
|
87
|
+
attributes: z.record(z.string(), z.number()),
|
|
88
|
+
skills: z.record(z.string(), z.number()),
|
|
89
|
+
status: characterStatusSchema,
|
|
90
|
+
locationId: z.string().nullable(),
|
|
91
|
+
notes: z.string(),
|
|
92
|
+
createdAt: z.string(),
|
|
93
|
+
};
|
|
94
|
+
export const characterListOutputSchema = {
|
|
95
|
+
characters: z.array(z.object({
|
|
96
|
+
id: z.string(),
|
|
97
|
+
name: z.string(),
|
|
98
|
+
isPlayer: z.boolean(),
|
|
99
|
+
status: characterStatusSchema,
|
|
100
|
+
locationId: z.string().nullable(),
|
|
101
|
+
})),
|
|
102
|
+
count: z.number(),
|
|
103
|
+
};
|
|
104
|
+
// ============================================================================
|
|
105
|
+
// LOCATION SCHEMAS
|
|
106
|
+
// ============================================================================
|
|
107
|
+
export const exitSchema = z.object({
|
|
108
|
+
direction: z.string(),
|
|
109
|
+
destinationId: z.string(),
|
|
110
|
+
description: z.string().optional(),
|
|
111
|
+
locked: z.boolean().optional(),
|
|
112
|
+
hidden: z.boolean().optional(),
|
|
113
|
+
});
|
|
114
|
+
export const locationOutputSchema = {
|
|
115
|
+
id: z.string(),
|
|
116
|
+
gameId: z.string(),
|
|
117
|
+
name: z.string(),
|
|
118
|
+
description: z.string(),
|
|
119
|
+
properties: z.object({
|
|
120
|
+
exits: z.array(exitSchema),
|
|
121
|
+
features: z.array(z.string()),
|
|
122
|
+
atmosphere: z.string(),
|
|
123
|
+
}),
|
|
124
|
+
};
|
|
125
|
+
export const locationListOutputSchema = {
|
|
126
|
+
locations: z.array(z.object({
|
|
127
|
+
id: z.string(),
|
|
128
|
+
name: z.string(),
|
|
129
|
+
description: z.string(),
|
|
130
|
+
})),
|
|
131
|
+
count: z.number(),
|
|
132
|
+
};
|
|
133
|
+
// ============================================================================
|
|
134
|
+
// QUEST SCHEMAS
|
|
135
|
+
// ============================================================================
|
|
136
|
+
export const questObjectiveSchema = z.object({
|
|
137
|
+
id: z.string(),
|
|
138
|
+
description: z.string(),
|
|
139
|
+
completed: z.boolean(),
|
|
140
|
+
optional: z.boolean().optional(),
|
|
141
|
+
});
|
|
142
|
+
export const questOutputSchema = {
|
|
143
|
+
id: z.string(),
|
|
144
|
+
gameId: z.string(),
|
|
145
|
+
name: z.string(),
|
|
146
|
+
description: z.string(),
|
|
147
|
+
objectives: z.array(questObjectiveSchema),
|
|
148
|
+
status: z.enum(["active", "completed", "failed", "abandoned"]),
|
|
149
|
+
rewards: z.string().optional(),
|
|
150
|
+
};
|
|
151
|
+
// ============================================================================
|
|
152
|
+
// COMBAT SCHEMAS
|
|
153
|
+
// ============================================================================
|
|
154
|
+
export const combatParticipantSchema = z.object({
|
|
155
|
+
characterId: z.string(),
|
|
156
|
+
initiative: z.number(),
|
|
157
|
+
isActive: z.boolean(),
|
|
158
|
+
});
|
|
159
|
+
export const combatOutputSchema = {
|
|
160
|
+
id: z.string(),
|
|
161
|
+
gameId: z.string(),
|
|
162
|
+
locationId: z.string(),
|
|
163
|
+
participants: z.array(combatParticipantSchema),
|
|
164
|
+
currentTurn: z.number(),
|
|
165
|
+
round: z.number(),
|
|
166
|
+
status: z.enum(["active", "resolved"]),
|
|
167
|
+
log: z.array(z.string()),
|
|
168
|
+
};
|
|
169
|
+
// ============================================================================
|
|
170
|
+
// DICE SCHEMAS
|
|
171
|
+
// ============================================================================
|
|
172
|
+
export const diceRollOutputSchema = {
|
|
173
|
+
expression: z.string(),
|
|
174
|
+
rolls: z.array(z.number()),
|
|
175
|
+
modifier: z.number(),
|
|
176
|
+
total: z.number(),
|
|
177
|
+
};
|
|
178
|
+
export const checkResultOutputSchema = {
|
|
179
|
+
roll: z.object({
|
|
180
|
+
expression: z.string(),
|
|
181
|
+
rolls: z.array(z.number()),
|
|
182
|
+
modifier: z.number(),
|
|
183
|
+
total: z.number(),
|
|
184
|
+
}),
|
|
185
|
+
modifier: z.number(),
|
|
186
|
+
total: z.number(),
|
|
187
|
+
difficulty: z.number(),
|
|
188
|
+
success: z.boolean(),
|
|
189
|
+
criticalSuccess: z.boolean(),
|
|
190
|
+
criticalFailure: z.boolean(),
|
|
191
|
+
margin: z.number(),
|
|
192
|
+
};
|
|
193
|
+
// ============================================================================
|
|
194
|
+
// ITEM SCHEMAS
|
|
195
|
+
// ============================================================================
|
|
196
|
+
export const itemOutputSchema = {
|
|
197
|
+
id: z.string(),
|
|
198
|
+
gameId: z.string(),
|
|
199
|
+
ownerId: z.string(),
|
|
200
|
+
ownerType: z.enum(["character", "location"]),
|
|
201
|
+
name: z.string(),
|
|
202
|
+
properties: z.object({
|
|
203
|
+
description: z.string(),
|
|
204
|
+
type: z.string(),
|
|
205
|
+
weight: z.number().optional(),
|
|
206
|
+
value: z.number().optional(),
|
|
207
|
+
effects: z.array(z.string()).optional(),
|
|
208
|
+
}),
|
|
209
|
+
};
|
|
210
|
+
export const inventoryOutputSchema = {
|
|
211
|
+
ownerId: z.string(),
|
|
212
|
+
ownerType: z.enum(["character", "location"]),
|
|
213
|
+
items: z.array(z.object({
|
|
214
|
+
id: z.string(),
|
|
215
|
+
name: z.string(),
|
|
216
|
+
properties: z.object({
|
|
217
|
+
description: z.string(),
|
|
218
|
+
type: z.string(),
|
|
219
|
+
}),
|
|
220
|
+
})),
|
|
221
|
+
count: z.number(),
|
|
222
|
+
};
|
|
223
|
+
// ============================================================================
|
|
224
|
+
// NARRATIVE SCHEMAS
|
|
225
|
+
// ============================================================================
|
|
226
|
+
export const narrativeEventOutputSchema = {
|
|
227
|
+
id: z.string(),
|
|
228
|
+
gameId: z.string(),
|
|
229
|
+
eventType: z.string(),
|
|
230
|
+
content: z.string(),
|
|
231
|
+
timestamp: z.string(),
|
|
232
|
+
};
|
|
233
|
+
export const narrativeSummaryOutputSchema = {
|
|
234
|
+
totalEvents: z.number(),
|
|
235
|
+
firstEvent: z.string().nullable(),
|
|
236
|
+
lastEvent: z.string().nullable(),
|
|
237
|
+
eventTypes: z.record(z.string(), z.number()),
|
|
238
|
+
recentEvents: z.array(z.object({
|
|
239
|
+
id: z.string(),
|
|
240
|
+
eventType: z.string(),
|
|
241
|
+
content: z.string(),
|
|
242
|
+
timestamp: z.string(),
|
|
243
|
+
})),
|
|
244
|
+
};
|
|
245
|
+
// ============================================================================
|
|
246
|
+
// MAP SCHEMAS
|
|
247
|
+
// ============================================================================
|
|
248
|
+
export const mapOutputSchema = {
|
|
249
|
+
nodes: z.array(z.object({
|
|
250
|
+
id: z.string(),
|
|
251
|
+
name: z.string(),
|
|
252
|
+
hasPlayer: z.boolean(),
|
|
253
|
+
exits: z.array(z.object({
|
|
254
|
+
direction: z.string(),
|
|
255
|
+
destinationId: z.string(),
|
|
256
|
+
})),
|
|
257
|
+
})),
|
|
258
|
+
connections: z.array(z.object({
|
|
259
|
+
from: z.string(),
|
|
260
|
+
to: z.string(),
|
|
261
|
+
direction: z.string(),
|
|
262
|
+
})),
|
|
263
|
+
bounds: z.object({
|
|
264
|
+
minX: z.number(),
|
|
265
|
+
maxX: z.number(),
|
|
266
|
+
minY: z.number(),
|
|
267
|
+
maxY: z.number(),
|
|
268
|
+
}),
|
|
269
|
+
playerLocation: z.string().optional(),
|
|
270
|
+
};
|
|
271
|
+
// ============================================================================
|
|
272
|
+
// RESOURCE SCHEMAS
|
|
273
|
+
// ============================================================================
|
|
274
|
+
export const resourceOutputSchema = {
|
|
275
|
+
id: z.string(),
|
|
276
|
+
gameId: z.string(),
|
|
277
|
+
ownerId: z.string().nullable(),
|
|
278
|
+
ownerType: z.enum(["game", "character"]),
|
|
279
|
+
name: z.string(),
|
|
280
|
+
description: z.string(),
|
|
281
|
+
category: z.string().nullable(),
|
|
282
|
+
value: z.number(),
|
|
283
|
+
minValue: z.number().nullable(),
|
|
284
|
+
maxValue: z.number().nullable(),
|
|
285
|
+
};
|
|
286
|
+
// ============================================================================
|
|
287
|
+
// CONDITION/STATUS EFFECT SCHEMAS
|
|
288
|
+
// ============================================================================
|
|
289
|
+
export const conditionModifyOutputSchema = {
|
|
290
|
+
characterId: z.string(),
|
|
291
|
+
characterName: z.string(),
|
|
292
|
+
conditions: z.array(z.string()),
|
|
293
|
+
action: z.enum(["added", "removed", "modified"]),
|
|
294
|
+
added: z.array(z.string()),
|
|
295
|
+
removed: z.array(z.string()),
|
|
296
|
+
};
|
|
297
|
+
export const statusEffectOutputSchema = {
|
|
298
|
+
id: z.string(),
|
|
299
|
+
targetId: z.string(),
|
|
300
|
+
name: z.string(),
|
|
301
|
+
description: z.string(),
|
|
302
|
+
effectType: z.enum(["buff", "debuff", "neutral"]).nullable(),
|
|
303
|
+
duration: z.number().nullable(),
|
|
304
|
+
stacks: z.number(),
|
|
305
|
+
};
|
|
306
|
+
// ============================================================================
|
|
307
|
+
// TAG SCHEMAS
|
|
308
|
+
// ============================================================================
|
|
309
|
+
export const tagModifyOutputSchema = {
|
|
310
|
+
entityId: z.string(),
|
|
311
|
+
entityType: z.string(),
|
|
312
|
+
tags: z.array(z.string()),
|
|
313
|
+
action: z.enum(["added", "removed"]),
|
|
314
|
+
tag: z.string(),
|
|
315
|
+
};
|
|
316
|
+
// ============================================================================
|
|
317
|
+
// IMAGE SCHEMAS
|
|
318
|
+
// ============================================================================
|
|
319
|
+
export const storedImageOutputSchema = {
|
|
320
|
+
id: z.string(),
|
|
321
|
+
gameId: z.string(),
|
|
322
|
+
entityId: z.string(),
|
|
323
|
+
entityType: z.string(), // Flexible: character, location, item, scene, faction, quest, ability, etc.
|
|
324
|
+
fileSize: z.number(),
|
|
325
|
+
mimeType: z.string(),
|
|
326
|
+
width: z.number().nullable(),
|
|
327
|
+
height: z.number().nullable(),
|
|
328
|
+
label: z.string().nullable(),
|
|
329
|
+
isPrimary: z.boolean(),
|
|
330
|
+
createdAt: z.string(),
|
|
331
|
+
};
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import type { ToolAnnotations } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Pre-defined tool annotation sets for common patterns.
|
|
4
|
+
* These follow MCP best practices for describing tool behavior.
|
|
5
|
+
*
|
|
6
|
+
* Per the MCP spec:
|
|
7
|
+
* - readOnlyHint: If true, the tool does not modify its environment (default: false)
|
|
8
|
+
* - destructiveHint: If true, the tool may perform destructive updates (default: true when readOnlyHint is false)
|
|
9
|
+
* - idempotentHint: If true, calling the tool multiple times with same args has same effect as calling once
|
|
10
|
+
* - openWorldHint: If true, the tool may interact with an "open world" of external entities
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Read-only operations that don't modify state.
|
|
14
|
+
* Examples: get_character, list_locations, render_map
|
|
15
|
+
*/
|
|
16
|
+
export declare const READ_ONLY: ToolAnnotations;
|
|
17
|
+
/**
|
|
18
|
+
* Operations that create new entities.
|
|
19
|
+
* Examples: create_game, create_character, create_location
|
|
20
|
+
*/
|
|
21
|
+
export declare const CREATE: ToolAnnotations;
|
|
22
|
+
/**
|
|
23
|
+
* Operations that update existing entities.
|
|
24
|
+
* Examples: update_character, move_character, apply_damage
|
|
25
|
+
*/
|
|
26
|
+
export declare const UPDATE: ToolAnnotations;
|
|
27
|
+
/**
|
|
28
|
+
* Idempotent update operations where repeated calls have the same effect.
|
|
29
|
+
* Examples: set_rules, set_time (setting to same value)
|
|
30
|
+
*/
|
|
31
|
+
export declare const IDEMPOTENT_UPDATE: ToolAnnotations;
|
|
32
|
+
/**
|
|
33
|
+
* Operations that delete or remove entities permanently.
|
|
34
|
+
* These should trigger human-in-the-loop confirmation in MCP clients.
|
|
35
|
+
* Examples: delete_game, delete_character, remove_combatant
|
|
36
|
+
*/
|
|
37
|
+
export declare const DESTRUCTIVE: ToolAnnotations;
|
|
38
|
+
/**
|
|
39
|
+
* Operations that connect to external systems.
|
|
40
|
+
* Examples: store_image with URL fetching
|
|
41
|
+
*/
|
|
42
|
+
export declare const EXTERNAL: ToolAnnotations;
|
|
43
|
+
/**
|
|
44
|
+
* Read-only operations that connect to external systems.
|
|
45
|
+
* Examples: fetching external images for display
|
|
46
|
+
*/
|
|
47
|
+
export declare const EXTERNAL_READ: ToolAnnotations;
|
|
48
|
+
/**
|
|
49
|
+
* Helper to merge annotation sets with custom overrides.
|
|
50
|
+
*/
|
|
51
|
+
export declare function withAnnotations(base: ToolAnnotations, overrides: Partial<ToolAnnotations>): ToolAnnotations;
|
|
52
|
+
/**
|
|
53
|
+
* Annotation sets organized by tool category for easy reference.
|
|
54
|
+
*/
|
|
55
|
+
export declare const ANNOTATIONS: {
|
|
56
|
+
readonly READ_ONLY: {
|
|
57
|
+
title?: string | undefined;
|
|
58
|
+
readOnlyHint?: boolean | undefined;
|
|
59
|
+
destructiveHint?: boolean | undefined;
|
|
60
|
+
idempotentHint?: boolean | undefined;
|
|
61
|
+
openWorldHint?: boolean | undefined;
|
|
62
|
+
};
|
|
63
|
+
readonly CREATE: {
|
|
64
|
+
title?: string | undefined;
|
|
65
|
+
readOnlyHint?: boolean | undefined;
|
|
66
|
+
destructiveHint?: boolean | undefined;
|
|
67
|
+
idempotentHint?: boolean | undefined;
|
|
68
|
+
openWorldHint?: boolean | undefined;
|
|
69
|
+
};
|
|
70
|
+
readonly UPDATE: {
|
|
71
|
+
title?: string | undefined;
|
|
72
|
+
readOnlyHint?: boolean | undefined;
|
|
73
|
+
destructiveHint?: boolean | undefined;
|
|
74
|
+
idempotentHint?: boolean | undefined;
|
|
75
|
+
openWorldHint?: boolean | undefined;
|
|
76
|
+
};
|
|
77
|
+
readonly IDEMPOTENT_UPDATE: {
|
|
78
|
+
title?: string | undefined;
|
|
79
|
+
readOnlyHint?: boolean | undefined;
|
|
80
|
+
destructiveHint?: boolean | undefined;
|
|
81
|
+
idempotentHint?: boolean | undefined;
|
|
82
|
+
openWorldHint?: boolean | undefined;
|
|
83
|
+
};
|
|
84
|
+
readonly DESTRUCTIVE: {
|
|
85
|
+
title?: string | undefined;
|
|
86
|
+
readOnlyHint?: boolean | undefined;
|
|
87
|
+
destructiveHint?: boolean | undefined;
|
|
88
|
+
idempotentHint?: boolean | undefined;
|
|
89
|
+
openWorldHint?: boolean | undefined;
|
|
90
|
+
};
|
|
91
|
+
readonly EXTERNAL: {
|
|
92
|
+
title?: string | undefined;
|
|
93
|
+
readOnlyHint?: boolean | undefined;
|
|
94
|
+
destructiveHint?: boolean | undefined;
|
|
95
|
+
idempotentHint?: boolean | undefined;
|
|
96
|
+
openWorldHint?: boolean | undefined;
|
|
97
|
+
};
|
|
98
|
+
readonly EXTERNAL_READ: {
|
|
99
|
+
title?: string | undefined;
|
|
100
|
+
readOnlyHint?: boolean | undefined;
|
|
101
|
+
destructiveHint?: boolean | undefined;
|
|
102
|
+
idempotentHint?: boolean | undefined;
|
|
103
|
+
openWorldHint?: boolean | undefined;
|
|
104
|
+
};
|
|
105
|
+
readonly GET: {
|
|
106
|
+
title?: string | undefined;
|
|
107
|
+
readOnlyHint?: boolean | undefined;
|
|
108
|
+
destructiveHint?: boolean | undefined;
|
|
109
|
+
idempotentHint?: boolean | undefined;
|
|
110
|
+
openWorldHint?: boolean | undefined;
|
|
111
|
+
};
|
|
112
|
+
readonly LIST: {
|
|
113
|
+
title?: string | undefined;
|
|
114
|
+
readOnlyHint?: boolean | undefined;
|
|
115
|
+
destructiveHint?: boolean | undefined;
|
|
116
|
+
idempotentHint?: boolean | undefined;
|
|
117
|
+
openWorldHint?: boolean | undefined;
|
|
118
|
+
};
|
|
119
|
+
readonly RENDER: {
|
|
120
|
+
title?: string | undefined;
|
|
121
|
+
readOnlyHint?: boolean | undefined;
|
|
122
|
+
destructiveHint?: boolean | undefined;
|
|
123
|
+
idempotentHint?: boolean | undefined;
|
|
124
|
+
openWorldHint?: boolean | undefined;
|
|
125
|
+
};
|
|
126
|
+
readonly DELETE: {
|
|
127
|
+
title?: string | undefined;
|
|
128
|
+
readOnlyHint?: boolean | undefined;
|
|
129
|
+
destructiveHint?: boolean | undefined;
|
|
130
|
+
idempotentHint?: boolean | undefined;
|
|
131
|
+
openWorldHint?: boolean | undefined;
|
|
132
|
+
};
|
|
133
|
+
readonly REMOVE: {
|
|
134
|
+
title?: string | undefined;
|
|
135
|
+
readOnlyHint?: boolean | undefined;
|
|
136
|
+
destructiveHint?: boolean | undefined;
|
|
137
|
+
idempotentHint?: boolean | undefined;
|
|
138
|
+
openWorldHint?: boolean | undefined;
|
|
139
|
+
};
|
|
140
|
+
readonly SET: {
|
|
141
|
+
title?: string | undefined;
|
|
142
|
+
readOnlyHint?: boolean | undefined;
|
|
143
|
+
destructiveHint?: boolean | undefined;
|
|
144
|
+
idempotentHint?: boolean | undefined;
|
|
145
|
+
openWorldHint?: boolean | undefined;
|
|
146
|
+
};
|
|
147
|
+
};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pre-defined tool annotation sets for common patterns.
|
|
3
|
+
* These follow MCP best practices for describing tool behavior.
|
|
4
|
+
*
|
|
5
|
+
* Per the MCP spec:
|
|
6
|
+
* - readOnlyHint: If true, the tool does not modify its environment (default: false)
|
|
7
|
+
* - destructiveHint: If true, the tool may perform destructive updates (default: true when readOnlyHint is false)
|
|
8
|
+
* - idempotentHint: If true, calling the tool multiple times with same args has same effect as calling once
|
|
9
|
+
* - openWorldHint: If true, the tool may interact with an "open world" of external entities
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Read-only operations that don't modify state.
|
|
13
|
+
* Examples: get_character, list_locations, render_map
|
|
14
|
+
*/
|
|
15
|
+
export const READ_ONLY = {
|
|
16
|
+
readOnlyHint: true,
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Operations that create new entities.
|
|
20
|
+
* Examples: create_game, create_character, create_location
|
|
21
|
+
*/
|
|
22
|
+
export const CREATE = {
|
|
23
|
+
readOnlyHint: false,
|
|
24
|
+
destructiveHint: false, // Additive, not destructive
|
|
25
|
+
idempotentHint: false, // Creates new entity each time
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Operations that update existing entities.
|
|
29
|
+
* Examples: update_character, move_character, apply_damage
|
|
30
|
+
*/
|
|
31
|
+
export const UPDATE = {
|
|
32
|
+
readOnlyHint: false,
|
|
33
|
+
destructiveHint: false, // Updates, not deletes
|
|
34
|
+
idempotentHint: false, // State changes with each call
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Idempotent update operations where repeated calls have the same effect.
|
|
38
|
+
* Examples: set_rules, set_time (setting to same value)
|
|
39
|
+
*/
|
|
40
|
+
export const IDEMPOTENT_UPDATE = {
|
|
41
|
+
readOnlyHint: false,
|
|
42
|
+
destructiveHint: false,
|
|
43
|
+
idempotentHint: true,
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Operations that delete or remove entities permanently.
|
|
47
|
+
* These should trigger human-in-the-loop confirmation in MCP clients.
|
|
48
|
+
* Examples: delete_game, delete_character, remove_combatant
|
|
49
|
+
*/
|
|
50
|
+
export const DESTRUCTIVE = {
|
|
51
|
+
readOnlyHint: false,
|
|
52
|
+
destructiveHint: true,
|
|
53
|
+
idempotentHint: true, // Deleting twice has same effect as deleting once
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Operations that connect to external systems.
|
|
57
|
+
* Examples: store_image with URL fetching
|
|
58
|
+
*/
|
|
59
|
+
export const EXTERNAL = {
|
|
60
|
+
readOnlyHint: false,
|
|
61
|
+
openWorldHint: true,
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Read-only operations that connect to external systems.
|
|
65
|
+
* Examples: fetching external images for display
|
|
66
|
+
*/
|
|
67
|
+
export const EXTERNAL_READ = {
|
|
68
|
+
readOnlyHint: true,
|
|
69
|
+
openWorldHint: true,
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* Helper to merge annotation sets with custom overrides.
|
|
73
|
+
*/
|
|
74
|
+
export function withAnnotations(base, overrides) {
|
|
75
|
+
return { ...base, ...overrides };
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Annotation sets organized by tool category for easy reference.
|
|
79
|
+
*/
|
|
80
|
+
export const ANNOTATIONS = {
|
|
81
|
+
// Read operations
|
|
82
|
+
READ_ONLY,
|
|
83
|
+
// Write operations
|
|
84
|
+
CREATE,
|
|
85
|
+
UPDATE,
|
|
86
|
+
IDEMPOTENT_UPDATE,
|
|
87
|
+
DESTRUCTIVE,
|
|
88
|
+
// External operations
|
|
89
|
+
EXTERNAL,
|
|
90
|
+
EXTERNAL_READ,
|
|
91
|
+
// Convenience aliases
|
|
92
|
+
GET: READ_ONLY,
|
|
93
|
+
LIST: READ_ONLY,
|
|
94
|
+
RENDER: READ_ONLY,
|
|
95
|
+
DELETE: DESTRUCTIVE,
|
|
96
|
+
REMOVE: DESTRUCTIVE,
|
|
97
|
+
SET: IDEMPOTENT_UPDATE,
|
|
98
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Common input length limits for security and performance.
|
|
4
|
+
* These prevent DoS attacks via extremely large inputs.
|
|
5
|
+
*/
|
|
6
|
+
export declare const LIMITS: {
|
|
7
|
+
readonly NAME_MAX: 200;
|
|
8
|
+
readonly DESCRIPTION_MAX: 5000;
|
|
9
|
+
readonly CONTENT_MAX: 50000;
|
|
10
|
+
readonly NARRATIVE_MAX: 200000;
|
|
11
|
+
readonly ARRAY_MAX: 100;
|
|
12
|
+
readonly MAX_DEPTH: 10;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Pre-built Zod schemas with length limits
|
|
16
|
+
*/
|
|
17
|
+
export declare const validatedSchemas: {
|
|
18
|
+
readonly name: z.ZodString;
|
|
19
|
+
readonly description: z.ZodString;
|
|
20
|
+
readonly content: z.ZodString;
|
|
21
|
+
readonly narrative: z.ZodString;
|
|
22
|
+
readonly id: z.ZodString;
|
|
23
|
+
readonly tag: z.ZodString;
|
|
24
|
+
readonly stringArray: z.ZodArray<z.ZodString, "many">;
|
|
25
|
+
readonly tagArray: z.ZodArray<z.ZodString, "many">;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Helper to create a bounded string schema
|
|
29
|
+
*/
|
|
30
|
+
export declare function boundedString(maxLength?: number): z.ZodString;
|
|
31
|
+
/**
|
|
32
|
+
* Helper to create a bounded array schema
|
|
33
|
+
*/
|
|
34
|
+
export declare function boundedArray<T extends z.ZodType>(schema: T, maxItems?: number): z.ZodArray<T, "many">;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Common input length limits for security and performance.
|
|
4
|
+
* These prevent DoS attacks via extremely large inputs.
|
|
5
|
+
*/
|
|
6
|
+
export const LIMITS = {
|
|
7
|
+
// Short text fields (names, titles)
|
|
8
|
+
NAME_MAX: 200,
|
|
9
|
+
// Medium text fields (descriptions)
|
|
10
|
+
DESCRIPTION_MAX: 5000,
|
|
11
|
+
// Long text fields (notes, content)
|
|
12
|
+
CONTENT_MAX: 50000,
|
|
13
|
+
// Very long text fields (story exports, narrative)
|
|
14
|
+
NARRATIVE_MAX: 200000,
|
|
15
|
+
// Array limits
|
|
16
|
+
ARRAY_MAX: 100,
|
|
17
|
+
// JSON object depth limit (for nested structures)
|
|
18
|
+
MAX_DEPTH: 10,
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Pre-built Zod schemas with length limits
|
|
22
|
+
*/
|
|
23
|
+
export const validatedSchemas = {
|
|
24
|
+
// Name fields (character names, location names, etc.)
|
|
25
|
+
name: z.string().min(1).max(LIMITS.NAME_MAX),
|
|
26
|
+
// Description fields
|
|
27
|
+
description: z.string().max(LIMITS.DESCRIPTION_MAX),
|
|
28
|
+
// Content fields (notes, large text)
|
|
29
|
+
content: z.string().max(LIMITS.CONTENT_MAX),
|
|
30
|
+
// Narrative content (very large text allowed)
|
|
31
|
+
narrative: z.string().max(LIMITS.NARRATIVE_MAX),
|
|
32
|
+
// ID fields (UUIDs are 36 characters)
|
|
33
|
+
id: z.string().max(100),
|
|
34
|
+
// Tag/category strings
|
|
35
|
+
tag: z.string().min(1).max(100),
|
|
36
|
+
// Array of strings with limits
|
|
37
|
+
stringArray: z.array(z.string().max(LIMITS.NAME_MAX)).max(LIMITS.ARRAY_MAX),
|
|
38
|
+
// Array of tags
|
|
39
|
+
tagArray: z.array(z.string().min(1).max(100)).max(LIMITS.ARRAY_MAX),
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Helper to create a bounded string schema
|
|
43
|
+
*/
|
|
44
|
+
export function boundedString(maxLength = LIMITS.NAME_MAX) {
|
|
45
|
+
return z.string().max(maxLength);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Helper to create a bounded array schema
|
|
49
|
+
*/
|
|
50
|
+
export function boundedArray(schema, maxItems = LIMITS.ARRAY_MAX) {
|
|
51
|
+
return z.array(schema).max(maxItems);
|
|
52
|
+
}
|