run-dmcp 0.3.0 → 0.5.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/README.md +19 -5
- package/dist/bin/run-dmcp.js +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +7 -1
- package/dist/mcp-server.d.ts +5 -1
- package/dist/mcp-server.js +5 -1
- package/dist/register/batch.js +11 -10
- package/dist/register/character.js +16 -16
- package/dist/register/core.js +128 -111
- package/dist/register/display.js +42 -41
- package/dist/register/resolve.js +4 -1
- package/dist/register/world.js +13 -13
- package/dist/rpg/index.d.ts +0 -16
- package/dist/rpg/index.js +4 -22
- package/dist/rpg/register/batch.js +3 -3
- package/dist/rpg/server.d.ts +16 -0
- package/dist/rpg/server.js +22 -0
- package/dist/schemas/index.d.ts +62 -62
- package/dist/schemas/index.js +91 -72
- package/dist/server.d.ts +1 -0
- package/dist/server.js +20 -0
- package/dist/utils/output-schemas.d.ts +58 -58
- package/dist/utils/validation.d.ts +31 -2
- package/dist/utils/validation.js +67 -10
- package/package.json +9 -1
- package/dist/register/abilities.d.ts +0 -2
- package/dist/register/abilities.js +0 -165
- package/dist/register/combat.d.ts +0 -2
- package/dist/register/combat.js +0 -207
- package/dist/register/mcp-prompts.d.ts +0 -2
- package/dist/register/mcp-prompts.js +0 -684
- package/dist/register/quests.d.ts +0 -2
- package/dist/register/quests.js +0 -118
- package/dist/register/status.d.ts +0 -2
- package/dist/register/status.js +0 -130
- package/dist/register/tables.d.ts +0 -2
- package/dist/register/tables.js +0 -146
- package/dist/tools/ability.d.ts +0 -48
- package/dist/tools/ability.js +0 -238
- package/dist/tools/combat.d.ts +0 -13
- package/dist/tools/combat.js +0 -195
- package/dist/tools/dice.d.ts +0 -23
- package/dist/tools/dice.js +0 -111
- package/dist/tools/quest.d.ts +0 -34
- package/dist/tools/quest.js +0 -164
- package/dist/tools/status.d.ts +0 -36
- package/dist/tools/status.js +0 -218
- package/dist/tools/tables.d.ts +0 -33
- package/dist/tools/tables.js +0 -209
package/dist/register/core.js
CHANGED
|
@@ -1,9 +1,24 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import * as gameTools from "../tools/game.js";
|
|
3
3
|
import * as rulesTools from "../tools/rules.js";
|
|
4
|
-
import { LIMITS } from "../utils/validation.js";
|
|
4
|
+
import { LIMITS, validatedSchemas } from "../utils/validation.js";
|
|
5
5
|
import { getGameUrl, getWebUiBaseUrl } from "../utils/webui.js";
|
|
6
6
|
import { ANNOTATIONS } from "../utils/tool-annotations.js";
|
|
7
|
+
/**
|
|
8
|
+
* One answer from the preferences interview: what the player said, or a
|
|
9
|
+
* delegation to the DM. `save_game_preferences` takes eighteen of these and
|
|
10
|
+
* they were eighteen copies of the same three fields, which is how half of
|
|
11
|
+
* them ended up unbounded.
|
|
12
|
+
*
|
|
13
|
+
* A FUNCTION, not a shared constant. Reusing one instance eighteen times
|
|
14
|
+
* inside a single tool publishes seventeen `$ref` pointers where a consumer
|
|
15
|
+
* expects a declaration -- see the comment on `validatedSchemas`.
|
|
16
|
+
*/
|
|
17
|
+
const preferenceAnswer = () => z.object({
|
|
18
|
+
value: validatedSchemas.token.nullable(),
|
|
19
|
+
delegatedToDM: z.boolean(),
|
|
20
|
+
notes: validatedSchemas.description.optional(),
|
|
21
|
+
});
|
|
7
22
|
export function registerCoreTools(server) {
|
|
8
23
|
// ============================================================================
|
|
9
24
|
// GAME TOOLS
|
|
@@ -109,7 +124,7 @@ export function registerCoreTools(server) {
|
|
|
109
124
|
server.registerTool("get_game_state", {
|
|
110
125
|
description: "Get full current state overview for a game",
|
|
111
126
|
inputSchema: {
|
|
112
|
-
gameId:
|
|
127
|
+
gameId: validatedSchemas.id.describe("The game ID"),
|
|
113
128
|
},
|
|
114
129
|
annotations: ANNOTATIONS.READ_ONLY,
|
|
115
130
|
}, async ({ gameId }) => {
|
|
@@ -140,7 +155,7 @@ export function registerCoreTools(server) {
|
|
|
140
155
|
server.registerTool("delete_game", {
|
|
141
156
|
description: "Delete a game and all its data. This is IRREVERSIBLE and removes all characters, locations, quests, and history.",
|
|
142
157
|
inputSchema: {
|
|
143
|
-
gameId:
|
|
158
|
+
gameId: validatedSchemas.id.describe("The game ID to delete"),
|
|
144
159
|
},
|
|
145
160
|
annotations: ANNOTATIONS.DESTRUCTIVE,
|
|
146
161
|
}, async ({ gameId }) => {
|
|
@@ -153,7 +168,7 @@ export function registerCoreTools(server) {
|
|
|
153
168
|
server.registerTool("update_game", {
|
|
154
169
|
description: "Update a game's name, setting, or style",
|
|
155
170
|
inputSchema: {
|
|
156
|
-
gameId:
|
|
171
|
+
gameId: validatedSchemas.id.describe("The game ID to update"),
|
|
157
172
|
name: z.string().min(1).max(LIMITS.NAME_MAX).optional().describe("New name for the game"),
|
|
158
173
|
setting: z.string().min(1).max(LIMITS.DESCRIPTION_MAX).optional().describe("New setting description"),
|
|
159
174
|
style: z.string().min(1).max(LIMITS.NAME_MAX).optional().describe("New narrative style"),
|
|
@@ -190,8 +205,8 @@ export function registerCoreTools(server) {
|
|
|
190
205
|
server.registerTool("set_game_title_image", {
|
|
191
206
|
description: "Set or remove the title image for a game",
|
|
192
207
|
inputSchema: {
|
|
193
|
-
gameId:
|
|
194
|
-
imageId:
|
|
208
|
+
gameId: validatedSchemas.id.describe("The game ID"),
|
|
209
|
+
imageId: validatedSchemas.id.nullable().describe("The image ID to set as title image, or null to remove"),
|
|
195
210
|
},
|
|
196
211
|
annotations: ANNOTATIONS.SET,
|
|
197
212
|
}, async ({ gameId, imageId }) => {
|
|
@@ -219,8 +234,8 @@ export function registerCoreTools(server) {
|
|
|
219
234
|
server.registerTool("set_game_favicon", {
|
|
220
235
|
description: "Set or remove the favicon image for a game. This image will be displayed as the browser favicon when viewing this game in the web UI. Should be a square image (ideally 32x32 or larger).",
|
|
221
236
|
inputSchema: {
|
|
222
|
-
gameId:
|
|
223
|
-
imageId:
|
|
237
|
+
gameId: validatedSchemas.id.describe("The game ID"),
|
|
238
|
+
imageId: validatedSchemas.id.nullable().describe("The image ID to set as favicon, or null to remove"),
|
|
224
239
|
},
|
|
225
240
|
annotations: ANNOTATIONS.SET,
|
|
226
241
|
}, async ({ gameId, imageId }) => {
|
|
@@ -596,30 +611,30 @@ export function registerCoreTools(server) {
|
|
|
596
611
|
server.registerTool("save_game_preferences", {
|
|
597
612
|
description: "Save the player's game preferences after the interview",
|
|
598
613
|
inputSchema: {
|
|
599
|
-
gameId:
|
|
614
|
+
gameId: validatedSchemas.id.describe("The game ID"),
|
|
600
615
|
preferences: z.object({
|
|
601
|
-
genre:
|
|
602
|
-
tone:
|
|
603
|
-
setting:
|
|
604
|
-
complexity:
|
|
605
|
-
combatFrequency:
|
|
606
|
-
combatStyle:
|
|
607
|
-
lethality:
|
|
608
|
-
narrativeStyle:
|
|
609
|
-
playerAgency:
|
|
610
|
-
npcDepth:
|
|
611
|
-
romanceContent:
|
|
612
|
-
worldFamiliarity:
|
|
613
|
-
magicOrTechLevel:
|
|
614
|
-
politicalComplexity:
|
|
615
|
-
sessionLength:
|
|
616
|
-
pacingPreference:
|
|
617
|
-
characterCreation:
|
|
618
|
-
startingPowerLevel:
|
|
619
|
-
contentToAvoid:
|
|
620
|
-
contentToInclude:
|
|
621
|
-
inspirations:
|
|
622
|
-
additionalNotes:
|
|
616
|
+
genre: preferenceAnswer(),
|
|
617
|
+
tone: preferenceAnswer(),
|
|
618
|
+
setting: preferenceAnswer(),
|
|
619
|
+
complexity: preferenceAnswer(),
|
|
620
|
+
combatFrequency: preferenceAnswer(),
|
|
621
|
+
combatStyle: preferenceAnswer(),
|
|
622
|
+
lethality: preferenceAnswer(),
|
|
623
|
+
narrativeStyle: preferenceAnswer(),
|
|
624
|
+
playerAgency: preferenceAnswer(),
|
|
625
|
+
npcDepth: preferenceAnswer(),
|
|
626
|
+
romanceContent: preferenceAnswer(),
|
|
627
|
+
worldFamiliarity: preferenceAnswer(),
|
|
628
|
+
magicOrTechLevel: preferenceAnswer(),
|
|
629
|
+
politicalComplexity: preferenceAnswer(),
|
|
630
|
+
sessionLength: preferenceAnswer(),
|
|
631
|
+
pacingPreference: preferenceAnswer(),
|
|
632
|
+
characterCreation: preferenceAnswer(),
|
|
633
|
+
startingPowerLevel: preferenceAnswer(),
|
|
634
|
+
contentToAvoid: validatedSchemas.stringArray,
|
|
635
|
+
contentToInclude: validatedSchemas.stringArray,
|
|
636
|
+
inspirations: validatedSchemas.stringArray,
|
|
637
|
+
additionalNotes: validatedSchemas.description,
|
|
623
638
|
}).describe("The collected preferences"),
|
|
624
639
|
},
|
|
625
640
|
annotations: ANNOTATIONS.CREATE,
|
|
@@ -654,7 +669,7 @@ export function registerCoreTools(server) {
|
|
|
654
669
|
server.registerTool("get_game_preferences", {
|
|
655
670
|
description: "Get the saved game preferences for a game",
|
|
656
671
|
inputSchema: {
|
|
657
|
-
gameId:
|
|
672
|
+
gameId: validatedSchemas.id.describe("The game ID"),
|
|
658
673
|
},
|
|
659
674
|
annotations: ANNOTATIONS.READ_ONLY,
|
|
660
675
|
}, async ({ gameId }) => {
|
|
@@ -676,96 +691,98 @@ export function registerCoreTools(server) {
|
|
|
676
691
|
defaultTool: z.enum(["dalle", "sdxl", "midjourney", "comfyui", "flux", "other"]).optional()
|
|
677
692
|
.describe("Default image generation tool/service"),
|
|
678
693
|
defaultStyle: z.object({
|
|
679
|
-
artisticStyle:
|
|
680
|
-
mood:
|
|
681
|
-
colorScheme:
|
|
682
|
-
qualityTags:
|
|
683
|
-
negativePrompts:
|
|
684
|
-
influences:
|
|
694
|
+
artisticStyle: validatedSchemas.token.optional().describe("E.g., 'digital painting', 'oil painting', 'anime'"),
|
|
695
|
+
mood: validatedSchemas.token.optional().describe("E.g., 'dark', 'epic', 'whimsical'"),
|
|
696
|
+
colorScheme: validatedSchemas.token.optional().describe("E.g., 'warm', 'cold', 'muted', 'vibrant'"),
|
|
697
|
+
qualityTags: validatedSchemas.stringArray.optional().describe("E.g., ['highly detailed', '8k', 'masterpiece']"),
|
|
698
|
+
negativePrompts: validatedSchemas.stringArray.optional().describe("Things to avoid globally"),
|
|
699
|
+
influences: validatedSchemas.stringArray.optional().describe("Artist/game/movie style references"),
|
|
685
700
|
}).optional().describe("Default style settings applied to all images"),
|
|
686
701
|
comfyui: z.object({
|
|
687
|
-
endpoint:
|
|
688
|
-
checkpoint:
|
|
702
|
+
endpoint: validatedSchemas.token.optional().describe("ComfyUI server URL"),
|
|
703
|
+
checkpoint: validatedSchemas.token.optional().describe("Default checkpoint model"),
|
|
689
704
|
loras: z.array(z.object({
|
|
690
|
-
name:
|
|
705
|
+
name: validatedSchemas.token,
|
|
691
706
|
weight: z.number(),
|
|
692
707
|
})).optional().describe("LoRA models to apply"),
|
|
693
708
|
samplerSettings: z.object({
|
|
694
|
-
sampler:
|
|
695
|
-
scheduler:
|
|
709
|
+
sampler: validatedSchemas.token.optional(),
|
|
710
|
+
scheduler: validatedSchemas.token.optional(),
|
|
696
711
|
steps: z.number().optional(),
|
|
697
712
|
cfg: z.number().optional(),
|
|
698
713
|
}).optional(),
|
|
699
714
|
workflows: z.record(z.string(), z.object({
|
|
700
|
-
name:
|
|
701
|
-
description:
|
|
715
|
+
name: validatedSchemas.token.describe("Human-readable workflow name"),
|
|
716
|
+
description: validatedSchemas.description.optional().describe("What this workflow does"),
|
|
702
717
|
workflow: z.record(z.string(), z.unknown()).describe("Full ComfyUI workflow JSON (API format)"),
|
|
703
718
|
inputNodes: z.object({
|
|
704
|
-
positivePrompt:
|
|
705
|
-
negativePrompt:
|
|
706
|
-
checkpoint:
|
|
707
|
-
seed:
|
|
708
|
-
width:
|
|
709
|
-
height:
|
|
710
|
-
steps:
|
|
711
|
-
cfg:
|
|
712
|
-
sampler:
|
|
713
|
-
scheduler:
|
|
719
|
+
positivePrompt: validatedSchemas.token.optional().describe("Node ID for positive prompt"),
|
|
720
|
+
negativePrompt: validatedSchemas.token.optional().describe("Node ID for negative prompt"),
|
|
721
|
+
checkpoint: validatedSchemas.token.optional().describe("Node ID for checkpoint loader"),
|
|
722
|
+
seed: validatedSchemas.token.optional().describe("Node ID for seed/noise"),
|
|
723
|
+
width: validatedSchemas.token.optional().describe("Node ID for width"),
|
|
724
|
+
height: validatedSchemas.token.optional().describe("Node ID for height"),
|
|
725
|
+
steps: validatedSchemas.token.optional().describe("Node ID for steps"),
|
|
726
|
+
cfg: validatedSchemas.token.optional().describe("Node ID for CFG scale"),
|
|
727
|
+
sampler: validatedSchemas.token.optional().describe("Node ID for sampler"),
|
|
728
|
+
scheduler: validatedSchemas.token.optional().describe("Node ID for scheduler"),
|
|
714
729
|
}).optional().describe("Node IDs for dynamic value injection"),
|
|
715
730
|
})).optional().describe("Named workflow templates - full ComfyUI workflows"),
|
|
716
|
-
defaultWorkflowId:
|
|
717
|
-
defaultWorkflow:
|
|
731
|
+
defaultWorkflowId: validatedSchemas.id.optional().describe("ID of the default workflow to use"),
|
|
732
|
+
defaultWorkflow: validatedSchemas.token.optional().describe("Legacy: Workflow name or ID"),
|
|
718
733
|
workflowOverrides: z.record(z.string(), z.unknown()).optional(),
|
|
719
734
|
}).optional().describe("ComfyUI-specific settings"),
|
|
720
735
|
dalle: z.object({
|
|
721
|
-
model:
|
|
736
|
+
model: validatedSchemas.token.optional().describe("'dall-e-3' or 'dall-e-2'"),
|
|
722
737
|
quality: z.enum(["standard", "hd"]).optional(),
|
|
723
738
|
style: z.enum(["vivid", "natural"]).optional(),
|
|
724
739
|
size: z.enum(["1024x1024", "1792x1024", "1024x1792"]).optional(),
|
|
725
740
|
}).optional().describe("DALL-E specific settings"),
|
|
726
741
|
midjourney: z.object({
|
|
727
|
-
version:
|
|
742
|
+
version: validatedSchemas.token.optional().describe("'v5', 'v6', 'niji'"),
|
|
728
743
|
stylize: z.number().optional().describe("0-1000"),
|
|
729
744
|
chaos: z.number().optional().describe("0-100"),
|
|
730
745
|
quality: z.number().optional().describe("0.25, 0.5, 1, 2"),
|
|
731
|
-
aspectRatio:
|
|
746
|
+
aspectRatio: validatedSchemas.token.optional().describe("E.g., '1:1', '16:9', '2:3'"),
|
|
732
747
|
}).optional().describe("Midjourney specific settings"),
|
|
733
748
|
sdxl: z.object({
|
|
734
|
-
model:
|
|
735
|
-
samplerName:
|
|
749
|
+
model: validatedSchemas.token.optional().describe("Model ID or path"),
|
|
750
|
+
samplerName: validatedSchemas.token.optional(),
|
|
736
751
|
steps: z.number().optional(),
|
|
737
752
|
cfg: z.number().optional(),
|
|
738
753
|
width: z.number().optional(),
|
|
739
754
|
height: z.number().optional(),
|
|
740
|
-
|
|
755
|
+
// Free text, not a node ID -- a negative prompt is a comma-separated
|
|
756
|
+
// list that routinely runs past a token's 200.
|
|
757
|
+
negativePrompt: validatedSchemas.description.optional(),
|
|
741
758
|
}).optional().describe("Stable Diffusion / SDXL settings"),
|
|
742
759
|
flux: z.object({
|
|
743
|
-
model:
|
|
760
|
+
model: validatedSchemas.token.optional().describe("'schnell', 'dev', 'pro'"),
|
|
744
761
|
steps: z.number().optional(),
|
|
745
762
|
guidance: z.number().optional(),
|
|
746
763
|
}).optional().describe("Flux settings"),
|
|
747
764
|
defaults: z.object({
|
|
748
|
-
aspectRatio:
|
|
765
|
+
aspectRatio: validatedSchemas.token.optional().describe("Default aspect ratio for images"),
|
|
749
766
|
generateOnCreate: z.boolean().optional().describe("Auto-generate images when entities are created"),
|
|
750
767
|
savePrompts: z.boolean().optional().describe("Store prompts with entities"),
|
|
751
768
|
framing: z.object({
|
|
752
|
-
character:
|
|
753
|
-
location:
|
|
754
|
-
item:
|
|
769
|
+
character: validatedSchemas.token.optional().describe("Default framing for character portraits"),
|
|
770
|
+
location: validatedSchemas.token.optional().describe("Default framing for location scenes"),
|
|
771
|
+
item: validatedSchemas.token.optional().describe("Default framing for item images"),
|
|
755
772
|
}).optional(),
|
|
756
773
|
}).optional().describe("Generation defaults"),
|
|
757
774
|
consistency: z.object({
|
|
758
775
|
maintainColorPalette: z.boolean().optional(),
|
|
759
|
-
characterSeedImages: z.record(z.string(),
|
|
760
|
-
styleReferenceImage:
|
|
776
|
+
characterSeedImages: z.record(z.string(), validatedSchemas.description).optional().describe("characterId -> seed image"),
|
|
777
|
+
styleReferenceImage: validatedSchemas.description.optional().describe("Game-wide style reference"),
|
|
761
778
|
useCharacterRefs: z.boolean().optional().describe("Use existing character images as reference"),
|
|
762
779
|
}).optional().describe("Consistency settings"),
|
|
763
|
-
notes:
|
|
780
|
+
notes: validatedSchemas.description.optional().describe("Custom notes for the DM about image generation"),
|
|
764
781
|
});
|
|
765
782
|
server.registerTool("list_image_generation_presets", {
|
|
766
783
|
description: "List all image generation presets for a game. Presets allow different configurations for different use cases (character portraits, location art, items with text, etc.)",
|
|
767
784
|
inputSchema: {
|
|
768
|
-
gameId:
|
|
785
|
+
gameId: validatedSchemas.id.describe("The game ID"),
|
|
769
786
|
},
|
|
770
787
|
annotations: ANNOTATIONS.READ_ONLY,
|
|
771
788
|
}, async ({ gameId }) => {
|
|
@@ -792,8 +809,8 @@ export function registerCoreTools(server) {
|
|
|
792
809
|
server.registerTool("get_image_generation_preset", {
|
|
793
810
|
description: "Get a specific image generation preset by ID, including full configuration details",
|
|
794
811
|
inputSchema: {
|
|
795
|
-
gameId:
|
|
796
|
-
presetId:
|
|
812
|
+
gameId: validatedSchemas.id.describe("The game ID"),
|
|
813
|
+
presetId: validatedSchemas.id.describe("The preset ID"),
|
|
797
814
|
},
|
|
798
815
|
annotations: ANNOTATIONS.READ_ONLY,
|
|
799
816
|
}, async ({ gameId, presetId }) => {
|
|
@@ -811,7 +828,7 @@ export function registerCoreTools(server) {
|
|
|
811
828
|
server.registerTool("get_default_image_preset", {
|
|
812
829
|
description: "Get the default image generation preset for a game",
|
|
813
830
|
inputSchema: {
|
|
814
|
-
gameId:
|
|
831
|
+
gameId: validatedSchemas.id.describe("The game ID"),
|
|
815
832
|
},
|
|
816
833
|
annotations: ANNOTATIONS.READ_ONLY,
|
|
817
834
|
}, async ({ gameId }) => {
|
|
@@ -834,9 +851,9 @@ export function registerCoreTools(server) {
|
|
|
834
851
|
server.registerTool("create_image_generation_preset", {
|
|
835
852
|
description: "Create a new image generation preset. Use different presets for different purposes: character portraits, location art, items with text, etc. Each preset can have its own tool, model, style, and workflow configuration.",
|
|
836
853
|
inputSchema: {
|
|
837
|
-
gameId:
|
|
838
|
-
name:
|
|
839
|
-
description:
|
|
854
|
+
gameId: validatedSchemas.id.describe("The game ID"),
|
|
855
|
+
name: validatedSchemas.token.describe("Human-readable preset name (e.g., 'Character Portraits', 'Location Art', 'Items with Text')"),
|
|
856
|
+
description: validatedSchemas.description.optional().describe("What this preset is for"),
|
|
840
857
|
entityTypes: z.array(z.string().max(50)).optional()
|
|
841
858
|
.describe("Which entity types this preset is best suited for (e.g., character, location, item, scene, faction)"),
|
|
842
859
|
isDefault: z.boolean().optional().describe("Make this the default preset"),
|
|
@@ -871,10 +888,10 @@ export function registerCoreTools(server) {
|
|
|
871
888
|
server.registerTool("update_image_generation_preset", {
|
|
872
889
|
description: "Update an existing image generation preset. Only specified fields are updated; others are preserved.",
|
|
873
890
|
inputSchema: {
|
|
874
|
-
gameId:
|
|
875
|
-
presetId:
|
|
876
|
-
name:
|
|
877
|
-
description:
|
|
891
|
+
gameId: validatedSchemas.id.describe("The game ID"),
|
|
892
|
+
presetId: validatedSchemas.id.describe("The preset ID to update"),
|
|
893
|
+
name: validatedSchemas.token.optional().describe("New preset name"),
|
|
894
|
+
description: validatedSchemas.description.optional().describe("New description"),
|
|
878
895
|
entityTypes: z.array(z.string().max(50)).optional()
|
|
879
896
|
.describe("Update which entity types this preset is for (e.g., character, location, item, scene, faction)"),
|
|
880
897
|
isDefault: z.boolean().optional().describe("Make this the default preset"),
|
|
@@ -902,8 +919,8 @@ export function registerCoreTools(server) {
|
|
|
902
919
|
server.registerTool("delete_image_generation_preset", {
|
|
903
920
|
description: "Delete an image generation preset. This is IRREVERSIBLE.",
|
|
904
921
|
inputSchema: {
|
|
905
|
-
gameId:
|
|
906
|
-
presetId:
|
|
922
|
+
gameId: validatedSchemas.id.describe("The game ID"),
|
|
923
|
+
presetId: validatedSchemas.id.describe("The preset ID to delete"),
|
|
907
924
|
},
|
|
908
925
|
annotations: ANNOTATIONS.DELETE,
|
|
909
926
|
}, async ({ gameId, presetId }) => {
|
|
@@ -921,8 +938,8 @@ export function registerCoreTools(server) {
|
|
|
921
938
|
server.registerTool("set_default_image_preset", {
|
|
922
939
|
description: "Set which image generation preset should be used by default",
|
|
923
940
|
inputSchema: {
|
|
924
|
-
gameId:
|
|
925
|
-
presetId:
|
|
941
|
+
gameId: validatedSchemas.id.describe("The game ID"),
|
|
942
|
+
presetId: validatedSchemas.id.describe("The preset ID to make default"),
|
|
926
943
|
},
|
|
927
944
|
annotations: ANNOTATIONS.SET,
|
|
928
945
|
}, async ({ gameId, presetId }) => {
|
|
@@ -943,50 +960,50 @@ export function registerCoreTools(server) {
|
|
|
943
960
|
server.registerTool("set_rules", {
|
|
944
961
|
description: "Store a rule system for the game",
|
|
945
962
|
inputSchema: {
|
|
946
|
-
gameId:
|
|
963
|
+
gameId: validatedSchemas.id.describe("The game ID"),
|
|
947
964
|
rules: z.object({
|
|
948
|
-
name:
|
|
949
|
-
description:
|
|
965
|
+
name: validatedSchemas.token,
|
|
966
|
+
description: validatedSchemas.description,
|
|
950
967
|
attributes: z.array(z.object({
|
|
951
|
-
name:
|
|
952
|
-
abbreviation:
|
|
953
|
-
description:
|
|
968
|
+
name: validatedSchemas.token,
|
|
969
|
+
abbreviation: validatedSchemas.token,
|
|
970
|
+
description: validatedSchemas.description,
|
|
954
971
|
defaultValue: z.number(),
|
|
955
972
|
minValue: z.number(),
|
|
956
973
|
maxValue: z.number(),
|
|
957
974
|
})),
|
|
958
975
|
skills: z.array(z.object({
|
|
959
|
-
name:
|
|
960
|
-
governingAttribute:
|
|
961
|
-
description:
|
|
976
|
+
name: validatedSchemas.token,
|
|
977
|
+
governingAttribute: validatedSchemas.token,
|
|
978
|
+
description: validatedSchemas.description,
|
|
962
979
|
})),
|
|
963
980
|
derivedStats: z.array(z.object({
|
|
964
|
-
name:
|
|
965
|
-
abbreviation:
|
|
966
|
-
description:
|
|
967
|
-
formula:
|
|
981
|
+
name: validatedSchemas.token,
|
|
982
|
+
abbreviation: validatedSchemas.token,
|
|
983
|
+
description: validatedSchemas.description,
|
|
984
|
+
formula: validatedSchemas.token,
|
|
968
985
|
})),
|
|
969
986
|
combatRules: z.object({
|
|
970
|
-
initiativeFormula:
|
|
987
|
+
initiativeFormula: validatedSchemas.token,
|
|
971
988
|
actionsPerTurn: z.number(),
|
|
972
|
-
attackFormula:
|
|
973
|
-
defenseFormula:
|
|
974
|
-
damageFormula:
|
|
989
|
+
attackFormula: validatedSchemas.token,
|
|
990
|
+
defenseFormula: validatedSchemas.token,
|
|
991
|
+
damageFormula: validatedSchemas.token,
|
|
975
992
|
conditions: z.array(z.object({
|
|
976
|
-
name:
|
|
977
|
-
description:
|
|
978
|
-
effects:
|
|
993
|
+
name: validatedSchemas.token,
|
|
994
|
+
description: validatedSchemas.description,
|
|
995
|
+
effects: validatedSchemas.description,
|
|
979
996
|
})),
|
|
980
997
|
}),
|
|
981
998
|
checkMechanics: z.object({
|
|
982
|
-
baseDice:
|
|
983
|
-
modifierCalculation:
|
|
999
|
+
baseDice: validatedSchemas.token,
|
|
1000
|
+
modifierCalculation: validatedSchemas.token,
|
|
984
1001
|
difficultyScale: z.record(z.string(), z.number()),
|
|
985
1002
|
criticalSuccess: z.number().optional(),
|
|
986
1003
|
criticalFailure: z.number().optional(),
|
|
987
1004
|
}),
|
|
988
1005
|
progression: z.object({
|
|
989
|
-
experienceFormula:
|
|
1006
|
+
experienceFormula: validatedSchemas.token,
|
|
990
1007
|
levelUpThresholds: z.array(z.number()),
|
|
991
1008
|
attributePointsPerLevel: z.number(),
|
|
992
1009
|
skillPointsPerLevel: z.number(),
|
|
@@ -1004,7 +1021,7 @@ export function registerCoreTools(server) {
|
|
|
1004
1021
|
server.registerTool("get_rules", {
|
|
1005
1022
|
description: "Get the current rule system for a game",
|
|
1006
1023
|
inputSchema: {
|
|
1007
|
-
gameId:
|
|
1024
|
+
gameId: validatedSchemas.id.describe("The game ID"),
|
|
1008
1025
|
},
|
|
1009
1026
|
annotations: ANNOTATIONS.READ_ONLY,
|
|
1010
1027
|
}, async ({ gameId }) => {
|
|
@@ -1021,7 +1038,7 @@ export function registerCoreTools(server) {
|
|
|
1021
1038
|
server.registerTool("update_rules", {
|
|
1022
1039
|
description: "Partially update the rule system",
|
|
1023
1040
|
inputSchema: {
|
|
1024
|
-
gameId:
|
|
1041
|
+
gameId: validatedSchemas.id.describe("The game ID"),
|
|
1025
1042
|
updates: z.record(z.string(), z.unknown()).describe("Partial rule updates"),
|
|
1026
1043
|
},
|
|
1027
1044
|
annotations: ANNOTATIONS.UPDATE,
|
package/dist/register/display.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { getDisplayConfig, setDisplayConfig, resetDisplayConfig, applyThemePreset, listThemePresets, getGameDisplayConfig, setGameDisplayConfig, applyGameThemePreset, resetGameTheme, inferAndApplyTheme, } from "../tools/display.js";
|
|
3
3
|
import { ANNOTATIONS } from "../utils/tool-annotations.js";
|
|
4
|
+
import { validatedSchemas } from "../utils/validation.js";
|
|
4
5
|
// All available theme presets
|
|
5
6
|
const themePresetNames = [
|
|
6
7
|
"high-fantasy",
|
|
@@ -37,19 +38,19 @@ export function registerDisplayTools(server) {
|
|
|
37
38
|
server.registerTool("set_display_config", {
|
|
38
39
|
description: "Set display configuration for the web viewer. Can set any subset of options.",
|
|
39
40
|
inputSchema: {
|
|
40
|
-
bgColor:
|
|
41
|
-
bgSecondary:
|
|
42
|
-
bgElevated:
|
|
43
|
-
textColor:
|
|
44
|
-
textMuted:
|
|
45
|
-
accentColor:
|
|
46
|
-
accentHover:
|
|
47
|
-
borderColor:
|
|
48
|
-
successColor:
|
|
49
|
-
warningColor:
|
|
50
|
-
dangerColor:
|
|
51
|
-
codeBackground:
|
|
52
|
-
codeText:
|
|
41
|
+
bgColor: validatedSchemas.token.optional().describe("Background color (e.g., '#1a1a2e')"),
|
|
42
|
+
bgSecondary: validatedSchemas.token.optional().describe("Secondary background color"),
|
|
43
|
+
bgElevated: validatedSchemas.token.optional().describe("Elevated surface background"),
|
|
44
|
+
textColor: validatedSchemas.token.optional().describe("Main text color"),
|
|
45
|
+
textMuted: validatedSchemas.token.optional().describe("Muted text color"),
|
|
46
|
+
accentColor: validatedSchemas.token.optional().describe("Accent color for links and highlights"),
|
|
47
|
+
accentHover: validatedSchemas.token.optional().describe("Accent color on hover"),
|
|
48
|
+
borderColor: validatedSchemas.token.optional().describe("Border color"),
|
|
49
|
+
successColor: validatedSchemas.token.optional().describe("Success/positive color"),
|
|
50
|
+
warningColor: validatedSchemas.token.optional().describe("Warning/caution color"),
|
|
51
|
+
dangerColor: validatedSchemas.token.optional().describe("Danger/error color"),
|
|
52
|
+
codeBackground: validatedSchemas.token.optional().describe("Code/monospace block background"),
|
|
53
|
+
codeText: validatedSchemas.token.optional().describe("Code/monospace text color"),
|
|
53
54
|
borderRadius: z
|
|
54
55
|
.enum(["sharp", "rounded", "soft"])
|
|
55
56
|
.optional()
|
|
@@ -58,13 +59,13 @@ export function registerDisplayTools(server) {
|
|
|
58
59
|
.enum(["clean", "grungy", "tech", "parchment", "metallic", "wooden"])
|
|
59
60
|
.optional()
|
|
60
61
|
.describe("Card visual style"),
|
|
61
|
-
fontDisplay:
|
|
62
|
-
fontBody:
|
|
63
|
-
fontMono:
|
|
62
|
+
fontDisplay: validatedSchemas.token.optional().describe("Display/heading font (Google Font name)"),
|
|
63
|
+
fontBody: validatedSchemas.token.optional().describe("Body text font (Google Font name)"),
|
|
64
|
+
fontMono: validatedSchemas.token.optional().describe("Monospace font (Google Font name)"),
|
|
64
65
|
showHealthBars: z.boolean().optional().describe("Show health bars on character cards"),
|
|
65
66
|
showConditionTags: z.boolean().optional().describe("Show condition tags"),
|
|
66
67
|
showImages: z.boolean().optional().describe("Show images in the viewer"),
|
|
67
|
-
appTitle:
|
|
68
|
+
appTitle: validatedSchemas.token.optional().describe("Custom title for the web viewer"),
|
|
68
69
|
},
|
|
69
70
|
annotations: ANNOTATIONS.SET,
|
|
70
71
|
}, async (args) => {
|
|
@@ -143,7 +144,7 @@ export function registerDisplayTools(server) {
|
|
|
143
144
|
server.registerTool("get_game_theme", {
|
|
144
145
|
description: "Get the display configuration for a specific game",
|
|
145
146
|
inputSchema: {
|
|
146
|
-
gameId:
|
|
147
|
+
gameId: validatedSchemas.id.describe("The game ID"),
|
|
147
148
|
},
|
|
148
149
|
annotations: ANNOTATIONS.READ_ONLY,
|
|
149
150
|
}, async ({ gameId }) => {
|
|
@@ -161,29 +162,29 @@ export function registerDisplayTools(server) {
|
|
|
161
162
|
server.registerTool("set_game_theme", {
|
|
162
163
|
description: "Set display configuration for a specific game. Each game can have its own visual theme.",
|
|
163
164
|
inputSchema: {
|
|
164
|
-
gameId:
|
|
165
|
-
bgColor:
|
|
166
|
-
bgSecondary:
|
|
167
|
-
bgElevated:
|
|
168
|
-
textColor:
|
|
169
|
-
textMuted:
|
|
170
|
-
accentColor:
|
|
171
|
-
accentHover:
|
|
172
|
-
borderColor:
|
|
173
|
-
successColor:
|
|
174
|
-
warningColor:
|
|
175
|
-
dangerColor:
|
|
176
|
-
codeBackground:
|
|
177
|
-
codeText:
|
|
165
|
+
gameId: validatedSchemas.id.describe("The game ID"),
|
|
166
|
+
bgColor: validatedSchemas.token.optional().describe("Background color"),
|
|
167
|
+
bgSecondary: validatedSchemas.token.optional().describe("Secondary background"),
|
|
168
|
+
bgElevated: validatedSchemas.token.optional().describe("Elevated surface background"),
|
|
169
|
+
textColor: validatedSchemas.token.optional().describe("Text color"),
|
|
170
|
+
textMuted: validatedSchemas.token.optional().describe("Muted text"),
|
|
171
|
+
accentColor: validatedSchemas.token.optional().describe("Accent color"),
|
|
172
|
+
accentHover: validatedSchemas.token.optional().describe("Accent hover color"),
|
|
173
|
+
borderColor: validatedSchemas.token.optional().describe("Border color"),
|
|
174
|
+
successColor: validatedSchemas.token.optional().describe("Success color"),
|
|
175
|
+
warningColor: validatedSchemas.token.optional().describe("Warning color"),
|
|
176
|
+
dangerColor: validatedSchemas.token.optional().describe("Danger color"),
|
|
177
|
+
codeBackground: validatedSchemas.token.optional().describe("Code block background"),
|
|
178
|
+
codeText: validatedSchemas.token.optional().describe("Code text color"),
|
|
178
179
|
borderRadius: z.enum(["sharp", "rounded", "soft"]).optional().describe("Border radius style"),
|
|
179
180
|
cardStyle: z.enum(["clean", "grungy", "tech", "parchment", "metallic", "wooden"]).optional().describe("Card style"),
|
|
180
|
-
fontDisplay:
|
|
181
|
-
fontBody:
|
|
182
|
-
fontMono:
|
|
181
|
+
fontDisplay: validatedSchemas.token.optional().describe("Display font"),
|
|
182
|
+
fontBody: validatedSchemas.token.optional().describe("Body font"),
|
|
183
|
+
fontMono: validatedSchemas.token.optional().describe("Mono font"),
|
|
183
184
|
showHealthBars: z.boolean().optional().describe("Show health bars"),
|
|
184
185
|
showConditionTags: z.boolean().optional().describe("Show condition tags"),
|
|
185
186
|
showImages: z.boolean().optional().describe("Show images"),
|
|
186
|
-
appTitle:
|
|
187
|
+
appTitle: validatedSchemas.token.optional().describe("App title"),
|
|
187
188
|
},
|
|
188
189
|
annotations: ANNOTATIONS.SET,
|
|
189
190
|
}, async ({ gameId, ...config }) => {
|
|
@@ -201,7 +202,7 @@ export function registerDisplayTools(server) {
|
|
|
201
202
|
server.registerTool("apply_game_theme_preset", {
|
|
202
203
|
description: "Apply a predefined theme preset to a specific game. This allows different games to have completely different visual themes.",
|
|
203
204
|
inputSchema: {
|
|
204
|
-
gameId:
|
|
205
|
+
gameId: validatedSchemas.id.describe("The game ID"),
|
|
205
206
|
preset: z.enum(themePresetNames).describe("Theme preset name"),
|
|
206
207
|
},
|
|
207
208
|
annotations: ANNOTATIONS.SET,
|
|
@@ -226,7 +227,7 @@ export function registerDisplayTools(server) {
|
|
|
226
227
|
server.registerTool("reset_game_theme", {
|
|
227
228
|
description: "Remove a game's custom theme, reverting to the global theme",
|
|
228
229
|
inputSchema: {
|
|
229
|
-
gameId:
|
|
230
|
+
gameId: validatedSchemas.id.describe("The game ID"),
|
|
230
231
|
},
|
|
231
232
|
annotations: ANNOTATIONS.SET,
|
|
232
233
|
}, async ({ gameId }) => {
|
|
@@ -244,9 +245,9 @@ export function registerDisplayTools(server) {
|
|
|
244
245
|
server.registerTool("auto_theme_game", {
|
|
245
246
|
description: "Automatically apply an appropriate theme to a game based on its genre and setting. Call this when creating a new game to set up the visual style.",
|
|
246
247
|
inputSchema: {
|
|
247
|
-
gameId:
|
|
248
|
-
genre:
|
|
249
|
-
setting:
|
|
248
|
+
gameId: validatedSchemas.id.describe("The game ID"),
|
|
249
|
+
genre: validatedSchemas.token.describe("Game genre (e.g., 'fantasy', 'sci-fi', 'western', 'noir')"),
|
|
250
|
+
setting: validatedSchemas.description.optional().describe("Optional setting description for more accurate theme matching"),
|
|
250
251
|
},
|
|
251
252
|
annotations: ANNOTATIONS.SET,
|
|
252
253
|
}, async ({ gameId, genre, setting }) => {
|
package/dist/register/resolve.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { ANNOTATIONS } from "../utils/tool-annotations.js";
|
|
3
|
+
import { validatedSchemas } from "../utils/validation.js";
|
|
3
4
|
import { createLogger } from "../utils/logger.js";
|
|
4
5
|
import { errors, formatErrorResponse } from "../utils/errors.js";
|
|
5
6
|
import { ConstraintViolationError } from "../timeline/registry.js";
|
|
@@ -37,7 +38,9 @@ export function registerResolveTools(server, resolver) {
|
|
|
37
38
|
.array(z.object({
|
|
38
39
|
entityId: z.string().max(100).describe("The entity this expectation is about"),
|
|
39
40
|
key: z.string().max(200).describe("The fact key this expectation is about"),
|
|
40
|
-
value: z
|
|
41
|
+
value: z
|
|
42
|
+
.union([validatedSchemas.token, z.number()])
|
|
43
|
+
.describe("The value this proposal declares it depends on"),
|
|
41
44
|
}))
|
|
42
45
|
.optional()
|
|
43
46
|
.describe("Facts this proposal declares it depends on, verified BEFORE the mechanic is dispatched. A caller's " +
|