[{"data":1,"prerenderedAt":630},["ShallowReactive",2],{"blog-post-\u002Fblog\u002Fhermes-bot-mode":3,"blog-surround-\u002Fblog\u002Fhermes-bot-mode":624},{"id":4,"title":5,"authors":6,"badge":12,"body":14,"date":605,"description":606,"extension":607,"image":608,"meta":610,"navigation":618,"path":619,"seo":620,"stem":622,"__hash__":623},"posts\u002Fblog\u002Fhermes-bot-mode.md","Hermes Agent Bot Mode: how I split work across three specialist bots",[7],{"name":8,"to":9,"avatar":10},"Made Y","\u002F",{"src":11},"\u002Fimages\u002Fprofile2.jpg",{"label":13},"AI Agents",{"type":15,"value":16,"toc":586},"minimark",[17,28,32,47,67,72,79,108,115,118,134,141,153,156,160,168,175,186,189,193,200,203,207,210,219,222,229,235,238,241,253,256,267,274,277,280,309,312,315,330,334,340,355,362,410,420,423,441,444,459,483,487,498,501,507,510,516,519,526,530,534,537,541,544,548,557,561,564,568,571,582],[18,19,21,22],"div",{"style":20},"display:flex;align-items:center;justify-content:center;gap:1.5rem;margin:1.5rem 0 2rem;","\n  ",[23,24],"img",{"src":25,"alt":26,"style":27},"https:\u002F\u002Fres.cloudinary.com\u002Ffpfvgqrg\u002Fimage\u002Fupload\u002Fv1785599903\u002Flogo_w9akfu.png","Hermes Agent","height:4rem;width:auto;max-width:40%;object-fit:contain;",[29,30,31],"p",{},"I used to keep one Hermes profile for everything: blog drafts, Nuxt pages, ASP.NET APIs. Same memory, same skill dump, same MCP list. The chat got noisy, and the agent kept reaching for the wrong conventions.",[29,33,34,41,42,46],{},[35,36,40],"a",{"href":37,"rel":38},"https:\u002F\u002Fhermes-agent.nousresearch.com\u002Fdocs\u002Fuser-guide\u002Fbot-mode",[39],"nofollow","Hermes Agent Bot Mode"," is how I split that into named teammates. The docs put it in one line: Bot Mode turns your Hermes profiles into a roster of named Bots. Each Bot is still a profile. It shows up with a role and a face, plus a canonical Bot Chat that stays the relationship instead of forking into a scratch session every time you type ",[43,44,45],"code",{},"\u002Fnew",".",[29,48,49,50,54,55,58,59,62,63,46],{},"I now run ",[51,52,53],"strong",{},"Blogi"," for writing, ",[51,56,57],{},"Nuxti"," for Nuxt UI, and ",[51,60,61],{},"Aspi"," for ASP.NET. This is the setup, the messaging flow, and the parts that still annoy me. If you want the earlier single-agent loop (skills, MCP, Flash-0731), that's in my ",[35,64,66],{"href":65},"\u002Fblog\u002Fai-agent-workflow-deepseek-hermes","Hermes + DeepSeek lab note",[68,69,71],"h2",{"id":70},"what-bot-mode-is","What Bot Mode is",[29,73,74,75,78],{},"A Bot is a Hermes profile. Isolated config, memory, skills, credentials, and chat history live under ",[43,76,77],{},"~\u002F.hermes\u002Fprofiles\u002F\u003Cname>\u002F",". Bot Mode is a UI over that primitive. Chat with the same agent from the desktop roster or from a shell:",[80,81,86],"pre",{"className":82,"code":83,"language":84,"meta":85,"style":85},"language-bash shiki shiki-themes material-theme-lighter github-light github-dark monokai","hermes -p blogi chat\n","bash","",[43,87,88],{"__ignoreMap":85},[89,90,93,97,101,105],"span",{"class":91,"line":92},"line",1,[89,94,96],{"class":95},"sR7ES","hermes",[89,98,100],{"class":99},"sFhLe"," -p",[89,102,104],{"class":103},"sLACW"," blogi",[89,106,107],{"class":103}," chat\n",[29,109,110,111,114],{},"Routines on a Bot are ordinary Hermes cron jobs. They show up in ",[43,112,113],{},"hermes cron list",". Nothing extra is stored, and there's no background daemon that only Bot Mode understands.",[29,116,117],{},"On the desktop it appears as a Bots tab next to Sessions. The roster is one row per profile: avatar, latest-message preview, timestamp. Click a Bot and you land in its canonical Bot Chat, created and pinned the moment the Bot exists. Sessions still exist (the context menu filters the last 200 stored conversations on that profile). The difference is the click-to-chat path always returns to the same forever chat.",[29,119,120,121,123,124,127,128,131,132,46],{},"That forever chat is the part I care about. Typing ",[43,122,45],{}," or ",[43,125,126],{},"\u002Freset"," inside the canonical Bot Chat would fork the relationship. The composer reroutes those to ",[43,129,130],{},"\u002Fcompact"," instead: fresh working context, same conversation. Regular sessions on the same profile still get a real ",[43,133,45],{},[29,135,136,137,140],{},"You can pin a model per Bot, write a custom ",[43,138,139],{},"SOUL.md",", and tick skills, toolsets, and MCP servers so a specialist only loads what it needs. Shared keys are the default, so refreshing a token on one Bot doesn't invalidate the others. Older gateways copy credentials instead; that still works, it's just forked.",[29,142,143,144,148,149,152],{},"The words I use come from the ",[35,145,147],{"href":37,"rel":146},[39],"official Bot Mode page",": Bot, profile, teammate, roster, Bot Chat, handoff, group chat. \"Handoff\" here means an ",[43,150,151],{},"@mention"," or a CLI message into another Bot's Bot Chat, not a workflow engine.",[29,154,155],{},"Bot Mode ships built into the desktop app and is on by default. No plugin install. Flip it off in Settings → Plugins → Bots if you want the old session list back. Profiles, sessions, and cron jobs stay put either way. Bot Mode never owns the data; it only renders it.",[68,157,159],{"id":158},"why-i-split-the-work","Why I split the work",[29,161,162,163,167],{},"I'm a ",[35,164,166],{"href":165},"\u002Fabout","fullstack .NET and Nuxt developer",". Most weeks that's minimal APIs, EF Core, PostgreSQL, Nuxt pages, and the occasional blog post about the same stack. One profile can do all of that. It just does it with a bloated prompt.",[29,169,170,171,174],{},"Skills in Hermes are ",[43,172,173],{},"SKILL.md"," files. The agent keeps a light index and pulls full rules when a skill is invoked, which helps with token burn. Even so, a profile that holds writing skills, Nuxt UI skills, and ASP.NET skills will grab the wrong house style. Coding turns start sounding like blog intros, and writing turns invent Nuxt prop names.",[29,176,177,178,181,182,185],{},"Splitting by domain is the boring fix. Blogi never sees ",[43,179,180],{},"aspnetcore-minimal-api",". Aspi never loads ",[43,183,184],{},"humanizer",". Nuxti can hammer Nuxt UI MCP without also carrying Prima accounting rules.",[29,187,188],{},"That's how my week actually splits. If I added a Unity-heavy stretch I might give that its own Bot. I didn't, yet. Aspi already has the Unity MCP listed, which is leftover surface I should probably turn off.",[68,190,192],{"id":191},"the-bots","The bots",[18,194,21,195],{"style":20},[23,196],{"src":197,"alt":198,"style":199},"https:\u002F\u002Fres.cloudinary.com\u002Ffpfvgqrg\u002Fimage\u002Fupload\u002Fv1787128571\u002FHermes_2026-08-19_16-33-04_nk7jrp.jpg","Hermes Agent Bot mode","height:24rem;width:auto;max-width:40%;object-fit:contain;",[29,201,202],{},"Each one is a named profile with a tight skill list and the MCPs that profile actually uses. I created them from the New Agent dialog (name, title, description) and then trimmed capabilities in Edit Profile.",[204,205,53],"h3",{"id":206},"blogi",[29,208,209],{},"Content writer. That's the profile I use for posts like this.",[29,211,212,213,216,217,46],{},"Skills: ",[43,214,215],{},"blog-seo-writer",", ",[43,218,184],{},[29,220,221],{},"MCPs: Nuxt, GitHub (HTTP), Nuxt UI, X search.",[29,223,224,225,228],{},"The Nuxt and Nuxt UI MCPs look odd on a writer until you remember the blog is a Nuxt Content site. Blogi needs to know how posts are shaped (YAML frontmatter, ",[43,226,227],{},"content\u002Fblog\u002F\u003Cslug>.md",", the same author block as the other entries) without also knowing how I map a minimal API. GitHub is there so it can open a PR when I ask. X search is optional; I rarely need it for a lab note.",[29,230,231,232,234],{},"I keep Blogi's ",[43,233,139],{}," short: first person, no em dashes, no \"robust \u002F seamless \u002F showcase\", match the existing posts. The humanizer skill is the checklist. The SEO skill is the structure (one primary keyword, meta around 155 characters, keyword in the first 100 words). Neither skill should leak into Aspi's commit messages.",[204,236,57],{"id":237},"nuxti",[29,239,240],{},"Nuxt UI engineer. Nuxt 3\u002F4, Nuxt UI 4, Nuxt Content 3, Tailwind.",[29,242,212,243,216,246,216,249,252],{},[43,244,245],{},"nuxt-development",[43,247,248],{},"nuxt-ui",[43,250,251],{},"hermes-agent",", plus the shared software-dev skills I keep on coding profiles (git\u002FPR habits, the usual debugging loop).",[29,254,255],{},"MCPs: Nuxt, nuxtui, github-http, mcp-server-git.",[29,257,258,259,262,263,266],{},"This is the bot I want in the repo when the task is a page, a ",[43,260,261],{},"UButton"," variant, or a content collection quirk. Live docs MCP is the same trick I wrote about in the ",[35,264,265],{"href":65},"DeepSeek lab note",": without it, a cheap model invents prop names; with it, the UI glue stays boring.",[29,268,269,270,273],{},"Nuxti is allowed to touch ",[43,271,272],{},"app\u002F"," and the Vue files. I still don't want it \"fixing\" an EF Core migration because it noticed a YAML typo and kept going.",[204,275,61],{"id":276},"aspi",[29,278,279],{},"Backend bot. ASP.NET Core Web APIs, EF Core, PostgreSQL.",[29,281,212,282,216,284,216,287,216,290,216,293,216,296,216,299,216,302,305,306,308],{},[43,283,180],{},[43,285,286],{},"dotnet-ecosystem",[43,288,289],{},"farmora-backend",[43,291,292],{},"farmora-accounting",[43,294,295],{},"commit-changes",[43,297,298],{},"systematic-debugging",[43,300,301],{},"requesting-code-review",[43,303,304],{},"plan",", plus ",[43,307,251],{}," and the github-* skills.",[29,310,311],{},"MCPs: Nuxt, nuxtui, mcp-server-git, github-http.",[29,313,314],{},"The Nuxt MCPs on a backend bot are the messy part. Some weeks Aspi has to read a frontend contract. Most weeks they're noise. Unity is sitting there for a different experiment. I haven't cleaned that list yet, which is a good example of Bot Mode not magically enforcing discipline. You still have to tick the boxes.",[29,316,317,318,322,323,325,326,46],{},"Aspi is the profile I'd hand ",[35,319,321],{"href":320},"\u002Fprojects\u002Fauthendpoints","AuthEndpoints"," work, or a feature slice on a client API. The ",[43,324,180],{}," skill is the same house layout I published in the earlier lab note: feature folders, static Map* extension methods, no controller soup. When the task is \"announce a release,\" I don't use Aspi. That's Blogi's job, as in the ",[35,327,329],{"href":328},"\u002Fblog\u002Fauthendpoints-3-0-rc","AuthEndpoints 3.0 RC post",[68,331,333],{"id":332},"how-they-message-each-other","How they message each other",[29,335,336,337,339],{},"Two paths matter for me: ",[43,338,151],{}," from a chat I'm already in, and a headless CLI drop into a teammate's Bot Chat.",[29,341,342,343,346,347,350,351,354],{},"In any chat, ",[43,344,345],{},"@aspi have a look at this"," makes the active Bot hand the message off, wait for a reply, and report back. Mention names are checked against the live roster, so an email address or an unknown ",[43,348,349],{},"@"," is left alone. If the teammate lives on another registered connection, you use ",[43,352,353],{},"@name-device"," when names collide. I run everything on one machine, so I haven't needed that yet.",[29,356,357,358,361],{},"Direct messages are the same CLI you'd run yourself. The Bot writes the body to a temp file (so quotes, ",[43,359,360],{},"$(...)",", and backticks aren't shell-interpreted), then:",[80,363,365],{"className":82,"code":364,"language":84,"meta":85,"style":85},"hermes -p nuxti chat --in ~ -c \"Bot Chat\" --create-if-missing -Q --query-file \u002Ftmp\u002Fmsg.txt\n",[43,366,367],{"__ignoreMap":85},[89,368,369,371,373,376,379,382,385,388,392,395,398,401,404,407],{"class":91,"line":92},[89,370,96],{"class":95},[89,372,100],{"class":99},[89,374,375],{"class":103}," nuxti",[89,377,378],{"class":103}," chat",[89,380,381],{"class":99}," --in",[89,383,384],{"class":103}," ~",[89,386,387],{"class":99}," -c",[89,389,391],{"class":390},"siCPE"," \"",[89,393,394],{"class":103},"Bot Chat",[89,396,397],{"class":390},"\"",[89,399,400],{"class":99}," --create-if-missing",[89,402,403],{"class":99}," -Q",[89,405,406],{"class":99}," --query-file",[89,408,409],{"class":103}," \u002Ftmp\u002Fmsg.txt\n",[29,411,412,413,416,417,419],{},"The file starts with an attribution prefix like ",[43,414,415],{},"Message from 🤖 blogi (@blogi):",". The receiving Bot sees it the next time it runs. The messaging protocol is injected into the canonical Bot Chat system prompt at prompt-build time, including when a teammate opens that chat headlessly. Regular sessions and ",[43,418,139],{}," stay untouched.",[29,421,422],{},"That's a config flag, on by default:",[80,424,428],{"className":425,"code":426,"language":427,"meta":85,"style":85},"language-yaml shiki shiki-themes material-theme-lighter github-light github-dark monokai","agent:\n  bot_mode_protocol: true\n","yaml",[43,429,430,435],{"__ignoreMap":85},[89,431,432],{"class":91,"line":92},[89,433,434],{},"agent:\n",[89,436,438],{"class":91,"line":437},2,[89,439,440],{},"  bot_mode_protocol: true\n",[29,442,443],{},"Delivery is per-invocation. If Nuxti is mid-turn, Blogi's message waits. Live interrupt of a Bot that's already talking is listed as future work in the docs. In practice I don't fire a handoff and walk away. I check the other Bot Chat.",[29,445,446,447,450,451,454,455,458],{},"Group chats exist too: 2 to 6 Bots, Open chat on a group row, up to three serial rounds, 10 messages per send. ",[43,448,449],{},"@name"," pulls a quiet member in. ",[43,452,453],{},"@user"," pings you, and the group row gets a needs-you badge. Each member keeps its own ",[43,456,457],{},"Group: \u003Cname>"," session. I haven't made Blogi, Nuxti, and Aspi a standing room. For a portfolio post, Blogi asking Nuxti \"does this frontmatter still parse?\" is enough.",[29,460,461,462,465,466,468,469,472,473,476,477,480,481,46],{},"Same agents from a shell: ",[43,463,464],{},"hermes -p blogi chat"," opens Blogi's profile, ",[43,467,113],{}," shows routines (jobs named ",[43,470,471],{},"[bot:\u003Cname>]","), and ",[43,474,475],{},"hermes profile list"," \u002F ",[43,478,479],{},"hermes profile create"," inspect or add profiles. The files sit in ",[43,482,77],{},[68,484,486],{"id":485},"what-worked-and-whats-still-rough","What worked and what's still rough",[29,488,489,490,493,494,497],{},"The split helps on the tasks I actually repeat. Blogi stays in ",[43,491,492],{},"content\u002Fblog\u002F"," and doesn't \"helpfully\" rewrite a Vue component. Nuxti can answer Nuxt UI questions with current component metadata. Aspi stays closer to feature-folder APIs. Switching bots is a click (or ",[43,495,496],{},"-p \u003Cname>","), which is less friction than I expected.",[29,499,500],{},"What's still rough:",[29,502,503,504,506],{},"Handoffs are not a pipeline. Per-invocation delivery means I am the scheduler. If I ",[43,505,151],{}," Aspi from Blogi and then keep talking to Blogi, I can miss the reply until I open Aspi's Bot Chat.",[29,508,509],{},"Capability lists drift. Aspi still has Nuxt and Unity MCPs. Blogi has X search. None of that is Bot Mode's fault. The New Agent dialog makes it easy to clone too much, and I haven't gone back through every checkbox.",[29,511,512,513,515],{},"Group chats have hard caps for a reason. I don't want three models politely passing in a circle while I wait. For my use, DM and ",[43,514,151],{}," are the whole workflow.",[29,517,518],{},"I still hop to Cursor or a stronger model when a turn gets gnarly. Bot Mode didn't change that. It changed how much junk sits in the prompt while the cheap loop does mechanical work.",[29,520,521,522,525],{},"Hidden Bots are display-only. ",[43,523,524],{},"@mentions"," still resolve, routines keep running, unread activity piles up behind an eye toggle. That's easy to forget if you \"hide\" a Bot you meant to retire. Delete Profile is the actual removal, and the default profile can't be deleted.",[68,527,529],{"id":528},"faq","FAQ",[204,531,533],{"id":532},"what-is-hermes-agent-bot-mode","What is Hermes Agent Bot Mode?",[29,535,536],{},"A desktop roster over Hermes profiles. Each Bot has a role, model, memory, skills, and avatar. Bots can run routines, sit in group chats, and message each other. The underlying object is still a profile.",[204,538,540],{"id":539},"do-i-need-a-separate-plugin","Do I need a separate plugin?",[29,542,543],{},"Not on current desktop builds. Bot Mode is bundled and on by default. Settings → Plugins → Bots turns the UI off without deleting profiles.",[204,545,547],{"id":546},"how-do-teammates-talk","How do teammates talk?",[29,549,550,552,553,556],{},[43,551,151],{}," from a chat, or ",[43,554,555],{},"hermes -p \u003Cname> chat --in ~ -c \"Bot Chat\" --query-file \u003Cfile>"," into the canonical Bot Chat. The protocol is injected into that Bot Chat only.",[204,558,560],{"id":559},"should-i-copy-this-three-bot-split","Should I copy this three-bot split?",[29,562,563],{},"Only if your week splits that way. One specialist is already a win over a single overloaded profile. Start with the domain that keeps polluting the others.",[68,565,567],{"id":566},"where-this-sits-for-me","Where this sits for me",[29,569,570],{},"This is the setup on my machine today: three named Bots, domain-split skills, MCP still a bit messy, handoffs that I watch. Cheap enough to keep. Unfinished on purpose.",[29,572,573,574,578,579,46],{},"If you're already on Hermes, the Bots tab is probably sitting next to Sessions. The docs to read first: ",[35,575,577],{"href":37,"rel":576},[39],"Bot Mode",". The prior experiment, before I split the roster, is the ",[35,580,581],{"href":65},"Hermes Agent + DeepSeek lab note",[583,584,585],"style",{},"html pre.shiki code .sR7ES, html code.shiki .sR7ES{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .sFhLe, html code.shiki .sFhLe{--shiki-light:#91B859;--shiki-default:#005CC5;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html pre.shiki code .sLACW, html code.shiki .sLACW{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html pre.shiki code .siCPE, html code.shiki .siCPE{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}",{"title":85,"searchDepth":437,"depth":587,"links":588},3,[589,590,591,596,597,598,604],{"id":70,"depth":437,"text":71},{"id":158,"depth":437,"text":159},{"id":191,"depth":437,"text":192,"children":592},[593,594,595],{"id":206,"depth":587,"text":53},{"id":237,"depth":587,"text":57},{"id":276,"depth":587,"text":61},{"id":332,"depth":437,"text":333},{"id":485,"depth":437,"text":486},{"id":528,"depth":437,"text":529,"children":599},[600,601,602,603],{"id":532,"depth":587,"text":533},{"id":539,"depth":587,"text":540},{"id":546,"depth":587,"text":547},{"id":559,"depth":587,"text":560},{"id":566,"depth":437,"text":567},"2026-08-19","How I run Hermes Agent Bot Mode with three specialist bots (Blogi, Nuxti, Aspi): what a Bot is, how they message each other, and what still feels unfinished.","md",{"src":609},"\u002Fimages\u002Fhermes-bot-mode.svg",{"sitemap":611,"schemaOrg":612},{"lastmod":605},[613],{"type":614,"headline":5,"author":615,"datePublished":605},"BlogPosting",{"type":616,"name":617},"Person","Made Yoga",true,"\u002Fblog\u002Fhermes-bot-mode",{"keywords":621,"title":5,"description":606},"hermes agent bot mode, hermes agent teammates, multi-agent setup, bot-to-bot messaging, hermes profiles","blog\u002Fhermes-bot-mode","NRX4ORSgyJLHgjM_6urPzDVy5V49BOsnP1ukQQSVatk",[625,629],{"title":626,"path":328,"stem":627,"description":628},"AuthEndpoints 3.0 RC: a composable auth endpoints library for ASP.NET Core","blog\u002Fauthendpoints-3-0-rc","Announcing AuthEndpoints 3.0 RC, an auth library for ASP.NET Core. Composable auth endpoints on top of ASP.NET Core Identity: registration, login, 2FA, password reset, and passkeys bootstrapped in minutes.",null,1787129552715]