Skip to main content
Glama

Search Notes

search_notes
Read-only

Searches Apple Notes by title or content.

Paginated: limit is capped at 100 per call, so page with offset instead of asking for a bigger limit. The response carries total (how many notes match the query in all) and has_more, so a capped page is never mistaken for the complete answer — page until has_more is false, which is exact even when total_is_estimated says the count is only a lower bound. To walk every match, pass order="id" — see the order parameter.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
limitNoMatches per page (default 20, capped at 100). To get more, page with offset.20
orderNoorder: "modified" (default) sorts newest-modified first — what you want to SHOW someone, but NOT safe for paging: modification date changes, so a note edited between two calls jumps to the front and another note is pushed past your cursor and never returned. "id" sorts by the note's immutable store id — stable, never renumbered, new notes append at the end — so use order="id" to walk an entire library page by page: edits and insertions mid-crawl are safe with it. One case it cannot cover, because pages are addressed by offset: if a note is DELETED mid-crawl, every note after the hole shifts one slot back and the note that was on the page boundary is skipped, silently. If completeness matters, re-run the crawl and reconcile against total, or crawl while nothing is deleting notes.modified
queryYesText to look for. Matches a note's title or its snippet (the opening of the body), NOT the full body — a word that appears only deep inside a long note will not be found. Must not be empty.
offsetNoHow many matches to skip (default 0). An offset past the end returns an empty page with has_more=false, not an error.0

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
countNoMatches in THIS page
orderNoThe ordering actually applied (modified | id)
queryNo
totalNoMatches in total, ignoring limit/offset. A LOWER BOUND, not the exact figure, when total_is_estimated is true
offsetNoWhere this page started
resultsNo
has_moreNoTrue when matches remain past this page — call again with offset = offset + count
next_actionsNo
total_is_estimatedNoTrue when the exact count could not be taken (the unbounded COUNT failed, or the JXA fallback answered) — total is then only a lower bound. has_more stays exact either way: page until it is false, never until count reaches total

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • addedInput schema / properties / query / description
      Added value: +"Text to look for. Matches a note's title or its snippet (the opening of the body), NOT the full body — a word that appears only deep inside a long note will not be found. Must not be empty."
  2. Changed1 schema field changed
    • removedInput schema / properties / query / description
      Removed value: -"Text to look for. Matches a note's title or its snippet (the opening of the body), NOT the full body — a word that appears only deep inside a long note will not be found. Must not be empty."
  3. Changed1 schema field changed
    • addedInput schema / properties / query / description
      Added value: +"Text to look for. Matches a note's title or its snippet (the opening of the body), NOT the full body — a word that appears only deep inside a long note will not be found. Must not be empty."
  4. Changed9 schema fields changed
    • addedInput schema / properties / limit / description
      Added value: +"Matches per page (default 20, capped at 100). To get more, page with offset."
    • addedInput schema / properties / offset
      Added value: +{
      +  "default": "0",
      +  "description": "How many matches to skip (default 0). An offset past the end returns an empty page with has_more=false, not an error.",
      +  "minimum": 0,
      +  "type": "integer"
      +}
    • addedInput schema / properties / order
      Added value: +{
      +  "default": "modified",
      +  "description": "order: \"modified\" (default) sorts newest-modified first — what you want to SHOW someone, but NOT safe for paging: modification date changes, so a note edited between two calls jumps to the front and another note is pushed past your cursor and never returned. \"id\" sorts by the note's immutable store id — stable, never renumbered, new notes append at the end — so use order=\"id\" to walk an entire library page by page: edits and insertions mid-crawl are safe with it. One case it cannot cover, because pages are addressed by offset: if a note is DELETED mid-crawl, every note after the hole shifts one slot back and the note that was on the page boundary is skipped, silently. If completeness matters, re-run the crawl and reconcile against total, or crawl while nothing is deleting notes.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / count / description
      Added value: +"Matches in THIS page"
    • addedOutput schema / properties / has_more
      Added value: +{
      +  "description": "True when matches remain past this page — call again with offset = offset + count",
      +  "type": "boolean"
      +}
    • addedOutput schema / properties / offset
      Added value: +{
      +  "description": "Where this page started",
      +  "type": "integer"
      +}
    • addedOutput schema / properties / order
      Added value: +{
      +  "description": "The ordering actually applied (modified | id)",
      +  "type": "string"
      +}
    • addedOutput schema / properties / total
      Added value: +{
      +  "description": "Matches in total, ignoring limit/offset. A LOWER BOUND, not the exact figure, when total_is_estimated is true",
      +  "type": "integer"
      +}
    • addedOutput schema / properties / total_is_estimated
      Added value: +{
      +  "description": "True when the exact count could not be taken (the unbounded COUNT failed, or the JXA fallback answered) — total is then only a lower bound. has_more stays exact either way: page until it is false, never until count reaches total",
      +  "type": "boolean"
      +}
  5. First observed

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and destructiveHint, so the description adds substantial behavioral detail beyond them: the 100-call limit cap, total/has_more semantics, order stability for paging, and the deletion-hole edge case. This is exactly the kind of behavior an agent needs to know for correct execution, going well beyond the safety annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but tightly packed: each sentence conveys essential caveats (pagination, estimation, deletion). The opening sentence clearly states the purpose, and the subsequent details are necessary for correct usage. Slightly verbose but not wasteful.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (pagination, ordering pitfalls), the description covers all critical aspects: limit capping, total/has_more, order stability, and deletion behavior. An output schema exists to describe return values, so nothing needed for correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with rich descriptions per parameter (e.g., the order parameter explains modified vs id stability). The overall description reiterates the limit cap and adds strategic advice like using order="id" for crawling, but the schema already carries most of the meaning. Marginal added value beyond the schema, so a baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'Searches Apple Notes by title or content,' specifying the verb and resource. It distinguishes itself from sibling tools like list_notes (which lists all notes) and read_note (which reads a specific note), making the purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides extensive usage guidance on pagination and ordering ('page until has_more is false', 'pass order="id"' to walk every match). It implies this tool is for searching notes by query but does not explicitly contrast with alternatives like list_notes, so when-to-use versus not is partially implicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources