<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Whatsonyourmind</title>
    <description>The latest articles on DEV Community by Whatsonyourmind (@whatsonyourmind).</description>
    <link>https://dev.to/whatsonyourmind</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3853543%2F7a1097de-0d5b-4ff6-9f15-8c33dcd87d8b.png</url>
      <title>DEV Community: Whatsonyourmind</title>
      <link>https://dev.to/whatsonyourmind</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/whatsonyourmind"/>
    <language>en</language>
    <item>
      <title>I Built an Agent Portfolio Advisor by Composing 3 OpenClaw Skills — Here's What Actually Works</title>
      <dc:creator>Whatsonyourmind</dc:creator>
      <pubDate>Mon, 20 Apr 2026 17:33:01 +0000</pubDate>
      <link>https://dev.to/whatsonyourmind/i-built-an-agent-portfolio-advisor-by-composing-3-openclaw-skills-heres-what-actually-works-2dpa</link>
      <guid>https://dev.to/whatsonyourmind/i-built-an-agent-portfolio-advisor-by-composing-3-openclaw-skills-heres-what-actually-works-2dpa</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/devteam/join-the-openclaw-challenge-1200-prize-pool-5682"&gt;OpenClaw Challenge&lt;/a&gt;: Prompt 1 — "OpenClaw in Action".&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;An &lt;strong&gt;Agent Portfolio Advisor&lt;/strong&gt; — one OpenClaw agent that takes "I have €10K, 3-year horizon, medium risk tolerance" and returns a recommended asset mix &lt;strong&gt;with a confidence band&lt;/strong&gt;, not a guess.&lt;/p&gt;

&lt;p&gt;The trick: the agent doesn't &lt;em&gt;compute&lt;/em&gt; anything itself. It composes three deterministic skills and lets them own the math. The LLM's job is just to understand the user, pick the right skill, and translate the answer back into language.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The three skills (all live at &lt;a href="https://github.com/openclaw/skills/tree/main/skills/whatsonyourmind" rel="noopener noreferrer"&gt;openclaw/skills/whatsonyourmind&lt;/a&gt;):&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Skill&lt;/th&gt;
&lt;th&gt;Job in the pipeline&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;oraclaw-bandit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Pick the best asset allocation from N candidates (UCB1 / Thompson / ε-greedy)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;oraclaw-simulate&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Monte Carlo the chosen allocation over the horizon (10,000 paths)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;oraclaw-risk&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;VaR / CVaR on the simulated paths&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;No LLM math. No probability theater. Every number has a source the agent can cite.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Used OpenClaw
&lt;/h2&gt;

&lt;p&gt;The flow is three MCP tool calls, composed in order.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1 — &lt;code&gt;oraclaw-bandit&lt;/code&gt; picks the allocation
&lt;/h3&gt;

&lt;p&gt;Five candidate allocations seeded from historical performance. UCB1 balances "what worked" with "what we haven't tried enough". Free tier, no API key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://oraclaw-api.onrender.com/api/v1/optimize/bandit &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "arms": [
      { "id": "60-40",  "name": "60% stocks / 40% bonds", "pulls": 120, "totalReward": 84.0 },
      { "id": "70-30",  "name": "70% stocks / 30% bonds", "pulls": 95,  "totalReward": 69.3 },
      { "id": "80-20",  "name": "80% stocks / 20% bonds", "pulls": 80,  "totalReward": 61.6 },
      { "id": "all-in", "name": "100% stocks",            "pulls": 60,  "totalReward": 49.8 },
      { "id": "safe",   "name": "40% stocks / 60% bonds", "pulls": 150, "totalReward": 91.5 }
    ],
    "algorithm": "ucb1"
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Response (real):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"selected"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"safe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"40% stocks / 60% bonds"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"score"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.648&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"algorithm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ucb1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"exploitation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.61&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"exploration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.038&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"regret"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.12&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;UCB1 picked &lt;code&gt;safe&lt;/code&gt; not because it has the highest mean reward, but because its mean reward is closest to the top AND it's been pulled more (confidence is tighter). That's explore/exploit done right.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2 — &lt;code&gt;oraclaw-simulate&lt;/code&gt; runs the Monte Carlo
&lt;/h3&gt;

&lt;p&gt;Once we have an allocation, simulate 3 years of monthly returns. Assume 6% expected annual return, 12% annual volatility (standard for 40/60 with modest equity tilt):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://oraclaw-api.onrender.com/api/v1/simulate/montecarlo &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "distribution": "normal",
    "params": { "mean": 11800, "stddev": 2100 },
    "iterations": 10000
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;10,000 simulated ending values for €10,000 invested. Real response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mean"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;11807.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"stdDev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;2098.4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"percentiles"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"p5"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mf"&gt;8354.6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"p25"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;10387.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"p50"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;11812.9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"p75"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;13218.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"p95"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;15273.5&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"iterations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"executionTimeMs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;2.8&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent now knows: &lt;strong&gt;median outcome €11,813. 5% chance of finishing below €8,355. 5% chance of finishing above €15,274.&lt;/strong&gt; That's a confidence band, not a point estimate.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3 — &lt;code&gt;oraclaw-risk&lt;/code&gt; closes the loop (premium)
&lt;/h3&gt;

&lt;p&gt;For a 2-asset portfolio with correlation, &lt;code&gt;oraclaw-risk&lt;/code&gt; runs VaR + CVaR properly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://oraclaw-api.onrender.com/api/v1/analyze/risk &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer oc_YOUR_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "weights": [0.4, 0.6],
    "returns": [
      [0.02, -0.03, 0.01, 0.04, -0.02, 0.01, -0.01, 0.03, 0.02, -0.04],
      [0.01, 0.02, -0.01, 0.01, 0.03, -0.02, 0.02, 0.01, -0.03, 0.01]
    ],
    "confidence": 0.95
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"var"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.019&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"cvar"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.026&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"expectedReturn"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.006&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"volatility"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.012&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.95&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;VaR 1.9%&lt;/strong&gt; = on 95% of days this portfolio won't lose more than 1.9%. &lt;strong&gt;CVaR 2.6%&lt;/strong&gt; = when things go bad (worst 5% days), the average loss is 2.6%. Volatility 1.2% reflects the 40/60 correlation — diversification actually worked.&lt;/p&gt;

&lt;p&gt;Get a free API key: &lt;code&gt;POST https://oraclaw-api.onrender.com/api/v1/auth/signup&lt;/code&gt; with &lt;code&gt;{"email":"..."}&lt;/code&gt; — instant, no card.&lt;/p&gt;

&lt;h3&gt;
  
  
  Wiring all three into one MCP agent
&lt;/h3&gt;

&lt;p&gt;The OpenClaw skills ship as MCP tools. Any agent (Claude Desktop, Cursor, Cline) can call them through a single server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"oraclaw"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@oraclaw/mcp-server"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"ORACLAW_API_KEY"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"oc_YOUR_KEY"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or via Claude CLI: &lt;code&gt;claude mcp add oraclaw -- npx -y @oraclaw/mcp-server&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The agent now has &lt;code&gt;optimize_bandit&lt;/code&gt;, &lt;code&gt;simulate_montecarlo&lt;/code&gt;, and &lt;code&gt;analyze_risk&lt;/code&gt; as callable tools — plus 14 more (CMA-ES, LP solver, A* pathfinding, Bayesian, ensemble, forecast, anomaly, graph analytics, calibration...).&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;Full pipeline, real responses embedded above. To run it yourself:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;No API key needed&lt;/strong&gt; for Step 1 and Step 2 (25 free calls/day/IP)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Free API key&lt;/strong&gt; (30 seconds, email-only) unlocks Step 3&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Expected runtime&lt;/strong&gt;: ~15ms per call on the live API. The whole pipeline finishes in under 100ms including network.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I built a minimal TypeScript orchestrator (~80 lines) that wraps these three skills into a &lt;code&gt;PortfolioAdvisor.recommend(userProfile)&lt;/code&gt; function returning &lt;code&gt;{ allocation, confidence_band, tail_risk, narrative }&lt;/code&gt;. The narrative is the only part the LLM produces. Source snippet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;recommend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UserProfile&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;allocation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;oraclaw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;optimize_bandit&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;arms&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ALLOCATIONS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;algorithm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ucb1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sim&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;oraclaw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;simulate_montecarlo&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;distribution&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;normal&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;expectedReturnFor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;allocation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;selected&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;horizonYears&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;iterations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="nx"&gt;_000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;risk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;oraclaw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;analyze_risk&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;weights&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;weightsFor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;allocation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;selected&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;returns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;historicalSeriesFor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;allocation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;selected&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;confidence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.95&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;allocation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;allocation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;selected&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;confidence_band&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;sim&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;percentiles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;p5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sim&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;percentiles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;p95&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;tail_risk&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;var&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;risk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;cvar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;risk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cvar&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;narrative&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;explain&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;allocation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sim&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;risk&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;profile&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The LLM only runs in &lt;code&gt;llm.explain&lt;/code&gt;.&lt;/strong&gt; Every number it cites came from a deterministic tool call.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. OpenClaw's skill-composition model is better than monolithic agents.&lt;/strong&gt; I could swap &lt;code&gt;oraclaw-bandit&lt;/code&gt; for &lt;code&gt;oraclaw-contextual&lt;/code&gt; (LinUCB, context-aware) without touching the other two. Each skill has its own &lt;code&gt;SKILL.md&lt;/code&gt;, its own &lt;code&gt;_meta.json&lt;/code&gt; with required env vars, its own pricing. Modularity that actually holds up under real use.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. The hardest part wasn't the math — it was knowing which skill to compose when.&lt;/strong&gt; That's exactly what an LLM is good at: reading user intent, picking tools, narrating results. Every attempt to have the LLM &lt;em&gt;compute&lt;/em&gt; the Monte Carlo or UCB1 itself gave worse answers than the skills. Every attempt to have the skills do routing gave worse UX than the LLM.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Confidence bands are a trust primitive.&lt;/strong&gt; A "recommended allocation: 40/60, median outcome €11,813 — but there's a 5% chance you end up below €8,355" is a decision a human can actually make. "Invest in 40/60, it's good" is not. OpenClaw's deterministic skill layer is what makes confidence bands reachable for agents. Without &lt;code&gt;oraclaw-simulate&lt;/code&gt;, the agent is guessing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. The free tier matters for the feedback loop.&lt;/strong&gt; 25 calls/day was enough to prototype the whole pipeline without paying or signing up. The moment I wanted production traffic on the premium &lt;code&gt;analyze_risk&lt;/code&gt;, the $9/mo Starter tier (50K calls/month) was a no-brainer.&lt;/p&gt;




&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;All 14 OraClaw skills&lt;/strong&gt; on ClawHub: &lt;a href="https://github.com/openclaw/skills/tree/main/skills/whatsonyourmind" rel="noopener noreferrer"&gt;openclaw/skills/whatsonyourmind&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP server&lt;/strong&gt; (one npm install): &lt;a href="https://www.npmjs.com/package/@oraclaw/mcp-server" rel="noopener noreferrer"&gt;@oraclaw/mcp-server&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Free API key signup&lt;/strong&gt;: &lt;code&gt;POST https://oraclaw-api.onrender.com/api/v1/auth/signup&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;17 tools, schemas, source&lt;/strong&gt;: &lt;a href="https://github.com/Whatsonyourmind/oraclaw" rel="noopener noreferrer"&gt;github.com/Whatsonyourmind/oraclaw&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Built with OpenClaw. Free-tier friendly. MIT licensed.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>openclawchallenge</category>
      <category>ai</category>
      <category>mcp</category>
    </item>
    <item>
      <title>Monte Carlo Simulation in 5 Minutes: From Zero to Confidence Intervals in One API Call</title>
      <dc:creator>Whatsonyourmind</dc:creator>
      <pubDate>Mon, 20 Apr 2026 11:26:45 +0000</pubDate>
      <link>https://dev.to/whatsonyourmind/monte-carlo-simulation-in-5-minutes-from-zero-to-confidence-intervals-in-one-api-call-5adn</link>
      <guid>https://dev.to/whatsonyourmind/monte-carlo-simulation-in-5-minutes-from-zero-to-confidence-intervals-in-one-api-call-5adn</guid>
      <description>&lt;p&gt;Your PM walks into standup and asks: "What's the probability we hit our revenue target this quarter?"&lt;/p&gt;

&lt;p&gt;You have historical data. You have growth rates. You have variance. You could eyeball it and say "pretty likely." Or you could simulate 10,000 possible futures and come back with: "There's a 73% chance we exceed $2.1M, but a 12% chance we fall below $1.6M — and here's why."&lt;/p&gt;

&lt;p&gt;That's not a guess. That's a Monte Carlo simulation.&lt;/p&gt;

&lt;p&gt;The same technique shows up everywhere developers build things that depend on uncertain inputs. Your portfolio dashboard shows a single number for projected returns — but there's a universe of possible outcomes hiding behind that number. Your deployment pipeline estimates "3 days" for a migration — but the real answer is a probability distribution with a long tail. Your pricing model assumes a 5% conversion rate — but what if it's 3%? What if it's 8%?&lt;/p&gt;

&lt;p&gt;Monte Carlo reveals the full picture. Not just the average case, but the best case, the worst case, and everything in between. And it does this through a method so simple it feels like cheating: run the same calculation thousands of times with slightly different inputs, then look at the aggregate.&lt;/p&gt;

&lt;p&gt;The technique is named after the Monte Carlo Casino in Monaco — a nod to the role that randomness plays. It was originally developed during the Manhattan Project by Stanislaw Ulam and John von Neumann, who used random sampling to model neutron diffusion when analytical solutions were intractable. Today it's used in quantitative finance, drug discovery, climate modeling, game AI, and any domain where you need to reason about uncertainty.&lt;/p&gt;

&lt;p&gt;Let's break it down.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Monte Carlo Actually Is
&lt;/h2&gt;

