Anchor MCP
Anchor MCP
Anchor と同じ Docker Compose スタック内で動作するサイドカーとして、安全な Anchor Notes ツールを ChatGPT に公開する実装計画です。
調査根拠: Anchor の上流リポジトリ ZhFahim/anchor(デフォルトブランチ main、2026-08-20 時点)を確認。Anchor は Nest.js 製バックエンドで、/api/* 配下に認証付き REST エンドポイントを持ちます。
目標
Anchor と並行して MCP サーバーを実行し、外部アシスタントが Anchor のノートの一覧表示・検索・閲覧・作成・更新・インポート・ファイル添付を、Anchor のデータベースやプライベート API を直接公開せずにできるようにします。
Related MCP server: NotesBridge
現在の状況
最初のマイルストーンが実装済みです:
POST /mcpでの Streamable HTTP MCP エンドポイント。GET /healthzのヘルスチェックエンドポイント。読み取り専用ツール:
anchor_list_notes、anchor_search_notes、anchor_get_note、anchor_list_tags、anchor_list_attachments。ANCHOR_MCP_TOKENによるオプションの MCP ガード。Anchor API 呼び出しには
ANCHOR_TOKENとANCHOR_BASE_URLを使用。Dockerfile を含む。
書き込みツールは意図的に未実装です。
開発
NixOS では、Node/npm コマンドに nix-shell を使用します:
nix-shell -p nodejs --run 'npm install'
nix-shell -p nodejs --run 'npm run typecheck'
nix-shell -p nodejs --run 'npm run build'ローカル実行:
ANCHOR_BASE_URL=https://anchor.cri.su \
ANCHOR_TOKEN=... \
ANCHOR_MCP_TOKEN=... \
nix-shell -p nodejs --run 'npm run dev'MCP エンドポイントは http://localhost:8000/mcp です。ANCHOR_MCP_TOKEN が設定されている場合、呼び出し元は Authorization: Bearer <token> ヘッダーを送信する必要があります。
デプロイモデル
想定するスタックは 3 つのサービスで構成されます:
services:
anchor:
# Existing Anchor service.
anchor-mcp:
build: /path/to/anchor-mcp
environment:
ANCHOR_BASE_URL: http://anchor:3000
ANCHOR_TOKEN: ${ANCHOR_TOKEN}
ANCHOR_MCP_TOKEN: ${ANCHOR_MCP_TOKEN}
expose:
- "8000"
depends_on:
- anchor
chatgpt-tunnel-client:
# Outbound tunnel client.
environment:
MCP_TARGET_URL: http://anchor-mcp:8000/mcp
MCP_TARGET_TOKEN: ${ANCHOR_MCP_TOKEN}
depends_on:
- anchor-mcpMCP サーバーは Docker ネットワーク上でのみ到達可能にし、外部からのアクセスはトンネルクライアントのみを経由させます。
確認済みの Anchor API サーフェス
以下の全エンドポイントは Authorization: Bearer <token> ヘッダーを要求し、有効なユーザーに関連付けられた Anchor トークンのみがアクセスできます。
ノート:
POST /api/notesGET /api/notes?search=<search>&tagId=<tagId>&limit=<limit>GET /api/notes/:idPATCH /api/notes/:idDELETE /api/notes/:idDELETE /api/notes/:id/permanentPATCH /api/notes/:id/restoreGET /api/notes/trashGET /api/notes/archivePOST /api/notes/bulk/deletePOST /api/notes/bulk/archivePOST /api/notes/bulk/pinPOST /api/notes/bulk/tags
タグ:
POST /api/tagsGET /api/tagsGET /api/tags/:idGET /api/tags/:id/notesPATCH /api/tags/:idDELETE /api/tags/:id
添付ファイル:
POST /api/notes/:noteId/attachmentsGET /api/notes/:noteId/attachmentsGET /api/notes/:noteId/attachments/:idDELETE /api/notes/:noteId/attachments/:idPATCH /api/notes/:noteId/attachments/reorder
インポート/エクスポート:
POST /api/import/notesPOST /api/import/notes/:noteId/attachmentsGET /api/export
同期 API:
POST /api/syncGET /api/sync/events(Server-Sent Events)
共有:
POST /api/notes/:id/sharesGET /api/notes/:id/sharesGET /api/notes/:id/shares/:shareIdPATCH /api/notes/:id/shares/:shareIdDELETE /api/notes/:id/shares/:shareId
MCP サーバーは、まず notes / tags / attachments / import の各エンドポイントに対応します。同期 API は、競合を意識したオフラインクライアント向けのものであるため、MCP サイドカーでは初期段階では使用しません。
データ構造
ノート作成ボディ:
{
"title": "string",
"content": "optional string",
"isPinned": false,
"isArchived": false,
"background": "optional string",
"tagIds": ["tag-id"]
}ノート更新ボディは部分更新に加え、楽観的ロック用のオプションフィールドを含みます:
{
"title": "optional string",
"content": "optional string",
"isPinned": false,
"isArchived": false,
"background": "optional string",
"tagIds": ["tag-id"],
"baseVersion": 1
}Anchor が返すノートの主要フィールド:
{
"id": "uuid",
"title": "string",
"content": "string or null",
"version": 1,
"isPinned": false,
"isArchived": false,
"background": null,
"state": "active",
"createdAt": "iso timestamp",
"updatedAt": "iso timestamp",
"userId": "uuid",
"tagIds": ["tag-id"],
"permission": "owner",
"attachmentCount": 0,
"imagePreviewIds": []
}インポートボディ:
{
"notes": [
{
"ref": "external stable reference, max 256 chars",
"id": "optional uuid",
"title": "string",
"content": "stringified Quill Delta JSON",
"isPinned": false,
"isArchived": false,
"isTrashed": false,
"background": "optional background id",
"tagNames": ["tag name"],
"createdAt": "iso timestamp",
"updatedAt": "iso timestamp"
}
],
"tags": [{ "name": "tag", "color": "#8B5CF6" }],
"skipExisting": true
}インポート結果の構造:
{
"results": [
{
"ref": "external reference",
"status": "created | skipped | remapped | failed",
"noteId": "uuid",
"warning": "optional string",
"error": "optional string"
}
],
"tags": { "created": 0, "reused": 0 }
}添付ファイルのアップロード形式:
通常のノート添付:
POST /api/notes/:noteId/attachmentsへのマルチパートfileフィールド。インポート時の添付:
POST /api/import/notes/:noteId/attachmentsへのマルチパートfileフィールドとpositionフィールド。添付ファイルのレスポンスには
id、noteId、type、originalFilename、mimeType、size、position、uploadedBy、createdAtが含まれます。
検証と制約
ノート一覧:
GET /api/notesのlimitは1から200の範囲に制限されます。
一括操作:
noteIds: 最大 200 件。tagIds: 最大 50 件。
インポート:
バッチあたりのノート数: 50。
文字列化された Delta の最大長: 1,000,000 文字。
タイトル: 1000 文字。
ノートあたりのタグ数: 50。
インポートバッチあたりのタグ数: 50。
タグ名: 100 文字。
添付ファイル:
最大ファイルサイズ: 50 MB。
許可される画像 MIME タイプ:
image/jpeg、image/png、image/webp、image/gif。許可される音声 MIME タイプ:
audio/mpeg、audio/wav、audio/x-wav、audio/ogg、audio/aac、audio/mp4。許可されるドキュメント MIME タイプ:
application/pdf、text/plain、application/json。その他のファイルタイプ(例: ZIP、実行ファイル、その他のバイナリ)は Anchor API によって拒否されます。
インポートの制限:
バッチあたりのノート数: 最大 50。
文字列化された Delta コンテンツの長さ: 1,000,000 文字。
タイトル長: 1000 文字。
ノートあたりのタグ数: 50。
インポートバッチあたりのタグ数: 50。
タグ名の長さ: 100。
添付ファイルの制限:
最大ファイルサイズ: 50 MB。
許可される画像 MIME タイプ:
image/jpeg、image/png、image/webp、image/gif。許可される音声 MIME タイプ:
audio/mpeg、audio/wav、audio/mp4、audio/ogg、audio/aac、audio/webm。その他のファイルタイプは現在のソースでは拒否されます。
データモデル
ノート作成ボディ:
{
"title": "string",
"content": "optional string",
"isPinned": false,
"isArchived": false,
"background": "optional string",
"tagIds": ["tag-id"]
}ノート更新ボディは部分更新に加えて、オプションの楽観ロックを含みます:
{
"title": "optional string",
"content": "optional string",
"isPinned": false,
"isArchived": false,
"background": "optional string",
"tagIds": ["tag-id"],
"baseVersion": 1
}Anchor が返すノートで重要なフィールド:
{
"id": "uuid",
"title": "string",
"content": "string or null",
"version": 1,
"isPinned": false,
"isArchived": false,
"background": null,
"state": "active",
"createdAt": "iso timestamp",
"updatedAt": "iso timestamp",
"userId": "uuid",
"tagIds": ["tag-id"],
"permission": "owner",
"attachmentCount": 0,
"imagePreviewIds": []
}一括インポートのボディ:
{
"notes": [
{
"ref": "external stable reference, max 256 chars",
"id": "optional uuid",
"title": "string",
"content": "stringified Quill Delta JSON",
"isPinned": false,
"isArchived": false,
"isTrashed": false,
"background": "optional background id",
"tagNames": ["tag name"],
"createdAt": "iso timestamp",
"updatedAt": "iso timestamp"
}
],
"tags": [{ "name": "tag", "color": "#8B5CF6" }],
"skipExisting": true
}インポート結果の形状:
{
"results": [
{
"ref": "external reference",
"status": "created | skipped | remapped | failed",
"noteId": "uuid",
"warning": "optional string",
"error": "optional string"
}
],
"tags": { "created": 0, "reused": 0 }
}添付ファイルの形状:
通常のノート添付:
POST /api/notes/:noteId/attachmentsへのマルチパートfile。インポート時の添付:
POST /api/import/notes/:noteId/attachmentsへのマルチパートfileとpositionフォームフィールド。添付ファイルのレスポンスには
id、noteId、type、originalFilename、mimeType、fileSize、position、uploadedBy、createdAtが含まれます。
検証と制限
ノート一覧の
limitは1..200にクランプ。一括操作の
noteIdsは最大 200 件。一括操作の
tagIdsは最大 50 件。インポート時のバッチあたりノート数は最大 200。
インポート時のノートあたりタグ数は最大 50。
タグ名は最大 100 文字。
インポート時のノート内容は、Stringified Quill Delta で最大 1,000,000 文字。
タイトルは最大 1000 文字。
添付ファイルは最大 25 MB。
コンテンツ形式
Anchor はノートの content を文字列として保存します。既存のインポート処理により、リッチテキストインポートでは content が文字列化された Quill Delta JSON であることが確認されています。
MCP サーバーは Markdown 入力を受け付け、Anchor に送信する前に内部で Quill Delta に変換します。また、ネイティブ Delta 入力を受け付ける高級モードのツールも公開します。
推奨される変換ポリシー:
anchor_create_noteは Markdown を受け付け、Delta に変換してPOST /api/notesを呼び出す。anchor_update_noteは Markdown を受け付け、Delta に変換してPATCH /api/notes/:idを呼び出す(オプションでbaseVersionを指定)。anchor_import_notesは Markdown またはネイティブ Delta を受け付け、POST /api/import/notesでバッチ処理する。anchor_get_noteは生のコンテンツに加えて、LLM 可読性のためのベストエフォートなテキスト/Markdown 投影を返します。
認証モデル
Anchor は Authorization: Bearer <token> ヘッダーからのベアラートークン抽出を使用します。MCP サイドカーは2つの認証レイヤーを維持します:
ANCHOR_TOKEN:anchor-mcpが Anchor を呼び出すときに使用するトークン。ANCHOR_MCP_TOKEN: トンネルクライアントが MCP リクエストを送信する前に提示することが期待されるトークン。
MCP サーバーは、呼び出し元のトークンを Anchor に転送してはなりません。
ソース参照
上流で確認されたファイル:
server/src/notes/controllers/notes.controller.tsserver/src/notes/controllers/note-attachments.controller.tsserver/src/notes/controllers/note-shares.controller.tsserver/src/tags/tags.controller.tsserver/src/import-export/import.controller.tsserver/src/import-export/export.controller.tsserver/src/sync/sync.controller.tsserver/src/sync/sync-events.controller.tsserver/src/notes/dto/create-note.dto.tsserver/src/notes/dto/update-note.dto.tsserver/src/import-export/dto/import-notes.dto.tsserver/src/import-export/dto/import-attachment.dto.tsserver/src/notes/constants/note.constants.tsserver/src/import-export/constants/import.constants.tsserver/src/notes/utils/note-mapper.util.ts
MCP ツール
フェーズ 1 — 読み取り専用(実装済み):
anchor_list_notes(limit, offset, tag_id)— ノートを一覧表示します。anchor_search_notes(query, limit)— ノートを検索します。anchor_get_note(note_id)— ノートの内容とメタデータを返します。anchor_list_tags()— タグを一覧表示します。anchor_list_attachments(note_id)— 添付ファイルのメタデータのみを返し、バイトはダウンロードしません。
フェーズ 2 の書き込みツール:
anchor_create_note(title, markdown)anchor_update_note(note_id, markdown, base_version)anchor_import_notes(notes)anchor_create_tag(name, color)anchor_upload_attachment(note_id, file, filename, mime_type)
フェーズ 3 の管理ツール:
anchor_archive_notes(note_ids)anchor_pin_notes(note_ids, is_pinned)anchor_add_tags(note_ids, tag_ids)anchor_export()(トンネルクライアントがストリームされたアーカイブを処理できる場合)
破壊的ツールはゲート付きで段階的に導入:
anchor_delete_note(note_id, confirm)は論理削除にマップされ、confirm=trueを要求します。anchor_permanent_delete_note(note_id, confirm)は最初は省略。anchor_delete_tag(tag_id, confirm)は最初は省略。生の任意 HTTP プロキシツールは公開しないでください。
セキュリティ
ANCHOR_TOKENは、anchor-mcpが Anchor を呼び出すときにのみ使用します。ANCHOR_MCP_TOKENは、トンネルが MCP サーバーと話すことを許可する別のシークレットです。読み取り専用ツールを既定とし、破壊的ツールを最初のフェーズでは有効にしないでください。
ANCHOR_TOKENには Anchor ユーザーアカウント専用のスコープを持つトークンを使用し、管理・昇格された認証情報を共有しないでください。ノートの内容を Markdown に変換する際は、インライン画像の data URL を除去してください。これらは LLM コンテキストを膨張させ、外部アシスタントには有用でないためです。
プロンプトインジェクションは Anchor のノートコンテンツ経由で発生する可能性があります。読み取りツールはノートを外部コンテンツとして扱い、その中の指示に従わないでください。
実装済みツール
フェーズ 1(読み取り専用):
anchor_list_notes(limit, offset, tag_id)anchor_search_notes(query, limit)anchor_get_note(note_id)anchor_list_tags()anchor_list_attachments(note_id)
制限:
anchor_list_notesはlimitを 1..200 にクランプし、デフォルトは 20 です。offsetは 0 以上にクランプされます。anchor_search_notesはクエリを必須とし、limitを 1..200 にクランプします。anchor_get_noteは、提供されたnote_idが数値であることを検証します。anchor_list_tagsは入力を受け付けません。anchor_list_attachmentsはメタデータのみを返し、添付ファイルのバイト列をダウンロードしません。
フェーズ 2 の書き込みツール
anchor_create_note(title, markdown)— タイトル付きでノートを作成します。anchor_update_note(note_id, markdown, base_version)— オプションの楽観ロックバージョンでノートを更新します。anchor_import_notes(notes)— 拡張 Markdown 形式のノート配列を受け取り、バッチ処理します。anchor_create_tag(name, color)anchor_upload_attachment(note_id, file, filename, mime_type)
破壊的ツール
破壊的操作はガードを設けます:
anchor_delete_note(note_id, confirm)— ソフト削除。confirm=trueが必要。anchor_archive_notes(note_ids)— 復元可能。anchor_unarchive_notes(note_ids)— 復元可能。anchor_permanent_delete_note(note_id, confirm)— 最初は省略。anchor_delete_tag(tag_id, confirm)— 最初は省略。生の任意 HTTP プロキシツールは公開しない。
セキュリティ
ANCHOR_TOKENはanchor-mcpコンテナ内にのみ保存します。トンネル上のすべての MCP リクエストには
ANCHOR_MCP_TOKENが必要です。実行を制限するツールを公開しないでください。
ファイルアップロードは Anchor の許可リストに制限されます(画像、音声、PDF)。実行ファイルやスクリプトは拒否されます。
エクスポートはストリーム処理されるため、トンネルクライアントが大きな応答を処理できる場合にのみ公開してください。
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceMCP server for AI agents to read, write, and organize notes in a local-first, human-in-the-loop note-taking app.01MIT
- AlicenseNot gradedqualityAmaintenanceMCP server enabling ChatGPT to search, read, and write Apple Notes via a local Mac agent with a privacy-preserving relay.MIT
- AlicenseNot gradedqualityAmaintenanceA secure multi-tenant MCP proxy that exposes 81 tools for full CRUD, search, chat, podcast, and command management on the OpenNotebook API, enabling natural language interaction with notebooks, notes, sources, and more.GPL 3.0
- AlicenseNot gradedqualityBmaintenanceSelf-hosted MCP server for private Obsidian vaults on GitHub, exposing tools to search, read, write, and analyze Markdown notes and their link graph.MIT
Related MCP Connectors
Search, read, and write your Apple Notes from ChatGPT/Claude via a local Mac agent + MCP relay.
Search your AI chat history (ChatGPT, Claude, Codex) from any MCP client. Remote, private, read-only
Agent-native MCP server over the public saagarpatel.dev corpus. Read-only, stateless.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/llego/anchor-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server