Skip to Content
Energon runs in the operator's Cloudflare account. Published links are open by default.
Operate an InstanceDeploy an Energon host

By the end of this tutorial, you will have an Energon host with dedicated D1 and R2 resources, separate hub and content origins, and an agent plugin bound to that deployment. An individual can run it for personal agent work; an organization can operate it for team handoffs. You need a Cloudflare Workers Paid account, control of two hostnames, and a GitHub fork. Complete the steps in order because the runtime identity, storage bindings, and install coordinates must agree before anyone connects.

Deploy an Energon host

Bind the runtime and plugin to one instance

Energon’s runtime and its agent plugin describe the same instance from opposite sides. Wrangler tells the Worker which origins and policies to expose; skill:init tells agents which origin and token environment to use. Establishing the operator-owned fork first keeps those names aligned and prevents users from installing the upstream placeholder plugin.

Prerequisites

  • A fork whose origin points at a repository controlled by the instance operator.
  • Cloudflare Workers Paid and permission to create D1, R2, Access, and custom domains.
  • Two distinct hostnames, such as energon.company.example and content.energon.company.example.
  • A decision on allowed email domains, retention, token lifetime, and default write policy.

1. Install dependencies and create unique resources

Run these from the operator’s fork. The names remain energon because the checked-in deployment workflow expects them; the resources themselves must belong only to this instance.

npm install npx wrangler r2 bucket create energon npx wrangler d1 create energon

Copy the D1 identifier printed by Wrangler into wrangler.toml:

[[d1_databases]] binding = "DB" database_name = "energon" database_id = "PASTE_D1_DATABASE_ID_HERE" migrations_dir = "migrations" [[r2_buckets]] binding = "BUCKET" bucket_name = "energon"

2. Render the instance plugin

Replace the three replace-... values before running this example. The slug must be lowercase kebab-case, and the repository must be the operator’s fork.

INSTANCE_SLUG=replace-with-instance-slug INSTANCE_DOMAIN=replace.with.instance.domain INSTANCE_REPO=replace-with-owner/energon npm run skill:init -- \ --name "$INSTANCE_SLUG" \ --origin "https://energon.$INSTANCE_DOMAIN" \ --repo "$INSTANCE_REPO" npm run skill:render -- --check

The name identifies this deployment wherever an agent uses it. For example, --name personal produces personal-energon and PERSONAL_ENERGON_TOKEN, while --name acme produces acme-energon and ACME_ENERGON_TOKEN. Init writes the corresponding plugin directory, marketplace catalogs, and instance-skill.json. Commit those generated files in the fork.

3. Align Wrangler identity and policy

Set both origins and copy the rendered identity into [vars]. The content origin must be different from the hub origin.

[vars] PUBLIC_ORIGIN = "https://energon.company.example" CONTENT_ORIGIN = "https://content.energon.company.example" TOKEN_ENV = "EXAMPLE_COMPANY_ENERGON_TOKEN" SKILL_NAME = "example-company-energon" MARKETPLACE_NAME = "example-company-energon" MARKETPLACE_REPO = "example-org/energon" ALLOW_UNLIMITED_RETENTION = "true" DEFAULT_TTL = "never" MAX_TTL = "never" WRITE_POLICY = "instance" ALLOW_UNLIMITED_TOKENS = "true" ALLOWED_EMAIL_DOMAINS = "company.example"

The values above illustrate a trusted organization configuration. A personal instance commonly keeps expiring content, owner-only writes, and finite tokens instead. Review Configure instance policy before copying either operating profile into a real deployment.

4. Attach domains and set Access paths

Attach both custom domains to the Worker. Put Cloudflare Access only on the human hub paths:

  • Allow with sign-in: /, /account*, /about, /stats, /setup, /tokens.
  • Bypass on the hub: /v1*, /health, /llms.txt, /favicon.svg, /static*.
  • Bypass on the content hostname: /{handle}/s/* and /{handle}/f/*.

Do not put Access on the content hostname. Agents need /v1 to remain reachable with API tokens, and public content URLs need to open without inheriting a human’s hub session.

5. Enable the guarded deployment workflow

Add these GitHub Actions secrets to the operator’s fork:

CLOUDFLARE_API_TOKEN CLOUDFLARE_ACCOUNT_ID

Set the repository variable ENABLE_PRODUCTION_DEPLOY to the exact string true. With it unset, pushes still run tests but do not deploy. On a push to main, the workflow generates types, typechecks, lints, runs unit and Worker tests, applies remote D1 migrations, and only then deploys the Worker.

6. Verify the instance

After the guarded workflow succeeds, use the configured hub origin:

curl -fsS https://energon.company.example/v1/health curl -fsS https://energon.company.example/v1/help

The health response should be {"ok":true}. In the help response, confirm the hub origin, rendered skill name, token environment, install line, retention policy, token lifetime policy, and capacity limits. Then open the hub in a browser and verify that Access admits only the intended personal identity or organization members.

Stop conditions

Never reuse another instance’s D1 database id or R2 bucket. If either binding points at shared storage, stop before deployment, create new operator-controlled resources, and update wrangler.toml.

Never deploy with the same hub and content origin. If the host reports content_origin_not_configured, attach a second custom hostname, set CONTENT_ORIGIN, and keep Access off that hostname.

Run skill:init only in the operator’s fork. If git remote origin still points at tmchow/energon, correct the remote or pass --repo replace-with-owner/energon, rerender, and commit the resulting marketplace files.

Migrations must run before the Worker deploys. Prefer the checked-in GitHub Actions job. Do not use a cloud agent to run wrangler login, modify d1_migrations, or execute ad hoc SQL against production.

Verify the complete boundary

The deployment is ready for use only when all five pieces agree: dedicated catalog and object storage, an Access-protected human hub, API-token agent routes, a separate content origin, and the instance plugin committed in the fork. Continue with Configure instance policy, and review Upgrade and recover before the first upstream merge.

Last updated on