Static reference for the interfaces available to play Structs (Desktop MCP, structsd
CLI, GRASS streaming, Guild Stack). Read this to understand what each tool does.
Your connection details (RPC, chain ID, key name, MCP URL) and preferences now live in
config/operator.md(copy fromconfig/operator.example.md). To detect what’s actually available in your environment, runscripts/preflight.sh— it writes a capability profile toconfig/environment.json. This page is the catalog; that profile is the truth for your machine.
The structsd binary must be installed before you can play. If structsd version fails, use the structsd-install skill to either download a prebuilt release binary or build from source via the Makefile (Go 1.23+).
Never commit mnemonics, private keys, or secrets to the repository.
Storage options (in order of preference):
export STRUCTS_MNEMONIC="word1 word2 ..." — set per session, no file on disk..env file: Store in the workspace root as STRUCTS_MNEMONIC=.... The .env file must be in .gitignore.structsd keys add [name] stores the key in the system keyring. Retrieve the address with structsd keys show [name] -a. The mnemonic is still needed for guild signup (Path B in onboarding).The guild signup script reads the mnemonic from its --mnemonic argument. Pass it from the environment: --mnemonic "$STRUCTS_MNEMONIC".
Warning: structsd keys add --output json outputs the mnemonic in plaintext to stdout. Avoid --output json unless redirecting to a secure file. The default text output shows the mnemonic only once during creation.
Structs can run in several configurations:
structs-desktop app gives a human the game interface and embeds an MCP server their agent connects to (see MCP Tools). This is the standard setup for a human playing alongside their agent — nothing else to deploy.Check which deployment you’re connected to and update the URLs below accordingly.
For sub-second game state queries, real-time threat detection, and combat automation, deploy the Guild Stack locally via Docker Compose. It provides PostgreSQL-indexed game state (via structs-sync-state), a local GRASS/NATS server, webapp, and optional transaction signing agent.
Repository: https://github.com/playstructs/docker-structs-guild
Setup: git clone the repo, configure .env, run docker compose up -d, wait for chain sync (hours on first run). See the structs-guild-stack skill for the full procedure.
The guild stack is optional – CLI commands via a remote node work for basic gameplay. PG access becomes essential for combat automation and galaxy-wide intelligence.
public.testnet.structs.network is a public Structs testnet node served over SSL. Use it for queries when no local node is available — the SSL endpoint avoids mixed-content and CORS issues that plagued the older HTTP testnet hosts.
https://public.testnet.structs.networkhttps://public.testnet.structs.network:26657wss://public.testnet.structs.network:26657/websockethttps://public.testnet.structs.network/structs/guildThis node runs only structsd (chain). Guild API and GRASS NATS WebSocket services are hosted by individual guilds — see the guild config you fetch from /structs/guild.
By default, structsd commands connect to localhost:26657. If you are not running a local node, you must configure a remote node or every command will fail.
Option 1: Set the default node permanently by editing ~/.structs/config/client.toml:
broadcast-mode = "sync"
chain-id = "structstestnet-111"
keyring-backend = "test"
node = "https://public.testnet.structs.network:26657"
output = "text"
Option 2: Per-command flag for one-off queries:
structsd query structs player 1-11 --node https://public.testnet.structs.network:26657
If you see connection errors like “connection refused” on port 26657, you need to configure this.
| Service | URL | Status |
|---|---|---|
| Consensus API | http://localhost:1317 |
(fill in: running/offline) |
| Webapp API | http://localhost:8080 |
(fill in: running/offline) |
| NATS Streaming | nats://localhost:4222 |
(fill in: running/offline) |
| GRASS WebSocket | ws://localhost:1443 |
(fill in — or use guild config’s grass_nats_websocket) |
Address: (fill in during first session — your cosmos address)
Player ID: (discover via structsd query structs address [your-address])
Fleet ID: (matches player index: player 1-18 has fleet 9-18)
To find your player ID from your address: structsd query structs address [your-address]. If the result shows player ID 1-0, no player exists for that address yet.
Never store private keys here. Use environment variables or a secure keystore.
Guild ID: (fill in after joining a guild — or set as preferred guild for signup)
Guild Name:
Guild API: (from the guild config’s services.guild_api field — needed for programmatic signup)
Role:
Central Bank Status:
To discover available guilds and their configs, see the onboarding skill’s guild signup section or query: curl https://public.testnet.structs.network/structs/guild
| Player ID | Name/Alias | Guild | Relationship | Notes |
|---|---|---|---|---|
| Planet ID | Name | Status | Primary Use | Notes |
|---|---|---|---|---|
Agents play Structs through the MCP server embedded in structs-desktop. The human runs the desktop app for the game interface, and their agent connects to that same app over MCP — one program gives both the human’s screen and the agent’s tools, with no separate infrastructure to deploy. This is the standard way for a human and their agent to play together.
The embedded server runs on http://127.0.0.1:8420/mcp with bearer-token authentication. The exact URL and token are shown in the app’s Debug menu panel (and the browser console); the Debug panel can copy a ready-made .mcp.json for you:
{
"mcpServers": {
"structs-game": {
"type": "http",
"url": "http://127.0.0.1:8420/mcp",
"headers": { "Authorization": "Bearer YOUR_TOKEN_HERE" }
}
}
}
The bearer token is generated on first launch and stored with the app’s config. Every request must carry it — requests without the token are rejected (400 Bad Request), which keeps other local processes and websites from driving the game. Treat the token like a key.
| Tool | Purpose |
|---|---|
structs_dashboard |
Full player overview: power, charge (with per-action readiness), resources, structs + HP, hash tasks, recent events. player_id defaults to the logged-in player |
structs_hash |
Proof-of-work tasks — list / start (task_type MINE, REFINE, BUILD, RAID) / progress / stop / config (enabled, engine cpu/gpu/auto, difficulty_start, max_concurrent, auto_tune) |
structs_action |
Execute one game action with preflight checks: explore, build, mine, refine, attack, defend, activate, deactivate, move_fleet, transfer, deploy, raid, update_primary_reactor, resync |
structs_intel |
Strategic intelligence + perception. query is one of whoami, intents, ruleset, simulate, strike_options, what_can_i_build, power_forecast, economy_status, plan_timeline, planet_history, valid_targets, scout, battle_log, slot_map, is_active, market, metric_trend, query (raw entity reads) |
structs_policy |
Standing orders — list / set / remove / log over auto_refine, power_alert, combat_alert, agent_ui, auto_counterattack, auto_retreat_if_cmd_below, auto_rebuild_losses, rules_of_engagement, primary_home_guard, board_auto_open, watchdog_remediate |
structs_events |
Long-poll event feed (wait_secs) with mine_only, team (whole roster), threats_only (server-side threat classifier — a ready-made under-attack detector), category, since/next_cursor |
structs_sequence |
Guarded autonomous action chains, paced to the charge cooldown, with abort_if predicates; as runs the chain as a virtual player |
structs_players |
Virtual players and the native automation loops: list, roster, create, state, act, capacity, role, economy, infra, harvest, autobuild, autodefend, autoresponse, autoraid, infuse |
structs_board |
Team Ops board + human UI (component elicitation) and web dashboard toggle. MCP board path never signs; web:"on" serves a separate human dashboard that can sign — see below |
structs_system |
Health, logs, self-tuning — status, logs, loops, tx, pow, watchdog, feed, config |
structs_map |
Render a planet map to PNG/GIF using the game’s renderer |
structs_doctrine |
Standing rules of engagement, per-tick executor, and the persistent combat lists (set / show / tick / lists, autonomy advise/auto, presets turtle / economy / balanced / warfighter) |
structs_strike |
Coordinated team attack + kill-chain (strip blockers → kill → raid window) |
Full descriptions, parameters, and subsystems: knowledge/infrastructure/structs-desktop.md. (structs_query and structs_ui were folded into structs_intel and structs_board. The old names still answer with a pointer to the replacement, but are no longer advertised — tools/list returns exactly the 13 above.)
The Desktop Command Center pages (Armada, Energy, Work, Tx, War, Inventory, Config, …) use internal Tauri/web_board handlers (board_pages.rs) — they are not extra MCP tools. Multi-guild infra switching is app-side (guild_config + guild_directory discovery); agents do not get a separate guild-config tool.
| Prompt | Purpose |
|---|---|
getting_started |
Guided first session for a brand-new player: explore → build → mine → refine, with the agent as the tutorial |
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 |
This structs-ai compendium is bundled as MCP resources, so an agent can read the docs on demand by URI (e.g. structs://START.md, structs://play/index.md, structs://knowledge/mechanics/combat.md, structs://reference/index.md). URIs are derived from the file tree — see the resource map and develop/structs-resources.md.
The sync is a build step, so a given build may ship none. A live server checked on 2026-07-24 returned an empty resources/list and 404’d every URI above. Call resources/list once before relying on it, and fall back to structs.ai or a local checkout if it is empty.
The MCP never holds keys: structs_action/structs_sequence submit through the app’s CosmJS bridge after preflight checks, and the engine never auto-signs outside those gated paths. structs_sequence paces action chains to the per-player charge bar with abort predicates; structs_board can drive the human’s screen for co-op (display/elicitation only — it cannot sign). The native automation loops (structs_players harvest / autobuild / autodefend / infuse) do auto-sign for the players they manage and are off until you enable them. Two further loops — autoresponse and autoraid — auto-sign combat: returning fire when raided, and selecting and raiding targets. Both are off by default and, once enabled, still default to autonomy: advise (they explain, they do not sign) until you set autonomy: auto. Treat arming either as a standing grant to attack other players; see SAFETY.md. See structs-desktop.md for the policy engine, virtual players, hashing, and agent-driven UI.
structs_board {web:"on"} serves the same Team Ops dashboard as a web page at http://127.0.0.1:8420/board?token=… (off by default). The server still binds loopback only, so a remote human reaches it through their own tunnel (ssh -L 8420:127.0.0.1:8420 user@host). The token in that URL is the MCP bearer token and grants full operator control, including mass actions that sign transactions — treat it like a password and turn the dashboard off with structs_board {web:"off"} when you’re done.
When the desktop app isn’t running, fall back to direct CLI commands: structsd tx structs [command] and structsd query structs [command]. See reference/api-quick-reference.md for endpoint details.
Common pitfalls when using structsd directly:
| Gotcha | Problem | Fix |
|---|---|---|
-- separator |
Entity IDs like 3-1 or 4-5 are parsed as flags by the Cobra CLI parser |
Place -- after all flags and before positional args: structsd tx structs command --from key --gas auto -y -- 4-5 6-10 |
| reactor-infuse address | Takes the validator address (structsvaloper1...), not the reactor ID (3-1) |
Look up the reactor’s validator field first: structsd query structs reactor [id] |
| Amount denomination | Amounts must include the denomination suffix | Use 60000000ualpha not 60000000. Same for guild tokens: 100uguild.0-1 |
| provider-withdraw-balance | Takes two positional args: provider ID (contains a dash) and the destination address for the earnings | Use: structsd tx structs provider-withdraw-balance --from key --gas auto -y -- [provider-id] [destination-address] |
| substation-create | Takes two positional args: owner player ID and allocation ID | Use: structsd tx structs substation-create --from key --gas auto -y -- [owner-id] [allocation-id] |
| Sequence mismatch | Two transactions from the same account at the same time | Wait ~6 seconds between transactions from the same key |
| TX fees | Players don’t need Alpha tokens to pay gas fees | Pure Structs gameplay messages are free (dedicated free-gas meter, no ualpha fee) — see transactions. Still pass --gas auto. Being online/powered gates acting; it is not a per-tx fee |
| Concurrent PoW | Two *-compute jobs sharing the same signing key submit conflicting sequence numbers |
Use one signing key per player; never run concurrent compute jobs on the same key |
Update this file when your environment changes.