Structs Desktop (Embedded MCP)

Purpose: AI-readable reference for Structs Desktop — a native (Tauri) desktop app that wraps the structs-webapp game client and runs an embedded MCP server so an AI agent can play the game through one authenticated HTTP connection. It adds GPU-accelerated proof-of-work, native notifications, a policy/automation engine, a perception + combat-simulation layer, virtual-player management, and an agent-driven UI for human+agent co-op.

Repository: https://github.com/playstructs/structs-desktop

Download: prebuilt installers for macOS, Windows, and Linux are on the releases page.

This is the primary way an agent connects to Structs. The Guild Stack provides the PostgreSQL data store and GRASS event bridge that back the game infrastructure; Structs Desktop is the client + MCP surface an agent actually talks to. For raw CLI play without the app, see the structsd commands referenced throughout the skills.


Overview

Structs Desktop wraps the webapp in a Tauri shell and exposes an MCP server on the loopback interface. A single connection gives an agent full situational awareness, action execution with preflight checks, background hashing, event streaming, and a standing-order automation engine. The app never hands out signing keys — every transaction is signed inside the webview’s CosmJS client via a Rust ↔ JS bridge, so the MCP tools request signatures rather than holding secrets.

Key subsystems the MCP fronts:


Connecting

Detail Value
Endpoint http://127.0.0.1:8420/mcp (loopback only)
Transport HTTP (MCP)
Auth Authorization: Bearer <token> on every request
Missing/bad token 400 Bad Request (not 401 — a 401 would trigger a Claude Code OAuth flow)
Liveness probe unauthenticated GET /health
Token location generated on first launch; shown in the app’s Debug tab and browser console, stored at ~/Library/Application Support/structs-app/mcp_config.json (macOS)

Example client config (copyable from the Debug tab):

{
  "mcpServers": {
    "structs-game": {
      "type": "http",
      "url": "http://127.0.0.1:8420/mcp",
      "headers": { "Authorization": "Bearer YOUR_TOKEN_HERE" }
    }
  }
}

The bearer token exists because any browser page can reach localhost — without it a malicious site could drive the game. See agent-security.md for the agent threat model.


Tool Catalog (13)

Tool Purpose
structs_dashboard Full player overview: power, charge (with per-action readiness), resources, structs + HP, hash tasks, recent events
structs_hash Manage proof-of-work tasks with ETAs (list/start/stop/progress) and tune the engine (config: enable/disable, engine cpu/gpu/auto, difficulty_start, max_concurrent, auto_tune) — knobs persist across restarts
structs_action Execute game actions with preflight checks (explore, build, mine, refine, attack, defend, raid, resync, etc.); routes through the signing bridge
structs_intel Strategic intelligence + perception: whoami, scout, valid_targets, simulate, strike_options, battle_log, ruleset, slot_map, is_active, intents, power forecast, economy, timeline — plus query for raw entity reads/lists/filters (absorbs the retired structs_query)
structs_policy Standing orders: auto_refine, power_alert, agent_ui, combat orders, watchdog_remediate
structs_events Long-poll event feed (raids, attacks, fleet moves, completions) so agents react instead of polling
structs_sequence Guarded autonomous action chains, paced to the charge cooldown, with abort predicates (e.g. CMD-ship HP floor); pass as to run as a virtual player
structs_players Manage virtual players (extra players off the same mnemonic, joined to your guild): create / list / roster / state / act-as. Keys stay in the webapp
structs_board Team Ops board + human-facing UI surfaces: the at-a-glance command view and event feed, plus declarative components (menus, dialogues, map previews, HUD badges, prompts — absorbs the retired structs_ui). Display/elicitation only, never signs
structs_system System health, logs, self-tuning: watchdog status, per-loop liveness, tx-attempt ledger, PoW solve stats, and the persistent structured log
structs_map Render a planet map to PNG/GIF using the game’s own renderer
structs_doctrine Standing rules of engagement + per-tick executor (advise / auto autonomy)
structs_strike Coordinated team attack + kill-chain (strip blockers → kill → raid window)

