MCP server for managing structured content items with support for drafts, publishing, and normalization from WordPress/Drupal sources
Invert has 9 well-structured tools with complete input schemas and descriptions. Naming follows verb_noun convention (invert_list, invert_get, invert_create, etc.). All tools have descriptions (avg ~120 chars, within 10-1024 range). Input parameters are typed and described. However, output schemas are not documented in the source, the code shows return types (e.g. Promise<InvertContent[]>) but no explicit schema definitions visible to the LLM. Error handling is minimal: no recovery guidance, no categorization of retryable vs fatal errors. The invert_normalize_and_create tool combines two concerns (fetch + normalize + create), violating single-responsibility. Parameter descriptions lack format constraints (e.g., slug format, date format). No tool annotations (readOnlyHint, destructiveHint) despite clear risk levels.
Create a new content item. Set status to "draft" to write to .drafts/ (gitignored, never deployed); omit or set to "published" to write to content/ (committed and deployed).
Delete a content item.
Get a single content item by type and slug.
List content items, optionally filtered by type.
Normalize raw content returned by a WordPress or Drupal source MCP and import it as Invert content. The AI fetches from the source MCP, then passes the raw result here — field mapping is handled in code, not in the AI reasoning chain.
Promote a draft to published: moves it from .drafts/ to content/ and sets status to "published". The file will be picked up by git on the next commit.
Output schemas not documented. Code shows return types (InvertContent[], {path: string}, etc.) but no explicit schema definitions visible to LLM. LLMs cannot plan downstream tool calls or extract fields without documented output structure.
No error handling guidance. Tools return null or {deleted: false} on failure, but do not explain what went wrong or what the LLM should do next. No recovery hints (e.g., 'Try search_types() first' if contentType is invalid).
invert_normalize_and_create violates single-responsibility: it fetches from source MCP, normalizes, and creates in one call. Should split into separate tools (fetch_from_source, normalize_content, create_content) so agent can compose them.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 58 | 2026-07-28+ | v2 |
Full-text search across all content (title, body, excerpt).
List all available content types.
Update an existing content item. Changing status between "draft" and "published" moves the file between .drafts/ and content/.
Parameter descriptions lack format constraints. 'slug' has no pattern (e.g., lowercase alphanumeric + hyphens). 'date' has no format (ISO 8601?). 'limit' and 'offset' have no min/max bounds. LLMs cannot validate inputs without explicit constraints.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint). Risk levels are documented in the spec (READ_ONLY, WRITE, DESTRUCTIVE) but not exposed to the LLM via annotations. LLMs cannot reason about side effects or retry safety.