Skip to main content
Glama

Harden Stack

clawops_harden
DestructiveIdempotent

Apply security hardening to a deployed stack: SSH, firewall, fail2ban, unattended-upgrades, Docker socket, and per-cloud checks. Optionally join Tailscale for private access.

Instructions

Apply security hardening to a deployed stack: SSH, UFW, fail2ban, unattended-upgrades, the Docker socket, and per-cloud checks. Optionally join the stack to a Tailscale network and reach it there instead of over the public internet.

Use when: the user asks to harden, secure, or lock down a stack; asks what the hardening report says (with dryRun: true, which changes nothing); or asks to put a stack on their tailnet.

tailscale: true installs Tailscale, joins the tailnet as clawops-, and then moves clawops onto that address — but only after opening an SSH session to it, against host keys pinned over the connection already trusted. If that fails, nothing is recorded and the public address stays in use. The auth key comes from clawops secret set TAILSCALE_AUTH_KEY and is never passed through this tool (R6).

tailscaleRevert: true takes the host back off the tailnet, over its public address. On a private-only stack it refuses and names the plan/apply commands that reopen SSH first — relay them rather than trying to work around it.

To close the public ports afterwards, plan with privateOnly: true and apply that plan; this tool does not change firewall rules.

Do NOT use when: the user wants to know whether a stack is healthy — that is clawops_doctor. Do NOT pass tailscale and tailscaleRevert together.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
yesNoSkip elicitation; CI/scripted use only
dryRunNoReport the current state, change nothing
optionsNoComma-separated module IDs; default is every defaultOn module for the provider
stackNameNoWhich stack to harden. Omitted = the default stack in ~/.clawops/config.json
tailscaleNoJoin the tailnet, verify this machine reaches the host there, then use that address
tailscaleRevertNoLeave the tailnet and go back to the public address

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed6 schema fields changedv2.1.3
    • addedInput schema / properties / dryRun / description
      Added value: +"Report the current state, change nothing"
    • addedInput schema / properties / options / description
      Added value: +"Comma-separated module IDs; default is every defaultOn module for the provider"
    • addedInput schema / properties / stackName / description
      Added value: +"Which stack to harden. Omitted = the default stack in ~/.clawops/config.json"
    • addedInput schema / properties / tailscale / description
      Added value: +"Join the tailnet, verify this machine reaches the host there, then use that address"
    • addedInput schema / properties / tailscaleRevert / description
      Added value: +"Leave the tailnet and go back to the public address"
    • addedInput schema / properties / yes / description
      Added value: +"Skip elicitation; CI/scripted use only"
  2. First observedv2.1.1

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes far beyond the annotations. It discloses the rollback/failure path for tailscale: true ('If that fails, nothing is recorded and the public address stays in use'), the refusal behavior for tailscaleRevert on private-only stacks, that it 'does not change firewall rules', and that the auth key is never passed through the tool (R6). Consistent with readOnlyHint=false and destructiveHint=true — no contradiction.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core purpose is front-loaded in the first sentence, and the paragraphs are logically grouped (usage triggers, tailscale, revert, exclusions). It is long, but the Tailscale integration is genuinely intricate and every sentence earns its place — no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Comprehensive for a 6-param, security-sensitive tool: covers scope, when-to-use, failure modes, reversals, and non-goals (firewall, health checks). There is no output schema, and the description doesn't spell out the return format, but it does reference 'the hardening report' under dryRun. Minor gap only.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds genuine value beyond the schema for tailscale and tailscaleRevert (host-key pinning, failure semantics, private-only refusal), pushing it to a 4. The yes, options, and stackName params are fully covered by the schema alone.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb-resource pair ('Apply security hardening to a deployed stack') and enumerates concrete modules (SSH, UFW, fail2ban, unattended-upgrades, Docker socket, per-cloud checks). It also names the sibling it is not ('that is clawops_doctor'), so an agent can disambiguate without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit 'Use when' triggers (harden/secure/lock down, ask for the hardening report, put a stack on the tailnet) and explicit 'Do NOT use when' exclusions (health checks → clawops_doctor), plus a hard constraint ('Do NOT pass tailscale and tailscaleRevert together'). Nothing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.