Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 104 additions & 15 deletions examples/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Each example should focus on **one feature or concept** (e.g., MCP servers, emai

## All examples are full-stack

Every example has both a frontend and a backend. This makes them immediately runnable and visually demonstrable — users can `npm run dev` and see the feature in action, not just read server logs.
Every example has both a frontend and a backend. This makes them immediately runnable and visually demonstrable — users can `npm start` and see the feature in action, not just read server logs.

All examples use the [Cloudflare Vite plugin](https://developers.cloudflare.com/workers/vite-plugin/) for development and builds.

Expand All @@ -22,37 +22,85 @@ example-name/
tsconfig.json # must extend ../../tsconfig.base.json
index.html # Vite entry point
README.md # What this example demonstrates, how to run it
public/
favicon.ico # Cloudflare favicon
src/
server.ts # Worker entry point
client.tsx # React client entry
styles.css # Kumo + Tailwind imports
```

## Conventions

### Scripts

Use `start` (not `dev`) for the development server:

```json
{
"scripts": {
"start": "vite dev",
"deploy": "vite build && wrangler deploy",
"types": "wrangler types env.d.ts --include-runtime false"
}
}
```

### wrangler.jsonc

- Use `wrangler.jsonc` (not `.toml`)
- Include `"$schema": "../../node_modules/wrangler/config-schema.json"`
- `compatibility_date: "2026-01-28"`, `compatibility_flags: ["nodejs_compat"]`
- Full-stack apps with client routing: add `"assets": { "not_found_handling": "single-page-application" }`
- Use `"run_worker_first"` to route API/agent paths to the Worker
- Do not set `"directory"` in assets — the Vite plugin handles this

### vite.config.ts

Every example must use both the React and Cloudflare Vite plugins:
Every example must use the React, Cloudflare, and Tailwind Vite plugins:

```ts
import { cloudflare } from "@cloudflare/vite-plugin";
import react from "@vitejs/plugin-react";
import tailwindcss from "@tailwindcss/vite";
import { defineConfig } from "vite";

export default defineConfig({
plugins: [react(), cloudflare()]
plugins: [react(), cloudflare(), tailwindcss()]
});
```

### index.html

Include the theme flash prevention script and favicon:

```html
<!doctype html>
<html lang="en" data-theme="workers">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" href="/favicon.ico" />
<title>Example Title</title>
<script>
(() => {
const stored = localStorage.getItem("theme");
const mode = stored || "light";
document.documentElement.setAttribute("data-mode", mode);
document.documentElement.style.colorScheme = mode;
})();
</script>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/client.tsx"></script>
</body>
</html>
```

### tsconfig.json

Extend the base config. Only add overrides when the example genuinely needs them (e.g., JSX for React examples):
Extend the base config:

```json
{
Expand All @@ -64,8 +112,6 @@ Extend the base config. Only add overrides when the example genuinely needs them

Generated by `npx wrangler types`. Do not hand-edit. Regenerate when bindings change.

Examples using `worker-configuration.d.ts` instead should be migrated to `env.d.ts`.

### .env.example

If the example needs secrets (API keys, etc.), include a `.env.example` showing what keys are needed:
Expand All @@ -74,17 +120,18 @@ If the example needs secrets (API keys, etc.), include a `.env.example` showing
OPENAI_API_KEY=your-key-here
```

Never commit actual secrets. Prefer `.env` / `.env.example` over `.dev.vars` / `.dev.vars.example`.
Never commit actual secrets. Use `.env` / `.env.example` (not `.dev.vars` / `.dev.vars.example`).

### UI — Kumo + agents-ui

All examples use [Kumo](https://kumo-ui.com/) (`@cloudflare/kumo`) for components and `@cloudflare/agents-ui` for shared cross-example UI. **Always check agents-ui before building something custom** — if it handles connection status, theme toggling, or branding, use the package.

#### Kumo basics

- Use Kumo components (`Button`, `Input`, `Surface`, `Text`, `Badge`, `Empty`, etc.) instead of hand-rolled HTML
- Use Kumo components (`Button`, `Surface`, `Text`, `Badge`, `Empty`, etc.) instead of hand-rolled HTML
- Use `@phosphor-icons/react` for icons (Kumo's icon library)
- Use Kumo semantic color tokens (`text-kumo-default`, `bg-kumo-base`, `border-kumo-line`, etc.) instead of raw Tailwind colors
- `Text` does not accept a `className` prop — wrap in a `<span>` if you need custom classes
- Use the `data-mode` attribute for dark mode — no `dark:` Tailwind variants
- Set `data-theme="workers"` on `<html>` for the Cloudflare-branded color theme

Expand All @@ -94,6 +141,7 @@ All examples use [Kumo](https://kumo-ui.com/) (`@cloudflare/kumo`) for component
@import "tailwindcss";
@import "@cloudflare/kumo/styles/tailwind";
@import "@cloudflare/agents-ui/theme/workers.css";
@source "../../../node_modules/@cloudflare/kumo/dist/**/*.{js,jsx,ts,tsx}";
```

#### `@cloudflare/agents-ui` — required shared components
Expand All @@ -109,6 +157,50 @@ Don't re-implement connection indicators, theme toggles, or branding — import

See `/design/visuals.md` for detailed Kumo usage patterns and known gaps.

#### Explainer section

Every example should include an info card at the top of the page explaining what the demo shows. Use the consistent pattern:

```tsx
<Surface className="p-4 rounded-xl ring ring-kumo-line">
<div className="flex gap-3">
<InfoIcon
size={20}
weight="bold"
className="text-kumo-accent shrink-0 mt-0.5"
/>
<div>
<Text size="sm" bold>
Title
</Text>
<span className="mt-1 block">
<Text size="xs" variant="secondary">
Description of what this demo shows and how to use it.
</Text>
</span>
</div>
</div>
</Surface>
```

### Agent communication

Prefer `@callable` methods + `useAgent`/`agent.call()` over manual `onRequest`/`agentFetch` or raw WebSocket messages:

```typescript
// server.ts
export class MyAgent extends Agent {
@callable()
async doSomething(arg: string) {
return { result: arg };
}
}

// client.tsx
const agent = useAgent({ agent: "my-agent", name: sessionId });
const result = await agent.call("doSomething", ["hello"]);
```

### Dependencies

- Keep example-specific dependencies minimal — these ship as learning material
Expand All @@ -120,17 +212,14 @@ See `/design/visuals.md` for detailed Kumo usage patterns and known gaps.
Every example needs one. Keep it short:

1. One sentence: what this example demonstrates
2. How to run it (`npm install && npm run dev`)
2. How to run it (`npm install && npm start`)
3. Any required env vars
4. Link to relevant SDK docs in `/docs` if applicable
4. Code snippets showing the key pattern
5. Links to related examples

## Known issues to clean up

See `TODO.md` in this folder for the full checklist.

- Several examples are worker-only and need a frontend added: `email-agent/`, `mcp-elicitation/`, `mcp-server/`, `mcp-worker/`, `mcp-worker-authenticated/`, `x402/`, `x402-mcp/`
- `email-agent/` is worker-only and needs a frontend
- `cross-domain/` has a `vite.config.ts` but does not use `@cloudflare/vite-plugin`
- `x402/` is missing README.md
- `x402/` and `x402-mcp/` use `worker-configuration.d.ts` instead of `env.d.ts`
- `codemode/` uses `.env.example` instead of `.dev.vars.example`
- Some full-stack examples set `assets.directory: "public"` — not needed with the Vite plugin
50 changes: 26 additions & 24 deletions examples/TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,54 +5,44 @@ Tracked issues from the examples audit. See `AGENTS.md` in this folder for the c
## Missing README.md

- [x] `resumable-stream-chat/` — add README
- [ ] `x402/` — add README
- [x] `x402/` — add README

## Add frontend + Vite plugin

All examples must be full-stack (frontend + backend). These worker-only examples need a frontend, `index.html`, `vite.config.ts`, and `src/client.tsx` added:

- [ ] `email-agent/` — add frontend demonstrating the email feature
- [ ] `mcp-elicitation/` — add frontend demonstrating MCP elicitation
- [ ] `mcp-server/` — add frontend demonstrating the MCP server
- [ ] `mcp-worker/` — add frontend demonstrating the MCP worker
- [ ] `mcp-worker-authenticated/` — add frontend demonstrating authenticated MCP
- [ ] `x402/` — add frontend demonstrating x402 payments
- [ ] `x402-mcp/` — add frontend demonstrating x402 MCP
- [x] `mcp-elicitation/` — added landing page with connection instructions
- [x] ~~`mcp-server/`~~removed (redundant with `mcp-worker/`)
- [x] `mcp-worker/` — added MCP tool tester frontend
- [x] `mcp-worker-authenticated/` — added info page with endpoint docs
- [x] `x402/` — added React+Kumo frontend with "Fetch & Pay" UI
- [x] `x402-mcp/` — added React+Kumo frontend with tool forms and payment modal

## Vite plugin fix

- [ ] `cross-domain/` — add `@cloudflare/vite-plugin` to existing `vite.config.ts` (currently uses `@vitejs/plugin-react` only)

## Type declarations

- [ ] `x402/` — rename `worker-configuration.d.ts` to `env.d.ts`, regenerate with `npx wrangler types`
- [ ] `x402-mcp/` — rename `worker-configuration.d.ts` to `env.d.ts`, regenerate with `npx wrangler types`
- [x] `x402/` — renamed `worker-configuration.d.ts` to `env.d.ts`, regenerated
- [x] `x402-mcp/` — renamed `worker-configuration.d.ts` to `env.d.ts`, regenerated

## Missing env.d.ts

- [ ] `a2a/` — generate `env.d.ts` with `npx wrangler types`
- [ ] `email-agent/` — generate `env.d.ts` with `npx wrangler types`
- [ ] `mcp-worker-authenticated/` — generate `env.d.ts` with `npx wrangler types`
- [x] `mcp-worker-authenticated/` — generated `env.d.ts`

## Secrets examples

Standardise on `.env` / `.env.example` (not `.dev.vars` / `.dev.vars.example`).

- [ ] `github-webhook/` — rename `.dev.vars.example` to `.env.example`
- [ ] `mcp-client/` — rename `.dev.vars.example` to `.env.example`
- [x] `playground/` — rename `.dev.vars.example` to `.env.example`
- [x] `resumable-stream-chat/` — rename `.dev.vars.example` to `.env.example`
- [x] `tictactoe/` — rename `.dev.vars.example` to `.env.example`

## wrangler.jsonc assets cleanup

Remove unnecessary `"directory"` from assets — the Vite plugin handles the build output directory automatically.

- [ ] `codemode/wrangler.jsonc` — remove `"directory": "public"` from assets
- [ ] `github-webhook/wrangler.jsonc` — remove `"directory": "public"` from assets
- [x] `tictactoe/wrangler.jsonc` — remove `"directory": "public"` from assets
- [ ] `workflows/wrangler.jsonc` — remove `"directory": "public"` from assets
- [ ] `resumable-stream-chat/wrangler.jsonc` — remove `"directory": "dist"` and `"binding": "ASSETS"`, align with standard pattern
- [x] `mcp-client/` — renamed `.dev.vars.example` to `.env.example`
- [x] `playground/` — renamed `.dev.vars.example` to `.env.example`
- [x] `resumable-stream-chat/` — renamed `.dev.vars.example` to `.env.example`
- [x] `tictactoe/` — renamed `.dev.vars.example` to `.env.example`

## SPA routing

Expand All @@ -62,3 +52,15 @@ Check which full-stack examples with client-side routing are missing `"not_found
- [ ] `github-webhook/` — audit whether it needs SPA fallback
- [x] `tictactoe/` — no client-side routing, not needed
- [ ] `workflows/` — audit whether it needs SPA fallback

## Kumo + agents-ui migration

Migrate examples to use Kumo components, agents-ui shared UI, and Tailwind.

- [x] `mcp/` — migrated from Hello World to full Kumo tool tester
- [x] `mcp-client/` — migrated from custom CSS to Kumo, replaced agentFetch with @callable
- [x] `mcp-worker/` — added Kumo frontend
- [x] `mcp-worker-authenticated/` — added Kumo frontend
- [x] `mcp-elicitation/` — added Kumo landing page
- [x] `x402/` — migrated from worker-only to Kumo frontend
- [x] `x402-mcp/` — migrated from inline HTML to React+Kumo, replaced raw WebSocket with useAgent
2 changes: 0 additions & 2 deletions examples/mcp-client/.dev.vars.example

This file was deleted.

4 changes: 4 additions & 0 deletions examples/mcp-client/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Optional: override the auto-detected host for OAuth callbacks.
# Only needed if the callback host differs from the request origin
# (e.g. when deploying behind a custom domain).
HOST=https://my-worker.workers.dev
Loading
Loading