<?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: Mervin</title>
    <description>The latest articles on DEV Community by Mervin (@mervindublin).</description>
    <link>https://dev.to/mervindublin</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%2F3906971%2F89876791-af06-4c66-a1b7-99df14df1b85.png</url>
      <title>DEV Community: Mervin</title>
      <link>https://dev.to/mervindublin</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mervindublin"/>
    <language>en</language>
    <item>
      <title>Idea2Post Agent Mode: turning a working content SaaS into an autonomous operator with Hermes</title>
      <dc:creator>Mervin</dc:creator>
      <pubDate>Wed, 20 May 2026 15:57:32 +0000</pubDate>
      <link>https://dev.to/mervindublin/idea2post-agent-mode-turning-a-working-content-saas-into-an-autonomous-operator-with-hermes-3g</link>
      <guid>https://dev.to/mervindublin/idea2post-agent-mode-turning-a-working-content-saas-into-an-autonomous-operator-with-hermes-3g</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hermes-agent-2026-05-15"&gt;Hermes Agent Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Idea2Post Agent Mode&lt;/strong&gt; — a new autonomous "Agent" tab inside an already-shipped content SaaS (&lt;a href="https://idea2post.app" rel="noopener noreferrer"&gt;idea2post.app&lt;/a&gt;). The existing product is a one-shot generator: paste an idea, get hooks/blog/social posts. Useful, but it's still a stateless AI wrapper — the user has to decide &lt;em&gt;what&lt;/em&gt; to generate.&lt;/p&gt;

&lt;p&gt;Agent Mode flips that. The user types a goal — &lt;em&gt;"What should I post on Facebook this week?"&lt;/em&gt; — and a Hermes Agent autonomously:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pulls the system's own state (queued jobs, recent content) via MCP tools&lt;/li&gt;
&lt;li&gt;Reads the most recent posts from the user's tracked competitors (real crawler signal, not made up)&lt;/li&gt;
&lt;li&gt;Analyzes the engagement and identifies underserved themes&lt;/li&gt;
&lt;li&gt;Optionally calls the existing in-house content generator for concrete drafts&lt;/li&gt;
&lt;li&gt;Reports back with citations to the actual data it used&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Crucially, none of the existing flows were touched. Quick Mode (one-shot generation), auto-pipelines (cron-driven crawl→generate→publish loops), and the 7 background workers all keep running unchanged. Agent Mode is a parallel route that &lt;em&gt;orchestrates the same building blocks&lt;/em&gt; in a different sequence.&lt;/p&gt;

&lt;p&gt;The whole layer is roughly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Browser  ──SSE──▶  PHP proxy  ──HTTP──▶  Hermes Agent
                                         (gateway @ :8642)
                                              │
                                              ├─ web search (built-in)
                                              └─ idea2post MCP server (stdio)
                                                     │
                                                     └─▶ PHP CLI ─▶ MySQL + content engine
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Live agent run inside the dashboard. Notice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tool chips (&lt;code&gt;🔧 status_report&lt;/code&gt;, &lt;code&gt;🔧 recent_competitor_posts&lt;/code&gt;) appear as &lt;strong&gt;Hermes calls them&lt;/strong&gt;, pulsing while running, turning green when complete&lt;/li&gt;
&lt;li&gt;Content streams in token-by-token after research finishes&lt;/li&gt;
&lt;li&gt;Numbers and competitor names in the reply come from the &lt;strong&gt;real database&lt;/strong&gt;, not the LLM's imagination&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;[ &lt;a href="https://youtu.be/7e4dsX8pd1s" rel="noopener noreferrer"&gt;https://youtu.be/7e4dsX8pd1s&lt;/a&gt; — record from cp.idea2post.app/?page=i2p-agent]&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Quick prompts the demo runs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;"What should I post on Facebook this week? Check my competitor signal and propose 3 angles."&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"Give me a status report — queued jobs, content last 7 days, active pipelines, recent competitor activity."&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"Generate a full content plan: research recent competitor posts, pick the most engaging theme, draft 1 blog + 3 FB posts."&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/melyx-id/idea2post-agent" rel="noopener noreferrer"&gt;https://github.com/melyx-id/idea2post-agent&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Key files:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Path&lt;/th&gt;
&lt;th&gt;Lines&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;MCP server (Python, FastMCP) — exposes idea2post engine as tools&lt;/td&gt;
&lt;td&gt;&lt;code&gt;opt/idea2post-mcp/server.py&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;~95&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PHP CLI bridge — talks to MySQL + existing content engine&lt;/td&gt;
&lt;td&gt;&lt;code&gt;engine/i2p_agent_cli.php&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;~110&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agent UI (chat, streaming)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pages/i2p-agent.php&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;~270&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SSE proxy: browser ↔ Hermes Agent&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pages/i2p-agent-api-stream.php&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;~110&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  My Tech Stack
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hermes Agent&lt;/strong&gt; v0.14.0 — running as a systemd user service on a Ubuntu 22.04 VPS&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LLM&lt;/strong&gt;: &lt;code&gt;openai/gpt-oss-120b:free&lt;/code&gt; via OpenRouter (free tier, supports tool calling)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP&lt;/strong&gt;: official &lt;code&gt;mcp&lt;/code&gt; Python SDK (&lt;code&gt;FastMCP&lt;/code&gt;) over stdio&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backend&lt;/strong&gt;: existing SaaS — PHP 8.3, MySQL 10.6 (MariaDB), Apache → Caddy&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Frontend&lt;/strong&gt;: vanilla JS + Tailwind CDN, Server-Sent Events for live tool/token streaming&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Infra&lt;/strong&gt;: Caddy reverse proxy, idea2post's existing 7-worker cron stack&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No new frameworks, no rewrites. The whole agent layer is ~600 lines.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Used Hermes Agent
&lt;/h2&gt;

