Repository

dwarf_fortress_mcp

A semantic, transactional, replayable MCP control plane that lets autonomous AI agents operate Dwarf Fortress as a long-lived civilization. Safe-Rust phase-0B scaffold: MVCC world state, witnessed semantic plans, evidence-backed effects, deterministic replay.

Tool
Role
fortress.open_session
Negotiate capabilities, budgets, fortress identity, and initial anchor.
fortress.observe
Refresh canonical state or return a heartbeat.
fortress.query
Run bounded semantic queries.

Specs

  • ToolRole
  • fortress.open_sessionNegotiate capabilities, budgets, fortress identity, and initial anchor.
  • fortress.observeRefresh canonical state or return a heartbeat.
  • fortress.queryRun bounded semantic queries.
  • fortress.planCompile an intent in modes that support planning.
  • fortress.commitCommit a prepared plan in modes that support effects.
  • fortress.waitPoll active work or refresh when useful.
  • fortress.cancelRequest and reconcile cancellation in effect-capable modes.
  • fortress.checkpointCreate a recovery point in checkpoint-capable modes.
  • fortress.restoreRestore into a new observation epoch.
  • fortress.explainExplain state, provenance, plans, decisions, or failures.
  • fortress.doctorDiagnose compatibility, bridge, state, and recovery posture.
  • ProjectAccretive role
  • asupersyncSole async runtime, structured concurrency, cancellation, deterministic lab, ATP foundation.
  • frankensqliteMVCC, witnessed reads, negative SSI, deterministic rebase, certified merge.
  • frankenfsRoot-last publication, crash matrices, generation fencing, retrievability.
  • frankensearchProgressive bounded cognition, immutable generations, explicit completeness.
  • franken_markdownDependency-light semantic extraction, exact spans, transactional sibling publication.
  • frankengraphdbOne version universe, incremental graph projections, branch-per-agent experiments.
  • franken_networkxCanonical graph semantics, tie-break policies, complexity and decision witnesses.
  • fastmcp_rustOwned modern-only MCP 2026-07-28 presentation plane.
  • eidetic_engine_cliEvidence-linked advisory campaign memory with no authority path.
  • doodlestein_self_releaserLocal/self-hosted qualification and exact release asset contracts.

README

dwarf_fortress_mcp

A semantic, transactional, replayable control plane for agents operating Dwarf Fortress as a
long-lived civilization rather than a keyboard-and-screen toy.

Current status: the repository contains an authenticated protocol-1.0 read-only DFHack
stack, canonical live citizen observations, an agent-oriented MCP server, exact compatibility and
anti-rollback machinery, source-bound executable qualification, a protocol-bound V2 process
boundary, and an implemented protocol-1.1 retained-announcement development stack. The checked-in
compatibility registry is empty. No live tuple is admitted, protocol 1.1 is not in the
production runner map, no live mutation RPC exists, and the final current source generation has
no newly checked-in full qualification receipt. Read
IMPLEMENTATION_STATUS.md before interpreting target architecture as
deployed behavior.

The motivating problem is not merely “let a model press keys.” Dwarf Fortress is an unusually rich
long-horizon environment, but a naive automation layer would expose incomplete observations,
command acknowledgements mistaken for success, unsafe retries, version drift, unbounded output,
and no durable explanation of why the fortress reached its current state.

dwarf_fortress_mcp instead treats the game as a partially observed, continuously evolving typed
world:

observe exact state
→ orient economically
→ formulate semantic intent
→ prepare against witnessed state
→ revalidate authority and conflicts
→ commit idempotently
→ observe authoritative post-state
→ prove the goal or reconcile uncertainty
→ retain evidence for the next agent

Implemented source

Protocol 1.0: authenticated citizen reads

The production-source bridge exposes exactly:

Handshake
ReadObservation

It includes:

  • loopback bearer-token authentication;
  • bounded nonce, client, token, frame, text, and payload domains;
  • exact protocol, bridge, plugin, version, and method-manifest identity;
  • stable unit-ID ordering and bounded citizen pagination;
  • optional citizen-name projection;
  • complete-roster coverage semantics;
  • paused-world requirements for coherent multi-page assembly;
  • fail-closed restart, generation, nonce, version, ordering, malformed-wire, and budget checks;
  • no remote-service flag;
  • no command, Lua, keyboard, arbitrary RPC, direct memory-write, filesystem, or mutation route.

The Rust trust domain uses supported out-of-process DFHack RPC. It contains no C/C++ FFI and forbids
unsafe Rust.

Protocol 1.1: retained-announcement reads

