svg-annotate-mcp
svg-annotate-mcp
Аннотирование SVG-рисунков к статьям прямо в браузере — клик по элементу (при наведении подсвечивается семантический элемент, в стиле Claude Design) или выделение области. Аннотация (включая информацию о задетых SVG-элементах) передаётся обратно в Claude через MCP; Claude изменяет исходный файл (SVG или генерирующий скрипт), а страница следит за изменениями файла и автоматически обновляется, образуя цикл «аннотация → изменение → обновление → повторная аннотация».
Бэкенд: Python + официальный SDK
mcp(MCPServer, stdio), в процессе запускается HTTP-поток из стандартной библиотеки (127.0.0.1, временный порт).Фронтенд: один файл
src/svg_annotate_mcp/web/index.html. SVG через fetch + DOMParser добавляется в Shadow DOM (двусторонняя изоляция от стилей и id страницы); аннотации рисуются на отдельном оверлее; при отправке определение попаданий выполняется на стороне браузера.
Установка и регистрация
cd ~/Projects/svg-annotate-mcp && uv sync
claude mcp add --scope user svg-annotate -- \
uv run --directory /Users/boryant/Projects/svg-annotate-mcp svg-annotate-mcpНеобязательно: ослабьте таймаут MCP-клиента, чтобы один вызов wait_for_annotations мог ждать дольше (можно и без этого, просто цикл будет опрашивать чаще): задайте MCP_TOOL_TIMEOUT=600000 в профиле shell или в env настроек Claude Code.
Поверхность инструментов (4)
Инструмент | Действие |
| Открывает SVG в браузере. В |
| Блокирует выполнение, пока пользователь не нажмёт «Отправить в Claude». Возврат |
| Неблокирующий запасной вариант: отдаёт последнюю партию отправленных аннотаций (для восстановления контекста после обрыва цепочки ожидания). |
| Отправляет статус в верхнюю панель страницы (например, «правлю fig_xxx.py и перезапускаю…»). После изменения файла вызывать её не нужно — страница обновится автоматически. |
Выбор элемента по клику (v2)
По умолчанию работает инструмент «Выбор»: при наведении сразу подсвечивается семантический элемент под курсором (для matplotlib — это группы text_N/line2d_N/legend_N и другие g[id]; берётся минимальная по площади область попадания), на выноске показывается id+текст. Клик открывает инспектор элементов (в боковой панели: id, точный текст, хлебные крошки предков — по ним можно переключиться на родительскую группу, например text_54 → legend_1); аннотация создаётся только после ввода текста в поле «Описание изменения» — обычный клик означает только инспектор и не создаёт мусорных аннотаций. Esc или «Отменить выбор» закрывает инспектор. Элементные аннотации на рисунке отображаются пунктирной рамкой с номером.
Структура возвращаемых аннотаций (расчёт на то, что Claude найдёт объект)
Каждая аннотация содержит:
kind(element/rect/arrow/freehand/text),note(пользовательское описание изменения),number(номер на холсте);для
kind:"element"также естьtarget:tag/id/text(точный текст)/ancestors/d_prefix/bbox_svgвыбранного элемента — это самый надёжный якорь, используйте его в первую очередь (ищите по id или text в генерирующем скрипте или в SVG);geometry_norm(0–1) иgeometry_svg(координаты viewBox, пересчитаны на сервере);hits[]: задетые выделением элементы SVG; каждый содержитtag/id(семантические группы matplotlib, напримерtext_N/line2d_N)/text(точный текст элемента)/ancestors(цепочка родительских id, например["figure_1", "legend_1", "text_54"])/bbox_svg/coverage/d_prefix(первые 30 символов строкиdу path — якорь для grep при прямой правке SVG). Выполнена очистка от шума: фоновые контейнеры отбрасываются, семантические группы имеют приоритет (листья внутри групп не дублируются), не более 10 элементов на запись;text_region_region: все тексты внутри выделенной области (в порядке чтения, без дубликатов) — первая зацепка для поиска по grep в генерирующем скрипте.
Что изменять — решает Claude: если в аннотации есть source_script, сначала изменить скрипт и запустить его заново (изменение SVG-результата будет перезаписано при следующем запуске); если скрипта нет — править файл SVG. Страница не предполагает способа изменений, она отслеживает только изменение mtime файла (опрос каждые 500 мс, проверка стабильности значения, проверка окончания </svg> против записи половины файла).
Жизненный цикл аннотаций
Неотправленные черновики аннотаций сохраняются после обновления страницы; после нажатия «Отправить в Claude» эта аннотация становится полупрозрачной (35%) и остаётся на рисунке (номер сохраняется для сопоставления); следующее обновление, вызванное изменением файла в Claude, удаляет полупрозрачные аннотации.
Типовой цикл
用户: 帮我改 figure11,我来圈
Claude: open_svg("/path/figures/figure11.svg", source_script="/path/fig_tri_complement.py")
wait_for_annotations() # 挂起
用户: (浏览器里圈图例写「图例移到右上」,点提交)
Claude: 收到批注 → set_status("正在改 fig_tri_complement.py…")
→ 改脚本 → 重跑出图 → 页面自动刷新
→ wait_for_annotations() # 等下一轮Тестирование
uv run python tests/smoke_test.py # 端到端:握手/HTTP/阻塞等待/坐标换算/SSE reload/复用 tab
uv run python tests/manual_driver.py <svg> [script] # 起 server 供手动/浏览器自动化测试,批次落盘 tests/out/batches.jsonlОтладочные параметры страницы: ?nosse=1 — отключить SSE (для headless-скриншотов); ?autotest=x,y,w,h — после загрузки автоматически нарисовать прямоугольную аннотацию и отправить её (координаты нормализованы 0–1); ?autotest_click=x,y — кликнуть по элементу в этой точке и отправить аннотацию (если добавить &autotest_stage=pick, будет только выбор и подсветка — для скриншотов инспектора).
Переменные окружения: SVG_ANNOTATE_NO_OPEN=1 — заставляет open_svg не открывать браузер автоматически (для тестов).
Возвестные ограничения (первая версия)
Одна сессия на рисунок (один рисунок за раз, новый вызов open_svg просто меняет рисунок; несколько сессий Claude работают с независимыми экземплярами сервера, не мешая друг другу); не реализован экспорт annotations.json (аннотации передаются только через память, теряются при перезапуске сервера — надёжный источник сохранности — контекст Claude); внешние ресурсы внутри SVG не проксируются (open_svg выдаст предупреждение; выдача matplotlib всегда встроена, поэтому она не сработает); на macOS только open может открывать браузер; localhost без аутентификации.
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 Connectors
Real-time collaborative whiteboard — AI agents and humans edit the same board live over MCP.
Live browser debugging for AI assistants — DOM, console, network via MCP.
Cross-agent artifact workspace with provenance across Claude Code, Codex, Cursor, LangGraph.
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/sunjianbo-123/svg-annotate-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server