Skip to content

io.github.seunghan91/ainote

by seunghan91 · remote · local (npm) · no sign-in to list tools · v1.3.2 · published by GitHub user seunghan91

Agent-native notes, tasks, dev-docs, vaults, sync & handoffs. MCP + OpenAPI dual surface.

Deletes · 16Final · 1Changes · 7

34 tools: 16 can delete or cancel things, 1 do something that can't be undone, 7 change things and 10 only read.

Scanned Oct 21, 2026

3 checks matched something in the tool definitions. No finding is not a safety guarantee. How the checks work.

claude mcp add --transport http ainote https://api.ainote.dev/api/mcp --header 'Authorization: <your-authorization>'

Findings

Matches of fixed checks, with the text they matched.

3 warn
  • The server marks "env_sync.secret_pull" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

    Matched text

    annotations: {"readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}; The name "env_sync.secret_pull" says "sync": a word for a change.

    What this check looks for
  • The server marks "sync_read" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

    Matched text

    annotations: {"readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}; The name "sync_read" says "sync": a word for a change.

    What this check looks for
  • The server marks "env_sync_read" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

    Matched text

    annotations: {"readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}; The name "env_sync_read" says "sync": a word for a change.

    What this check looks for

Tools

Open a tool for its reasons and full description. Descriptions are the publisher's own words, shown as they are.

34 tools

Deletes or cancels 16Claude Code: deny
  • assumption_writeCreate or update an assumption under a project (L2 intent layer).No findings

    Why it is in this group

    • The name "assumption_write" says "write": a word for a change.
    • The input takes a statement or command to run (input.statement), which can change anything it can reach.
    • The server marks it destructive (destructiveHint: true).
    Description, as the server wrote it
    Create or update an assumption under a project (L2 intent layer). Omit `id` to create, pass it to update. There is no delete tool. 🔴 `verdict` is REJECTED with an error if passed — verdict is confirmed only through a human judgment decision (see judgment_submit). This tool can only shape the assumption itself: what is being assumed, how critical it is, and what evidence would settle it.

    Annotations the server declares

    • destructiveHint: true
    • idempotentHint: false
    • openWorldHint: false
    • readOnlyHint: false
  • delete_dev_docSoft-delete a dev document by title or UUID.No findings

    Why it is in this group

    • The name "delete_dev_doc" says "delete": a word for removing or ending something.
    • The server marks it destructive (destructiveHint: true).
    Description, as the server wrote it
    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).

    Annotations the server declares

    • destructiveHint: true
    • idempotentHint: true
    • openWorldHint: false
    • readOnlyHint: false
  • delete_taskSoft-delete a task by ID.No findings

    Why it is in this group

    • The name "delete_task" says "delete": a word for removing or ending something.
    • The server marks it destructive (destructiveHint: true).
    Description, as the server wrote it
    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.

    Annotations the server declares

    • destructiveHint: true
    • idempotentHint: true
    • openWorldHint: false
    • readOnlyHint: false
  • dev_doc_writeCreate or update a dev doc.No findings

    Why it is in this group

    • The name "dev_doc_write" says "write": a word for a change.
    • The server marks it destructive (destructiveHint: true).
    Description, as the server wrote it
    Create or update a dev doc. action: create | update. Deletion is a separate tool (delete_dev_doc). (consolidated surface — same handlers as the legacy tools) Required per action — create: title, content | update: content.

    Annotations the server declares

    • destructiveHint: true
    • idempotentHint: false
    • openWorldHint: false
    • readOnlyHint: false
  • env_sync_txn_pushIngest a batched envelope of client-recorded env_sync mutations.No findings

    Why it is in this group

    • The name "env_sync_txn_push" says "sync": a word for a change.
    • The server marks it destructive (destructiveHint: true).
    Description, as the server wrote it
    Ingest a batched envelope of client-recorded env_sync mutations. HLC-skew gated, partial-success on conflict.

    Annotations the server declares

    • destructiveHint: true
    • idempotentHint: false
    • openWorldHint: false
    • readOnlyHint: false
  • env_sync_txn_rollbackInverse-apply a prior env_sync transaction.No findings

    Why it is in this group

    • The name "env_sync_txn_rollback" says "sync": a word for a change.
    • The server marks it destructive (destructiveHint: true).
    Description, as the server wrote it
    Inverse-apply a prior env_sync transaction. Safety gates: ownership, idempotency, descendant-conflict (force opt-out).

    Annotations the server declares

    • destructiveHint: true
    • idempotentHint: false
    • openWorldHint: false
    • readOnlyHint: false
  • env_sync.secret_rotateRotate a secret: soft-delete the old node, create a new live node with the same alias and the new ciphertext+recipients.No findings

    Why it is in this group

    • The name "env_sync.secret_rotate" says "sync": a word for a change.
    • The server marks it destructive (destructiveHint: true).
    Description, as the server wrote it
    Rotate a secret: soft-delete the old node, create a new live node with the same alias and the new ciphertext+recipients. 7-day grace before hard delete of old ciphertext bytes.

    Annotations the server declares

    • destructiveHint: true
    • idempotentHint: false
    • openWorldHint: false
    • readOnlyHint: false
  • graph_soft_deleteSoft-delete an env_sync graph node (sets deleted_at; .live scope hides it from reads).No findings

    Why it is in this group

    • The name "graph_soft_delete" says "delete": a word for removing or ending something.
    • The server marks it destructive (destructiveHint: true).
    Description, as the server wrote it
    Soft-delete an env_sync graph node (sets deleted_at; .live scope hides it from reads). Idempotent — re-deleting a deleted node is a no-op success.

    Annotations the server declares

    • destructiveHint: true
    • idempotentHint: true
    • openWorldHint: false
    • readOnlyHint: false
  • graph_writeAdd or update a graph entity.No findings

    Why it is in this group

    • The name "graph_write" says "write": a word for a change.
    • The server marks it destructive (destructiveHint: true).
    Description, as the server wrote it
    Add or update a graph entity. action: add | update. Deletion is a separate tool (graph_soft_delete). (consolidated surface — same handlers as the legacy tools) Required per action — add: node_type, alias, payload, device_id | update: node_id, device_id, field_updates.

    Annotations the server declares

    • destructiveHint: true
    • idempotentHint: false
    • openWorldHint: false
    • readOnlyHint: false
  • handoff_saveSave a session handoff note for cross-device / cross-session continuation.No findings

    Why it is in this group

    • The name "handoff_save" says "save": a word for a change.
    • The server marks it destructive (destructiveHint: true).
    Description, as the server wrote it
    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).

    Annotations the server declares

    • destructiveHint: true
    • idempotentHint: true
    • openWorldHint: false
    • readOnlyHint: false
  • project_writeCreate or update a project (L2 intent layer).No findings

    Why it is in this group

    • The name "project_write" says "write": a word for a change.
    • The server marks it destructive (destructiveHint: true).
    Description, as the server wrote it
    Create or update a project (L2 intent layer). Omit `id` to create, pass it to update. There is no delete tool — use status: 'archived' to retire a project.

    Annotations the server declares

    • destructiveHint: true
    • idempotentHint: false
    • openWorldHint: false
    • readOnlyHint: false
  • sync_deleteDelete a file from the primary vault.No findings

    Why it is in this group

    • The name "sync_delete" says "sync": a word for a change.
    • The description's first verb is "delete": a word for removing or ending something.
    • The server marks it destructive (destructiveHint: true).
    Description, as the server wrote it
    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/intent/, global/claude-config/, handoffs/) require base_sha or explicit force:true (audited). Idempotent: deleting a non-existent path returns success with deleted:false.

    Annotations the server declares

    • destructiveHint: true
    • idempotentHint: true
    • openWorldHint: false
    • readOnlyHint: false
  • sync_pushPush a markdown file into the primary vault.No findings

    Why it is in this group

    • The name "sync_push" says "sync": a word for a change.
    • The server marks it destructive (destructiveHint: true).
    Description, as the server wrote it
    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. When the push CREATES a new .md file, the response may carry `dedup_candidates` — existing memory files that look similar (keyword + title similarity, no LLM). It is an advisory, not a rejection: YOU decide to merge into one of them (re-push that path), drop this write as a duplicate (skip), or keep it as a new memory (store).

    Annotations the server declares

    • destructiveHint: true
    • idempotentHint: true
    • openWorldHint: false
    • readOnlyHint: false
  • sync_push_batchPush MANY files into the primary vault in ONE call.No findings

    Why it is in this group

    • The name "sync_push_batch" says "sync": a word for a change.
    • The server marks it destructive (destructiveHint: true).
    Description, as the server wrote it
    Push MANY files into the primary vault in ONE call. Use this instead of looping sync_push whenever you have more than a couple of changed paths — the cost of sync_push is round trips, not bytes. Per-item semantics are identical to sync_push (Layer 3 base_sha CAS, superseded contract, content_b64 WAF fallback). Partial success is normal and returns HTTP 200: read `results[]` and match entries by `path`, NOT by position. A conflict result always carries `remote_sha` + `conflict_reason` so you can go straight to sync_merge. Request-level failures (duplicate paths in one batch, idempotency key reused with a different payload, >200 items, >4MB) return 4xx and apply NOTHING. Each item MUST carry `content_sha` (SHA1 hex of the decoded body, same algorithm as git_sha) — it powers both the integrity check and the retry-safe `skipped_identical` result. Newly created .md items may carry `dedup_candidates` (same merge/skip/store advisory as sync_push); a batch creating more than 10 new files skips the check entirely and reports `dedup_skipped: "bulk"`.

    Annotations the server declares

    • destructiveHint: true
    • idempotentHint: true
    • openWorldHint: false
    • readOnlyHint: false
  • task_writeCreate or update a task.No findings

    Why it is in this group

    • The name "task_write" says "write": a word for a change.
    • The server marks it destructive (destructiveHint: true).
    Description, as the server wrote it
    Create or update a task. action: create | update. Deletion is a separate tool (delete_task). (consolidated surface — same handlers as the legacy tools) Required per action — create: content | update: id.

    Annotations the server declares

    • destructiveHint: true
    • idempotentHint: false
    • openWorldHint: false
    • readOnlyHint: false
  • vault_syncWrapper around vault file sync.Reads text others writeNo findings

    Why it is in this group

    • The name "vault_sync" says "sync": a word for a change.
    • The server marks it destructive (destructiveHint: true).

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    Description, as the server wrote it
    Wrapper around vault file sync. action=list|pull|push to work against the primary vault. list/pull are paginated — narrow with `path`/`since` and follow `next_cursor` instead of pulling the whole vault. To fetch specific files, pull with `paths` (up to 100 exact paths, one call). For push: WAF-bypass via `content_b64` or `content: '__B64__:...'` prefix (mirrors sync_push).

    Annotations the server declares

    • destructiveHint: true
    • idempotentHint: false
    • openWorldHint: true
    • readOnlyHint: false
