Abilities

Create Post

lh-mcp-general-abilities/create-post

Creates a new post or page as a draft. Content is supplied as one of: Markdown (content_md) or HTML (content_html), converted to Gutenberg block markup before saving; or serialized block markup (content_blocks, or content_blocks_base64 when the site firewall blocks the request), saved exactly as sent after checking it parses to blocks that are registered on this site. Always a draft: there is no status parameter, and nothing created here is publicly visible until a human publishes it. Only the post types on the writable allowlist (post and page by default) can be created – other content types have their own purpose-built abilities. Returns the new ID plus an edit link, reports every block type in the saved content and any content that degraded to a generic block wrapper, and confirms the stored content matches what was sent. Requires edit_posts, plus the post type's create_posts capability.

ParameterTypeRequiredDefaultDescription
post_typestringNo"post"Post type to create. Defaults to "post". Must be on the writable allowlist – post and page by default.
titlestringYesPost title.
content_mdstringNoBody content as Markdown. Converted to Gutenberg block markup before saving. Use only one of content_md, content_html, content_blocks or content_blocks_base64.
content_htmlstringNoBody content as HTML. Converted to Gutenberg block markup before saving. Use this rather than content_md when the content needs layout, media, buttons or other structure Markdown cannot express – call lh-mcp-content-transformer/get-pattern-guide to learn which HTML shapes produce which blocks. HTML that already contains block comments is refused here; send it as content_blocks. Use only one of content_md, content_html, content_blocks or content_blocks_base64.
content_blocksstringNoBody content as serialized block markup (<!– wp:name {…} –>…<!– /wp:name –>), saved exactly as sent with no conversion. Use it for custom blocks, nested inner blocks, block bindings or anything else the converter cannot produce. It must contain at least one block and no HTML outside block comments (send plain HTML as content_html). Every block name must be registered on this site unless allow_unregistered is true. Use only one of content_md, content_html, content_blocks or content_blocks_base64.
content_blocks_base64stringNocontent_blocks, base64-encoded. Use it when the markup is blocked by the firewall on this site, which rejects some request bodies (for example ones containing SQL keywords). Same rules as content_blocks once decoded.
allow_unregisteredbooleanNofalseWith content_blocks or content_blocks_base64, save even if some block names are not registered on this site. Off by default, because an unregistered name is usually a typo or an inactive plugin and saves as an invalid block. Ignored with content_md and content_html.
excerptstringNoPlain-text excerpt.
post_parentintegerNoParent post ID. Accepted only from the parent types list-post-types reports as parent_types for this post type: by default a hierarchical type takes a parent of its own type and any other type takes none, and plugins can allow other parent types. The parent must exist, not be in the trash, and be readable by the caller; it need not be a draft. Passing a parent where none is allowed is an error rather than a silently ignored field. 0 means no parent.
metaobjectNoPost meta as key => value. Protected keys (those starting with an underscore) are refused unless registered with show_in_rest. A null value deletes the key.
termsobjectNoTaxonomy => array of term slugs or term IDs, e.g. {"category": ["news"], "post_tag": ["touch", "season-2026"]}. Replaces the post's terms in each taxonomy named; taxonomies not named are left alone. Terms must already exist – none are created.

Get Post

lh-mcp-general-abilities/get-post Read-only Idempotent

Retrieve a full post of any post type by ID or slug. Returns its type, parent, author, every taxonomy's terms, attachment file details where relevant, the raw stored content, and a Markdown rendering produced by LH Content Converter. If content_markdown is null, markdown_source says why and notice says what to do — content_raw is always complete regardless. A slug shared by more than one post returns a 409 listing the candidates; repeat with id or post_type. Requires edit_posts for the post type, plus read_post on the post.

ParameterTypeRequiredDefaultDescription
idintegerNoPost ID. Either id or slug is required; id wins if both are given.
slugstringNoPost slug. Either id or slug is required.
post_typestringNoOnly used with slug: the post type to look in. Default: every type in the default readable set (see list-post-types).

Get Site Info

lh-mcp-general-abilities/get-site-info Read-only Idempotent

Returns public site information: title, tagline, home URL, charset, and language. Everything it returns is already public, so it is a simple way to test a connection. No capability required; open to anyone.

ParameterTypeRequiredDefaultDescription
fieldsarray of stringNoOptional subset of fields to return. Available: name, description, url, charset, language. Defaults to all.

List MCP Resources

lh-mcp-general-abilities/list-mcp-resources Read-only Idempotent

Lists all publicly registered MCP resource-typed abilities (name, uri, description, mimeType). Resources are application-controlled per the MCP spec and on every current Claude surface require explicit human action to attach (Connectors panel / @-mention) – this ability lets the model discover them on its own. Pair with read-mcp-resource to retrieve the content of a specific one. Requires edit_posts.

ParameterTypeRequiredDefaultDescription
_stringNoUnused. This ability takes no parameters.

List Post Types

lh-mcp-general-abilities/list-post-types Read-only Idempotent

Returns registered post types (public ones by default) with name, labels, REST base and editor support, plus what the current caller can do with each: in_default_set (covered by list-posts when post_type is omitted), can_read (list-posts and get-post will serve it; read_post is still checked per post), can_write (create-post will accept it) and parent_types (the post types create-post and update-post accept as its post_parent). Requires edit_posts.

