Static source inference · medium confidence · detected: Logging
Deprecated protocol patterns detected
Summary
This server exposes 22 tools for Cloudinary asset management. Critical deficiencies: (1) Tool naming is inconsistent and overly verbose, tools like 'assetsRenameAsset', 'assetRelationsCreateAssetRelationsByAssetId', 'foldersUpdateFolder' use redundant prefixes that violate verb_noun clarity (pattern:tool). The naming convention makes it harder for LLMs to parse intent. (2) Descriptions are generic and lack context. Most tools have 1-2 sentence descriptions (e.g., 'Rename an asset', 'Delete a folder') that do NOT explain WHEN to use them, WHAT they return, or any prerequisites, violating pattern:tool-description. (3) Parameter schemas are largely invisible in the source provided. Only 3 tools show input schemas (assetsDownloadAsset, assetsDestroyByAssetId, assetsDerivedDestroy); the remaining 19 tools have schemas inferred from file paths but not visible. (4) No output schemas documented anywhere. LLMs cannot reason about what fields to expect or plan downstream calls. (5) Error handling is absent from the tool code samples, no recovery guidance, no categorization, no actionable messages. (6) No evidence of permission gates, audit trails, or secret injection patterns despite tools like 'assetsDestroyByAssetId' and 'foldersDestroyFolder' being destructive. Baseline expectation for 22 tools: average description 194 chars (observed ~50 chars), 100% of params described (observed ~30%), all schemas visible (observed ~14%). This server falls well below production baselines.
Tool naming violates verb_noun clarity. Names like 'assetsRenameAsset', 'assetRelationsCreateAssetRelationsByAssetId', and 'foldersCreateFolder' use redundant resource prefixes that obscure the action. LLMs cannot quickly parse intent from overly long, repetitive names. Names should be concise and action-first: rename_asset, create_asset_relation, create_folder.
Rename all tools to follow verb_noun_object pattern: uploadUpload → upload_asset, assetsRenameAsset → rename_asset, assetRelationsCreateAssetRelationsByAssetId → create_asset_relation, foldersCreateFolder → create_folder. This improves LLM parsing of intent and reduces naming confusion.
Expand all tool descriptions to 100 - 200 characters following pattern:tool-description baseline. Each description must answer: (1) What does it do? (2) When/why should the LLM call it? (3) What does it return? (4) Any prerequisites? Example: 'List all image assets in the cloud account, ordered by creation date. Call this first to discover asset IDs before updating or deleting. Returns array of {asset_id, public_id, url, created_at, width, height}. Paginated: use limit and offset parameters.'
Extract and document all input and output schemas in JSON Schema format. Make them visible in the tool registration code or a schema.json companion file. For each parameter, include: type, description (50+ chars), constraints (min/max for numbers, enum for constrained values), and examples. For outputs, document all returned fields with types and descriptions.
Add pagination support to list/search tools (assetsListImages, assetsListVideos, searchSearchAssets, searchVisualSearchAssets, foldersSearchFolders). Include limit (default 20, max 100), offset, and total_count in responses. Document in descriptions: 'Results are paginated. Default limit is 20 items per call. Use offset to fetch additional pages. Returns total_count to calculate remaining results.'
Spec posture evidence
Inferred effective spec: <=2025-11-25.
Relies on Logging (deprecated) - log to stderr or use OpenTelemetry
19 of 22 tools lack visible input schemas. Only assetsDownloadAsset, assetsDestroyByAssetId, and assetsDerivedDestroy expose schemas in the provided code. The remaining tools have schemas inferred from file paths but not visible in the source. This prevents LLMs from understanding parameter types, constraints, and required fields.
Tool descriptions are generic and under 25 characters on average. Examples: 'Upload an asset' (15 chars), 'Rename an asset' (15 chars), 'Delete a folder' (15 chars). These do NOT explain WHEN to use the tool, WHAT it returns, required prerequisites, or dependencies. Per pattern:tool-description baseline (194 chars avg), descriptions should explain context, not just restate the action. Current descriptions prevent LLM tool selection reasoning.
No output schemas or return-value documentation visible. LLMs cannot reason about what fields a tool returns or plan downstream calls that depend on those fields. For example, after calling assetsListImages, what field contains the asset IDs needed for assetsDestroyByAssetId? This is not documented, forcing LLMs to guess or make extra lookup calls.
Destructive tools (assetsDestroyByAssetId, assetsDerivedDestroy, foldersDestroyFolder) have no confirmation or dry-run support. Agents cannot safely preview the impact before committing irreversible deletions. No error guidance if deletion fails. Violates pattern:confirmation-request and pattern:recovery-guide.
No evidence of permission gates, audit trails, or scope declarations. Destructive and sensitive tools (delete, update, upload) lack security documentation. No indication of RBAC, audit logging, or rate limiting. Violates pattern:permission-gate, pattern:scope-declaration, and pattern:audit-trail.
No error handling guidance visible in tool implementations. Error responses likely return raw API errors or stack traces rather than actionable messages telling LLMs what to do next. Violates pattern:recovery-guide and pattern:error-classification.
Parameters lack type definitions and descriptions in most tools. Tools like assetsRenameAsset, assetsGenerateArchive, foldersUpdateFolder have no visible schemas, making it impossible to know what parameters they accept or what types are valid.
Implement error handling with recovery guidance. For each tool, catch errors and return structured responses: {isError: true, content: [{type: 'text', text: 'Invalid asset_id: XYZ. Call assetsListImages() to discover valid asset IDs.'}]}. For destructive tools (delete, update), always provide the option to list affected resources first.
Add dry-run or confirmation flow for destructive tools (assetsDestroyByAssetId, assetsDerivedDestroy, foldersDestroyFolder). Implement Multi Round-Trip Requests (MRTRs) using result 'input_required' to ask for confirmation before executing irreversible operations.
Document all tool security requirements: which scopes/permissions each requires (e.g., 'read:assets', 'delete:assets'), whether it's idempotent (safe to retry), whether it's read-only, and whether it requires audit logging. Add this to tool descriptions and implement permission gates.
For tools that return asset/folder IDs, ensure output includes all IDs needed by downstream tools. For example, assetsListImages should return asset_id AND public_id if both are needed by update and delete tools. Document field relationships.
Add tool annotations (destructiveHint, readOnlyHint, idempotentHint) to tool definitions. Example: assetsDestroyByAssetId should have destructiveHint=true; assetsListImages should have readOnlyHint=true. This enables MCP clients to warn users or prevent accidental destructive operations.
Validate all inputs before calling downstream APIs. Return clear validation errors: 'cloud_name must be 1-64 alphanumeric characters; got: "invalid name"'. This lets LLMs self-correct in one retry instead of hitting API errors.