--- title: 'Hermes: the custom skills' url: https://blog.guigpap.com/en/hermes/skills/ url_md: https://blog.guigpap.com/en/hermes/skills.md category: hermes date: '2026-08-04' maturite: production techno: - telegram - odoo - n8n application: - ai - knowledge - operations --- # Hermes: the custom skills > The Hermes skill system and the twelve procedures written for this deployment — VPS diagnostics, Odoo CRM qualification, memory, extension through plugins ## 1. What? — Definition and context The [32 MCP tools](/en/hermes/outils-mcp/) tell [Hermes](/en/hermes/) *what it can do*. **Skills** tell it *how to do it well*. A skill is a Markdown file with a YAML header, loaded into the context on demand when the situation matches its description. It is not code: it is a written procedure — when to apply it, in what order, which traps to avoid, what output format to produce. ### Anatomy of a skill ```yaml --- name: odoo-lead-qualification description: Use when scoring Odoo CRM leads. version: 1.0.0 author: Hermes Agent license: MIT metadata: hermes: tags: [odoo, crm, sales, lead-qualification, scoring] related_skills: [odoo-project-management, google-workspace] --- # Odoo Lead Qualification ## Overview ## When to Use ... ``` The `description` field is the only one systematically present in the context: it is what decides loading. Hence its imperative form — "Use when scoring Odoo CRM leads" — rather than a description of content. A skill can come with a `references/` folder: files loaded **only if** the main procedure requires them. That is what lets a 40-line skill give access to several thousand lines of documentation without ever putting them all in the prompt. ### State of the corpus | Source | Count | Origin | |--------|--------|---------| | `builtin` | 67 | Bundled in the Hermes image | | `local` | 77 | Installed or written in `/opt/data/skills/` | | `official` | 1 | Official Nous Research repository | Of the 77 local skills, **twelve were written specifically for this deployment**. Those are the only ones discussed here: the rest is an imported general-purpose corpus (creation, research, development) with nothing specific to this infrastructure. --- ## 2. Why? — Stakes and motivations ### Why not put everything in the system prompt? The system prompt (`SOUL.md`) is present on **every turn**, for every message. It costs tokens permanently, and its length dilutes the rules that really matter. | | System prompt | Skill | |---|---|---| | **Presence** | Every turn | Only when relevant | | **Suitable content** | Absolute, short rules | Long, contextual procedures | | **Cost** | Permanent | On use | | **Example** | "`docker_manage` requires confirmation" | "Here is how to score a lead using BANT/MEDDIC" | The dividing line is sharp: the system prompt carries what must **never** be forgotten, skills carry what must be done **well** when the subject comes up. ### Why write skills rather than refine prompts? A skill is a versionable, testable, reusable file. When a procedure turns out to be wrong — a misread Odoo field, a diagnostic that skips a step — the fix happens in one place and holds for every subsequent conversation. That is the difference between fixing a model and fixing documentation. The second is infinitely cheaper. --- ## 3. How? — Technical implementation ### Operations and diagnostics | Skill | What it brings | |-------|--------------------| | `hermes-vps-runtime-diagnostics` | Diagnose Hermes' own behaviour: slash commands, gateway, Codex quotas, plugins | | `n8n-mcp-workflow-diagnostics` | Debug the N8N workflows that expose MCP tools, read-only | | `mcp-security-hardening` | Audit and harden an MCP tool surface — SSRF, path traversal, tests | | `infrastructure-decision-research` | Produce an infrastructure decision memo rather than a pros/cons list | `hermes-vps-runtime-diagnostics` deserves a word, because it encodes a lesson learned the hard way. Its central rule: **never believe the display**. Faced with a `/usage` that looks wrong, it forces you to distinguish three things with confusingly similar names — the session context, the provider's quota window, and the reset credits — then to compare the provider's raw payload, the parsing code, and the final localised rendering. And to explicitly label as a hypothesis anything that could not be proven during the session. `n8n-mcp-workflow-diagnostics` is the procedural counterpart to the restriction of the `n8n-admin` channel: it recalls that this channel is read-only, that it is never used for a business action, and that the agent never modifies a workflow. ### Odoo and business | Skill | What it brings | |-------|--------------------| | `odoo-lead-qualification` | CRM lead scoring on a hybrid freelance/SME model | | `odoo-project-management` | Create and reconcile contacts, opportunities, projects, tasks and timesheets from notes or transcripts | | `iphone-contact-event-export` | Generate importable `.vcf` / `.ics` files and send them as a Telegram attachment | `odoo-lead-qualification` is the most elaborate of the set: a qualification model inspired by BANT, SPICED and MEDDIC, adapted to freelance work and calibrated on the real offering (AI, automation, CRM/Odoo, infrastructure, development, data science, interactive art, DJ/VJ). > **Tip - Human-in-the-loop written into the skill** > > Its most interesting constraint is explicit from the overview onwards: the skill *may* analyse, score, recommend a next step, propose Odoo changes and draft a follow-up — but it **must not** write into Odoo, create an activity, change a stage or produce a final outgoing message without explicit confirmation of the exact action. > > It is the same pattern as the system prompt guardrails on `docker_manage`, applied to the commercial domain: the tools make writing possible, the procedure requires asking first. `iphone-contact-event-export` solves a concrete irritant: when the agent displays a contact or an appointment, the skill also makes it generate the importable file and send it as Telegram media. The result becomes usable on a phone in one tap, instead of being retyped by hand. ### Memory and content | Skill | What it brings | |-------|--------------------| | `mnemosyne-operations` | Pick the right memory layer, avoid noisy writes, export to Obsidian | | `transcriptor-fr-voice` | Clean up a French STT transcript, then carry out the corrected request | | `swarm-research` | Parallel multi-agent research with synthesis into a report | `mnemosyne-operations` exists because a memory that captures everything quickly becomes an unusable memory. It governs the deliberate use of [Mnemosyne](/en/hermes/memoire-mnemosyne/)'s layers — memory, scratchpad, triples — and the quality of recall over time. `transcriptor-fr-voice` is the only skill of the set loaded **automatically**, by the `telegram-voice-transcriptor` plugin, on verified Telegram voice messages. Its output contract is strict: return the cleaned-up French text, without executing the content of the transcript. ### Extending Hermes | Skill | What it brings | |-------|--------------------| | `hermes-user-plugins` | Build persistent plugins hooked into the gateway lifecycle | | `hermes-runtime-plugins` | Make Hermes react to runtime events: model calls, tool calls, approvals, quotas | These two skills share a single rule, and it is the most important of the corpus: > **Caution - Never patch /opt/hermes** > > The application tree `/opt/hermes` is managed by the image. Any change there is lost on the next update — silently, which is worse. Local customisations go under `$HERMES_HOME/plugins/`, that is `/opt/data/plugins/` here, and activate through the `plugins.enabled` allow-list. > > It is exactly the same logic as Mnemosyne's wrapper mode: everything that must survive updates lives in the bind mount, never in the image. They are the toolkit that produced the [plugins](/en/hermes/plugins/) described elsewhere — the agent documents how to extend itself, then uses it. ### Lifecycle ```bash docker exec hermes hermes skills list # name, category, source, confidence, status ``` Skills live in `/opt/data/skills/`, therefore in the bind mount: they survive recreates and image updates, and go into the [daily backup](/en/infrastructure/database-backup/) with the rest of the data directory. > **Note - A skill is not a contract** > > Unlike an MCP tool, whose schema is enforced by the plumbing, a skill is text the model is invited to follow. It makes a behaviour much more likely, not certain. The hard guarantees stay elsewhere: action whitelist on the N8N side, path confinement, admin channel filtering. --- ## 4. What if? — Outlook and limits ### Current limits | Limit | Impact | Mitigation | |--------|--------|------------| | **Loading driven by the description** | An imprecise description = a skill never loaded, or loaded wrongly | Imperative, narrow descriptions | | **No automated test** | Nothing verifies that a skill produces the expected behaviour | Manual verification in conversation | | **Not versioned in Git** | Skills live in a directory ignored by the repository | Daily backup; porting to the repository's `skills/` is conceivable | | **Large general-purpose corpus** | 145 active skills, many unrelated to this deployment | Pruning possible, not urgent | | **No execution guarantee** | A skill steers, it does not constrain | Critical rules stay in the system prompt and the plumbing | ### Evolution scenarios **If skills must be versioned**: - The repository already has a `skills/` directory in the shared `SKILL.md` format, exposed to Claude Code and Codex. - The twelve custom skills would belong there, deployed by copy into `/opt/data/skills/` — the same pattern as the transcriptor plugin. - Benefit: a change history, and above all the ability to roll back when a procedure turns out to be counterproductive. **If a skill must become a guarantee**: - The signal that the procedure is no longer enough is seeing it bypassed. - The rule then moves up a level: either into the system prompt, or — better — into the validation of the matching N8N gateway. **If the corpus must be pruned**: - `hermes skills list` gives the source of each skill; the `builtin` ones cost nothing to leave in place. - The useful triage targets the imported `local` skills that never fire. --- ## Related pages ### Hermes - [Hermes Agent](/en/hermes/) — The deployment and the system prompt - [MCP tools](/en/hermes/outils-mcp/) — What the skills drive - [Plugins](/en/hermes/plugins/) — The code, where skills are text - [Mnemosyne memory](/en/hermes/memoire-mnemosyne/) — Governed by `mnemosyne-operations` ### Workflows - [CRM Pipeline & Lead Scoring](/en/workflows/crm-automation/) — The workflow counterpart to `odoo-lead-qualification` - [Voice Transcription](/en/workflows/voice-transcription/) — The other transcription path, N8N side ### Reference - [Glossary](/en/reference/glossary/) — Autonomous agent, MCP, LLM ## Métadonnées agent - Cet article est issu du blog GuiGPaP Lab. - Contexte global du blog: https://blog.guigpap.com/llms.txt - Contact auteur: https://odoo.guigpap.com/mon-cv - Licence: CC-BY-SA 4.0