Skip to content

Releases: kOlapsis/herald

v0.1.2

17 Feb 16:50

Choose a tag to compare

This release focuses on stability and architecture. Claude Chat no longer burns through rate limits polling every few seconds, and Herald's executor layer is now ready for alternative CLI backends.


Highlights

  • Polling guidance — Tool descriptions and responses now instruct Claude Chat to use long-polling (wait_seconds=30), drastically reducing unnecessary API calls.
  • Executor registry — The executor layer is now pluggable. Claude Code is registered as a backend via init(), and new CLI backends can be added without touching existing code.
  • Task context tracking — Tasks now carry a human-readable context field, making it easy to understand why a task was launched when reviewing history across sessions.

What's New

Reduced Polling Frequency

Claude Chat was calling check_task every few seconds, quickly exhausting rate limits and wasting tokens. Three changes fix this:

  • Tool descriptions for start_task and check_task now explicitly recommend wait_seconds=30 long-polling.
  • Response text from both handlers includes clear guidance: "Do NOT call check_task more than once every 30 seconds."
  • longPollMaxWait increased from 30 to 60 seconds, allowing Claude Chat to wait longer per request.

Combined with the rate limit increase (see Fixes), polling-related throttling should be eliminated.

Executor Registry

The executor layer has been refactored into a pluggable registry pattern:

  • Register / Get / Available — Factory-based registration. Backends register themselves via init().
  • Claude Code moved to internal/executor/claude/ — Auto-registered sub-package, cleanly separated from the registry.
  • Capabilities struct — Each executor declares what it supports (sessions, model selection, tool lists, dry run, streaming), so handlers can adapt.
  • GracefulKill extracted — Shared process termination logic in kill.go.
  • Config field — New executor field in ExecutionConfig (defaults to "claude-code" for backward compatibility).

Zero breaking changes on the MCP API or YAML configuration.

Task Context Field

A new context parameter on start_task lets Claude Chat attach a human-readable description of why a task was launched:

start_task(prompt="...", context="User asked to fix the login bug from mobile")

The context appears in check_task, list_tasks, and get_result responses, making task history meaningful across sessions.

Fixes

  • Rate limits increased — Default bumped from 100 req/min (burst 30) to 600 req/min (burst 200). Claude Chat sends many parallel MCP requests that exhausted the old limits.
  • OAuth authorize URL — Fixed incorrect redirect in the authorization flow.
  • Security findings — Resolved remaining gosec and gocritic findings in main.go (HTTP server timeouts, error handling, if-else to switch).

Upgrade

# Binary upgrade
curl -fsSL https://raw.githubusercontent.com/btouchard/herald/main/install.sh | sh

# Or rebuild from source
git pull && make build

No configuration changes required. All new defaults are backward compatible.

What's Next (v0.2)

  • Shared memory — bidirectional context between Claude Chat and Claude Code
  • Model templates per task type (e.g. review → opus, test → sonnet)

License: AGPL-3.0
Documentation: btouchard.github.io/herald
Built by: Benjamin Touchard

If Herald saves you time, leave a star. It helps others find the project.

v0.1.1

14 Feb 16:10

Choose a tag to compare

This release makes Herald dramatically easier to set up. No more Traefik, Caddy, or DNS configuration — just plug in your ngrok token and go.


Highlights

  • ngrok tunnel built-in — One config flag and Herald is accessible over HTTPS. No reverse proxy, no TLS certificates, no DNS records.
  • Interactive install wizard — The install script now walks you through port, exposure method, and project setup. Generates a complete herald.yaml.
  • Graceful shutdown — Long-running SSE connections no longer block server shutdown for 10+ seconds.

What's New

ngrok Tunnel Integration

Herald can now expose itself over HTTPS instantly via ngrok, without any reverse proxy setup:

tunnel:
  enabled: true
  provider: "ngrok"
  authtoken: "2abc..."  # or set HERALD_NGROK_AUTHTOKEN env var
  # domain: "my-herald.ngrok-free.app"  # optional: fixed domain (paid plans)

Run herald serve and the tunnel URL appears in the startup banner — paste it into Claude Chat and you're connected. Free ngrok plans work fine.

The tunnel starts before OAuth metadata is served, so the public URL is always correct for Custom Connector discovery.

Install Script Improvements

  • --local flag — Install from the local bin/ directory instead of downloading from GitHub. Useful for testing.
  • Setup wizard — Interactive guided configuration: port, exposure method (ngrok / domain / local), and project setup.
  • Config backup — If a config file already exists, the wizard backs it up with a timestamp before overwriting.