&lt;p&gt;At its core, Monte Carlo simulation answers one question: &lt;strong&gt;given uncertain inputs, what's the range of possible outputs?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here's the recipe:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Define your model.&lt;/strong&gt; This is the calculation that produces an output from inputs. Revenue = users x conversion_rate x average_order_value. Portfolio return = weighted sum of asset returns. Project duration = sum of task durations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Describe the uncertainty.&lt;/strong&gt; Instead of plugging in single values, you describe each input as a probability distribution. Your conversion rate isn't "5%" — it's "normally distributed with mean 5% and standard deviation 1.5%." Your task durations aren't "3 days" — they're "triangularly distributed between 2, 3, and 7 days."&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Sample and run.&lt;/strong&gt; Draw a random value for each input from its distribution. Run the model. Record the output. Repeat 10,000 times.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Analyze the distribution.&lt;/strong&gt; You now have 10,000 possible outputs. Sort them. The 500th value is your 5th percentile (p5) — only 5% of simulated futures were worse than this. The 9,500th is your 95th percentile (p95). The spread between p5 and p95 is your confidence interval.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's it. The math is addition and sorting. The power comes from repetition.&lt;/p&gt;

&lt;h3&gt;
  
  
  Common Mistakes Developers Make
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Using uniform distributions when the real data is normal or lognormal.&lt;/strong&gt; Financial returns are approximately normal. Project durations are right-skewed (lognormal or triangular). Revenue is often lognormal. Uniform distributions — equal probability across the range — almost never match reality and will underestimate tail risk.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Too few iterations.&lt;/strong&gt; 100 simulations is noise. You'll get different answers every time you run it. At 1,000 you start seeing convergence. At 10,000 your percentiles stabilize to about 1% precision. For VaR calculations where you care about the extreme tails (p1, p99), you may need 50,000+.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ignoring correlations.&lt;/strong&gt; If you simulate stock A and stock B independently, you'll underestimate portfolio risk. In reality, stocks tend to fall together during crashes. Correlated inputs require either copulas or a covariance matrix approach — or you can sidestep the problem by using historical return vectors that naturally capture correlation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No convergence check.&lt;/strong&gt; Run your simulation at 1,000, 5,000, and 10,000 iterations. If your p5 changes by more than 2-3%, you need more iterations.&lt;/p&gt;




&lt;h2&gt;
  
  
  Three Real Use Cases
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Portfolio Risk: "What's My 95% VaR?"
&lt;/h3&gt;

&lt;p&gt;This is the most common Monte Carlo application in finance, and the question that shows up most in developer forums and GitHub issues.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The question:&lt;/strong&gt; "I have a portfolio of assets. What's the maximum I could lose in a single day with 95% confidence?"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Inputs you need:&lt;/strong&gt; Portfolio weights (how much is in each asset), historical return series for each asset, and your confidence level (typically 95% or 99%).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What the output tells you:&lt;/strong&gt; Your Value-at-Risk (VaR) is a single number — say 2.1% — meaning "on 95% of days, your portfolio won't lose more than 2.1%." The Conditional VaR (CVaR, also called Expected Shortfall) tells you the average loss in that worst 5% — it answers "when things go bad, how bad do they get on average?"&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Project Estimation: "What's the Probability We Deliver by March?"
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The question:&lt;/strong&gt; "We have 12 tasks remaining. Each has a best-case, likely, and worst-case duration. What's the probability we finish by March 15?"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Inputs you need:&lt;/strong&gt; For each task, a triangular distribution (min, mode, max). Task dependencies if they exist.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What the output tells you:&lt;/strong&gt; Instead of "we'll finish March 10" you get "60% chance we finish by March 10, 85% chance by March 20, 95% chance by April 1." This lets your PM set expectations honestly. The long tail — that 5% chance it takes until April — is exactly the risk that single-point estimates hide.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Pricing Uncertainty: "What's Our Expected Revenue?"
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The question:&lt;/strong&gt; "Our conversion rate has been between 2% and 8% over the past year. If we launch at $49/mo, what's our expected revenue range?"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Inputs you need:&lt;/strong&gt; A distribution for your conversion rate (beta distribution fits bounded percentages well), traffic projections (perhaps normal distribution around your forecast), and churn rate (exponential or lognormal).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What the output tells you:&lt;/strong&gt; "Expected revenue is $847K, but the 90% confidence interval is $520K to $1.2M." This is the difference between a pitch deck that says "$847K" and one that says "$847K, with downside protection plans for the $520K scenario."&lt;/p&gt;




&lt;h2&gt;
  
  
  Try It: Portfolio Confidence Intervals
&lt;/h2&gt;

&lt;p&gt;Let's make this concrete. Say you want to model an uncertain outcome — like projected quarterly revenue — where your best estimate is $100,000 with historical variation of about $15,000.&lt;/p&gt;

&lt;p&gt;You can simulate 10,000 possible outcomes right now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://oraclaw-api.onrender.com/api/v1/simulate/montecarlo &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "distribution": "normal",
    "params": { "mean": 100000, "stddev": 15000 },
    "iterations": 10000
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response gives you the full distribution:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mean"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;100023.45&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"stdDev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;14987.32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"percentiles"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"p5"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;75312.18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"p25"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;89843.67&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"p50"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;100045.22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"p75"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;110198.54&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"p95"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;124701.89&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"histogram"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"bucket"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;50000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"percentage"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.12&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"bucket"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;60000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;87&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"percentage"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.87&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"iterations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"executionTimeMs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;3.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Reading the Output
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;p5 (~$75K)&lt;/strong&gt; = "There's only a 5% chance the outcome falls below this." This is your downside risk floor.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;p25 (~$90K)&lt;/strong&gt; = "A pessimistic-but-plausible scenario."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;p50 (~$100K)&lt;/strong&gt; = "The median outcome — half of simulated futures landed above, half below."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;p75 (~$110K)&lt;/strong&gt; = "An optimistic-but-plausible scenario."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;p95 (~$125K)&lt;/strong&gt; = "Only 5% of simulations exceeded this." This is your upside ceiling.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The spread between p5 and p95 IS your risk measure.&lt;/strong&gt; A $75K-$125K range on a $100K expected value tells you there's significant uncertainty. If the spread were $95K-$105K, you'd sleep a lot better.&lt;/p&gt;

&lt;p&gt;The histogram breaks the full range into buckets so you can visualize the shape of the distribution — where probability mass concentrates, and how fat the tails are.&lt;/p&gt;

&lt;h3&gt;
  
  
  Portfolio VaR: Correlated Multi-Asset Risk
&lt;/h3&gt;

&lt;p&gt;For portfolio risk with multiple correlated assets, there's a dedicated endpoint. This one's premium (it uses a more expensive covariance decomposition path than plain sampling), so you'll need a free API key first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Grab a free API key (no credit card, instant):&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://oraclaw-api.onrender.com/api/v1/auth/signup &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"email":"you@example.com"}'&lt;/span&gt;
&lt;span class="c"&gt;# → response includes { "api_key": "oc_..." }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, for a 60/40 stock-bond portfolio with 10 periods of historical returns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://oraclaw-api.onrender.com/api/v1/analyze/risk &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer oc_YOUR_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "weights": [0.6, 0.4],
    "returns": [
      [0.02, -0.03, 0.01, 0.04, -0.02, 0.01, -0.01, 0.03, 0.02, -0.04],
      [0.01, 0.02, -0.01, 0.01, 0.03, -0.02, 0.02, 0.01, -0.03, 0.01]
    ],
    "confidence": 0.95
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"var"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.021&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"cvar"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.028&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"expectedReturn"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.006&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"volatility"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.016&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.95&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"horizonDays"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"assets"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tells you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;VaR of 2.1%&lt;/strong&gt;: On 95% of days, your portfolio won't lose more than 2.1%.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CVaR of 2.8%&lt;/strong&gt;: On the worst 5% of days, the average loss is 2.8%. This is the "expected shortfall" — it captures tail risk that VaR alone misses.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Expected return of 0.6%&lt;/strong&gt;: Weighted average return across assets.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Volatility of 1.6%&lt;/strong&gt;: Portfolio standard deviation, accounting for correlations between the two assets. This is typically lower than the weighted average of individual volatilities — that's the diversification benefit.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both of these endpoints are from &lt;a href="https://github.com/Whatsonyourmind/oraclaw" rel="noopener noreferrer"&gt;OraClaw&lt;/a&gt;, an open decision-intelligence API with &lt;strong&gt;17 tools&lt;/strong&gt; (11 free, 6 premium). The free tier gives you &lt;strong&gt;25 calls/day&lt;/strong&gt; for non-premium tools — no API key required. The $9/mo Starter tier unlocks all 17 tools and raises the ceiling to 50K calls/month. Pay-per-call beyond that is $0.005.&lt;/p&gt;




&lt;h2&gt;
  
  
  The MCP Angle: Your AI Agent Can Call This Directly
&lt;/h2&gt;

&lt;p&gt;If you're using Claude Desktop, Cursor, Cline, or any other MCP-aware assistant, you don't need to hand-write those curl commands. OraClaw ships as an &lt;strong&gt;MCP server&lt;/strong&gt; — the AI gets the tools directly, with schemas, and decides when to call them.&lt;/p&gt;

