Overview
search_notes returns notes matching a keyword together with their primary documents (one-pager, custom). Use it when you need the content of the notes, such as decisions or action items.
For lightweight metadata-only listing (e.g., “which notes are in folder X”), use list_notes instead.
When to use
- “What did the team decide about OKR Q2?”
- “Where is the source note for this decision?”
- “Show me the notes that mention 네이버.”
- Keyword required; results ordered by full-text relevance with
createdAtdesc as tiebreaker. - Each matched note carries its primary documents inline (one-pager, custom).
- HTML stripped from document content; documents larger than 5,000 chars are truncated and flagged.
- When the search index is unavailable, a normal response is returned with
degraded: true, an emptynotesarray, anddegradedReason.
A workspace-scoped API key drops notes in private folders from the results even when the keyword matches (What notes a system API key reads).
Parameters
keyword (required)
The search term. Tokenized server-side; Korean text is morphologically analyzed (e.g.,네이버 → [네, 버]). Empty or whitespace-only keywords return 400.
Keyword search accepts both user-scoped and workspace-scoped API keys. Omit workspaceGuid to search across every workspace you can access. A workspace-scoped API key searches only the workspace it is connected to. To scope the search to a specific workspace, pass a workspaceGuid.
filter.folderId (optional)
Same semantics aslist_notes — recursive folder scope, authorized server-side.
filter.createdAtFrom / filter.createdAtTo (optional)
Half-open[from, to) range filter on createdAt. Both accept ISO 8601 UTC datetime ending in Z. It is applied before the relevance-ranked result limit.
For calendar years, months, or days, convert the boundaries from the user’s timezone to UTC. For example, July–August 2025 in Korea Standard Time is createdAtFrom: "2025-06-30T15:00:00Z", createdAtTo: "2025-08-31T15:00:00Z".
pagination (optional)
{ cursor, size }. Default size: 10, max 30. The cap reflects the higher per-result cost (each note carries its documents).
Response Format
Success Response
Degraded Response
When the search index is unavailable, the response setsdegraded=true and returns an empty notes array:
degradedReason is one of:
search_index_unavailable— the search index is disabled in this environment.search_index_degraded— the search index threw an error mid-query.
Usage Examples
Example 1: Topical search
Request:Example 2: Folder-scoped Korean keyword
Request:네이버 only inside folder 455765 (and descendants). Korean morphological analysis runs server-side.
Example 3: Date-bounded deep search
Request:Best Practices
Start with list_notes, switch to search_notes when content is needed
Start with list_notes, switch to search_notes when content is needed
Use
list_notes first to find which notes match. If the LLM still needs document content to answer, switch to search_notes for the same keyword. This is the cheapest progressive-disclosure path.Use folderId to narrow the search universe
Use folderId to narrow the search universe
A folder-scoped search is faster and returns better-ranked results because the relevance space is smaller. Pair with
list_notes(filter.folderId) to find folder candidates first.Don't loop on nextCursor
Don't loop on nextCursor
The deep-search endpoint currently emits
nextCursor: null. If 30 results aren’t enough, refine the keyword (more specific) or scope by folderId/dateRange instead of paginating.Watch the degraded flag
Watch the degraded flag
A
degraded=true response is honest — the search index couldn’t run. Don’t treat the empty notes array as “no matches”; instead, surface the degradation to the user/LLM so retries can be timed appropriately.Common Errors
Empty keyword
keyword must be at least 1 character (zod min(1)). An empty keyword is rejected as a standard MCP validation error, not a custom error code.