LexEdge · HermesLegal Workflow Lab
v1.0 · local / docker

Hands-on setup guide

Wire Hermes to ten legal workflows in n8n

You already have the Hermes Desktop Agent. This lab walks you through running n8n locally in Docker, connecting it to Hermes over MCP, and building ten working legal automations — from client intake to GST notice analysis. Hermes does the reasoning; n8n does the work.

Time
~90 minutes
You need
Docker + Hermes
Runtime
n8n · local
Bridge
MCP over SSE
Lawyer natural language Hermes Agent reason · plan · MCP SSE n8n MCP Server 10 workflow tools Gmail · Drive AI · OCR Postgres · Court APIs returns JSON →

Orientation

How the bridge works

Keep one idea in mind and the rest follows: Hermes is the assistant, n8n is the operations team. Hermes understands what the lawyer wants, asks any missing questions, and picks the right tool. n8n runs the actual steps — reading email, OCRing PDFs, calling AI, writing to a database — and hands back a tidy JSON result that Hermes reads aloud in plain language.

The two talk over the Model Context Protocol (MCP). In n8n you build one "server" workflow whose MCP Server Trigger node publishes a URL. Each legal workflow is attached to that node as a callable tool. Hermes connects to the URL as an MCP client, sees the ten tools, and calls whichever one matches the request. Nothing about the automation lives inside Hermes — so you can rewrite a workflow in n8n without touching the agent.

The dividing line

If it involves judgement, wording, or talking to the lawyer → Hermes. If it involves moving data, calling an API, or waiting → n8n. Never put automation logic in the agent, and never put legal reasoning in a workflow.

Step 01

Prerequisites

Five minutes of checks before you start. Confirm each one:

RequirementWhyCheck
Docker Desktop (or Engine + Compose)Runs n8n in an isolated containerdocker --version
Hermes Desktop Agent installedThe MCP client that will call your workflowsOpens and reaches its settings screen
Port 5678 freen8n's editor and MCP endpoint bind hereNothing else is using it
An AI provider key (optional)Several workflows call an LLM for review/draftinge.g. Anthropic or OpenAI key on hand
Gmail / Drive access (optional)Intake and email workflows read from theseAccount you can authorise in n8n
This is a local lab, not production

The single-container setup below is meant for development and testing on your own machine. Client data protections, backups, HTTPS and access controls come later — see Toward production. Don't point it at live client matters yet.

Step 02

Run n8n in Docker

