The Problem

Huginn solves the problem of self-hosted automation. Services like IFTTT and Zapier control your data and limit you to their connectors. Huginn gives you a hackable agent system on your own server, where agents read the web, watch for events, and act on your behalf—with full visibility into what runs and where data goes.

What This Does

This is a fork of the popular huginn/huginn project (49k stars upstream). It's a Rails application with ~70 agent types in app/models/agents/, each a self-contained automation unit. Agents create and consume events along a directed graph, with propagation handled by jobs in app/jobs/.

The system supports scraping (website_agent.rb), social media monitoring (twitter_search_agent.rb), notifications (email, Slack, Telegram, Pushover), and integrations with 20+ services including FTP, IMAP, JIRA, MQTT, and OpenAI. A web UI in app/controllers/ and app/views/ manages agents, scenarios, and event flows.

How It Is Wired

The import graph shows 18 internal modules with zero edges—no circular dependencies, but also no meaningful module coupling detected. The real wiring runs through Rails conventions rather than explicit imports.

Execution starts at app/controllers/agents_controller.rb, which handles CRUD and triggers agent runs. The core loop: AgentCheckJobAgent#check → agent-specific logic → creates Event records → AgentPropagateJob routes events to downstream agents via ControlLink records.

The widest blast radius sits in app/models/agent.rb (the base model) and app/concerns/web_request_concern.rb, which nearly every agent includes for HTTP operations. app/models/agents/website_agent.rb is the largest agent at 1,345 lines and handles scraping, parsing, and event emission—changes there ripple across all scraping workflows.

External effects: HTTP calls via web_request_concern.rb, database writes to events, agent_logs, and user_credentials tables, plus outbound email via app/mailers/system_mailer.rb. Docker deployment is defined in docker/multi-process/ and docker/single-process/.

How To Use It

Setup: Docker is the fastest path. Build from docker/multi-process/Dockerfile or use the single-process compose file:

git clone https://github.com/moses-y/huginn
cd huginn
cp .env.example .env
docker compose -f docker/single-process/docker-compose.yml up

Configuration: .env.example defines required variables—database credentials, secret key, and integration API keys (Twitter, Slack, OpenAI). The docker/secrets.env file exists but contains secret-shaped paths; verify contents before deploying.

Running it: The Rails app starts via bin/rails server (or the Docker entrypoint). Background jobs use bin/rails jobs:work for the single-process mode, or separate worker containers in multi-process mode.

Real-World Use

A practical deployment: a WebsiteAgent scrapes a competitor's pricing page every hour. It emits events to a TriggerAgent that checks for price drops below a threshold. That triggers a SlackAgent posting to your team channel and an EmailAgent sending a digest. All agents connect through the event graph defined in the UI, with the AgentCheckJob scheduler driving the cycle.

Code Health & Issues

Static analysis found 80 issues (40 high, 40 medium) across four kinds:

  • High – Deep nesting (49 instances): app/controllers/agents_controller.rb, app/controllers/scenarios_controller.rb hit max indentation depth 8; control flow is hard to follow.
  • High – Duplicated code (128 repeated 6-line blocks across 51 files): concentrated in app/concerns/openai_concern.rb, app/concerns/web_request_concern.rb, and several agent models.
  • High – Oversized files (4): spec/models/agents/website_agent_spec.rb and app/models/agents/website_agent.rb (1,345 lines) are the worst.
  • Medium – High branching density (6): app/concerns/email_concern.rb has 18 branch points over 49 lines.

Security audit findings: GitHub Actions pinned to mutable tags (ruby/setup-ruby@v1) instead of commit SHAs—a known supply-chain risk. CI uses npm install rather than npm ci, and the Docker base image rubylang/ruby:4.0.6-jammy isn't pinned by digest. No dependency vulnerability scan gates pull requests.

The Bottom Line

Solid, mature codebase with broad agent coverage and a working Docker story. The complexity is real—deep nesting and large files will slow contributors—but the architecture is sound and the upstream project is battle-tested. Use it if you need self-hosted automation with full data control and can tolerate a Ruby/Rails stack with some maintenance debt.