Can't be undone 1Claude Code: ask
  • env_sync.secret_pushPush a new client-encrypted secret.Can send data outNo findings

    Why it is in this group

    • The name "env_sync.secret_push" says "sync": a word for a change.
    • The input addresses people (input.recipients): what it sends cannot be taken back.

    What it can reach

    • outboundThe input takes a destination (input.recipients): what the tool writes goes there.
    Description, as the server wrote it
    Push a new client-encrypted secret. Ciphertext only — server never sees plaintext. Recipients must include the pushing device's own pubkey.

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: false
    • openWorldHint: false
    • readOnlyHint: false
Changes things 7Claude Code: ask
  • env_sync_readRead env-sync state.1 finding

    Why it is in this group

    • The name "env_sync_read" says "sync": a word for a change.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.

    Findings

    • Warn

      The server marks "env_sync_read" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

      Matched text

      annotations: {"readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}; The name "env_sync_read" says "sync": a word for a change.

      What this check looks for
    Description, as the server wrote it
    Read env-sync state. action: devices | drift | status | txn_pull. Secret reads are a separate tool (env_sync.secret_pull). (consolidated surface — same handlers as the legacy tools)

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
    • readOnlyHint: true
  • env_sync_writeNon-destructive env-sync writes.No findings

    Why it is in this group

    • The name "env_sync_write" says "sync": a word for a change.
    Description, as the server wrote it
    Non-destructive env-sync writes. action: enroll | request_share | heartbeat. Secret push/rotate are separate tools. (consolidated surface — same handlers as the legacy tools) Required per action — enroll: alias, age_pubkey, enrollment_token | request_share: target_device_id, secret_shares, device_id | heartbeat: device_id, installed_skills_hash, installed_hooks_hash.

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: false
    • openWorldHint: false
    • readOnlyHint: false
  • env_sync.secret_pullPull an encrypted secret blob.1 finding

    Why it is in this group

    • The name "env_sync.secret_pull" says "sync": a word for a change.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.

    Findings

    • Warn

      The server marks "env_sync.secret_pull" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

      Matched text

      annotations: {"readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}; The name "env_sync.secret_pull" says "sync": a word for a change.

      What this check looks for
    Description, as the server wrote it
    Pull an encrypted secret blob. Response is ciphertext_b64 only — server never sees and never returns plaintext.

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
    • readOnlyHint: true
  • judgment_submitRequest a human judgment (L3 layer) by attaching evidence — approval, evidence, or verdict.No findings

    Why it is in this group

    • The name "judgment_submit" says "submit": a word for a change.
    Description, as the server wrote it
    Request a human judgment (L3 layer) by attaching evidence — approval, evidence, or verdict. This is the ONLY door an agent has into the judgment queue. 🔴 `decision` is REJECTED with an error if passed — judgments are always created with decision='pending'. Only a human decides them (from the /command queue). Use judgment_list afterwards to check whether this judgment has since been decided. risk_tier controls urgency: 1=destructive (blocks execution until decided), 2=reversible (may auto-proceed after a wait window), 3=informational (auto-expires after 24h).

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: false
    • openWorldHint: false
    • readOnlyHint: false
  • sync_audit_layer5Record the result of a client-side Layer 5 codex review (sync.py merge gate) as a vault_events row.No findings

    Why it is in this group

    • The name "sync_audit_layer5" says "sync": a word for a change.
    Description, as the server wrote it
    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.

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: false
    • openWorldHint: false
    • readOnlyHint: false
  • sync_readRead-only vault sync operations.1 finding

    Why it is in this group

    • The name "sync_read" says "sync": a word for a change.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.

    Findings

    • Warn

      The server marks "sync_read" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

      Matched text

      annotations: {"readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}; The name "sync_read" says "sync": a word for a change.

      What this check looks for
    Description, as the server wrote it
    Read-only vault sync operations. action: list | pull | diff | merge | conflicts. Writes (push/delete) are separate tools — they carry CAS semantics. (consolidated surface — same handlers as the legacy tools) Required per action — diff: path | merge: path, base_text, local_text.

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
    • readOnlyHint: true
  • vault_createCreate a new private vault as a GitHub repository under the user's account.Reads text others writeNo findings

    Why it is in this group

    • The name "vault_create" says "create": a word for a change.

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    Description, as the server wrote it
    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.

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: false
    • openWorldHint: true
    • readOnlyHint: false
Only reads 10Claude Code: allow
  • dev_docs_readRead dev docs.Reads private dataNo findings

    Why it is in this group

    • The name "dev_docs_read" says "read": a word for reading.

    What it can reach

    • private-dataThe name "dev_docs_read" says "read" and "doc": it reads documents.
    • private-dataThe description's first sentence says "read" and "doc": it reads documents.
    Description, as the server wrote it
    Read dev docs. action: get | list | categories | pull (consolidated surface — same handlers as the legacy tools)

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
    • readOnlyHint: true
  • get_setup_guideGet instructions for setting up AI Note MCP in Claude Desktop, Cursor, or other MCP clients.Reads private dataNo findings

    Why it is in this group

    • The name "get_setup_guide" says "get": a word for reading.

    What it can reach

    • private-dataThe description's first sentence says "get" and "note": it reads notes.
    Description, as the server wrote it
    Get instructions for setting up AI Note MCP in Claude Desktop, Cursor, or other MCP clients. No authentication required.

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
    • readOnlyHint: true
  • graph_readRead knowledge-graph nodes.No findings

    Why it is in this group

    • The name "graph_read" says "read": a word for reading.
    Description, as the server wrote it
    Read knowledge-graph nodes. action: get | list (consolidated surface — same handlers as the legacy tools)

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
    • readOnlyHint: true
  • handoff_readRead session handoffs.No findings

    Why it is in this group

    • The name "handoff_read" says "read": a word for reading.
    Description, as the server wrote it
    Read session handoffs. action: get | list (consolidated surface — same handlers as the legacy tools) Required per action — get: project, topic.

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
    • readOnlyHint: true
  • judgment_listList the authenticated user's own judgments (L3 layer) — use this to check your own blocking status (risk_tier 1 pending = execution blocked).No findings

    Why it is in this group

    • The name "judgment_list" says "list": a word for reading.
    Description, as the server wrote it
    List the authenticated user's own judgments (L3 layer) — use this to check your own blocking status (risk_tier 1 pending = execution blocked). Default order matches the /command queue: risk_tier ascending, then arrival order.

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
    • readOnlyHint: true
  • list_papersList notes/papers from AI Note.Reads private dataNo findings

    Why it is in this group

    • The name "list_papers" says "list": a word for reading.

    What it can reach

    • private-dataThe description's first sentence says "list" and "note": it reads notes.
    Description, as the server wrote it
    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.

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
    • readOnlyHint: true
  • memory_readRead agent memory.No findings

    Why it is in this group

    • The name "memory_read" says "read": a word for reading.
    Description, as the server wrote it
    Read agent memory. action: get | search (consolidated surface — same handlers as the legacy tools) Required per action — get: source | search: query.

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
    • readOnlyHint: true
  • project_readList the authenticated user's projects (L2 intent layer), or fetch one by id.No findings

    Why it is in this group

    • The name "project_read" says "read": a word for reading.
    Description, as the server wrote it
    List the authenticated user's projects (L2 intent layer), or fetch one by id. Each entry includes riskiest_assumption — the single highest-priority unverified assumption (or, if all are verified, the highest-criticality one).

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
    • readOnlyHint: true
  • tasks_readRead tasks and task categories.No findings

    Why it is in this group

    • The name "tasks_read" says "read": a word for reading.
    Description, as the server wrote it
    Read tasks and task categories. action: tasks | categories (consolidated surface — same handlers as the legacy tools)

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
    • readOnlyHint: true
  • vault_readRead vault metadata.Reads private dataNo findings

    Why it is in this group

    • The name "vault_read" says "read": a word for reading.

    What it can reach

    • private-dataThe name "vault_read" says "read" and "vault": it reads secrets.
    • private-dataThe description's first sentence says "read" and "vault": it reads secrets.
    Description, as the server wrote it
    Read vault metadata. action: list | clone | status (consolidated surface — same handlers as the legacy tools) Required per action — clone: name.

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
    • readOnlyHint: true

This is not a safety rating, and no finding is not a safety guarantee. The groups and findings come from fixed checks of the tool definitions the server returned on the date shown, not from its code or what it does when called. How the checks work.

Exfil surface

Which tools read private data, which read text someone else can write, and which can send data out. One of each is a path a prompt injection can use.

8 paths in this server alone from private data, through text someone else wrote, to a way out. Denying 1 outbound tool breaks every one.

Reads private data4
Reads files, mail, messages, databases, secrets, calendars or repositories.
Reads text others write2
Brings in text someone else can write: web pages, inbound email, messages, issues and comments.
Can send data out1
Can carry data to people or systems: it sends, posts or publishes, or takes a recipient, channel or URL.
deny to break every path
{
  "permissions": {
    "deny": [
      "mcp__ainote__env_sync_secret_push"
    ]
  }
}

Other servers in the same agent add their own tools to these paths. Audit your whole setup to see them together.

Remote posture

What anyone on the internet sees at the remote endpoint: an anonymous initialize and tools/list, and the public OAuth metadata.

Looked at Oct 22, 2026, 15:05 UTC, unchanged since Oct 22, 2026. No credentials were sent and no tool was called. What is looked at.

Reachable
yes
HTTP status of an anonymous initialize
200
tools/list served without credentials
yes
Tools that change things, listed without credentials
24
Protocol version
2025-06-18
WWW-Authenticate on 401
not observed
resource_metadata in WWW-Authenticate
none
RFC 9728 protected resource metadata
https://api.ainote.dev/.well-known/oauth-protected-resource/api/mcp
Authorization servers
https://app.ainote.dev
Legacy HTTP+SSE transport
no
Dynamic client registration
no
Client ID metadata documents
yes
  • HighThe whole server

    The endpoint served tools/list without credentials, and the list has 24 tools that change things (16 destructive, 1 irreversible, 7 write). Whether a call also works without credentials was not tested: tools are never called.

    Matched text

    https://api.ainote.dev/api/mcp: tools/list returned 34 tools to an anonymous client, including delete_task (destructive), project_write (destructive), assumption_write (destructive), delete_dev_doc (destructive), vault_sync (destructive) and 19 more

    What this check looks for

Install

Pinned to version 1.3.2. Values in angle brackets are yours to fill in.

claude mcp add --transport http ainote https://api.ainote.dev/api/mcp --header 'Authorization: <your-authorization>'

Run in a terminal.

Claude Code permissions

Allow the reads, ask before a change or a way out, deny the deletes. Paste into .claude/settings.json.

.claude/settings.json
{
  "permissions": {
    "allow": [
      "mcp__ainote__list_papers",
      "mcp__ainote__project_read",
      "mcp__ainote__judgment_list",
      "mcp__ainote__get_setup_guide",
      "mcp__ainote__tasks_read",
      "mcp__ainote__dev_docs_read",
      "mcp__ainote__vault_read",
      "mcp__ainote__graph_read",
      "mcp__ainote__handoff_read",
      "mcp__ainote__memory_read"
    ],
    "ask": [
      "mcp__ainote__judgment_submit",
      "mcp__ainote__vault_create",
      "mcp__ainote__sync_audit_layer5",
      "mcp__ainote__env_sync_secret_push",
      "mcp__ainote__env_sync_secret_pull",
      "mcp__ainote__sync_read",
      "mcp__ainote__env_sync_read",
      "mcp__ainote__env_sync_write"
    ],
    "deny": [
      "mcp__ainote__delete_task",
      "mcp__ainote__project_write",
      "mcp__ainote__assumption_write",
      "mcp__ainote__delete_dev_doc",
      "mcp__ainote__vault_sync",
      "mcp__ainote__sync_push",
      "mcp__ainote__sync_push_batch",
      "mcp__ainote__sync_delete",
      "mcp__ainote__handoff_save",
      "mcp__ainote__graph_soft_delete",
      "mcp__ainote__env_sync_secret_rotate",
      "mcp__ainote__env_sync_txn_push",
      "mcp__ainote__env_sync_txn_rollback",
      "mcp__ainote__task_write",
      "mcp__ainote__dev_doc_write",
      "mcp__ainote__graph_write"
    ]
  }
}

Tools that only read are allowed, tools that change things ask first, tools that delete or cancel are denied. A read that can send data out (it takes a URL, say) asks first too. It assumes the server is installed as ainote. Review it before you use it.

Capability tags behind 7 rules
  • mcp__ainote__list_papers private-data
  • mcp__ainote__get_setup_guide private-data
  • mcp__ainote__vault_create untrusted-input
  • mcp__ainote__vault_sync untrusted-input
  • mcp__ainote__env_sync_secret_push outbound
  • mcp__ainote__dev_docs_read private-data
  • mcp__ainote__vault_read private-data