Protocol 1.1 keeps the same two-method native waist and adds bounded announcement fields inside
ReadObservation. It has a distinct protobuf package, plugin, bridge version, source contract,
native receipt, A1-A6 acceptance campaign, evidence journal, diagnostic probe, adapter, and
separately named development MCP binary.

The canonical announcement model provides:

  • strictly increasing report IDs;
  • 512-record and 2,048-byte-per-text ceilings;
  • oldest and latest retained report identity;
  • explicit gap_before_window evidence;
  • explicit complete_through_latest evidence;
  • retained-suffix completeness distinct from complete fortress history;
  • deterministic world entities, coverage, briefing, attention, and report-ID changes;
  • no text-derived authority and no mutation method.

Citizen pagination and announcement continuation publish transactionally. No combined capsule is
visible until every required page agrees on the same observation instant and both domains are
complete under their declared limits.

Bootstrap uses one complete combined capsule. A primed replay layer supplies fortress identity,
source digest, and adapter initialization without another underlying bridge read, preserving the
full two-dimensional request surface:

citizen pagination × announcement continuation

The development runtime is:

DFMCP_ALLOW_UNADMITTED_LIVE_V1_1=1 \
DFMCP_BRIDGE_TOKEN='<32..256-byte loopback secret>' \
cargo run --locked --bin dfmcp-live-v1-1-dev-server

It is explicitly unadmitted. It rejects production admission environment state, uses a distinct
session namespace, cannot consume a production ticket, and cannot appear in admitted Agent Turn
provenance.

See docs/LIVE_ANNOUNCEMENT_STREAM.md and
docs/LIVE_ANNOUNCEMENT_IMPLEMENTATION_STATUS.md.

Canonical live state

A complete bridge publication becomes an immutable observation capsule. Transport pagination is not
canonical state: equivalent one-page and multi-page reads produce identical canonical bytes and the
same SHA-256 identity.

Current projections include:

  • fortress identity, version manifest, clock, pause state, and citizen count;
  • one entity per completely covered citizen;
  • deterministic citizen-membership edges;
  • optional citizen names plus profession, position, and basic status;
  • protocol-1.1 announcement event entities and retained-window coverage;
  • fact-level provenance tied to the source capsule digest;
  • explicit complete, conditional, partial, and omitted domains;
  • canonical anchors with observation epoch and sequence.

The live adapters implement heartbeats, ordinary state advancement, restart and clock-regression
resets, world/site/version switch refusal, exact queries, explanations, and read-only health
diagnosis.

Agent-facing MCP

The public namespace remains the frozen eleven-tool waist:

Tool Role
fortress.open_session Negotiate capabilities, budgets, fortress identity, and initial anchor.
fortress.observe Refresh canonical state or return a heartbeat.
fortress.query Run bounded semantic queries.
fortress.plan Compile an intent in modes that support planning.
fortress.commit Commit a prepared plan in modes that support effects.
fortress.wait Poll active work or refresh when useful.
fortress.cancel Request and reconcile cancellation in effect-capable modes.
fortress.checkpoint Create a recovery point in checkpoint-capable modes.
fortress.restore Restore into a new observation epoch.
fortress.explain Explain state, provenance, plans, decisions, or failures.
fortress.doctor Diagnose compatibility, bridge, state, and recovery posture.

Live read-only modes grant only:

doctor
observe
query
wait

The remaining tools stay registered for protocol stability and fail closed without reaching an
effect path.

Every success and error converges on a canonical Agent Turn Packet:

identity + exact anchor + continuity
briefing + semantic changes + ranked attention
active work + legal affordances + next protocol steps
uncertainty + coverage + budget + typed references

After admitted startup, Agent Turns also expose the exact bridge protocol, ticket, compatibility
entry, registry, decision, monotonic floor, server receipt, launch, and executable identities. Those
fields explain authority; they do not create more authority.

Exact admission, not “works on my machine”

Source presence is not compatibility evidence. One exact tuple must pass:

R1 native plugin build and binary inventory
R2 authentication and non-disclosure matrix
R3 deterministic complete-read matrix
R4 restart, drift, gap, and partial-publication fencing
R5 cold-agent semantic orientation

Protocol 1.1 additionally requires its complete A1-A6 announcement campaign and a re-executed
baseline citizen campaign under protocol 1.1.

Only reviewed evidence may be promoted into:

architecture/live_compatibility_registry_v1.json

The registry currently has zero entries. Therefore the repository does not claim a runnable
admitted live configuration.

Local anti-rollback floor

