@mythxengine/mcp-server 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 +21 -0
- package/dist/__tests__/assemble.test.d.ts +2 -0
- package/dist/__tests__/assemble.test.d.ts.map +1 -0
- package/dist/__tests__/assemble.test.js +81 -0
- package/dist/__tests__/assemble.test.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -0
- package/dist/resources/index.d.ts +9 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/index.js +202 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/server.d.ts +41 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +91 -0
- package/dist/server.js.map +1 -0
- package/dist/state/manager.d.ts +88 -0
- package/dist/state/manager.d.ts.map +1 -0
- package/dist/state/manager.js +308 -0
- package/dist/state/manager.js.map +1 -0
- package/dist/state/rules.d.ts +30 -0
- package/dist/state/rules.d.ts.map +1 -0
- package/dist/state/rules.js +61 -0
- package/dist/state/rules.js.map +1 -0
- package/dist/state/worldpacks.d.ts +43 -0
- package/dist/state/worldpacks.d.ts.map +1 -0
- package/dist/state/worldpacks.js +125 -0
- package/dist/state/worldpacks.js.map +1 -0
- package/dist/tools/augmentation/augment.d.ts +15 -0
- package/dist/tools/augmentation/augment.d.ts.map +1 -0
- package/dist/tools/augmentation/augment.js +512 -0
- package/dist/tools/augmentation/augment.js.map +1 -0
- package/dist/tools/augmentation/index.d.ts +6 -0
- package/dist/tools/augmentation/index.d.ts.map +1 -0
- package/dist/tools/augmentation/index.js +7 -0
- package/dist/tools/augmentation/index.js.map +1 -0
- package/dist/tools/characters.d.ts +26 -0
- package/dist/tools/characters.d.ts.map +1 -0
- package/dist/tools/characters.js +362 -0
- package/dist/tools/characters.js.map +1 -0
- package/dist/tools/clocks.d.ts +33 -0
- package/dist/tools/clocks.d.ts.map +1 -0
- package/dist/tools/clocks.js +438 -0
- package/dist/tools/clocks.js.map +1 -0
- package/dist/tools/combat.d.ts +38 -0
- package/dist/tools/combat.d.ts.map +1 -0
- package/dist/tools/combat.js +574 -0
- package/dist/tools/combat.js.map +1 -0
- package/dist/tools/dice.d.ts +9 -0
- package/dist/tools/dice.d.ts.map +1 -0
- package/dist/tools/dice.js +287 -0
- package/dist/tools/dice.js.map +1 -0
- package/dist/tools/encounters.d.ts +21 -0
- package/dist/tools/encounters.d.ts.map +1 -0
- package/dist/tools/encounters.js +521 -0
- package/dist/tools/encounters.js.map +1 -0
- package/dist/tools/engagement.d.ts +25 -0
- package/dist/tools/engagement.d.ts.map +1 -0
- package/dist/tools/engagement.js +491 -0
- package/dist/tools/engagement.js.map +1 -0
- package/dist/tools/expansion/archetype.d.ts +12 -0
- package/dist/tools/expansion/archetype.d.ts.map +1 -0
- package/dist/tools/expansion/archetype.js +157 -0
- package/dist/tools/expansion/archetype.js.map +1 -0
- package/dist/tools/expansion/index.d.ts +12 -0
- package/dist/tools/expansion/index.d.ts.map +1 -0
- package/dist/tools/expansion/index.js +21 -0
- package/dist/tools/expansion/index.js.map +1 -0
- package/dist/tools/expansion/location.d.ts +12 -0
- package/dist/tools/expansion/location.d.ts.map +1 -0
- package/dist/tools/expansion/location.js +149 -0
- package/dist/tools/expansion/location.js.map +1 -0
- package/dist/tools/expansion/monster.d.ts +12 -0
- package/dist/tools/expansion/monster.d.ts.map +1 -0
- package/dist/tools/expansion/monster.js +157 -0
- package/dist/tools/expansion/monster.js.map +1 -0
- package/dist/tools/expansion/npc.d.ts +12 -0
- package/dist/tools/expansion/npc.d.ts.map +1 -0
- package/dist/tools/expansion/npc.js +153 -0
- package/dist/tools/expansion/npc.js.map +1 -0
- package/dist/tools/generation/archetypes.d.ts +12 -0
- package/dist/tools/generation/archetypes.d.ts.map +1 -0
- package/dist/tools/generation/archetypes.js +129 -0
- package/dist/tools/generation/archetypes.js.map +1 -0
- package/dist/tools/generation/arcs.d.ts +13 -0
- package/dist/tools/generation/arcs.d.ts.map +1 -0
- package/dist/tools/generation/arcs.js +186 -0
- package/dist/tools/generation/arcs.js.map +1 -0
- package/dist/tools/generation/encounters.d.ts +12 -0
- package/dist/tools/generation/encounters.d.ts.map +1 -0
- package/dist/tools/generation/encounters.js +169 -0
- package/dist/tools/generation/encounters.js.map +1 -0
- package/dist/tools/generation/index.d.ts +19 -0
- package/dist/tools/generation/index.d.ts.map +1 -0
- package/dist/tools/generation/index.js +42 -0
- package/dist/tools/generation/index.js.map +1 -0
- package/dist/tools/generation/items.d.ts +12 -0
- package/dist/tools/generation/items.d.ts.map +1 -0
- package/dist/tools/generation/items.js +149 -0
- package/dist/tools/generation/items.js.map +1 -0
- package/dist/tools/generation/locations.d.ts +12 -0
- package/dist/tools/generation/locations.d.ts.map +1 -0
- package/dist/tools/generation/locations.js +131 -0
- package/dist/tools/generation/locations.js.map +1 -0
- package/dist/tools/generation/monsters.d.ts +12 -0
- package/dist/tools/generation/monsters.d.ts.map +1 -0
- package/dist/tools/generation/monsters.js +154 -0
- package/dist/tools/generation/monsters.js.map +1 -0
- package/dist/tools/generation/narrative.d.ts +12 -0
- package/dist/tools/generation/narrative.d.ts.map +1 -0
- package/dist/tools/generation/narrative.js +129 -0
- package/dist/tools/generation/narrative.js.map +1 -0
- package/dist/tools/generation/npcs.d.ts +12 -0
- package/dist/tools/generation/npcs.d.ts.map +1 -0
- package/dist/tools/generation/npcs.js +136 -0
- package/dist/tools/generation/npcs.js.map +1 -0
- package/dist/tools/generation/resume.d.ts +12 -0
- package/dist/tools/generation/resume.d.ts.map +1 -0
- package/dist/tools/generation/resume.js +288 -0
- package/dist/tools/generation/resume.js.map +1 -0
- package/dist/tools/generation/rules-prompt.d.ts +23 -0
- package/dist/tools/generation/rules-prompt.d.ts.map +1 -0
- package/dist/tools/generation/rules-prompt.js +209 -0
- package/dist/tools/generation/rules-prompt.js.map +1 -0
- package/dist/tools/generation/seed.d.ts +12 -0
- package/dist/tools/generation/seed.d.ts.map +1 -0
- package/dist/tools/generation/seed.js +171 -0
- package/dist/tools/generation/seed.js.map +1 -0
- package/dist/tools/generation/situations.d.ts +13 -0
- package/dist/tools/generation/situations.d.ts.map +1 -0
- package/dist/tools/generation/situations.js +247 -0
- package/dist/tools/generation/situations.js.map +1 -0
- package/dist/tools/gm-guidance.d.ts +13 -0
- package/dist/tools/gm-guidance.d.ts.map +1 -0
- package/dist/tools/gm-guidance.js +395 -0
- package/dist/tools/gm-guidance.js.map +1 -0
- package/dist/tools/index.d.ts +33 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +80 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/investigation.d.ts +41 -0
- package/dist/tools/investigation.d.ts.map +1 -0
- package/dist/tools/investigation.js +586 -0
- package/dist/tools/investigation.js.map +1 -0
- package/dist/tools/leads.d.ts +29 -0
- package/dist/tools/leads.d.ts.map +1 -0
- package/dist/tools/leads.js +460 -0
- package/dist/tools/leads.js.map +1 -0
- package/dist/tools/players.d.ts +30 -0
- package/dist/tools/players.d.ts.map +1 -0
- package/dist/tools/players.js +448 -0
- package/dist/tools/players.js.map +1 -0
- package/dist/tools/portable-clues.d.ts +29 -0
- package/dist/tools/portable-clues.d.ts.map +1 -0
- package/dist/tools/portable-clues.js +490 -0
- package/dist/tools/portable-clues.js.map +1 -0
- package/dist/tools/relationships.d.ts +29 -0
- package/dist/tools/relationships.d.ts.map +1 -0
- package/dist/tools/relationships.js +471 -0
- package/dist/tools/relationships.js.map +1 -0
- package/dist/tools/scene-framing.d.ts +21 -0
- package/dist/tools/scene-framing.d.ts.map +1 -0
- package/dist/tools/scene-framing.js +380 -0
- package/dist/tools/scene-framing.js.map +1 -0
- package/dist/tools/sessions.d.ts +30 -0
- package/dist/tools/sessions.d.ts.map +1 -0
- package/dist/tools/sessions.js +253 -0
- package/dist/tools/sessions.js.map +1 -0
- package/dist/tools/time.d.ts +26 -0
- package/dist/tools/time.d.ts.map +1 -0
- package/dist/tools/time.js +438 -0
- package/dist/tools/time.js.map +1 -0
- package/dist/tools/turns.d.ts +38 -0
- package/dist/tools/turns.d.ts.map +1 -0
- package/dist/tools/turns.js +560 -0
- package/dist/tools/turns.js.map +1 -0
- package/dist/tools/worldpack/assemble.d.ts +20 -0
- package/dist/tools/worldpack/assemble.d.ts.map +1 -0
- package/dist/tools/worldpack/assemble.js +237 -0
- package/dist/tools/worldpack/assemble.js.map +1 -0
- package/dist/tools/worldpack/docs-generator.d.ts +18 -0
- package/dist/tools/worldpack/docs-generator.d.ts.map +1 -0
- package/dist/tools/worldpack/docs-generator.js +264 -0
- package/dist/tools/worldpack/docs-generator.js.map +1 -0
- package/dist/tools/worldpack/export.d.ts +12 -0
- package/dist/tools/worldpack/export.d.ts.map +1 -0
- package/dist/tools/worldpack/export.js +209 -0
- package/dist/tools/worldpack/export.js.map +1 -0
- package/dist/tools/worldpack/index.d.ts +15 -0
- package/dist/tools/worldpack/index.d.ts.map +1 -0
- package/dist/tools/worldpack/index.js +30 -0
- package/dist/tools/worldpack/index.js.map +1 -0
- package/dist/tools/worldpack/lookup.d.ts +19 -0
- package/dist/tools/worldpack/lookup.d.ts.map +1 -0
- package/dist/tools/worldpack/lookup.js +320 -0
- package/dist/tools/worldpack/lookup.js.map +1 -0
- package/dist/tools/worldpack/manage.d.ts +20 -0
- package/dist/tools/worldpack/manage.d.ts.map +1 -0
- package/dist/tools/worldpack/manage.js +101 -0
- package/dist/tools/worldpack/manage.js.map +1 -0
- package/dist/tools/worldpack/save-result.d.ts +12 -0
- package/dist/tools/worldpack/save-result.d.ts.map +1 -0
- package/dist/tools/worldpack/save-result.js +222 -0
- package/dist/tools/worldpack/save-result.js.map +1 -0
- package/dist/tools/worldpack/summary.d.ts +13 -0
- package/dist/tools/worldpack/summary.d.ts.map +1 -0
- package/dist/tools/worldpack/summary.js +180 -0
- package/dist/tools/worldpack/summary.js.map +1 -0
- package/dist/tools/worldpack/validate.d.ts +12 -0
- package/dist/tools/worldpack/validate.d.ts.map +1 -0
- package/dist/tools/worldpack/validate.js +388 -0
- package/dist/tools/worldpack/validate.js.map +1 -0
- package/package.json +59 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NPC Expansion Tool
|
|
3
|
+
*
|
|
4
|
+
* Expands an NPC with additional detail.
|
|
5
|
+
*/
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
import { randomUUID } from "crypto";
|
|
8
|
+
import { sessionManager, readManifest, writeManifest, addManifestStep, } from "../../state/manager.js";
|
|
9
|
+
const ExpandNPCInput = z.object({
|
|
10
|
+
sessionId: z.string(),
|
|
11
|
+
npcId: z.string().describe("ID of the NPC to expand"),
|
|
12
|
+
});
|
|
13
|
+
/**
|
|
14
|
+
* expand_npc tool
|
|
15
|
+
*/
|
|
16
|
+
export const expandNPCTool = {
|
|
17
|
+
name: "expand_npc",
|
|
18
|
+
description: "Expand an NPC with additional detail (backstory, combat stats, quest hooks). Returns a prompt for LLM execution.",
|
|
19
|
+
inputSchema: {
|
|
20
|
+
type: "object",
|
|
21
|
+
properties: {
|
|
22
|
+
sessionId: { type: "string", description: "Session ID" },
|
|
23
|
+
npcId: { type: "string", description: "ID of the NPC to expand" },
|
|
24
|
+
},
|
|
25
|
+
required: ["sessionId", "npcId"],
|
|
26
|
+
},
|
|
27
|
+
handler: async (args) => {
|
|
28
|
+
const input = ExpandNPCInput.parse(args);
|
|
29
|
+
const session = await sessionManager.get(input.sessionId);
|
|
30
|
+
if (!session) {
|
|
31
|
+
throw new Error(`Session not found: ${input.sessionId}`);
|
|
32
|
+
}
|
|
33
|
+
if (!session.generation?.worldSeed) {
|
|
34
|
+
throw new Error("World seed not found. Call generate_world_seed first.");
|
|
35
|
+
}
|
|
36
|
+
const worldSeed = session.generation.worldSeed;
|
|
37
|
+
// Find the NPC
|
|
38
|
+
const npcs = session.generation.generatedContent.npcs;
|
|
39
|
+
const npc = npcs.find((n) => n.id === input.npcId);
|
|
40
|
+
if (!npc) {
|
|
41
|
+
throw new Error(`NPC not found: ${input.npcId}`);
|
|
42
|
+
}
|
|
43
|
+
// Check if already expanded
|
|
44
|
+
const expandedNPCs = session.generation.expansions.npcs;
|
|
45
|
+
const alreadyExpanded = expandedNPCs.find((n) => n.id === input.npcId);
|
|
46
|
+
if (alreadyExpanded) {
|
|
47
|
+
throw new Error(`NPC already expanded: ${input.npcId}`);
|
|
48
|
+
}
|
|
49
|
+
const stepId = randomUUID();
|
|
50
|
+
// Get items for inventory
|
|
51
|
+
const items = session.generation.generatedContent.items;
|
|
52
|
+
// Record the generation step
|
|
53
|
+
session.generation.history.push({
|
|
54
|
+
id: stepId,
|
|
55
|
+
type: "expand_npc",
|
|
56
|
+
startedAt: new Date().toISOString(),
|
|
57
|
+
completedAt: null,
|
|
58
|
+
status: "in_progress",
|
|
59
|
+
generatedIds: [],
|
|
60
|
+
});
|
|
61
|
+
session.generation.status = "expanding";
|
|
62
|
+
await sessionManager.save(session);
|
|
63
|
+
// Update manifest
|
|
64
|
+
const manifest = await readManifest(input.sessionId);
|
|
65
|
+
if (manifest) {
|
|
66
|
+
addManifestStep(manifest, "expand_npc", `expansions/npc-${input.npcId}.json`);
|
|
67
|
+
manifest.status = "expanding";
|
|
68
|
+
await writeManifest(input.sessionId, manifest);
|
|
69
|
+
}
|
|
70
|
+
const systemPrompt = `You are expanding an NPC for a tabletop RPG. Add backstory, combat stats (if relevant), quest hooks, and inventory while maintaining the NPC's established identity.
|
|
71
|
+
|
|
72
|
+
Rules:
|
|
73
|
+
- Backstory should explain how they became who they are
|
|
74
|
+
- Combat stats only for NPCs who might fight (antagonists, guards, etc.)
|
|
75
|
+
- Quest hooks should connect to their motivation and narrative role
|
|
76
|
+
- Inventory should fit their role and economic status
|
|
77
|
+
- Abilities: STR, AGI, WIT, CON (-3 to +3)
|
|
78
|
+
|
|
79
|
+
Output valid JSON only.`;
|
|
80
|
+
const userPrompt = `Expand this NPC with additional detail:
|
|
81
|
+
|
|
82
|
+
World: ${worldSeed.name}
|
|
83
|
+
Tone: ${worldSeed.aesthetic.tone}
|
|
84
|
+
Themes: ${worldSeed.aesthetic.themes.join(", ")}
|
|
85
|
+
Core Conflict: ${worldSeed.coreConflict}
|
|
86
|
+
Lethality: ${worldSeed.settings.lethality}
|
|
87
|
+
|
|
88
|
+
NPC to expand:
|
|
89
|
+
- ID: ${npc.id}
|
|
90
|
+
- Name: ${npc.name}
|
|
91
|
+
- Description: ${npc.description}
|
|
92
|
+
- Personality: ${npc.personality}
|
|
93
|
+
- Motivation: ${npc.motivation}
|
|
94
|
+
- Attitude: ${npc.attitude}
|
|
95
|
+
- Narrative Role: ${npc.narrativeRole}
|
|
96
|
+
- Dialogue Hints: ${npc.dialogueHints.join("; ")}
|
|
97
|
+
${npc.secrets ? `- Secrets: ${npc.secrets.join("; ")}` : ""}
|
|
98
|
+
|
|
99
|
+
Available items for inventory:
|
|
100
|
+
${items.slice(0, 20).map(i => `- ${i.id}: ${i.name} (${i.kind})`).join("\n")}
|
|
101
|
+
|
|
102
|
+
Output a JSON object with the expanded NPC (include ALL original fields plus new ones):
|
|
103
|
+
{
|
|
104
|
+
"expandedNPC": {
|
|
105
|
+
"id": "${npc.id}",
|
|
106
|
+
"name": "${npc.name}",
|
|
107
|
+
"description": "${npc.description}",
|
|
108
|
+
"personality": "${npc.personality}",
|
|
109
|
+
"motivation": "${npc.motivation}",
|
|
110
|
+
"attitude": "${npc.attitude}",
|
|
111
|
+
"dialogueHints": ${JSON.stringify(npc.dialogueHints)},
|
|
112
|
+
"narrativeRole": "${npc.narrativeRole}",
|
|
113
|
+
"locations": ${JSON.stringify(npc.locations || [])},
|
|
114
|
+
"relationships": ${JSON.stringify(npc.relationships || {})},
|
|
115
|
+
"secrets": ${JSON.stringify(npc.secrets || [])},
|
|
116
|
+
"backstory": "Detailed backstory explaining their history and how they came to be who they are",
|
|
117
|
+
"combatStats": {
|
|
118
|
+
"hp": 10,
|
|
119
|
+
"armor": 0,
|
|
120
|
+
"abilities": { "STR": 0, "AGI": 0, "WIT": 0, "CON": 0 },
|
|
121
|
+
"attacks": [
|
|
122
|
+
{ "name": "Attack Name", "damage": "d6" }
|
|
123
|
+
]
|
|
124
|
+
},
|
|
125
|
+
"questHooks": [
|
|
126
|
+
"A quest or task they might offer",
|
|
127
|
+
"A problem they need help with",
|
|
128
|
+
"Information they could trade for a favor"
|
|
129
|
+
],
|
|
130
|
+
"inventory": ["item:id-from-list", "item:another-id"]
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
Notes:
|
|
135
|
+
- Backstory should be 2-4 sentences
|
|
136
|
+
- Include combatStats only if this NPC might fight (null otherwise)
|
|
137
|
+
- Quest hooks should connect to their motivation
|
|
138
|
+
- Inventory should be 2-5 appropriate items
|
|
139
|
+
|
|
140
|
+
Return ONLY the JSON object, no markdown formatting.`;
|
|
141
|
+
return {
|
|
142
|
+
prompt: {
|
|
143
|
+
system: systemPrompt,
|
|
144
|
+
user: userPrompt,
|
|
145
|
+
outputSchemaName: "ExpandedNPC",
|
|
146
|
+
},
|
|
147
|
+
stepId,
|
|
148
|
+
message: `NPC expansion initiated for ${npc.name}. Execute the prompt and call save_generation_result.`,
|
|
149
|
+
};
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
export const expandNPCTools = [expandNPCTool];
|
|
153
|
+
//# sourceMappingURL=npc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"npc.js","sourceRoot":"","sources":["../../../src/tools/expansion/npc.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Archetype Generation Tool
|
|
3
|
+
*
|
|
4
|
+
* Generates playable character archetypes based on the world seed.
|
|
5
|
+
*/
|
|
6
|
+
import type { MCPToolEntry } from "@mythxengine/types";
|
|
7
|
+
/**
|
|
8
|
+
* generate_archetypes tool
|
|
9
|
+
*/
|
|
10
|
+
export declare const generateArchetypesTool: MCPToolEntry;
|
|
11
|
+
export declare const archetypeTools: MCPToolEntry[];
|
|
12
|
+
//# sourceMappingURL=archetypes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"archetypes.d.ts","sourceRoot":"","sources":["../../../src/tools/generation/archetypes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,oBAAoB,CAAC;AAezE;;GAEG;AACH,eAAO,MAAM,sBAAsB,EAAE,YA+HpC,CAAC;AAEF,eAAO,MAAM,cAAc,gBAA2B,CAAC"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Archetype Generation Tool
|
|
3
|
+
*
|
|
4
|
+
* Generates playable character archetypes based on the world seed.
|
|
5
|
+
*/
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
import { randomUUID } from "crypto";
|
|
8
|
+
import { sessionManager, readManifest, writeManifest, addManifestStep, } from "../../state/manager.js";
|
|
9
|
+
import { buildRulesPromptSection, buildHPGuidelines } from "./rules-prompt.js";
|
|
10
|
+
const GenerateArchetypesInput = z.object({
|
|
11
|
+
sessionId: z.string(),
|
|
12
|
+
count: z.number().min(1).max(10).optional().describe("Number of archetypes to generate (default: from world seed)"),
|
|
13
|
+
focusOn: z.array(z.string()).optional().describe("Specific archetype seeds to focus on (by name)"),
|
|
14
|
+
});
|
|
15
|
+
/**
|
|
16
|
+
* generate_archetypes tool
|
|
17
|
+
*/
|
|
18
|
+
export const generateArchetypesTool = {
|
|
19
|
+
name: "generate_archetypes",
|
|
20
|
+
description: "Generate playable character archetypes based on the world seed. Returns a prompt for LLM execution.",
|
|
21
|
+
inputSchema: {
|
|
22
|
+
type: "object",
|
|
23
|
+
properties: {
|
|
24
|
+
sessionId: { type: "string", description: "Session ID" },
|
|
25
|
+
count: { type: "number", description: "Number of archetypes to generate (default: from world seed)" },
|
|
26
|
+
focusOn: { type: "array", items: { type: "string" }, description: "Specific archetype seeds to focus on (by name)" },
|
|
27
|
+
},
|
|
28
|
+
required: ["sessionId"],
|
|
29
|
+
},
|
|
30
|
+
handler: async (args) => {
|
|
31
|
+
const input = GenerateArchetypesInput.parse(args);
|
|
32
|
+
const session = await sessionManager.get(input.sessionId);
|
|
33
|
+
if (!session) {
|
|
34
|
+
throw new Error(`Session not found: ${input.sessionId}`);
|
|
35
|
+
}
|
|
36
|
+
if (!session.generation?.worldSeed) {
|
|
37
|
+
throw new Error("World seed not found. Call generate_world_seed first.");
|
|
38
|
+
}
|
|
39
|
+
const worldSeed = session.generation.worldSeed;
|
|
40
|
+
const stepId = randomUUID();
|
|
41
|
+
const archetypeSeeds = input.focusOn
|
|
42
|
+
? worldSeed.archetypeSeeds.filter(a => input.focusOn.includes(a.name))
|
|
43
|
+
: worldSeed.archetypeSeeds;
|
|
44
|
+
const count = input.count || archetypeSeeds.length;
|
|
45
|
+
// Record the generation step
|
|
46
|
+
session.generation.history.push({
|
|
47
|
+
id: stepId,
|
|
48
|
+
type: "archetypes",
|
|
49
|
+
startedAt: new Date().toISOString(),
|
|
50
|
+
completedAt: null,
|
|
51
|
+
status: "in_progress",
|
|
52
|
+
generatedIds: [],
|
|
53
|
+
});
|
|
54
|
+
session.generation.status = "generating";
|
|
55
|
+
await sessionManager.save(session);
|
|
56
|
+
// Update manifest
|
|
57
|
+
const manifest = await readManifest(input.sessionId);
|
|
58
|
+
if (manifest) {
|
|
59
|
+
addManifestStep(manifest, "archetypes", "archetypes.json");
|
|
60
|
+
manifest.status = "generating";
|
|
61
|
+
await writeManifest(input.sessionId, manifest);
|
|
62
|
+
}
|
|
63
|
+
// Build rules section from seed (uses defaults if no custom rules)
|
|
64
|
+
const rulesSection = buildRulesPromptSection(worldSeed.rules);
|
|
65
|
+
const hpGuidelines = buildHPGuidelines(worldSeed.rules);
|
|
66
|
+
const systemPrompt = `You are a character archetype designer for tabletop RPGs. Create compelling, balanced archetypes that fit the world's tone and offer distinct playstyles.
|
|
67
|
+
|
|
68
|
+
${rulesSection}
|
|
69
|
+
|
|
70
|
+
${hpGuidelines}
|
|
71
|
+
|
|
72
|
+
Design Guidelines:
|
|
73
|
+
- Ability modifiers should sum to approximately +2 total
|
|
74
|
+
- Each archetype needs 2 unique features
|
|
75
|
+
- Starting items should be 3-5 thematic items (reference by ID like "item:weapon-name")
|
|
76
|
+
- Playstyle guidance should help players understand the archetype's role
|
|
77
|
+
|
|
78
|
+
Output valid JSON only.`;
|
|
79
|
+
const userPrompt = `Generate ${count} playable character archetypes for this world:
|
|
80
|
+
|
|
81
|
+
World: ${worldSeed.name}
|
|
82
|
+
Tagline: ${worldSeed.tagline}
|
|
83
|
+
Tone: ${worldSeed.aesthetic.tone}
|
|
84
|
+
Themes: ${worldSeed.aesthetic.themes.join(", ")}
|
|
85
|
+
Core Conflict: ${worldSeed.coreConflict}
|
|
86
|
+
Lethality: ${worldSeed.settings.lethality}
|
|
87
|
+
Magic Level: ${worldSeed.settings.magicLevel}
|
|
88
|
+
|
|
89
|
+
Archetype seeds to develop:
|
|
90
|
+
${archetypeSeeds.map((a, i) => `${i + 1}. ${a.name}: ${a.concept}`).join("\n")}
|
|
91
|
+
|
|
92
|
+
Output a JSON object:
|
|
93
|
+
{
|
|
94
|
+
"archetypes": [
|
|
95
|
+
{
|
|
96
|
+
"id": "archetype:slug-name",
|
|
97
|
+
"name": "Archetype Name",
|
|
98
|
+
"tagline": "Short hook",
|
|
99
|
+
"description": "2-3 sentences describing the archetype",
|
|
100
|
+
"starting": {
|
|
101
|
+
"abilities": { "STR": 0, "AGI": 0, "WIT": 0, "CON": 0 },
|
|
102
|
+
"hp": 10,
|
|
103
|
+
"maxHp": 10
|
|
104
|
+
},
|
|
105
|
+
"startingItems": ["item:weapon-id", "item:armor-id", "item:gear-id"],
|
|
106
|
+
"features": [
|
|
107
|
+
{ "id": "feature:feature-id", "name": "Feature Name", "description": "What it does" }
|
|
108
|
+
],
|
|
109
|
+
"playstyle": "How to play this archetype effectively",
|
|
110
|
+
"background": "Lore and backstory for this archetype",
|
|
111
|
+
"flavor": "Evocative one-liner"
|
|
112
|
+
}
|
|
113
|
+
]
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
Return ONLY the JSON object, no markdown formatting.`;
|
|
117
|
+
return {
|
|
118
|
+
prompt: {
|
|
119
|
+
system: systemPrompt,
|
|
120
|
+
user: userPrompt,
|
|
121
|
+
outputSchemaName: "WorldArchetype[]",
|
|
122
|
+
},
|
|
123
|
+
stepId,
|
|
124
|
+
message: `Archetype generation initiated for ${count} archetypes. Execute the prompt and call save_generation_result.`,
|
|
125
|
+
};
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
export const archetypeTools = [generateArchetypesTool];
|
|
129
|
+
//# sourceMappingURL=archetypes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"archetypes.js","sourceRoot":"","sources":["../../../src/tools/generation/archetypes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Arc Generation Tool
|
|
3
|
+
*
|
|
4
|
+
* Generates story arcs that group related situations around a central tension.
|
|
5
|
+
* Arcs provide structure for multi-session storylines.
|
|
6
|
+
*/
|
|
7
|
+
import type { MCPToolEntry } from "@mythxengine/types";
|
|
8
|
+
/**
|
|
9
|
+
* generate_arcs tool
|
|
10
|
+
*/
|
|
11
|
+
export declare const generateArcsTool: MCPToolEntry;
|
|
12
|
+
export declare const arcTools: MCPToolEntry[];
|
|
13
|
+
//# sourceMappingURL=arcs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arcs.d.ts","sourceRoot":"","sources":["../../../src/tools/generation/arcs.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAcvD;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,YAgM9B,CAAC;AAEF,eAAO,MAAM,QAAQ,gBAAqB,CAAC"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Arc Generation Tool
|
|
3
|
+
*
|
|
4
|
+
* Generates story arcs that group related situations around a central tension.
|
|
5
|
+
* Arcs provide structure for multi-session storylines.
|
|
6
|
+
*/
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
import { randomUUID } from "crypto";
|
|
9
|
+
import { sessionManager, readManifest, writeManifest, addManifestStep, } from "../../state/manager.js";
|
|
10
|
+
const GenerateArcsInput = z.object({
|
|
11
|
+
sessionId: z.string(),
|
|
12
|
+
count: z.number().min(1).max(10).optional().describe("Number of arcs to generate (default: from world seed or 2)"),
|
|
13
|
+
focusOn: z.array(z.string()).optional().describe("Specific arc seeds to focus on (by name)"),
|
|
14
|
+
});
|
|
15
|
+
/**
|
|
16
|
+
* generate_arcs tool
|
|
17
|
+
*/
|
|
18
|
+
export const generateArcsTool = {
|
|
19
|
+
name: "generate_arcs",
|
|
20
|
+
description: "Generate story arcs that group situations around central tensions. Returns a prompt for LLM execution.",
|
|
21
|
+
inputSchema: {
|
|
22
|
+
type: "object",
|
|
23
|
+
properties: {
|
|
24
|
+
sessionId: { type: "string", description: "Session ID" },
|
|
25
|
+
count: { type: "number", description: "Number of arcs to generate" },
|
|
26
|
+
focusOn: { type: "array", items: { type: "string" }, description: "Specific arc seeds to focus on" },
|
|
27
|
+
},
|
|
28
|
+
required: ["sessionId"],
|
|
29
|
+
},
|
|
30
|
+
handler: async (args) => {
|
|
31
|
+
const input = GenerateArcsInput.parse(args);
|
|
32
|
+
const session = await sessionManager.get(input.sessionId);
|
|
33
|
+
if (!session) {
|
|
34
|
+
throw new Error(`Session not found: ${input.sessionId}`);
|
|
35
|
+
}
|
|
36
|
+
if (!session.generation?.worldSeed) {
|
|
37
|
+
throw new Error("World seed not found. Call generate_world_seed first.");
|
|
38
|
+
}
|
|
39
|
+
const worldSeed = session.generation.worldSeed;
|
|
40
|
+
// Get existing situations for references
|
|
41
|
+
const existingSituations = session.generation.generatedContent.situations;
|
|
42
|
+
if (existingSituations.length === 0) {
|
|
43
|
+
throw new Error("No situations found. Call generate_situations first to create situations to group into arcs.");
|
|
44
|
+
}
|
|
45
|
+
const stepId = randomUUID();
|
|
46
|
+
const arcSeeds = input.focusOn && worldSeed.arcSeeds
|
|
47
|
+
? worldSeed.arcSeeds.filter(a => input.focusOn.includes(a.name))
|
|
48
|
+
: worldSeed.arcSeeds || [];
|
|
49
|
+
const count = input.count || arcSeeds.length || 2;
|
|
50
|
+
// Record the generation step
|
|
51
|
+
session.generation.history.push({
|
|
52
|
+
id: stepId,
|
|
53
|
+
type: "arcs",
|
|
54
|
+
startedAt: new Date().toISOString(),
|
|
55
|
+
completedAt: null,
|
|
56
|
+
status: "in_progress",
|
|
57
|
+
generatedIds: [],
|
|
58
|
+
});
|
|
59
|
+
session.generation.status = "generating";
|
|
60
|
+
await sessionManager.save(session);
|
|
61
|
+
// Update manifest
|
|
62
|
+
const manifest = await readManifest(input.sessionId);
|
|
63
|
+
if (manifest) {
|
|
64
|
+
addManifestStep(manifest, "arcs", "arcs.json");
|
|
65
|
+
manifest.status = "generating";
|
|
66
|
+
await writeManifest(input.sessionId, manifest);
|
|
67
|
+
}
|
|
68
|
+
const systemPrompt = `You are a narrative architect for tabletop RPGs. You create story arcs that organize situations into meaningful campaigns.
|
|
69
|
+
|
|
70
|
+
An ARC groups related situations around a central tension. Arcs provide:
|
|
71
|
+
- Structure for pacing (funnel, layer-cake, hub-spoke, chain, web)
|
|
72
|
+
- Clear opposing forces and conflicts
|
|
73
|
+
- Resolution patterns for satisfying conclusions
|
|
74
|
+
- GM guidance for running the arc
|
|
75
|
+
|
|
76
|
+
Arc Structure Types:
|
|
77
|
+
- FUNNEL: Multiple entry points that narrow toward a single climax
|
|
78
|
+
- LAYER_CAKE: Situations unlock in layers (solve layer 1 to access layer 2)
|
|
79
|
+
- HUB_SPOKE: Central hub situation with satellite situations
|
|
80
|
+
- CHAIN: Linear progression from start to finish
|
|
81
|
+
- WEB: Interconnected without clear structure
|
|
82
|
+
|
|
83
|
+
Output valid JSON only.`;
|
|
84
|
+
const situationList = existingSituations.map(s => `- ${s.id}: ${s.name} - ${s.description.substring(0, 100)}...${s.layer !== undefined ? ` (layer ${s.layer})` : ""}`).join("\n");
|
|
85
|
+
const userPrompt = `Generate ${count} story arc(s) for this world:
|
|
86
|
+
|
|
87
|
+
World: ${worldSeed.name}
|
|
88
|
+
Tone: ${worldSeed.aesthetic.tone}
|
|
89
|
+
Themes: ${worldSeed.aesthetic.themes.join(", ")}
|
|
90
|
+
Core Conflict: ${worldSeed.coreConflict}
|
|
91
|
+
|
|
92
|
+
${arcSeeds.length > 0 ? `Arc seeds to develop:\n${arcSeeds.slice(0, count).map((a, i) => `${i + 1}. ${a.name}: ${a.concept}${a.structure ? ` (structure: ${a.structure})` : ""}`).join("\n")}` : "Create arcs that explore the core conflict from different angles."}
|
|
93
|
+
|
|
94
|
+
Existing Situations to organize into arcs:
|
|
95
|
+
${situationList}
|
|
96
|
+
|
|
97
|
+
NPCs available for key roles:
|
|
98
|
+
${worldSeed.npcSeeds.map(n => `- ${n.name}: ${n.concept}`).join("\n")}
|
|
99
|
+
|
|
100
|
+
Output a JSON object:
|
|
101
|
+
{
|
|
102
|
+
"arcs": [
|
|
103
|
+
{
|
|
104
|
+
"id": "arc:slug-name",
|
|
105
|
+
"name": "Arc Name",
|
|
106
|
+
"description": "Overview of this storyline",
|
|
107
|
+
|
|
108
|
+
"tension": {
|
|
109
|
+
"centralConflict": "The core conflict of this arc",
|
|
110
|
+
"source": "Where the conflict originates",
|
|
111
|
+
"opposingForces": [
|
|
112
|
+
{
|
|
113
|
+
"name": "Force Name",
|
|
114
|
+
"goal": "What they want",
|
|
115
|
+
"factionId": "faction:id-if-applicable"
|
|
116
|
+
}
|
|
117
|
+
],
|
|
118
|
+
"urgency": "Why this matters now"
|
|
119
|
+
},
|
|
120
|
+
|
|
121
|
+
"situationIds": ["situation:id-1", "situation:id-2"],
|
|
122
|
+
|
|
123
|
+
"structure": {
|
|
124
|
+
"type": "funnel|layer_cake|hub_spoke|chain|web",
|
|
125
|
+
"layers": {
|
|
126
|
+
"situation:id-1": 1,
|
|
127
|
+
"situation:id-2": 2
|
|
128
|
+
},
|
|
129
|
+
"entryPoints": ["situation:entry-1"],
|
|
130
|
+
"climax": "situation:climax-id",
|
|
131
|
+
"hub": "situation:hub-id",
|
|
132
|
+
"suggestedOrder": ["situation:first", "situation:second"]
|
|
133
|
+
},
|
|
134
|
+
|
|
135
|
+
"resolution": {
|
|
136
|
+
"patterns": [
|
|
137
|
+
{
|
|
138
|
+
"name": "Victory Pattern",
|
|
139
|
+
"description": "How the arc concludes positively",
|
|
140
|
+
"triggerConditions": ["All antagonists defeated", "Key artifact secured"]
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"name": "Pyrrhic Victory",
|
|
144
|
+
"description": "Win at a cost",
|
|
145
|
+
"triggerConditions": ["Main threat stopped but ally lost"]
|
|
146
|
+
}
|
|
147
|
+
],
|
|
148
|
+
"unlocksArcs": ["arc:sequel-arc-id"],
|
|
149
|
+
"worldChanges": ["Major change 1", "Major change 2"]
|
|
150
|
+
},
|
|
151
|
+
|
|
152
|
+
"themes": ["Theme 1", "Theme 2"],
|
|
153
|
+
|
|
154
|
+
"gmGuidance": {
|
|
155
|
+
"introduction": "How to introduce this arc to players",
|
|
156
|
+
"pacing": "Advice on running this arc over multiple sessions",
|
|
157
|
+
"keyNpcs": ["npc:key-character-1", "npc:key-character-2"],
|
|
158
|
+
"atmosphere": "The feel and mood to maintain"
|
|
159
|
+
},
|
|
160
|
+
|
|
161
|
+
"status": "dormant"
|
|
162
|
+
}
|
|
163
|
+
]
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
IMPORTANT:
|
|
167
|
+
- Reference actual situation IDs from the existing situations list
|
|
168
|
+
- Choose appropriate structure type for the arc's pacing needs
|
|
169
|
+
- Include multiple resolution patterns for player agency
|
|
170
|
+
- Key NPCs should drive the narrative
|
|
171
|
+
- World changes should be meaningful consequences
|
|
172
|
+
|
|
173
|
+
Return ONLY the JSON object, no markdown formatting.`;
|
|
174
|
+
return {
|
|
175
|
+
prompt: {
|
|
176
|
+
system: systemPrompt,
|
|
177
|
+
user: userPrompt,
|
|
178
|
+
outputSchemaName: "WorldArc[]",
|
|
179
|
+
},
|
|
180
|
+
stepId,
|
|
181
|
+
message: `Arc generation initiated for ${count} arc(s). Execute the prompt and call save_generation_result.`,
|
|
182
|
+
};
|
|
183
|
+
},
|
|
184
|
+
};
|
|
185
|
+
export const arcTools = [generateArcsTool];
|
|
186
|
+
//# sourceMappingURL=arcs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arcs.js","sourceRoot":"","sources":["../../../src/tools/generation/arcs.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEpC,OAAO,EACL,cAAc,EACd,YAAY,EACZ,aAAa,EACb,eAAe,GAChB,MAAM,wBAAwB,CAAC;AAEhC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,4DAA4D,CAAC;IAClH,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,0CAA0C,CAAC;CAC7F,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAiB;IAC5C,IAAI,EAAE,eAAe;IACrB,WAAW,EAAE,wGAAwG;IACrH,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,YAAY,EAAE;YACxD,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,4BAA4B,EAAE;YACpE,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,WAAW,EAAE,gCAAgC,EAAE;SACrG;QACD,QAAQ,EAAE,CAAC,WAAW,CAAC;KACxB;IACD,OAAO,EAAE,KAAK,EAAE,IAAa,EAAE,EAAE;QAC/B,MAAM,KAAK,GAAG,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAE5C,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAC1D,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,sBAAsB,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;QAC3D,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,SAAS,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;QAC3E,CAAC;QAED,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,SAOpC,CAAC;QAEF,yCAAyC;QACzC,MAAM,kBAAkB,GAAG,OAAO,CAAC,UAAU,CAAC,gBAAgB,CAAC,UAK7D,CAAC;QAEH,IAAI,kBAAkB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CAAC,8FAA8F,CAAC,CAAC;QAClH,CAAC;QAED,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,IAAI,SAAS,CAAC,QAAQ;YAClD,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,OAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACjE,CAAC,CAAC,SAAS,CAAC,QAAQ,IAAI,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,QAAQ,CAAC,MAAM,IAAI,CAAC,CAAC;QAElD,6BAA6B;QAC7B,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC;YAC9B,EAAE,EAAE,MAAM;YACV,IAAI,EAAE,MAAM;YACZ,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,WAAW,EAAE,IAAI;YACjB,MAAM,EAAE,aAAa;YACrB,YAAY,EAAE,EAAE;SACjB,CAAC,CAAC;QACH,OAAO,CAAC,UAAU,CAAC,MAAM,GAAG,YAAY,CAAC;QACzC,MAAM,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAEnC,kBAAkB;QAClB,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACrD,IAAI,QAAQ,EAAE,CAAC;YACb,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;YAC/C,QAAQ,CAAC,MAAM,GAAG,YAAY,CAAC;YAC/B,MAAM,aAAa,CAAC,KAAK,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QACjD,CAAC;QAED,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;wBAeD,CAAC;QAErB,MAAM,aAAa,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAC/C,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACpH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEb,MAAM,UAAU,GAAG,YAAY,KAAK;;SAE/B,SAAS,CAAC,IAAI;QACf,SAAS,CAAC,SAAS,CAAC,IAAI;UACtB,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;iBAC9B,SAAS,CAAC,YAAY;;EAErC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,0BAA0B,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,mEAAmE;;;EAGlQ,aAAa;;;EAGb,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qDA2EhB,CAAC;QAElD,OAAO;YACL,MAAM,EAAE;gBACN,MAAM,EAAE,YAAY;gBACpB,IAAI,EAAE,UAAU;gBAChB,gBAAgB,EAAE,YAAY;aAC/B;YACD,MAAM;YACN,OAAO,EAAE,gCAAgC,KAAK,8DAA8D;SAC7G,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,gBAAgB,CAAC,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Encounter Generation Tool
|
|
3
|
+
*
|
|
4
|
+
* Generates encounters based on the world seed.
|
|
5
|
+
*/
|
|
6
|
+
import type { MCPToolEntry } from "@mythxengine/types";
|
|
7
|
+
/**
|
|
8
|
+
* generate_encounters tool
|
|
9
|
+
*/
|
|
10
|
+
export declare const generateEncountersTool: MCPToolEntry;
|
|
11
|
+
export declare const encounterTools: MCPToolEntry[];
|
|
12
|
+
//# sourceMappingURL=encounters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encounters.d.ts","sourceRoot":"","sources":["../../../src/tools/generation/encounters.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,oBAAoB,CAAC;AAezE;;GAEG;AACH,eAAO,MAAM,sBAAsB,EAAE,YA0KpC,CAAC;AAEF,eAAO,MAAM,cAAc,gBAA2B,CAAC"}
|