# The Unreal agent session contract and a five-check quick check (free sample of Unreal from Codex)

Version 1.0, 2026-10-28. By PaperChaseWebb. For Unreal Engine 5.8 with its Unreal MCP plugin, and any coding agent that connects to it: Codex, Claude Code, Grok Bot or Hermes. One Markdown file and one Python 3 script, standard library only. The script was tested on its worked example (5 findings, then 0). The Unreal steps were not run in Unreal for this sample.

When a coding agent can call editor tools, the useful question is not what it can do but what it is supposed to do this session, and what it already did. This sample gives you the one file that answers the first question and the log that answers the second, plus a script that checks both in under a second.

## The session file

Put this in Agent/SESSION.md next to your .uproject, before the agent makes its first call. The agent reads it and does not edit it.

```markdown
# Session

Engine: 5.8
Checkpoint: 4f2a9c1
Endpoint: http://127.0.0.1:8000/mcp
Objective: Place the approved crates in /Game/_Agent/CrateRoom
Leave out: lighting, maps outside /Game/_Agent, packaging
```

- Checkpoint is the commit you made right before the session. If the session goes wrong, you reset to it.
- Endpoint is the address of the editor's MCP server. Keep it on your own machine: 127.0.0.1 or localhost, never 0.0.0.0 or a network address.
- Objective is one sentence with a folder in it. Leave out is the list that stops the agent from improving things you did not ask about.

## The tiers

| Tier | What | Who decides |
|---|---|---|
| 0 | read only: list actors, get properties, find references | the agent |
| 1 | a small, reversible edit inside /Game/_Agent | the agent, logged |
| 2 | create or import inside /Game/_Agent | the agent, logged |
| 3 | delete, rename, bulk change, editor Python, console command, anything outside /Game/_Agent | you, before the call |
| 4 | package, cook, upload, publish | you, with a separate release yes |

## The action log

After every call the agent adds one row to Agent/actions.csv, with what it checked by reading back after a write:

```
time,toolset,tool,tier,target,verify,approval
09:00,actors,list_actors,0,CrateRoom,12 actors,
09:10,actors,spawn_actor,2,SM_Crate x4,4 actors found at the marks,
09:30,assets,delete_asset,3,/Game/_Agent/Old,folder gone,A1
```

"done" is not a verify result. A value read back, a count, or a folder that is gone is.

## Rules to paste into AGENTS.md or CLAUDE.md

```markdown
1. Read Agent/SESSION.md first and do not edit it. No Checkpoint, Objective or Leave out line means stop and ask.
2. Start each session with list_toolsets and describe_toolset. Never call a tool from memory.
3. Give every call a tier. Tier 3 and 4: ask first with the target, the call, how you will verify and how to undo, then wait for my words.
4. After every write, confirm with a read call and log the row with the result you saw.
5. After a restart or timeout, stop, re-read SESSION.md and the last ten actions, and check the last write before going on. Never repeat a tier 3 or 4 call on your own.
```

## The quick check, worked example

```
python3 session_quick_check.py --example crate-room
python3 session_quick_check.py crate-room
```

The example has five planted problems, and the check finds all five:

```
S1  no checkpoint commit in Agent/SESSION.md: save, commit, then write the hash
S2  Agent/SESSION.md needs both an Objective line and a Leave out line
S3  Endpoint http://0.0.0.0:8000/mcp is not this machine (use http://127.0.0.1:8000/mcp)
S5  actions.csv line 3: spawn_actor has no verify result
S4  actions.csv line 4: tier 3 delete_asset has no approval
5 findings
```

Fix them: write a commit hash on the Checkpoint line, add a Leave out line, change the endpoint to 127.0.0.1, write what the agent saw after the spawn ("4 actors found at the marks"), and put your approval id on the delete. Run it again and it prints 0 findings, exit 0. It reads only; it never changes your files.

## session_quick_check.py

