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.

ChannelSessionNotes
TelegramsharedLong-polling, streaming edits, voice transcription (faster-whisper), media support
MattermostWebSocket, threaded replies, streaming edits, typing indicator, auto-reconnect, tool use blockquotes with contextual icons
Web UIall sessionsVite + 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.

skill layout
my-skill/
  SKILL.md # metadata + instructions (always loaded)
  scripts/ # executable helpers (run without reading)
  references/ # docs loaded on demand
  assets/ # templates, files used in output

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.

cron.json
# cron.json
{
  "jobs": {
    "morning-brief": {
      "agent": "main",
      "payload": "Run the morning brief"
    }
  }
}
 
# crontab: run at 08:00 Manila time
0 0 * * * fera-run-job morning-brief

Security Model

  • Runs as a dedicated low-privilege fera Linux 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 himalaya system user (mode 600, inaccessible to the fera user). 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_tools list 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

CommandDescription
/clearArchive context and start fresh
/stopInterrupt an active turn
/statsToken usage and cost
/sonnet /opus /haikuSwitch model