All plugins

writing-guard

Style check for every Hermes answer in German and English: finds em and en dashes outside code, links and quotes (optionally replaces them by rule: ranges and list bullets become hyphens, dashes between words a comma), reports stock AI phrases (German and English) and mixed or switched forms of address (du/Sie) in German. Reports by default with one line appended to the answer; rule based, no model calls. Disclosure — no network calls and no model calls. A transform_llm_output hook reads the final answer of each turn; in report mode it appends one report line when there is a finding, in fix mode it also replaces dashes, with footer: false it never changes the answer; the returned text is what Hermes stores and shows. Stores per chat session id only the last form of address (du or sie) and a timestamp in HERMES_HOME/plugin-data/writing-guard/sessions.json (30 days, at most 2000 sessions); the last report with matched phrases stays in process memory only. Reads only its own plugin settings. Off on cron, subagent, kanban, batch and webhook by default. Registers the tool writing_guard_check (checks a draft, returns JSON), the slash command /writing-guard (settings, last report, check a text) and a skill that adds one line to the skills index of every session while the plugin is enabled.

MadeByBrainToolsv1.0.1Updated 5 days ago

About

Style check for every Hermes answer in German and English: finds em and en dashes outside code, links and quotes (optionally replaces them by rule: ranges and list bullets become hyphens, dashes between words a comma), reports stock AI phrases (German and English) and mixed or switched forms of address (du/Sie) in German. Reports by default with one line appended to the answer; rule based, no model calls. Disclosure — no network calls and no model calls. A transform_llm_output hook reads the final answer of each turn; in report mode it appends one report line when there is a finding, in fix mode it also replaces dashes, with footer: false it never changes the answer; the returned text is what Hermes stores and shows. Stores per chat session id only the last form of address (du or sie) and a timestamp in HERMES_HOME/plugin-data/writing-guard/sessions.json (30 days, at most 2000 sessions); the last report with matched phrases stays in process memory only. Reads only its own plugin settings. Off on cron, subagent, kanban, batch and webhook by default. Registers the tool writing_guard_check (checks a draft, returns JSON), the slash command /writing-guard (settings, last report, check a text) and a skill that adds one line to the skills index of every session while the plugin is enabled.

writing-guard: style check for Hermes answers (German and English)

writing-guard: dashes, AI phrases, du and Sie. Hermes Agent plugin

If your style rule for texts written with AI says no em dashes, no stock phrases and one form of address, models still break it. writing-guard checks the final answer of every Hermes turn against that rule before it is stored and shown:

  • Dashes: finds em and en dashes outside code, links and quotes. Optionally replaces them by rule.
  • AI phrases: reports stock phrases in German and English, such as "Es ist wichtig zu beachten", "Ich hoffe, das hilft", "It's important to note", "delve" or "seamless".
  • du and Sie: in German answers, reports both forms in the same paragraph, a switch against the previous answer of the same chat, or the wrong form when you set one.

By default it only reports, with one line under the answer:

writing-guard: 2 Gedankenstriche; 1 KI-Floskel („Gute Frage“).

Rule based: no model calls, no network, a few milliseconds per answer.

Who it is for

  • Anyone who publishes or sends texts written with Hermes: posts, newsletters, client mails, web pages, documentation. Teams with a style guide that bans dashes or stock phrases.
  • German speaking teams. Mixing du and Sie is easy to miss in a long answer. No other plugin in the Hermes catalog checks it (October 2026).
  • Agencies and editors, as a starting point. It checks surface rules. It does not judge tone, facts, or whether a text fits your brand, and it does not know your own style guide beyond the phrases you add.

Beyond this plugin

writing-guard is free and stays free. A writing setup that really matches a company needs its own material, so it is not a public plugin:

  • a style profile built from your own published texts, with your terms and banned words;
  • checks for brand names, product names and legal wording that must not change;
  • a review step before a text leaves the company (mail, CMS, social media scheduling).

MadeByBrain, the maintainer of this plugin, plans and builds such Hermes setups for businesses.

Install

hermes plugins install MadeByBrain/hermes-extensions/plugins/writing-guard --enable

To install one exact version, pin the commit (the --ref option takes a full 40 character commit SHA, not a tag; every GitHub release lists its SHA):

hermes plugins install MadeByBrain/hermes-extensions/plugins/writing-guard --ref <commit-sha> --enable

Requires Hermes Agent v0.22.2 or newer. No Python dependencies (standard library only). With a running gateway, the new plugin loads after hermes gateway restart.

Modes

| mode | What happens |
|---|---|
| report (default) | The answer stays as it is. When there is a finding, one italic line is appended. |
| fix | Dashes are replaced by the rules below. AI phrases and the form of address are still only reported. |
| off | Nothing. |

Set footer: false to never change the answer at all. The last report is then only shown by /writing-guard.

Phrases and the form of address are never rewritten automatically, because a rule cannot know the meaning. For texts that will be published, the plugin gives the model a tool to check its own draft (see below).

Dash rules (mode: fix)

