MCP server for generating images using Replicate's Flux model and uploading them to Cloudflare R2
Single tool 'generate-image' has critical definition gaps. Tool is registered with explicit Zod schema (prompt: string, filename: string), but lacks descriptions on both parameters and the tool itself. Tool description is null/missing entirely. Parameter descriptions are null. Input schema exists but is minimally typed (no constraints, ranges, or format specifications). Output is unstructured text wrapped in a content array, with no documented schema. Error handling returns generic error.message without actionable recovery guidance. Tool performs a destructive/write operation (uploads file to cloud storage) but no error classification, confirmation, or dry-run capability. No tool annotations (destructiveHint absent). This is a minimal, production-unsafe definition.
Tool 'generate-image' has no description. The tool definition in index.js passes null/undefined descriptions to server.tool(). Without a description, LLMs cannot determine when or why to call this tool vs. other image generation tools.
Parameter 'prompt' has null description. Parameter 'filename' has null description. LLMs cannot infer what 'filename' controls (output filename? storage path? file extension?).
Input schema lacks constraints. 'prompt' is unbounded string (no length limits, no guidance on quality). 'filename' is unbounded (no pattern, no extension rules, no validation against path traversal). Zod schema uses z.string() without refinements.
Output schema not documented. Tool returns { content: [{ type: 'text', text: ... }] } but no schema description specifies what fields are in the response, what 'imageUrl' format to expect, or how to extract it for downstream tools.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 33 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 41 | - | v1 |
Tool performs a write operation (uploads to cloud storage, modifies state) but error handling is generic. On failure, returns 'Image generation failed: {error.message}'. No error classification (retryable? user-fixable? fatal?), no recovery guidance, no actionable next step for the LLM.
Destructive tool lacks confirmation. generate-image calls Replicate and uploads to R2 (irreversible side effects) with no dry-run, confirmation step, or rollback capability. An agent mistake results in unwanted images stored permanently.
No tool annotations. Tool definition does not include destructiveHint=true, despite modifying state. LLMs cannot reason about idempotency, retry safety, or whether side effects occur.
Sensitive credentials exposed via environment variables without server-side validation. REPLICATE_API_TOKEN, STORAGE_ACCESS_KEY, STORAGE_SECRET_KEY are read directly in generateImage.js. If a tool parameter were to accept these, they would log in agent traces. Current implementation avoids parameter exposure, but pattern is unsafe.
Tool naming 'generate-image' uses hyphen (kebab-case) instead of underscore (snake_case). Baseline naming convention is verb_noun (e.g., 'generate_image'). LLM tools conventionally use underscores.