A deployment host separately maintains an owner-only monotonic floor for the last accepted exact
registry bytes:

architecture/live_compatibility_floor_v1.json
scripts/live_compatibility_floor.py

The floor uses exact 0700 directory and 0600 file custody, no-follow reads, compare-and-swap,
atomic fsynced replacement, a monotonic sequence, a digest chain, and preservation of every prior
accepted entry ID. An older but valid registry cannot silently replace the trusted generation.

The floor is local custody. It does not admit a tuple, implement distributed consensus, or defend
against compromise of the owning account or root.

Authority-free readiness doctor

Before touching a bridge secret or executing a binary:

python3 scripts/doctor_live_admission.py \
  /path/to/live-deployment-manifest.json \
  --registry architecture/live_compatibility_registry_v1.json \
  --compatibility-floor /private/dfmcp/live-compatibility-floor.json \
  --require-entry-id <64-hex-entry-id>

The deterministic doctor checks registry, floor, exact tuple, and optional server artifact. It does
not execute the server, connect to DFHack, read the bearer token, alter custody, or grant
capabilities.

Protocol-bound V2 process boundary

architecture/live_admission_ticket_v2.json closes protocol confusion at the final launch seam. The
exact protocol must agree across:

deployment manifest
→ compatibility decision
→ launch record
→ single-use ticket
→ DFMCP_ADMITTED_BRIDGE_PROTOCOL
→ Rust admission provenance
→ final private runner

Both launch and ticket digests cover the protocol. The production map currently contains only:

1.0 → dwarf-fortress-mcp serve-live → private protocol-1.0 server

Protocol 1.1, unknown protocols, mismatches, and legacy V1 tickets fail before server startup. A
future protocol-1.1 production runner cannot be added safely until its separate source, native,
live, registry, floor, artifact, and dispatch evidence exists.

The launcher additionally verifies exact registry/floor generation, required entry ID, source-bound
server receipt, loader hygiene, executable owner/mode/device/inode/length/SHA-256, and descriptor
stability. It issues an exact-mode 0600 ticket inside a real exact-mode 0700 directory and
executes only the already-qualified descriptor. The Rust process repeats the process, protocol,
capability, custody, and executable checks, deletes the ticket, and only then starts MCP.

Direct serve-live invocation fails closed. No path-based execution fallback exists.

See docs/LIVE_COMPATIBILITY_ADMISSION.md.

Canonical source custody

Release source is produced from one exact clean Git commit, not copied from an ambient worktree:

scripts/create_source_bundle.sh

The bundle system uses canonical Git archive modes and metadata, an ordered manifest of every
tracked regular blob, hostile tar verification without extraction, create-only verification
receipts, and sibling-directory atomic publication after every check succeeds.

A source bundle proves source and archive identity only. It does not prove compilation, tests,
compatibility, binary reproducibility, or runtime admission.

See docs/SOURCE_BUNDLE.md.

System architecture

The target is one synthetic system with authoritative, cognition, effect, and deployment-admission
boundaries.

flowchart TB
    A[Agents / MCP clients] --> B[Session, capability, budget, continuity]
    B --> C[Authoritative observations, evidence, intents, witnesses]
    C --> D[Multi-version semantic world]
    D --> E[Derived graph, search, attention, counterfactuals]
    D --> F[Prepared plans and conflict validation]
    F --> G[Typed out-of-process DFHack effect boundary]
    G --> H[Dwarf Fortress + DFHack]
    H --> C
    C --> I[ATP state and evidence movement]
    J[Registry + floor + receipt + V2 ticket] --> B
    J --> G

Authoritative plane

The only source of truth for what was observed, what effect was attempted, and what was proved:

  • immutable observation capsules;
  • multi-version semantic state;
  • positive, negative, range, aggregate, spatial, and epoch witnesses;
  • sealed plans and idempotent effects;
  • bounded obligations;
  • checkpoints, reconciliation, evidence, and compatibility epochs.

Cognition plane

Discardable, rebuildable, anchor-bound intelligence:

  • graph and spatial projections;
  • deterministic graph algorithms and decision witnesses;
  • search and knowledge generations;
  • attention, affordances, recommendations, and counterfactuals;
  • evidence-gated memory export.

It may propose an intent. It cannot authorize or dispatch an effect.

Effect plane

The target mutation protocol is always:

prepare → revalidate → commit → observe → prove

A transport acknowledgement is not game success, and game mutation is not goal completion. Unknown
outcomes remain indeterminate until observation and operation lookup reconcile them. The current
live protocols expose no mutation method.

