Guides

Agents

A reviewer, a translator and a weekly auditor that work on your content next to your Hollware, and never publish.

Agents

@hollware/agents runs three agents on a Worker of your own, next to your Hollware:

AgentWhat it does
ReviewerComments once on each pending review: clarity, the voice of your style guide, claims without an example.
TranslatorDrafts the missing translation of a published entry, fixes what the contracts refuse, and asks for its review.
AuditorOnce a week, reports much-read entries that have not changed in months, and published entries the contracts refuse now.

None of them publishes. Their MCP client refuses every tool that publishes or decides (publish, approve_review, request_changes, unpublish), whatever their token holds. A translation reaches readers only when a person approves its review; an audit is a draft.

Set them up

  1. Create a token for them, with no publishing:
npx hollware token create --label agents --scopes content:read,content:write --remote
  1. Create a KV namespace for what they remember:
npx wrangler kv namespace create my-cms-agents
  1. Make a Worker for them. Its wrangler.jsonc, with the name of your Hollware Worker in service:
{
  "name": "my-cms-agents",
  "main": "src/index.ts",
  "compatibility_date": "2026-10-06",
  "vars": { "HOLLWARE_PUBLIC_URL": "https://cms.example.com" },
  "services": [{ "binding": "HOLLWARE", "service": "my-cms" }],
  "ai": { "binding": "AI" },
  "kv_namespaces": [{ "binding": "AGENTS_KV", "id": "<the id of step 2>" }]
}

And src/index.ts:

import { createHollwareAgents } from '@hollware/agents'
import { WorkerEntrypoint } from 'cloudflare:workers'

const agents = createHollwareAgents({
  auditor: { collection: 'reports', locale: 'en' },
})

export class HollwareAgents extends WorkerEntrypoint<Env> {
  async run() {
    await agents.run(this.env)
  }
}

export default { fetch: agents.fetch, scheduled: agents.scheduled }
  1. Give it the token, and deploy:
npx wrangler secret put HOLLWARE_AGENT_TOKEN
npx wrangler deploy
  1. Let your Hollware wake them. In the wrangler.jsonc of your Hollware, then deploy it again:
"services": [{ "binding": "AGENTS", "service": "my-cms-agents", "entrypoint": "HollwareAgents" }]

Hollware's cron trigger wakes the agents every ten minutes, so they need no cron trigger of their own: the Workers free plan has five for the account. Each run is one agent, in turn: the reviewer, then the translator, then the auditor, which checks a dozen entries a run and writes its report once a week. One agent at a time keeps a run within the fifty calls a free Worker may make.

If you have cron triggers to spare, give the agents one instead of the binding: scheduled runs them the same way.

The model

The agents use Workers AI, @cf/meta/llama-3.3-70b-instruct-fp8-fast unless you name another. They stop for the day after 100 calls to the model, which keeps them in the free allowance of Workers AI:

createHollwareAgents({ model: '@cf/openai/gpt-oss-120b', dailyLimit: 50, gateway: 'my-gateway' })

gateway sends the calls through an AI Gateway, for its logs and its cache. For another provider, pass a function that takes the messages and returns the answer.

The report

The auditor needs no model. Its report gathers what its runs found in the last week, with the much-read pages that have not changed in six months. It writes the report as a draft of the collection you give it, with the slug audit-<day>, and never publishes it. The collection needs a title and a description in its schema, or a frontmatter function that returns what it does need.

To get the report in Slack as well, set the URL of an incoming webhook as a secret:

npx wrangler secret put AGENTS_WEBHOOK_URL

The auditor reports much-read pages only when the site's analytics are connected: see Search and analytics.

Tip
Turn an agent off with reviewer: false, translator: false or auditor: false.