run-dmcp 0.4.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.
@@ -2,7 +2,11 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { type Mechanic } from "./timeline/resolve.js";
3
3
  import { type RenderVocabulary } from "./timeline/render.js";
4
4
  export declare const SERVER_NAME = "dmcp";
5
- export declare const SERVER_VERSION = "0.3.0";
5
+ /** What the server tells a client it is, in the MCP handshake. Kept equal to
6
+ * the published package version by src/__tests__/serverVersion.test.ts --
7
+ * this said "0.3.0" for the whole of 0.4.0, because a release bumps
8
+ * package.json and nothing was watching this. */
9
+ export declare const SERVER_VERSION = "0.5.0";
6
10
  /**
7
11
  * Build an MCP server with every CORE tool, resource and prompt this engine
8
12
  * serves -- entities, facts, events, the timeline, and the entity/property
@@ -41,7 +41,11 @@ import { registerRenderTools } from "./register/render.js";
41
41
  import { createResolver } from "./timeline/resolve.js";
42
42
  import { createStateRenderer } from "./timeline/render.js";
43
43
  export const SERVER_NAME = "dmcp";
44
- export const SERVER_VERSION = "0.3.0";
44
+ /** What the server tells a client it is, in the MCP handshake. Kept equal to
45
+ * the published package version by src/__tests__/serverVersion.test.ts --
46
+ * this said "0.3.0" for the whole of 0.4.0, because a release bumps
47
+ * package.json and nothing was watching this. */
48
+ export const SERVER_VERSION = "0.5.0";
45
49
  /**
46
50
  * Build an MCP server with every CORE tool, resource and prompt this engine
47
51
  * serves -- entities, facts, events, the timeline, and the entity/property
@@ -3,7 +3,7 @@ import * as characterTools from "../tools/character.js";
3
3
  import * as worldTools from "../tools/world.js";
4
4
  import * as inventoryTools from "../tools/inventory.js";
5
5
  import * as narrativeTools from "../tools/narrative.js";
6
- import { LIMITS } from "../utils/validation.js";
6
+ import { LIMITS, validatedSchemas } from "../utils/validation.js";
7
7
  import { ANNOTATIONS } from "../utils/tool-annotations.js";
8
8
  import { imageGenSchema, voiceSchema } from "../schemas/index.js";
9
9
  // Multi-entity workflow tools over entity/property concepts -- characters,
@@ -18,7 +18,7 @@ export function registerBatchTools(server) {
18
18
  server.registerTool("batch_create_npcs", {
19
19
  description: "Create multiple NPCs at once. Use this when populating a location with several characters. Returns all created characters.",
20
20
  inputSchema: {
21
- gameId: z.string().describe("The game ID"),
21
+ gameId: validatedSchemas.id.describe("The game ID"),
22
22
  npcs: z
23
23
  .array(z.object({
24
24
  name: z.string().min(1).max(LIMITS.NAME_MAX).describe("NPC name"),
@@ -28,10 +28,10 @@ export function registerBatchTools(server) {
28
28
  .object({
29
29
  health: z.number().optional(),
30
30
  maxHealth: z.number().optional(),
31
- conditions: z.array(z.string()).optional(),
31
+ conditions: validatedSchemas.stringArray.optional(),
32
32
  })
33
33
  .optional(),
34
- locationId: z.string().optional().describe("Starting location"),
34
+ locationId: validatedSchemas.id.optional().describe("Starting location"),
35
35
  notes: z.string().max(LIMITS.CONTENT_MAX).optional(),
36
36
  voice: voiceSchema.optional(),
37
37
  imageGen: imageGenSchema.optional(),
@@ -105,12 +105,13 @@ export function registerBatchTools(server) {
105
105
  server.registerTool("scene_transition", {
106
106
  description: "Complete scene transition in one call: moves specified characters to a new location and logs a narrative event. Perfect for moving between scenes.",
107
107
  inputSchema: {
108
- gameId: z.string().describe("The game ID"),
108
+ gameId: validatedSchemas.id.describe("The game ID"),
109
109
  characterIds: z
110
- .array(z.string())
110
+ .array(validatedSchemas.id)
111
111
  .min(1)
112
+ .max(LIMITS.ARRAY_MAX)
112
113
  .describe("Characters to move to the new scene"),
113
- destinationId: z.string().describe("Destination location ID"),
114
+ destinationId: validatedSchemas.id.describe("Destination location ID"),
114
115
  narrativeDescription: z
115
116
  .string()
116
117
  .max(LIMITS.DESCRIPTION_MAX)
@@ -165,7 +166,7 @@ export function registerBatchTools(server) {
165
166
  server.registerTool("get_character_context", {
166
167
  description: "Get comprehensive character context in one call: character details, inventory, and current location info. Reduces multiple tool calls to one.",
167
168
  inputSchema: {
168
- characterId: z.string().describe("The character ID"),
169
+ characterId: validatedSchemas.id.describe("The character ID"),
169
170
  },
170
171
  annotations: ANNOTATIONS.READ_ONLY,
171
172
  }, async ({ characterId }) => {
@@ -219,8 +220,8 @@ export function registerBatchTools(server) {
219
220
  server.registerTool("get_location_context", {
220
221
  description: "Get comprehensive location context in one call: location details, present characters, and items here. Reduces multiple tool calls to one.",
221
222
  inputSchema: {
222
- locationId: z.string().describe("The location ID"),
223
- gameId: z.string().describe("The game ID (needed for character lookup)"),
223
+ locationId: validatedSchemas.id.describe("The location ID"),
224
+ gameId: validatedSchemas.id.describe("The game ID (needed for character lookup)"),
224
225
  },
225
226
  annotations: ANNOTATIONS.READ_ONLY,
226
227
  }, async ({ locationId, gameId }) => {
@@ -1,7 +1,7 @@
1
1
  import { z } from "zod";
2
2
  import * as characterTools from "../tools/character.js";
3
3
  import { imageGenSchema, voiceSchema } from "../schemas/index.js";
4
- import { LIMITS } from "../utils/validation.js";
4
+ import { LIMITS, validatedSchemas } from "../utils/validation.js";
5
5
  import { ANNOTATIONS } from "../utils/tool-annotations.js";
6
6
  import { characterOutputSchema, characterStatusSchema, conditionModifyOutputSchema, } from "../utils/output-schemas.js";
7
7
  import { verbositySchema, applyVerbosity } from "../utils/verbosity.js";
@@ -44,7 +44,7 @@ export function registerCharacterTools(server) {
44
44
  server.registerTool("get_character", {
45
45
  description: "Get character details",
46
46
  inputSchema: {
47
- characterId: z.string().describe("The character ID"),
47
+ characterId: validatedSchemas.id.describe("The character ID"),
48
48
  },
49
49
  outputSchema: characterOutputSchema,
50
50
  annotations: ANNOTATIONS.READ_ONLY,
@@ -67,13 +67,13 @@ export function registerCharacterTools(server) {
67
67
  server.registerTool("update_character", {
68
68
  description: "Update character attributes, skills, status, or voice",
69
69
  inputSchema: {
70
- characterId: z.string().describe("The character ID"),
71
- name: z.string().optional().describe("New name"),
70
+ characterId: validatedSchemas.id.describe("The character ID"),
71
+ name: validatedSchemas.token.optional().describe("New name"),
72
72
  attributes: z.record(z.string(), z.number()).optional().describe("Attribute updates"),
73
73
  skills: z.record(z.string(), z.number()).optional().describe("Skill updates"),
74
74
  status: z.record(z.string(), z.unknown()).optional().describe("Status updates"),
75
- locationId: z.string().optional().describe("New location"),
76
- notes: z.string().optional().describe("Notes update"),
75
+ locationId: validatedSchemas.id.optional().describe("New location"),
76
+ notes: validatedSchemas.content.optional().describe("Notes update"),
77
77
  voice: voiceSchema.nullable().optional().describe("Voice characteristics (null to remove)"),
78
78
  imageGen: imageGenSchema.nullable().optional().describe("Image generation metadata (null to remove)"),
79
79
  },
@@ -98,9 +98,9 @@ export function registerCharacterTools(server) {
98
98
  server.registerTool("list_characters", {
99
99
  description: "List characters in a game. Use verbosity to control response size: 'minimal' for quick lookups (id/name only), 'standard' for common fields, 'full' for all details.",
100
100
  inputSchema: {
101
- gameId: z.string().describe("The game ID"),
101
+ gameId: validatedSchemas.id.describe("The game ID"),
102
102
  isPlayer: z.boolean().optional().describe("Filter by player/NPC"),
103
- locationId: z.string().optional().describe("Filter by location"),
103
+ locationId: validatedSchemas.id.optional().describe("Filter by location"),
104
104
  verbosity: verbositySchema,
105
105
  },
106
106
  outputSchema: {
@@ -128,8 +128,8 @@ export function registerCharacterTools(server) {
128
128
  server.registerTool("move_character", {
129
129
  description: "Move a character to a different location",
130
130
  inputSchema: {
131
- characterId: z.string().describe("The character ID"),
132
- locationId: z.string().describe("The destination location ID"),
131
+ characterId: validatedSchemas.id.describe("The character ID"),
132
+ locationId: validatedSchemas.id.describe("The destination location ID"),
133
133
  },
134
134
  outputSchema: {
135
135
  success: z.boolean(),
@@ -163,7 +163,7 @@ export function registerCharacterTools(server) {
163
163
  server.registerTool("modify_health", {
164
164
  description: "Modify a character's health. Use mode 'damage' to reduce health, or 'heal' to restore health.",
165
165
  inputSchema: {
166
- characterId: z.string().describe("The character ID"),
166
+ characterId: validatedSchemas.id.describe("The character ID"),
167
167
  mode: z.enum(["damage", "heal"]).describe("'damage' to reduce health, 'heal' to restore health"),
168
168
  amount: z.number().describe("Amount of damage or healing"),
169
169
  },
@@ -201,7 +201,7 @@ export function registerCharacterTools(server) {
201
201
  server.registerTool("modify_conditions", {
202
202
  description: "Add and/or remove conditions from a character in a single call. More efficient than separate add/remove calls.",
203
203
  inputSchema: {
204
- characterId: z.string().describe("The character ID"),
204
+ characterId: validatedSchemas.id.describe("The character ID"),
205
205
  add: z.array(z.string().max(100)).max(LIMITS.ARRAY_MAX).optional().describe("Conditions to add"),
206
206
  remove: z.array(z.string().max(100)).max(LIMITS.ARRAY_MAX).optional().describe("Conditions to remove"),
207
207
  },
@@ -244,8 +244,8 @@ export function registerCharacterTools(server) {
244
244
  server.registerTool("get_character_by_name", {
245
245
  description: "Look up a character by name within a game. Supports exact, partial, and fuzzy matching. Returns the best match or an error if no reasonable match found.",
246
246
  inputSchema: {
247
- gameId: z.string().describe("The game ID to search within"),
248
- name: z.string().describe("Character name to search for (case-insensitive)"),
247
+ gameId: validatedSchemas.id.describe("The game ID to search within"),
248
+ name: validatedSchemas.token.describe("Character name to search for (case-insensitive)"),
249
249
  },
250
250
  outputSchema: characterOutputSchema,
251
251
  annotations: ANNOTATIONS.READ_ONLY,
@@ -268,7 +268,7 @@ export function registerCharacterTools(server) {
268
268
  server.registerTool("list_character_summaries", {
269
269
  description: "List characters with quick-identification summaries. Use this to help identify characters by appearance before looking up their full details. More efficient than loading full character data when you just need to identify who's who.",
270
270
  inputSchema: {
271
- gameId: z.string().describe("The game ID"),
271
+ gameId: validatedSchemas.id.describe("The game ID"),
272
272
  },
273
273
  outputSchema: {
274
274
  summaries: z.array(z.object({
@@ -297,7 +297,7 @@ export function registerCharacterTools(server) {
297
297
  server.registerTool("delete_character", {
298
298
  description: "Delete a character permanently. This is IRREVERSIBLE and will remove the character and all associated data.",
299
299
  inputSchema: {
300
- characterId: z.string().describe("The character ID to delete"),
300
+ characterId: validatedSchemas.id.describe("The character ID to delete"),
301
301
  },
302
302
  outputSchema: {
303
303
  success: z.boolean(),