Anchor MCP
Anchor MCP
Anchor의 안전한 노트 도구를 ChatGPT에 노출하는 소형 MCP 사이드카 구현 계획. 터널 클라이언트가 Anchor와 동일한 Docker Compose 스택에서 실행된다.
연구 근거: Anchor 업스트림 저장소 ZhFahim/anchor, 기본 브랜치 main, 2026-08-20 검토. Anchor는 /api/* 아래에 인증된 REST 엔드포인트를 가진 Nest.js 백엔드다.
목표
Anchor 옆에서 MCP 서버를 실행하여 외부 어시스턴트가 Anchor의 데이터베이스나 비공개 API를 직접 노출하지 않고도 노트를 나열, 검색, 읽기, 생성, 업데이트, 가져오기, 파일 첨부를 할 수 있게 한다.
Related MCP server: NotesBridge
현재 상태
첫 번째 마일스톤이 구현되었다:
POST /mcp의 Streamable HTTP MCP 엔드포인트.GET /healthz의 헬스 엔드포인트.읽기 전용 Anchor 도구:
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>을 보내야 한다.
배포 모델
의도된 스택은 세 가지 서비스로 구성된다:
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 표면
아래의 모든 엔드포인트는 Anchor의 AuthGuard로 보호되며 Authorization: Bearer <token>을 기대한다. 가드는 활성 사용자로 확인되는 Anchor 토큰을 허용한다.
노트:
POST /api/notesGET /api/notes?search=<query>&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(서버 전송 이벤트)
공유:
POST /api/notes/:id/sharesGET /api/notes/:id/sharesPATCH /api/notes/:id/shares/:shareIdDELETE /api/notes/:id/shares/:shareId
MCP 서버는 일반 노트/태그/첨부 파일/가져오기 엔드포인트로 시작해야 한다. 동기화 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에 multipartfile필드.가져오기 첨부 파일 업로드:
POST /api/import/notes/:noteId/attachments에 multipartfile과position폼 필드.첨부 파일 응답에는
id,noteId,type,originalFilename,mimeType,fileSize,position,uploadedByUserId,createdAt이 포함된다.
제한 및 검증
노트 목록 제한:
GET /api/notes는limit을1..200으로 제한한다.
일괄 제한:
noteIds: 최대 200개.tagIds: 최대 50개.
가져오기 제한:
배치당 노트 수: 50개.
문자열화된 Delta 콘텐츠 길이: 1,000,000바이트/문자.
제목 길이: 1000자.
노트당 태그 수: 50개.
가져오기 배치당 태그 수: 500개.
태그 이름 길이: 100자.
첨부 파일 제한:
최대 파일 크기: 50MB.
허용 이미지:
image/jpeg,image/png,image/webp,image/gif.허용 오디오:
audio/mpeg,audio/wav,audio/mp4,audio/x-m4a,audio/ogg,audio/aac,audio/webm.PDF, JSON, ZIP 및 일반
application/octet-stream은 현재 소스에서 거부된다.
가져오기에서 허용되는 배경 ID:
color_red,color_orange,color_yellow,color_green,color_teal,color_blue,color_dark_blue,color_purple,color_pink,color_brown.pattern_dots,pattern_grid,pattern_lines,pattern_waves,pattern_groceries,pattern_music,pattern_travel,pattern_code.
콘텐츠 형식
Anchor는 노트 content를 문자열로 저장한다. 기존 가져오기 작업을 통해 리치 텍스트 가져오기에는 문자열화된 Quill Delta JSON이어야 함이 확인되었다.
MCP 서버는 Markdown 친화적 도구를 노출하고 내부적으로 Markdown을 Quill Delta로 변환해야 한다. 이후 전문가 모드 네이티브 Delta 도구도 노출할 수 있다.
권장 변환 정책:
anchor_create_note는 Markdown을 받아 Delta로 변환하고POST /api/notes를 호출한다.anchor_update_note는 Markdown을 받아 Delta로 변환하고 선택적baseVersion과 함께PATCH /api/notes/:id를 호출한다.anchor_import_notes는 Markdown 또는 네이티브 Delta를 받아POST /api/import/notes를 통해 배치 처리한다.anchor_get_note는 원시 콘텐츠와 LLM 가독성을 위한 최선의 텍스트/Markdown 투영을 반환한다.
인증 모델
Anchor 소스는 Authorization: Bearer <token>에서 베어러 토큰 추출을 사용한다. 따라서 MCP 사이드카는 두 개의 인증 계층을 유지해야 한다:
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/notes.constants.tsserver/src/import-export/constants/import.constants.tsserver/src/notes/utils/note-transformer.util.tsserver/src/notes/utils/attachment-storage.util.ts
MCP 도구
1단계 읽기 도구:
anchor_list_notes(limit, offset)anchor_search_notes(query, limit)anchor_get_note(note_id)anchor_list_tags()anchor_list_attachments(note_id)
구현된 도구 세부 사항:
anchor_list_notes는limit,offset,include_content,tag_id를 지원한다. Anchor는 limit 기반 목록만 노출하므로offset + limit는 최대 200이어야 한다.anchor_search_notes는query,limit,include_content,tag_id를 지원한다.anchor_get_note는note_id와include_content를 지원한다.anchor_list_tags는 입력을 받지 않는다.anchor_list_attachments는 메타데이터만 반환하며 첨부 파일 바이트를 다운로드하지 않는다.
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은 Docker 스택 환경 또는.env에만 저장하고 이미지에 포함하지 마라.터널 클라이언트에서
anchor-mcp로의 호출을 위한 별도의ANCHOR_MCP_TOKEN을 추가하라.MCP 서버를 컨테이너 네트워크에만 바인딩하고, 의도적으로 노출하지 않는 한 Traefik 라벨을 추가하지 마라.
도구를 좁고 타입화된 상태로 유지하라. 호출자가 임의의 Anchor API 경로를 선택할 수 없게 하라.
노트 콘텐츠나 토큰이 아닌 요청 메타데이터만 로그하라.
터널 인증 경로가 검증될 때까지 기본적으로 읽기 전용 도구로 유지하라.
소프트 삭제 및 일괄 파괴적 작업에는 명시적
confirm=true를 요구하라.별도의
ENABLE_DANGEROUS_TOOLS=true설정이 없는 한 영구 삭제를 거부하라.
구현 단계
최소 TypeScript MCP HTTP 서버를 생성한다.
환경에서 구성 추가:
ANCHOR_BASE_URL,ANCHOR_TOKEN,ANCHOR_MCP_TOKEN, 바인드 호스트/포트.Docker 및 터널 진단을 위한
/healthz를 구현한다.임의 경로 탈출구가 없는 타입화된 메서드를 가진 소형 Anchor API 클라이언트를 구현한다.
anchor_list_notes,anchor_search_notes,anchor_get_note,anchor_list_tags를 구현한다.명시적으로 요청되지 않는 한 무거운 필드를 제거하는 응답 형태를 추가한다.
Markdown-to-Delta 변환 헬퍼와 테스트를 구현한다.
baseVersion을 통한 선택적 낙관적 잠금으로 생성/업데이트를 구현한다.알려진 가져오기 제한으로 가져오기 배치 처리를 구현한다.
허용된 이미지/오디오에 대해서만 첨부 파일 업로드를 구현한다.
터널 클라이언트 자리 표시자를 포함한 Dockerfile과 Compose 예제를 추가한다.
모의 Anchor 응답 및 검증 실패 테스트를 추가한다.
토큰 순환 및 ChatGPT 터널 클라이언트 연결에 대한 운영 문서를 추가한다.
미해결 질문
정확한 터널 클라이언트 이미지, 환경 변수 및 인증 헤더 형식.
Anchor가 PDF 및 기타 파일 유형을 허용하도록 구성 또는 패치될 수 있는지 여부.
노트 콘텐츠를 Markdown으로 받아 Quill Delta로 변환할지, 아니면 MCP가 Anchor의 네이티브 콘텐츠 형식을 직접 노출해야 하는지 여부.
터널 클라이언트가 첨부 파일 업로드 및 내보내기 다운로드를 위해 바이너리 페이로드를 충분히 잘 전달할 수 있는지 여부.
GET /api/notes가 limit만 노출하고 offset 페이지네이션을 노출하지 않으므로offset을 클라이언트 측에서 시뮬레이션해야 하는지 여부.
권장 첫 마일스톤
anchor_list_notes, anchor_search_notes, anchor_get_note, anchor_list_tags가 있는 읽기 전용 MCP 서버를 구축한다. 터널 클라이언트 뒤의 Anchor 스택에 비공개로 배포한다. 읽기 경로와 인증 모델이 검증된 후에만 생성/업데이트/가져오기를 추가한다.
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