Franken substrate synthesis

Project Accretive role
asupersync Sole async runtime, structured concurrency, cancellation, deterministic lab, ATP foundation.
frankensqlite MVCC, witnessed reads, negative SSI, deterministic rebase, certified merge.
frankenfs Root-last publication, crash matrices, generation fencing, retrievability.
frankensearch Progressive bounded cognition, immutable generations, explicit completeness.
franken_markdown Dependency-light semantic extraction, exact spans, transactional sibling publication.
frankengraphdb One version universe, incremental graph projections, branch-per-agent experiments.
franken_networkx Canonical graph semantics, tie-break policies, complexity and decision witnesses.
fastmcp_rust Owned modern-only MCP 2026-07-28 presentation plane.
eidetic_engine_cli Evidence-linked advisory campaign memory with no authority path.
doodlestein_self_releaser Local/self-hosted qualification and exact release asset contracts.

The production dependency universe is closed. Rust is 2024 edition on the latest nightly, unsafe
code is forbidden, asupersync is the sole async runtime, and broad substitute frameworks are not
admitted.

Build and qualify

The normative local gates are:

./scripts/verify.sh
./scripts/qualify_local.sh

They are intended for controlled local or self-hosted machines. GitHub workflow files are portable
job specifications for doodlestein_self_releaser, act, or controlled hosts; they are not
correctness authority.

A static-only, dirty-tree, or missing-Rust run is development evidence, never release evidence. Full
local qualification requires exact source integrity, every Python/shell contract, locked/offline
Cargo metadata, rustfmt, warning-denied Clippy, debug and release tests, warning-denied rustdoc, and
executable checks.

Protocol 1.1 has a narrower source-only qualifier:

scripts/qualify_live_announcement_source.sh

It still does not prove a native plugin build, A1-A6, baseline R2-R5, registry admission, or
production runtime admission.

After full local qualification, qualify the protocol-1.0 release server separately:

scripts/qualify_live_server_binary.sh \
  target/qualification/<run>/qualification-receipt.json \
  target/live-server-binary-qualification/<run>

Immediate roadmap

  1. Produce a full latest-nightly clean-head qualification receipt.
  2. Qualify the exact protocol-1.0 server binary.
  3. Run R1-R5 for one exact current protocol-1.0 tuple.
  4. Review and promote it, advance a deployment floor, and launch through the V2 protocol boundary.
  5. Separately qualify protocol 1.1 source, native plugin, A1-A6, and baseline R2-R5.
  6. Add a protocol-1.1 production runner only after its complete evidence chain exists.
  7. Expand read coverage through jobs, items, buildings, and bounded map state.
  8. Add pause/resume only as a separately versioned, witnessed, idempotent, reconciled mutation
    generation.

Documentation map

  1. IMPLEMENTATION_STATUS.md — exact present evidence posture.
  2. AGENTS.md — normative engineering rules.
  3. docs/AGENT_OPERATING_MODEL.md — synthetic agent control loop.
  4. ARCHITECTURE.md — compact system map.
  5. COMPREHENSIVE_PLAN_FOR_DWARF_FORTRESS_MCP.md — full target plan.
  6. FRANKENSTACK_DEEP_DIVE.md — source-level substrate synthesis.
  7. MCP_SURFACE.md — frozen protocol waist.
  8. docs/LIVE_DFHACK_READ_PATH.md — protocol-1.0 read path.
  9. docs/LIVE_ANNOUNCEMENT_STREAM.md — protocol-1.1 announcement semantics.
  10. docs/LIVE_COMPATIBILITY_ADMISSION.md — exact evidence and V2 launch chain.
  11. docs/LOCAL_QUALIFICATION_AND_RELEASE.md — local trust model.
  12. docs/SOURCE_BUNDLE.md — canonical source custody.
  13. ROADMAP.md — gate-based next steps.

Hard refusals

This project does not accept:

  • arbitrary command or Lua execution through the default MCP surface;
  • direct memory scraping or C/C++ FFI in the Rust trust domain;
  • hidden second async runtimes;
  • inference, memory, attention, recommendations, or text as mutation authority;
  • absence claims without complete-domain coverage;
  • retrying indeterminate effects blindly;
  • path-based fallback after qualifying a different executable inode;
  • protocol selection that is not covered by the compatibility, launch, and ticket digests;
  • treating source presence, development execution, unit tests, old receipts, or a green badge as
    current live evidence.

The standard is not “the command ran.” The standard is exact state, bounded authority,
deterministic behavior, replayable evidence, and honest uncertainty.