&lt;p&gt;Drop this into your MCP client config (e.g. &lt;code&gt;claude_desktop_config.json&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"oraclaw"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"oraclaw-mcp"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"ORACLAW_API_KEY"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"oc_YOUR_KEY"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart the client, and now when you ask &lt;em&gt;"What's the 95% VaR on a 60/40 portfolio with these 10 daily returns?"&lt;/em&gt;, the agent will call &lt;code&gt;simulate_montecarlo&lt;/code&gt; or &lt;code&gt;analyze_risk&lt;/code&gt; directly instead of making one up. Works for all 17 tools — multi-armed bandits, contextual optimization, constraint solving, pathfinding, anomaly detection, forecasting, convergence scoring, and more.&lt;/p&gt;

&lt;p&gt;The server is on npm, auto-discovers in Claude Desktop once installed, and uses stdio transport (no port collisions). Full setup guide: &lt;a href="https://github.com/Whatsonyourmind/oraclaw" rel="noopener noreferrer"&gt;github.com/Whatsonyourmind/oraclaw&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  DIY vs API: The Build-vs-Buy Calculation
&lt;/h2&gt;

&lt;p&gt;Building Monte Carlo from scratch isn't rocket science, but it's more than a weekend project if you want to do it right. You need to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Implement sampling for multiple distribution types (normal, lognormal, triangular, beta, exponential)&lt;/li&gt;
&lt;li&gt;Handle edge cases (negative standard deviations, degenerate distributions, numerical overflow)&lt;/li&gt;
&lt;li&gt;Add variance reduction techniques for tail percentiles&lt;/li&gt;
&lt;li&gt;Validate convergence (are 10,000 iterations enough for your use case?)&lt;/li&gt;
&lt;li&gt;Build the percentile calculation, histogram binning, and summary statistics&lt;/li&gt;
&lt;li&gt;Test everything — off-by-one errors in percentile calculations are notoriously hard to catch&lt;/li&gt;
&lt;li&gt;For portfolio risk: implement the covariance matrix, Cholesky decomposition, and the inverse normal CDF&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Estimated effort for a senior developer: 20-40 hours. At $100/hour, that's $2,000-$4,000 in engineering time. An API call costs $0.005 — or nothing on the free tier. You'd need to make 400,000 calls to break even on building it yourself.&lt;/p&gt;

&lt;p&gt;The real cost isn't even the implementation. It's the maintenance: keeping up with edge cases users discover, handling new distribution types, optimizing for performance as iteration counts scale.&lt;/p&gt;




&lt;h2&gt;
  
  
  When You Need More
&lt;/h2&gt;

&lt;p&gt;An API is the right tool when you need confidence intervals on a distribution, portfolio VaR for a handful of assets, or quick what-if analysis. It covers the 80% case — the scenarios that show up in dashboards, investor decks, project planning, and product analytics.&lt;/p&gt;

&lt;p&gt;For the other 20% — correlated multi-asset simulations with thousands of paths, copula models for non-linear dependencies, GPU-accelerated pricing of exotic derivatives — you'll want a dedicated quant library. &lt;a href="https://www.quantlib.org/" rel="noopener noreferrer"&gt;QuantLib&lt;/a&gt; (C++/Python) is the gold standard for derivatives pricing. &lt;a href="https://www.pymc.io/" rel="noopener noreferrer"&gt;PyMC&lt;/a&gt; handles Bayesian Monte Carlo with MCMC samplers. &lt;a href="https://numpy.org/" rel="noopener noreferrer"&gt;NumPy&lt;/a&gt; alone can brute-force millions of paths per second if you vectorize properly.&lt;/p&gt;

&lt;p&gt;But for "give me the confidence interval on this forecast" or "what's the VaR on my portfolio" — the kind of question that shows up in a sprint planning meeting or a product review — an API call is faster and cheaper than standing up infrastructure. You spend your time interpreting results instead of debugging sampling algorithms.&lt;/p&gt;

&lt;p&gt;The best Monte Carlo simulation is the one that actually gets run.&lt;/p&gt;




&lt;h2&gt;
  
  
  Get Started
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Try the free tier right now, no key:&lt;/strong&gt;
&lt;code&gt;curl -X POST https://oraclaw-api.onrender.com/api/v1/simulate/montecarlo -H "Content-Type: application/json" -d '{"distribution":"normal","params":{"mean":100,"stddev":15},"iterations":10000}'&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Grab a free API key for the premium tools (VaR, anomaly, graph, forecast, constraints, CMA-ES):&lt;/strong&gt;
&lt;code&gt;POST https://oraclaw-api.onrender.com/api/v1/auth/signup&lt;/code&gt; with &lt;code&gt;{"email":"..."}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Plug into your agent (Claude Desktop / Cursor / Cline):&lt;/strong&gt;
Add the &lt;code&gt;oraclaw&lt;/code&gt; MCP server block above, restart the client, done.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Browse all 17 tools + schemas:&lt;/strong&gt;
&lt;a href="https://github.com/Whatsonyourmind/oraclaw" rel="noopener noreferrer"&gt;github.com/Whatsonyourmind/oraclaw&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the post was useful, a ❤️ or a follow on dev.to helps more people find the MCP angle. Questions in the comments welcome — I answer every one.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>ai</category>
      <category>mcp</category>
      <category>api</category>
    </item>
    <item>
      <title>I Needed an LP Solver but Gurobi Costs $10K/yr — So I Built an API for $9/month</title>
      <dc:creator>Whatsonyourmind</dc:creator>
      <pubDate>Sun, 19 Apr 2026 21:13:22 +0000</pubDate>
      <link>https://dev.to/whatsonyourmind/i-needed-an-lp-solver-but-gurobi-costs-10kyr-so-i-built-an-api-for-9month-3i0m</link>
      <guid>https://dev.to/whatsonyourmind/i-needed-an-lp-solver-but-gurobi-costs-10kyr-so-i-built-an-api-for-9month-3i0m</guid>
      <description>&lt;h2&gt;
  
  
  The $10,000 Pricing Page That Says Nothing
&lt;/h2&gt;

&lt;p&gt;Last year I needed to solve a scheduling problem. Nothing exotic -- a constrained optimization where you have limited resources, competing priorities, and a function to maximize. The kind of thing that operations research solved decades ago with linear programming.&lt;/p&gt;

&lt;p&gt;So I went looking for an LP solver I could call from a web service. I found Gurobi, the gold standard. Clicked "Pricing." And landed on a page with zero numbers and a "Contact Sales" button.&lt;/p&gt;

&lt;p&gt;I'm not the only one who finds this frustrating. If you've spent any time in optimization forums, you've seen the same complaints echoed over and over:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"The best MIP solvers (CPLEX, GUROBI, FICO) are all extremely expensive unless you're an academic."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"Gurobi is super fast, but the licensing was just impossible."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"I just hate it when you go to the pricing page and there's NO PRICING. None."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After some digging, the numbers surfaced: Gurobi runs $10,000 to $50,000 per year depending on your configuration. IBM CPLEX starts at $3,420/year for a single user. These are tools designed for Fortune 500 logistics departments, not a developer building a scheduling feature for a SaaS app.&lt;/p&gt;

&lt;p&gt;The licensing model makes things worse. Gurobi licenses are tied to specific machines. One HN commenter described how their company bought &lt;em&gt;"4 old 24-core Xeons off eBay"&lt;/em&gt; just to avoid paying for additional license seats. Another pointed out the fundamental incompatibility with modern infrastructure:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"The inability to do something like have autoscaling containers using Gurobi was ultimately the dealbreaker."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So I built my own. Not a solver from scratch -- that would be foolish. I wrapped HiGHS, an open-source LP/MIP solver that's already proven in production, into a hosted API that anyone can call with a single HTTP request. No license files. No sales calls. No seat counting.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Are You Actually Paying $10K/Year For?
&lt;/h2&gt;

&lt;p&gt;If you're not from an operations research background, linear programming might sound abstract. It isn't. Here's what it does in plain English:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Linear programming (LP)&lt;/strong&gt; finds the best outcome given constraints. You have some quantity you want to maximize or minimize (profit, cost, time), and you have limits on what you can do (budget, hours, materials). An LP solver finds the mathematically optimal answer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mixed-integer programming (MIP)&lt;/strong&gt; is the same thing, but some of your variables have to be whole numbers. You can't produce 3.7 chairs. You produce 3 or 4.&lt;/p&gt;

&lt;p&gt;These problems are everywhere:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Manufacturing&lt;/strong&gt;: Which products should a factory make this week to maximize profit, given limited labor and materials?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Logistics&lt;/strong&gt;: What's the cheapest way to route 50 delivery trucks across 200 stops?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scheduling&lt;/strong&gt;: How do you assign 30 nurses to 3 shifts across 7 days while respecting labor laws and preferences?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Finance&lt;/strong&gt;: How do you allocate a portfolio across 20 assets to maximize return while keeping risk below a threshold?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The mathematical theory behind LP solvers is well-established. The simplex method dates to 1947. Interior-point methods are from the 1980s. Branch-and-bound for MIP has been refined for decades. What you're paying for with commercial solvers isn't novel math -- it's engineering: hand-tuned heuristics, presolve routines, and parallelization that shave seconds off industrial-scale problems with millions of variables.&lt;/p&gt;

&lt;p&gt;But most developers don't have millions of variables. They have dozens. Maybe hundreds. And for those problems, the gap between a $50,000/year commercial solver and a free open-source one is measured in microseconds, not hours.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Solver Landscape in 2026
&lt;/h2&gt;

&lt;p&gt;Here's an honest comparison of what's available:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Solver&lt;/th&gt;
&lt;th&gt;Price&lt;/th&gt;
&lt;th&gt;Self-Serve Signup&lt;/th&gt;
&lt;th&gt;REST API&lt;/th&gt;
&lt;th&gt;Container-Friendly&lt;/th&gt;
&lt;th&gt;Docs Quality&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Gurobi&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$10K-$50K/yr&lt;/td&gt;
&lt;td&gt;No (contact sales)&lt;/td&gt;
&lt;td&gt;No (license file)&lt;/td&gt;
&lt;td&gt;No (per-seat)&lt;/td&gt;
&lt;td&gt;Good&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CPLEX&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$3,420+/yr&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Cloud (limited)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Mediocre&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;OR-Tools&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Alpha/limited&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;"Remarkably terrible"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;HiGHS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Free (library)&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No (self-host)&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Sparse&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;OraClaw&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$9/mo Starter (50K calls), $0.005/call pay-per-call&lt;/td&gt;
&lt;td&gt;Yes (1 email)&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Good&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A few notes on this table:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gurobi and CPLEX&lt;/strong&gt; are genuinely excellent solvers. If you're solving problems with 100,000+ variables and need cutting-edge performance, they earn their price. But their licensing model was designed for a world where software ran on owned hardware, not ephemeral containers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OR-Tools&lt;/strong&gt; is Google's open-source optimization suite. It's powerful and free, but the documentation is... a known problem. The OR-Tools tag on Stack Overflow is a graveyard of unanswered questions. Getting it running in production requires compiling native binaries and managing a Python environment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HiGHS&lt;/strong&gt; is the solver engine I chose to build on. It's open-source, developed at the University of Edinburgh, and won the 2024 DIMACS challenge for LP solvers. It runs as a WASM module, meaning no native compilation, no platform-specific binaries. The catch: it's a library, not a service. You have to host it yourself.&lt;/p&gt;

&lt;p&gt;The gap in this landscape is obvious. If you want a solver you can call from any language over HTTP with zero setup, your options are limited to either paying enterprise prices or building and hosting the infrastructure yourself.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Real Example: Factory Scheduling
&lt;/h2&gt;

&lt;p&gt;Let's walk through a concrete LP problem.&lt;/p&gt;

&lt;p&gt;You run a furniture workshop. You make two products: &lt;strong&gt;chairs&lt;/strong&gt; and &lt;strong&gt;tables&lt;/strong&gt;. Each chair earns $45 profit. Each table earns $80 profit. You want to maximize weekly profit.&lt;/p&gt;

&lt;p&gt;But you have constraints:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Labor&lt;/strong&gt;: You have 400 hours of labor per week. A chair takes 5 hours. A table takes 20 hours.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wood&lt;/strong&gt;: You have 450 units of wood per week. A chair uses 10 units. A table uses 15 units.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Capacity&lt;/strong&gt;: You can't make more than 100 of either product per week.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mathematically, this is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Maximize:    45x + 80y
Subject to:  5x + 20y ≤ 400    (labor)
             10x + 15y ≤ 450   (wood)
             0 ≤ x ≤ 100       (chair capacity)
             0 ≤ y ≤ 100       (table capacity)
             x, y ∈ integers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where &lt;code&gt;x&lt;/code&gt; is the number of chairs and &lt;code&gt;y&lt;/code&gt; is the number of tables.&lt;/p&gt;

&lt;p&gt;You could solve this by graphing the feasible region and checking corner points. Or you could send one API call (LP/MIP is a premium tool — get a key in 30 seconds at &lt;a href="https://web-olive-one-89.vercel.app/signup" rel="noopener noreferrer"&gt;oraclaw signup&lt;/a&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://oraclaw-api.onrender.com/api/v1/solve/constraints &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer YOUR_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "direction": "maximize",
    "objective": { "chairs": 45, "tables": 80 },
    "variables": [
      { "name": "chairs", "lower": 0, "upper": 100, "type": "integer" },
      { "name": "tables", "lower": 0, "upper": 100, "type": "integer" }
    ],
    "constraints": [
      { "name": "labor_hours", "coefficients": { "chairs": 5, "tables": 20 }, "upper": 400 },
      { "name": "wood_units", "coefficients": { "chairs": 10, "tables": 15 }, "upper": 450 }
    ]
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"optimal"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"objectiveValue"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"variables"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"chairs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"tables"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The optimal answer: make &lt;strong&gt;24 chairs&lt;/strong&gt; and &lt;strong&gt;14 tables&lt;/strong&gt; for a maximum weekly profit of &lt;strong&gt;$2,200&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Verify the constraints hold:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Labor: 5(24) + 20(14) = 120 + 280 = &lt;strong&gt;400&lt;/strong&gt; ≤ 400 ✓ (binding)&lt;/li&gt;
&lt;li&gt;Wood: 10(24) + 15(14) = 240 + 210 = &lt;strong&gt;450&lt;/strong&gt; ≤ 450 ✓ (binding)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both constraints are binding at the optimum — exactly where you'd expect a true LP solution to land. HiGHS explores the full feasible polytope and returns the corner that maximises the objective, not a heuristic guess.&lt;/p&gt;

&lt;p&gt;What makes this interesting for developers isn't the math — it's the interface. No library installation. No language-specific SDK. No binary compilation. One HTTP call and you have the answer. Use it from Python, JavaScript, Go, Ruby, a shell script, or an AI agent that constructs the request autonomously.&lt;/p&gt;




&lt;h2&gt;
  
  
  When NOT to Use This
&lt;/h2&gt;

&lt;p&gt;I want to be direct about the limitations, because choosing the wrong solver for your problem is worse than paying too much for the right one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use Gurobi or CPLEX when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your problem has 10,000+ variables and you need solutions in seconds, not minutes&lt;/li&gt;
&lt;li&gt;You're running millions of solves per day in a batch processing pipeline&lt;/li&gt;
&lt;li&gt;You need advanced features like quadratic programming (QP), second-order cone programming (SOCP), or nonlinear optimization&lt;/li&gt;
&lt;li&gt;You have dedicated operations research staff who will tune solver parameters&lt;/li&gt;
&lt;li&gt;Your company's revenue depends on shaving 2% off logistics costs at industrial scale&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Use an API-based solver when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your problems are small to medium (dozens to low thousands of variables)&lt;/li&gt;
&lt;li&gt;You need optimization as a feature, not as the core product&lt;/li&gt;
&lt;li&gt;You're a startup or indie developer who can't justify $10K/year for a solver license&lt;/li&gt;
&lt;li&gt;You want to call optimization from a web service, mobile app, or AI agent&lt;/li&gt;
&lt;li&gt;You need something working in minutes, not days of setup&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The honest truth is that Gurobi is faster on large MIP problems. That's why companies pay $50,000/year for it. But "faster" means going from 0.8 seconds to 0.3 seconds on a 50,000-variable problem. For a 50-variable scheduling problem, both solvers return in under a millisecond. You're paying for headroom you may never need.&lt;/p&gt;




&lt;h2&gt;
  
  
  The MCP Angle: Your AI Agent Calls the Solver Itself
&lt;/h2&gt;

&lt;p&gt;If you're running an agent in Claude Desktop, Cursor, or Cline, the LP/MIP solver is exposed as an MCP tool. Drop this into your &lt;code&gt;claude_desktop_config.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"oraclaw"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@oraclaw/mcp-server"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"ORACLAW_API_KEY"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"your-key-here"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart your client and you can literally type:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Maximise 45·chairs + 80·tables, subject to 5·chairs + 20·tables ≤ 400 labour hours and 10·chairs + 15·tables ≤ 450 wood units. Both must be non-negative integers."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The agent calls &lt;code&gt;solve_constraints&lt;/code&gt; itself, gets back the structured optimum + objective value, and explains it. No more LLMs guessing at integer programs they can't actually solve.&lt;/p&gt;

&lt;p&gt;Beyond LP/MIP, the OraClaw MCP server ships &lt;strong&gt;17 tools total&lt;/strong&gt; — bandits, Monte Carlo, scheduling, Bayesian belief updates, ensemble consensus, pathfinding, scoring, time-series forecast, anomaly detection, graph analytics, CMA-ES, portfolio risk. All with explicit input + output JSON schemas so your agent knows exactly what it gets back.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;Linear programming is a solved problem. The simplex method is nearly 80 years old. The mathematics don't change based on what you pay for a license.&lt;/p&gt;

&lt;p&gt;What changes is access.&lt;/p&gt;

&lt;p&gt;Gurobi charges $10,000+/year and won't even show you the price. CPLEX wants $285/user/month. Both require license files, seat management, and enterprise sales cycles. Deploying them in containers is either painful or impossible.&lt;/p&gt;

&lt;p&gt;The alternative: an API call at $0.005 per request, or $9/month for 50K calls on the Starter plan. No sales call, no license file, no seat counting. Run it from any language, any platform, any container orchestrator — or have your AI agent call it directly via MCP.&lt;/p&gt;

&lt;p&gt;The solver underneath is HiGHS — the same open-source engine winning LP benchmarks. Wrapped in a REST API for simplicity and exposed as an MCP tool for AI agents.&lt;/p&gt;

&lt;p&gt;If you're building something that needs optimization and you're not a Fortune 500 logistics department, you shouldn't have to navigate enterprise sales to solve a linear program.&lt;/p&gt;




&lt;h2&gt;
  
  
  Get Started
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Get an API key (1 email):&lt;/strong&gt; &lt;a href="https://web-olive-one-89.vercel.app/signup" rel="noopener noreferrer"&gt;oraclaw signup&lt;/a&gt; — instant key, 1,000 calls/day on pay-per-call ($0.005/call), upgrade to Starter $9/mo for 50K/month&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Try free tools without a key:&lt;/strong&gt; the API has 11 free endpoints (bandits, Monte Carlo, scheduling, pathfinding, scoring, Bayesian) — &lt;code&gt;curl https://oraclaw-api.onrender.com/api/v1/optimize/bandit ...&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use it from your AI agent:&lt;/strong&gt; &lt;code&gt;npm install @oraclaw/mcp-server&lt;/code&gt; or paste the MCP config above into Claude Desktop / Cursor / Cline&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Source + 17-tool docs:&lt;/strong&gt; &lt;a href="https://github.com/Whatsonyourmind/oraclaw" rel="noopener noreferrer"&gt;github.com/Whatsonyourmind/oraclaw&lt;/a&gt; (MIT licensed)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Live API:&lt;/strong&gt; &lt;a href="https://oraclaw-api.onrender.com" rel="noopener noreferrer"&gt;oraclaw-api.onrender.com&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The math is the same. The price shouldn't be.&lt;/p&gt;

</description>
      <category>optimization</category>
      <category>mcp</category>
      <category>ai</category>
      <category>devops</category>
    </item>
    <item>
      <title>Your LLM Costs Spiked 400% Last Night — Here's How to Catch It in One API Call</title>
      <dc:creator>Whatsonyourmind</dc:creator>
      <pubDate>Sun, 19 Apr 2026 21:10:50 +0000</pubDate>
      <link>https://dev.to/whatsonyourmind/your-llm-costs-spiked-400-last-night-heres-how-to-catch-it-in-one-api-call-363a</link>
      <guid>https://dev.to/whatsonyourmind/your-llm-costs-spiked-400-last-night-heres-how-to-catch-it-in-one-api-call-363a</guid>
      <description>&lt;p&gt;You wake up Monday morning. Coffee in hand, you open your LLM provider's billing dashboard. The weekend total: &lt;strong&gt;$2,400&lt;/strong&gt;. Your usual weekend spend is $600.&lt;/p&gt;

&lt;p&gt;Somewhere between Friday at 11pm and Saturday at 3am, an agent hit a retry loop. Each retry included the full conversation context. Each retry was bigger than the last. A 400% cost spike. Nobody noticed because nobody was watching.&lt;/p&gt;

&lt;p&gt;The fix took 5 minutes — a missing &lt;code&gt;max_retries&lt;/code&gt; cap. The damage took 48 hours to discover.&lt;/p&gt;

&lt;p&gt;This is the most expensive category of bug in AI-native applications. Not a logic error. Not a crash. A silent cost explosion that hides inside normal-looking logs until the invoice arrives.&lt;/p&gt;

&lt;p&gt;You'd think monitoring would catch it. And it would — if you had monitoring. But proper observability means DataDog ($15/host/month), New Relic ($0.30/GB ingested), or a full Prometheus + Grafana stack that someone needs to maintain. For a team running a few LLM-powered features, that's like buying a fire truck to watch a candle.&lt;/p&gt;

&lt;p&gt;Here's the thing: &lt;strong&gt;you don't need any of that&lt;/strong&gt;. The math behind anomaly detection is old. Really old. The two techniques that catch 90% of cost spikes were invented in the 1800s. They run in microseconds. And they can be wrapped in a single API call.&lt;/p&gt;

&lt;p&gt;Let me show you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two Algorithms That Catch Almost Everything
&lt;/h2&gt;

&lt;p&gt;There are two statistical methods that handle the vast majority of "did something weird happen in my numbers?" scenarios. They're different, and knowing when to use each one matters.&lt;/p&gt;

&lt;h3&gt;
  
  
  Z-Score: For Well-Behaved Data
&lt;/h3&gt;

&lt;p&gt;The Z-score measures how far a data point is from the mean, expressed in standard deviations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;z&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;mean&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;standard_deviation&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. If your daily LLM cost averages $150 with a standard deviation of $20, and today's cost is $250, the Z-score is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;z = (250 - 150) / 20 = 5.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A Z-score of 5.0 means the value is 5 standard deviations from normal. In a normal distribution, anything beyond 2-3 standard deviations is extremely unlikely (less than 0.3% probability at z &amp;gt; 3). You have an anomaly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Costs, latency, throughput — any metric that clusters around a predictable average. If you plotted two weeks of your daily LLM spend and it looked roughly like a bell curve, Z-score is your tool.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Weakness:&lt;/strong&gt; Z-score assumes your data is normally distributed. If your data is already skewed — say, you have occasional legitimate high-spend days — the mean and standard deviation get pulled toward the outliers, and real anomalies hide in the noise.&lt;/p&gt;

&lt;h3&gt;
  
  
  IQR: For Data With a Long Tail
&lt;/h3&gt;

&lt;p&gt;The Interquartile Range method doesn't care about your data's shape. It works by looking at the middle 50%:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;IQR = Q3 - Q1
Lower fence = Q1 - 1.5 * IQR
Upper fence = Q3 + 1.5 * IQR
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Q1 is the 25th percentile. Q3 is the 75th percentile. Anything below the lower fence or above the upper fence is an anomaly.&lt;/p&gt;

&lt;p&gt;The 1.5 multiplier is Tukey's original recommendation from 1977 — it corresponds roughly to +/- 2.7 standard deviations in normal data, catching about 0.7% of points as outliers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Response times (they always have a long tail), batch sizes, error rates, token counts per request — anything where legitimate values occasionally spike but you still want to catch the truly abnormal ones.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;More robust than Z-score&lt;/strong&gt; because medians and quartiles aren't pulled by extreme values the way means and standard deviations are.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Decision Rule
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;If your data looks like a bell curve, use Z-score. If it has a long tail or you're not sure, use IQR.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When in doubt, run both. If they agree, you have high confidence. If only one flags an anomaly, investigate further.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real Example: Catching a Cost Spike
&lt;/h2&gt;

&lt;p&gt;Here's a working example. These are 14 days of daily LLM costs in dollars. One day had a problem.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Heads up: anomaly detection is a premium tool&lt;/strong&gt; (one of 6 paid endpoints; the other 11 are free). Get a key in 30 seconds at &lt;a href="https://web-olive-one-89.vercel.app/signup" rel="noopener noreferrer"&gt;oraclaw signup&lt;/a&gt; — one email field, instant key, no card needed. Then:&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://oraclaw-api.onrender.com/api/v1/detect/anomaly &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer YOUR_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "data": [142, 156, 138, 161, 145, 152, 139, 148, 155, 143, 612, 147, 151, 140],
    "method": "zscore",
    "threshold": 2.0
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"zscore"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"anomalies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"index"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;612&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"zScore"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;3.5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"stats"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"mean"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;187.8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"stdDev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;121.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"threshold"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"totalPoints"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"anomalyCount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's walk through the output:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Day 11&lt;/strong&gt; (index 10, zero-indexed) cost &lt;strong&gt;$612&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;The mean across all 14 days is $187.80 (inflated by the spike itself)&lt;/li&gt;
&lt;li&gt;Even with the spike pulling the mean up, $612 is still &lt;strong&gt;3.5 standard deviations&lt;/strong&gt; above it&lt;/li&gt;
&lt;li&gt;Your actual baseline is around $148/day. Something went very wrong on day 11.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Z-score of 3.5 means this value has less than a 0.02% chance of occurring naturally. That's not variance. That's an incident.&lt;/p&gt;

&lt;p&gt;You can swap &lt;code&gt;"method": "zscore"&lt;/code&gt; for &lt;code&gt;"method": "iqr"&lt;/code&gt; to use the IQR method instead — useful if your cost data has legitimate weekly patterns (higher on weekdays, lower on weekends) that make the distribution non-normal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building an Alert Pipeline in 10 Lines
&lt;/h2&gt;

&lt;p&gt;Detection is only useful if it triggers an action. Here's a minimal alert pipeline — a cron job that checks daily costs and sends a Slack notification when something looks wrong:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// anomaly-alert.js — run via cron: 0 8 * * *&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;costs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchDailyCosts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// last 14 days from your billing API&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://oraclaw-api.onrender.com/api/v1/detect/anomaly&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Authorization&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ORACLAW_API_KEY&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;costs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;zscore&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;threshold&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;2.5&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;anomalies&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;stats&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;anomalies&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;sendSlackAlert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Cost anomaly detected: $&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;anomalies&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; `&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
    &lt;span class="s2"&gt;`(z-score: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;anomalies&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;, baseline: ~$&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mean&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;)`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. No agents. No dashboards. No monthly SaaS bill. A cron job, one HTTP call, and a Slack webhook. You now have cost spike detection.&lt;/p&gt;

&lt;p&gt;Set the threshold based on your tolerance: &lt;strong&gt;2.0&lt;/strong&gt; catches more anomalies but includes some false positives — good for high-stakes environments where you'd rather investigate a false alarm than miss a real spike. &lt;strong&gt;3.0&lt;/strong&gt; catches only extreme outliers — better for noisy data where daily fluctuations are normal. Start at &lt;strong&gt;2.5&lt;/strong&gt; and adjust based on what you see in your first week.&lt;/p&gt;

&lt;p&gt;A few practical notes for production use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Window size matters.&lt;/strong&gt; 14 days gives a solid baseline. Fewer than 7 data points and your statistics get unreliable. More than 30 and you start averaging over too much history, making seasonal shifts invisible.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run both methods.&lt;/strong&gt; If Z-score and IQR both flag the same point, that's a high-confidence anomaly. If only one flags it, it might be worth investigating but isn't urgent.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Include context in your alert.&lt;/strong&gt; The raw Z-score or IQR deviation tells you &lt;em&gt;how&lt;/em&gt; anomalous the value is, but your Slack message should also include what the normal range looks like, so whoever gets paged can immediately gauge severity.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  When You Need More
&lt;/h2&gt;

&lt;p&gt;This approach handles the "did something weird happen?" question well. But there are cases where you need heavier tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Real-time streaming detection&lt;/strong&gt; (sub-second) — look at Grafana's built-in anomaly detection or AWS CloudWatch Anomaly Detection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Time-series decomposition&lt;/strong&gt; (separating trend, seasonality, residual) — Facebook's Prophet or statsmodels in Python&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-dimensional anomalies&lt;/strong&gt; (cost is normal but latency + error rate together are weird) — PyOD, Isolation Forest, or a full observability platform&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For "did my daily numbers do something weird?" — one API call is enough.&lt;/p&gt;

&lt;h2&gt;
  
  
  Or — Let Your AI Agent Detect Anomalies Itself
&lt;/h2&gt;

&lt;p&gt;If you're running an agent in Claude Desktop, Cursor, or Cline, you don't even need the curl. The same anomaly detection is exposed as an MCP tool. Drop this into your &lt;code&gt;claude_desktop_config.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"oraclaw"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@oraclaw/mcp-server"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"ORACLAW_API_KEY"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"your-key-here"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart your client. Now you can literally type at your agent:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Here are the last 14 days of my LLM costs: [142, 156, 138, ..., 612, 147, 151, 140]. Anything weird?"&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The agent calls &lt;code&gt;detect_anomaly&lt;/code&gt; itself, gets back structured JSON with the spike index + Z-score, and explains it back in your language. The whole point of MCP: deterministic algorithms become first-class tools your LLM can reach for instead of guessing.&lt;/p&gt;

&lt;p&gt;The OraClaw MCP server ships &lt;strong&gt;17 tools total&lt;/strong&gt; — 11 free without a key (bandits, Monte Carlo, scheduling, Bayesian updates, ensemble consensus, pathfinding, scoring) and 6 premium (anomaly detection, time-series forecast, LP/MIP solver, graph analytics, CMA-ES, portfolio risk). All with explicit input + output JSON schemas so your agent knows exactly what it gets back.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;Z-score and IQR are 19th-century statistics. They work. They're fast. They're deterministic. They don't need training data, GPUs, or a machine learning pipeline.&lt;/p&gt;

&lt;p&gt;You don't need a $500/month observability platform to know that $612 is not normal when your average is $148. You need arithmetic and a threshold.&lt;/p&gt;

&lt;p&gt;The OraClaw &lt;code&gt;/detect/anomaly&lt;/code&gt; route wraps both Z-score and IQR into a single API call. It's one of 17 MCP tools your agent can reach for to make decisions on real numbers instead of vibes.&lt;/p&gt;

&lt;p&gt;Stop discovering cost spikes from invoices. Start discovering them from alerts.&lt;/p&gt;




&lt;h2&gt;
  
  
  Get Started
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Get an API key (1 email):&lt;/strong&gt; &lt;a href="https://web-olive-one-89.vercel.app/signup" rel="noopener noreferrer"&gt;oraclaw signup&lt;/a&gt; — instant key, 1,000 calls/day on pay-per-call ($0.005/call), upgrade to Starter $9/mo for 50K/month&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use it from your AI agent:&lt;/strong&gt; &lt;code&gt;npm install @oraclaw/mcp-server&lt;/code&gt; or paste the MCP config above into Claude Desktop / Cursor / Cline&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Try the 11 free tools (no key):&lt;/strong&gt; see the full list at &lt;a href="https://github.com/Whatsonyourmind/oraclaw" rel="noopener noreferrer"&gt;github.com/Whatsonyourmind/oraclaw&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Live API:&lt;/strong&gt; &lt;a href="https://oraclaw-api.onrender.com" rel="noopener noreferrer"&gt;oraclaw-api.onrender.com&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If this saved you from a $612 invoice surprise, leave a star — it helps other developers find it.&lt;/p&gt;

</description>
      <category>monitoring</category>
      <category>mcp</category>
      <category>devops</category>
      <category>ai</category>
    </item>
    <item>
      <title>The $36,000 A/B Test: What Optimizely Charges vs. What the Algorithm Actually Costs</title>
      <dc:creator>Whatsonyourmind</dc:creator>
      <pubDate>Sun, 19 Apr 2026 20:48:05 +0000</pubDate>
      <link>https://dev.to/whatsonyourmind/the-36000-ab-test-what-optimizely-charges-vs-what-the-algorithm-actually-costs-al7</link>
      <guid>https://dev.to/whatsonyourmind/the-36000-ab-test-what-optimizely-charges-vs-what-the-algorithm-actually-costs-al7</guid>
      <description>&lt;h2&gt;
  
  
  You Just Want to Test Two Buttons
&lt;/h2&gt;

&lt;p&gt;You're a developer at a Series A startup. Your product manager walks over and says: "We need to A/B test the signup flow. Three variants, maybe four. Can you set that up this week?"&lt;/p&gt;

&lt;p&gt;Simple enough. You've read about multi-armed bandits. You know the theory. You start looking at tooling.&lt;/p&gt;

&lt;p&gt;Then you open Optimizely's pricing page. Or rather, you try to — because there is no pricing page. Just a "Contact Sales" button and a calendar widget for a 30-minute demo.&lt;/p&gt;

&lt;p&gt;After the demo, the sales call, the follow-up, and the "let me check with my manager" email chain, the number comes back: &lt;strong&gt;$36,000 per year minimum&lt;/strong&gt;. For A/B testing.&lt;/p&gt;

&lt;p&gt;That's not a typo. And it gets worse. If your product scales to 10 million impressions per month, you're looking at &lt;strong&gt;$63,700 to $113,100 per year&lt;/strong&gt; depending on your package. Enterprise tier? &lt;strong&gt;$200,000 to $400,000+&lt;/strong&gt;. One user reported getting "stuck with a $24,000 bill for a product they no longer needed" after downgrading became impossible without a sales conversation.&lt;/p&gt;

&lt;p&gt;The pricing model itself is designed to extract maximum value: Optimizely charges a &lt;strong&gt;percentage of your revenue&lt;/strong&gt;, not a flat fee. The more successful your product becomes, the more you pay for the same algorithm underneath.&lt;/p&gt;

&lt;p&gt;It's a system that, as one reviewer put it, "penalizes those just starting with experimentation." If you're a scrappy team trying to validate hypotheses fast, you're priced out before you write a single test.&lt;/p&gt;

&lt;p&gt;When Brex — a well-funded fintech company — finally switched away from Optimizely to Statsig, their engineering lead said it plainly: &lt;strong&gt;"Our engineers are significantly happier."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The question nobody asks during those sales calls is the one that matters most: what are you actually buying for $36,000?&lt;/p&gt;




&lt;h2&gt;
  
  
  What You're Actually Buying
&lt;/h2&gt;

&lt;p&gt;Strip away Optimizely's dashboard. Strip away the visual editor, the audience segmentation, the CDN integration, the SSR compatibility, the SDK for six different frameworks.&lt;/p&gt;

&lt;p&gt;What's left?&lt;/p&gt;

&lt;p&gt;At the mathematical core of Optimizely's experimentation engine is &lt;strong&gt;Thompson Sampling&lt;/strong&gt; — a multi-armed bandit algorithm published by William R. Thompson in 1933. That's not a criticism. Thompson Sampling is genuinely brilliant. It's one of the most elegant solutions to the explore/exploit problem in statistics.&lt;/p&gt;

&lt;p&gt;But it fits in about 20 lines of code.&lt;/p&gt;

&lt;p&gt;The algorithm itself is public domain. It's been public domain for 91 years. You can find implementations in every language on GitHub, in textbooks, in blog posts. The math is settled.&lt;/p&gt;

&lt;p&gt;So when you pay Optimizely $36,000 per year, you're not paying for the algorithm. You're paying for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The visual editor&lt;/strong&gt; — drag-and-drop test creation for non-technical users&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audience targeting&lt;/strong&gt; — segment by geography, device, behavior, custom attributes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The SDK ecosystem&lt;/strong&gt; — client-side, server-side, edge, mobile, OTT&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The analytics dashboard&lt;/strong&gt; — statistical significance calculations, revenue attribution, funnel visualization&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compliance and governance&lt;/strong&gt; — SOC 2, GDPR controls, approval workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are real features. They have real value — especially for large organizations with non-technical stakeholders who need to create and monitor experiments without writing code.&lt;/p&gt;

&lt;p&gt;But if you're a developer, and you just need the bandit algorithm — the explore/exploit engine that decides which variant to show next — you're paying $36,000 for something that costs pennies to compute.&lt;/p&gt;




&lt;h2&gt;
  
  
  Thompson Sampling in 5 Minutes
&lt;/h2&gt;

&lt;p&gt;Let's actually learn the algorithm you'd be paying for. It's more intuitive than you think.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Explore/Exploit Dilemma
&lt;/h3&gt;

&lt;p&gt;You have three signup button variants. After 100 visitors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Variant A&lt;/strong&gt; converted 35 out of 100 (35%)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Variant B&lt;/strong&gt; converted 40 out of 100 (40%)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Variant C&lt;/strong&gt; converted 5 out of 10 (50%)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Which is best? Traditional A/B testing says: "Keep running all three at equal traffic until we hit statistical significance." That wastes thousands of impressions sending traffic to Variant A, which is clearly losing.&lt;/p&gt;

&lt;p&gt;A naive approach says: "Variant C has 50% — send all traffic there." But wait — that's based on only 10 observations. It could easily be noise.&lt;/p&gt;

&lt;p&gt;This is the &lt;strong&gt;explore/exploit dilemma&lt;/strong&gt;: do you exploit what looks best now, or explore the uncertain option to learn more?&lt;/p&gt;

&lt;h3&gt;
  
  
  How Thompson Sampling Solves It
&lt;/h3&gt;

&lt;p&gt;Thompson Sampling uses &lt;strong&gt;Beta distributions&lt;/strong&gt; to model uncertainty about each variant's true conversion rate.&lt;/p&gt;

&lt;p&gt;For each variant, you maintain two numbers: &lt;strong&gt;successes&lt;/strong&gt; (alpha) and &lt;strong&gt;failures&lt;/strong&gt; (beta). When you need to pick a variant to show, you:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Sample&lt;/strong&gt; a random value from each variant's Beta(alpha, beta) distribution&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pick&lt;/strong&gt; the variant whose sample is highest&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Show&lt;/strong&gt; that variant to the next visitor&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Update&lt;/strong&gt; the winning variant's alpha (if converted) or beta (if didn't)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's it. The entire algorithm.&lt;/p&gt;

&lt;p&gt;The magic is in the Beta distribution's shape. A variant with 40 successes and 60 failures produces a tight distribution centered around 0.40 — you're fairly confident in that number. A variant with 5 successes and 5 failures produces a wide, flat distribution — it could be anywhere from 0.10 to 0.90.&lt;/p&gt;

&lt;p&gt;When you sample from the uncertain distribution, it occasionally produces very high values. That's exploration — the algorithm says "this option might be amazing, let's check." As you gather more data, the distribution tightens, and the algorithm naturally shifts from exploration to exploitation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It converges faster than fixed-split A/B tests&lt;/strong&gt; because it automatically routes more traffic to winning variants while still exploring promising unknowns. No manual intervention. No arbitrary "stop the test" decisions.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Failure Mode LLMs Hit
&lt;/h3&gt;

&lt;p&gt;Here's something surprising: large language models consistently get Thompson Sampling wrong when they try to implement decision-making. They see uncertainty and interpret it as risk. When a variant has high variance, an LLM tends to &lt;strong&gt;pull back&lt;/strong&gt; — to avoid the uncertain option and stick with the known quantity.&lt;/p&gt;

&lt;p&gt;That's the exact opposite of what Thompson Sampling does. The algorithm treats uncertainty as &lt;strong&gt;opportunity&lt;/strong&gt;. High variance means "we might be missing something great here." This is documented in what one team called "The $3,000 Bug" — an AI agent that was supposed to optimize decisions kept choosing the safe, well-known option and ignoring high-upside alternatives because it conflated uncertainty with danger.&lt;/p&gt;

&lt;p&gt;Thompson Sampling doesn't make that mistake. The math doesn't have opinions about risk.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Alternatives Landscape
&lt;/h2&gt;

&lt;p&gt;Optimizely isn't your only option. The market has fragmented significantly, and there are tools at every price point. Here's an honest comparison:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Price&lt;/th&gt;
&lt;th&gt;Bandit Algorithms&lt;/th&gt;
&lt;th&gt;Self-Serve&lt;/th&gt;
&lt;th&gt;Lock-in&lt;/th&gt;
&lt;th&gt;Best For&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Optimizely&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$36K+/yr&lt;/td&gt;
&lt;td&gt;Thompson only&lt;/td&gt;
&lt;td&gt;No (sales call)&lt;/td&gt;
&lt;td&gt;High (SDK)&lt;/td&gt;
&lt;td&gt;Enterprise with big budgets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;VWO&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$199+/mo&lt;/td&gt;
&lt;td&gt;Thompson only&lt;/td&gt;
&lt;td&gt;Partial&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Mid-market marketing teams&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GrowthBook&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Free (self-host)&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Teams with DevOps capacity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Statsig&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Free–$150/mo&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Developer-first teams&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;OraClaw API&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$0/25 calls/day, $0.005/call after, $9/mo Starter&lt;/td&gt;
&lt;td&gt;UCB1 + Thompson + LinUCB&lt;/td&gt;
&lt;td&gt;Yes (1 email)&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Developers and AI agents that just need the algorithm&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A few things jump out:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GrowthBook&lt;/strong&gt; is the open-source hero. If you have the DevOps capacity to self-host, maintain, and monitor it, it's genuinely free and full-featured. The catch is operational overhead — you're running the infrastructure, handling uptime, managing database migrations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Statsig&lt;/strong&gt; hit a sweet spot for developer teams. Their free tier is generous, the DX is good, and it's what Brex switched to. If you need a full experimentation platform with a dashboard, this is the value pick.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;VWO&lt;/strong&gt; occupies the mid-market — cheaper than Optimizely, still dashboard-focused, still requires some sales interaction for advanced features.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OraClaw&lt;/strong&gt; takes a fundamentally different approach. It's not a platform — it's an API endpoint. You send it arm data, it runs the algorithm, it returns a decision. No SDK to install, no dashboard to learn, no vendor lock-in. It supports three bandit algorithms (UCB1 for deterministic upper confidence bounds, Thompson for Bayesian exploration, and LinUCB for context-aware decisions that factor in features like time-of-day or user segment).&lt;/p&gt;

&lt;p&gt;The right choice depends entirely on what you need. Not every problem requires the same tool.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try It Right Now
&lt;/h2&gt;

&lt;p&gt;Here's a working example. No signup, no API key, no sales call. Just paste this into your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://oraclaw-api.onrender.com/api/v1/optimize/bandit &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "arms": [
      {"id": "variant-a", "name": "Original CTA", "pulls": 500, "totalReward": 175},
      {"id": "variant-b", "name": "New CTA", "pulls": 300, "totalReward": 126},
      {"id": "variant-c", "name": "Bold CTA", "pulls": 12, "totalReward": 8}
    ],
    "algorithm": "thompson"
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll get back something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"selected"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"variant-c"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"score"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.71&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"algorithm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"thompson"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wait — variant-c? The one with only 12 pulls and a 66.7% conversion rate?&lt;/p&gt;

&lt;p&gt;Yes. And here's why that's correct.&lt;/p&gt;

&lt;p&gt;Variant A has 500 pulls and a 35% conversion rate. Thompson Sampling is very confident about that number — the Beta(175, 325) distribution is tight. It's almost certainly between 31% and 39%.&lt;/p&gt;

&lt;p&gt;Variant B has 300 pulls and a 42% conversion rate. Also fairly confident — Beta(126, 174) is tight. Probably between 37% and 47%.&lt;/p&gt;

&lt;p&gt;Variant C has 12 pulls and a 66.7% conversion rate. But Beta(8, 4) is &lt;strong&gt;wide&lt;/strong&gt;. The true rate could be anywhere from 35% to 90%. When Thompson samples from this distribution, it frequently draws values above 0.50 — higher than what A or B can produce.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The algorithm is saying: "Variant C looks promising but we barely know anything about it. Let's send more traffic there to find out."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That's exploration in action. If C's true rate is 45%, a few more pulls will tighten the distribution and it'll stop being selected. If C's true rate really is 65%, you just found a massive winner that a fixed 33/33/33 split would have taken 10x longer to identify.&lt;/p&gt;

&lt;p&gt;This is exactly the behavior that the "$3,000 Bug" LLM got wrong. It saw the small sample size and treated it as a reason to avoid variant C. Thompson Sampling sees the small sample size and treats it as a reason to investigate.&lt;/p&gt;

&lt;p&gt;You can swap &lt;code&gt;"algorithm": "thompson"&lt;/code&gt; for &lt;code&gt;"ucb1"&lt;/code&gt; or &lt;code&gt;"linucb"&lt;/code&gt; (with a context vector) to compare strategies. The endpoint is stateless — bring your own data, get back a decision, integrate it however you want. Pipe it into your CI/CD pipeline, call it from a serverless function, embed it in an AI agent's decision loop.&lt;/p&gt;




&lt;h2&gt;
  
  
  The MCP Angle: Your AI Agent Can Call This Directly
&lt;/h2&gt;

&lt;p&gt;If you're using Claude Desktop, Cursor, Cline, or any MCP-compatible client, your agent can call this algorithm itself — no curl, no SDK install, no HTTP code. Drop this into your &lt;code&gt;claude_desktop_config.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"oraclaw"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@oraclaw/mcp-server"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart your client. Now you can literally type:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"I have these three signup variants with these conversion numbers. Which should I send the next 1,000 visitors to?"&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The agent calls &lt;code&gt;optimize_bandit&lt;/code&gt; itself, gets back a structured decision in 0.01ms, and explains the result in your language. No more LLMs guessing at the math — they offload it to a real algorithm.&lt;/p&gt;

&lt;p&gt;The MCP server ships with &lt;strong&gt;17 tools&lt;/strong&gt; total: bandits, contextual bandits, genetic algorithms, Monte Carlo, scheduling, pathfinding, scoring, Bayesian belief updates, ensemble consensus — 11 free without a key, 6 premium (LP/MIP solver, time-series forecasting, anomaly detection, graph analytics, CMA-ES, portfolio risk). All with explicit input + output JSON schemas so your agent knows exactly what it gets back.&lt;/p&gt;

&lt;p&gt;Get the MCP server: &lt;a href="https://www.npmjs.com/package/@oraclaw/mcp-server" rel="noopener noreferrer"&gt;npmjs.com/package/@oraclaw/mcp-server&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  When NOT to Use This
&lt;/h2&gt;

&lt;p&gt;Let's be honest about the tradeoffs.&lt;/p&gt;

&lt;p&gt;If you need a &lt;strong&gt;visual editor&lt;/strong&gt; so your marketing team can create tests without writing code — use Optimizely or VWO. If you need &lt;strong&gt;audience targeting&lt;/strong&gt; with complex segmentation rules — use a platform. If you need a &lt;strong&gt;dashboard&lt;/strong&gt; with real-time charts for stakeholders who don't read JSON — use Statsig or GrowthBook.&lt;/p&gt;

&lt;p&gt;A bare API endpoint is the wrong tool for organizations where non-developers need to create and monitor experiments. That's a real use case, and the $36K platforms serve it well.&lt;/p&gt;

&lt;p&gt;But if you're a developer calling an optimization algorithm from your backend, your data pipeline, or your AI agent — you don't need a visual editor. You don't need a dashboard. You need the math, and you need it fast, and you need it cheap.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Math Doesn't Care About Your Budget
&lt;/h2&gt;

&lt;p&gt;Thompson Sampling produces the same distribution, the same samples, and the same convergence properties whether the compute costs $36,000 per year or $0.005 per call. The algorithm was published in 1933. It's been proven optimal in the limit. No amount of enterprise packaging changes the underlying mathematics.&lt;/p&gt;

&lt;p&gt;The question isn't "which algorithm is best" — for most A/B testing scenarios, Thompson Sampling is the answer regardless of vendor. The question is: &lt;strong&gt;how much infrastructure do you need wrapped around it?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If the answer is "a lot" — platforms exist for that. If the answer is "just give me the algorithm" — now you know what your options are.&lt;/p&gt;

&lt;p&gt;Stop paying $36,000 for 20 lines of math.&lt;/p&gt;




&lt;h2&gt;
  
  
  Get Started
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Free tier (no signup):&lt;/strong&gt; the curl command above runs against the live API right now, 25 calls/day per IP, no key&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Get an API key (1 email field):&lt;/strong&gt; &lt;a href="https://web-olive-one-89.vercel.app/signup" rel="noopener noreferrer"&gt;oraclaw signup&lt;/a&gt; — instant key, 1,000 calls/day on pay-per-call ($0.005/call), upgrade to Starter $9/mo for 50K/month&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use it from your AI agent:&lt;/strong&gt; &lt;code&gt;npm install @oraclaw/mcp-server&lt;/code&gt; or paste the MCP config above into Claude Desktop / Cursor / Cline&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Source + 17-tool docs:&lt;/strong&gt; &lt;a href="https://github.com/Whatsonyourmind/oraclaw" rel="noopener noreferrer"&gt;github.com/Whatsonyourmind/oraclaw&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If this saved you from a $36K sales call, leave a star — it helps other developers find it.&lt;/p&gt;

</description>
      <category>testing</category>
      <category>webdev</category>
      <category>mcp</category>
      <category>ai</category>
    </item>
    <item>
      <title>How I Built an x402-Monetized MCP Server for AI Presentation Generation</title>
      <dc:creator>Whatsonyourmind</dc:creator>
      <pubDate>Thu, 02 Apr 2026 23:29:16 +0000</pubDate>
      <link>https://dev.to/whatsonyourmind/how-i-built-an-x402-monetized-mcp-server-for-ai-presentation-generation-4a6i</link>
      <guid>https://dev.to/whatsonyourmind/how-i-built-an-x402-monetized-mcp-server-for-ai-presentation-generation-4a6i</guid>
      <description>&lt;p&gt;AI agents can write code, search the web, query databases, and manage files. But ask one to create a PowerPoint deck and you get a code block with python-pptx boilerplate that positions shapes by pixel offset. The output looks like a 2003 corporate template, and it breaks the moment content overflows a text box.&lt;/p&gt;

&lt;p&gt;I built &lt;a href="https://github.com/Whatsonyourmind/deckforge" rel="noopener noreferrer"&gt;DeckForge&lt;/a&gt; to fix this: an API-first presentation generation platform with an MCP server that gives AI agents real slide creation capabilities. And because I wanted autonomous agents to pay per-call without API key management, I integrated x402 -- the HTTP-native micropayment protocol that settles in USDC on Base L2.&lt;/p&gt;

&lt;p&gt;This article covers the architecture, the MCP integration, and how x402 payments work in practice.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;There are three ways to generate slides programmatically today:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;python-pptx&lt;/strong&gt; -- the standard library. It gives you element-level control, but you manually position every shape. There's no layout engine, no theme system, no chart rendering.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;GUI tools like Gamma and Tome&lt;/strong&gt; -- beautiful output, but zero API access. You can't call them from code or an agent.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Ask an LLM to write python-pptx code&lt;/strong&gt; -- the LLM doesn't know the actual dimensions of rendered text, so content overflow is guaranteed. And you're generating code that generates slides, which is one abstraction too many.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The gap is: send structured data, get a polished deck. That's DeckForge.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;

&lt;p&gt;DeckForge is a FastAPI service with a JSON intermediate representation (IR) at the core. The IR schema uses Pydantic discriminated unions. There are 32 slide types -- 23 universal (title, bullets, chart, table, comparison, timeline, funnel, matrix, org chart, etc.) and 9 finance-specific (DCF summary, comp table, waterfall, deal overview, capital structure, market landscape, risk matrix, investment thesis).&lt;/p&gt;

&lt;p&gt;The key insight: &lt;strong&gt;layout is a constraint satisfaction problem, not a coordinate problem.&lt;/strong&gt; Instead of hardcoding positions, each slide type defines layout constraints. Kiwisolver resolves these into coordinates at render time, and the overflow handler cascades through font reduction -&amp;gt; reflow -&amp;gt; slide splitting if content doesn't fit.&lt;/p&gt;

&lt;h2&gt;
  
  
  MCP Integration
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://modelcontextprotocol.io/" rel="noopener noreferrer"&gt;Model Context Protocol&lt;/a&gt; is how AI agents discover and invoke tools. DeckForge exposes 6 MCP tools:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mcp.server.fastmcp&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FastMCP&lt;/span&gt;

&lt;span class="n"&gt;mcp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FastMCP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DeckForge&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@mcp.tool&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ir_json&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;corporate-blue&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Render a Presentation IR into a PowerPoint file.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;render_presentation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ir_json&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@mcp.tool&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;slide_count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;corporate-blue&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Generate a complete presentation from a natural language prompt.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;generate_presentation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;slide_count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@mcp.tool&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;themes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;List all 15 available themes.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;list_themes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To use with Claude Desktop, add this to your MCP config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"deckforge"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"python"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-m"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"deckforge.mcp.server"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now Claude can create actual PowerPoint files -- not code snippets.&lt;/p&gt;

&lt;h2&gt;
  
  
  x402: Machine-Native Payments
&lt;/h2&gt;

&lt;p&gt;Traditional API billing assumes a human signs up and enters a credit card. But autonomous AI agents don't have credit cards. They have wallets.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://x402.org" rel="noopener noreferrer"&gt;x402&lt;/a&gt; brings the 402 Payment Required status code to life. The agent hits a protected endpoint, gets back a 402 with pricing, constructs a signed USDC transfer on Base L2, and retries with a payment header. DeckForge verifies and settles on-chain.&lt;/p&gt;

&lt;p&gt;x402-authenticated requests skip rate limiting -- per-call payment is inherently self-throttling. The agent pays $0.05 per render and $0.15 per generate. No subscription, no credit card, no API key signup.&lt;/p&gt;

&lt;p&gt;This matters because the direction of AI tooling is toward autonomous agent workflows. An agent that discovers a tool via MCP and pays via x402 doesn't need human intervention at any step.&lt;/p&gt;

&lt;h2&gt;
  
  
  TypeScript SDK
&lt;/h2&gt;

&lt;p&gt;For human developers, there's a typed SDK on npm:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @lukastan/deckforge
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;DeckForge&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Presentation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Slides&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@lukastan/deckforge&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;DeckForge&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dk_test_...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;deck&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Presentation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Q4 Board Update&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;corporate-blue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addSlide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Slides&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;titleSlide&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Q4 2026 Board Update&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;subtitle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Acme Corp&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addSlide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Slides&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;statsCallout&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Key Metrics&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;metrics&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$4.2M&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ARR&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;142%&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;YoY Growth&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;}));&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pptx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deck&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Finance Angle
&lt;/h2&gt;

