xmppc
xmppc is a CLI XMPP client written in C on top of
libstrophe. It's useful when you want a script,
shell, or agent to do one XMPP thing and then exit, like list a roster, send a
chat message, read recent archive entries, wait for a reply, inspect bookmarks,
and so on.
This repository is a fork β probably a hard fork β of the original xmppc. It may be renamed later. Please do not send issues from using this fork straight upstream; see Issues.
Install from source
On Debian or Ubuntu-like systems, install the build tools and libraries first:
sudo apt-get update
sudo apt-get install -y \
autoconf \
automake \
gcc \
libglib2.0-dev \
libgpgme-dev \
libstrophe-dev \
libtool \
make \
pkg-config
Then build the binary:
./bootstrap.sh
./configure
make
Put the resulting xmppc somewhere in your PATH, for example:
mkdir -p ~/.local/bin
mv xmppc ~/.local/bin/xmppc
Files
~/.config/xmppc/configβ account configuration.~/.config/xmppc/AGENTS.mdβ optional instructions for LLM agents usingxmppc.
Accounts and passwords
You can pass a JID directly:
xmppc --jid user@example.net --pwd 'secret' --mode roster list
If --pwd is omitted, xmppc asks for the password without echoing it. If you
want to pipe a password in, use --pwd -:
pass show xmpp/example | xmppc --jid user@example.net --pwd - --mode roster list
Named accounts are probably nicer. xmppc reads them from
~/.config/xmppc/config; the [default] account is used when neither --account
nor --jid is provided.
[default]
jid=user@example.net
pwd=secret
[work]
jid=user@work.example
pwd-cmd=pass show xmpp/work
[bot]
jid=bot@example.net
pwd=another-secret
Prefer pwd-cmd if you already keep passwords in a local password manager. It
runs locally and its stdout, minus the trailing newline, becomes the password.
Command shape
Most commands follow this pattern:
xmppc [--account ACCOUNT] [--jid JID] [--pwd PASSWORD] --mode MODE COMMAND [args...]
Short options are available too:
xmppc -a work -m roster list
xmppc -j user@example.net -p - -m mam list friend@example.net
Use -v, -vv, -vvv, or -vvvv for progressively noisier logging. Use
--help for the built-in summary.
Modes
Roster
xmppc -a work -m roster list
xmppc -a work -m roster export
list shows the account's contacts. export exports them.
Message
xmppc -a work -m message chat friend@example.net 'hello from xmppc'
message chat sends an unencrypted chat message. After the sent stanza appears
in Message Archive Management (MAM), it prints one compact XML line:
<sent archive-id="mam-id" message-id="stanza-id" to="friend@example.net"/>
An important bit is the distinction between the two IDs:
archive-idis the MAM cursor. Use it withmam receive after-id=...when you want to wait for the next reply.message-idis the client stanza ID. It's useful for matching messages, but it's not a MAM cursor.
If archive-id is empty, the message was sent but the archive cursor wasn't
resolved before the lookup timed out. See Send, then wait for a
reply for the fallback.
Message Archive Management (MAM)
MAM commands use XEP-0313 to read archived messages.
xmppc -a work -m mam list friend@example.net
xmppc -a work -m mam list with=friend@example.net start=-15m max=20
xmppc -a work -m mam receive friend@example.net after-id=mam-id timeout=300s max=5
mam list accepts unordered field=value terms:
with=<jid>filters to a conversation. A bare JID is shorthand forwith=<jid>.start=<time>andend=<time>bound the query. They accept XMPP timestamps or relative values such as-30s,-5m,-2h, or-1d.after-id=<mam-id>andbefore-id=<mam-id>use RSM cursors.ids=<id>[,<id>...]asks for specific archive IDs.max=<n>limits the number of printed messages. It defaults to5and is capped at50.
If you don't supply any range or ID field, mam list defaults to start=-5m so
it doesn't accidentally ask for an unbounded archive.
mam receive is for βwait until someone replies.β It requires a conversation JID
and after-id=<mam-id>, polls with real MAM/RSM after queries, and exits when
at least one newer archived message is available or the timeout is reached.
timeout defaults to 300s; max defaults to 5. If nothing arrives before
the timeout, it exits without printing anything.
Normal MAM output is one XML record per archived message:
<message id="mam-id" message-id="stanza-id" stamp="..." from="..." to="..."><body>escaped body</body></message>
Again, id is the MAM archive cursor. message-id is the stanza ID.
There is also a nicer pretty command:
xmppc -a work -m mam pretty friend@example.net start=-5m
Send, then wait for a reply
- Send the message and capture the
<sent .../>line. - Extract
archive-id. - Run
mam receivefor the same JID withafter-id=<archive-id>.
For example:
xmppc -a work -m message chat friend@example.net 'ping'
# extract archive-id from the sent line
xmppc -a work -m mam receive friend@example.net after-id='the-archive-id-from-sent'
That skips your outgoing message and waits only for newer archived messages in the conversation.
If the sent line has an empty archive-id, fall back to a recent mam list,
find the message whose message-id matches the sent message-id, then use that
message line's id as the after-id cursor.
PGP and OpenPGP
xmppc -a work -m pgp chat friend@example.net 'encrypted with old-style XEP-0027 PGP'
xmppc -a work -m openpgp signcrypt friend@example.net 'signed and encrypted with XEP-0373 OpenPGP'
The pgp mode supports XEP-0027. The openpgp mode supports XEP-0373
signcrypt.
OMEMO
xmppc -a work -m omemo list
xmppc -a work -m omemo delete-device-list
list shows OMEMO device IDs and fingerprints. delete-device-list removes the
account's OMEMO device list.
Monitor
xmppc -a work -m monitor stanza
xmppc -a work -m monitor monitor
stanza monitors raw stanzas. monitor watches XEP-0277 microblog events.
Bookmarks
xmppc -a work -m bookmark list
Lists XEP-0048 bookmarks.
Discovery
xmppc -a work -m discovery info conference.example.net
xmppc -a work -m discovery item conference.example.net
Runs XEP-0030 service discovery info or item queries.
Agent support
This fork has an agent-skill command for LLM agents:
xmppc agent-skill
It prints an agent skill they should follow, the MAM cursor rules, and explains
that agents should read ~/.config/xmppc/AGENTS.md when it exists for
user-local instructions, but must not read ~/.config/xmppc/config.
To install a proper agent skill that points back to the one embedded in your binary, run:
xmppc agent-skill install
That writes:
~/.agents/skills/communicating-through-xmppc/SKILL.md~/.agents/skills/communicating-through-xmppc/references/installation.md
Exit status
0means success.1means failure.
Issues
Please don't report problems related to this fork to upstream xmppc! Send me a
message somewhere (it's pretty easy to find how) and I'll decide whether it's a
bug in my fork or something I should report upstream. Please don't bother the
original maintainer with issues I may have introduced.
License
Copyright Β© 2020 Anoxinon e.V. This project is free software under the GNU General Public License. See LICENSE for the full text.