| Before | After |
|---|---|
| Das Plugin – gebaut an einem Tag – läuft. | Das Plugin, gebaut an einem Tag, läuft. |
| The plugin—built in a day—works. | The plugin, built in a day, works. |
| Mo–Fr 9–17 Uhr, Seiten 12 – 14 | Mo-Fr 9-17 Uhr, Seiten 12-14 |
| – first item (list bullet) | - first item |
| Fertig. – Weiter geht es. | Fertig. Weiter geht es. |
| Text at the end of a line – | Text at the end of a line |

dash_style: hyphen turns a dash between words into " - " instead of a comma. Covered characters: em dash, en dash, figure dash and horizontal bar.

Never touched: fenced code blocks, inline code, URLs and link targets, MEDIA: lines, and quoted lines starting with > (set skip_quotes: false to include quotes).

du and Sie

Only German answers are checked. Counted as du: du, dich, dir, dein..., euch, euer.... Counted as Sie: Sie, Ihnen, Ihr... with a capital letter inside a sentence.

  • Mixed: both forms in the same paragraph. A chat answer in du followed by a mail draft in Sie (separate paragraphs) is not reported.
  • Switch: the answer uses a different form than the previous answer of the same chat (track_switches).
  • Wrong form: with address: du or address: sie, every use of the other form is reported.

Not counted, to avoid false alarms: "Sie" at the start of a sentence (it may mean "they" or "she"), quotations in „…“ or "…", and talk about the forms themselves ("du oder Sie", "per Du", "die Sie-Form").

Tool, skill and command

  • writing_guard_check (tool): checks a draft the model is about to deliver. fix: true returns the text with dashes replaced; address sets the expected form. Returns JSON with all findings.
  • writing-guard:check-draft (skill): tells the model to run the tool before it delivers a mail, post or page, and to rewrite reported phrases itself. Hermes lists plugin tools through Tool Search; the skill makes the model look for it.
  • /writing-guard (slash command): shows the settings and the report of the last checked answer. /writing-guard check <text> checks any text.

Settings

Set with hermes config set plugins.entries.writing-guard.settings.<key> <value>, or in the plugin form of the Desktop app.

| Key | Default | Meaning |
|---|---|---|
| mode | report | report, fix or off |
| footer | true | false = never change the answer |
| language | auto | language of the report line: auto (language of the answer), en, de |
| dash_style | comma | comma or hyphen for a dash between words |
| address | auto | auto, du or sie |
| check_dashes, check_phrases, check_address | true | switch single checks off |
| track_switches | true | report du/Sie switches between answers |
| skip_quotes | true | skip lines starting with > |
| extra_phrases | [] | your own phrases to report (plain text, case insensitive) |
| ignore_phrases | [] | rule ids (for example en.seamless) or exact phrases to ignore |
| disabled_platforms | cron, subagent, kanban, batch, webhook | platforms that are never checked |

Good to know

  • One transform wins. Hermes uses the first plugin that returns a changed answer in transform_llm_output. If you run another plugin that changes answers on this hook (for example one that appends MEDIA: lines), set footer: false on writing-guard, so it never changes the text.
  • The report line is part of the answer. Hermes stores the final answer with the line and sends it back to the model in later turns. In our tests the model did not copy the line into its own answers.
  • fix and streaming in the CLI. An appended report line is shown as a plain suffix after streaming. A real rewrite (fix with dashes) is shown by the CLI as "[Response transformed after streaming]" followed by the whole answer again; gateways like Telegram edit the streamed message instead (from the Hermes code, not tested live). If that bothers you, use report, or hermes config set display.streaming false.
  • Rules, not judgement. A comma is not always the best replacement for a dash, and the phrase list is not complete. Add your own with extra_phrases.

Data and privacy

No network calls, no model calls. The plugin stores, per chat session id, only the last form of address used (du or sie) and a timestamp, in <HERMES_HOME>/plugin-data/writing-guard/sessions.json (deleted after 30 days, at most 2,000 sessions). The last report, with the matched phrases, is kept in process memory for /writing-guard and is not written to disk. Settings are read through the Hermes plugin config.

Tested

  • 55 offline tests (python -m unittest discover -s tests in the plugin folder), hermes plugins validate --json without warnings.
  • Live on Hermes v0.22.2 (CLI, isolated HERMES_HOME, Gemini 3.7 Flash over OpenRouter), installed through Git from the plugins/writing-guard subfolder: report line in German and English, report stored in the session exactly as shown, du to Sie switch across turns, mode: fix replacing five dashes in an English answer, the model calling writing_guard_check on its own for a LinkedIn draft (with address: "sie" and fix: true), /writing-guard in the interactive CLI.
  • With GPT-4o and Claude Haiku 4.5 (same setup), plain requests for a short LinkedIn post without any hint about style: both models used dashes or listed phrases, and the report line appeared.
  • Run over 1,000 recent German answers from our own Hermes instance (read only, average 2,168 characters): 133 contained dashes, 1 contained a listed phrase, 0 du/Sie false alarms after tuning; about 5 ms per answer.
  • Not tested live: Desktop app, TUI, gateways (Telegram and others), the API server, fix with CLI streaming, models other than these three. Same hook, but that is an assumption.