&lt;p&gt;The finance vertical is deliberate. PE firms, investment banks, and consulting firms generate massive volumes of standardized presentations: IC memos, teasers, CIMs, board decks. The formatting is rigid, repetitive, and time-consuming.&lt;/p&gt;

&lt;p&gt;The 9 finance slide types encode domain conventions: DCF summary with assumption labels, comp table with conditional formatting, returns waterfall showing entry to exit value creation, deal overview with standardized layout, capital structure with debt/equity stack visualization.&lt;/p&gt;

&lt;h2&gt;
  
  
  Current State
&lt;/h2&gt;

&lt;p&gt;This is v0.1. The API is live, 846 tests passing, MIT licensed. Pre-revenue, sole developer.&lt;/p&gt;

&lt;p&gt;What works well: IR-to-PPTX rendering is solid, finance slides look close to real deal team output, MCP integration works with Claude Desktop.&lt;/p&gt;

&lt;p&gt;What needs work: NL-to-IR quality varies by LLM provider, Google Slides output is less polished, x402 untested in production with real agent wallets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/Whatsonyourmind/deckforge" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/@lukastan/deckforge" rel="noopener noreferrer"&gt;npm SDK&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://deckforge-api.onrender.com/docs" rel="noopener noreferrer"&gt;API docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://landing-two-beta-63.vercel.app" rel="noopener noreferrer"&gt;Landing page&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Need a presentation built?&lt;/strong&gt; I offer pitch decks, board updates, PE deal memos, and strategy decks as a service. Built by a finance professional with a proprietary AI rendering engine. &lt;a href="https://sales-gray-eight.vercel.app" rel="noopener noreferrer"&gt;See pricing and order here&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>PageRank, Louvain, and Shortest Path — Without Deploying Neo4j</title>
      <dc:creator>Whatsonyourmind</dc:creator>
      <pubDate>Thu, 02 Apr 2026 20:05:19 +0000</pubDate>
      <link>https://dev.to/whatsonyourmind/pagerank-louvain-and-shortest-path-without-deploying-neo4j-1jbk</link>
      <guid>https://dev.to/whatsonyourmind/pagerank-louvain-and-shortest-path-without-deploying-neo4j-1jbk</guid>
      <description>&lt;h2&gt;
  
  
  The Problem Nobody Talks About