ParameterTypeRequiredDefaultDescription
include_privatebooleanNofalseInclude non-public post types. Default false.

List Posts

lh-mcp-general-abilities/list-posts Read-only Idempotent

Lists posts across one or more post types, with phrase search, status filtering, ordering, pagination and field subsetting. post_type, status and search all take arrays. Omit post_type to cover every type in the default readable set (list-post-types reports in_default_set and can_read per type). Each search entry is a phrase matched against title, excerpt and content, and entries are OR-ed, so pass synonyms together (e.g. ["AGM", "annual general meeting"]). status takes any registered status, custom ones included; default any. Each result is checked against read_post: withheld counts posts dropped on this page, and total can overstate by that much. Requires edit_posts, plus the edit_posts capability of each post type listed.

ParameterTypeRequiredDefaultDescription
post_typearray of stringNoPost types to list. Omit for every type in the default readable set. Types the caller cannot edit are dropped and reported in skipped_post_types.
statusarray of stringNoPost statuses to include: any registered status, including custom ones such as restrict or archive, or "any". Default ["any"], which excludes trash and auto-draft.
searcharray of stringNoPhrases to search for, OR-ed together. Each phrase is matched as a whole, case-insensitively, against title, excerpt and content.
orderbystringNo"date"Sort order: date or modified (newest first), or title (A-Z). Default date. One of: date, modified, title.
per_pageintegerNo20Results per page. Default 20, max 100.
pageintegerNo1Page number (1-based).
fieldsarray of stringNoSubset of fields to return. Available: id, type, title, slug, link, status, date, modified, excerpt, parent, author. Defaults to: id, type, title, slug, link, status, date.

Read MCP Resource

lh-mcp-general-abilities/read-mcp-resource Read-only Idempotent

Reads the content of a public MCP resource-typed ability by uri (as listed by list-mcp-resources). Invokes the target ability exactly as the MCP resources/read handler does: its own permission_callback via check_permissions(), then its execute_callback via execute() with no arguments. Requires edit_posts, plus whatever the target resource's own permission check requires.

ParameterTypeRequiredDefaultDescription
uristringYesThe resource URI to read, as returned by list-mcp-resources.

Update Post

lh-mcp-general-abilities/update-post Destructive Idempotent

Revises an existing draft or pending post. Only the fields supplied are changed; anything omitted is left alone. Refuses any post that is already published or otherwise live – use lh-agora/propose-changes for those, which routes through human review. There is no status parameter, so this can never publish anything. Content is supplied as one of: Markdown (content_md) or HTML (content_html), converted to Gutenberg block markup before saving; or serialized block markup (content_blocks, or content_blocks_base64 when the site firewall blocks the request), saved exactly as sent after checking it parses to blocks that are registered on this site. The response reports every block type in the saved content and confirms the stored content matches what was sent. Use get-post first to read the current content. Requires edit_posts, plus edit_post on the post.

ParameterTypeRequiredDefaultDescription
post_idintegerYesID of the post to revise. Must currently be a draft, pending, or auto-draft.
titlestringNoNew title. Omit to leave the existing title unchanged.
content_mdstringNoBody content as Markdown. Converted to Gutenberg block markup before saving. Use only one of content_md, content_html, content_blocks or content_blocks_base64.
content_htmlstringNoBody content as HTML. Converted to Gutenberg block markup before saving. Use this rather than content_md when the content needs layout, media, buttons or other structure Markdown cannot express – call lh-mcp-content-transformer/get-pattern-guide to learn which HTML shapes produce which blocks. HTML that already contains block comments is refused here; send it as content_blocks. Use only one of content_md, content_html, content_blocks or content_blocks_base64.
content_blocksstringNoBody content as serialized block markup (<!– wp:name {…} –>…<!– /wp:name –>), saved exactly as sent with no conversion. Use it for custom blocks, nested inner blocks, block bindings or anything else the converter cannot produce. It must contain at least one block and no HTML outside block comments (send plain HTML as content_html). Every block name must be registered on this site unless allow_unregistered is true. Use only one of content_md, content_html, content_blocks or content_blocks_base64.
content_blocks_base64stringNocontent_blocks, base64-encoded. Use it when the markup is blocked by the firewall on this site, which rejects some request bodies (for example ones containing SQL keywords). Same rules as content_blocks once decoded.
allow_unregisteredbooleanNofalseWith content_blocks or content_blocks_base64, save even if some block names are not registered on this site. Off by default, because an unregistered name is usually a typo or an inactive plugin and saves as an invalid block. Ignored with content_md and content_html.
excerptstringNoPlain-text excerpt.
post_parentintegerNoParent post ID. Accepted only from the parent types list-post-types reports as parent_types for this post type: by default a hierarchical type takes a parent of its own type and any other type takes none, and plugins can allow other parent types. The parent must exist, not be in the trash, and be readable by the caller; it need not be a draft. Passing a parent where none is allowed is an error rather than a silently ignored field. 0 means no parent.
metaobjectNoPost meta as key => value. Protected keys (those starting with an underscore) are refused unless registered with show_in_rest. A null value deletes the key.
termsobjectNoTaxonomy => array of term slugs or term IDs, e.g. {"category": ["news"], "post_tag": ["touch", "season-2026"]}. Replaces the post's terms in each taxonomy named; taxonomies not named are left alone. Terms must already exist – none are created.