Content
# WizNote MCP Server
WizNote MCP (Model Context Protocol) server, providing AI with semantic search and knowledge organization, management notes, and "clipping" web pages.
## 24 MCP Tools
| # | Tool | Purpose |
|---|------|------|
| 1 | `wiznote_kb_list` | List knowledge bases |
| 2 | `wiznote_kb_overview` | Knowledge base overview (number of notes + directory structure + number of tags) |
| 3 | `wiznote_category_list` | List folders |
| 4 | `wiznote_category_create` | Create folder |
| 5 | `wiznote_note_list` | List notes (pagination, sorting) |
| 6 | `wiznote_note_get` | Get complete note content |
| 7 | `wiznote_note_create` | Create note |
| 8 | `wiznote_note_update` | Update note / move directory / set tags |
| 9 | `wiznote_note_delete` | Delete note |
| 10 | `wiznote_note_search` | BM25 full-text search (fuzzy / phrase / boolean / chunk) |
| 11 | `wiznote_tag_list` | List all tags |
| 12 | `wiznote_tag_create` | Create tag (support hierarchy) |
| 13 | `wiznote_tag_rename` | Rename tag |
| 14 | `wiznote_tag_delete` | Delete tag |
| 15 | `wiznote_note_list_by_tag` | List notes by tag |
| 16 | `wiznote_clip` | Clip - save original webpage |
| 17 | `wiznote_save_content` | Clip - save after AI processing |
| 18 | `wiznote_batch_read` | Clip - read webpage for AI processing |
| 19 | `wiznote_organize` | Organize notes - list directory notes for classification |
| 20 | `wiznote_note_batch_get` | Batch get note content |
| 21 | `wiznote_export_category` | Export directory as Markdown collection |
| 22 | `wiznote_recent_changes` | Recent change tracking (within N days) |
| 23 | `wiznote_category_rename` | Rename folder |
| 24 | `wiznote_normalize` | Note normalization data preparation |
---
### Operation Type Description
Each tool is divided into three categories based on operation type, which can be enabled/disabled as needed in clients like MCPHub:
| Type | Description | Tool List |
|------|------|---------|
| 🔍 **Read-only** | Query/检索, no modification to notes | `kb_list`, `category_list`, `note_list`, `note_get`, `note_search`, `tag_list`, `note_list_by_tag`, `batch_read`, `organize`, `note_batch_get`, `export_category`, `recent_changes`, `normalize` |
| ✏️ **Write** | Create or modify notes/folders/tags | `category_create`, `note_create`, `note_update`, `tag_create`, `tag_rename`, `clip`, `save_content`, `category_rename` |
| 🗑️ **Delete** | Permanently delete notes or tags | `note_delete`, `tag_delete` |
Each tool's description shows `[Read-only]` / `[Write]` / `[Delete]` prefix, and clients like MCPHub can filter accordingly.
### Scenario Recommendation: AI External Knowledge Base
If you only use this MCP service as an AI external knowledge base (**no modification to notes**), enable the following **13 read-only tools**:
```
Enable: wiznote_kb_list, wiznote_category_list, wiznote_note_list,
wiznote_note_get, wiznote_note_search, wiznote_tag_list,
wiznote_note_list_by_tag, wiznote_batch_read, wiznote_organize,
wiznote_note_batch_get, wiznote_export_category,
wiznote_recent_changes, wiznote_normalize
Disable: wiznote_category_create, wiznote_note_create, wiznote_note_update,
wiznote_tag_create, wiznote_tag_rename, wiznote_tag_delete,
wiznote_clip, wiznote_save_content, wiznote_category_rename,
wiznote_note_delete (10 write/delete tools)
```
Even with a read-only account, AI can query and retrieve note content without triggering any write operations.
---
## Project Features
### 🔍 BM25 Full-Text Search + Chunk-Level RAG
`wiznote_note_search` built-in **Bleve BM25 full-text search engine** (pure Go, zero external dependencies), allowing AI to quickly locate notes through keywords, no longer relying on WizNote server's limited search capabilities.
- **Chinese word segmentation**: support CJK word segmentation, friendly to Chinese content search
- **Fuzzy matching**: tolerate spelling errors (`emb~2` can match `embedding`)
- **Phrase and boolean queries**: support `"exact phrase"` exact matching, `+rust -c++` boolean combination, `title:rust` field limitation
- **Chunk-level search**: add `mode="chunk"` return matching paragraph fragments + title breadcrumbs, AI no need to pull full text to directly read fragments and answer
- **Incremental indexing**: first startup full build index, subsequent intelligent synchronization; create/update/delete notes real-time update chunk
- **Offline available**: index on local service, no dependence on WizNote server search interface
- **Non 24/7 friendly**: service restart millisecond-level recovery
- **Three-layer synchronization engine**: T1 hierarchical probe (default 24h) detect external additions/modifications, T2 directional incremental precise update, T3 statistical sampling detect deletion
- **Automatic cleaning of deleted notes during search**: return search results and then asynchronously verify the existence of TOP 3 notes, deleted notes removed from index
### 🏷️ Tag System
WizNote API native support tag management. Now provide complete tag CRUD:
- List, create, rename, delete tags
- Tags support tree-level hierarchy (through parent tag GUID association)
- List notes by tag
AI when organizing notes, first scan existing tag pool, prefer to reuse existing tags, no match and then create new tags. Tags support multiple tags.
### 📦 Batch Operation
WizNote API itself does not provide batch endpoint, the following tools through client concurrency implementation:
- **Batch get**: input multiple docGuid, concurrent download complete content, return plain text body
- **Directory export**: traverse directory notes, concurrent get body, assemble to Markdown collection
- **Recent changes**: list notes within specified days in reverse order
- **Folder rename**: complete WizNote API existing `PUT /ks/category/rename` endpoint
### 📝 Note Normalization
`wiznote_normalize` provide note normalization data preparation for AI:
- Concurrent get complete body of notes under directory (HTML → Text cleaning)
- Detect title first character is English punctuation (`,` `.` `!` `?` `#` `:` `;` `~`), mark out auto-naming and manual naming notes
- AI accordingly: notes starting with punctuation only add tags do not change title; others generate new title and assign tags according to body
This tool follows **data preparation mode** - only do data acquisition and feature marking, intelligent decision-making completely by AI.
---
## "Clip" Two Working Modes
### Mode 1: Original Webpage Saving
```
User says: "Save this webpage to wiznote"
→ wiznote_clip(urls=[url1, url2])
→ Each URL saved as a separate note
→ Images/CSS/JS all downloaded to local
```
**Tool: `wiznote_clip`**
| Parameter | Description |
|------|------|
| `urls` | One or more URLs, each saved separately |
| `timeout` | Each URL timeout (default 60s, max 600s) |
| `use_browser` | Browser rendering (default true) |
| `category` | Save directory, default `/Webpage Collection/Original Webpage/` |
### Mode 2: AI Processing and Saving
```
User says: "Save this webpage to wiznote with AI processing"
→ wiznote_batch_read(urls=[url1, url2]) ← Read original content
→ AI analyze content, noise reduction, reorganization
→ wiznote_save_content(title, content) ← Save structured notes
→ Multiple URLs merged into one note
```
**Step 1: `wiznote_batch_read`**
| Parameter | Description |
|------|------|
| `urls` | One or more URLs read plain text |
| `timeout` | Each URL timeout (default 60s) |
Return: plain text body (no HTML tags) + image URL list
**Step 2: `wiznote_save_content`**
| Parameter | Description |
|------|------|
| `title` | Note title |
| `content` | Markdown format body (after AI organization) |
| `category` | Save directory, default `/Webpage Collection/AI Processing/` |
| `source_url` | Original link |
| `image_urls` | Image URL list (automatic download) |
---
## Directory Rules
AI automatically decide directory storage location according to user intention:
| User says | AI behavior |
|--------|---------|
| "Save to /Linux directory" | Call `wiznote_category_create` create (if not exist) → save |
| "Store in suitable directory" | Call `wiznote_category_list` view existing directory → match most deep subdirectory according to content |
| "Save to wiznote" (no directory mentioned) | Original webpage → `/Webpage Collection/Original Webpage/`; AI processing → `/Webpage Collection/AI Processing/` |
AI prefer to choose most specific subdirectory (like `/Programming/JAVA/` instead of `/Programming/`).
---
## Organize Notes
### Tool: `wiznote_organize`
When user says "Help me organize wiznote's certain directory", AI through this tool get directory notes list, analyze and classify into suitable folders.
| Parameter | Description |
|------|------|
| `source` | Source directory path (**must be leaf directory without subdirectories**) |
| `target` | Target root directory (optional, default whole directory tree) |
| `count` | Maximum return note number (default 50, max 200) |
### Pre-check (AI mandatory execution)
```
User says: "Help me organize wiznote's /Webpage Collection/Original Webpage/ directory"
↓
AI call wiznote_category_list() check /Webpage Collection/Original Webpage/ has subdirectories
├── Has subdirectories → cancel task, inform user
└── No subdirectories → continue
↓
AI call wiznote_organize(source="/Webpage Collection/Original Webpage/")
→ Get notes list (title + docGuid)
↓
AI analyze each title, determine which directory to put into
↓
AI call wiznote_note_update(docGuid="xxx", category="/target directory/")
→ Move notes one by one
```
### Two Organization Modes
| User says | AI behavior |
|--------|---------|
| "Help me organize wiznote's /Webpage Collection/Original Webpage/ directory" | Find best matching directory in whole directory tree |
| "Help me organize wiznote's /Webpage Collection/Original Webpage/ directory, organize to /Linux directory" | Find best matching in `/Linux/` subdirectory |
### Note Moving
Through `wiznote_note_update`'s `category` parameter realize note moving. Only need to pass new directory path, no need to modify note's HTML content.
---
## Note Normalization
### Tool: `wiznote_normalize`
When user says "Normalize notes in wiznote's certain directory", AI through this workflow execute:
**Workflow:**
```
User says: "Normalize notes in /Webpage Collection/Original Webpage/ directory"
↓
Step 1: AI call wiznote_category_list check directory has subdirectories
├── Has subdirectories → cancel
└── No subdirectories → continue
↓
Step 2: AI call wiznote_tag_list get existing tag pool
↓
Step 3: AI call wiznote_normalize(source="/Webpage Collection/Original Webpage/")
→ Return each note's docGuid, title, body, startsWithPunctuation
↓
Step 4: AI traverse each note:
├── startsWithPunctuation == true (title starts with English punctuation like , . ! ? # : ; ~)
│ └── This note is human-named → only add tags, no title change
│
└── startsWithPunctuation == false
└── Generate new title according to body → call wiznote_note_update(title=new title)
↓
Step 5: AI analyze body content theme, match tags
├── Has similar existing tags → reuse tagGuid
└── No match → call wiznote_tag_create create new tag
↓
Step 6: AI call wiznote_note_update(docGuid, tagGuids="guid1*guid2")
→ Set tags (pipe separated, support multiple tags)
```
**Tool parameters:**
| Parameter | Required | Description |
|------|------|------|
| `source` | ✅ | Source directory path (**must be leaf directory**)|
| `count` | — | Maximum return note number (default 50, max 200)|
| `kbGuid` | — | Knowledge base GUID |
---
> Developers please refer to [ARCHITECTURE.md](./ARCHITECTURE.md) to understand design principles, scheme selection, and implementation details.
## Quick Start
### Method 1: Docker Compose (Recommended)
```bash
# 1. Copy environment variable configuration
cp .env.example .env
# Edit .env, fill in WIZNOTE_USERNAME and WIZNOTE_PASSWORD
# 2. Start
docker compose up --build
# 3. AI client connection
http://localhost:8080/mcp
# 4. CloakBrowser-Manager Web GUI
http://localhost:8081
```
### Method 2: Direct Run
```bash
# Need CloakBrowser-Manager environment
export WIZNOTE_USERNAME=your@email.com
export WIZNOTE_PASSWORD=your_password
export WIZNOTE_INDEX_DIR=./data # BM25 index persistence directory
go build -o wiznote-mcp ./cmd/wiznote-mcp/
./wiznote-mcp
```
### Environment Variables
| Variable | Default value | Description |
|------|--------|------|
| `WIZNOTE_USERNAME` | — | **Required** WizNote account |
| `WIZNOTE_PASSWORD` | — | **Required** WizNote password |
| `WIZNOTE_AS_URL` | `https://as.wiz.cn` | Account server URL (modify when private deployment) |
| `WIZNOTE_PORT` | `8080` | MCP service port |
| `WIZNOTE_INDEX_DIR` | `./data` | BM25 index persistence directory |
| `WIZNOTE_SYNC_CRUD_HOOK` | `true` | T0 CRUD hook switch |
| `WIZNOTE_SYNC_PROBE_INTERVAL_HOURS` | `24` | T1 probe cycle (detect external additions/modifications) |
| `WIZNOTE_SYNC_PROBE_SAMPLE_RATE` | `1.0` | T1 probe sampling rate |
| `WIZNOTE_SYNC_DELETION_INTERVAL_HOURS` | `168` | T3 deletion detection cycle |
| `WIZNOTE_SYNC_DELETION_SAMPLE_COUNT` | `100` | T3 sampling number |
| `WIZNOTE_READ_ONLY` | `false` | Read-only mode (disable all write/delete tools) |
| `WIZNOTE_READ_CATEGORIES` | `["/"]` | Read permission directory range (JSON array, prefix match) |
| `WIZNOTE_WRITE_CATEGORIES` | `["/Webpage Collection/"]` | Write permission directory range (JSON array, prefix match) |
| `HTTPS_PROXY` | — | Proxy (download CloakBrowser) |
| `CLOAKBROWSER_DATA_DIR` | `/data` | Manager profile data directory |
---
## Other Instructions
**This project is for personal research and learning only**
**GitHub**: https://github.com/jiadxin/wiznote-mcp
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
No recommendations available