A Model Context Protocol (MCP) server that integrates with Joplin notes, allowing AI clients (like Perplexity) to access and manipulate your notebooks and notes through Joplin's Web Clipper API.
- π Search Functionality: Search notes and notebooks
- π Content Reading: Get complete content of specific notes
- π Creation Features: Create new notes and notebooks
- ποΈ Deletion Features: Delete notes and notebooks (supports trash or permanent deletion)
- π Move Functionality: Move notes to different notebooks
- π List Functionality: List all notebooks and notes within specific notebooks
- Joplin Desktop - Ensure it's installed and running
- Node.js 18+ - Required to run the MCP server
- Web Clipper Enabled - Enable Web Clipper service in Joplin
- Open Joplin desktop application
- Go to Tools β Options β Web Clipper
- Check Enable Web Clipper Service
- Note the port number displayed (usually 41184)
- Copy the API Token (if authentication is required)
# Clone or download this project
cd mcp-joplin
# Install dependencies
npm install
# Compile TypeScript
npm run build# Run directly (will auto-detect Joplin service)
npm start
# Or specify port
npm start -- --port 41184
# Or specify token (if needed)
npm start -- --token YOUR_API_TOKEN
# View help
npm start -- --help# Global installation (recommended)
npm install -g .
# Then use anywhere
npx mcp-joplin
# Or run locally
npx . --port 41184Add the following configuration to your MCP client configuration file:
This MCP server requires a Joplin API token to function properly:
{
"mcpServers": {
"joplin": {
"command": "npx",
"args": [
"/ABSOLUTE/PATH/TO/mcp-joplin",
"--port",
"41184",
"--token",
"YOUR_API_TOKEN"
]
}
}
}π‘ Important: The API token is required for this MCP server to work properly.
In ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"joplin": {
"command": "npx",
"args": [
"/Users/yourusername/path/to/mcp-joplin",
"--token",
"YOUR_API_TOKEN"
]
}
}
}Get the complete content of a specific note
Parameters: noteId (string) - The ID of the note
Search for notes
Parameters:
- query (string) - Search keywords
- limit (number, optional) - Result limit (default: 20)
Search for notebooks
Parameters: query (string) - Search keywords
List all notebooks
Parameters: None
List notes in a specific notebook
Parameters:
- notebookId (string) - The ID of the notebook
- limit (number, optional) - Result limit (default: 50)
List sub-notebooks within a specific notebook
Parameters:
- parentNotebookId (string) - The ID of the parent notebook
Create a new note
Parameters:
- title (string) - Note title
- body (string) - Note content (Markdown format)
- notebookId (string, optional) - Target notebook ID
Create a new notebook
Parameters:
- title (string) - Notebook title
- parentId (string, optional) - Parent notebook ID (for sub-notebooks)
Delete a note
Parameters:
- noteId (string) - ID of the note to delete
- permanent (boolean, optional) - Whether to permanently delete (default: false, moves to trash)
Delete a notebook
Parameters:
- notebookId (string) - ID of the notebook to delete
- permanent (boolean, optional) - Whether to permanently delete (default: false, moves to trash)
Move a note to a different notebook
Parameters:
- noteId (string) - ID of the note to move
- targetNotebookId (string) - Target notebook ID
List sub-notebooks within a specific notebook
Parameters:
- parentNotebookId (string) - The ID of the parent notebook
Scan notebooks and sub-notebooks for uncompleted todo items (- [ ])
Parameters:
- notebookId (string) - ID of the notebook to scan
- includeSubNotebooks (boolean, optional) - Whether to recursively scan sub-notebooks (default: true)
You: "Search for notes containing 'Python'"
AI: Using search_notes tool to search for relevant notes...
You: "Create a new notebook called 'Learning Plan'"
AI: Using create_notebook tool to create a new notebook...
You: "Create a note about JavaScript in the Learning Plan notebook"
AI: Using list_notebooks to find the notebook ID, then using create_note to create the note...
You: "Show the complete content of a specific note"
AI: Using get_note_content tool to retrieve note content...
You: "Scan my project notebook for all uncompleted todo items"
AI: Using scan_unchecked_items tool to scan all sub-notebooks...
-
Confirm Joplin is running
- Joplin desktop application must remain open
-
Check Web Clipper settings
- Ensure Web Clipper service is enabled
- Check port settings (default 41184)
-
View error messages
# Use verbose mode to see errors DEBUG=* npm start
- "Joplin Web Clipper service not found": Ensure Joplin is running and Web Clipper is enabled
- "Connection refused": Check if port settings are correct
- "Unauthorized" or "403 Forbidden": API token is required (see instructions below)
API Token is required for this MCP server to function properly.
- In Joplin go to Tools β Options β Web Clipper
- Copy the displayed token
- Add
--token YOUR_TOKENto the startup command
# Run in development mode
npm run dev
# Compile
npm run build
# Prepare for publishing
npm run prepublishOnly- Language: TypeScript/Node.js
- MCP SDK: @modelcontextprotocol/sdk
- HTTP Client: axios
- CLI: commander
- API: Joplin Web Clipper API
- Notebook Search: Due to limitations in Joplin's search API for folder searches, we use client-side filtering to implement notebook search functionality
- Pagination Handling: Automatically handles Joplin API's pagination mechanism (default 100 items per page), ensuring complete notebook and note lists are retrieved, solving the issue of incomplete sub-notebook display
- Error Handling: Complete error handling mechanism, including Joplin API errors and network connection errors
- Auto-detection: Supports automatic detection of Joplin Web Clipper port (41184-41194)
MIT License
Issues and Pull Requests are welcome!
If you encounter problems, please:
- Check if Joplin Web Clipper is running normally
- Review error messages and logs
- Submit an Issue with detailed error information