Skip to main content
Glama

save_level

Destructive

Writes the editor's current level (.umap) to disk, refusing during Play-in-Editor and for read-only files; use it to persist level edits.

Instructions

Write the editor's current level (.umap) to disk; it REFUSES while PIE is running (the engine guard rejects the write anyway) and derives success from the file being on disk afterwards, never from the save call's own bool. WARNING: it also REFUSES when the target .umap is READ-ONLY on disk, which in an LFS repo means a lockable path you have not git lfs locked: that write cannot succeed, and answering over HEAD's still-untouched bytes would report success:true having written nothing. The refusal names the file and the fix (git lfs lock <file>) -- take the lock, do not retry. WARNING: on a file that ALREADY existed, file_exists_on_disk alone still cannot tell "I wrote it" from "it was already there": the field that proves the write is file_mtime_changed. It is deliberately NOT gating success, because a save with nothing dirty to write also leaves the mtime alone and that is not a failure. WARNING: with filename this is a SaveAs that DUPLICATES: the editor stays on the old map, the new one becomes a resident world (which then makes load_level refuse), and a SECOND save to the same filename opens a modal that freezes the editor -- treat filename as one-shot per name per session.

Returns: { success: bool, error?: string, data?: { saved_filename?: string, saved_package?: string, saved_disk_path?: string, level_name?: string, file_exists_on_disk: bool, file_size_bytes: int, file_existed_before: bool, file_mtime_changed: bool (the write itself -- see the read-only note above), save_call_returned: bool, rescued_with_save_packages: bool, pie_was_stopped: bool, orphan_world_risk?: bool, requested?: { filename?: string, save_as?: bool } } }

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
forceNoOptional. This command is REFUSED while a Play-in-Editor session is running: it either compiles a Blueprint (the reinstancer can retain a world, and CheckForWorldGCLeaks is Fatal -- it KILLS the editor) or writes to disk (Editor.AllowSavingAssetsDuringPIE=0 makes the engine refuse the write, so it would report success without writing a byte). Stop PIE and retry instead; force=true runs it anyway, at your own risk.
save_asNoAccepted for wire compatibility and IGNORED: the branch is chosen by whether `filename` was given. It comes back inside `requested` to mark it as your input, not a measurement.
filenameNoOptional. A /Game asset path (e.g. /Game/Maps/Foo) or a disk .umap path; both accepted and resolved. Omit it to save the level in place -- that is the branch that just works. Passing one is a SaveAs: duplicate + resident world + the one-shot rule above.

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observedv1.1.0

TDQS

A4.6/5.0
Behavior5/5

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

Annotations already declare destructive=true, readOnly=false, idempotent=false, and the description adds substantial non-inferable behavior: engine guard refusal under PIE, read-only/LFS refusals that would falsely report success, why mtime (not success) proves the write, the resident-world side effect that breaks load_level, and the modal freeze on a second SaveAs. All consistent with the destructive annotations, no contradiction.

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?

Front-loaded with the core action and consequence, and every warning carries real information. It is on the long side with three repeated 'WARNING:' blocks and some restatement of the per-parameter schema text, so it is dense rather than optimally tight, but little is pure filler.

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

Completeness5/5

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

For a destructive mutation tool with no output schema, the description fully compensates: it documents the return shape inline (success, error, data fields) including the subtle `file_mtime_changed` vs `success` distinction. An agent has everything needed to call it and interpret the result.

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

Parameters3/5

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

Schema description coverage is 100% and each parameter already carries a rich description (force/PIE, save_as ignored, filename/SaveAs). The description largely restates those same semantics (e.g., 'with `filename` this is a SaveAs') without adding format or syntax detail beyond the schema, so baseline 3 is appropriate.

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 first clause states a specific verb and resource: 'Write the editor's current level (.umap) to disk.' It clearly distinguishes this from sibling save tools (save_asset, save_usd_stage) by naming the .umap level asset, and it even contrasts the two operational branches (in-place save vs. SaveAs via `filename`).

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

Usage Guidelines5/5

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

It explicitly states when the tool will refuse (PIE running, read-only LFS-locked file) and what to do instead ('take the lock, do not retry'). It also gives clear branch-selection guidance: omit `filename` for a plain in-place save, pass it for a duplication SaveAs bounded by the one-shot-per-name rule.

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

Deploy Server

Other Tools