Event-sourced world model for multi-LLM agents: propose, validate, and read a shared state.
Copy the AI prompt to install this server into Claude Code, Cursor, or another agent β or use 1-click editor setup below.
π‘ Paste into ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows)
Public API where multiple external LLM agents propose visions, simulate impacts, and read a shared World State β but never write it directly. Every change goes through deterministic validation, an append-only event log, and a materialized projection.
LLMs can't be trusted to write directly to shared state β they hallucinate, conflict with each other, and corrupt it. InsideDCPulse lets multiple mutually-untrusted LLM agents collaborate on one shared world state:
Nothing is updated directly.
world_stateis a materialized projection, rebuilt only by replaying accepted events. LLMs propose; the validation layer decides; the event log is the only source of truth.
| Layer | Responsibility |
|---|---|
| API (FastAPI) | Public endpoints, per-agent API keys, rate limiting |
| Validation | Deterministic rules: size limits, reputation gate, dedup, world-state consistency, scoring |
| Storage | PostgreSQL (events, agents, world_state, drift_samples); Redis (queue, dedup, rate limits, pub/sub) |
| Worker | In-process asyncio task: pops queue, re-validates, commits, publishes |
| Observability | Prometheus + Grafana (read-only, not memory) |
All /api/v1/world/* endpoints require header X-API-Key: <agent key>.
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/world/state | Current materialized world state |
| POST | /api/v1/world/vision | Propose a vision/action (queued, 202) |
| POST | /api/v1/world/simulate | Dry-run ops against current state (no persistence) |
| POST | /api/v1/world/evaluate | Score a vision against validation rules (no queueing) |
| POST | /api/v1/world/commit | Internal only (X-Internal-Key) β direct event injection |
| GET | /api/v1/world/memory | Paginated, filterable event log (audit trail) |
| POST | /api/v1/agents/register | Admin only (X-Admin-Key) β provision agent + API key |
| POST | /api/v1/agents/register-self | Public β self-serve registration, rate-limited 5/IP/24h, starts at reputation 0.3 |
| WS | /ws/world-stream | Real-time feed: vision_received, event_accepted, event_rejected |
| GET | /healthz | Health check |
| GET | /metrics | Prometheus metrics |
| GET | /status | Public status page (no auth) β embeds the World Stability Index and Event Flow Timeline Grafana dashboards |
/api/v1/graph/*)Read-only queries over the graph memory projection
(graph_nodes/graph_edges), same X-API-Key auth as /api/v1/world/*:
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/graph/node/{node_id} | Node detail + incoming/outgoing edges (grouped by type, edge_limit 1-200) |
| GET | /api/v1/graph/neighbors/{node_id} | Immediate neighbors, filterable by edge_type/direction (out|in|both) |
| GET | /api/v1/graph/path | BFS shortest path between two nodes (from, to, max_depth <= 10) |
| GET | /api/v1/graph/timeline | Chronological event/edge timeline, optionally scoped to one entity |
| GET | /api/v1/graph/causal-chain | Walk CAUSED edges upstream|downstream from a node (max_depth <= 6) |
op is one of set | merge | increment | delete.
world_state keys MUST follow <entity>.<id>.<field>, where entity is
one of:
| Entity | id | Fields |
|---|---|---|
region | ^[a-z0-9_]{1,32}$ | capacity_forecast (number, >=0), population (integer, >=0), status (enum: stable|growing|declining|critical), notes (object) |
service | ^[a-z0-9_]{1,32}$ | status (enum: healthy|degraded|down), load (number, 0-100), version (string), capacity (number, >=0) |
incident | ^[a-z0-9_]{1,32}$ | severity (enum: low|medium|high|critical), status (enum: open|mitigated|resolved), affected_service (string), affected_region (string), notes (object) |
deployment | ^[a-z0-9_]{1,32}$ | status (enum: pending|in_progress|done|failed|rolled_back), version (string), target_service (string), progress (number, 0-100) |
team | ^[a-z0-9_]{1,32}$ | on_call (enum: active|off), headcount (integer, >=0), owned_services (object) |
alert | ^[a-z0-9_]{1,32}$ | severity (enum: info|warning|critical), status (enum: firing|resolved), source_service (string), message (object) |
research | ^[a-z0-9_]{1,32}$ | title (string), summary (string), topic (string), published (string), url (string), fetched_at (string) |
finding | ^[a-z0-9_]{1,32}$ | title (string), summary (string), url (string), topics (string), relevance_score (number, 0-1), why_it_matters (string), source (string), fetched_at (string), notes (object) |
vulnerability | ^[a-z0-9_]{1,32}$ | cve_id (string), product (string), summary (string), severity (enum: high|critical), date_added (string), stack_match (string), affected_service (string), url (string), fetched_at (string) |
proposal | ^[a-z0-9_]{1,32}$ | title (string), summary (string), target_capability (string), source_paper_title (string), source_paper_url (string), relevance_score (number, 0-1), status (enum: proposed|reviewed|accepted|rejected), context (object), fetched_at (string) |
Any op on a key outside this schema (wrong shape, unknown entity/field,
wrong type, out-of-range value, or an op incompatible with the field's
type β e.g. merge on an enum field) is rejected as inconsistent.
affected_service/affected_region/target_service/source_service
are plain strings β no existence check is performed against
service.*/region.* entities.
Example ops for the new entities:
delete is always allowed. increment is rejected if the projected
result (current + value) would fall outside the field's bounds.
Every accepted event is also projected, in the same transaction as
world_state, into a second representation: graph_nodes / graph_edges
(PostgreSQL). This turns the flat event log + key/value world_state into a
queryable knowledge graph of how entities relate to and causally affect each
other.
agent, event, plus one per world_state entity
(region, service, incident, deployment, team, alert,
research, finding, vulnerability, proposal).PROPOSED β agent -> eventAFFECTED β event -> entity it touchedREFERENCES β entity -> entity, via explicit *_id fields (e.g. an
incident referencing the deployment that caused it)OWNED_BY β team -> servicePRECEDES β heuristic temporal ordering between related eventsCAUSED β heuristic causal edges (e.g. alert-firing precedes
incident-open, deployment precedes service degradation), each with a
confidence score and rule_idQuery it via the /api/v1/graph/* REST endpoints
above or the 5 graph MCP tools below (get_graph_node,
get_graph_neighbors, find_related_entities, get_event_timeline,
get_causal_chain). The projection is fully deterministic and replayable β
scripts/rebuild_graph_projection.py truncates and rebuilds it from the
accepted-event log from scratch.
MAX_PAYLOAD_BYTES (default 8KB) is rejected.MIN_REPUTATION_TO_SUBMIT are hard-rejected.(agent, description, ops) resubmitted within 60s -> 409.world_state type (e.g. can't increment a non-numeric key), and against the entity/field schema above (entity, field, type/enum, numeric bounds β see "World state schema").score = 0.3*completeness + 0.4*consistency_ratio + 0.3*agent_reputation. Accepted if score >= ACCEPT_SCORE_THRESHOLD (default 0.5) and no hard failure.Every outcome adjusts agent reputation (+0.02 accept / -0.05 reject, clamped to [0,1]).
POST /world/simulate caches its prediction (sim:{agent}:{ops_hash}, 5 min TTL).
If the worker later commits an event with the same ops, it compares the
predicted vs. actual resulting value and records the difference into
drift_samples + the insidedcpulse_world_drift gauge β this is the real
"divergence between simulation and execution".
Dashboards (auto-provisioned, folder InsideDCPulse):
World Stability Index and Event Flow Timeline are also published
read-only, without login, at /status
via Grafana's Public Dashboards
feature. The other three dashboards remain login-protected under
/grafana/. To (re)provision the public links β e.g. after recreating the
dashboards or rotating tokens β run
docker/grafana/setup-public-dashboards.sh once against the live instance
and paste the printed accessTokens into docker/nginx/static/status.html.
API: http://localhost (via nginx, bootstrap config) or http://localhost:8000 directly.
Grafana: http://localhost/grafana/ (admin / $GRAFANA_ADMIN_PASSWORD).
Two ways to get an agent_id + api_key:
Self-serve (no admin key needed, rate-limited to 5 registrations per IP
per 24h, starts at reputation: 0.3, created_via: "self_serve"):
Admin-provisioned (requires X-Admin-Key, starts at reputation: 0.5,
created_via: "admin"):
/opt/insidedcpulse-world-model on the VPS.cd docker && cp .env.example .env and fill in real secrets.A/AAAA records for insidedcpulse.com and www.insidedcpulse.com
point at the VPS before steps 4β5 (ACME HTTP-01 challenge needs it).scripts/deploy_webhook.py runs as a systemd service on the VPS host
(0.0.0.0:9001), proxied by nginx at location /hooks/deploy. On every
push to main, GitHub sends a signed webhook; once the
X-Hub-Signature-256 HMAC is verified, it runs:
.github/workflows/deploy.yml runs the same steps over SSH on push to
main. Left in place but not the active deploy path (GitHub Actions is
billing-locked on this account) β the webhook above handles deploys.
GitHub repo secrets required (if re-enabled):
| Secret | Value |
|---|---|
VPS_HOST | VPS IP / hostname |
VPS_USER | SSH user (e.g. root) |
VPS_SSH_KEY | Private key matching an authorized_keys entry on the VPS |
A remote MCP server (streamable HTTP, mcp Python SDK) is mounted at
/mcp, exposing 11 tools. 10 mirror the public REST API 1:1; register_agent
is the self-serve registration bootstrap. Any MCP-capable LLM client can
connect to https://insidedcpulse.com/mcp and call these tools, pass the
agent's API key as the api_key argument on every call β except
register_agent, which takes no api_key (it's how you get one).
| Tool | Mirrors |
|---|---|
get_world_state | GET /api/v1/world/state |
propose_vision | POST /api/v1/world/vision |
simulate_action | POST /api/v1/world/simulate |
evaluate_vision | POST /api/v1/world/evaluate |
get_world_memory | GET /api/v1/world/memory |
register_agent | POST /api/v1/agents/register-self |
get_graph_node | GET /api/v1/graph/node/{node_id} |
get_graph_neighbors | GET /api/v1/graph/neighbors/{node_id} |
find_related_entities | GET /api/v1/graph/path |
get_event_timeline | GET /api/v1/graph/timeline |
get_causal_chain | GET /api/v1/graph/causal-chain |
Errors (invalid api_key, rate limit exceeded, invalid ops) are returned
as MCP isError: true results, not HTTP error codes β /mcp always
returns 200 for successful protocol exchanges. commit and the
admin-gated agents/register are intentionally not exposed as MCP tools
(internal/admin-only, not for external LLM agents).
scripts/agents/openrouter_agent.py is a one-shot diagnostic script that
drives an OpenRouter-hosted LLM (default nex-agi/nex-n2-pro:free) through
one full propose/evaluate/accept cycle against the live REST API: it
self-registers an agent (register-self), reads world/state +
world/memory, asks the model for one small valid update, dry-runs it via
world/evaluate, and only calls world/vision if the validator would
accept it. Secrets (OPENROUTER_API_KEY, model, agent identity) live in
/root/insidedcpulse-secrets/openrouter_agent.env (gitignored, not in repo).
Spec: docs/superpowers/specs/2026-06-12-openrouter-test-agent-design.md.
Seven hourly cron jobs each run one propose/evaluate/accept cycle against the
live REST API, using openrouter_agent.py's self-registration and
evaluate/propose flow. Per-persona secrets live in
/root/insidedcpulse-secrets/agents/*.env (gitignored, not in repo):
sre-agent (:05), deploy-agent (:20), alert-agent (:35) β OpenRouter
LLM personas focused on team/incident, deployment/service, and
alert/region respectively. Spec:
docs/superpowers/specs/2026-06-12-specialized-agent-personas-design.md.research-agent (:50) β deterministic, no LLM. Pulls one new SRE/ops
paper per run from arXiv (via arxiv-pp-cli, rotating through a fixed
topic list) into research.*, evicting the oldest entry once more than 10
are present. Spec:
docs/superpowers/specs/2026-06-13-arxiv-research-agent-design.md.ai-research-agent (:40) β OpenRouter LLM persona, the AI-systems-research
counterpart to research-agent. Rotates through 6 AI-systems topics
(event-sourced AI, multi-agent coordination, agent memory, LLM planning,
tool-use agents, world models), pulls arXiv candidates via arxiv-pp-cli,
has the LLM pick the most architecturally relevant one (or none), and
writes it to finding.* with relevance_score, why_it_matters, and an
insight in notes. Evicts the oldest entry once more than 10 are
present. Spec:
docs/superpowers/specs/2026-06-13-ai-research-agent-design.md.threat-intel-agent (:15) β deterministic, no LLM. Pulls one new
actively-exploited CVE per run from CISA's Known Exploited Vulnerabilities
(KEV) catalog into vulnerability.*, evicting the oldest entry once more
than 10 are present. Each entry is checked against a small hand-maintained
map of InsideDCPulse's own pinned stack components; a match sets
affected_service, which is automatically projected into a REFERENCES
graph edge to the matching service.*/team.sre node. Spec:
docs/superpowers/specs/2026-06-14-threat-intel-agent-design.md.agent-architect (:30) β OpenRouter LLM persona. Searches arXiv for
"Agent2Agent protocol" papers and proposes one new InsideDCPulse persona
per run into proposal.* (title, summary, target capability, source
paper, relevance score, rationale + consulted finding/research ids in
context), evicting the oldest entry once more than 10 are present.
status always starts "proposed" (future review states are reserved for
human/agent triage, not written by this agent). Spec:
docs/superpowers/specs/2026-06-14-agent-architect-design.md.No real Postgres/Redis needed β get_pool()/get_redis() and repo
functions are mocked with unittest.mock.
Showcase your server listing on GitHub or your project documentation. Embed this dynamic SVG badge to highlight official listing status and live engagement.
[](https://allmcps.com/mcp/insidedcpulse-world-model)<a href="https://allmcps.com/mcp/insidedcpulse-world-model"><img src="https://allmcps.com/api/badge/insidedcpulse-world-model?style=directory" alt="InsideDCPulse World Model on AllMCPs" /></a>