MCP server for managing Squidex CMS content and schemas from AI agents
Strong foundation with 18 well-named tools following verb_noun convention (language_list, asset_upload, content_create, schema_publish). All tools have descriptions (avg 180 chars, within 10-1024 baseline). Input schemas use Zod with type definitions and parameter descriptions. However, output schemas are not documented, responses are inferred from code (jsonResult wrapper). Error handling is basic; no recovery guidance or error categorization. Missing tool annotations (readOnlyHint, destructiveHint). Some parameter descriptions could be more prescriptive about constraints and formats.
Get a single asset's metadata (file name, mime type, size, slug) by id.
List/query assets in a Squidex app's asset library — use asset_get's id (or an asset field's value) to reference an existing asset from content, or check what's already uploaded before asset_upload.
Upload a new asset — needed before a content item's Assets field can reference it. Provide exactly one of filePath (reads a local file) or url (Squidex fetches it server-side).
Change a content item's workflow status (e.g. publish or archive it).
Create a new content item.
Delete a content item.
Output schemas not documented. Tool responses are wrapped in jsonResult() but no schema is declared for callers. LLMs cannot plan downstream tool calls without knowing what fields to expect.
Missing tool annotations. No readOnlyHint, destructiveHint, or idempotentHint declared. Agents cannot distinguish safe reads from destructive writes (delete, publish) without reading descriptions.
Error handling lacks recovery guidance. No categorization of errors as retryable vs user-fixable. asset_upload validation error 'requires exactly one of filePath or url' is good, but most tools have no visible error handling.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 61 | <=2025-11-25 | v2 |
Get a single content item by id.
Query content items of a schema using OData-style parameters.
Replace a content item's field data.
List the languages configured for a Squidex app. content_create/content_update must partition localized fields by these iso2Code values (e.g. { "en": ..., "de": ... }) — call this before writing content with localized fields instead of guessing which languages are configured.
List configured Squidex profile names (never secrets), so an agent can discover which instances are available.
Add a field to a schema. Set parentId (the parent field's fieldId, from schema_get) to add a nested field under an existing Array/Component field instead of a root field.
Create a new content schema. Squidex creates schemas in Draft by default and content_create/content_update reject drafts — pass isPublished:true, or call schema_publish afterwards.
Delete a schema — for discarding a failed design iteration. Irreversible; permanent:true also deletes its content instead of soft-deleting.
Get a schema's full field definitions, including each field's id and localization mode — use this before content_create/content_update to shape the data payload correctly, and before schema_add_field/schema_update_field to find parentId/fieldId.
List content schemas available in a Squidex app.
Publish a schema. Squidex creates schemas in Draft by default and rejects content_create/content_update against an unpublished schema.
Replace a field's properties. Get the field's fieldId (and parentId, for nested fields) from schema_get.
Parameter descriptions lack prescriptive constraints. 'OData $filter expression' and 'OData $orderby expression' are vague, no examples of valid syntax or common patterns. LLMs may hallucinate invalid OData.
No pagination guidance in list tools. asset_list and content_query accept top/skip but no documentation of default limits, max results, or when to paginate. Large result sets risk context window exhaustion.