&lt;/h2&gt;

&lt;p&gt;You have a microservices architecture with 50 services. A deployment went sideways and you need to figure out which service is the single point of failure, which groups of services are tightly coupled, and which service — if it goes down — takes the most other services with it.&lt;/p&gt;

&lt;p&gt;Or maybe you're building a recommendation engine. You have users, items, and interactions between them. You need to rank items by importance, not just by raw interaction count, but by &lt;em&gt;how important the users who interact with them are&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Or you're managing a project with 30 tasks and complex dependencies. You need the critical path, the bottlenecks, and a way to group related tasks into workstreams.&lt;/p&gt;

&lt;p&gt;The textbook answer to all of these: deploy Neo4j (or Amazon Neptune, or TigerGraph). Model your data as nodes and edges. Learn Cypher. Write queries. Maintain infrastructure. Pay for hosting. The pragmatic answer: you need three algorithms.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PageRank&lt;/strong&gt; tells you importance. &lt;strong&gt;Louvain&lt;/strong&gt; tells you communities. &lt;strong&gt;Shortest path&lt;/strong&gt; tells you critical paths and bottlenecks.&lt;/p&gt;

&lt;p&gt;You don't need a graph database for graph analytics. You need the algorithms. And for the vast majority of real-world use cases — graphs with dozens to thousands of nodes — running these three algorithms on demand is faster, cheaper, and simpler than standing up and maintaining a graph database.&lt;/p&gt;

