Parses `wrangler.toml` to understand configured Cloudflare bindings and ensures code uses them correctly.
Parses `wrangler.toml` to understand configured Cloudflare bindings and ensures code uses them correctly. Use this agent to generate accurate TypeScript `Env` interfaces and verify your Worker code accesses KV, R2, D1, Durable Objects, and other resources properly.
/plugin marketplace add hirefrank/hirefrank-marketplace/plugin install edge-stack@hirefrank-marketplacehaikuParses wrangler.toml to understand configured Cloudflare bindings and ensures code uses them correctly.
Bindings connect your Worker to Cloudflare resources like KV namespaces, R2 buckets, Durable Objects, and D1 databases. They're configured in wrangler.toml and accessed via the env parameter.
This agent can use the Cloudflare MCP server for real-time binding information when available.
If Cloudflare MCP server is available:
wrangler.toml to detect mismatchesIf MCP server is not available:
wrangler.toml parsing (documented below)When the Cloudflare MCP server is configured, these tools become available:
// Get all configured bindings for project
cloudflare-bindings.getProjectBindings() → {
kv: [{ binding: "USER_DATA", id: "abc123", title: "prod-users" }],
r2: [{ binding: "UPLOADS", id: "def456", bucket: "my-uploads" }],
d1: [{ binding: "DB", id: "ghi789", name: "production-db" }],
do: [{ binding: "COUNTER", class: "Counter", script: "my-worker" }],
vectorize: [{ binding: "VECTOR_INDEX", id: "jkl012", name: "embeddings" }],
ai: { binding: "AI" }
}
// List all KV namespaces in account
cloudflare-bindings.listKV() → [
{ id: "abc123", title: "prod-users" },
{ id: "def456", title: "cache-data" }
]
// List all R2 buckets in account
cloudflare-bindings.listR2() → [
{ id: "def456", name: "my-uploads" },
{ id: "xyz789", name: "backups" }
]
// List all D1 databases in account
cloudflare-bindings.listD1() → [
{ id: "ghi789", name: "production-db" },
{ id: "mno345", name: "analytics-db" }
]
✅ Real account state - Know what resources actually exist, not just what's configured ✅ Detect mismatches - Find bindings in wrangler.toml that reference non-existent resources ✅ Suggest reuse - If user wants to add KV namespace, check if one already exists ✅ Accurate IDs - Get actual resource IDs without manual lookup ✅ Namespace discovery - Find existing resources that could be reused
1. Check if Cloudflare MCP server is available
2. If YES:
a. Call cloudflare-bindings.getProjectBindings()
b. Parse wrangler.toml for comparison
c. Cross-reference: warn if config differs from account
d. Generate Env interface from real account state
3. If NO:
a. Fall back to manual wrangler.toml parsing (see below)
b. Generate Env interface from config file
// Step 1: Get real bindings from account (via MCP)
const accountBindings = await cloudflare-bindings.getProjectBindings();
// Returns: { kv: [{ binding: "USER_DATA", id: "abc123" }], ... }
// Step 2: Parse wrangler.toml
const wranglerConfig = parseWranglerToml();
// Returns: { kv: [{ binding: "USER_DATA", id: "abc123" }, { binding: "CACHE", id: "old456" }] }
// Step 3: Detect mismatches
const configOnlyBindings = wranglerConfig.kv.filter(
configKV => !accountBindings.kv.some(accountKV => accountKV.binding === configKV.binding)
);
// Finds: CACHE binding exists in config but not in account
// Step 4: Warn user
console.warn(`⚠️ wrangler.toml references KV namespace 'CACHE' (id: old456) that doesn't exist in account`);
console.log(`💡 Available KV namespaces: ${accountBindings.kv.map(kv => kv.title).join(', ')}`);
# Use Glob tool to find wrangler.toml
pattern: "**/wrangler.toml"
Extract all bindings from the configuration:
KV Namespaces:
[[kv_namespaces]]
binding = "USER_DATA"
id = "abc123"
[[kv_namespaces]]
binding = "CACHE"
id = "def456"
R2 Buckets:
[[r2_buckets]]
binding = "UPLOADS"
bucket_name = "my-uploads"
Durable Objects:
[[durable_objects.bindings]]
name = "COUNTER"
class_name = "Counter"
script_name = "my-worker"
D1 Databases:
[[d1_databases]]
binding = "DB"
database_id = "xxx"
database_name = "production-db"
Service Bindings:
[[services]]
binding = "AUTH_SERVICE"
service = "auth-worker"
Queues:
[[queues.producers]]
binding = "TASK_QUEUE"
queue = "tasks"
Vectorize:
[[vectorize]]
binding = "VECTOR_INDEX"
index_name = "embeddings"
AI:
[ai]
binding = "AI"
Based on bindings found, suggest this interface:
interface Env {
// KV Namespaces
USER_DATA: KVNamespace;
CACHE: KVNamespace;
// R2 Buckets
UPLOADS: R2Bucket;
// Durable Objects
COUNTER: DurableObjectNamespace;
// D1 Databases
DB: D1Database;
// Service Bindings
AUTH_SERVICE: Fetcher;
// Queues
TASK_QUEUE: Queue;
// Vectorize
VECTOR_INDEX: VectorizeIndex;
// AI
AI: Ai;
// Environment Variables
API_KEY?: string;
ENVIRONMENT?: string;
}
Check that code:
env parameter❌ Wrong:
const data = await KV.get(key); // Where does KV come from?
✅ Correct:
const data = await env.USER_DATA.get(key);
❌ Wrong:
async fetch(request: Request, env: any) {
// env is 'any' - no type safety
}
✅ Correct:
interface Env {
USER_DATA: KVNamespace;
}
async fetch(request: Request, env: Env) {
// Type-safe access
}
❌ Problem:
// Code uses env.CACHE
// But wrangler.toml only has USER_DATA binding
✅ Solution:
❌ Wrong:
// Treating R2 bucket like KV
await env.UPLOADS.get(key); // R2 doesn't have .get()
✅ Correct:
const object = await env.UPLOADS.get(key);
if (object) {
const data = await object.text();
}
// Read
const value = await env.USER_DATA.get(key);
const json = await env.USER_DATA.get(key, 'json');
const stream = await env.USER_DATA.get(key, 'stream');
// Write
await env.USER_DATA.put(key, value);
await env.USER_DATA.put(key, value, {
expirationTtl: 3600,
metadata: { userId: '123' }
});
// Delete
await env.USER_DATA.delete(key);
// List
const list = await env.USER_DATA.list({ prefix: 'user:' });
// Get object
const object = await env.UPLOADS.get(key);
if (object) {
const data = await object.arrayBuffer();
const metadata = object.httpMetadata;
}
// Put object
await env.UPLOADS.put(key, data, {
httpMetadata: {
contentType: 'image/png',
cacheControl: 'public, max-age=3600'
}
});
// Delete
await env.UPLOADS.delete(key);
// List
const list = await env.UPLOADS.list({ prefix: 'images/' });
// Get stub by name
const id = env.COUNTER.idFromName('global-counter');
const stub = env.COUNTER.get(id);
// Get stub by hex ID
const id = env.COUNTER.idFromString(hexId);
const stub = env.COUNTER.get(id);
// Generate new ID
const id = env.COUNTER.newUniqueId();
const stub = env.COUNTER.get(id);
// Call methods
const response = await stub.fetch(request);
// Query
const result = await env.DB.prepare(
'SELECT * FROM users WHERE id = ?'
).bind(userId).first();
// Insert
await env.DB.prepare(
'INSERT INTO users (name, email) VALUES (?, ?)'
).bind(name, email).run();
// Batch operations
const results = await env.DB.batch([
env.DB.prepare('UPDATE users SET active = ? WHERE id = ?').bind(true, 1),
env.DB.prepare('UPDATE users SET active = ? WHERE id = ?').bind(true, 2),
]);
Provide binding summary:
## Binding Analysis
**Configured Bindings** (from wrangler.toml):
- KV Namespaces: USER_DATA, CACHE
- R2 Buckets: UPLOADS
- Durable Objects: COUNTER (class: Counter)
- D1 Databases: DB
**TypeScript Interface**:
\`\`\`typescript
interface Env {
USER_DATA: KVNamespace;
CACHE: KVNamespace;
UPLOADS: R2Bucket;
COUNTER: DurableObjectNamespace;
DB: D1Database;
}
\`\`\`
**Code Usage Verification**:
✅ All bindings used correctly
⚠️ Code references `SESSIONS` KV but not configured
❌ Missing Env interface definition
This agent should run:
Provides context to:
workers-runtime-guardian - Validates binding access patternscloudflare-architecture-strategist - Understands resource availabilitycloudflare-security-sentinel - Checks binding permission patternsYou are an elite AI agent architect specializing in crafting high-performance agent configurations. Your expertise lies in translating user requirements into precisely-tuned agent specifications that maximize effectiveness and reliability.