wp_search: search site content
Runs a WordPress search over a post type and returns matching items.
Arguments
| Argument | Default | Meaning |
|---|---|---|
query |
— | The search term |
post_type |
post |
Any public post type |
status |
publish |
Post status to search |
page |
1 | Page number |
per_page |
20 | Items per page, clamped to 1–100 |
Permissions
mcp:read and wp:content:read.
Searching published content needs no further capability. Searching any other status requires edit_posts, or edit_pages for pages.
What it returns
The same shape as wp_get_posts: items and total, with each item carrying id, post_type, title, slug, status, date, modified, link and excerpt.
No content. To read a match in full, call wp_get_post with its ID.
It searches one post type at a time
Despite the name, this is not a site-wide search. It searches within one post type, defaulting to post.
To search across several, call it once per type:
Search posts for "warranty", then search pages for the same term, and show me both sets.
It is WordPress search
The matching is WordPress's own, with its known characteristics: it looks at titles, content and excerpts, does not do fuzzy matching, and its relevance ordering is basic.
If the site runs a search enhancement plugin, MCP results may differ from what a visitor sees — this tool queries WordPress directly rather than going through the site's search page.
Do not treat an empty result as proof a term is absent from the site.
Its most useful job: finding what you are about to change
Before an edit whose target you know by wording rather than by ID:
Search pages for "0800 123 456" and tell me which ones contain it.
That turns "update the phone number everywhere" from an unbounded instruction into a list of IDs you can bound the job to.
The same pattern applies to finding outdated claims, old product names or a term you intend to retire.
Pagination applies
per_page clamps at 100 and total reports the real number of matches. A search returning many results needs paging, and an assistant that acted on "all the matches" from one call acted on at most a hundred.
Using it well
Search posts for "spring campaign" and show me the IDs and titles, then stop.
Search the "project" post type for "Bilbao".
Search drafts for "TODO".
That last one needs the capability for non-published content, and is a genuinely useful audit.
What it does not do
- No cross-type search in one call.
- No content in the results.
- No taxonomy or meta search.
- No replacement. Finding occurrences is a read; changing them is a separate write per item, and should be bounded to the IDs found.
Common problems
| Symptom | Cause |
|---|---|
| No results for a term you can see on the site | The term is in a shortcode attribute or meta, not the searchable content |
| Fewer results than expected | per_page clamps at 100; read total |
| Drafts missing | Default status is publish |
| Results differ from the site's search | A search plugin enhances the front end, not this query |
pom_ai_mcp_forbidden |
Searching unpublished content without the capability |