Eco MCP battery: node-local privileged surface for warded agents to inspect on-disk server state #42
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Goal
Let warded directors and engineers inspect the state of the local Eco game server on disk. Rather than bind-mount the live
EcoServer/tree into every warded container (heavy, and leaks Discord/Chronicler/API tokens sitting inConfigs/), expose the state over a network MCP surface the agents fetch. This is the inside-out counterpart to eco-app's existing outside-in MCP.Two views, this is the second
/infoendpoint, redacts player names, serves anyone. Live runtime, network-visible.Configs/,Storage/saves +Backup/(×40), the Chronicler SQLite history, per-subsystemLogs/, unredacted admin data, mod install state, and the loopback-only admin endpoints. Privileged, at-rest + admin, warded-agents-only.Home
Fold into
coilyco-gaming/eco-appas a second, privileged MCP surface (distinct deployment from the public one). Decided.Where it runs - node-local k3s pattern
The Eco server is a native systemd service (
eco-server.service) at/home/kai/Steam/steamapps/common/EcoServer/, NOT in k3s. But k3s runs on the same host, so a pod pinned to kai-server:hostPath-mountsEcoServer/{Configs,Storage,Logs,Mods}read-only, and127.0.0.1:3001/:3002admin endpoints over thehostAliasesloopback pin.MCP is exposed over the tailnet sidecar (reuse eco-app's deploy idiom), ACL'd to the ward/kai-server tailnet, not the public ingress. This is a node-agent MCP: the same DaemonSet-or-node-pinned + hostPath shape as node-exporter / promtail / CSI node plugins.
Tool inventory (provisional)
Save + world (
Storage/):eco_save_status(Game.eco/Game.db size + age since last autosave),eco_backup_list(Backup/ count, cadence, newest/oldest),eco_world_meta(size, seed, cluster centers, world-days).Config (
Configs/, redacted, enum-not-path):eco_config_get(named .eco/.diff.json),eco_config_diff(diff vs *.original.json - what's tuned off default),eco_mod_configs(MightyMooseCore, DiscordLink, StrangeWorlds, NidToolbox - secrets stripped).Chronicler / events (SQLite, read RO):
eco_events_recent(joins, laws, elections, deaths),eco_player_activity(from EcoReplay.db / Chronicler, redaction-gated).Logs (
Logs/<subsystem>/):eco_log_tail,eco_log_grep(named subsystem enum: MightyMooseCore, NidToolbox, web, Kestrel, migrations).Live runtime (loopback
:3001admin/exporter):eco_live_status(players, world time, next meteor, uptime - unredacted),eco_service_health(systemd active-state + last restart).Mods (
Mods/):eco_mods_installed(modules + versions, drift vs push-mods manifest).Security boundary
public(names hashed),operator(names shown, secrets stripped),raw(operator + secrets - default DENY). Proposed default:operatorfor the trusted warded callers;rawoff by default. Secrets (Discord bot token,/eco/server-api-token, any token in Configs) never returned aboveraw.../../.ssh.Proposed defaults for the open questions
operator(names shown, secrets always stripped). Open to holding atpublic./infoclient as a thin add-on, not a reimplementation.Build phases
eco_save_status+eco_backup_list+eco_config_getagainst a local checkout of the state dirs - prove tools + redaction on real files.coilyco-bridge/deploy/services/, hostPath RO mounts, node pin, loopback pin, tailnet sidecar, ward ACL.Context
/home/kai/Steam/steamapps/common/EcoServer/(the eco-server-setup skill's/home/ubuntu/games/eco/paths are stale legacy).Storage/Game.db(256MB world SQLite),Game.ecosave,EcoReplay.db,Backup/×40,Configs/*.eco+*.diff.json+*.original.json,Logs/{MightyMooseCore,NidToolbox,web,Microsoft.AspNetCore.*,migrations}/.0.0.0.0:3001(Kestrel/ASP.NET, 200 on/and/api) +:3002.coilysiren/eco-mcp-app).Filed from a spec drafting session on kai-server.
Two refinements (director session, 2026-07-05):
1. REST is out of scope — MCP-only. The surface stays a network MCP; no parallel REST API. (It still consumes the loopback admin REST endpoints, but only re-exposes them as MCP tools.)
2. Access model: add an
/adminmount + the Authelia OAuth overlay for the claude.ai-hosted-connector path, complementing the tailnet-agent path this spec already has. Two callers, one surface:tailnet ACL, warded-agents-onlymodel.Ergonomics: the auth is not eco-app code — it is an ingress-layer overlay (deploy repo). eco-app only adds the
/adminStarlette mount, feature-flagged (ECO_ADMIN_ENABLED) so only the privileged node-local deployment exposes it.eco-mcp.coilysiren.mealready serves eco-app's MCP through Traefik + external-dns + LE, so there is no ingress to invent, only a gate to add in front of one path.Threat model unchanged: the overlay authenticates who, it does not relax this spec's redaction levels — secrets stay default-DENY even for an authenticated caller. On-disk data access (hostPath RO, node-pin) is orthogonal to the auth gate and stays as specified.