Features
Persistent Memory
Fera's memory lives in plain Markdown files, indexed at build time into SQLite
with FTS5 full-text search and sqlite-vec vector embeddings
(local ONNX via fastembed — no external API calls).
Hybrid search uses Reciprocal Rank Fusion to merge keyword and semantic results.
An optional deep-search mode expands queries via Haiku for improved recall.
Memory is structured into a daily timeline, a curated MEMORY.md,
and topic-specific files. The Dream Cycle runs nightly to
synthesize the day's transcripts and keep long-term memory clean.
Knowledge Base
Fera includes a two-stage pipeline for building a searchable knowledge base from your documents — PDFs, text files, markdown notes, even scanned images via OCR.
A background daemon (fera-knowledge-indexer) watches a source folder
via inotify, extracts text (with a fallback chain: pypdf → pdftotext →
tesseract OCR for scanned documents), and chunks it into a staging area.
A periodic ingest step (fera-knowledge-ingest) then writes those chunks
as memory files for a dedicated librarian agent to search.
This keeps the two long-term stores apart: the main agent stays sharp for daily work, while the knowledge base sits quietly in the background — searchable by a lightweight Haiku-powered librarian agent, ready to surface a fact, a document, or a record from months ago when you need it.
Multi-Channel I/O
Telegram and Mattermost DMs share a single persistent Claude Code session — Fera maintains one continuous context regardless of which app you message from. The Web UI gives access to all sessions. Adding support for other platforms should be straightforward using the existing adapters as a blueprint.
| Channel | Session | Notes |
|---|---|---|
Telegram | shared | Long-polling, streaming edits, voice transcription (faster-whisper), media support |
Mattermost | WebSocket, threaded replies, streaming edits, typing indicator, auto-reconnect, tool use blockquotes with contextual icons | |
Web UI | all sessions | Vite + TypeScript SPA, WebSocket streaming, session switcher |
Multi-Agent
Fera supports running multiple agents on the same system, each with its own identity, persona, workspace, memory, and tool configuration. Agents can communicate with each other via the shared gateway — useful for separating concerns, like a dedicated coding agent, a librarian agent for knowledge retrieval, or a specialized task runner.
Each agent's config supports fine-grained tool control: allowed_tools for
an explicit allowlist, and disabled_tools to exclude specific tools without
redefining the full list — useful for locking down capabilities in specialized agents.
Heartbeat System
Every 30 minutes during active hours, Fera wakes up and checks
HEARTBEAT.md for actionable tasks: email, calendar, weather,
typhoon watch, shipment tracking — whatever you configure.
Responses are delivered on the channel you last used.
Silent turns (no news) are suppressed automatically.
Skills
Skills
are a Claude Code concept — self-contained directories with a SKILL.md
(metadata + instructions) and optional scripts, references, and assets. They're
auto-discovered from workspace/.claude/skills/ and loaded into context
only when triggered, keeping the context window lean.
Tools & Plugins
Because Fera is built on Claude Code, it inherits the full Claude Code tool and plugin ecosystem out of the box — MCP servers, bash execution, file operations, web search, and anything else Claude Code supports. No reimplementing tool interfaces, no capability gaps. When Anthropic ships something new, Fera gets it too.
MCP Integrations & Custom Skills
Fera connects to external services via the Model Context Protocol. But not every service has an MCP API — and that's fine. When there's no MCP server available, Fera can write a purpose-built client on the fly and package it as a skill with supporting scripts. The result is a self-contained, reusable integration that lives in the workspace and doesn't touch the core codebase.
A real example: checking for active typhoons in the Philippine Area of Responsibility
means polling a weather feed, parsing the data, and deciding whether to alert.
There's no MCP server for that — so Fera wrote a Python script, packaged it as the
typhoon-check skill, and now runs it twice daily via Bash.
- Home Assistant — lights, sensors, climate control
- Redmine / Planio — issue tracking, wiki, time logging
- Playwright — browser automation and web scraping
- Memory server — internal hybrid search (localhost only)
- Any MCP-compatible server, or a custom skill for anything else
Worth knowing: obra/superpowers
is a community plugin that works great alongside Fera — it ships 20+ battle-tested skills
including the meta writing-skills skill for authoring new skills.
Scheduled Jobs
Scheduled jobs are defined in $FERA_HOME/cron.json and triggered via the
fera-run-job CLI, which you wire into a standard system crontab.
Each job can target a persistent session (with full conversation history) or run
in an ephemeral one-shot session.
Per-job overrides for model, tools, prompt mode, and delivery channel.
Security Model
- Runs as a dedicated low-privilege
feraLinux user - All external content wrapped in
<untrusted>tags (prompt injection defence) - Canary token injection detection — a unique token is embedded in the system prompt; any agent output containing it triggers a security alert routed to all adapters
- Gateway auth via HMAC shared secret (Tailscale identity auth is planned)
-
Email isolation via setuid wrapper — IMAP credentials are stored under a
dedicated
himalayasystem user (mode 600, inaccessible to theferauser). A small setuid Rust binary (himalaya-wrapper) acts as gatekeeper: it checks every command against a hardcoded allowlist, clears the environment, then exec's himalaya running as the credential-owning user. Allowed operations: read, list, search, flag, save draft. Blocked: send, write, reply, forward — and anything not explicitly on the list. The kernel enforces this; even a fully-compromised agent cannot send email or extract credentials. - Per-agent tool allowlisting and a
disabled_toolslist for fine-grained exclusions - We recommend encrypting either the full system or at least
/home— LUKS for full-disk encryption or userspace options like gocryptfs work well
Slash Commands
| Command | Description |
|---|---|
/clear | Archive context and start fresh |
/stop | Interrupt an active turn |
/stats | Token usage and cost |
/sonnet /opus /haiku | Switch model |