↑ ↓ to navigate
↵ to select
esc to close
Guides Intermediate

Full-Text Search

How entry content is indexed and ranked, and how to search it with the MCP search_query tool.

Overview

Airogel CMS keeps a full-text search index of every entry in your account. The index uses English-language stemming and ranks results by relevance. Today the only way to search it is the search_query tool on the MCP server, so you can search from an AI assistant or an MCP client.

Where search is available

SurfaceFull-text search?
MCP tool search_queryYes
REST API (api.airogelcms.com/v1)No. There is no search endpoint. GET …/entries can only filter by handle and published.
Liquid templates and your public siteNo. There is no search tag, filter or public endpoint, so you can't build a visitor-facing search box with built-in features.
Dashboard quick searchMatches titles, handles and file names only. It does not use the full-text index.

What gets indexed

Each entry is indexed as one block of text made up of:

  • Title
  • Handle, with hyphens treated as spaces (so spring-sale matches "spring sale")
  • Text fields
  • Rich Text fields, with HTML tags removed
  • Raw HTML fields, with HTML tags removed

All of these count equally. A match in the title doesn't rank higher than the same match in the body. Other field types (Markdown, enumerate, entity, number, date, image and so on) are not indexed.

The index updates automatically when an entry is created, when its title or handle changes, and when any indexed field is saved or cleared. If you clear a field, its old text stops matching.

How matching works

  • Stemming. Words are reduced to their English root, so "programming" matches "program" and "programs".
  • Every word must match. annual budget report only returns entries that contain all three words (after stemming), in any order and anywhere in the entry.
  • No query syntax. Punctuation is removed before searching, so quotes, OR, -exclude and wildcards have no special meaning. Search for plain words only.
  • Ranking. Results are sorted by relevance, which depends on how often and how close together the terms appear.
  • English only. There is no fuzzy matching or typo tolerance, and results don't include highlighted snippets.

The search_query tool

This tool needs the entries:read scope (or the full mcp scope).

ParameterTypeDescription
account_idstringRequired. The account's acct_… ID, which you can get from accounts_list.
querystringRequired. The words to search for.
collection_handlestringOptional. Only search one collection.
publishedbooleanOptional. true returns published entries only, false returns drafts only, and omitting it returns both.
pageintegerOptional. Page number, starting at 1 (default 1).
per_pageintegerOptional. Results per page (default 25, max 100).

If you leave out published, drafts are included in the results. Pass published: true when you only want content that is live.

Example

{
  "account_id": "acct_XXXXXXXX",
  "query": "volunteer training",
  "collection_handle": "posts",
  "published": true,
  "per_page": 10
}

Response

{
  "page": 1,
  "per_page": 10,
  "total": 2,
  "total_pages": 1,
  "items": [
    {
      "id": "cnety_XXXXXXXX",
      "title": "Volunteer Training Dates",
      "handle": "volunteer-training-dates",
      "collection_handle": "posts",
      "published": true,
      "published_at": "2026-09-01T14:00:00Z",
      "content_path": "/blog/volunteer-training-dates"
    }
  ]
}

content_path is the entry's path on your site. To get the full URL, add your site's domain in front of it.

Related