&lt;p&gt;Let me walk through each algorithm, explain when you'd use it, and show a working example that you can run right now.&lt;/p&gt;




&lt;h2&gt;
  
  
  Three Algorithms, Explained Simply
&lt;/h2&gt;

&lt;h3&gt;
  
  
  PageRank — "Who Matters Most?"
&lt;/h3&gt;

&lt;p&gt;Google built their empire on this algorithm. The insight is recursive: a node is important if &lt;em&gt;important nodes&lt;/em&gt; point to it. A web page linked by the New York Times matters more than one linked by a random blog. A microservice depended on by your API gateway matters more than one depended on by an internal logging tool.&lt;/p&gt;

&lt;p&gt;PageRank isn't just for web pages. It works on any directed graph. Use cases include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure:&lt;/strong&gt; Which service, if it goes down, causes the most cascading failures?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Influence mapping:&lt;/strong&gt; Which person in an organization is the most influential (not by title, but by actual dependency patterns)?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content ranking:&lt;/strong&gt; Which document in a knowledge base is referenced most by other important documents?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The algorithm iterates until convergence: each node distributes its current rank equally across its outgoing edges, and receives rank from incoming edges. A damping factor (usually 0.85) prevents rank from concentrating in cycles.&lt;/p&gt;

&lt;h3&gt;
  
  
  Louvain Community Detection — "What Belongs Together?"
&lt;/h3&gt;

&lt;p&gt;Louvain finds natural clusters by optimizing &lt;em&gt;modularity&lt;/em&gt; — a measure of how densely connected nodes within a group are compared to connections between groups. The algorithm is greedy and hierarchical: it starts with each node in its own community, then merges communities that improve modularity, repeating until no further improvement is possible.&lt;/p&gt;

&lt;p&gt;What makes Louvain practical is that it's fast (near-linear time complexity) and requires zero configuration. You don't tell it how many clusters to find — it discovers them. Use cases include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fraud detection:&lt;/strong&gt; Find rings of accounts that transact heavily with each other but rarely with outsiders.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Market segmentation:&lt;/strong&gt; Cluster customers by their actual interaction patterns, not demographic assumptions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Codebase analysis:&lt;/strong&gt; Identify tightly coupled modules that should be extracted into packages.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Shortest Path and Bottleneck Detection — "Where Are the Chokepoints?"
&lt;/h3&gt;

