An agent is a TypeScript function with declared powers
Flue defines an agent as a function marked with 'use agent'. Inside it, hooks select a model, attach tools and skills, choose a sandbox, and return instructions. That puts the operating boundary in code review: a maintainer can see which filesystem, API actions, and specialist subagents the model receives. The repository splits those concerns across 6 named packages for runtime, Vite, CLI, client SDK, OpenTelemetry, and Postgres.
This approach suits agents that do work over time rather than answer one prompt. Conversations can accept messages from an HTTP client, scheduled trigger, channel, or application dispatch. Slack, Teams, Discord, and GitHub are documented channel targets. MCP servers can add remote tools, while first-party tools use typed definitions. The framework also exposes observer and tracing paths instead of leaving model calls hidden inside an application route.
Accepted work has a recovery contract with limits
Flue records a submission before model work begins and returns a 202 receipt. Its durability guide says accepted work must settle as completed, failed, or aborted. Interrupted attempts can recover from stored conversation evidence, and durable tools divide side effects into named steps. The default budget is 10 attempts and one hour per submission, both configurable on the agent.
That contract does not make arbitrary effects exactly once. The docs describe execution as at least once with exactly-once recording. A payment, message, or outside database write still needs an idempotency strategy. On Node.js, the default in-memory store also disappears with the process, so restart recovery requires a durable adapter such as the Postgres package. Cloudflare uses a Durable Object and its storage for each conversation. Workspace persistence remains a separate sandbox decision.
What happened when we ran it
Our sandbox installed 1,292 pnpm packages in 28 seconds, consuming 1,520 MB on disk. The build completed successfully in 159 seconds. Vitest then finished in 15 seconds with 7 passed and 0 failed. Those numbers make the initial trial predictable, but they also show that Flue is a platform-sized dependency rather than a small helper around a model client.
The checkout contained 1,006 files, roughly 85,828 source lines, and occupied 11.9 MB before installation. It is a workspace monorepo with 3 CI workflow files. Our scan found no Dockerfile and no tests directory, even though the provided Vitest command found and passed 7 cases. The passing checks are good evidence for commit 6285b0e; seven cases cannot exercise every provider, sandbox, recovery path, and deployment target in that codebase.
No vulnerability count was supplied by our lab run, so this review makes no audit claim. The useful finding is narrower: installation, build, and the available tests all completed in the stated Node 22 container. Teams should add integration tests around their chosen model, database, sandbox, and target because those combinations determine behavior that a root monorepo check cannot prove for them.
The local sandbox runs directly on the Node host
Flue's sandbox choices differ sharply. Its virtual Bash environment is in memory, starts empty, and restricts network access unless URLs are allowed. The Node local() adapter runs commands as real host processes and uses the real filesystem. The guide explicitly says it is not an isolation boundary for untrusted requests or multiple tenants. Only selected environment variables pass by default, but operators can still hand the model secrets through configuration.
Remote adapters cover providers such as Daytona, E2B, Modal, Vercel, and Cloudflare. They can give each conversation a separate workspace and reconnect by agent instance ID. Provider behavior varies. Some SDKs stop a command when cancelled, while others only reject the caller and leave remote work running. Open issue 720 reports a specific Cloudflare adapter case where the caller's abort signal is not forwarded and the underlying command continues occupying its slot.
MCP tools arrive with trust and context costs
A call to useMcpConnection() discovers a server's tools and mounts them under names that avoid collisions. Flue supports static service tokens or a function that supplies a changing user token, but it does not own the OAuth flow, token store, or refresh logic. An allowlist can keep a large server from adding every tool to the model's context. That is worth using for cost as well as access control.
Release 2.1.0 preserves MCP annotations such as read-only or destructive hints on adapted tools. The documentation is careful about their meaning: server-supplied hints are not a security boundary unless the application trusts that server. Tool descriptions and results also enter the conversation, so connecting an unknown server expands the prompt-injection surface. Wrap or filter tools in trusted application code when an annotation affects approval.
Cloudflare support still has visible client seams
Open issue 665 says Cloudflare conversation streams do not forward incremental tool-input data to browser clients. For a long generated tool argument, the reporter measured 3 to 4 minutes with no visible progress while the observer API could see deltas. Issue 721 describes a separate Anthropic beta-client mismatch after overriding a dependency to 0.85.x. Both reports name exact paths and remain open, which makes them useful adoption tests rather than vague complaints.
The project is moving quickly around those edges. GitHub showed 8,300 stars, 33 open issues and pull requests combined, and a last push on September 18, 2026. The @flue/cli@2.1.0 release shipped that day with tool timeouts, MCP annotation documentation, and tracing-budget controls. If your agent needs the durability and sandbox contracts Flue provides, the passing 159-second build earns a serious trial. Budget the 1,520 MB install and test the exact Cloudflare or Node path before committing production work to it.

