manage_aura
Create, track, and apply D&D 5e aura effects like Spirit Guardians to targets within range, handling damage, healing, conditions, and saving throws.
Instructions
Manage D&D 5e aura effects (Spirit Guardians, Aura of Protection, etc.). Operations: create (new aura), list (active auras), process (apply effects to targets in range), remove (end aura). Supports damage, healing, conditions, and saving throws.
Tool call template
This tool declares no required parameters. Add optional parameters from the input schema as needed.
{
"id": 1,
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"arguments": {},
"name": "manage_aura"
}
}Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| operation | No | ||
| ownerId | No | ||
| spellName | No | ||
| radius | No | ||
| duration | No | ||
| damage | No | ||
| damageType | No | ||
| healing | No | ||
| effect | No | ||
| condition | No | ||
| saveDC | No | ||
| saveAbility | No | ||
| halfOnSave | No | ||
| affectsEnemies | No | ||
| affectsAllies | No | ||
| auraId | No | ||
| reason | No | ||
| targets | No | ||
| decrementDuration | No | ||
| manualDamageRolls | No | ||
| manualHealingRolls | No | ||
| manualSaveRolls | No |
Implementation Reference
- src/modules/magic.ts:633-647 (handler)Main handler function for the manage_aura tool. Dispatches to operation-specific handlers: create, list, remove, process.
export function manageAura(input: ManageAuraInput): string { switch (input.operation) { case 'create': return handleCreateAura(input); case 'list': return handleListAuras(input); case 'remove': return handleRemoveAura(input); case 'process': return handleProcessAura(input); default: const _exhaustive: never = input; throw new Error(`Unknown operation: ${(_exhaustive as { operation: string }).operation}`); } } - src/modules/magic.ts:592-599 (schema)Zod schema for manage_aura input validation. Union of schemas for create, list, remove, process operations.
export const manageAuraSchema = z.union([ createAuraSchema, listAuraSchema, removeAuraSchema, processAuraSchema, ]); export type ManageAuraInput = z.infer<typeof manageAuraSchema>; - src/registry.ts:980-998 (registration)Tool registration in the MCP registry. Defines name, description, input schema, and handler wrapper that validates args and calls manageAura.
manage_aura: { name: 'manage_aura', description: 'Manage D&D 5e aura effects (Spirit Guardians, Aura of Protection, etc.). Operations: create (new aura), list (active auras), process (apply effects to targets in range), remove (end aura). Supports damage, healing, conditions, and saving throws.', inputSchema: toJsonSchema(manageAuraSchema), handler: async (args) => { try { const validated = manageAuraSchema.parse(args); const result = manageAura(validated); return success(result); } catch (err) { if (err instanceof z.ZodError) { const messages = err.errors.map(e => `${e.path.join('.')}: ${e.message}`).join(', '); return error(`Validation failed: ${messages}`); } const message = err instanceof Error ? err.message : String(err); return error(message); } }, }, - src/modules/magic.ts:653-724 (helper)Helper: Creates a new aura with generated ID and stores it in auraStore. Formats ASCII output with aura details.
function handleCreateAura(input: z.infer<typeof createAuraSchema>): string { const id = `aura-${randomUUID().slice(0, 8)}`; const content: string[] = []; const aura: ExtendedAuraState = { id, ownerId: input.ownerId, spellName: input.spellName, radius: input.radius, duration: input.duration, damage: input.damage, damageType: input.damageType, healing: input.healing, effect: input.effect, condition: input.condition, saveDC: input.saveDC, saveAbility: input.saveAbility, halfOnSave: input.halfOnSave, affectsEnemies: input.affectsEnemies, affectsAllies: input.affectsAllies, }; auraStore.set(id, aura); content.push(centerText('AURA CREATED', DISPLAY_WIDTH)); content.push(''); content.push(`ID: ${id}`); content.push(`Spell: ${input.spellName}`); content.push(`Owner: ${input.ownerId}`); content.push(`Radius: ${input.radius} ft`); if (input.duration !== undefined) { content.push(`Duration: ${input.duration} rounds`); } content.push(''); content.push(BOX.LIGHT.H.repeat(DISPLAY_WIDTH)); if (input.damage) { content.push(''); content.push(`Damage: ${input.damage} ${input.damageType || ''}`); if (input.saveDC && input.saveAbility) { content.push(`Save: DC ${input.saveDC} ${input.saveAbility.toUpperCase()}`); if (input.halfOnSave) { content.push('Half damage on save'); } } } if (input.healing) { content.push(''); content.push(`Healing: ${input.healing}`); } if (input.condition) { content.push(''); content.push(`Applies: ${input.condition}`); } if (input.affectsEnemies !== undefined || input.affectsAllies !== undefined) { content.push(''); const targets: string[] = []; if (input.affectsEnemies) targets.push('enemies'); if (input.affectsAllies) targets.push('allies'); if (targets.length === 0) { targets.push(input.affectsEnemies === false ? 'allies only' : 'all'); } content.push(`Affects: ${targets.join(', ')}`); } return createBox('AURA CREATED', content); } - src/modules/magic.ts:536-647 (helper)In-memory storage for auras, used by manage_aura operations.
const auraStore = new Map<string, ExtendedAuraState>(); // ============================================================ // AURA SCHEMAS // ============================================================ const auraTargetSchema = z.object({ targetId: z.string(), distance: z.number(), saveModifier: z.number().optional(), }); const manualSaveRollSchema = z.object({ targetId: z.string(), roll: z.number().min(1).max(20), }); const createAuraSchema = z.object({ operation: z.literal('create'), ownerId: z.string(), spellName: z.string(), radius: z.number().min(1), duration: z.number().optional(), damage: z.string().optional(), damageType: DamageTypeSchema.optional(), healing: z.string().optional(), effect: z.string().optional(), condition: ConditionSchema.optional(), saveDC: z.number().optional(), saveAbility: AbilitySchema.optional(), halfOnSave: z.boolean().optional(), affectsEnemies: z.boolean().optional(), affectsAllies: z.boolean().optional(), }); const listAuraSchema = z.object({ operation: z.literal('list'), ownerId: z.string().optional(), }); const removeAuraSchema = z.object({ operation: z.literal('remove'), auraId: z.string(), reason: z.string().optional(), }); const processAuraSchema = z.object({ operation: z.literal('process'), auraId: z.string(), targets: z.array(auraTargetSchema), decrementDuration: z.boolean().optional(), manualDamageRolls: z.array(z.number()).optional(), manualHealingRolls: z.array(z.number()).optional(), manualSaveRolls: z.array(manualSaveRollSchema).optional(), }); export const manageAuraSchema = z.union([ createAuraSchema, listAuraSchema, removeAuraSchema, processAuraSchema, ]); export type ManageAuraInput = z.infer<typeof manageAuraSchema>; // ============================================================ // AURA PUBLIC API // ============================================================ /** * Get an aura by ID. */ export function getAura(auraId: string): ExtendedAuraState | undefined { return auraStore.get(auraId); } /** * Get all auras for an owner. */ export function getAurasForOwner(ownerId: string): ExtendedAuraState[] { return Array.from(auraStore.values()).filter(a => a.ownerId === ownerId); } /** * Clear all auras (for testing). */ export function clearAllAuras(): void { auraStore.clear(); } // ============================================================ // AURA HANDLER // ============================================================ /** * Main handler for the manage_aura tool. */ export function manageAura(input: ManageAuraInput): string { switch (input.operation) { case 'create': return handleCreateAura(input); case 'list': return handleListAuras(input); case 'remove': return handleRemoveAura(input); case 'process': return handleProcessAura(input); default: const _exhaustive: never = input; throw new Error(`Unknown operation: ${(_exhaustive as { operation: string }).operation}`); } }