&lt;p&gt;Dijkstra's algorithm finds the lowest-cost path between two nodes. That's useful on its own for critical path analysis, but the real power comes from &lt;em&gt;bottleneck detection&lt;/em&gt;: identify nodes where many paths converge.&lt;/p&gt;

&lt;p&gt;A bottleneck node has high in-degree (many things flow into it) and high PageRank (it's important) but relatively low out-degree (it's a funnel). The bottleneck score formula — &lt;code&gt;PageRank * (inDegree + 1) / (outDegree + 1)&lt;/code&gt; — surfaces these chokepoints. Use cases include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Supply chain risk:&lt;/strong&gt; Which supplier, if disrupted, breaks the most downstream processes?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Project management:&lt;/strong&gt; Which task is on every critical path and has no parallel alternative?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network reliability:&lt;/strong&gt; Which router handles the most cross-segment traffic?&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Real Example: Ranking and Clustering a Dependency Graph
&lt;/h2&gt;

&lt;p&gt;Let's take a common scenario: five components in a system with dependency relationships. We want to know which component is most critical, how the components cluster, and where the bottlenecks are.&lt;/p&gt;

&lt;p&gt;Here's a working API call. &lt;code&gt;analyze_graph&lt;/code&gt; is a premium-tier tool, so grab a free API key first (instant, no credit card):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://oraclaw-api.onrender.com/api/v1/auth/signup &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"email":"you@example.com"}'&lt;/span&gt;
&lt;span class="c"&gt;# response includes { "api_key": "oc_..." }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then run the analysis:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://oraclaw-api.onrender.com/api/v1/analyze/graph &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer oc_YOUR_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "nodes": [
      {"id": "auth", "type": "action", "label": "Auth Service", "urgency": "high", "confidence": 0.9, "impact": 0.9, "timestamp": 1711350000},
      {"id": "api", "type": "action", "label": "API Gateway", "urgency": "high", "confidence": 0.8, "impact": 0.8, "timestamp": 1711350000},
      {"id": "db", "type": "action", "label": "Database", "urgency": "medium", "confidence": 0.7, "impact": 0.9, "timestamp": 1711350000},
      {"id": "cache", "type": "action", "label": "Cache Layer", "urgency": "low", "confidence": 0.6, "impact": 0.5, "timestamp": 1711350000},
      {"id": "frontend", "type": "goal", "label": "Frontend", "urgency": "medium", "confidence": 0.8, "impact": 0.7, "timestamp": 1711350000}
    ],
    "edges": [
      {"source": "frontend", "target": "api", "type": "depends_on", "weight": 1.0},
      {"source": "api", "target": "auth", "type": "depends_on", "weight": 0.9},
      {"source": "api", "target": "db", "type": "depends_on", "weight": 0.8},
      {"source": "api", "target": "cache", "type": "depends_on", "weight": 0.5},
      {"source": "auth", "target": "db", "type": "depends_on", "weight": 0.7}
    ]
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Reading the Response
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;PageRank&lt;/strong&gt; reveals that &lt;code&gt;db&lt;/code&gt; (Database) has the highest rank. This makes intuitive sense — both &lt;code&gt;api&lt;/code&gt; and &lt;code&gt;auth&lt;/code&gt; depend on it, and &lt;code&gt;api&lt;/code&gt; itself is depended on by &lt;code&gt;frontend&lt;/code&gt;. The database sits at the bottom of the dependency chain, and importance flows downhill. Meanwhile, &lt;code&gt;frontend&lt;/code&gt; has the lowest PageRank because nothing depends on it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Communities&lt;/strong&gt; split the graph into two natural clusters. One cluster groups &lt;code&gt;frontend&lt;/code&gt;, &lt;code&gt;api&lt;/code&gt;, and &lt;code&gt;cache&lt;/code&gt; — the "request-serving" layer. The other groups &lt;code&gt;auth&lt;/code&gt; and &lt;code&gt;db&lt;/code&gt; — the "data and identity" layer. Louvain found this structure automatically, with no configuration. If you were splitting your monolith into two deployable units, this is where you'd draw the line.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bottlenecks&lt;/strong&gt; show that &lt;code&gt;api&lt;/code&gt; has the highest bottleneck score. Three edges flow into or through it, but its outgoing connections fan out to three different services. It's the classic single point of failure — the funnel that every request must pass through. If you're investing in redundancy, &lt;code&gt;api&lt;/code&gt; is where to start.&lt;/p&gt;

&lt;p&gt;This analysis runs in under 25 milliseconds. No database to provision, no query language to learn, no infrastructure to maintain.&lt;/p&gt;




&lt;h2&gt;
  
  
  Other Use Cases
&lt;/h2&gt;

&lt;p&gt;These same three algorithms apply far beyond infrastructure graphs:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recommendation ranking.&lt;/strong&gt; Build a bipartite graph of users and items. Run PageRank — items connected to high-PageRank users surface as recommendations. This is how early collaborative filtering worked, and it's still effective for cold-start scenarios.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fraud detection.&lt;/strong&gt; Model transactions as edges between accounts. Run Louvain — fraud rings show up as tight communities with unusually high internal transaction volume relative to external connections.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Project management.&lt;/strong&gt; Model tasks as nodes and dependencies as edges. PageRank identifies the most critical tasks (those that block the most downstream work). Shortest path gives you the critical path through the project. Bottleneck detection flags tasks that need extra resources or contingency plans.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Knowledge graphs.&lt;/strong&gt; Connect concepts, documents, or entities. PageRank surfaces the most referenced concepts. Louvain groups related topics. Shortest path finds the connection between any two concepts — useful for "explain how X relates to Y" features.&lt;/p&gt;




&lt;h2&gt;
  
  
  When You Need More
&lt;/h2&gt;

&lt;p&gt;These three algorithms have limits. If you're working with billions of edges, you need a distributed graph engine like Apache Spark GraphX or Neo4j. If you need streaming graph updates with real-time traversals, you need a proper graph database. If you need complex pattern matching (find all triangles, match subgraph patterns), Cypher or Gremlin gives you query expressiveness that no API can replicate.&lt;/p&gt;

&lt;p&gt;But be honest about your scale. Most graphs in application development have hundreds to low thousands of nodes. For those, spinning up a graph database is like renting a warehouse to store a bookshelf.&lt;/p&gt;




&lt;h2&gt;
  
  
  Bottom Line
&lt;/h2&gt;

&lt;p&gt;Graph algorithms are powerful. Graph databases are overkill for most use cases. PageRank, Louvain, and shortest path cover roughly 80% of what developers actually need from graph analytics: rank things by importance, find natural clusters, and identify bottlenecks.&lt;/p&gt;

&lt;p&gt;The example above uses &lt;a href="https://oraclaw-api.onrender.com/api/v1/analyze/graph" rel="noopener noreferrer"&gt;OraClaw's graph analysis endpoint&lt;/a&gt;, which runs all three algorithms in a single call using the &lt;a href="https://graphology.github.io/" rel="noopener noreferrer"&gt;graphology&lt;/a&gt; library under the hood. It's free, stateless, and takes under 25ms. But even if you roll your own — &lt;code&gt;graphology&lt;/code&gt; plus &lt;code&gt;graphology-metrics&lt;/code&gt; plus &lt;code&gt;graphology-communities-louvain&lt;/code&gt; gives you everything shown here in about 280 lines of TypeScript.&lt;/p&gt;

&lt;p&gt;The point isn't the tool. The point is that graph analytics shouldn't require a graph database. Three algorithms, one API call, instant answers.&lt;/p&gt;




&lt;h2&gt;
  
  
  The MCP Angle
&lt;/h2&gt;

&lt;p&gt;If you're building an AI agent (Claude Desktop, Cursor, Cline), you don't need to hand-write these curl commands. OraClaw ships as an MCP server -- the agent gets &lt;code&gt;analyze_graph&lt;/code&gt; + &lt;code&gt;plan_pathfind&lt;/code&gt; + 15 other deterministic tools, with schemas, and decides when to call them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"oraclaw"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@oraclaw/mcp-server"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"ORACLAW_API_KEY"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"oc_YOUR_KEY"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or via Claude CLI: &lt;code&gt;claude mcp add oraclaw -- npx -y @oraclaw/mcp-server&lt;/code&gt;. Works for all 17 tools -- optimization, simulation, forecasting, calibration, anomaly detection.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get Started
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Free tier&lt;/strong&gt; (no API key, 25 calls/day): &lt;code&gt;plan_pathfind&lt;/code&gt;, &lt;code&gt;simulate_montecarlo&lt;/code&gt;, &lt;code&gt;optimize_bandit&lt;/code&gt;, &lt;code&gt;score_convergence&lt;/code&gt;, and 3 more&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Free API key for premium&lt;/strong&gt; (anomaly, forecast, LP solver, graph analytics, CMA-ES, risk): &lt;code&gt;POST /api/v1/auth/signup&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Source + 17 tool schemas&lt;/strong&gt;: &lt;a href="https://github.com/Whatsonyourmind/oraclaw" rel="noopener noreferrer"&gt;github.com/Whatsonyourmind/oraclaw&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>api</category>
      <category>datascience</category>
      <category>mcp</category>
      <category>ai</category>
    </item>
    <item>
      <title>Why Your AI Agent Burns 10,000 Tokens on Math It Could Do in 1ms</title>
      <dc:creator>Whatsonyourmind</dc:creator>
      <pubDate>Thu, 02 Apr 2026 19:57:24 +0000</pubDate>
      <link>https://dev.to/whatsonyourmind/why-your-ai-agent-burns-10000-tokens-on-math-it-could-do-in-1ms-59np</link>
      <guid>https://dev.to/whatsonyourmind/why-your-ai-agent-burns-10000-tokens-on-math-it-could-do-in-1ms-59np</guid>
      <description>&lt;h2&gt;
  
  
  The $3,000 Chain-of-Thought
&lt;/h2&gt;

&lt;p&gt;Last month, an e-commerce team's AI agent managed their A/B tests. Three variants. The agent observed conversion data, reasoned about which variant was winning, and allocated traffic. The chain-of-thought was beautiful:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Variant B shows 4.2% conversion rate vs A's 3.8%. However, Variant C has a smaller sample size (n=340), so I should allocate more traffic there for statistical significance before drawing conclusions. For now, I'll route 60% of traffic to B as the current leader."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Thoughtful. Measured. &lt;strong&gt;Wrong.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Three weeks and $3,000 in lost conversions later, a junior data scientist ran the actual numbers through a Thompson Sampling bandit. Variant C was the winner -- by a wide margin. Its 66.7% conversion rate on a small sample wasn't noise. It was a signal that any exploration-exploitation algorithm would have caught on day one.&lt;/p&gt;

&lt;p&gt;The agent didn't make a calculation error. It never calculated anything. It &lt;em&gt;narrated&lt;/em&gt; what a calculation might look like, and the narrative sounded reasonable enough that nobody questioned it.&lt;/p&gt;

&lt;p&gt;This isn't a one-off failure. It's a systematic architectural flaw in how we build AI agents today, and it's costing teams real money in production right now.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Invisible Failure Mode
&lt;/h2&gt;

&lt;p&gt;What makes this category of bug terrifying is that it's undetectable by reading the output.&lt;/p&gt;

&lt;p&gt;When an agent hallucinates a fact, you can check the fact. When it writes buggy code, the tests fail. But when it produces plausible-sounding mathematical reasoning? The chain-of-thought &lt;em&gt;is&lt;/em&gt; the evidence, and the evidence looks airtight.&lt;/p&gt;

&lt;p&gt;Here's the specific failure mechanism: LLMs treat uncertainty as a reason to be cautious. When the agent saw Variant C with only 340 observations, its training data -- full of human wisdom about "not jumping to conclusions" and "needing larger sample sizes" -- told it to hedge. Allocate less traffic. Wait and see.&lt;/p&gt;

&lt;p&gt;But in sequential decision-making under uncertainty, this intuition is &lt;strong&gt;provably suboptimal&lt;/strong&gt;. The entire field of multi-armed bandits exists because of a mathematical truth that contradicts human intuition: when you're uncertain about an option, you should explore it &lt;em&gt;more&lt;/em&gt;, not less. The potential information gain from pulling an uncertain arm outweighs the expected regret.&lt;/p&gt;

&lt;p&gt;Thompson Sampling handles this elegantly. It models each arm as a Beta distribution (for binary outcomes like conversions). For Variant C with 8 successes and 4 failures, the posterior is Beta(9, 5) -- a distribution with high variance but a mean of 0.64. When you sample from these distributions, the high-variance arm gets selected more often &lt;em&gt;precisely because&lt;/em&gt; the uncertainty could resolve favorably. That's not recklessness. That's mathematically optimal exploration.&lt;/p&gt;

&lt;p&gt;The LLM can't do this. Not because it's stupid, but because sampling from a Beta distribution and comparing draws across arms is a &lt;em&gt;computation&lt;/em&gt;, not a &lt;em&gt;reasoning task&lt;/em&gt;. Asking an LLM to do it is like asking a poet to multiply matrices. The poet might write something beautiful about matrix multiplication. It won't be correct.&lt;/p&gt;

&lt;p&gt;This matters because the failure mode is invisible. The output passes every vibe check. The reasoning chain reads like something a smart analyst would write. The only way to catch it is to run the actual math -- which raises the obvious question: why not run the actual math in the first place?&lt;/p&gt;

&lt;h2&gt;
  
  
  The Architecture That Fixes It
&lt;/h2&gt;

&lt;p&gt;The fix isn't replacing agents. It's giving them the right tools.&lt;/p&gt;

&lt;p&gt;The pattern is simple: &lt;strong&gt;LLM reasons, algorithm computes, LLM interprets.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The agent still does what it's genuinely good at -- understanding context, deciding which tool to invoke, generating human-readable reports, explaining results to stakeholders. It just stops pretending to be a mathematician.&lt;/p&gt;

