Skip to main content
Glama

synthesize_spell

Create custom spell effects in RPG sessions by proposing spell parameters, rolling Arcana checks with DC based on spell level and modifiers, and generating temporary magical outcomes or mishaps.

Instructions

Arcane Synthesis for improvised magic. Caster proposes a custom spell effect; Arcana check DC = 10 + (level × 2) + modifiers. Success creates temporary spell effect, failure may cause mishaps. Supports circumstance modifiers (ley lines, desperation, material components).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
encounterIdNo
casterIdYes
intentYes
proposedSpellYes
arcanaBonusNo
rollModeNo
manualRollNo
manualRollsNo
nearLeyLineNo
desperationBonusNo
materialComponentValueNo

Implementation Reference

  • Main handler function for the synthesize_spell tool. Performs Arcana check with DC calculation based on spell level and modifiers, resolves roll with advantage/disadvantage support, determines success/mishap/critical outcomes, and returns formatted ASCII output describing the improvised spell creation result.
    export function synthesizeSpell(input: SynthesizeSpellInput): string {
      const content: string[] = [];
      const {
        encounterId,
        casterId,
        intent,
        proposedSpell,
        arcanaBonus = 0,
        rollMode = 'normal',
        manualRoll,
        manualRolls,
        nearLeyLine,
        desperationBonus,
        materialComponentValue,
      } = input;
    
      // Calculate DC using helper function
      const { dc, modifiers: dcModifiers } = calculateSynthesisDC(
        proposedSpell.level,
        nearLeyLine,
        materialComponentValue
      );
    
      // Build header
      content.push(centerText('ARCANE SYNTHESIS', DISPLAY_WIDTH));
      content.push('');
      content.push(`Caster: ${casterId}`);
      if (encounterId) {
        content.push(`Encounter: ${encounterId}`);
      }
      content.push('');
      content.push(`Intent: "${intent}"`);
      content.push('');
      content.push(BOX.LIGHT.H.repeat(DISPLAY_WIDTH));
      content.push('');
    
      // Show proposed spell
      content.push(centerText('PROPOSED SPELL', DISPLAY_WIDTH));
      content.push('');
      content.push(`Name: ${proposedSpell.name}`);
      content.push(`Level: ${proposedSpell.level}`);
      content.push(`School: ${proposedSpell.school}`);
      content.push(`Range: ${proposedSpell.range} ft`);
    
      // Effect details
      content.push('');
      content.push(`Effect Type: ${proposedSpell.effect.type}`);
      if (proposedSpell.effect.damage) {
        content.push(`Damage: ${proposedSpell.effect.damage} ${proposedSpell.effect.damageType || ''}`);
      }
      if (proposedSpell.effect.healing) {
        content.push(`Healing: ${proposedSpell.effect.healing}`);
      }
      if (proposedSpell.effect.condition) {
        content.push(`Condition: ${proposedSpell.effect.condition}`);
      }
    
      // Area of effect
      if (proposedSpell.area) {
        content.push(`Area: ${proposedSpell.area.size} ft ${proposedSpell.area.shape}`);
      }
    
      // Saving throw
      if (proposedSpell.savingThrow) {
        content.push(`Save: DC ${proposedSpell.savingThrow.dc} ${proposedSpell.savingThrow.ability.toUpperCase()}`);
      }
    
      // Concentration and duration
      if (proposedSpell.concentration) {
        content.push(`Concentration: Yes`);
      }
      if (proposedSpell.duration) {
        content.push(`Duration: ${proposedSpell.duration}`);
      }
    
      content.push('');
      content.push(BOX.LIGHT.H.repeat(DISPLAY_WIDTH));
      content.push('');
    
      // Show DC calculation
      content.push(centerText('ARCANA CHECK', DISPLAY_WIDTH));
      content.push('');
      content.push(`Base DC: 10 + (${proposedSpell.level} × 2) = ${10 + proposedSpell.level * 2}`);
      if (dcModifiers.length > 0) {
        content.push(`Modifiers: ${dcModifiers.join(', ')}`);
      }
      content.push(`Final DC: DC ${dc}`);
      content.push('');
    
      // Show circumstance bonuses
      if (nearLeyLine) {
        content.push('Near ley line: DC reduced');
      }
      if (desperationBonus) {
        content.push(`Desperation: +${DESPERATION_ROLL_BONUS} to roll (mishap on failure)`);
      }
      if (materialComponentValue !== undefined) {
        content.push(`Material components: ${materialComponentValue}gp`);
      }
    
      // Roll the check
      const { finalRoll, rollDisplay } = resolveArcanaRoll(rollMode, manualRoll, manualRolls);
    
      // Apply desperation bonus to roll
      let rollBonus = arcanaBonus;
      if (desperationBonus) {
        rollBonus += DESPERATION_ROLL_BONUS;
      }
    
      const total = finalRoll + rollBonus;
      const isNat1 = finalRoll === 1;
      const isNat20 = finalRoll === 20;
    
      content.push('');
      content.push(`Roll: ${rollDisplay}`);
      if (rollBonus !== 0) {
        content.push(`Modifier: ${formatModifier(rollBonus)}`);
        content.push(`Total: ${finalRoll} ${formatModifier(rollBonus)} = ${total}`);
      } else {
        content.push(`Total: ${total}`);
      }
    
      content.push('');
      content.push(BOX.LIGHT.H.repeat(DISPLAY_WIDTH));
      content.push('');
    
      // Determine outcome
      const success = total >= dc && !isNat1;
      const marginOfSuccess = total - dc;
      const enhancedSuccess = success && marginOfSuccess >= ENHANCED_MASTERY_THRESHOLD;
      const criticalSuccess = success && isNat20;
      const mishap = isNat1 || (desperationBonus && !success);
    
      // Display result
      if (criticalSuccess) {
        content.push(centerText('CRITICAL SUCCESS!', DISPLAY_WIDTH));
        content.push('');
        content.push('The magic flows flawlessly!');
        content.push('The spell manifests with perfect clarity.');
        content.push('');
        content.push(`${proposedSpell.name} created successfully!`);
        if (proposedSpell.effect.damage) {
          content.push(`Deals maximum damage: ${proposedSpell.effect.damage}`);
        }
      } else if (enhancedSuccess) {
        content.push(centerText('ENHANCED SUCCESS!', DISPLAY_WIDTH));
        content.push('');
        content.push('Exceptional mastery of the arcane!');
        content.push(`Beat DC by ${marginOfSuccess} - enhanced effect`);
        content.push('');
        content.push(`${proposedSpell.name} created with bonus!`);
      } else if (success) {
        content.push(centerText('SUCCESS', DISPLAY_WIDTH));
        content.push('');
        content.push('The improvised magic takes form!');
        content.push('');
        content.push(`${proposedSpell.name} created successfully!`);
        if (proposedSpell.effect.damage) {
          content.push(`Damage: ${proposedSpell.effect.damage} ${proposedSpell.effect.damageType || ''}`);
        }
        if (proposedSpell.effect.healing) {
          content.push(`Healing: ${proposedSpell.effect.healing}`);
        }
      } else if (mishap) {
        if (isNat1) {
          content.push(centerText('MISHAP!', DISPLAY_WIDTH));
          content.push('');
          content.push('The magic surges wildly!');
          content.push('A critical failure causes a magical backfire!');
        } else {
          content.push(centerText('SEVERE MISHAP!', DISPLAY_WIDTH));
          content.push('');
          content.push('Desperation magic gone wrong!');
          content.push('The risky casting has backfired terribly!');
        }
        content.push('');
        content.push('The DM should determine the mishap effect:');
        content.push('- Wild magic surge');
        content.push('- Damage to caster');
        content.push('- Unintended effect');
      } else {
        content.push(centerText('FAILED', DISPLAY_WIDTH));
        content.push('');
        content.push('The magic fails to coalesce.');
        content.push('The spell fizzles without taking form.');
        content.push('');
        content.push(`Missed DC by ${dc - total}`);
      }
    
      const title = mishap ? 'SPELL MISHAP' : success ? 'SPELL SYNTHESIZED' : 'SYNTHESIS FAILED';
      return createBox(title, content);
    }
  • Zod schema defining input validation for synthesize_spell, including proposed spell details, caster info, intent, and various modifiers for the Arcana check.
    export const synthesizeSpellSchema = z.object({
      encounterId: z.string().optional(),
      casterId: z.string(),
      intent: z.string(),
      proposedSpell: ProposedSpellSchema,
    
      // Arcana check modifiers
      arcanaBonus: z.number().optional(),
      rollMode: RollModeSchema.optional(),
      manualRoll: z.number().min(1).max(20).optional(),
      manualRolls: z.array(z.number().min(1).max(20)).length(2).optional(),
    
      // Circumstance modifiers
      nearLeyLine: z.boolean().optional(),
      desperationBonus: z.boolean().optional(),
      materialComponentValue: z.number().optional(),
    });
  • Tool registration in the central registry, including name, description, input schema conversion, and wrapper handler that validates input and delegates to the synthesizeSpell function.
    synthesize_spell: {
      name: 'synthesize_spell',
      description: 'Arcane Synthesis for improvised magic. Caster proposes a custom spell effect; Arcana check DC = 10 + (level × 2) + modifiers. Success creates temporary spell effect, failure may cause mishaps. Supports circumstance modifiers (ley lines, desperation, material components).',
      inputSchema: toJsonSchema(synthesizeSpellSchema),
      handler: async (args) => {
        try {
          const validated = synthesizeSpellSchema.parse(args);
          const result = synthesizeSpell(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);
        }
      },
    },
  • Helper function to calculate the Arcana check DC for spell synthesis based on spell level, ley line proximity, and material component value.
    function calculateSynthesisDC(
      level: number,
      nearLeyLine?: boolean,
      materialComponentValue?: number
    ): { dc: number; modifiers: string[] } {
      let dc = 10 + (level * 2);
      const modifiers: string[] = [];
    
      if (nearLeyLine) {
        dc -= 2;
        modifiers.push('Near ley line: -2');
      }
    
      if (materialComponentValue && materialComponentValue >= 100) {
        const reduction = Math.floor(materialComponentValue / 100);
        dc -= reduction;
        modifiers.push(`Components (${materialComponentValue}gp): -${reduction}`);
      }
    
      return { dc, modifiers };
    }
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It effectively describes key behavioral traits: the success/failure mechanics (Arcana check DC calculation, temporary effect on success, possible mishaps on failure), and mentions circumstance modifiers. However, it doesn't specify what 'mishaps' entail or the exact nature of 'temporary' effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is efficiently structured in three sentences: purpose statement, mechanics explanation, and modifier context. Every sentence adds value, though it could be slightly more front-loaded by mentioning the tool's core function more explicitly at the beginning rather than starting with 'Arcane Synthesis'.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (11 parameters with nested objects, no output schema, no annotations), the description is insufficient. It explains the high-level mechanics but doesn't address parameter usage, return values, error conditions, or implementation details needed for a complex spell-creation tool. The description leaves too many unknowns for effective agent use.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage and 11 parameters (many nested), the description provides almost no parameter guidance. It mentions 'circumstance modifiers (ley lines, desperation, material components)' which hints at three parameters, but doesn't explain the 8 other parameters or how the complex 'proposedSpell' object should be structured. The description fails to compensate for the significant schema coverage gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Arcane Synthesis for improvised magic' with 'Caster proposes a custom spell effect' and 'Success creates temporary spell effect'. It specifies the verb (synthesize/create), resource (custom spell), and distinguishes from siblings like 'roll_dice' or 'use_scroll' by focusing on custom spell creation rather than predefined actions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage context ('improvised magic', 'circumstance modifiers') but doesn't explicitly state when to use this tool versus alternatives like 'execute_action' or 'use_scroll'. It provides clear context for when this tool is appropriate (custom spell creation with risk/reward mechanics) but lacks explicit exclusions or named alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Mnehmos/ChatRPG'

If you have feedback or need assistance with the MCP directory API, please join our Discord server