License

MIT, see LICENSE. Maintained by MadeByBrain.

README from the reviewed commit c18ef19; it updates when the author re-pins.

More by MadeByBrain

4 plugins by MadeByBrain in the catalog.

MadeByBrainchat-lengthTells the user when a chat is getting too long and hands them a short opener for a fresh chat; the new chat pulls the earlier context itself via session_search, no handover document. Fill level from real provider token counts, measured against Hermes' compaction point by default; notices at 70 % and 90 % (configurable), once each per chat, re-armed after compaction, never in cron, subagent, kanban, batch or webhook runs. Notice in the conversation language, English or German. Disclosure — on the turn that crosses a threshold, pre_llm_call adds a one-turn instruction to that turn's user message (never the system prompt; replayed byte-identical, so prompt caching stays intact); post_api_request stores per-session token counts, model and provider name and which notice fired (no message content) under HERMES_HOME/plugin-data/chat-length/, pruned after 30 days; reads the session title read-only from state.db and the compression settings read-only from config.yaml; no network calls, no tools, no dependencies.Communitytools1MadeByBrainde-lawGerman federal law, EU law and German federal court decisions for Hermes Agent: read one section or article (§ 203 StGB, Art. 6 DSGVO, Art. 50 AI Act) in the source wording with version status (Stand), gazette reference and a ready source line, search the index of federal laws, list a law's sections, and find and read published decisions of BVerfG, BGH, BVerwG, BFH, BAG, BSG and BPatG. Legal texts, not legal advice. Disclosure: sends HTTPS GET requests only to www.gesetze-im-internet.de (law folder names, the daily index, weekly abbreviation lists), www.rechtsprechung-im-internet.de (the daily index, document ids of decisions you read) and publications.europa.eu (CELEX numbers, text language, one SPARQL query per act listing its consolidated versions); section numbers and search words are not sent, because whole laws are downloaded and searched locally. Public sources, no key. Writes public legal texts and indexes (JSON with ETag, Last-Modified and fetch time; no questions, no session data) under HERMES_HOME/plugin-data/de-law/cache, capped by the cache_max_mb setting (default 200 MB). Reads only its own plugin settings. At most one request per second per host, 25 s timeout, 40 MB response cap. rechtsprechung-im-internet.de sends a tdm-reservation header; the plugin fetches its index and single decisions on request only, and case_law: false turns that source off. No hooks, no cron jobs, no background processes. Tools stay on every platform, including gateways (a guest can call them; hermes tools disables one). While the plugin is enabled, its skill adds one line to the skills index of every session.Communitytools1MadeByBrainprivacy-xrayWhere does your data actually go? Records every outgoing model request, the main loop and side tasks such as title generation, compression and vision, as metadata only: destination host, vendor, vendor HQ country, the model vendor behind aggregators such as OpenRouter (read from the model id; the final processing vendor behind an aggregator is not visible), size and counts of detected personal data types (e-mail, IBAN, payment card, phone, IPv4, German Steuer-ID and USt-IdNr, own watch terms). /xray canary invents a fictitious person and /xray trace shows every request and local store that carried it. /xray check audits the config with a severity and the exact hermes config set fix per path; /xray fix <id> --yes applies one; a session retention hint is advice only and is never applied. /xray fix --yes and /xray find run only on local surfaces (CLI, TUI, desktop, dashboard) unless allow_sensitive_on_gateways is turned on. /xray find searches the local stores for a person, /xray report writes a self-contained HTML leak map (no scripts, no external assets) with a before and after view of two canaries; a dashboard tab shows the same page in a sandboxed frame. Not legal advice and not a compliance certificate. Disclosure: no network calls, no model calls, standard library only. pre_api_request and pre_auxiliary_call are observers; they write one metadata line per request (time, session and turn id, task, provider, model, host, vendor, counts, canary id and message fields; never message text or matched values) to HERMES_HOME/plugin-data/privacy-xray/ledger.jsonl (rotated once at ledger_max_mb, default 5 MB). The llm_request middleware is off by default (guard: false); when turned on it masks canary values and watch terms in main model requests before they are sent. Reads the merged Hermes config through load_config_readonly. /xray trace, /xray find and /xray check read outside the plugin's own data, read-only and under a time budget (scan_seconds, default 30): state.db (messages, session titles, stored system prompts, delivery queue), session files including request dumps, memories, logs, cron output, other plugins' plugin-data, paste and pending folders; output shows counts and masked snippets only. Writes config only on /xray fix <id> --yes, through hermes_cli.config.set_config_value (same code as hermes config set); never deletes files. Stores fake canary persons, last check and trace results and requested HTML or Markdown/JSON reports under its plugin-data folder. Registers the tool privacy_xray (map, check, trace, find; read-only, never changes settings), the slash command /xray and a skill that adds one line to the skills index of every session while the plugin is enabled. No credentials, no shell commands, no cron jobs, no background processes, no telemetry.Communitytools