@smilintux/skchat
v0.13.33
Published
SKChat - AI-native encrypted P2P chat daemon. Sovereign communication for humans and AI agents with 40+ MCP tools.
Maintainers
Readme
skchat — AI-Native Encrypted Chat 🐧
Chat should be sovereign — and your AI should be in the room. Text, voice, and files between humans and AI agents, end-to-end PGP-encrypted, carried over your own transports, identified by your own keys. No SaaS, no bolted-on chatbot — the AI is a first-class participant with its own identity.
skchat is the chat experience of the SKWorld sovereign
agent ecosystem — the human-and-AI conversation surface that sits on top of
skcomms (transport) and capauth (identity). It is a single Python package
(skchat-sovereign) that ships a CLI, a Textual TUI, a Web UI, a systemd daemon,
and an MCP server so agents running inside Claude Code / Cursor / any
MCP host can send, receive, react, call, and transfer files as native tools.
The core idea: a message is composed locally, persisted to a local SQLite
history, PGP-signed/encrypted, and handed to SKComm for delivery over whichever
transport is healthy. When a message @mentions an agent, the AdvocacyEngine
routes it into the live skcapstone consciousness loop and replies in-thread — so
the AI answers for itself, in the same conversation, not through a separate bot.
The 60-second version
flowchart LR
YOU["you type<br/>(CLI · TUI · WebUI · MCP)"] --> DAEMON["skchat daemon<br/>compose · persist · route"]
DAEMON -->|"PGP sign/encrypt"| TX["ChatTransport"]
TX -->|"hand to SKComm"| COMMS["skcomms<br/>(transport · failover)"]
COMMS --> PEER["a peer or group<br/>(human or AI)"]
DAEMON -->|"@mention an agent"| ADV["AdvocacyEngine"]
ADV -->|"consciousness loop"| AI["the agent replies<br/>in-thread"]
DAEMON --> HIST["ChatHistory<br/>(local SQLite)"]Everything is local-first: messages live in ~/.skchat, voice (Piper TTS +
Whisper STT) runs on-device, and identity is your own PGP key — that is the
"sovereign" part.
Quickstart
skchat installs into the shared ~/.skenv venv like every other sk* package.
pip install -e . # PyPI name: skchat-sovereign
# entry points: skchat (CLI) · skchat-mcp (MCP server) · skchat-tui (TUI)
skchat status # identity, transport health, message counts
skchat send lumina "deploy complete" # DM a peer by short name or full URI
skchat inbox --watch # live-updating inbox
skchat chat lumina # interactive session
skchat tui # full-screen Textual UIGroups, voice, and files use the same CLI:
skchat group create "Sovereign Squad" -d "core team"
skchat group send <group_id> "standup time"
skchat voice # record → Whisper STT → send
skchat send-file lumina ./blueprint.md
skchat react <message_id> 👍Run as a managed service (preferred — do not skchat daemon start by hand,
which spawns a second unmanaged daemon):
systemctl --user restart skchat-daemon.service
journalctl --user -u skchat-daemon -fIdentity resolves agent-aware from SKAGENT (→ capauth:<agent>@skworld.io);
no SKCHAT_IDENTITY pin is required. See docs/ARCHITECTURE.md
for the full request lifecycle and module map.
What's in the box
| Piece | Module | What it does |
|---|---|---|
| CLI | cli.py | skchat — send/reply/inbox/history/threads/search/chat/group/voice/file/react/status |
| MCP server | mcp_server.py | FastMCP server — exposes the full feature set as agent tools (messaging, groups, threads, reactions, presence, files, voice, WebRTC, memory) |
| TUI / WebUI | tui.py, webui.py | Textual full-screen UI (skchat-tui) + browser UI / voice-chat server |
| Daemon | daemon.py, _daemon_entry.py, watchdog.py | Polling receive loop; spawns advocacy + WebRTC init; health endpoint; watchdog |
| AI advocacy | advocacy.py | Detects @opus/@claude/@ai, calls the skcapstone consciousness loop, replies in-thread |
| Transport | transport.py, agent_comm.py, outbox.py | Send/receive over SKComm; reliable outbox with retry/backoff |
| History | history.py, encrypted_store.py, ephemeral.py | Persistent SQLite store; AES-encrypted store; ephemeral (TTL) channels |
| Groups | group.py, reactions.py | Encrypted group chat, roles, key rotation; emoji reactions |
| Identity | identity_bridge.py, agent_profile.py, peer_discovery.py | Delegates to canonical capauth.resolve_agent_identity; loads peers from ~/.skcapstone/peers/ |
| Crypto | crypto.py, plugins_skseal.py | PGP sign/verify (PGPy); SKSeal encryption plugin |
| Voice | voice.py, voice_stream.py, voice_backends.py, facetime.py, livekit_routes.py | Piper TTS + Whisper STT (local); WebRTC P2P + LiveKit SFU for group calls |
| Memory | memory_bridge.py | Forwards chat threads to skcapstone memory (session_capture) |
| Plugins | plugins.py, plugins_builtin.py | Plugin loader + built-ins; file-type / pattern / command triggers |
| Integration | integration.py | Optional skcapstone backbone — routes alerts to sk-alert, registers the outbox-flush sweep with skscheduler (default-on-by-presence) |
Two modes of operation
- Secured — full CapAuth identity, AI advocate active, every message PGP-encrypted and every file capability-gated.
- Standalone — skchat runs fully on its own (PGP keys only). When the
optional
skcapstoneextra is present it lights up advocacy, thesk-alertbus, and theskscheduleroutbox sweep; when absent, every call degrades gracefully to local logging /notify-sendand the daemon's own loop.
Where it lives in SKStack v2
skchat is a comms capability. It is a thin, opinionated experience layer:
it owns conversation, presence, advocacy, and the UIs — and delegates the hard
parts to dedicated ports. Transport is skcomms, identity is capauth, and
the agent reasoning behind @mention advocacy comes from the skcapstone
consciousness loop (skmodel-backed). It reuses two shared platform primitives
— sk-alert and skscheduler — only when skcapstone is present.
flowchart TD
OP["operator / agent"] -->|"skchat send · skchat-mcp · TUI"| SKCHAT
subgraph COMMS["Comms"]
SKCHAT["**skchat**<br/>conversation · groups · presence<br/>AI advocacy · voice · MCP tools"]
SKCOMMS["skcomms<br/>(transport · PGP · failover)"]
SKVOICE["skvoice<br/>(Piper TTS · Whisper STT)"]
end
subgraph CORE["Core"]
CAPAUTH["capauth<br/>(identity — resolve_agent_identity)"]
SKMEMORY["skmemory<br/>(thread capture)"]
end
subgraph COMPUTE["Compute"]
SKMODEL["skmodel (ollama)<br/>(advocacy reasoning)"]
end
subgraph PLATFORM["Platform primitives skchat reuses"]
ALERT["sk-alert bus<br/>(when skcapstone present)"]
SCHED["skscheduler<br/>(outbox-flush sweep)"]
end
SKCHAT -->|"messages over"| SKCOMMS
SKCHAT -->|"resolve identity"| CAPAUTH
SKCHAT -->|"TTS / STT"| SKVOICE
SKCHAT -->|"@mention → consciousness loop"| SKMODEL
SKCHAT -->|"capture threads"| SKMEMORY
SKCHAT -.->|"alerts"| ALERT
SKCHAT -.->|"register outbox sweep"| SCHEDThe dashed edges are optional (default-on-by-presence): skchat works standalone, and only wires into the
sk-alert/skschedulerplatform primitives when theskcapstoneextra is installed.
Documentation
| Doc | Contents | |---|---| | Architecture | inbound/outbound message lifecycle, the @mention advocacy loop, group key state, voice pipeline, source-map, where-it-lives (mermaids) | | MCP reference | every MCP tool, its arguments, and usage from an agent host | | CLAUDE.md | running the daemon, systemd units, identity, troubleshooting |
License
GPL-3.0-or-later — because communication is a right, not a product.
Part of the SKWorld sovereign ecosystem · site: skchat.skworld.io · 🐧 smilinTux
