Joplin MCP Server
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| JOPLIN_HOST | No | Joplin server hostname | localhost |
| JOPLIN_PORT | No | Joplin Web Clipper port | 41184 |
| JOPLIN_TOKEN | Yes | Joplin API authentication token | |
| JOPLIN_TIMEOUT | No | Request timeout in seconds | 30 |
| JOPLIN_NOTEBOOK_ALLOWLIST | No | Comma-separated list of notebook patterns for access control |
Capabilities
Features and capabilities supported by this server
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
| logging | {} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| extensions | {
"io.modelcontextprotocol/ui": {}
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| ping_joplinA | Test connection to Joplin server. Verifies connectivity to the Joplin application. Use to troubleshoot connection issues. Returns: str: Connection status information. |
| get_noteA | Retrieve a note with smart content display and sequential reading support. Smart behavior: Short notes show full content, long notes show TOC only. Sequential reading: Extract specific line ranges for progressive consumption. |
| get_note_resourcesA | List resources attached to a note, including OCR text for images and PDFs. Joplin runs OCR on attached images and PDFs and stores the result on each
resource. This tool exposes that text so an agent reading a note can also
see what's inside its images. Resources without OCR text (audio, plain
files, or images not yet OCRed) are still listed unless |
| get_linksA | Extract all links to other notes from a given note and find backlinks from other notes. Scans the note's content for links in the format text or text and searches for backlinks (other notes that link to this note). Returns link text, target/source note info, section slugs (if present), and line context. Returns: str: Formatted list of outgoing links and backlinks with titles, IDs, section slugs, and line context. Link formats: |
| create_noteA | Create a new note in a specified notebook in Joplin.
|
| update_noteA | Update note properties (title, body, todo status, due date) or move a note to another notebook. Replaces the entire body. Use this for metadata changes, moving a note between notebooks, or full body replacement. For targeted text edits (fix a word, append a line) use edit_note instead — it doesn't require reading first. Notebook can be specified by name or path:
Returns: str: Success message confirming the note was updated. Examples: - update_note("note123", title="New Title") - Update only the title - update_note("note123", body="New content", is_todo=True) - Update content and convert to todo - update_note("note123", notebook_name="Archive") - Move note to the "Archive" notebook - update_note("note123", notebook_name="Projects/Work/Tasks") - Move to a sub-notebook by path - update_note("note123", todo_due="2024-12-31T17:00:00") - Set due date - update_note("note123", todo_due=0) - Clear due date |
| edit_noteA | Precision-edit a note's body without reading or replacing the full content. Preferred over update_note for targeted text changes — no get_note round-trip needed. Use update_note instead when changing metadata (title, todo status, due date) or replacing the entire body. Modes:
|
| find_notesA | Find notes by searching titles and content. Use "*" to list all notes. Query syntax: "exact phrase", title:word, body:word, -exclude, word1 OR word2 Examples: - find_notes("") - List all notes - find_notes("meeting") - Find notes containing "meeting" - find_notes("", task=True) - List all tasks - find_notes("", trash=True) - List trashed (soft-deleted) notes - find_notes("", limit=20, offset=20) - Page 2 TIP: Use find_notes_with_tag() or find_notes_in_notebook() for filtered searches. TIP: Trashed notes can be restored with restore_from_trash(). IMPORTANT: trash=True only works with query="*" and no task/completed filters. Joplin's search API does not index trashed notes and ignores include_deleted for filter queries. |
| find_in_noteA | Search for a regex pattern inside a specific note and return paginated matches. Multiline mode is enabled by default so anchors like |
| find_notes_with_tagA | Find all notes that have a specific tag, with pagination support. MAIN FUNCTION FOR TAG SEARCHES! Use this when you want to find all notes tagged with a specific tag name. Returns: str: List of all notes with the specified tag, with pagination information. Examples: - find_notes_with_tag("time-slip") - Find all notes tagged with "time-slip" - find_notes_with_tag("work", limit=10, offset=10) - Find notes tagged with "work" (page 2) - find_notes_with_tag("work", task=True) - Find only tasks tagged with "work" - find_notes_with_tag("important", task=True, completed=False) - Find only uncompleted tasks tagged with "important" |
| find_notes_in_notebookA | Find all notes in a specific notebook, with pagination support. MAIN FUNCTION FOR NOTEBOOK SEARCHES! Use this when you want to find all notes in a specific notebook. Notebook can be specified by name or path:
Returns: str: List of all notes in the specified notebook, with pagination information. Examples: - find_notes_in_notebook("Work Projects") - Find all notes in "Work Projects" - find_notes_in_notebook("Personal Notes", limit=10, offset=10) - Find notes in "Personal Notes" (page 2) - find_notes_in_notebook("Personal Notes", task=True) - Find only tasks in "Personal Notes" - find_notes_in_notebook("Projects", task=True, completed=False) - Find only uncompleted tasks in "Projects" - find_notes_in_notebook("Project A/tasks") - Find notes in "tasks" sub-notebook under "Project A" |
| list_notebooksA | List all notebooks/folders in your Joplin instance. Retrieves and displays all notebooks (folders) in your Joplin application. Returns: str: Formatted list of all notebooks including title, unique ID, parent notebook (if sub-notebook), and creation date. |
| create_notebookA | Create a new notebook (folder) in Joplin to organize your notes. Creates a new notebook that can be used to organize and contain notes. You can create top-level notebooks or sub-notebooks within existing notebooks, optionally with an emoji icon shown in Joplin's sidebar. Notebook can be specified by name or path:
Returns: str: Success message containing the created notebook's title and unique ID. Examples: - create_notebook("Work Projects") - Create a top-level notebook - create_notebook("2024 Projects", "Work") - Create a sub-notebook under "Work" - create_notebook("Tasks", "Projects/Work") - Create a sub-notebook by path - create_notebook("Tasks", emoji="🎯") - Create a notebook with an emoji icon |
| list_tagsA | List all tags in your Joplin instance with note counts. Retrieves and displays all tags that exist in your Joplin application. Tags are labels that can be applied to notes for categorization and organization. Returns: str: Formatted list of all tags including title, unique ID, number of notes tagged with it, and creation date. |
| create_tagA | Create a new tag. Creates a new tag that can be applied to notes for categorization and organization. Returns: str: Success message with the created tag's title and unique ID. Examples: - create_tag("work") - Create a new tag named "work" - create_tag("important") - Create a new tag named "important" |
| get_tags_by_noteA | Get all tags for a specific note. Retrieves all tags that are currently applied to a specific note. Returns: str: Formatted list of tags applied to the note with title, ID, and creation date. |
| tag_noteA | Add one or more tags to one or more notes. Both args accept a single string or a list. When either is a list, the cartesian product is applied (every tag on every note) in one call — preferred over looping. Output: aggregated TAG_NOTE report with TOTAL_OPS / SUCCEEDED / FAILED, one row per (note, tag) pair (so the scalar case is a one-row report). Tags must exist beforehand — use create_tag to add new ones. Missing tags are reported up front and nothing is applied. Per-op failures (e.g. invalid note ID or allowlist denial) are captured in the report; other ops still run. Examples: - tag_note("abc...", "Work") - Tag one note with one tag - tag_note(["abc...", "def..."], "Work") - Tag two notes with one tag - tag_note("abc...", ["Work", "Urgent"]) - Add two tags to one note - tag_note(["abc...", "def..."], ["Work", "Urgent"]) - 2x2 = 4 ops |
| untag_noteA | Remove one or more tags from one or more notes. Both args accept a single string or a list. When either is a list, the cartesian product is applied (remove every tag from every note) in one call. Output: aggregated UNTAG_NOTE report with TOTAL_OPS / SUCCEEDED / FAILED, one row per (note, tag) pair (so the scalar case is a one-row report). Tags must exist (by name). Missing tags are reported up front and nothing is removed. Per-op failures (including allowlist denials) are captured in the report; other ops still run. Examples: - untag_note("abc...", "Work") - Remove one tag from one note - untag_note(["abc...", "def..."], "Work") - Remove one tag from two notes - untag_note("abc...", ["Work", "Urgent"]) - Remove two tags from one note - untag_note(["abc...", "def..."], ["Work", "Urgent"]) - 2x2 = 4 ops |
| restore_from_trashA | Restore a note or notebook from Joplin's trash. Restores a previously deleted item by setting its deleted_time back to 0. The item reappears in its original notebook. Scope of restore (important):
To find descendants to restore after restoring a notebook, use find_notes(query="*", trash=True) and filter to the relevant subtree. Returns: str: Success message confirming the item was restored. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
| get_server_info | Get Joplin server information. |
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/alondmnt/joplin-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server