One volume to keep your work, one command to start the container. Everything n8n stores — workflows, credentials, and its encryption key — lives in the named volume, so it survives restarts and upgrades.

  1. Create a persistent volume

    Do this once. Your workflows and credentials are stored here, not inside the container.

    terminal
    docker volume create n8n_data
  2. Start n8n

    Maps the editor to localhost:5678, mounts the volume, and sets your timezone so scheduled nodes behave. Swap Asia/Kolkata for your own zone.

    terminal · macOS / Linux
    docker run -it --rm --name n8n -p 5678:5678 \
      -e GENERIC_TIMEZONE="Asia/Kolkata" \
      -e TZ="Asia/Kolkata" \
      -e N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true \
      -e N8N_RUNNERS_ENABLED=true \
      -v n8n_data:/home/node/.n8n \
      docker.n8n.io/n8nio/n8n

    On Windows PowerShell, replace the trailing \ line-continuations with a backtick `, or paste it all on one line.

  3. Open the editor

    Visit the address below, create your owner account, and you're in. Keep this browser tab open — you'll build every workflow here.

    browser
    http://localhost:5678
  4. (Optional) Prefer Docker Compose

    If you'd rather manage n8n declaratively, save this as compose.yaml and run docker compose up -d. Easier to restart and version-control.

    compose.yaml
    services:
      n8n:
        image: docker.n8n.io/n8nio/n8n
        restart: unless-stopped
        ports:
          - "5678:5678"
        environment:
          - GENERIC_TIMEZONE=Asia/Kolkata
          - TZ=Asia/Kolkata
          - N8N_RUNNERS_ENABLED=true
          - N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
        volumes:
          - n8n_data:/home/node/.n8n
    volumes:
      n8n_data:
Updating later

Pull the newest image and restart: docker pull docker.n8n.io/n8nio/n8n, then stop and re-run the container (or docker compose pull && docker compose up -d). Your volume keeps everything intact.

Step 03

Connect Hermes over MCP

You'll build one small "server" workflow that acts as the front door for all ten tools. n8n's MCP Server Trigger node exposes a URL; Hermes connects to that URL and discovers every attached tool automatically.

  1. Create the MCP server workflow

    New workflow → name it Hermes MCP Gateway. Add a node and search for MCP Server Trigger. This is the only trigger this workflow needs.

  2. Turn on authentication

    In the node, set Authentication → Bearer and generate a credential with a long random token. Every request from Hermes must carry this token, so no stray process on your machine can call your tools.

    generate a token
    openssl rand -hex 32
  3. Copy the endpoint URL

    The node shows a Test URL and a Production URL (a path like /mcp/<random-id>). Use the Test URL while building; switch to the Production URL once the workflow is activated. It looks like this:

    mcp endpoint
    http://localhost:5678/mcp/<your-generated-path>
  4. Point Hermes at it

    In Hermes' settings, add an MCP server. Give it the URL and the bearer token. Save, then reconnect — Hermes should report the tools it discovered (none yet; you'll add them next).

    hermes · mcp server config
    {
      "name": "n8n-legal",
      "transport": "sse",
      "url": "http://localhost:5678/mcp/<your-path>",
      "headers": {
        "Authorization": "Bearer <your-token>"
      }
    }
    If Hermes runs in its own container

    Use http://host.docker.internal:5678 instead of localhost so the agent can reach n8n across the container boundary.

Step 04

The workflow pattern

Every one of the ten workflows follows the same shape, so once you build one the rest are variations. Each tool is a separate sub-workflow; the gateway just exposes them.

A · Build the sub-workflow

New workflow, starting with an Execute Sub-workflow Trigger. Define its input fields (its "arguments"). Add the processing nodes. End by returning a single structured JSON object.

B · Expose it on the gateway

In Hermes MCP Gateway, add a Custom n8n Workflow Tool node, connect it to the MCP Server Trigger, and point it at the sub-workflow. Its name and description are what Hermes reads when choosing a tool — write them for the lawyer, not the engineer.

Two rules that keep this maintainable

One workflow, one job. Resist the urge to build a single "legal automation" monster. Small, named workflows are easier to test, reuse, and reason about.

Always return structured JSON — and never a raw error. Hermes turns your JSON into a sentence. If something breaks, hand back a friendly failure object, not a 500.

Good failure

{
  "status": "failed",
  "reason": "Court API unavailable"
}

Hermes says

// spoken to the lawyer
"The court system is
 temporarily unavailable.
 Please try again shortly."
Description writing matters more than you think

Hermes picks a tool purely from its name and description. "Reviews an inbound contract PDF and flags risky clauses" beats "contract_review_v2" every time. Be concrete about what goes in and what comes out.

Step 05

The ten workflows

Build them in order — the first few are simple and teach the pattern; the later ones layer in OCR, retrieval, and long-form generation. For each: the phrase a lawyer might say, the pipeline of nodes, the JSON in and out, and expandable build notes.

01

Client Intake

Turn a new enquiry into a client, a matter, folders, and a welcome email.

create_client_matter
Lawyer"Open a new matter for ABC Limited — commercial contract work."
receive create client generate matter ID assign lawyer create folders welcome email notify staff

Input

{
  "client_name": "ABC Limited",
  "matter_type": "Commercial",
  "email": "gc@abc.co"
}

Output

{
  "status": "success",
  "matter_id": "MAT-1002",
  "assigned_to": "R. Shah",
  "folder_url": "..."
}
Build notes
  1. Sub-workflow trigger with fields: client_name, matter_type, email.
  2. Set node generates the matter ID (e.g. prefix + counter from a Postgres/Sheets row).
  3. Postgres (or Google Sheets) insert to create client + matter records.
  4. Google Drive "Create folder" for the matter workspace.
  5. Gmail send welcome email; Set node assembles the final JSON.
02

Contract Triage

Classify an inbound contract, flag its risk lane, and route it with an SLA.

triage_contract
Lawyer"Triage the NDA that just came in from the vendor."
receive PDF extract text classify type score risk pick lane set SLA route

Input

{
  "document_url": "...",
  "counterparty": "Vendor Co"
}

Output

{
  "status": "success",
  "doc_type": "NDA",
  "lane": "self_serve",
  "risk": "Low",
  "sla_hours": 24
}
Build notes
  1. Download the file (HTTP Request or Drive), then Extract from File for text.
  2. AI node with a strict classification prompt returning doc_type, risk, and rationale as JSON.
  3. Switch node maps risk → lane (self-serve / legal review / escalate) and SLA hours from your playbook thresholds.
  4. It routes only — it never drafts or approves. Escalations get a notification to counsel.
03

Legal Notice Draft

Read an incoming notice and prepare a first-draft response grounded in similar past notices.

draft_notice_reply
Lawyer"Draft a response to this legal notice."
receive notice OCR extract parties + facts retrieve similar generate draft save to matter notify

Input

{
  "document_url": "...",
  "matter_id": "MAT-1002"
}

Output

{
  "status": "success",
  "draft_url": "...",
  "precedents_used": 3,
  "summary": "Reply drafted"
}
Build notes
  1. OCR the notice (an OCR/vision node or AI vision) into clean text.
  2. AI node extracts parties, claims, and deadlines as structured fields.
  3. Retrieve similar past notices from your vector store / IntelliVault to ground the draft.
  4. AI node drafts the reply; save it to the matter folder and notify the responsible lawyer.
  5. Always returns a draft for human review — never sends anything.
04

Hearing Preparation

Assemble a hearing brief: where the matter stands, points to argue, documents and authorities needed.

prepare_hearing_brief
Lawyer"Prep me for the hearing on MAT-1002 tomorrow."
matter ID pull documents build timeline find authorities draft notes checklist

Input

{
  "matter_id": "MAT-1002",
  "hearing_purpose": "interim relief"
}

Output

{
  "status": "success",
  "brief_url": "...",
  "authorities": 4,
  "open_items": 2
}
Build notes
  1. Fetch all matter documents and metadata (Postgres + Drive).
  2. Build a chronological timeline with a Code or Sort node.
  3. Retrieve relevant precedents/authorities from your research store.
  4. AI node assembles hearing notes + a readiness checklist; save as a document.
  5. Prep for counsel — it lays out options; counsel decides strategy.
05

Legal Research

Answer a research question across judgments, legislation, and the firm's own past matters.

run_legal_research
Lawyer"What's the position on limitation for a suit on a dishonoured cheque?"
question search judgments search legislation search past matters AI synthesis report

Input

{
  "question": "limitation for
   dishonoured cheque suit",
  "jurisdiction": "India"
}

Output

{
  "status": "success",
  "report_url": "...",
  "sources": 7,
  "confidence": "Medium"
}
Build notes
  1. Fan out three searches in parallel: case law source, legislation source, internal matter store.
  2. Merge the results, then an AI node synthesises with citations and a confidence flag.
  3. Generate a report document; return its URL and source count.
  4. Surface citations so the lawyer can verify — never present unsourced conclusions as settled.
06

Client Email Processing

Triage the inbox: classify each message, attach it to a matter, and notify the right lawyer.

process_client_inbox
Lawyer"Sort through this morning's client emails."
read inbox classify extract attachments match to matter notify lawyer archive

Input

{
  "since": "today",
  "label": "Clients"
}

Output

{
  "status": "success",
  "processed": 14,
  "matched": 11,
  "needs_review": 3
}
Build notes
  1. Gmail node reads messages since the given time / label.
  2. Loop over each: AI node classifies (query, document, urgent, spam) and extracts attachments.
  3. Match sender/subject to a matter; unmatched items go to a "needs review" bucket.
  4. Notify the responsible lawyer and archive; return the tallies.
07

Invoice Automation

Read an inbound invoice, validate it, update accounting, and flag anything off.

process_invoice
Lawyer"Log this vendor invoice and check the numbers."
receive invoice extract details validate update accounting notify finance

Input

{
  "document_url": "...",
  "matter_id": "MAT-1002"
}

Output

{
  "status": "success",
  "amount": "12,400",
  "valid": true,
  "flags": []
}
Build notes
  1. Extract invoice fields with an AI / OCR node (vendor, amount, tax, due date).
  2. IF nodes validate totals, tax, and duplicates against your records.
  3. Write to your accounting sheet/system; raise flags for mismatches.
  4. Notify finance and return the parsed record.
08

Conflict Check

Screen a prospective matter against existing and former clients before it's opened.

run_conflict_check
Lawyer"Run a conflict check before we take on XYZ Corp against ABC Limited."
parties in normalise names match clients match matters classify conflict route to human

Input

{
  "prospective_client": "XYZ Corp",
  "adverse_parties": ["ABC Limited"]
}

Output

{
  "status": "success",
  "conflict": "potential",
  "basis": "ABC is a current client",
  "routed_to": "compliance"
}
Build notes
  1. Normalise party names (strip suffixes, alias table) with a Code node.
  2. Query client and matter tables for direct adversity, current/former, and positional conflicts.
  3. Classify status: clear / potential / conflict — with the specific basis.
  4. It never auto-clears. Any match routes to a human; a clean result still records the check.
09

Document Drafting

Generate a long-form legal document from a matter and a document type, section by section.

draft_document
Lawyer"Draft a shareholders' agreement for MAT-1002 from our template."
type + matter load template gather facts generate sections assemble save draft

Input

{
  "doc_type": "shareholders_agreement",
  "matter_id": "MAT-1002",
  "instructions": "2 founders,
   vesting over 4 years"
}

Output

{
  "status": "success",
  "draft_url": "...",
  "sections": 11,
  "words": 4200
}
Build notes
  1. Look up the document-type descriptor (sections, clauses) from your prompt library.
  2. Loop over sections — one AI call each — so long documents don't blow the context window.
  3. Merge sections into one document; write to Drive as an editable draft.
  4. This is the long-form generation engine: keep prompts version-controlled per document type.
10

GST Notice Analysis

Read a GST notice, classify it, extract the demand, and outline a response strategy.

analyse_gst_notice
Lawyer"Analyse this GST notice and tell me what we're dealing with."
receive notice OCR classify section extract demand check deadlines outline response

Input

{
  "document_url": "...",
  "gstin": "24AABC..."
}

Output

{
  "status": "success",
  "notice_type": "ASMT-10",
  "demand": "3,20,000",
  "reply_due": "2026-08-01"
}
Build notes
  1. OCR the notice, then an AI classification node maps it to a notice type using your JSON prompt library.
  2. Extract the demand amount, period, and reply deadline as structured fields.
  3. A Code node computes days remaining and urgency.
  4. Generate a short response outline; return the key facts for Hermes to summarise.
Start with five

If ten feels like a lot for day one, build 01, 02, 03, 05 and 06 first — client intake, contract triage, notice draft, research and email processing cover most daily work and teach every technique the others reuse.

Step 06

Test & troubleshoot

Test each layer in order

  1. Test the sub-workflow alone

    In the sub-workflow, click Execute and pass sample input. Confirm it returns clean JSON before wiring it to anything.

  2. Test the tool over MCP

    Activate the gateway workflow, then ask Hermes to run the tool with a simple request. Watch the Executions tab in n8n to see it fire.

  3. Test the whole sentence

    Say it the way a lawyer would. Check that Hermes picks the right tool and reads the result back naturally.

Common issues

SymptomLikely causeFix
Hermes sees no toolsUsing the Test URL on an inactive workflow, or wrong pathActivate the gateway and switch Hermes to the Production URL
401 UnauthorizedToken mismatchRe-copy the bearer token into Hermes' config exactly
Connection drops mid-callA reverse proxy buffering the SSE streamDisable proxy buffering on the MCP endpoint (not relevant for plain localhost)
Agent in a container can't reach n8nUsing localhost across containersUse host.docker.internal:5678
Tool never gets pickedVague tool name/descriptionRewrite the description in the lawyer's language

Step 07

Toward production

Once the lab works, the gap to something client-safe is mostly operational, not architectural — the Hermes ↔ MCP ↔ n8n shape stays the same. Before real matters touch it:

  • Switch off SQLite for Postgres and set a persistent, backed-up database — the single-container store is fine for a lab, not for client data.
  • Terminate TLS in front of n8n (Caddy or nginx) so the MCP endpoint runs over HTTPS, and keep the bearer token in a secret store.
  • Keep every credential inside n8n. Hermes should never hold API keys — it holds only the MCP URL and token.
  • Log every execution — user, matter, workflow, model, cost, duration, outcome — for audit and troubleshooting.
  • Version-control your prompts and workflow exports so drafting and classification behaviour is reproducible.
  • Keep humans in the loop where it counts: triage routes, conflict checks flag, drafts stay drafts. The workflows prepare; a lawyer decides.
The path forward

This same gateway can later sit behind VajraGrid, with IntelliVault supplying context and other engines (Python services, Celery pipelines) joining alongside n8n. The lawyer keeps talking only to Hermes while the execution layer underneath evolves.