How MiroShark works
A deep walkthrough of the engine, by category.
MiroShark is a universal swarm-intelligence engine. You bring a scenario; it builds the world around it - a temporal knowledge graph, hundreds of grounded personas, three platforms running in lockstep, and a citing report at the end. Here is exactly how each layer is wired.
Last updated · July 23, 2026
MiroShark ships fast - this page is a snapshot, not a contract. For the latest features, env vars, model defaults and breaking changes, check the repo directly: recent commits, open & merged PRs, README and docs/. When in doubt, the code on main is the source of truth.
The five-step pipeline
Document in, world out. Every simulation walks the same five stages: build a graph, ground the personas, run three platforms in parallel, write a citing report, and let you interact.
1 · Graph build
2 · Agent setup
3 · Simulation
4 · Report
5 · Interaction
Output surfaces
document ─▶ graph build ─▶ persona grounding ─▶ 3× platform loop ─▶ report
│
├─ Director Mode (inject)
├─ Fork (branch)
└─ Persona Chat (DM)Knowledge graph & memory pipeline
A Neo4j-backed temporal graph - NER, entity resolution, contradiction detection, fused retrieval, and Leiden community clusters - inspired by Hindsight, Graphiti, Letta and HippoRAG.
Ingestion
Text flows through NER (with an ontology) into a batched embedding call (OpenRouter text-embedding-3-large or a local Ollama equivalent). Entity resolution combines fuzzy matching, vector similarity, and an LLM reflection step - collapsing “NeuralCoin”, “Neural Coin” and “NC” into one canonical UUID. Same-endpoint relationship pairs are sent to an LLM adjudicator that invalidates the older edge instead of stacking contradictions.
text → NER (with ontology)
→ batch embed (text-embedding-3-large | Ollama)
→ entity resolve (fuzzy + vector + LLM reflection)
→ MERGE entities (canonical UUIDs)
→ contradiction adjudication (invalidate old)
→ CREATE RELATION {valid_at, invalid_at, kind, source_type, source_id}Retrieval
Each query fans out into three parallel searches - vector edge search over Neo4j HNSW, BM25 fulltext, and a BFS traversal from seed entities. The top 30 candidates are fused, filtered by valid_at / kind, and re-ranked by a BGE-reranker-v2-m3 cross-encoder on Apple MPS, CUDA or CPU.
query
├─ vector edge (Neo4j HNSW) ─┐
├─ BM25 edge (Neo4j fulltext) ─┼─ temporal + kind filters → fused top 30
└─ BFS traversal (from seed entities) ┘
↓
BGE-reranker-v2-m3 (MPS / CUDA / CPU)
↓
top N tagged with _sources ("v" / "k" / "g" / combos)Communities (zoom-out)
Reasoning memory
What it buys you
Persona generation & grounding
Each agent is built from five layers of context - graph attributes, relationships, semantic neighbours, BFS context and (optionally) live web research - then anchored to Nemotron demographics.
Five layers of grounding
Individual vs institutional
Web enrichment
Self-hosted search & scrape (SearXNG / Firecrawl)
Demographic anchoring (Nemotron)
entity ─┬─ attrs (Neo4j properties)
├─ relationships (1-hop edges)
├─ semantic (vector neighbours)
├─ BFS context (multi-hop)
└─ web enrichment (Perplexity / Sonar - public figures only)
↓
persona prompt ─▶ Wonderwall agent loopCross-platform simulation engine
Twitter, Reddit and a Polymarket-style prediction market run simultaneously every round. Belief states track stance, confidence and trust; a sliding-window memory keeps prompts compact.
┌──────────────────────────────────────────────────────────┐
│ Round Memory (sliding window) │
│ Old rounds: LLM-compacted summaries │
│ Previous round: full action detail │
│ Current round: live (partial) │
└────┬─────────────┬─────────────┬─────────────────────────┘
│ │ │
┌────▼────┐ ┌────▼────┐ ┌────▼──────────┐
│ Twitter │ │ Reddit │ │ Polymarket │
│ Posts │ │ Comments│ │ Trades (AMM) │
│ Likes │ │ Upvotes │ │ Single market │
│ Reposts │ │ Threads │ │ Buy/Sell/Wait │
└────┬────┘ └────┬────┘ └────┬──────────┘
│ │ │
┌────▼─────────────▼─────────────▼─────────────────────────┐
│ Market-Media Bridge │
│ Social sentiment → trader prompts │
│ Market prices → social media prompts │
│ Social posts → trader observation │
└────┬─────────────┬─────────────┬─────────────────────────┘
│ │ │
┌────▼─────────────▼─────────────▼─────────────────────────┐
│ Belief State (per agent) │
│ Positions: topic → stance (-1 to +1) │
│ Confidence: topic → certainty (0 to 1) │
│ Trust: agent → trust level (0 to 1) │
└──────────────────────────────────────────────────────────┘Three platforms, one round
Market-Media Bridge
Prediction market
Belief states
Sliding-window memory
Per-round frame API
Performance numbers (vs. naive baseline)
Neo4j writes 1 tx per entity → batched UNWIND (10×) Chunk processing sequential → ThreadPoolExecutor (3×) Config generation sequential batches → parallel batches (3×) Platform execution partial concurrency → all 3 in parallel Memory compaction blocking → background thread
Live interaction - Director, chat, forks
Inject breaking news mid-run, fork the timeline with a counterfactual event, or DM any agent. Forks are first-class siblings; comparisons are diffable.
Director Mode (inject)
Counterfactual Branching (fork)
Persona chat
Reports, signals & analytics
A ReACT report agent cites real posts and trades. Trajectory chart, signal JSON, peak-round analytics, per-agent sparklines, consensus badge, Nash equilibrium tool.
ReACT report agent
Signal JSON & direction
Trajectory chart (SVG)
Consensus badge (SVG)
Peak-round analytics
Belief volatility
Per-agent sparklines
Agent roster (agents.json)
Polymarket-ready prediction
Platform & project stats
Run cost (cost.json)
Predictive accuracy ledger
Quality diagnostics
Inputs - Smart Setup, Just Ask, Trending
Drop a doc, type a question, pick from RSS-driven trending news, or use one of six preset templates. Shareable links land readers on a pre-filled form.
Smart Setup
What's Trending
Just Ask
Preset templates
Live Oracle data (FeedOracle MCP)
Per-agent MCP tools
Locale - EN / 中 / DE / FR
Model routing - six slots, one key
LLM / Smart / Wonderwall / NER / Embedding / Reranker. One OpenRouter key, five env slots, full freedom to mix providers - including self-hosted vLLM or Claude Code with no API key.
MiroShark splits work across six independent model slots, so you can keep the cheap loop cheap and spend on the few prompts that actually steer the run.
LLM (default)
Smart
Wonderwall
NER
Embedding
Reranker
One key, five slots
The recommended path is a single OpenRouter key pasted into the five API-key env vars (LLM_API_KEY, SMART_API_KEY, NER_API_KEY, OPENAI_API_KEY, EMBEDDING_API_KEY). First run is ~10 min and ~$1.
Claude Code mode
Local Ollama
CoT toggle
MCP, webhooks, notifications
MCP server for Claude Desktop / Cursor / Windsurf / Continue. Signed webhooks with delivery log. Channel-native completion notifications on Discord, Slack, Email and Telegram. PWA push.
MCP server
Webhooks
Webhook event filter
WaybackClaw archive
Discord
Slack
Email (SMTP)
Telegram
PWA push
History database
Export, embed & provenance
37 published surfaces - reproducibility JSON, BibTeX, Jupyter, per-run cost, oEmbed/Frame v2, archive bundle, clone inputs, a self-describing /api/surfaces.json catalog - plus on-chain DKG and WaybackClaw IPFS/Nostr provenance.
Reproducibility JSON
Clone inputs (clone.json)
On-chain provenance (DKG)
BibTeX
Jupyter notebook
Archive bundle
Tweet thread export
oEmbed auto-unfurl
Farcaster Frame v2
Public gallery feeds
Live watch page
Surface catalog (surfaces.json)
Every export surface listed here is built on pure stdlib - no extra dependencies - and is opt-in via env flag. See the full reference in docs/FEATURES.md.
Ecosystem & integrators
Projects, agents and tools built on MiroShark - a human-readable ECOSYSTEM.md and a machine-readable /api/ecosystem.json catalog that integrators and registries crawl.
ECOSYSTEM.md (human-readable)
/api/ecosystem.json (machine-readable)
Who's building on it
Drive it from anywhere
GET /api/ecosystem.json
{ "success": true,
"data": {
"schema_version": "1",
"count": 14,
"ecosystem": [
{ "name": "Sparkleware", "category": "integration",
"x_handle": "…", "repo": "https://github.com/…" },
…
] } }Add your project with a PR to ECOSYSTEM.md - a square 40 px logo, one-line description, category, and links. The machine-readable catalog stays in lockstep via a drift-guard test.
Run MiroShark over x402
x402 turns the dormant HTTP 402 "Payment Required" status into a real payment rail: the server answers a request with a price, the client pays stablecoin over HTTP, and the same request goes through - no account, no API key, no signup. MiroShark is a paid x402 endpoint - your agent POSTs a prompt, pays $1 USDC, and gets back a live URL where a full multi-agent simulation report appears in ~10 minutes.
What you get for $1
Flat price, one dollar
No account, no key
Two chains, one endpoint
POST /run ($1 USDC)
│
├─ ingest seed → entities (~8 s)
├─ ontology entity types (~10 s)
├─ graph_build Neo4j knowledge graph (~11 s)
├─ create simulation scaffold (~0 s)
├─ prepare ~25 grounded personas (~70 s)
├─ simulate 10 rounds · Twitter/Reddit/Market (~6–18 min)
└─ report cited markdown post-mortem
│
└─▶ share_url (auto-published, recap card, 7 panels)The /run endpoint - seeds & price
POST /run with exactly one seed - a prompt, an article URL, or raw text. The price is a flat $1.00 USDC, settled on Base or Solana - the 402 advertises both and your wallet picks the chain it holds.
One seed, three shapes
{"prompt": "<scenario or question, 4–4000 chars>"} ← most common
{"url": "<article / news URL - MiroShark fetches & simulates it>"}
{"article": "<raw document text, 4–200000 chars>"}Price
No gas needed
Where the $1 goes - pick the chain your wallet holds
Base mainnet network eip155:8453
USDC 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
payTo 0x6cab485fc28ec70d3845113b704d4824e4d2b24f
amount "1000000"
Solana mainnet network solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp
USDC EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v
payTo 9vWbPNMvt8ui1cNN8jWWPUWT5LPmeXzq7nr3vry1vMPH
amount "1000000"Always trust the authoritative values in the live 402 response's PAYMENT-REQUIRED header (base64 JSON, field accepts[]) over anything hardcoded - a real x402 client reads them for you at call time. The values above are just a head-start so you can pre-fund the right wallet.
The x402 payment flow
The standard x402 v2 flow: POST → 402 with a PAYMENT-REQUIRED header → sign the USDC transfer → re-POST with PAYMENT-SIGNATURE → 202 Accepted with your run_id and follow URLs. Gas is sponsored by the CDP facilitator.
1. POST /run (no payment)
↓
2. 402 Payment Required + PAYMENT-REQUIRED header (base64 accepts[])
↓
3. client decodes accepts[], signs the USDC transfer authorization
↓
4. POST /run again + PAYMENT-SIGNATURE header (the signed payload), SAME body
↓
5. server settles on-chain → 202 Accepted + PAYMENT-RESPONSE (tx hash)What a v2 SDK does for you
The 202 response body
HTTP/2 202 Accepted
PAYMENT-RESPONSE: <base64 SettleResponse - tx hash + payer + network>
{
"success": true,
"data": {
"run_id": "run_86ead0ea7fa7",
"status": "queued",
"stages": ["ingest","ontology","graph_build","create","prepare","simulate","report"],
"wait_url": "https://x402.miroshark.xyz/wait/run_86ead0ea7fa7",
"status_url":"https://x402.miroshark.xyz/status/run_86ead0ea7fa7",
"payer": "0xYourWalletAddress",
"payment_chain": "base",
"payment_network": "eip155:8453"
}
}Pay from any runtime
Drop-in code for the official x402 SDK in Python (Base + Solana) and TypeScript, the awal CLI for shell agents, the payments MCP for Claude Desktop / ChatGPT, and an ERC-7710 sidecar for MetaMask Smart Accounts.
Python - Base (EVM), official x402 SDK
pip install 'x402[evm,requests]' eth-account requests
import os
from eth_account import Account
from x402.client import x402ClientSync
from x402.http.clients import x402_requests
from x402.mechanisms.evm.exact.client import ExactEvmScheme
account = Account.from_key(os.environ["X402_BUYER_PRIVATE_KEY"])
client = x402ClientSync()
client.register("eip155:8453", ExactEvmScheme(signer=account)) # Base mainnet
session = x402_requests(client) # handles 402 → sign → retry automatically
resp = session.post(
"https://x402.miroshark.xyz/run",
json={"prompt": "How will developers react if OpenAI releases GPT-6 next month?"},
timeout=120,
)
data = resp.json()["data"]
print("Run ID:", data["run_id"], "| follow:", data["wait_url"])Fund the address with ~$1+ USDC on Base mainnet - no ETH needed, settlement gas is sponsored.
Python - Solana (SVM)
pip install 'x402[svm,requests]'
import os, json
from solders.keypair import Keypair
from x402.client import x402ClientSync
from x402.http.clients import x402_requests
from x402.mechanisms.svm.exact.client import ExactSvmScheme
from x402.mechanisms.svm.signers import KeypairSigner
SOLANA_MAINNET = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"
raw = os.environ["SOLANA_BUYER_PRIVATE_KEY"].strip()
kp = (Keypair.from_bytes(bytes(json.loads(raw))) if raw.startswith("[")
else Keypair.from_base58_string(raw))
client = x402ClientSync()
client.register(SOLANA_MAINNET, ExactSvmScheme(signer=KeypairSigner(kp)))
session = x402_requests(client) # picks the Solana accepts[] entry automatically
resp = session.post(
"https://x402.miroshark.xyz/run",
json={"prompt": "Your scenario"}, timeout=120,
)
print(resp.json()["data"]["run_id"]) # paid on: "solana"TypeScript / JavaScript
npm install @x402/fetch @x402/evm viem
import { x402Client } from "@x402/fetch";
import { registerExactEvmScheme } from "@x402/evm/exact/client";
import { privateKeyToAccount } from "viem/accounts";
const client = new x402Client();
const signer = privateKeyToAccount(process.env.X402_BUYER_PRIVATE_KEY as `0x${string}`);
registerExactEvmScheme(client, { signer });
const res = await client.fetch("https://x402.miroshark.xyz/run", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ prompt: "Your scenario" }),
});
const data = (await res.json()).data;Shell / CLI agents
npx awal x402 pay \
https://x402.miroshark.xyz/run \
--body '{"prompt":"Your scenario"}'MCP-only hosts
MetaMask Smart Accounts
Any x402 v2 client works - these are the common ones. To mint a throwaway EVM wallet locally (the key never leaves your machine): python -c "from eth_account import Account; a=Account.create(); print(a.address, a.key.hex())", then fund it with USDC on Base.
Tuning the run & earning
One optional field rides along with any seed: prediction_market to pin the central market. Attach a Base Builder Code to your payment client to earn on the runs you drive - a share of each run from MiroShark (10% by default), plus Base's own builder rewards, both from the same on-chain attribution. A live-web deep-research sweep runs automatically for prompt seeds.
deep research - automatic for prompt seeds
{"prompt": "EU AI Act enforcement in 2026"}
// → live-web deep research runs automaticallyprediction_market - pin the market
{"prompt": "...",
"prediction_market": {
"question": "Will Argentina win the 2026 FIFA World Cup?",
"outcome_a": "YES", "outcome_b": "NO",
"initial_probability": 0.28
}}builder code - earn a share of every run you drive
Attach your own Base Builder Code to the x402 client you pay with, and every run you drive is attributed to your app on-chain (ERC-8021). That attribution earns you two ways on the same runs: MiroShark routes your share (10% by default) into a per-builder 0xSplits split at settlement, enforced on-chain - and it also counts toward Base's own builder rewards (base.dev analytics + program rewards).
You earn 10% of each run's $1 payment by default, paid on-chain into an immutable, ownerless 0xSplits contract. Nobody - MiroShark included - can redirect it or change the share. Anyone can trigger the payout, at any time, from the x402aff dashboard; the funds only ever reach the builder and the seller, so whoever clicks pays the gas and receives nothing extra.
npm install @x402/extensions
import { BuilderCodeClientExtension } from "@x402/extensions/builder-code";
// on the same x402Client() you registered the scheme on, before paying:
client.registerExtension(new BuilderCodeClientExtension("bc_yourcode"));
// every payment you drive now carries your code on-chainGet a code at base.dev → Settings → Builder Codes (format ^[a-z0-9_]{1,32}$). Attribution is written on-chain on Base mainnet via the CDP facilitator; verify any settlement at buildercode-checker.vercel.app.
run the same thing on your own API
None of this is MiroShark-specific. The revenue share is an open-source kit, x402aff, and any x402 seller can pay their own builders the same way. It deploys no contracts of its own - it reads the Base Builder Codes registry and lets the stock CDP facilitator settle into an audited 0xSplits contract, so there is no facilitator to run and no key to hold.
npm install x402aff viem # or: pip install x402aff
import { Affiliation } from "x402aff";
const aff = new Affiliation({ appCode: "bc_yourcode", sellerPayout: "0x…" });
const payTo = await aff.payToFor(req.headers); // the split, or your wallet
const extensions = aff.extensions; // declares your codeSet your route's payTo to aff.payToand each payment settles into a per-builder split instead of your wallet. An unknown or unresolvable code falls back to your wallet, so a payment never fails - it just isn't split. The x402aff dashboard is this kit running live against MiroShark, and its All sellers view lists every split the kit has routed on Base, whoever runs it.
Follow the run & read the report
The run_id is the token - no auth. Poll /status for JSON, open /wait for an auto-refreshing page, or pull the finished report as raw markdown or JSON from /report. Every run auto-publishes a shareable recap card.
status_url - JSON, for agents
wait_url - HTML, for humans
The status payload (declared in /openapi.json)
GET /status/<run_id>
{
"success": true,
"data": {
"run_id": "run_86ead0ea7fa7",
"status": "running", // queued | running | completed | failed | budget_exceeded | cancelled
"progress": 42, // 0–100
"current_stage": "simulate",
"current_round": 4,
"message": "Round 4/10",
"simulation_id": null, // set on completion
"share_url": null, // set on completion → https://<host>/share/<sim_id>
"budget": {"cost_usd": 0.11, "tokens_used": 184223, "calls": 57},
"payment_chain": "solana",
"payment_network": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"
}
}Poll until status is completed, failed, budget_exceeded or cancelled. One subtlety: stages here is an object keyed by stage name, whereas the stages in the 202 body is an array- don't reuse one parser for both.
Read the report without the website
GET /report/<run_id>?format=md → raw markdown
GET /report/<run_id>?format=json → {report_markdown, title, share_url, …}Before the run finishes these return 409 with the current status.The recap card (auto-unfurl)
GET /api/simulation/<sim_id>/share-card.pngGenerated on first request and cached, so it's cheap to hot-link.
Pre-flight & health checks
Three unpaid helpers: /suggest turns a vague topic into launchable prompts before you spend a cent, and /health + /ready tell you the service is up so your settle doesn't fail.
/suggest - ideas before you spend
POST /suggest {"prompt": "stablecoin regulation"}
→ {"data": {"ideas": [{title, pitch, prompt, angle}, …]}}/health & /ready - is it up?
GET /health → liveness, no downstream checks GET /ready → 200 when DB + Neo4j are reachable; 503 otherwiseThere are no chargebacks, so waiting for a green /ready is the cheapest insurance you have.
Discover & verify the service
MiroShark is cataloged across the main x402 directories - CDP Bazaar, agentic.market, x402scan, AgentCash, Ampersend - so an agent can find and vet it by semantic search before ever making a paid call.
Listed as “MiroShark”
Pick before paying
Where MiroShark indexes
- CDP Bazaar - indexes on each successful settle; reads the service metadata + bazaar input/output schemas.
- agentic.market - mirrors CDP Bazaar automatically.
- x402scan & AgentCash - read GET /openapi.json (OpenAPI 3.1) as the canonical contract.
- Ampersend marketplace - curated catalog; maps /skill.md + /logo.png to its skillmd_url / logo_url fields.
# CDP discovery is read-only and unauthenticated: curl 'https://api.cdp.coinbase.com/platform/v2/x402/discovery/search?query=miroshark' curl 'https://api.cdp.coinbase.com/platform/v2/x402/discovery/merchant?payTo=0x6cab485fc28ec70d3845113b704d4824e4d2b24f'
Wire-format reference
If you don't use a v2-aware SDK, here are the exact bytes: the base64 PAYMENT-REQUIRED challenge with both accepts[] entries, the PAYMENT-SIGNATURE payload shape, and the PAYMENT-RESPONSE that carries your tx hash.
1 · The 402 challenge (decoded PAYMENT-REQUIRED)
{
"x402Version": 2,
"resource": {
"url": "https://x402.miroshark.xyz/run",
"serviceName": "MiroShark",
"tags": ["Simulation","Research","Search","Crypto","AI"]
},
"accepts": [
{ "scheme":"exact", "network":"eip155:8453",
"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"amount":"1000000",
"payTo":"0x6cab485fc28ec70d3845113b704d4824e4d2b24f",
"maxTimeoutSeconds":300, "extra":{"name":"USDC","version":"2"} },
{ "scheme":"exact", "network":"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
"asset":"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
"amount":"1000000",
"payTo":"9vWbPNMvt8ui1cNN8jWWPUWT5LPmeXzq7nr3vry1vMPH",
"maxTimeoutSeconds":300, "extra":{"feePayer":"<facilitator-sponsored>"} }
]
}Two entries - Base (EVM) and Solana - both $1 USDC. Pick the one matching your wallet's chain.2 · Retry with PAYMENT-SIGNATURE (Base / EVM example)
{
"x402Version": 2,
"accepted": { … the chosen accepts[] entry … },
"resource": "https://x402.miroshark.xyz/run",
"payload": {
"signature": "0x…",
"authorization": {
"from": "0xYourWalletAddress",
"to": "0x6cab485fc28ec70d3845113b704d4824e4d2b24f",
"value":"1000000",
"validAfter":"…", "validBefore":"…",
"nonce":"0x<random 32 bytes>"
}
}
}On Solana you build and sign an SPL Token transfer of the same amount, leaving feePayerto the facilitator - the SDK's SVM scheme handles it.3 · The settle (decoded PAYMENT-RESPONSE)
{
"success": true,
"transaction": "0x1f2ab48e…2ee06a", // on-chain USDC transfer
"network": "eip155:8453",
"payer": "0xYourWalletAddress"
}Verify the transaction on BaseScan (Base) or Solscan (Solana - the value is a base58 signature). The same payment_chain / payment_network ride along in the 202 body and every /status response.Full reference: the x402 v2 specification.
Caveats - finality, refunds & errors
x402 is final - once USDC settles there is no chargeback. Design retries that never double-pay, know what 402 / 429 / 404 each mean, and understand there is no automatic refund if a paid run fails.
No chargebacks - ever
No automatic refund on failure
Runs take 15–20 min
404 on status_url
402 returned again after you sent PAYMENT-SIGNATURE?
Usually insufficient USDC, a signature mismatch, a reused nonce (EVM) or a stale blockhash (Solana). Check the balance on BaseScan / Solscan, mint a fresh nonce, confirm the EIP-712 domain matches extra.name / extra.version, and make sure you signed the right chain's accepts[] entry.
Heads-up for pay/ pay.sh users: the CLI only routes x402 for endpoints in its catalog. MiroShark's listing is pending; until it merges, pay falls back to MPP and won't settle here - use any direct x402 client above.
Your first simulation takes ~10 min and ~$1.
One OpenRouter key, one launcher. Clone, drop the key into the five slots, run ./miroshark, openlocalhost:3000.