&lt;p&gt;Three Hermes capabilities did the heavy lifting:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. The agent loop itself.&lt;/strong&gt; I didn't want to write a tool-calling state machine. Hermes' &lt;code&gt;/v1/chat/completions&lt;/code&gt; endpoint already runs the full reasoning→tool→observe→reason loop internally. My PHP backend just POSTs the user's goal and reads the stream. Multi-turn tool calls, retries, compression, all handled.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. MCP for tool surface.&lt;/strong&gt; Instead of hard-coding tools into the prompt, I built a small Python MCP server that exposes 7 idea2post operations (&lt;code&gt;status_report&lt;/code&gt;, &lt;code&gt;list_competitors&lt;/code&gt;, &lt;code&gt;recent_competitor_posts&lt;/code&gt;, &lt;code&gt;list_publish_accounts&lt;/code&gt;, &lt;code&gt;list_pipelines&lt;/code&gt;, &lt;code&gt;generate_content&lt;/code&gt;, &lt;code&gt;queue_publish&lt;/code&gt;). Each tool internally shells out to a PHP CLI that talks to the real MySQL and the existing content engine. &lt;code&gt;hermes mcp add idea2post --command ...&lt;/code&gt; registered it in one line. Adding a new capability later means adding one function in &lt;code&gt;server.py&lt;/code&gt; — Hermes picks it up.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. The streaming protocol.&lt;/strong&gt; Hermes' SSE stream emits both standard OpenAI &lt;code&gt;chat.completion.chunk&lt;/code&gt; frames &lt;strong&gt;and&lt;/strong&gt; custom &lt;code&gt;hermes.tool.progress&lt;/code&gt; events with &lt;code&gt;status: running&lt;/code&gt; / &lt;code&gt;completed&lt;/code&gt; per tool call. This is the difference between "spinner for 30 seconds" and "the agent is visibly thinking" — chip turns from purple-pulsing to green-✓ in real time as each MCP tool returns. Massive UX upgrade for ~30 lines of frontend code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why this was the right fit.&lt;/strong&gt; I had a working SaaS that already did the &lt;em&gt;expensive&lt;/em&gt; work — competitor crawlers, content generation, FB/LinkedIn publishing. What I was missing was an &lt;em&gt;orchestration layer&lt;/em&gt; that could reason over which subsystem to invoke for a given high-level goal. Hermes provided that layer without forcing a rewrite. The existing one-shot generator at &lt;code&gt;?page=i2p-generate&lt;/code&gt; is now one of many tools the agent can call, instead of being the entire product.&lt;/p&gt;

&lt;p&gt;The net result: same SaaS, but the user can ask it open-ended questions and watch it autonomously chain research → analysis → generation. That's the leap from "AI wrapper" to "agent product" — and Hermes did 80% of it.&lt;/p&gt;

</description>
      <category>hermesagentchallenge</category>
      <category>devchallenge</category>
      <category>agents</category>
    </item>
  </channel>
</rss>