Fixes

  • Graceful shutdown — SSE connections (MCP streaming) no longer cause a context deadline exceeded error on Ctrl+C. Herald force-closes remaining connections after a 5-second grace period.
  • OAuth redirect URI — Added https://claude.ai/api/mcp/auth_callback to the default allowed redirect URIs. This is the URI Claude.ai actually sends during Custom Connector authentication.
  • Startup banner — Now displays the full MCP URL (e.g. https://xxx.ngrok-free.app/mcp) ready to copy-paste into Claude Chat. No more forgetting the /mcp suffix.
  • Tunnel error messages — Common ngrok errors (invalid token, domain in use, session limit) now show actionable messages with remediation steps instead of raw error codes.
  • Executor pipe draining — Fixed a race condition where stdout/stderr pipes were not fully drained before calling Wait(), which could lose output on fast-completing tasks.
  • Security findings — Resolved all gosec and gocritic findings.

Upgrade

# Binary upgrade
curl -fsSL https://raw.githubusercontent.com/btouchard/herald/main/install.sh | sh

# Or rebuild from source
git pull && make build

If you already have a herald.yaml, add the new redirect URI to your config:

auth:
  redirect_uris:
    - "https://claude.ai/oauth/callback"
    - "https://claude.ai/api/oauth/callback"
    - "https://claude.ai/api/mcp/auth_callback"  # ← add this

Or remove the redirect_uris section entirely to use the new defaults.

What's Next (v0.2)

  • Shared memory — bidirectional context between Claude Chat and Claude Code
  • Model templates per task type (e.g. review → opus, test → sonnet)

License: AGPL-3.0
Documentation: btouchard.github.io/herald
Built by: Benjamin Touchard

If Herald saves you time, leave a star. It helps others find the project.

v0.1.0

13 Feb 16:06

Choose a tag to compare

The first public release of Herald, a self-hosted MCP server that bridges Claude Chat to Claude Code using Anthropic's official [Custom Connectors](https://support.claude.com/en/articles/11503834-building-custom-connectors-via-remote-mcp-servers) protocol.

One Go binary. Zero hacks. Your code never leaves your machine.


Highlights

  • Native MCP bridge — Claude Chat discovers Herald's 10 tools automatically via Streamable HTTP. No wrappers, no proxies, no unofficial APIs.
  • Bidirectional — Claude Chat dispatches tasks to Claude Code, and Claude Code can push sessions back to Herald via herald_push for remote continuation.
  • Single binary, zero CGO — ~15MB executable. Cross-compiles to Linux, macOS, Windows, ARM. No Docker required.
  • 6 dependencies — chi, mcp-go, modernc/sqlite, uuid, yaml, testify. That's it.

Features

Core

  • 10 MCP tools: start_task, check_task, get_result, list_tasks, cancel_task, get_diff, list_projects, read_file, herald_push, get_logs
  • Async task execution — Start tasks, check progress, get results. Claude Code runs in the background.
  • Git branch isolation — Each task runs on its own branch. Main stays untouched.
  • Session resumption — Multi-turn Claude Code conversations. Pick up where you left off.
  • Bidirectional bridgeherald_push lets Claude Code push session context to Herald for remote monitoring and continuation from another device.
  • Linked sessions — Sessions pushed via herald_push appear as linked tasks, listable and resumable from Claude Chat.
  • Configurable model per task — Choose the model for each task (model parameter on start_task), defaults to Sonnet for cost efficiency.

Multi-Project

  • Multiple projects with independent settings, paths, and tool restrictions.
  • Per-project allowed tools — Full sandboxing. No blanket --dangerously-skip-permissions.

Operations

  • MCP push notifications — Task lifecycle events pushed directly to Claude Chat via SSE. No polling needed.
  • Long-polling on check_task — Returns only on status change, not on every progress update.
  • Duration estimation on start_task — Provides an estimated completion time based on task parameters.
  • SQLite persistence — Tasks survive server restarts. Full history, searchable.
  • Structured logginglog/slog with text (stdout) and JSON (file) outputs.

Auth & Security

  • OAuth 2.1 + PKCE — Every MCP request requires a valid Bearer token. Authorization code flow with mandatory S256 PKCE.
  • Auto-generated secrets — Zero-config auth setup. Secret persisted to disk, displayed at startup.
  • herald rotate-secret — Rotate the client secret and invalidate all sessions.
  • Constant-time secret comparison — Client secret hashed at rest with SHA-256.
  • Redirect URI validation — Prevents open redirect attacks.
  • Per-token and per-IP rate limiting — Token bucket algorithm, configurable (default: 200 req/min).
  • Max concurrent task enforcement — Prevents resource exhaustion.
  • Timeout validation and clamping — Defense-in-depth at handler and task manager layers.
  • Path traversal protection — All file operations validated against project root. Symlink escapes blocked.
  • Security headers on all responses.

Deployment

  • herald serve — Start the server with optional --config flag.
  • herald check — Validate configuration without starting.
  • herald health — Check if the server is running (for Docker HEALTHCHECK).
  • Dockerfile — Multi-stage build (Go 1.26 → scratch).
  • docker-compose.yml — Minimal deployment with Traefik.
  • Install scriptcurl -fsSL https://raw.githubusercontent.com/btouchard/herald/main/install.sh | sh

Installation

# Binary install
curl -fsSL https://raw.githubusercontent.com/btouchard/herald/main/install.sh | sh

# Or build from source (requires Go 1.26+)
git clone https://github.com/btouchard/herald.git
cd herald && make build

Quick Start

mkdir -p ~/.config/herald
cp configs/herald.example.yaml ~/.config/herald/herald.yaml
# Edit with your domain and projects

herald serve
# Client secret is displayed in the console — use it to configure Claude Chat

Then in Claude Chat: Settings → Custom Connectors → Add https://herald.yourdomain.com/mcp

What's Next (v0.2)

  • Shared memory — bidirectional context between Claude Chat and Claude Code
  • Model templates per task type (e.g. review → opus, test → sonnet)

License: AGPL-3.0
Documentation: [btouchard.github.io/herald](https://btouchard.github.io/herald/)
Built by: [Benjamin Touchard](https://kolapsis.com)

If Herald saves you time, [leave a star](https://github.com/btouchard/herald). It helps others find the project.