Retired/folded tools: structs_query was merged into structs_intel (query), and structs_ui into structs_board (component). The old names remain only as deprecation stubs that return a pointer to the replacement.


Prompts (6)

Prompt Purpose
structs_first_session Orientation for new agents — check dashboard, identify priorities
structs_game_loop One tick: dashboard → assess → plan → execute → verify
structs_state_assessment Deep analysis with risk ratings: power, threats, economy, operations
structs_combat_planning Scout, simulate, recommend attack / wait / abort
structs_threat_check Assess hostile activity using planet history + valid targets
structs_market_check Survey the power-rental market

Resources

The structs-ai compendium (this documentation) is bundled as MCP resources, synced during the app’s build. URIs are derived from the file tree (no hardcoded paths — see develop/structs-resources.md). Agents read docs on demand under the structs:// scheme, e.g.:


Subsystems

GPU / CPU hashing

GPU (wgpu compute shader, ~200M h/s) is auto-selected when available and falls back to CPU (rayon + hardware SHA256, ~3M h/s). A Worker shim intercepts the webapp’s TaskWorker.js and routes hashing to Rust while keeping the existing TaskManager.js interface, which submits the completion transaction. Override at runtime with structs_hash {command:"config", engine:"cpu"|"gpu"|"auto"} and tune difficulty_start / max_concurrent.

Perception + combat simulator

structs_intel fronts a recon layer, a weapon-matrix ruleset, and a pure-math simulate so an agent can evaluate valid_targets, strike_options, and outcomes before committing charge. This mirrors the combat rules in combat.md.

Policy engine + watchdog

Standing orders run on game-state transitions using delta tracking (previous vs current snapshot) to avoid double-triggers. Defaults: auto_refine ON, power_alert ON (80%), agent_ui ON, watchdog_remediate ON; combat orders (auto_counterattack, auto_retreat_if_cmd_below, auto_rebuild_losses) and rules_of_engagement default OFF. Combat orders are agent-honored — the engine never auto-signs; the agent reads them via structs_intel {query:"intents"} and acts through structs_action/structs_sequence. The watchdog self-heals wedged loop guards / stalled hash tasks / dead sync ticks, logging every remedy (structs_system) and notifying only on repeat failure.

Combat mode

The policy engine auto-detects combat events (raids, attacks, fleet arrivals) and tightens the gameState sync interval from 10s to 3s, dropping back after ~30 quiet blocks (~3 min).

Virtual players

structs_players manages additional players derived from the same mnemonic at different HD indices and joined to your guild. Keys never leave the webapp; the MCP drives signing through the vplayer bridge. Run a chain as a specific virtual player with the as parameter on structs_sequence (and act-as on structs_players). See team-operations for why a team of players beats a single account (the charge bar is per-player).

Transaction signing bridge

MCP actions never hold keys. structs_action validates preconditions, Rust emits mcp_transaction_request to the webview, the JS SigningClientManager signs+broadcasts via CosmJS, and the result returns over mcp_transaction_response. This is why the app is a safe MCP host: the agent requests signatures, it does not possess them.

Agent-driven UI

structs_board component mode renders on the human’s screen (menu, dialogue, panel, info, map_preview, hud_badge, toast, open_menu, raw_html). notify shows-and-returns; prompt blocks until the human chooses. Guardrails: every agent-drawn surface carries an “⚡ Agent” marker, the agent_ui policy is a master off-switch, and directives are display/elicitation only — they cannot sign (any chosen action still flows through the approval-gated tx bridge).

Notifications

Native OS alerts fire off NATS WebSocket events, filtered to your planet/fleet: raid alerts, structs under attack, enemy fleet incoming/departed, your fleet moved, mining/refining/build started, struct status changed, Alpha Matter transfer, power alert. macOS uses UNUserNotificationCenter (needs a signed .app); Windows/Linux use notify-rust.

Guild configuration

The app connects to a guild’s infrastructure via stored configs (guildApi, reactorApi, clientWs, grassNatsWs); it supports multiple guild configs with one active at a time. A default config ships for new players.


See Also