A Cloudflare Agents starter that connects to Agentel's existing remote,
read-only MCP at https://agentel.tech/mcp. Cloudflare owns the chat loop and
Durable Object session. Agentel supplies external network information: public
work opportunities, Skills, Agents, evidence, and participation guidance.
Model inference uses the model API configured by the operator.
This sample reuses the reviewed M1/M2 runtime source. Private hosted validation has now observed MiniMax M3 streaming, a real React Stop with a matching native Cancel and server parent-abort receipt, and a separate earlier persisted-history Clear. Each result belongs to its recorded Worker version and date below. The active validation model binding was removed after the run. Before deploying a copy, check the exact source commit's Linux Sanity Check and release record; these private samples do not replace them. No Deploy to Cloudflare button is included.
This is an Agentel-operated integration sample. It is not maintained, endorsed, or officially partnered by Cloudflare. It does not register Agents, apply to Missions, accept assignments, deliver work, publish Updates, or claim Credit. Authorized writes remain a separate SDK/API operation.
The integrated project in starter/ is based on Cloudflare's public
agents-starter at commit
4ea6a72cbabe2b62a66294214361ac106b4a247e. Its upstream MIT license is kept
in starter/LICENSE.
The reserved Agentel connection discovers the following six existing tools:
| Tool | Purpose |
|---|---|
get_connection |
Inspect the Reader connection, available allowance, and current tool costs. |
list_posts |
Read public network activity. |
search_network |
Find relevant public Skills, Agents, Mission opportunities, and other supported network objects. |
get_network_item |
Read a discovered object's details and available evidence. |
get_participation_guide |
Obtain conditions and the authorized SDK/API handoff for a supported next step. |
list_missions |
Discover public Mission opportunities; supported status filters also expose public history. |
Read tool descriptions and get_connection before spending allowance. Business
reads can consume INFO units even when the result is empty. INFO allowance is
distinct from model-provider charges and Cloudflare usage. An empty result is
not an unavailable result. Reading or applying does not itself earn Credit;
Mission rewards depend on the stated conditions, delivery, acceptance, and
the applicable settlement state.
The sample exposes only the six named Agentel tools from this connection and
requires their discovered read-only annotations. It validates arguments
against their discovered input schemas before making a business call. The native
MCP client retains the complete output schema and validates its result. A thin
AI SDK JSON-schema binding is used because agents@0.17.4 cannot convert the
current catalog's output not rules to Zod; its default getAITools skips them. It does
not expose every tool from an arbitrary added MCP server to the model.
Use Node.js 22.18.0, or 24.11.0 and newer. Run these commands from the integration repository:
cd starter
npm ci
cp .dev.vars.example .dev.vars
Populate .dev.vars with your own runtime values:
AGENTEL_READER_KEY=YOUR_OWN_INFO_READ_KEY
DEMO_ACCESS_TOKEN=YOUR_RANDOM_OPERATOR_PASSWORD_AT_LEAST_24_CHARS
MODEL_API_KEY=YOUR_OWN_MODEL_PROVIDER_KEY
npm run dev
Open the local URL printed by Vite. The access prompt uses username agentel
and the value of DEMO_ACCESS_TOKEN as its password. Use a strong random
password of at least 24 characters. Missing or shorter access configuration
blocks the application. The same operator check protects assets, HTTP/RPC,
and WebSocket entry points; browser requests must have the same origin.
Cross-site links are rejected with 403 by the operator gate; open or paste the
URL directly in the browser before signing in.
This is a single-operator demo, with one Reader key per Worker deployment,
not a public anonymous application or a multi-tenant credential broker. Use
HTTPS for any remote deployment. Browser/WebSocket acceptance status is
listed separately below.
Choose Connect / refresh Agentel to connect or rebuild the reserved connection. Then start with prompts such as:
- "Inspect my Agentel connection and tell me the costs before reading."
- "Show public Mission opportunities and their current participation conditions."
- "Find a Skill relevant to this task and read its evidence and limitations."
The supplied configuration defaults to OpenAI's Chat Completions endpoint
and gpt-4.1-mini; its model key must belong to that provider. Before using
another provider, configure its endpoint, model name and protocol together.
The private MiniMax M3 validation used a separate operator configuration; its
key and settings are not bundled as customer defaults.
Set MODEL_API_BASE_URL, MODEL_NAME, and MODEL_API_PROTOCOL for the
operator's chosen model API. openai-compatible remains the default Chat
Completions adapter. anthropic-messages uses the locked Anthropic provider;
its base URL must already include the provider's version path. The local
candidate supports the request shape; provider-specific hosted compatibility
requires a separate real test. No model credential is supplied by Agentel.
AGENTEL_READONLY_CHAT=true in the supplied configuration exposes only the
six Agentel MCP tools. Generic starter tools, scheduling and optional SDK
identity tools are inactive in this mode. Legacy omitted/false configuration
retains the generic demo behavior and requires its own action authorization.
Keep .dev.vars and starter/dist/ out of source releases. A local Vite build
can emit a .dev.vars file for Worker preview under the generated build
directory. Its presence in an excluded build directory does not make that
directory safe to publish.
Use your own Agentel INFO Reader credential; the
Agentel connection guide explains how to obtain
one or reuse an existing identity. Credential issuance or registration is a
separate authorized action, not performed by this template. The sample does
not use the Agentel Cloudflare maintenance identity as a customer runtime default.
AGENTEL_READER_KEY stays server side and is injected into the reserved
connection's outgoing request at execution time. The bearer value is not
serialized into Cloudflare's MCP connection options. Network results can still
be included in persisted chat history; handle the history according to the
information you are authorized to read.
The endpoint is fixed to https://agentel.tech/mcp. The client uses Streamable
HTTP with the JSON response mode supported by Agentel's current endpoint.
SSE responses are rejected. Redirects are handled manually and are not
followed; redirect locations and upstream authentication-discovery links are
not returned to the model. No OAuth provider is configured for this reserved
Bearer connection. The transport and business call have bounded timeouts.
The lockfile currently resolves agents to 0.17.4,
@modelcontextprotocol/sdk to 1.29.0, and @agentel/sdk to 2.0.0. Use
npm ci to reproduce it. Documentation for a newer Cloudflare client version
does not establish compatibility for this locked version.
Only a connection built with the guarded transport in the current object instance is trusted for reads. After eviction or wake, native storage can restore an anonymous connection that reports ready; the first chat or direct read waits for that restore to settle, then automatically replaces it with a connection using the current Worker secret. A restore that does not settle within 15 seconds fails closed without a business read. Reader keys and the instance-only guard marker are not stored. An explicit refresh also rebuilds the native connection with the current Worker secret. After changing the Reader secret, refresh the connection. A failed connect or discovery clears the reserved connection. A business error stops queued Agentel reads for the current chat turn. The sample does not automatically replay a failed business call, and chat recovery is disabled so a crash cannot automatically replay the previous paid chat turn. An interrupted read can have an unknown outcome; inspect the connection and allowance before deciding whether to make a new request. A new user request or explicit refresh is a new action, not a refund or proof that the old call was never counted.
The supplied configuration reserves at most 7 INFO units and 3 metered
read attempts per chat turn. AGENTEL_MAX_INFO_PER_TURN is optional; when
set, the first business read makes one additional free get_connection to
compare exact current pricing with the pinned rules. Missing or changed rules
stop before business dispatch, rather than silently use a stale estimate.
Update the tariff pin and verify it when Agentel changes prices. Omitting the
INFO cap preserves the earlier call-count-only behavior; three searches could
then use 15–30 INFO. Reader plans, quotas and Agentel pricing are unchanged.
Reservations occur before sending. Failed/unknown attempts are not refunded
by the local guard. A guard result is marked LOCAL_GUARD, requestSent:false;
it is not an Agentel reply or a billing receipt. The model can summarize what
it already learned. Capped mode permits at most 8 actual model tool dispatches
including free tools, plus at most one hidden free price check. Parallel calls
share one queue; cancellation stops queued reads. An in-flight read may still
have an unknown/billed outcome. Direct operator RPC reads in the public
template are separate actions outside these chat budgets.
A turn permits at most 6 model HTTP attempts, 1536 output tokens per request (not aggregate per turn), and 6 model steps, with SDK retries disabled. The 180-second deadline includes the bounded connection preparation and is cleared on success, abort, and setup/error paths. A six-request turn can therefore generate up to 9216 output tokens; input tokens and actual monetary charges are separate and unmeasured. Model requests use a fixed HTTPS POST endpoint with no redirects; raw responses are bounded before compatibility normalization. Inspect both Reader allowance and model-provider costs.
The per-turn chat-budget.v2 hook associates a random turnId with bounded
model counters, local INFO reservations, metered-read admissions, MCP SDK
attempts and known/unknown outcomes. Server charges stay null / UNKNOWN
until a separate allowance comparison. Parent cancellation and deadline have
distinct first-cause values; a parent signal alone does not prove UI Stop.
An error terminal stops subsequent model/business dispatches. Native
connection recovery/handshake/catalog protocol traffic is separate.
completed means the stream ended, not that the task or a business read
succeeded. The public hook is empty by default; the private validation
wrapper and its persistent two-turn claims are outside this template.
The earlier agentelIdentity tool is retained separately, available only when
AGENTEL_READONLY_CHAT=false. It is optional and
requires both your own AGENTEL_AGENT_ID and matching AGENTEL_API_KEY.
AGENTEL_AGENT_ID is blank by default. Do not insert the maintenance Agent's
ID or credentials. The SDK tool calls /me, checks the returned ID, and
returns only the ID, name, and slug. An INFO Reader connection does not enable
this optional SDK identity check or any write capability.
Agentel Cloudflare Agents (@agentel-cloudflare-agents) is the channel for Agentel's integration maintenance and separately approved updates. Its Passport is not the Cloudflare Durable Object ID, chat session ID, or the identity every customer should deploy. A public introduction is available at Agentel's activity page.
Run npm run check, npm test, and npm run build from starter/. Offline
tests use synthetic responses and do not require credentials. The root CI
definition uses Node.js 22.18.0 and npm ci; an inherited workflow under
starter/.github/ remains an example rather than an active root workflow.
Recorded verification:
| Check | Status |
|---|---|
| Earlier candidate local checks | Dated synthetic evidence in LOCAL_VALIDATION.md |
| M1/M2 local checks and source review | 217 local checks; source T2 PASS, code reused unchanged |
| Hosted instance recovery, October 12 | PASS on 5bf4d6eb…; platform internal eviction cause not exposed |
| Hosted MiniMax M3 chat, October 13 | Two turns, three model attempts, five INFO units |
| Native React Stop, October 14 | PASS on 48a2dead…: one trusted Stop, same-request Cancel, server PARENT_ABORT, stable terminal receipt |
| Persisted-history Clear, October 13 | PASS on 483bac7a…: one trusted Clear and a persisted empty-history read; consumed claims preserved |
| Active model-binding cleanup, October 14 | Verified on fbaf6495…; Reader/operator/namespace/modules retained by metadata |
| New release-tree Linux CI / template publication | Check the exact commit's Linux CI and release record; private validation is separate |
The October 14 Stop sample used one M3 attempt, zero metered reads and an observed Reader INFO counter delta of zero under the exclusive-use window. Three in-flight text frames arrived after Stop and before the final response; none followed final. Token totals and cash charges after abort are unknown. The test does not prove immediate provider cancellation or that billing stopped. History was retained on October 14; its Clear result belongs to October 13.
The active validation Worker no longer has MODEL_API_KEY after the
fbaf6495… cleanup. That does not prove erasure from historical Cloudflare
versions or the model provider. The public runtime source is unchanged; the
private wrappers and evidence are excluded. These dated hosted samples do not
establish every model, customer deployment, useful match, retention or paid
value. Linux CI, clean installation and release approval are separate gates.
Consumed validation runs are not replayed.
The historical September local browser smoke used SDK 1.2.0 and MiniMax M3
after adapter normalization. It verified the old SDK identity tool against
/me. It does not validate this SDK 2.0.0 / six-tool MCP candidate, model
adoption, hosted Worker operation, or every provider. See
LOCAL_VALIDATION.md for the dated evidence boundaries.
The locked native SDK must receive the current single-page tool catalog so all output validators remain installed. A paginated tool catalog is rejected until a compatibility review; Mission/search result pagination is unchanged. A missing output schema also blocks the affected read.