io.github.seunghan91/ainote
Official34 toolsAgent-native notes, tasks, dev-docs, vaults, sync & handoffs. MCP + OpenAPI dual surface.
Create notes, tasks, and documentation with sync and handoff capabilities.
Captured live from the server via tools/list.
list_tasks
List all tasks from AI Note with advanced filtering, date ranges, location search, and sorting
Parameters (18)
- statusstring
Filter by task status
- is_importantboolean
Filter by important tasks only
- limitnumber
Maximum number of tasks to return (default: 25, max: 500)
- offsetnumber
Number of tasks to skip for pagination (default: 0). Use with limit to fetch additional pages.
- searchstring
Search keyword in task content and notes (case-insensitive partial match)
- locationstring
Filter by location (partial match, e.g., '여의도', '서울')
- category_idstring
Filter by category UUID
- due_date_startstring
Filter tasks with due_date >= this date (ISO 8601 format)
- due_date_endstring
Filter tasks with due_date <= this date (ISO 8601 format)
- completed_date_startstring
Filter tasks completed >= this date (ISO 8601 format)
- completed_date_endstring
Filter tasks completed <= this date (ISO 8601 format)
- created_date_startstring
Filter tasks created >= this date (ISO 8601 format)
- created_date_endstring
Filter tasks created <= this date (ISO 8601 format)
- overdueboolean
Filter overdue incomplete tasks (due_date < today)
- due_todayboolean
Filter tasks due today
- has_notificationboolean
Filter by notification enabled status
- sort_bystring
Sort field (default: created_at)
- sort_orderstring
Sort order (default: desc)
create_task
Create a new task in AI Note. Supports full task creation with dates, times, location, notes, and notifications.
Parameters (16)
- contentstringrequired
Task content (required)
- is_importantboolean
Mark task as important (default: false)
- due_datestring
Due date in ISO format (e.g., '2026-01-28' or '2026-01-28T15:00:00+09:00')
- due_timestring
Due time in HH:MM format (e.g., '15:00'). If not provided, task is treated as all-day.
- start_datestring
Start date for date range tasks in ISO format (e.g., for multi-day events)
- is_all_dayboolean
Mark as all-day event — suppresses time-of-day rendering.
- category_idstring
Category ID (UUID) to organize the task
- notesstring
Additional notes or details for the task
- locationstring
Location where the task takes place
- location_latnumber
GPS latitude. Pair with location_lng.
- location_lngnumber
GPS longitude. Pair with location_lat.
- travel_timenumber
Minutes of travel time to allow before due_date.
- has_notificationboolean
Enable reminder notifications (default: false)
- reminder_timinginteger
Minutes before due time to send reminder (e.g., 10 for 10 minutes before). Default: 30. Only used when has_notification is true.
- reminder_timingsarray
Multiple reminder offsets in minutes before due time (e.g., [10, 60] fires 10 min and 1 hour before). Overrides reminder_timing if provided.
- repeat_rulestring
Recurrence rule (e.g., 'daily', 'weekly', 'monthly', 'yearly', or RRULE format)
update_task
Update an existing task. All fields are optional except id.
Parameters (18)
- idstringrequired
Task ID (required)
- contentstring
New task content
- is_importantboolean
Update important status
- completed_atstring
Mark as completed (ISO format) or 'null' to uncomplete
- due_datestring
Update due date in ISO format (or 'null' to clear)
- due_timestring
Update due time in HH:MM format (or 'null' to make all-day)
- start_datestring
Update start date in ISO format (or 'null' to clear)
- is_all_dayboolean
Toggle all-day mode.
- category_idstring
Update category ID (or 'null' to remove category)
- notesstring
Update notes (or 'null' to clear)
- locationstring
Update location (or 'null' to clear)
- location_latnumber
Update GPS latitude.
- location_lngnumber
Update GPS longitude.
- travel_timenumber
Update travel-time minutes.
- has_notificationboolean
Enable/disable reminder notifications
- reminder_timinginteger
Minutes before due time to send reminder (e.g., 10 for 10 minutes before). Only used when has_notification is true.
- reminder_timingsarray
Multiple reminder offsets in minutes before due time (e.g., [10, 60]). Pass empty array [] to clear.
- repeat_rulestring
Update recurrence rule (or 'null' to make non-recurring)
delete_task
Soft-delete a task by ID. Destructive but reversible within 30 days (TaskCleanupJob purges trash daily at 2am KST). Returns 404 if the task does not exist or is not owned by the authenticated user.
Parameters (1)
- idstringrequired
Task ID to delete
list_categories
List all task categories for the authenticated user. Returns id/name/color/icon/task_count tuples. Read-only — use create_task with category_id to assign tasks to a category.
No parameters.
list_papers
List notes/papers from AI Note. Supports keyword search across title and content, category filtering, pagination, and sorting. Returns id/title/content_preview/category_id/created_at. Use this when the user asks 'find my note about X', 'what did I write on Y', or wants to search their knowledge base.
Parameters (8)
- searchstring
Keyword to match in paper title or content (case-insensitive partial match)
- category_idstring
Filter by category UUID
- paper_category_idstring
Filter by paper-specific folder UUID
- source_typestring
Filter by source type (e.g., 'manual', 'youtube', 'url', 'clipboard')
- limitnumber
Maximum number of papers to return (default: 25, max: 200)
- offsetnumber
Number to skip for pagination (default: 0)
- sort_bystring
Sort field (default: updated_at)
- sort_orderstring
Sort order (default: desc)
list_dev_docs
List dev documents under the dev/ category hierarchy. Filter by subcategory (claude, cursor, windsurf, copilot, docs, etc.), search by title, or filter by content type.
Parameters (3)
- categorystring
Subcategory filter (claude, cursor, windsurf, copilot, docs, etc.). Omit to list all dev docs.
- searchstring
Search keyword in document title
- content_typestring
Filter by content type
get_dev_doc
Get a single dev document by title or id. Returns full content.
Parameters (4)
- titlestring
Document title (e.g., project-a-memory.md)
- idstring
Document UUID
- categorystring
Subcategory (claude, cursor, etc.) to disambiguate title
- include_versionsboolean
Include version history (default: false)
create_dev_doc
Save a document to AI Note cloud for multi-device sync and persistent storage. PRIMARY USE CASES: - Memory files: ~/.claude/projects/.../memory/MEMORY.md (AI context that survives device switches) - AI config files: CLAUDE.md, .cursorrules, .windsurfrules (not in git, local-only) - Local env notes: API keys reference, server credentials (NOT actual secret values) - Project notes: architecture decisions, dev diaries, planning docs MULTI-DEVICE WORKFLOW: Laptop → push: create_dev_doc(title, content, local_path="~/.claude/.../MEMORY.md") Desktop → pull: pull_dev_docs() → automatically writes files to their local paths CATEGORIES (subcategories under dev/): - memory: Claude/AI memory files (~/.claude/projects/.../memory/) - claude: CLAUDE.md files and Claude-specific configs - cursor: .cursorrules files - env: environment notes and config references - docs: general project documentation Set local_path to enable pull_dev_docs auto-sync to this machine.
Parameters (6)
- titlestringrequired
Filename as title (e.g., ainote-memory.md, project-claude.md)
- contentstringrequired
Full file content (markdown, json, yaml, text)
- categorystring
Subcategory: memory | claude | cursor | env | docs | custom. Default: docs
- content_typestring
Content type. Auto-detected from title extension if omitted.
- local_pathstring
Absolute path on this machine (e.g., ~/.claude/projects/-Users-seunghan/memory/MEMORY.md). Used by pull_dev_docs to restore file on other devices. Supports ~ expansion.
- memory_typestring
Memory update semantics: 'state' = latest value replaces the past (used by memory_search latest_state mode), 'event' = immutable accumulating log, 'preference' = user preference. Omit for plain documents.
update_dev_doc
Update an existing dev document. Supports replace (default), append, or prepend modes. Optionally update the local_path for sync.
Parameters (7)
- titlestring
Document title
- idstring
Document UUID
- categorystring
Subcategory to disambiguate title
- contentstringrequired
New content
- modestring
Update mode (default: replace)
- local_pathstring
Update the local file path for multi-device sync
- memory_typestring
Set the memory update semantics (state | event | preference). Pass null/empty to clear.
pull_dev_docs
Restore all synced files to this device. Fetches every dev doc that has a local_path set and writes the content to that path on disk. WHEN TO USE: - First time setup on a new machine (desktop, laptop, etc.) - After reinstalling macOS or setting up a fresh environment - To restore Claude memory files, CLAUDE.md configs, and other local-only files WHAT IT DOES: 1. Fetches all your dev docs that have local_path set 2. Creates any missing parent directories automatically 3. Writes the file content to each local_path on THIS machine 4. Reports success/failure for each file TYPICAL FILES RESTORED: - ~/.claude/projects/.../memory/MEMORY.md (AI context memory) - ~/projects/*/CLAUDE.md (project-specific AI instructions) - .cursorrules, .windsurfrules (editor AI configs) Run this once after setting up ainote MCP on a new device.
Parameters (1)
- categorystring
Subcategory filter. Omit to pull all docs with local_path.
delete_dev_doc
Soft-delete a dev document by title or UUID. Reversible from trash. Pass `category` when multiple docs share the same title across subcategories (memory/claude/cursor/env/docs).
Parameters (3)
- titlestring
Document title
- idstring
Document UUID
- categorystring
Subcategory to disambiguate title
list_dev_categories
List all subcategories under dev/ (memory, claude, cursor, env, docs, mcp, custom...) with document counts. Use to discover which categories exist before calling list_dev_docs with a category filter.
No parameters.
signup_and_get_key
Create a new AI Note account and get an MCP API key. No authentication required. Use this if you don't have an account yet.
Parameters (3)
- emailstringrequired
Email address for the new account
- passwordstringrequired
Password (minimum 6 characters)
- namestring
Display name (optional)
login_and_get_key
Log in to an existing AI Note account and return an MCP API key. No prior authentication required. SIDE EFFECT: if the user has no MCP key yet, this call creates one (write to user.mcp_keys), so it is NOT idempotent and must be gated like other key-creation flows.
Parameters (2)
- emailstringrequired
Your account email address
- passwordstringrequired
Your account password
get_setup_guide
Get instructions for setting up AI Note MCP in Claude Desktop, Cursor, or other MCP clients. No authentication required.
No parameters.
vault_list
List the authenticated user's GitHub-backed vaults. Each entry includes slug, github_repo_full_name, sync status, indexed file count, and is_primary flag. Read-only. Pair with vault_clone to get the git clone URL or vault_sync to read/write vault files.
No parameters.
vault_create
Create a new private vault as a GitHub repository under the user's account. Requires the user to have completed the GitHub App install flow first.
Parameters (2)
- namestringrequired
Vault name. Slug is derived from this value and used as the GitHub repo name.
- descriptionstring
Optional GitHub repo description.
vault_clone
Return the GitHub HTTPS clone URL for an existing vault. Authentication is via the user's normal GitHub credentials (PAT or gh CLI).
Parameters (2)
- namestringrequired
Vault name or slug.
- target_pathstring
Preferred local clone path for the returned instructions.
vault_connect_status
Check whether the user has installed the ainote GitHub App. If connected, returns account_login + installation_id. If not, returns an install_url to surface to the user. Read-only; talks to GitHub API.
No parameters.
vault_sync
Wrapper around vault file sync. action=list|pull|push to work against the primary vault. For push: WAF-bypass via `content_b64` or `content: '__B64__:...'` prefix (mirrors sync_push).
Parameters (5)
- actionstring
Sync action. Default list.
- pathstring
Relative path filter or target file path.
- contentstring
Required for push (or `content_b64`). Prefix with '__B64__:' for WAF bypass.
- content_b64string
Optional: base64-encoded content (use INSTEAD of `content`) for WAF-bypass on large bodies. Server decodes before storing.
- sincestring
ISO 8601 timestamp for incremental pull.
sync_push
Push a markdown file into the primary vault. Optional CAS via base_sha to detect concurrent multi-PC writes (Layer 3 of multi-PC sync plan). WAF-bypass tip: large bodies (~10KB+) that get false-positive blocked at Cloudflare can be sent via `content_b64` (base64-encoded) OR `content` prefixed with `__B64__:` instead.
Parameters (7)
- pathstringrequired
Relative file path (e.g., 'global/MEMORY.md', 'launchcrew/firebase.md'). No leading slash, no '..'.
- contentstring
Full file content (markdown text). Alternatively prefix with '__B64__:' followed by base64 payload for WAF bypass.
- content_b64string
Optional: base64-encoded file content (use INSTEAD of `content`). For WAF-bypass on large bodies. Server decodes before storing. If both supplied, content_b64 wins.
- base_shastring
Optional: git_sha the client last observed for this path. When present, server compares with current git_sha and returns -32009 conflict on mismatch (with current content for 3-way diff). Omit for legacy LWW behavior (response will include a `warning` field nudging clients to upgrade).
- device_idstring
Optional: client device identifier (e.g., from ~/.claude/ainote-sync/device.id). Stored on FileIndex so future conflict responses can report which device last wrote the path.
- forceboolean
Optional: when true, skip CAS check even if base_sha is supplied. Use only for intentional overwrites; presence is auditable via warning logs.
- resolves_conflict_idstring
Optional: UUID of a vault_conflicts row this push resolves. When supplied, server validates ownership/unresolved/path/sha and atomically marks the conflict as resolution=clean inside the same transaction as the file_indices write. Validation failure rolls back the whole push and returns -32009 stale_conflict_id.
sync_pull
Legacy alias for pulling files from the primary vault.
Parameters (2)
- sincestring
ISO 8601 timestamp. Only return files updated after this time. Omit to get all files.
- pathstring
Optional directory filter (e.g., 'global' to pull only global files)
sync_list
Legacy alias for listing files in the primary vault.
Parameters (1)
- pathstring
Directory to list (e.g., 'global'). Omit to list all files.
sync_delete
Delete a file from the primary vault. Optional CAS via base_sha to detect concurrent multi-PC writes. Protected paths (global/memory/, global/skills/, global/planning/, global/claude-config/, handoffs/) require base_sha or explicit force:true (audited). Idempotent: deleting a non-existent path returns success with deleted:false.
Parameters (4)
- pathstringrequired
Relative file path to delete (e.g., 'global/_waf_probe.md'). No leading slash, no '..'.
- base_shastring
Optional: git_sha the client last observed for this path. When present, server compares with current git_sha and returns -32009 conflict on mismatch (with current content for 3-way diff).
- device_idstring
Optional: client device identifier for audit log (e.g., from ~/.claude/ainote-sync/device.id).
- forceboolean
Optional: when true, skip CAS check even if base_sha is supplied. Use only for intentional overwrites; presence is auditable via warning logs.
sync_merge
Compute a stateless 3-way merge for a vault file. Server runs `git merge-file --diff3 --stdout` over (base_text, local_text, current remote from file_indices) and returns the merged text plus the exact remote_sha it merged against. NO database mutation — to commit the result, follow up with sync_push(content=merged_text, base_sha=merged_against.remote_sha, resolves_conflict_id=conflict_id).
Parameters (5)
- pathstringrequired
Relative vault path (e.g., 'global/MEMORY.md').
- base_textstringrequired
Common ancestor text — what the client had cached when it started editing. Source: client state.json baseline. Required.
- base_shastring
Optional: git_sha the client believes is the merge base. When supplied, server verifies (informational; merge still runs).
- local_textstringrequired
Current local text on the client (post-edit). Required.
- device_idstring
Optional: client device identifier. Recorded on any vault_conflict row created downstream.
sync_diff
Return the unified diff (and raw remote text) of a vault file. Useful for surfacing what `sync_merge` would conflict on, or for the client to render a `git diff` view before pushing. NO database mutation. Server has no history — base_text must be supplied by the caller if a 3-way view is needed; otherwise this returns remote_text only.
Parameters (3)
- pathstringrequired
Relative vault path.
- local_textstring
Optional: client's current text. When supplied, response includes unified diff (remote → local).
- base_textstring
Optional: client's baseline (last-known remote). When supplied along with local_text, response includes both diffs (base → remote, base → local) so the client can render a 3-way view.
sync_pending_conflicts
List unresolved vault_conflicts rows for the authenticated user's primary vault. Used by clients (e.g. SessionStart hook) to surface conflicts that need merge attention. Returns up to `limit` rows ordered by most recent first.
Parameters (2)
- limitinteger
Optional: max rows to return (default 50, max 200).
- pathstring
Optional: filter to a specific path.
sync_audit_layer5
Record the result of a client-side Layer 5 codex review (sync.py merge gate) as a vault_events row. Body of the review is NOT stored — only an HMAC digest of the summary so operators can correlate without exposing review content. Opt-in: server skips writes (still returns success) unless ENV['AINOTE_LAYER5_AUDIT']='on' AND a versioned HMAC secret is configured. Used by the sync.py SessionStart hook + merge command to surface 'why was this blocked?' across multi-PC sessions.
Parameters (5)
- pathstringrequired
Vault path the review covered.
- verdictstringrequired
One of: pass, flag, block, error.
- summarystring
Free-form codex output summary. Server HMACs this; raw text is NEVER stored.
- chunk_countinteger
Optional: number of diff chunks the client fed to codex.
- duration_msinteger
Optional: wall-clock time of the codex review on the client.
handoff_save
Save a session handoff note for cross-device / cross-session continuation. Stored at handoffs/{project}-{topic}-{YYYY-MM-DD}.txt in the user's primary vault. Use the optional `time` param (HHMM, KST) to disambiguate multiple handoffs saved on the same day — it is appended to the topic slug (e.g. topic='phase-d', time='1555' → handoffs/{project}-phase-d-1555-{date}.txt).
Parameters (6)
- projectstringrequired
Project slug, e.g. 'logi', 'ainote', 'krx_ai'. Lowercase, no spaces.
- topicstringrequired
Short topic slug for this handoff, e.g. 'phase-d-port', 'oauth-fix'. Lowercase-hyphen.
- contentstringrequired
Full handoff text. Should follow the session-handoff skill template (현재 상태 / 작업 위치 / 수정 파일 / 결정 사항 / 다음 STEP / 알려진 이슈). WAF-bypass tip: prefix the string with '__B64__:' followed by base64-encoded payload to bypass Render/Cloudflare edge WAF for large bodies (~10KB+) that get false-positive blocked as SQLi/cmd-injection.
- content_b64string
Optional: base64-encoded handoff text (use INSTEAD of `content`). For WAF-bypass on large bodies. Server decodes before storing.
- datestring
Optional override date (YYYY-MM-DD). Defaults to today in server timezone.
- timestring
Optional time-of-day suffix in HHMM 24h format (KST), e.g. '1555'. Appended to the topic slug so multiple handoffs on the same day stay distinguishable. Omit for once-per-day saves.
handoff_list
List session handoff notes saved in the primary vault under handoffs/, most-recent first. v2 frontmatter fields (status / has_blockers / tags / task_type) can be filtered server-side and are exposed in each entry without fetching the body. Read-only: entries older than 7 days are filtered out of results (a daily server-side cleanup job permanently deletes them).
Parameters (7)
- projectstring
Optional project filter, e.g. 'logi' to list only logi-* handoffs.
- limitinteger
Max entries to return (default 50).
- statusstring
v2 only: filter by frontmatter status (e.g. 'in_progress', 'paused', 'completed', 'blocked'). v1 handoffs without frontmatter are excluded when this filter is set.
- has_blockersboolean
v2 only: filter by frontmatter has_blockers (true/false).
- task_typestring
v2 only: filter by frontmatter task_type (e.g. 'feature', 'bugfix', 'refactor', 'research', 'ops').
- tagsarray
v2 only: AND match — entries must contain ALL given tags. Example: ['auth', 'mobile'].
- sincestring
ISO8601 timestamp — only entries with updated_at >= since are returned.
handoff_get
Retrieve a session handoff by project + topic. If date is omitted, returns the most recent matching handoff. Pass `time` (HHMM, KST) to fetch a specific same-day save when multiple exist. Read-only: handoffs older than 7 days are not returned (a daily server-side cleanup job permanently deletes them).
Parameters (4)
- projectstringrequired
Project slug used at handoff_save time.
- topicstringrequired
Topic slug used at handoff_save time.
- datestring
Optional YYYY-MM-DD. Omit for latest.
- timestring
Optional HHMM (24h, KST) — same value passed at save time. Required to disambiguate when multiple handoffs share the same project/topic/date.
memory_search
Search your memory (dev docs / papers + vault markdown files) and get ranked snippets with IDs. COST PRINCIPLE: search returns snippets only; call memory_get for full content. MODES: - keyword (default): hybrid keyword + semantic match across title/path/content - latest_state: most recent memory, preferring entries saved with memory_type='state' (falls back to plain recency when no typed entries exist) Returns { found: false, message: "no memory found" } when nothing matches — treat that as a definitive empty signal and stop searching (do not guess).
Parameters (4)
- querystringrequired
Search text (e.g. 'render deploy key', 'ainote jwt'). May be blank only in latest_state mode.
- modestring
keyword (default) or latest_state
- sourcesarray
Memory stores to search. Default: both.
- limitinteger
Max results (default 10, max 20)
memory_get
Fetch the full content of ONE memory item found via memory_search. source='paper' requires `id`; source='vault_file' accepts `id` or `path`. Only the authenticated user's own items are accessible. Returns { found: false } when the item does not exist (or belongs to another user).
Parameters (3)
- sourcestringrequired
Which store the item lives in (use the `source` field from memory_search results)
- idstring
Item ID returned by memory_search
- pathstring
vault_file only: file path inside the vault (e.g. 'global/MEMORY.md')
README not available yet.
Install
Configuration
AINOTE_API_KEYrequiredsecret64-character ainote MCP key. Issue one via `npx @ainote/mcp signup` (RFC 8628 device flow), or in a Claude session by calling signup_and_get_key, or at https://app.ainote.dev -> Settings -> MCP keys.
claude_desktop_config.json
{
"mcpServers": {
"ainote": {
"command": "npx",
"args": [
"-y",
"@ainote/mcp@1.3.2"
],
"env": {
"AINOTE_API_KEY": "<YOUR_AINOTE_API_KEY>"
}
}
}
}