CLI Clients

Master the ph and mdb command-line tools to manage your people and infrastructure.

Quick Install

Looking to get the Pharos Toolbelt set up in seconds? Check out our Automated Installation Guide.

While the Pharos Web Console serves as the primary Agent-Native Control Plane and Human/AI interface, the specialized CLI clients remain the high-performance heart of the engineer’s daily terminal workflow. These tools are designed for speed, scriptability, and seamless integration into your daily DevSecOps pipelines.

Meet the Clients

Pharos provides two specialized clients to handle different types of data, both utilizing the high-performance RFC 2378 protocol.

ph: The People Registry

The ph tool is optimized for human contact management. Use it to quickly find colleagues, team members, or external partners.

  • Primary Use Case: Directory lookups, contact management, and team attribution.
  • Authentication: Read operations are open on the default (open) security tier; updates always require an authorized SSH key. protected/scoped tiers require authentication for reads too — see Server Setup.

mdb: The Machine Database

The mdb tool is your infrastructure’s source of truth. It manages everything from physical servers and LXC containers to cloud instances and network equipment.

  • Primary Use Case: Infrastructure inventory, automated provisioning, and service discovery.
  • Authentication: Read operations are open on the default (open) security tier; updates always require an authorized SSH key. protected/scoped tiers require authentication for reads too — see Server Setup.

Basic Usage

Both clients share a similar syntax. If you don’t specify a command, Pharos assumes you are performing a query.

Querying Data

To find a record, simply provide the field you are searching for.

# Search for a person by name
ph name="John Doe"

# Search for a machine by hostname
mdb hostname="srv-web-01"

# Search by IP or MAC address
mdb ip_addr="192.168.86.5"
mdb mac_addr="e0:51:d8:1d:e3:22"

For hosts with multiple NICs or dual-stack IPv4/IPv6, Pharos uses RFC-native multi-valued fields (ip_addr, mac_addr) to store multiple values per record. Subsequent add or change operations supplying an ip_addr or mac_addr append new values if not already present. Note that RFC 2378 does not define a single-value delete command — removing an IP or MAC address requires deleting and re-adding the record.

mdb also accepts a -H/--human flag, converting raw byte/KB fields and ISO8601 timestamps into human-friendly units for terminal reading — omit it (the default) when piping output to scripts, since that raw machine-readable format is what the pipe-friendly examples below expect:

mdb -H hostname="srv-web-01"

Always quote wildcard searches

mdb '*' and ph '*' search across every record — but only if your shell passes the * through untouched. An unquoted mdb * gets expanded by your shell into every filename in your current directory before mdb ever sees it, silently turning your wildcard search into a query for hundreds of local filenames. Beyond just breaking the search, this sends those filenames to your Pharos server, where they’re logged — a real information-disclosure risk if any of those names are sensitive. Always quote the wildcard: mdb '*', not mdb *. Both clients print a stderr warning if a command looks like it was affected by this.

A result with more than one matching record is prefixed with a match count and a blank line between each record’s fields, so a multi-record result is easy to scan at a glance:

$ mdb '*' return hostname ip_addr
2 matches:

       hostname: srv-web-01
        ip_addr: 10.0.0.5

       hostname: srv-db-01
        ip_addr: 10.0.0.6

A single-record result prints without the header or separator, exactly as it always has.

Adding Records

Adding records requires authorized write access. Pharos will automatically handle the SSH challenge-response if your key is enrolled.

First time, no key yet? If mdb/ph can’t find a signing key (default: ~/.ssh/id_ed25519) and you’re running interactively (not a script or CI job), the client offers to generate one on the spot and, once generated, offers to enroll its public half on a hub over SSH — reusing your existing SSH access instead of requiring you to shell in and copy files by hand. Decline either prompt and you’ll get manual enrollment instructions printed instead. Running non-interactively? Neither prompt appears — enroll a key ahead of time, or see Manual Authentication below.

# Add a new person
ph add name="Jane Smith" email="jane@lab.local"

# Add a new machine
mdb add hostname="db-01" ip="10.0.0.5" status="up"

ph always registers person-type records and mdb always registers machine-type records — you don’t need to set type= yourself. If you pass a conflicting type= value, the client overrides it to the correct type and prints a note to stderr explaining why. Type is set once at creation and is immutable afterward: neither re-add-ing over an existing record nor change can alter it.

Modifying & Deleting

Keep your registry accurate with the change and delete commands.

# Update a machine's status
mdb change hostname="db-01" make status="maintenance"

# Remove a decommissioned node
mdb delete hostname="old-server"

Advanced Automation

The true power of the Pharos CLIs lies in their scriptability. Since they are lightweight binaries with zero dependencies, they can be deployed anywhere—from your local workstation to a minimal CI/CD runner.

Environment Variables

Configure your client behavior without passing repetitive flags.

VariableDescriptionDefault
PHAROS_HOSTThe IP or hostname of your Pharos server.127.0.0.1
PHAROS_PORTThe port the server is listening on.2378
PHAROS_SERVERCombined host:port — overrides PHAROS_HOST/PHAROS_PORT if set.Unset
PHAROS_PRIVATE_KEYPath to your private SSH key for authentication.~/.ssh/id_ed25519

Debug Mode

Pass --debug to either client to see exactly what’s happening under the hood: the resolved server address (and which source it came from — env var, /etc/pharos/client.conf, or the built-in default), the exact wire command sent to the server, and the raw response received. Off by default, it produces zero extra output otherwise — useful for diagnosing “no matches” results that turn out to be a misconfigured host or an unexpected wire command.

mdb --debug hostname="srv-web-01"

Manual Authentication

For scripted or non-interactive authentication — producing credentials out of band to feed into another tool or workflow — sign a server-issued challenge string directly with your local key:

mdb auth sign "the-challenge-string-from-the-server"

This prints your public key and the resulting signature: everything needed to complete a manual auth "<pubkey>" "<signature>" handshake, without touching the network. Ordinary query/add/change/delete usage never needs this directly — mdb/ph already perform the same challenge-response automatically whenever a command requires authentication.

Pipe-Friendly Output

Pharos clients output clean, structured text that is easy to parse with standard Unix tools like grep, awk, or jq.

# Find the IP of a database and use it in a script
DB_IP=$(mdb hostname="prod-db" | grep "ip:" | awk '{print $2}')
ssh "admin@$DB_IP"

Next Steps

Now that you’ve mastered the basic clients, see how you can automate your network discovery with Pharos-Scan.