```python
#!/usr/bin/env python3
"""session_quick_check.py: five read-only checks on an agent's Unreal session before and after it runs.

Usage: python3 session_quick_check.py PROJECT_FOLDER      reads Agent/SESSION.md and Agent/actions.csv, writes nothing
       python3 session_quick_check.py --example DIR       writes a worked example with five planted problems into DIR
Checks: S1 checkpoint commit written down, S2 objective and leave-out list written down, S3 MCP endpoint is this
machine, S4 every tier 3 or 4 action names the owner's approval, S5 every action has a verify result.
Exit codes: 0 no findings, 1 findings, 2 folder missing. Standard library only, Python 3.8+.
Free sample from Unreal from Codex (pp-unreal-from-codex) at paperchasewebb.ai."""
import csv, ipaddress, os, re, sys
from urllib.parse import urlparse

def field(t, n):
    m = re.search(r"^\s*" + n + r"\s*:\s*(.*)$", t, re.M | re.I)
    return m.group(1).strip() if m else ""

def local(url):
    h = urlparse(url).hostname or ""
    if h == "localhost": return True
    try: return ipaddress.ip_address(h).is_loopback
    except ValueError: return False

def example(d):
    os.makedirs(os.path.join(d, "Agent"), exist_ok=True)
    open(os.path.join(d, "Agent", "SESSION.md"), "w").write("# Session\n\nEngine: 5.8\nCheckpoint: \nEndpoint: http://0.0.0.0:8000/mcp\nObjective: Place the approved crates in /Game/_Agent/CrateRoom\n")
    with open(os.path.join(d, "Agent", "actions.csv"), "w", newline="") as f:
        w = csv.writer(f); w.writerow(["time", "toolset", "tool", "tier", "target", "verify", "approval"])
        w.writerow(["09:00", "actors", "list_actors", "0", "CrateRoom", "12 actors", ""])
        w.writerow(["09:10", "actors", "spawn_actor", "2", "SM_Crate x4", "", ""])
        w.writerow(["09:30", "assets", "delete_asset", "3", "/Game/_Agent/Old", "folder gone", ""])
    print("wrote a worked example to " + d + "; run: python3 session_quick_check.py " + d)

def main(a):
    if len(a) == 3 and a[1] == "--example": example(a[2]); return 0
    if len(a) != 2 or not os.path.isdir(a[1]): print(__doc__.splitlines()[2]); return 2
    s_path, a_path, F = os.path.join(a[1], "Agent", "SESSION.md"), os.path.join(a[1], "Agent", "actions.csv"), []
    s = open(s_path, encoding="utf-8").read() if os.path.isfile(s_path) else ""
    if not re.fullmatch(r"[0-9a-f]{7,40}", field(s, "Checkpoint")): F.append("S1  no checkpoint commit in Agent/SESSION.md: save, commit, then write the hash")
    if not field(s, "Objective") or not field(s, "Leave out"): F.append("S2  Agent/SESSION.md needs both an Objective line and a Leave out line")
    ep = field(s, "Endpoint")
    if not ep or not local(ep): F.append("S3  Endpoint %s is not this machine (use http://127.0.0.1:8000/mcp)" % (ep or "missing"))
    acts = list(csv.DictReader(open(a_path, newline="", encoding="utf-8"))) if os.path.isfile(a_path) else []
    for i, r in enumerate(acts, 2):
        t = (r.get("tier") or "").strip()
        if t in ("3", "4") and not (r.get("approval") or "").strip(): F.append("S4  actions.csv line %d: tier %s %s has no approval" % (i, t, r.get("tool")))
        if not (r.get("verify") or "").strip(): F.append("S5  actions.csv line %d: %s has no verify result" % (i, r.get("tool")))
    for f in F: print(f)
    print("%d finding%s" % (len(F), "" if len(F) == 1 else "s"))
    return 1 if F else 0

if __name__ == "__main__":
    sys.exit(main(sys.argv))
```

## What the full pack adds

Unreal from Codex ($24) adds setup and config for Codex, Claude Code, Grok Bot and Hermes, a connection probe that calls no tools, an approval ledger tied to file hashes, recovery steps for editor restarts, stale tool lists, compiles and timeouts, a generator to Blender to Unreal asset path with a headless Blender prep script (tested on Blender 5.2.3), an import script that refuses changed files, and a fifteen-check read-only checker tested on a seeded fixture. If you want it set up for your team, there is a $5,000 Install sprint and $5,000/mo Manage. Book a call from paperchasewebb.ai.

Credit: the recovery advice draws on Oleg Soroko's Unreal skills for Codex (https://x.com/OlegSoroko/status/2112123914717655092) and Epic's Unreal MCP documentation (https://dev.epicgames.com/documentation/unreal-engine/unreal-mcp-in-unreal-editor?lang=en-US).

PaperChaseWebb 💸
