Skip to main content
Glama

create_campaign

Create a new Dungeons & Dragons 5e campaign with configurable rules versions and interaction modes for text, audio, or voice-enabled gameplay.

Instructions

Create a new D&D campaign.

The rules_version parameter selects which edition of the D&D 5e rules to use for this campaign. '2024' uses the revised 2024 rules, '2014' uses the original 5th edition rules.

The interaction_mode parameter controls how the DM communicates:

  • classic: Text-only, no voice dependencies required.

  • narrated: DM responses delivered as TTS audio + text via WebSocket.

  • immersive: Narrated + player STT input from browser.

Interaction mode and model profile are independent axes — any combination is valid.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
nameYesCampaign name
descriptionYesBrief decription of the campaign, or a tagline
dm_nameNoDungeon Master name
settingNo Campaign setting - a full description of the setting of the campaign in markdown format, or the path to a `.txt` or `.md` file containing the same.
rules_versionNoD&D rules version: '2014' or '2024' (default: '2024')2024
interaction_modeNoInteraction mode: 'classic' (text-only), 'narrated' (TTS audio + text), 'immersive' (narrated + STT input). Default: 'classic'classic

Implementation Reference

  • DnDStorage.create_campaign method handles campaign creation logic by delegating to a split backend and initializing campaign-specific metadata and directory structures.
    def create_campaign(self, name: str, description: str, dm_name: str | None = None, setting: str | Path | None = None, rules_version: str = "2024", interaction_mode: str = "classic") -> Campaign:
        """Create a new campaign using split storage format.
    
        Args:
            name: Campaign name
            description: Campaign description
            dm_name: Dungeon Master name
            setting: Campaign setting
            rules_version: D&D rules version ('2014' or '2024', default '2024')
            interaction_mode: Interaction mode ('classic', 'narrated', or 'immersive', default 'classic')
        """
        logger.info(f"✨ Creating new campaign: '{name}' (rules: {rules_version}, mode: {interaction_mode})")
    
        # Use split backend to create the campaign
        campaign = self._split_backend.create_campaign(
            name=name,
            description=description,
            dm_name=dm_name,
            setting=setting
        )
    
        # Sync to main storage
        self._current_campaign = campaign
        self._current_format = StorageFormat.SPLIT
    
        # Store rules_version and interaction_mode in campaign metadata
        self._rules_version = rules_version
        self._interaction_mode = interaction_mode
    
        # Create rulebooks directory structure
        campaign_dir = self._split_backend._get_campaign_dir(name)
        rulebooks_dir = campaign_dir / "rulebooks"
        rulebooks_dir.mkdir(exist_ok=True)
        (rulebooks_dir / "custom").mkdir(exist_ok=True)
        logger.debug(f"📂 Created rulebooks directory structure at {rulebooks_dir}")
    
        # Save rules_version and interaction_mode to campaign.json metadata
        self._save_rules_version(campaign_dir, rules_version)
        self._save_interaction_mode(campaign_dir, interaction_mode)
    
        # Rebuild indexes for new campaign
        self._rebuild_character_index()
    
        # Update campaign hash
        self._campaign_hash = self._compute_campaign_hash()
    
        # Initialize library bindings for the new campaign
        self._library_bindings = LibraryBindings(campaign_id=campaign.id)
        logger.debug(f"📚 Created empty library bindings for campaign '{name}'")
    
        # Initialize discovery tracker for the new campaign
        self._discovery_tracker = DiscoveryTracker(campaign_dir)
        logger.debug(f"Initialized empty DiscoveryTracker for campaign '{name}'")
    
        logger.info(f"✅ Campaign '{name}' created and set as active using {self._current_format} format (rules: {rules_version}, mode: {interaction_mode}).")
        return campaign
  • SplitStorageBackend.create_campaign method performs the actual file system operations to create a new campaign directory and store initialized JSON files.
    def create_campaign(self, name: str, description: str, dm_name: str | None = None, setting: str | Path | None = None) -> Campaign:
        """Create a new campaign.
    
        Args:
            name: Campaign name
            description: Campaign description
            dm_name: Dungeon Master name
            setting: Campaign setting (string or path to file)
    
        Returns:
            New Campaign object
        """
        logger.info(f"✨ Creating new campaign: '{name}'")
    
        # Ensure directory structure exists
        self._ensure_campaign_structure(name)
    
        # Create campaign object
        game_state = GameState(campaign_name=name)
        campaign = Campaign(
            name=name,
            description=description,
            dm_name=dm_name,
            setting=setting,
            game_state=game_state
        )
    
        self._current_campaign = campaign
        self.save_all(force=True)  # Force save for new campaign
        logger.info(f"✅ Campaign '{name}' created and set as active.")
        return campaign
Behavior3/5

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

No annotations are provided, so the description carries the full burden. It adds context about parameter behaviors (e.g., rules_version options, interaction_mode details), but does not disclose broader traits like permissions needed, rate limits, or what happens on success/failure. The description is informative but lacks operational transparency.

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

Conciseness5/5

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

The description is well-structured and front-loaded with the core purpose. Each sentence adds value: the first states the action, and subsequent sentences clarify parameter nuances without waste. It is appropriately sized for a tool with multiple parameters.

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

Completeness4/5

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

Given the complexity (6 parameters, no annotations, no output schema), the description does a good job explaining key parameters and their implications. However, it lacks information on return values or error handling, which would be helpful since there's no output schema. It's mostly complete but has minor gaps.

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

Parameters4/5

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

Schema description coverage is 100%, so the baseline is 3. The description adds meaningful semantics beyond the schema by explaining the significance of 'rules_version' (edition differences) and detailing the 'interaction_mode' options with clear examples. This enhances understanding without redundancy.

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: 'Create a new D&D campaign.' It specifies the exact action (create) and resource (campaign), and distinguishes it from siblings like 'list_campaigns' or 'delete_campaign' by focusing on creation rather than listing or deletion.

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

Usage Guidelines3/5

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

The description provides implied usage by explaining the parameters (rules_version and interaction_mode), but it does not explicitly state when to use this tool versus alternatives. No prerequisites, exclusions, or comparisons to similar tools (e.g., 'load_campaign') are mentioned.

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/Polloinfilzato/dm20-protocol'

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