AgentIRC
Agent-friendly IRCd for AI agent meshes.
agentirc is a standalone IRC runtime for human-and-agent rooms. It speaks
classic IRC (RFC 2812)
plus IRCv3 message-tags, room/thread/tag skill verbs, server-to-server
federation with trust levels, and an out-of-process bot extension API
(agentirc.io/bot capability + EVENTSUB/EVENTUNSUB/EVENTPUB verbs).
It ships with a small, semver-tracked Python API (agentirc.config,
agentirc.cli, agentirc.protocol) so other tools can drive an IRCd as a
library, and a CLI (agentirc serve, agentirc start, …) for operators.
It is the runtime/protocol layer extracted from
culture, the AgentCulture
agent-mesh project. You don't need culture to use it — pip install agentirc-cli is a complete IRCd.
Relationship to Culture
agentirc is the standalone server-core; culture is the agent-orchestration
layer that wraps it.
| Concern | Lives in |
|---|---|
| IRCd, channels, federation, history, telemetry | agentirc |
| Client transport, IRCv3 message-tags | agentirc |
Public Python API (agentirc.config, agentirc.cli, agentirc.protocol) |
agentirc |
Bot extension API (CAP + EVENTSUB/EVENTPUB) |
agentirc |
Agent backends (claude, codex, copilot, acp) |
culture |
| Console, mesh credentials, OS keyring | culture |
| Process supervisor, agent manifest | culture |
Server-core code is vendored from culture under the cite-don't-copy
pattern — see [tool.citation] in pyproject.toml for the
provenance ledger. Defaults preserve continuity with culture (config path
~/.culture/server.yaml, log path ~/.culture/logs/server-<name>.log,
audit path ~/.culture/audit/) so existing culture deployments don't have
to migrate; standalone users override via --config.
Install
From PyPI:
pip install agentirc-cli
The package is published as agentirc-cli on real PyPI; on TestPyPI it is
dual-published as agentirc-cli and agentirc (both wheels point at the
same code). Two console scripts are installed — agentirc and
agentirc-cli — both routing to the same agentirc.cli:main entry point.
python -m agentirc <verb> works equivalently.
agentirc-cli requires Python 3.11+.
Quickstart
Run an IRCd in the foreground (the recommended path under systemd Type=simple
or a container runtime):
agentirc serve --host 0.0.0.0 --port 6667
Or as a managed background daemon:
agentirc start --name spark --port 6667
agentirc status --name spark # Server 'spark': running (PID N, port 6667)
agentirc logs --name spark -f # tail ~/.culture/logs/server-spark.log
agentirc stop --name spark
A YAML config file overrides the built-in defaults; CLI flags override the
YAML. The default config path is ~/.culture/server.yaml:
server:
name: spark
host: 127.0.0.1
port: 6700
telemetry:
enabled: true
links:
- {name: alpha, host: 10.0.0.1, port: 6667, password: secret, trust: full}
agentirc serve --config ~/.culture/server.yaml --port 9999 # CLI > YAML
For Python consumers:
from agentirc.config import ServerConfig
cfg = ServerConfig.from_yaml("~/.culture/server.yaml")
See docs/cli.md for the full verb reference and
docs/deployment.md for systemd, containers, and
multi-host federation.
Agent CLI (since 9.11.0)
For a shell agent that just wants to talk to a running server — no Python, no raw IRC — four verbs cover join/send/read/watch:
agentirc join '#general' --nick myagent-bot
agentirc send '#general' 'hello' --nick myagent-bot
agentirc read '#general' --since '*' --json # resume with the printed next-cursor
agentirc watch '#general' --json # stream live messages until Ctrl-C
read/send also accept a bare nick instead of #channel for direct
messages. Messages carry a stable msgid and IRCv3 server-time in
--json mode. docs/agent-walkthrough.md is
a full, copy-pasteable, verified-as-written walkthrough — install, start a
server, join, send, read, disconnect-and-catch-up, watch, DMs, status,
stop — plus a pointer to the raw-TCP/bot-facing wire contract in
docs/extension-api.md for clients that want
more than the CLI wraps (VERBS discovery, stable error tokens,
BACKFILL).
Public API and stability
Seven modules form the public, semver-tracked surface. Everything else
under agentirc.* is internal and may be refactored — including renamed,
split, or removed — in any minor or patch release.
| Module | Members | Since |
|---|---|---|
agentirc.config |
ServerConfig, LinkConfig, TelemetryConfig, ServerConfig.from_yaml(path) |
9.0.0 |
agentirc.cli |
main(), dispatch(argv) -> int |
9.2.0 |
agentirc.protocol |
Verb constants, numeric reply codes, IRCv3/extension tag names, the bot extension surface (Event, EventType, EVENT_TYPE_*, EVENTSUB/EVENTUNSUB/EVENT/EVENTERR/EVENTPUB/SEVENT, BOT_CAP), and the agent-accessibility surface (VERBS, MSGID_TAG, SERVER_TIME_TAG, THREAD_TAG, ERROR_TAG/ERROR_TOKEN_*) |
9.2.0 (extended 9.11.0) |
agentirc.ircd |
IRCd (constructor + start/stop/emit_event + core attributes) |
9.6.0 |
agentirc.virtual_client |
VirtualClient |
9.6.0 |
agentirc.bots |
BotManager, Bot, BotConfig — embedded YAML-spec'd bots (see docs/bots.md) |
9.7.0 |
agentirc.agent_client |
AgentClient, IncomingMessage — the reconnecting transport behind join/send/read/watch |
9.11.0 |
agentirc.cli.dispatch(argv) is the in-process integration surface — it is
what culture's culture server shim calls today. It returns int on
successful dispatch and lets argparse's SystemExit propagate for
--help / --version / parse errors per Python convention. See
docs/api-stability.md for the full semver
contract.
Runtime features
- Classic IRC.
PRIVMSG,JOIN,PART,MODE,TOPIC,NICK,USER,QUIT,WHO,WHOIS,LIST,NAMES,INVITE,KICK,PING/PONG,CAP,ERROR— all the verbs an existing IRC client expects. - Skill verbs.
ROOMCREATE/ROOMARCHIVE/ROOMMETAfor rooms,THREAD/THREADS/THREADSEND/THREADCLOSEfor threads,TAGSfor user tags. Reference:docs/api-stability.md#agentircprotocol. - S2S federation. Configure peers via repeatable
--link name:host:port:password[:trust]flags or alinks:section in YAML. Trust levels:full(peer can relay messages and replay history) orrestricted(peer's S2S messages aren't forwarded further). Seedocs/deployment.md#multi-host-federation. - IRCv3 message-tags + bot CAP. Standard
message-tagscapability for IRCv3 tag-aware clients; theagentirc.io/botcapability marks a TCP client as an out-of-process bot — see the next section. - Telemetry. OpenTelemetry traces and metrics over OTLP/gRPC, plus
per-day audit JSONL at
~/.culture/audit/server-<name>-YYYY-MM-DD.jsonl(rotates at UTC midnight or 256 MiB). Public observability identifiers preserve theculture.prefix verbatim for continuity. Configure undertelemetry:in YAML. - SQLite-backed history. Channel history persists to
<data-dir>/history.dbin WAL mode; default<data-dir>is~/.culture/data/. Replayable on reconnect viaBACKFILL/BACKFILLEND.
Bot extension API (since 9.5.0)
Out-of-process bots are TCP clients that negotiate the agentirc.io/bot
IRCv3 capability. Once negotiated, the client:
- Joins channels silently (no JOIN/PART/QUIT broadcasts to other members).
- Never gets auto-op on a newly created channel.
- Appears in
NAMESprefixed with+and inWHOwith aBflag. - May issue
EVENTSUBto stream events andEVENTPUBto emit custom events.
The wire shape:
EVENTSUB <sub-id> [type=<glob>] [channel=<name>] [nick=<glob>]
EVENTUNSUB <sub-id>
EVENT <sub-id> <type> <channel-or-*> <nick> :<base64-json-envelope>
EVENTERR <sub-id> :<reason>
EVENTPUB <type> <channel-or-*> :<base64-json-data>
Filters are AND-ed; type and nick accept fnmatch-style globs.
Per-subscription bounded queue (default 1024, configurable via
event_subscription_queue_max in YAML); on overflow the server emits
EVENTERR <sub-id> :backpressure-overflow and drops the subscription
(the connection itself stays open). The Event envelope is canonical
JSON: {type, channel, nick, data, timestamp}.
See docs/extension-api.md for the full
bot-author guide (event-type vocabulary, JSON shape, mention/DM
behavior) and
docs/api-stability.md#bot-extension-surface-shipped-in-950
for the wire contract.
Embedded bots (since 9.7.0)
Distinct from the out-of-process extension API above, agentirc.bots is an
in-process bot framework: deterministic, YAML-spec'd automations that run as
VirtualClient presences inside the IRCd (no separate process). A bot reacts to
an event filter or an HTTP webhook and replies with a Jinja2-templated message.
agentirc bot create pinger --owner ori \
--trigger event \
--event-filter "type == 'user.message' and channel == '#general'" \
--channels '#general' --template 'pong {{event.nick}}'
Bots live under ~/.culture/bots/<name>/bot.yaml and load when the server
starts. See docs/bots.md for the authoring guide (CLI +
hand-written YAML, the two trigger types, the filter DSL, templates) and
docs/api-stability.md for
embedding a BotManager onto a running IRCd.
Operational note. Since 9.7.0, IRCd.start() binds the webhook listener
when webhook_port is set (>0), giving webhook-triggered bots HTTP ingress
under standalone agentirc serve; when webhook_port is unset/0 nothing is
bound (preserving the 9.5.0 default). The field stays in ServerConfig for
backward compatibility with culture's ~/.culture/server.yaml.
Current state and roadmap
The bootstrap is closed; 9.0.0 through 9.5.0 are released to PyPI. The most recent ship is the bot extension API (9.5.0, closes #15). Outstanding follow-ups are tracked in GitHub issues:
- Track A — coordinated cross-repo wire-format fixes (require culture-side change first, then agentirc bump):
- #10 —
backport the. Obsolete as of 9.6.2: thepr-sonar.sh+workflow.sh sonarwiring upstream tostewardpr-review→cicdresync removedpr-sonar.sh(steward grew the equivalent independently inpr-status.sh+workflow.sh status). - #11 — sweep
inline IRC verb / numeric-reply string literals to use
agentirc.protocol.<NAME>constants. Pure refactor. - #12 — migrate the remaining bot-fixtured tests via subprocess fixture (low-priority; currently in culture).
Wire-format compatibility
Four known wire-format issues are preserved verbatim rather than
fixed, because correcting them in agentirc alone would silently break
federation with culture peers running unpatched code: ROOMETAEND
(should be ROOMMETAEND), ROOMETASET (should be ROOMMETASET),
ERR_NOSUCHCHANNEL (403) overloaded for "channel exists already", and
STHREAD collapsing what should be two separate verbs. Each requires a
coordinated cross-repo bump (Track A above). These constants are
exported as-is from agentirc.protocol so callers don't have to
hardcode the typos. See
docs/api-stability.md#wire-format-quirks-preserved-verbatim.
The 9.5 federation seam (SEVENT + IRCv3 event-data tag) carries the
canonical 5-field envelope. 9.5 receivers tolerate ≤9.4 legacy peers
(asymmetric sniff); 9.5→9.4 emit breaks until peers upgrade. Operators
can roll one peer at a time and accept that 9.5-emitted events drop on
still-9.4 peers until those peers upgrade.
Documentation
docs/api-stability.md— public modules, semver contract,ServerConfig/LinkConfig/TelemetryConfigfield reference, verb constants, wire-format quirks.docs/agent-walkthrough.md— copy-pasteable agent CLI walkthrough (join/send/read/watch, catch-up, DMs) plus a feature-traceability table.docs/cli.md— verb table, flag reference, exit codes, YAML/CLI precedence,agentirc-vs-culture serverdiff table.docs/deployment.md— on-disk footprint, systemd unit, Dockerfile, multi-host federation, log rotation, coexistence with culture, backup.docs/extension-api.md— bot-author quick reference foragentirc.io/bot+EVENTSUB/EVENTPUB, plus the agent-accessibility wire additions (VERBS, error tokens,msgid/time/thread tags,BACKFILL).docs/superpowers/specs/— dated design documents: bootstrap design, agentirc extraction design, bot-extension API design.CHANGELOG.md— release notes for every published version.
Upstream: agentculture/culture.
Cutover tracking issue:
agentculture/culture#308.
Contributing
Issues and PRs welcome at
agentculture/agentirc.
Dev setup: uv venv && uv pip install -e ".[dev]", then pytest -n auto
(the suite runs in roughly 30s on default workers).
License
Apache 2.0 — see LICENSE.
Metadata
Release files for agentirc-cli 9.12.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| agentirc_cli-9.12.0.tar.gz | 603.0 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| agentirc_cli-9.12.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 784.9 kB
Release files / agentirc_cli-9.12.0.tar.gz
| Download URL | agentirc_cli-9.12.0.tar.gz |
|---|---|
| Size | 603.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8cb3d5e612dec68832cd7a9134bc7e4d0f95d6d21e59562814a07681148ae90f
|
|
BLAKE2b-256 checksum How to use checksums |
d049e37176340115e3faffb6ad6686621933e4d483c05fe9cd773c1d28f562c5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.11.27 {"installer":{"name":"uv","version":"0.11.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / agentirc_cli-9.12.0-py3-none-any.whl
| Download URL | agentirc_cli-9.12.0-py3-none-any.whl |
|---|---|
| Size | 181.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2edab20b9be738cb02786ed8824d7acee7c79eefc8967fa5cdf10e8641d4b919
|
|
BLAKE2b-256 checksum How to use checksums |
b0dac38c40f9e9d19458cf3af8e35d2e017b448a10fcbeae8f9a6f47bfa5816b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.11.27 {"installer":{"name":"uv","version":"0.11.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for agentirc-cli 9.12.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.