htb-hosts
Provides tools for managing /etc/hosts entries used in Hack The Box and other lab environments, allowing addition, removal, listing, and cleanup of hostname-to-IP mappings with tagging and backup features.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@htb-hostsadd 10.10.11.161 forest.htb"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
htb-hosts
Sudo-free, cleanable /etc/hosts management for Hack The Box (and any lab work).
Doing HTB, pentests, or CTFs means constantly adding IP → hostname lines to
/etc/hosts, then hunting them down to clean up later. htb-hosts keeps every
entry it manages inside one delimited block, grants you passwordless write access
via a POSIX ACL, and gives you one command to wipe a box (or everything). It ships
as both a CLI and a zero-dependency MCP server, so you and your AI coding
agents can manage hosts the same safe way.
$ htb-hosts add 10.10.11.161 forest.htb dc01.forest.htb
added: 10.10.11.161 forest.htb dc01.forest.htb [tag=forest]
$ htb-hosts show
HTB hosts — 5 managed entries in 3 boxes
forest (2)
10.10.11.161 forest.htb
10.10.11.161 dc01.forest.htb
machine (1)
10.129.45.2 machine.htb www.machine.htb
sequel (2)
10.10.11.202 sequel.htb dc01.sequel.htb
$ nmap -p- $(htb-hosts get forest) # resolve a box name to its IP, inline
Starting Nmap 7.95 ( https://nmap.org ) ...
$ htb-hosts clean --exclude forest # done with everything but forest
cleaned 3 entry/entries (all except ~forest)Features
No sudo for daily use: a one-time ACL grant lets you edit
/etc/hostswithoutsudoever again.One-shot cleanup: everything lives in a managed block.
cleanwipes it;clean --tag forestdrops one box;clean --exclude forestkeeps one and clears the rest.Pipe-friendly lookups:
htb-hosts get forestprints just the IP, sonmap $(htb-hosts get forest)andffuf -u http://$(htb-hosts get forest --host)just work.Automatic per-box tagging: hostnames are grouped by box name (
dc01.forest.htb→forest), even across multiple IPs.Safe by construction: strict input validation (no injection),
flocklocking for writers and readers, in-place writes that preserve the ACL, and automatic backups on every change (loud warning if a snapshot ever fails).Backup & restore: named snapshots (private:
0700/0600) and one-command rollback.Tab completion: zsh and bash completions for commands, flags, and your live hostnames, IPs, tags, and snapshots.
MCP server included: first-class tools for Claude Code / MCP agents.
Zero runtime dependencies: pure Python standard library.
Related MCP server: ssh-chat-mcp
Install
Requirements: Linux, Python 3.11+, and a filesystem with POSIX ACL support
(ext4/xfs/btrfs, the default almost everywhere) plus setfacl.
git clone https://github.com/sresarehumantoo/htb-hosts.git
cd htb-hosts
make installmake install copies the tool into /opt/htb-hosts and /usr/local/bin, grants
your user an ACL on /etc/hosts, installs the shell completions, and registers the
MCP server. It works whether
you run it directly or under sudo: the steps that need privilege call sudo
themselves, and the human user is auto-detected (SUDO_USER when under sudo, else
the current user) so the ACL always targets you, not root. Override with
HOSTS_USER=<name> if needed.
The one-time install needs privilege (it writes to
/optand/usr/local/binand sets the ACL). Everydayhtb-hostsuse afterward needs no sudo.
New shells pick the completions up automatically; in a shell that is already open,
exec zsh (or rm -f ~/.zcompdump && compinit) refreshes them.
Already have a pile of entries in /etc/hosts? Pull them into the managed block:
htb-hosts migrate # imports existing host lines, tagged by box nameTo uninstall: make remove (leaves your entries + ACL) or make purge (removes
everything, including the managed block and ACL).
Usage
htb-hosts add 10.10.11.161 forest.htb dc01.forest.htb # IP and hosts in any order
htb-hosts add 10.10.11.161 "forest.htb, dc01.forest.htb" # ...or one quoted string
htb-hosts add www.forest.htb 10.10.11.161 --tag forest # extra vhost, same box
htb-hosts show # box-grouped overview
htb-hosts show forest # ...narrowed to one box
htb-hosts show --flat # one line per entry
htb-hosts show --full # also show unmanaged/system lines
htb-hosts get forest # just the IP, for $(...)
htb-hosts get forest --host # just the hostnames
htb-hosts get forest --host -i 1 # just the first hostname
htb-hosts get forest --host -n # numbered, to pick an index
htb-hosts rm forest.htb # remove one hostname
htb-hosts clean --tag forest # remove a whole box
htb-hosts clean --match forest web # remove what `get` would show
htb-hosts clean --exclude forest # remove everything EXCEPT forest
htb-hosts clean # wipe all managed entries
htb-hosts doctor # check access / show the fixThe IP can go anywhere in the arguments: htb-hosts add forest.htb 10.10.11.161
works too, and any single argument may carry several names separated by commas or
spaces. Add --json to most commands for machine-readable output.
Command reference
Command | What it does |
| Add/update an entry (idempotent; merges by IP) |
| Remove a hostname or a whole IP from the block |
| Box-grouped view, narrowed to the pattern ( |
| Bare values for matching entries, for |
| Keep only the Nth value when a box has several |
| Remove all, one box, a fuzzy match, or all-but-matches |
| Re-derive every tag from its box name |
| Save an explicit snapshot |
| Roll back to a snapshot |
| Import existing |
| Check access + managed-block integrity; print the exact fix |
One rule for the two read commands:
showis for your eyes,getis for your pipes. Both take the same patterns; onlygetpromises bare, parseable output.
Selecting values for other tools
get prints nothing but the values of the entries matching a fuzzy pattern,
one per line, deduplicated, so they drop straight into another command:
nmap -p- $(htb-hosts get forest) # -> 10.10.11.161
ffuf -u "http://$(htb-hosts get forest --host)/FUZZ" -w words.txt
htb-hosts get # every managed IPThe pattern is matched case-insensitively against each entry's IP, tag, and
hostnames. --host switches the output from IPs to hostnames;
with --host, the output narrows to the hostnames that actually matched
(get jobs --host → jobs.example.htb), falling back to all of the entry's names
when the match came from its IP or tag.
Several patterns narrow, they don't add. Each one has to match, so patterns drill into a selection rather than growing it:
$ htb-hosts get forest --host # the whole box
forest.htb
dc01.forest.htb
www.forest.htb
$ htb-hosts get forest dc01 --host # drill in
dc01.forest.htb(clean --exclude is the opposite and deliberately so: it is a repeatable,
additive keep-list, where --exclude forest --exclude sequel keeps both.)
Nothing matched is an error: stdout stays empty and the exit code is 1, so a
typo can't silently hand an empty target list to the next command.
Picking one of several values
A box with a few vhosts has a few hostnames on one IP, and pasting all of them
into $(...) word-splits into several arguments: curl http://a.htb b.htb c.htb/.
-n/--numbered shows you what's there, and -i/--index keeps just the lines
you want (1-based):
$ htb-hosts get forest --host -n
1 forest.htb
2 dc01.forest.htb
3 www.forest.htb
$ curl "http://$(htb-hosts get forest --host -i 1)/" # -> forest.htb
$ htb-hosts get forest --host -i 2 # -> dc01.forest.htb
$ htb-hosts get forest --host -i -1 # last one
$ htb-hosts get forest --host -i 2-3 # a range
$ htb-hosts get forest --host -i 1,3 # a list, in that orderAn out-of-range index is an error (exit
2, empty stdout) rather than a silent drop, for the same reason an empty match
is: a pipeline should never quietly get fewer arguments than you asked for.
When you want every value but on one line, --sep joins them instead:
nmap $(htb-hosts get forest --sep ,) # -> nmap 10.10.11.161,10.10.11.162Tab completion
make install drops a zsh completion in $PREFIX/share/zsh/site-functions and a
bash one in $PREFIX/share/bash-completion/completions, both on the default
search paths, so no rc-file edit is needed. make completions installs just those.
Completion is live: candidates come from the managed block as it stands right now, not a static list.
You type | You get |
| subcommands, with descriptions |
| your managed hostnames and IPs |
| hostnames, IPs and tags (anything a pattern matches) |
| only the hostnames inside the forest box |
| your box tags |
| your snapshots, newest first |
| that subcommand's flags |
Completion is also scoped and field-aware: once you have typed a pattern, the
next one completes only from what that selection contains, and --host restricts
the menu to the hostnames that field can actually print. Accepting a suggestion
therefore always does what the menu implied, which is why patterns narrow.
The scripts get their data from htb-hosts complete <kind> [pattern…], a hidden
subcommand that prints one candidate per line. It is deliberately silent on failure: an
unreadable or malformed /etc/hosts degrades completion rather than spraying
errors into your prompt.
Tagging
Every entry carries a tag, defaulting to the box name derived from its first
hostname (dc01.forest.htb → forest; fileserver.corp.local → corp). That
groups a whole box (even across several IPs) under one tag, so clean --tag forest clears it in one go. Re-derive tags for existing entries any time:
htb-hosts retagRemoving a fuzzy match: clean --match
--match takes the same patterns as get, so what you selected is what goes:
$ htb-hosts get forest web --host # check first
web01.forest.htb
web02.forest.htb
$ htb-hosts clean --match forest web
will remove 2 entries:
10.10.11.161 web01.forest.htb [tag=forest]
10.10.11.161 web02.forest.htb [tag=forest]
proceed? [y/N] y
cleaned 2 entry/entries (~forest web)Because a fuzzy pattern is the one removal you cannot verify by reading the
command line, --match prints its plan and asks whenever it would remove more
than one entry. --yes skips the prompt, and --json implies it; with no
terminal to ask, it refuses rather than guessing. The exact modes (--tag,
--exclude, bare clean) are unchanged and still act immediately.
Keep-all-but: fuzzy --exclude
The inverse of --tag: remove everything except fuzzy matches. Patterns are
case-insensitive substrings tested against each entry's IP, tag, and hostnames,
and --exclude is repeatable:
htb-hosts clean --exclude forest # keep the forest box, clear the rest
htb-hosts clean --exclude forest --exclude vpnBackup & restore
Every write drops an automatic snapshot (last 5 kept). You can also take named snapshots that are never auto-pruned, and roll back:
htb-hosts backup --label before-pivot # explicit snapshot
htb-hosts restore --list # show snapshots (auto + saved)
htb-hosts restore # roll back to the most recent
htb-hosts restore before-pivot # roll back to a named/substring matchMCP integration
htb-hosts includes a stdio MCP server so MCP-aware agents (e.g. Claude Code) can
manage hosts natively. make install registers it; to register by hand:
claude mcp add -s user htb-hosts -- python3 /opt/htb-hosts/mcp_server.pyhtb_hosts_add, htb_hosts_remove, htb_hosts_show (accepts patterns),
htb_hosts_select, htb_hosts_clean (accepts match/exclude/dry_run),
htb_hosts_retag, htb_hosts_backup, htb_hosts_restore,
htb_hosts_list_backups.
How it works
Everything the tool manages lives between two markers:
# >>> htb-hosts >>> (managed by htb-hosts; run `htb-hosts clean` to remove)
10.10.11.161 forest.htb dc01.forest.htb # tag=forest added=2026-07-11
# <<< htb-hosts <<<Lines outside the markers (localhost, IPv6, anything you added by hand) are never touched.
Write access is granted once via a POSIX ACL:
setfacl -m u:youruser:rw /etc/hostsBecause a non-owner can't re-apply an ACL, the tool edits /etc/hosts in place
(open r+, rewrite, truncate) under an flock; it never renames a temp file over
it, which would drop the ACL and flip ownership. All input is strictly validated so
nothing can inject extra lines, and the prior contents are snapshotted before every
change. If the ACL is ever lost, htb-hosts doctor prints the exact command to
restore it (doctor also flags a mangled managed block, e.g. an orphaned marker).
Security notes
The ACL is broader than the tool.
setfacl -m u:you:rw /etc/hostslets any process running as your user rewrite the whole file and redirect name resolution system-wide; the managed block is a convention the tool honors, not something the kernel enforces. That's the deliberate trade-off for sudo-free use; make it on a personal lab machine, not a shared or production one.make purgeremoves the ACL again.Backups outlive
clean. Snapshots under~/.local/state/htb-hostskeep old box/engagement hostnames after you wipe the block. The directory is created0700(snapshots0600); delete snapshots by hand if that history matters.
Configuration
Variable | Default | Purpose |
|
| Target hosts file (handy for testing) |
|
| Where snapshots are stored |
| (empty) | Comma-separated domain substrings to keep outside the block on |
Development
make test # stdlib unittest suite (no root, /etc/hosts untouched)
make smoke # quick end-to-end CLI check against a throwaway file
make lint # black --check + pylint (gated at 10.00/10)
make audit # uv audit of the locked dev deps + zizmor over .github/
make help # list all targetsThe dev toolchain (black, pylint, zizmor) is pinned in uv.lock and run through
uv run --locked; make lint UV_RUN= uses whatever is already on your PATH.
Tests load the modules directly from src/, so they exercise the in-repo copy
regardless of what's installed under /opt, and each test runs against a throwaway
temp file, so your real /etc/hosts is never touched. Coverage includes input
validation/injection rejection, add/merge/rehome/idempotency, clean/exclude,
migration + tagging, backup/restore (including snapshot permissions, symlink and tamper refusal, and the
warn-but-don't-block behavior on backup failure), doctor's marker-integrity
check, the in-place-edit (inode-preserving) invariant that protects the ACL,
flock concurrency, and the full CLI + MCP surfaces.
Layout
src/htb_hosts.py core library (parse/validate/lock/backup) → /opt/htb-hosts
src/mcp_server.py zero-dependency stdio JSON-RPC MCP server → /opt/htb-hosts
src/htb-hosts CLI entrypoint → /usr/local/bin
completions/ zsh + bash tab completion scripts → share/{zsh,bash-completion}
tests/ unittest suite (core, CLI, MCP)
Makefile install / remove / lint / test targets
pyproject.toml dev dependency group + black/pylint config (line length 100)
uv.lock locked dev toolchainLicense
Available Tools
9 toolshtb_hosts_addA
Add or update an HTB host entry in /etc/hosts (no sudo needed). Use this whenever you need a hostname like machine.htb to resolve to a box IP. Entries go in a managed block and can be cleaned later.
| Name | Required | Description | Default |
|---|---|---|---|
| ip | Yes | Box IP, e.g. 10.129.45.2 | |
| tag | No | Optional group tag (defaults to the box name) for bulk cleanup | |
| hostnames | Yes | One or more hostnames, e.g. ['machine.htb','www.machine.htb']. A single comma/space separated string also works. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden well: it discloses that it writes to /etc/hosts, that no sudo is required, that entries are isolated in a managed block, and that the write is reversible via later cleanup. It stops short of saying whether an existing hostname mapping is overwritten or what the call returns.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, each earning its place: what it does, when to use it, and how its effects are scoped/reversible. The key fact (no sudo) is front-loaded in the first sentence.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a three-parameter mutation of a system file with no annotations and no output schema, the description covers the essentials: where it writes, privilege requirements, scoping, and reversibility. Overwrite semantics for pre-existing hostnames are the one notable omission.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3; the description adds conceptual grounding by explaining the 'managed block' that the tag parameter's 'bulk cleanup' grouping relies on. That link between the tag and the cleanup lifecycle is real value beyond the schema text.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb pair ('add or update') plus the exact resource and location ('HTB host entry in /etc/hosts'), which is unambiguous. It does not explicitly name the sibling it complements (e.g. htb_hosts_remove/htb_hosts_clean), but the verb is distinct enough from the other hosts_* tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Use this whenever you need a hostname like machine.htb to resolve to a box IP' gives a concrete triggering condition with an example. It hints at the cleanup sibling ('can be cleaned later') but does not explicitly state when to prefer remove/clean/show instead.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
htb_hosts_backupA
Save an explicit snapshot of /etc/hosts (never auto-pruned).
| Name | Required | Description | Default |
|---|---|---|---|
| label | No | Optional label for the backup filename |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It does disclose a genuine lifecycle trait — the snapshot is never auto-pruned — but says nothing about where the backup is written, whether repeat calls create duplicates, or whether permission errors are possible for a write operation on /etc/hosts.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One sentence, front-loaded with the action and target, with the non-pruned guarantee appended as a parenthetical. No filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-optional-param tool with no output schema, the description is close to sufficient, but it omits the return value (an identifier or filename an agent would need to later call htb_hosts_restore or htb_hosts_list_backups) and where the snapshot lives. Those are the remaining gaps an agent must discover empirically.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single 'label' parameter is described as an optional label for the backup filename, so the schema does the work. The description adds nothing about how the label affects filename collisions or ordering, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Save') and resource ('snapshot of /etc/hosts'), which cleanly separates it from siblings like htb_hosts_restore, htb_hosts_list_backups and htb_hosts_clean. It does not name a sibling explicitly, but 'explicit snapshot' implies a deliberate manual backup versus any automatic copy.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'explicit snapshot' and '(never auto-pruned)' imply the tool is for intentional, permanent backups before risky changes, but no when-to-use/when-not statement or alternative is given. An agent must infer that this is the pre-change safety step from the presence of htb_hosts_restore and htb_hosts_clean.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
htb_hosts_cleanA
Remove managed host entries. No args wipes the whole block; tag removes one box by its exact tag; match removes the entries htb_hosts_select would return for the same patterns (every pattern must match); exclude is the inverse keep-list, removing everything EXCEPT entries matching ANY pattern. The three are mutually exclusive. Set dry_run to preview what would go without touching the file.
| Name | Required | Description | Default |
|---|---|---|---|
| tag | No | Remove only entries with this exact tag | |
| match | No | Remove entries matching EVERY pattern (as htb_hosts_select) | |
| dry_run | No | Report what would be removed without changing the file | |
| exclude | No | Fuzzy patterns to KEEP; everything else is removed |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden and does reasonably well: it discloses that the operation mutates a file, that the no-argument form destroys the entire block, and that dry_run previews without writing. It does not mention reversibility or the existence of the backup/restore siblings, which would matter for a destructive tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core action, then one clause per mode, then the exclusivity rule, then dry_run. Dense and mostly waste-free, though the mode enumeration and the exclusivity sentence could be merged for tighter structure.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers all four optional parameters, the destructive default case, and the preview path, which is close to sufficient for a 4-param mutation tool with no annotations and no output schema. What's absent is what the operation returns and whether backups are taken automatically.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 meaning on top by tying `match` to htb_hosts_select's semantics, framing `exclude` as its inverse keep-list, and declaring the three selection parameters mutually exclusive. Only `dry_run`'s interaction with the other modes (e.g. combined with no args) is left implicit.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource ("Remove managed host entries") and then enumerates the four operating modes, so the agent knows exactly what the tool does. It does not, however, differentiate itself from the sibling htb_hosts_remove, which an agent could easily confuse with this tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Each mode's selection condition is spelled out (no args = full block, tag = exact tag, match = htb_hosts_select semantics, exclude = inverse keep-list) and mutual exclusivity is stated explicitly. Missing is any guidance on when to prefer this over htb_hosts_remove, or any prerequisite/confirmation context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
htb_hosts_list_backupsA
List available /etc/hosts snapshots, oldest first.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description must carry the load; 'List available' implies a safe read and the 'oldest first' ordering is a genuine behavioral detail. However, it says nothing about return shape (names vs. paths), whether the list can be empty, or failure modes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with zero filler; the ordering detail is attached directly to the resource rather than buried.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter tool with no output schema, the description should at least indicate what a returned snapshot looks like so the agent can hand an identifier to htb_hosts_restore. It covers purpose and ordering but leaves the return-value contract unspecified.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the baseline is 4. The description correctly implies no filtering or sorting options are needed to call it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('List') and resource ('/etc/hosts snapshots'), plus the ordering ('oldest first'), which cleanly separates it from the mutating siblings htb_hosts_backup and htb_hosts_restore. It never names a sibling explicitly, so it falls short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The listing purpose implies the workflow (inspect snapshots before htb_hosts_restore), but the description gives no explicit when-to-use, prerequisites, or named alternative. Usage is inferred rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
htb_hosts_removeB
Remove an HTB host entry from the managed block by hostname or IP.
| Name | Required | Description | Default |
|---|---|---|---|
| selector | Yes | Hostname or IP to remove |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure. It identifies an update to the managed block but does not say whether removal is idempotent, what happens if the host is absent, whether the change is reversible, whether a backup is created, or what permissions are required.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence that states action, target, scope, and selector format with no wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter tool with a complete schema, the definition is minimally adequate. However, as a mutation tool with no annotations or output schema, it should at least state idempotency, missing-host behavior, and relationship to backup/restore siblings.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, and the single parameter is documented with 'Hostname or IP to remove'. The description repeats that the selector accepts a hostname or IP but adds no matching/format details beyond the schema, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb (Remove) and resource (HTB host entry), and scopes it to the managed block by hostname or IP. This clearly separates it from siblings like htb_hosts_add or htb_hosts_show, though it does not explicitly name alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this versus htb_hosts_clean or htb_hosts_add, nor any prerequisites or exclusions. Usage is only implied by the mutation verb 'Remove'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
htb_hosts_restoreA
Restore /etc/hosts from a snapshot (most recent if no name is given).
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Backup name or substring to restore |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. 'Restore' implies overwriting the current /etc/hosts and the default-to-latest behavior is disclosed, but it never says the existing file content is replaced, whether a pre-restore backup is taken, or what privileges are required.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence that front-loads the verb and resource and packs the default-behavior rule into a parenthetical. Nothing is wasted and nothing needs to be scanned for.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-optional-parameter tool with no output schema, this covers the core action, but with zero annotations the omission of destructiveness (current hosts file is discarded), error behavior for unmatched names, and multi-match handling leaves meaningful gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so 'Backup name or substring' is already documented. The description adds real value by explaining the omission default (most recent snapshot), which the schema does not state for this optional parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb (restore) plus resource (/etc/hosts) plus source (a snapshot), which cleanly separates it from siblings like htb_hosts_backup and htb_hosts_list_backups. It stops short of naming those siblings as the related steps, but the operation itself is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The parenthetical 'most recent if no name is given' tells the agent what happens when the parameter is omitted, which is genuine usage guidance. However, there is no statement of prerequisites, no mention that a backup must exist first, and no pointer to htb_hosts_list_backups for discovering names.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
htb_hosts_retagA
Recompute every entry's tag from its box name (fixes bulk tag=imported).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It usefully discloses the blast radius ('every entry') and that tags are overwritten rather than merged, which is the key risk. It does not say whether manually curated tags are lost, whether the change is reversible, or whether it requires a populated host list.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with the action first and the motivating case in parentheses. Zero filler, nothing to trim.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a no-parameter tool with no output schema this is close to sufficient, but a bulk mutation with zero annotations and no reversibility warning leaves an agent guessing about side effects. A hint about backing up first (a sibling exists for exactly that) or about failure when a box name is missing would close the gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is nothing for the description to disambiguate; baseline 4 applies. The description correctly implies the operation is global and requires no scoping arguments.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Recompute every entry's tag from its box name', which is clearly distinct from siblings like htb_hosts_add, htb_hosts_clean and htb_hosts_restore. It doesn't name an adjacent sibling (e.g. htb_hosts_clean) to sharpen the boundary, so it stops short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'fixes bulk tag=imported' implies the triggering scenario, so an agent can infer when this tool is warranted. However, there are no explicit when-not conditions, no mention of prerequisites (e.g. that host entries must already exist), and no pointer to alternatives such as htb_hosts_backup before a bulk overwrite.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
htb_hosts_selectA
Look up managed entries by fuzzy pattern and return just their bare values, ready to feed into another command. patterns matches against ip/tag/hostname, and several patterns NARROW (every one must match). field picks what comes back: 'ip' (default) or 'host'. Use this to resolve a box name to its IP before scanning.
| Name | Required | Description | Default |
|---|---|---|---|
| field | No | Which values to return (default 'ip') | |
| index | No | Keep only these 1-based values when a box has several (a hostname per vhost): 2, -1 for the last, the range '2-4', or the list '1,3'. Omit to return them all. | |
| patterns | No | Fuzzy patterns, e.g. ['machine']; omit to match everything |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full load and does disclose key traits: read-style lookup, return of bare values only (not formatted output), and the non-obvious fact that multiple patterns NARROW rather than widen. It omits error/empty-match behavior and result ordering.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each earning its place, with the core action and output shape front-loaded before the matching semantics and the use case.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 3-param, 100%-covered, annotation-free read tool with no output schema, this covers purpose, output shape, and the tricky matching semantics. Only the `index` parameter's effect on results and empty-result behavior go unaddressed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds genuine meaning the schema lacks: that `patterns` matches against ip/tag/hostname and that multiple patterns are conjunctive, plus that `field` defaults to 'ip'. The `index` parameter is left entirely to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific verb and resource ('look up managed entries ... return just their bare values') and states the output shape, which implicitly distinguishes it from the sibling htb_hosts_show. It never names that contrast explicitly, so an agent must infer it, which keeps it short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a concrete use case ('resolve a box name to its IP before scanning') plus the AND-narrowing rule. It offers no explicit when-not guidance or named alternative among htb_hosts_show / htb_hosts_list-style siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
htb_hosts_showA
Structured overview of the managed hosts, both flat ('entries') and grouped by box ('groups'). patterns narrows to the entries they select, exactly as htb_hosts_select does. Set full=true to also include unmanaged/system entries (localhost, etc.).
| Name | Required | Description | Default |
|---|---|---|---|
| full | No | Also include unmanaged entries | |
| patterns | No | Fuzzy patterns to narrow to; omit for everything |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does disclose the main return structure and the effect of full=true. It does not explicitly state that the tool is read-only, nor does it cover permissions, side effects, or pagination behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is short, front-loaded with the main return shape, and then explains the two parameters in context. Every sentence adds useful information without repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema and no annotations, so the description should ideally explain the returned structure more fully. It identifies top-level entries/groups and the full=true inclusion behavior, but it does not describe the fields within those structures or other relevant output details.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3, but the description adds useful meaning: `patterns` narrows the selected entries exactly as htb_hosts_select does, and full=true includes unmanaged/system entries such as localhost. It clarifies that pattern filtering applies to entries rather than groups.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific resource and result shape: a structured overview of managed hosts, with both flat entries and grouped-by-box groups. It is clear what the tool returns, but it does not explicitly distinguish its purpose from siblings such as htb_hosts_select or htb_hosts_list_backups.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied through 'overview', the `patterns` narrowing behavior, and the `full=true` option for unmanaged/system entries. However, it does not explicitly say when to use this tool instead of htb_hosts_select or other sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
9 tool updates
v1.0.0- First observed
htb_hosts_add - First observed
htb_hosts_backup - First observed
htb_hosts_clean - First observed
htb_hosts_list_backups - First observed
htb_hosts_remove - First observed
htb_hosts_restore - First observed
htb_hosts_retag - First observed
htb_hosts_select - First observed
htb_hosts_show
TDQS
Scored across 9 tools
Most tools have clearly distinct purposes: add/remove/show/select/retag/backup/restore/list_backups are easy to separate. The main overlap is between htb_hosts_remove and htb_hosts_clean, since both can remove managed entries by hostname/IP or pattern, though their descriptions clarify the difference.
All tools use the same htb_hosts_ prefix and snake_case verb-based naming. The pattern is predictable throughout, including list_backups as a verb_noun variant.
Nine tools is well-scoped for a focused /etc/hosts management server. Each tool covers a meaningful operation: entry lifecycle, querying, cleanup, tagging, and backup/restore.
The surface covers the full lifecycle: add/update, remove, patterned cleanup, structured and bare-value lookup, retagging, snapshot creation, restore, and backup listing. No obvious operations are missing for managing a managed hosts block.
Maintenance
Related MCP Connectors
Remote MCP server exposing your Node Command fleet (files, shell, processes, browser) to AI hosts.
Syslog receiver and MCP server for homelab log intelligence.
Syslog receiver and MCP server for homelab log intelligence.
Nifty's MCP server — exposes tasks, projects, messages, and files as tools for AI agents.
Related MCP Servers
- AlicenseBqualityAmaintenanceAll-in-one homelab management MCP server. Docker monitoring, volume backup/restore (with compose and env files), Wake-on-LAN, network scanning, and multi-server SSH management.44315MIT
- AlicenseAqualityDmaintenanceZero-config SSH/SFTP MCP server that lets an LLM client open temporary SSH/SFTP sessions to remote hosts, run commands, and upload/download files without holding any pre-baked credentials.1711 npm2MIT
- AlicenseBqualityBmaintenanceLocal AI ops broker that keeps SSH secrets on your machine, exposes intent-level MCP tools to agents, and requires approval via a loopback Web UI for dangerous writes.141 npmMIT
- AlicenseNot gradedqualityAmaintenanceTurns any Linux server into an AI-agent-accessible machine over HTTPS, allowing MCP clients like ChatGPT, Claude, and Grok to securely control files, run shell commands, inspect system state, query SQLite, and work with git behind a bearer token.107 npm4MIT