Releases: mathematic-inc/earl
v0.5.2
v0.5.2 brings homelab support, hardened Bash security, and a big milestone: Earl is now officially home at mathematic-inc/earl under the Apache-2.0 license. Whether you're querying a self-hosted Home Assistant instance or running Earl in a hardened CI pipeline, this release has something for you.
✨ New Features
allow_private_ips — homelab and self-hosted services, unlocked
Earl's SSRF protection has always blocked RFC 1918 private addresses and loopback interfaces by default — the right call for cloud deployments. But if you're running Earl against a self-hosted Frigate camera server, an OPNsense router, or a local Home Assistant instance, those blocks were in the way.
v0.5.2 adds allow_private_ips to the [network] config section. Flip it on and Earl will happily reach your LAN services while still blocking cloud metadata endpoints (169.254.169.254 and friends) unconditionally.
# ~/.config/earl/config.toml
[network]
allow_private_ips = trueWith that set, a template targeting your local smart home hub just works:
command "get_light_state" {
title = "Get light state"
summary = "Returns the current state of a Home Assistant light entity"
param "entity_id" {
type = "string"
required = true
}
operation {
protocol = "http"
http {
method = "GET"
url = "http://192.168.1.100:8123/api/states/{{ args.entity_id }}"
headers = {
Authorization = "Bearer {{ secrets.ha_token }}"
}
}
}
}Cloud metadata endpoints and all other hazardous ranges remain blocked regardless of this setting — so you get homelab flexibility without giving up cloud safety.
🐛 Bug Fixes
Bash injection prevention in examples
The examples/bash/system.hcl templates were previously interpolating user-supplied arguments directly into the script string — a pattern that could allow shell injection via values containing ;, $(), or backticks. The examples now pass all string arguments through env vars and reference them safely:
# Safe pattern — user input never lands in the script string
bash {
script = "du -sh \"$EARL_PATH\""
env = {
EARL_PATH = "{{ args.path }}"
}
}The hardening docs and how-earl-works page have been updated with explicit before/after examples, and a regression test was added to ensure shell metacharacters in env var values are never interpreted.
⚡ Improvements
New home: mathematic-inc/earl
Earl has moved to the mathematic-inc GitHub org. All documentation, install scripts, and CI workflows have been updated to the new canonical URL. The license has also changed from MIT to Apache-2.0 — same permissiveness, broader patent protection.
Hardened CI and release pipeline
- All GitHub Actions steps are now pinned to full commit SHAs, closing a supply-chain attack vector.
- Per-job timeouts added across the CI matrix.
- TypeScript type-checking runs as a dedicated CI job (
pnpm turbo run types:check). - The release workflow now supports per-crate releases via
{crate-name}-vX.Y.Ztags in addition to rootvX.Y.Zreleases, making it easier to version the protocol crates independently.
Install / Upgrade
Shell one-liner (macOS & Linux):
curl -fsSL https://raw.githubusercontent.com/mathematic-inc/earl/main/scripts/install.sh | bashCargo:
cargo install earlAfter upgrading, run earl doctor to confirm everything is wired up correctly. Happy calling! 🎉
v0.5.1
Earl v0.5.1 brings the browser protocol — a full-featured Chrome automation engine baked directly into your HCL templates. With 62 step action variants and Playwright MCP parity, agents can now navigate, scrape, screenshot, click, fill forms, manage cookies, run JavaScript, and interact with the web using the same declarative, auditable, AI-safe template model you already know. Persistent sessions, an accessibility tree renderer for AI-driven interaction, and a brand-new earl runtime skill round out a release that makes Earl a genuinely capable browser automation platform.
✨ New Features
Browser Protocol — Chrome automation in HCL
Control Chrome via CDP directly from your Earl templates. Supports both scripted batch workflows (a declarative steps array) and AI-driven interactive sessions (stateful session_id). Ships with the same ~55 actions as the Playwright MCP server — navigation, snapshots, clicks, form fills, mouse events, waits, assertions, JavaScript execution, tab management, cookies, local storage, file uploads, dialogs, PDF export, and more.
Take a full-page screenshot in four lines:
operation {
protocol = "browser"
browser {
headless = true
steps = [
{ action = "navigate", url = "{{ args.url }}" },
{ action = "screenshot", full_page = true },
]
}
}For AI-driven navigation, pass a session_id and the browser stays open between calls — letting an agent snapshot the page, pick an element ref from the accessibility tree, then click it in the next command:
# Step 1 — get the accessibility tree
browser {
session_id = "{{ args.session_id }}"
steps = [{ action = "snapshot" }]
}
# Step 2 — click ref e8 (returned by the snapshot)
browser {
session_id = "{{ args.session_id }}"
steps = [
{ action = "click", ref = "{{ args.ref }}" },
{ action = "snapshot" },
]
}Four ready-to-use example templates are included under examples/browser/: screenshot.hcl, scrape.hcl, login.hcl, and ai_navigate.hcl.
Security first: only http:// and https:// URLs are allowed in navigate steps (SSRF protection). Sessions are stored at ~/.config/earl/browser-sessions/ with advisory flocks, atomic writes, and 0700 directory permissions. The LLM still never reads the template body — the security model is unchanged.
Earl runtime skill
A new skills/runtime/earl/SKILL.md teaches agents how to use Earl without prior knowledge of what templates are installed. It covers both MCP discovery mode (earl.tool_search + earl.tool_call) and CLI mode, with strict guidance on flag ordering, write-mode permission gating, pagination handling, and a three-tier error resolution ladder. Drop it into your agent config and it will discover and call the right command for any task automatically.
Load it in Claude Code:
/skills add https://raw.githubusercontent.com/brwse/earl/main/skills/runtime/earl/SKILL.md⚡ Improvements
Default browser session
Omitting session_id from a browser operation now defaults to a persistent session named "default" rather than launching a throw-away browser. This makes it trivially easy to chain commands across multiple tool calls without passing a session ID every time. To opt back into ephemeral behavior, pass an explicit empty string: session_id = "".
Skills reorganised by audience
All agent skills have been moved into two clearly labelled categories:
skills/development/— setup, template authoring, migration, security hardening, troubleshootingskills/runtime/— the newearlskill for agents calling commands at runtime
Protocol-first documentation
The Templates section of the docs has been restructured around protocols (HTTP, GraphQL, gRPC, Bash, SQL, Browser) rather than generic template concepts, making it faster to find syntax for the protocol you're actually using.
Third-party provider examples
Community-contributed provider templates have moved to examples/3p/ to keep the core examples/ directory clean.
Install / Upgrade
# Shell one-liner (macOS & Linux)
curl -fsSL https://raw.githubusercontent.com/brwse/earl/main/scripts/install.sh | bash
# Or via Cargo
cargo install earlFull documentation at brwse.github.io/earl.
earl-protocol-sql: v0.5.1
0.5.1 (2026-02-26)
Miscellaneous Chores
- earl-protocol-sql: Synchronize earl versions
Dependencies
- The following workspace dependencies were updated
- dependencies
- earl-core bumped from 0.5.0 to 0.5.1
- dependencies
earl-protocol-http: v0.5.1
0.5.1 (2026-02-26)
Miscellaneous Chores
- earl-protocol-http: Synchronize earl versions
Dependencies
- The following workspace dependencies were updated
- dependencies
- earl-core bumped from 0.5.0 to 0.5.1
- dependencies
earl-protocol-grpc: v0.5.1
0.5.1 (2026-02-26)
Miscellaneous Chores
- earl-protocol-grpc: Synchronize earl versions
Dependencies
- The following workspace dependencies were updated
- dependencies
- earl-core bumped from 0.5.0 to 0.5.1
- dependencies
earl-protocol-browser: v0.5.1
earl-protocol-bash: v0.5.1
0.5.1 (2026-02-26)
Miscellaneous Chores
- earl-protocol-bash: Synchronize earl versions
Dependencies
- The following workspace dependencies were updated
- dependencies
- earl-core bumped from 0.5.0 to 0.5.1
- dependencies
earl-core: v0.5.1
v0.5.0
Earl v0.5.0 is a milestone release that fundamentally expands how you manage multi-environment configurations and enterprise secrets — while making the whole experience faster and more robust. Named environments let a single template target production, staging, and local dev without duplicating a line of HCL. Five external secret-manager backends mean secrets can live in 1Password, Vault, AWS, GCP, or Azure and flow into your templates with zero changes to the call site. A compiled catalog cache makes CLI startup near-instant, Bash sandboxes gained hard memory and CPU limits, and optional parameters now cleanly omit themselves from requests rather than sending empty strings. On top of all that, a new Recall.ai template and a full suite of agent skills round out the release. There's something here for every Earl user.
✨ New Features
Named Environments
Define named variable sets at the provider level and switch between them with a single flag. One template, one command, every environment — no copy-paste required.
version = 1
provider = "myapi"
environments {
default = "production"
secrets = ["myapi.prod_token", "myapi.staging_token"]
production {
base_url = "https://api.myservice.com"
token = "{{ secrets['myapi.prod_token'] }}"
}
staging {
base_url = "https://staging.myservice.com"
token = "{{ secrets['myapi.staging_token'] }}"
}
}
command "list_widgets" {
title = "List widgets"
summary = "Fetch all widgets for the current account"
operation {
protocol = "http"
method = "GET"
url = "{{ vars.base_url }}/widgets"
auth {
kind = "bearer"
secret = "{{ vars.token }}"
}
}
}# Hit staging
earl call --env staging myapi.list_widgets
# Hit production (default)
earl call --yes --json myapi.list_widgetsResolution order: --env flag → [environments] default in config.toml → template default → none. Commands that need a fundamentally different operation for an environment (different URL shape, different protocol) can use per-command environment override blocks.
External Secret Manager Support
Secrets no longer have to live in the OS keychain. Five backends are now available, each behind a URI scheme:
| Backend | URI scheme |
|---|---|
| 1Password Connect | op://vault/item/field |
| HashiCorp Vault | vault://host/secret/path |
| AWS Secrets Manager | aws://region/secret-name |
| GCP Secret Manager | gcp://project/secret/version |
| Azure Key Vault | az://vault-name/secret-name |
Just reference the URI wherever you'd use a plain secret name:
annotations {
secrets = ["op://Engineering/GitHub Token/credential"]
}
auth {
kind = "bearer"
secret = "op://Engineering/GitHub Token/credential"
}Plain secret names (no ://) continue to use the OS keychain — fully backward compatible. All URI path segments are validated at load time to prevent injection.
Compiled Catalog Cache
Earl now persists a compiled, rkyv-serialized snapshot of your template catalog to ~/.cache/earl/catalog-N.bin. On subsequent invocations, if nothing has changed, the catalog loads in microseconds instead of re-parsing every .hcl file. The cache invalidates automatically whenever any file's mtime changes, and a safe atomic temp-file + rename write prevents corruption.
Bash Sandbox Resource Limits
Bash protocol templates can now cap memory and CPU usage in addition to wall-clock time and output size:
command "run_analysis" {
operation {
protocol = "bash"
bash {
script = "python3 /opt/scripts/analyse.py {{ args.input_file }}"
}
sandbox {
max_time_ms = 30000 # wall-clock limit
max_cpu_time_ms = 10000 # CPU time limit (RLIMIT_CPU)
max_memory_bytes = 134217728 # 128 MB address-space cap (RLIMIT_AS)
max_output_bytes = 1048576 # 1 MB stdout limit
}
}
}Limits follow the existing most-restrictive-wins policy between per-template values and global config.toml settings.
Recall.ai Integration
A full 14-command template for Recall.ai is now bundled — covering bot creation, scheduling, status polling, recording control, transcript retrieval, and more. An accompanying agent skill gives AI agents step-by-step guidance for the record → wait → transcribe workflow.
Earl Agent Skills Suite
Five new agent skills shipped for common onboarding and maintenance tasks:
- setup-earl — installs Earl and wires up MCP in one shot
- create-template — scaffolds a new HCL template from a description
- migrate-to-earl — converts existing curl/fetch calls into Earl templates
- troubleshoot-earl — diagnoses keychain, template, and MCP issues
- secure-agent — reviews templates for security best practices
⚡ Improvements
Graceful Optional Parameters
Optional parameters without defaults no longer appear as empty strings in requests. Earl now uses UndefinedBehavior::Chainable in the Jinja environment so undefined optional params evaluate to null, and null values are silently omitted from query strings and headers. The | default('') workarounds that littered example templates are gone. Additionally, all args.IDENT references in a template are validated against declared params at load time — typos are caught immediately, not at the moment an agent fires the call.
🐛 Bug Fixes
- Fixed a race condition in 1Password env-var resolver tests when run in parallel (
--test-threadscontention on the same env-var key). - Fixed release workflow: replaced a non-existent
peter-evans/workflow-dispatchaction with a directghCLI call. - Made crate publishing idempotent — re-running the release workflow no longer fails when a version already exists on crates.io.
Install / Upgrade
# Shell one-liner (macOS & Linux)
curl -fsSL https://raw.githubusercontent.com/brwse/earl/main/scripts/install.sh | bash
# Or via cargo
cargo install earlFull documentation at brwse.github.io/earl.