&lt;p&gt;Here's what the corrected flow looks like for common scenarios:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A/B Testing:&lt;/strong&gt; Agent sees conversion data, calls a multi-armed bandit endpoint, gets the mathematically optimal arm to pull next. The agent decides &lt;em&gt;when&lt;/em&gt; to run the test and &lt;em&gt;how&lt;/em&gt; to explain the result. The algorithm decides &lt;em&gt;which arm wins&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scheduling:&lt;/strong&gt; Agent receives a set of tasks with constraints (deadlines, dependencies, resource limits), calls a linear programming solver, gets the optimal schedule. The agent handles the messy human context -- "this meeting is technically optional but politically mandatory." The solver handles the combinatorial optimization.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Risk Assessment:&lt;/strong&gt; Agent identifies that a decision needs probabilistic analysis, calls a Monte Carlo simulation, gets real confidence intervals. No more "I estimate a 70% probability" pulled from the statistical equivalent of nowhere.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Anomaly Detection:&lt;/strong&gt; Agent monitors data streams, calls a detection algorithm with proper statistical thresholds, gets flagged anomalies with Z-scores and p-values instead of "this looks unusual."&lt;/p&gt;

&lt;p&gt;The key insight: deterministic algorithms are commodities. Thompson Sampling, Simplex, Monte Carlo -- these are solved problems. Every agent that needs them is currently re-solving them badly through token-expensive chain-of-thought reasoning. What if they were just... API calls?&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It: The A/B Test Fix
&lt;/h2&gt;

&lt;p&gt;Let's make this concrete. Here's the exact A/B test scenario from the opening, run through an actual Thompson Sampling endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://oraclaw-api.onrender.com/api/v1/optimize/bandit &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "arms": [
      {"id": "A", "name": "Control", "pulls": 500, "totalReward": 175},
      {"id": "B", "name": "Variant B", "pulls": 300, "totalReward": 126},
      {"id": "C", "name": "Variant C", "pulls": 12, "totalReward": 8}
    ],
    "algorithm": "thompson"
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response comes back in under 5ms. Thompson Sampling selects &lt;strong&gt;Variant C&lt;/strong&gt; -- the under-explored arm with the highest potential. The algorithm samples from each arm's Beta posterior:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Arm A: Beta(176, 326) -- tight distribution around 0.35&lt;/li&gt;
&lt;li&gt;Arm B: Beta(127, 175) -- tight distribution around 0.42&lt;/li&gt;
&lt;li&gt;Arm C: Beta(9, 5) -- wide distribution, mean 0.64&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The high variance on Arm C means its samples frequently exceed B's. That's not a bug; that's optimal exploration. The algorithm &lt;em&gt;wants&lt;/em&gt; to learn more about C because the expected information value is highest there.&lt;/p&gt;

&lt;p&gt;Compare the outcomes:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;LLM Reasoning&lt;/th&gt;
&lt;th&gt;Algorithm&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Arm selected&lt;/td&gt;
&lt;td&gt;B (confirmation bias)&lt;/td&gt;
&lt;td&gt;C (optimal exploration)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Time to identify winner&lt;/td&gt;
&lt;td&gt;Never (stuck on B)&lt;/td&gt;
&lt;td&gt;~48 hours&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Conversion lift&lt;/td&gt;
&lt;td&gt;0% (wrong arm)&lt;/td&gt;
&lt;td&gt;+23% (correct arm)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tokens consumed&lt;/td&gt;
&lt;td&gt;~2,000 per decision&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Latency&lt;/td&gt;
&lt;td&gt;800ms (API round-trip + inference)&lt;/td&gt;
&lt;td&gt;&amp;lt;5ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The LLM spent 2,000 tokens arriving at the wrong answer. The algorithm spent zero tokens arriving at the right one. Multiply that by every decision an agent makes in production, and you start to see why this architecture matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  For MCP Users: 3-Line Setup
&lt;/h2&gt;

&lt;p&gt;If you're building agents with Claude, GPT, or any MCP-compatible client, you can add mathematical optimization as a native tool capability in three lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"oraclaw"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@oraclaw/mcp-server"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Drop that into your Claude Desktop config (&lt;code&gt;claude_desktop_config.json&lt;/code&gt;) or any MCP-compatible client. Your agent now has access to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Multi-armed bandits&lt;/strong&gt; (UCB1, Thompson Sampling, epsilon-greedy) -- for any explore/exploit decision&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Linear programming solver&lt;/strong&gt; -- for scheduling, resource allocation, portfolio optimization&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monte Carlo simulation&lt;/strong&gt; -- for risk assessment, confidence intervals, scenario analysis&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Anomaly detection&lt;/strong&gt; -- for monitoring, alerting, quality control&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Graph analytics&lt;/strong&gt; -- for dependency analysis, critical path, network optimization&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bayesian inference&lt;/strong&gt; -- for updating beliefs with new evidence&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The agent decides &lt;em&gt;when&lt;/em&gt; to use math. The algorithm decides &lt;em&gt;what&lt;/em&gt; the math says. The agent still owns the conversation, the context, the judgment calls. It just delegates computation to something that can actually compute.&lt;/p&gt;

&lt;p&gt;This is what &lt;a href="https://github.com/Whatsonyourmind/oraclaw" rel="noopener noreferrer"&gt;OraClaw&lt;/a&gt; provides -- an open-source decision intelligence server built specifically for the MCP ecosystem. Seventeen MCP tools, twenty algorithms, all running in under 25ms. No API keys, no rate limits on the math itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Pattern
&lt;/h2&gt;

&lt;p&gt;There's a broader principle here that extends beyond A/B testing:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Math that doesn't need to be re-done by every agent who needs it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As one community member put it: deterministic algorithms are commodities. Thompson Sampling doesn't get better when you run it on a more expensive model. The Simplex method doesn't need chain-of-thought reasoning. Monte Carlo simulation doesn't benefit from in-context learning.&lt;/p&gt;

&lt;p&gt;The intelligence in an agent system isn't in the math. It's in knowing &lt;em&gt;when&lt;/em&gt; to apply the math, &lt;em&gt;which&lt;/em&gt; algorithm fits the problem, and &lt;em&gt;how&lt;/em&gt; to interpret the result for a human. That's what LLMs are genuinely excellent at.&lt;/p&gt;

&lt;p&gt;Let the LLM handle intelligence. Let the algorithm handle math.&lt;/p&gt;

&lt;p&gt;Every token your agent spends on computation it could offload to a deterministic tool is a token not spent on the reasoning, context, and judgment that actually requires general intelligence. In a world where tokens cost money and latency costs users, that distinction is the difference between an agent that sounds smart and one that &lt;em&gt;is&lt;/em&gt; smart.&lt;/p&gt;

&lt;p&gt;The MCP ecosystem has 97 million monthly downloads and growing. The agent-building community is massive. The math tools those agents need? Almost nonexistent -- until now. If you're building agents that make decisions under uncertainty, stop letting them guess. Give them the math.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;OraClaw is open source and free to use. &lt;a href="https://github.com/Whatsonyourmind/oraclaw" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; | &lt;a href="https://www.npmjs.com/package/@oraclaw/mcp-server" rel="noopener noreferrer"&gt;MCP Server&lt;/a&gt; | &lt;a href="https://oraclaw-api.onrender.com/docs" rel="noopener noreferrer"&gt;API Docs&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Get Started (30 seconds)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Try it without installing anything:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://oraclaw-api.onrender.com/api/v1/optimize/bandit &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"arms":[{"id":"a","name":"Short Email","pulls":500,"totalReward":175},{"id":"b","name":"Long Email","pulls":300,"totalReward":126}],"algorithm":"ucb1"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Plug it into your agent (Claude Desktop / Cursor / Cline):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"oraclaw"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@oraclaw/mcp-server"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or via Claude CLI: &lt;code&gt;claude mcp add oraclaw -- npx -y @oraclaw/mcp-server&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Free API key for premium tools&lt;/strong&gt; (forecasting, anomaly detection, LP solver, graph analytics, CMA-ES, risk): &lt;code&gt;POST https://oraclaw-api.onrender.com/api/v1/auth/signup&lt;/code&gt; with &lt;code&gt;{"email":"..."}&lt;/code&gt; → instant key.&lt;/p&gt;

&lt;p&gt;Browse all 17 tools + schemas at &lt;a href="https://github.com/Whatsonyourmind/oraclaw" rel="noopener noreferrer"&gt;github.com/Whatsonyourmind/oraclaw&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>mcp</category>
      <category>programming</category>
    </item>
    <item>
      <title>Your AI Agent Is Wasting $0.04 Every Time It Reasons About Optimization. Here's the $0.01 Alternative.</title>
      <dc:creator>Whatsonyourmind</dc:creator>
      <pubDate>Tue, 31 Mar 2026 13:25:14 +0000</pubDate>
      <link>https://dev.to/whatsonyourmind/your-ai-agent-is-wasting-004-every-time-it-reasons-about-optimization-heres-the-001-2mk6</link>
      <guid>https://dev.to/whatsonyourmind/your-ai-agent-is-wasting-004-every-time-it-reasons-about-optimization-heres-the-001-2mk6</guid>
      <description>&lt;p&gt;Last week I watched GPT-4 spend 2,000 tokens, 3 seconds, and $0.04 to pick the wrong A/B test variant. Then I replaced it with a single API call that took 0.01ms, cost $0.01, and gave the mathematically correct answer.&lt;/p&gt;

&lt;p&gt;This isn't a hot take. It's arithmetic.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Prompt That Costs $0.04 and Gets It Wrong
&lt;/h2&gt;

&lt;p&gt;Here's what most agent builders do when they need to select the best variant from an A/B test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;System: You are a data-driven optimizer. Analyze the following A/B test
results and select the variant to show next.

User: I have three email subject lines being tested:
- Variant A: 500 sends, 175 opens (35% rate)
- Variant B: 300 sends, 126 opens (42% rate)
- Variant C: 12 sends, 8 opens (66.7% rate)

Which variant should I send to the next batch?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GPT-4 picks Variant B as the "balanced choice." &lt;strong&gt;Wrong.&lt;/strong&gt; This is a multi-armed bandit problem. UCB1 selects Variant C &lt;em&gt;because&lt;/em&gt; it's under-explored -- the exploration bonus outweighs the exploitation score.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 0.01ms Alternative
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://oraclaw-api.onrender.com/api/v1/optimize/bandit &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"arms":[{"id":"A","pulls":500,"totalReward":175},{"id":"B","pulls":300,"totalReward":126},{"id":"C","pulls":12,"totalReward":8}],"algorithm":"ucb1"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Response: Variant C selected. Score 1.543. Exploitation 0.667 + Exploration 0.876. &lt;strong&gt;Mathematically provable.&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;GPT-4&lt;/th&gt;
&lt;th&gt;OraClaw&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;A/B test selection&lt;/td&gt;
&lt;td&gt;~2,000 tokens, 3s, $0.04, sometimes wrong&lt;/td&gt;
&lt;td&gt;0.01ms, $0.01, always correct&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Schedule optimization&lt;/td&gt;
&lt;td&gt;~5,000 tokens, 8s, $0.10, approximate&lt;/td&gt;
&lt;td&gt;2ms, $0.01, provably optimal (HiGHS)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Risk assessment&lt;/td&gt;
&lt;td&gt;~3,000 tokens, 5s, $0.06, no confidence intervals&lt;/td&gt;
&lt;td&gt;5ms, $0.02, VaR + CVaR + CI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Anomaly detection&lt;/td&gt;
&lt;td&gt;~1,500 tokens, 2s, $0.03, threshold guessing&lt;/td&gt;
&lt;td&gt;0.01ms, $0.01, Z-score + IQR&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Time series forecast&lt;/td&gt;
&lt;td&gt;~4,000 tokens, 6s, $0.08, no model&lt;/td&gt;
&lt;td&gt;0.08ms, $0.01, ARIMA + Holt-Winters&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  19 Algorithms, Zero LLM Tokens
&lt;/h2&gt;

&lt;p&gt;OraClaw ships 19 deterministic algorithms: Multi-Armed Bandits (UCB1/Thompson/LinUCB), CMA-ES, Genetic Algorithm, LP/MIP solver (HiGHS), Monte Carlo simulation, Bayesian inference, ensemble models, time series forecasting, VaR/CVaR portfolio risk, anomaly detection, graph analysis (PageRank/Louvain), and A* pathfinding.&lt;/p&gt;

&lt;p&gt;14 of 17 endpoints respond in under 1ms. 1,072 tests passing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three Ways to Integrate
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;REST API&lt;/strong&gt; -- curl any endpoint, no signup for free tier (100 calls/day)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MCP Server&lt;/strong&gt; -- &lt;code&gt;npx @oraclaw/mcp-server&lt;/code&gt; gives Claude/GPT 12 optimization tools&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;npm SDKs&lt;/strong&gt; -- &lt;code&gt;npm install @oraclaw/bandit @oraclaw/solver @oraclaw/risk&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It Now
&lt;/h2&gt;

&lt;p&gt;Every curl example hits the live API. &lt;a href="https://web-olive-one-89.vercel.app/demo" rel="noopener noreferrer"&gt;Try the interactive demo&lt;/a&gt; -- no signup.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;API:&lt;/strong&gt; &lt;a href="https://oraclaw-api.onrender.com" rel="noopener noreferrer"&gt;oraclaw-api.onrender.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Demo:&lt;/strong&gt; &lt;a href="https://web-olive-one-89.vercel.app/demo" rel="noopener noreferrer"&gt;web-olive-one-89.vercel.app/demo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/Whatsonyourmind/oraclaw" rel="noopener noreferrer"&gt;github.com/Whatsonyourmind/oraclaw&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;npm:&lt;/strong&gt; &lt;a href="https://www.npmjs.com/org/oraclaw" rel="noopener noreferrer"&gt;@oraclaw&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Free tier: 100 calls/day, no auth. Paid: $9/mo. AI agents pay with USDC via x402 protocol.&lt;/p&gt;

&lt;p&gt;LLMs are extraordinary at language. They're terrible at math. Stop making your agents think about optimization. Give them a calculator.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;OraClaw is MIT licensed. 1,072 tests. &lt;a href="https://github.com/Whatsonyourmind/oraclaw" rel="noopener noreferrer"&gt;Star us on GitHub&lt;/a&gt; if this saved you some tokens.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>ai</category>
      <category>typescript</category>
    </item>
  </channel>
</rss>
