# Joplin Search

> Search notes, notebooks, and tags in Joplin

- Skill: `leixinsun/joplin-search` (Agent Skill)
- Install (CLI): `npx skillmds@latest add leixinsun/joplin-search`
- Raw SKILL.md: https://api.skillmd.com/api/skills/leixinsun/joplin-search/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: LeixinSun (https://skillmd.com/u/leixinsun)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/leixinsun/joplin-search

---


# Joplin Search

This skill searches notes, notebooks, and tags in Joplin via the REST API.

## Configuration

- **Base URL**: `http://localhost:${JOPLIN_PORT:-41184}`
- **Auth Token**: `$JOPLIN_TOKEN`

## Basic Search

```bash
curl -s "http://localhost:${JOPLIN_PORT:-41184}/search?query=SEARCH_TERMS&token=$JOPLIN_TOKEN&fields=id,title,body,parent_id,updated_time&limit=20"
```

## Search Operators

| Operator | Example | Description |
|----------|---------|-------------|
| Plain text | `meeting notes` | All words must appear in the note |
| Title only | `title:meeting` | Search only in note titles |
| Notebook | `notebook:Work` | Restrict to a named notebook |
| Tag | `tag:important` | Notes with a specific tag |
| Todo | `type:todo` | Only todo items |
| Completed todo | `iscompleted:1` | Only completed todos |
| Any word | `any:1 cat dog` | Match any word (OR), default is AND |
| Wildcard | `meet*` | Prefix matching |
| Exact phrase | `"exact phrase"` | Match the exact phrase |
| Created date | `created:20240101` | Created on or after date (YYYYMMDD) |
| Updated date | `updated:20240601` | Updated on or after date |
| Latitude | `latitude:40` | Notes with geolocation |
| Longitude | `longitude:-74` | Notes with geolocation |
| Combine | `title:meeting notebook:Work tag:important` | Multiple operators together |

## Search Types

By default, search returns notes. Use the `type` parameter to search other item types:

```bash
# Search notebooks
curl -s "http://localhost:${JOPLIN_PORT:-41184}/search?query=TERM&type=folder&token=$JOPLIN_TOKEN&fields=id,title"

# Search tags
curl -s "http://localhost:${JOPLIN_PORT:-41184}/search?query=TERM&type=tag&token=$JOPLIN_TOKEN&fields=id,title"
```

## Pagination

Search results are paginated. Check `has_more` and increment `page`:

```bash
# Page 1 (default)
curl -s "http://localhost:${JOPLIN_PORT:-41184}/search?query=TERMS&token=$JOPLIN_TOKEN&fields=id,title,updated_time&limit=50&page=1"

# Page 2
curl -s "http://localhost:${JOPLIN_PORT:-41184}/search?query=TERMS&token=$JOPLIN_TOKEN&fields=id,title,updated_time&limit=50&page=2"
```

Response format:
```json
{
  "items": [
    {"id": "abc123", "title": "Meeting Notes", "updated_time": 1700000000000}
  ],
  "has_more": false
}
```

## Workflow

1. Parse the user's search intent and construct the query string.
2. URL-encode the query parameter (spaces become `%20` or `+`).
3. Execute the search.
4. Present results in a clear list: title, notebook (resolve `parent_id` if needed), last updated.
5. If `has_more` is true, ask if the user wants more results.
6. If the user wants to see a specific note's content, fetch it by ID:
   ```bash
   curl -s "http://localhost:${JOPLIN_PORT:-41184}/notes/NOTE_ID?token=$JOPLIN_TOKEN&fields=id,title,body,parent_id,updated_time"
   ```

## Getting Notebook Names for Results

To show notebook names alongside results, fetch notebooks:

```bash
curl -s "http://localhost:${JOPLIN_PORT:-41184}/folders?token=$JOPLIN_TOKEN&fields=id,title"
```

Then map `parent_id` from notes to the notebook `title`.

## Error Handling

- **403**: Invalid token
- **Empty results**: Try broader search terms, remove operators, or use wildcards
- **Connection refused**: Joplin not running

## Tips

- URL-encode special characters in the query: use `--data-urlencode` or `%20` for spaces
- For better results, use `curl -s -G "http://localhost:${JOPLIN_PORT:-41184}/search" --data-urlencode "query=SEARCH TERMS" --data-urlencode "token=$JOPLIN_TOKEN" --data-urlencode "fields=id,title,body,parent_id,updated_time"`
- Limit `fields` to only what you need — omitting `body` makes responses much smaller for listing
- When searching for exact titles, use `title:"exact note title"`

