Annotate
ProductConvertManifestoPricingClaude plugin

Claude plugin · MCP server

Every upload, converted first

In Claude Code, install the plugin once and every supported file converts to Markdown automatically before the model reads it. In Claude Desktop, Cowork, and other MCP clients, ask Claude to convert a file and it calls Annotate directly.

Install the plugin

Automatic interception runs in Claude Code and fails open — if conversion is unavailable, the original file is read untouched. Desktop and Cowork convert on request through the same MCP tool.

02 · Install

Install

Set your API key, then add the plugin to Claude Code or point any MCP client at the same server. Nothing else changes about how you attach files.

shell
$ export ANNOTATE_API_KEY="mdvk_..."

Not yet listed in a Claude Code plugin marketplace. Download the plugin and follow the two setup steps in its README.

Minting a key needs an Annotate account. Conversion itself runs against the Annotate API — see Where your files go below.

03 · Mechanism

What happens on an upload

In Claude Code, a PreToolUse hook intercepts file-read calls before they resolve. If the extension is one Annotate converts, the file is converted and the Markdown enters context in its place.

Fig C.1 · interception path
attach report.pdf
more tokens
PreToolUse hook
unsupported extension → passes through
convert
fewer tokens ↓
context

The model never sees the original file. It sees Markdown with the same content and fewer tokens.

04 · Trust

Where your files go

Supported files are sent to Annotate’s conversion API and returned as Markdown. The request is proxied straight through — nothing is written to a database or storage bucket at any point.

  • 01Only files matching a supported extension are sent. Everything else never leaves your machine.
  • 02Conversion is the only operation performed. The file is proxied to the conversion service and back — nothing is indexed, stored, or read by a person.
  • 03The hook only acts on the Read tool today. Files opened another way, such as through Bash, are never intercepted.
  • 04Requests are authenticated with a personal API key from Settings → API Keys, sent as a Bearer token — the same key system used by Annotate’s public API.

The hook and MCP server ship inside the plugin bundle — read annotate-filter.py before you install it.

05 · Coverage

What converts, and what doesn’t

Text-carrying documents and images convert cleanly: specs, transcripts, contracts, handbooks, screenshots. Layout, embedded charts, and slide graphics are dropped, so a deck built on visuals loses information that Markdown cannot carry.

Converts well

.bmp.csv.docx.gif.html.jpeg.jpg.json.pdf.png.pptx.webp.xlsx.xml

Matches what GET /api/convert/extensions returns today — the hook checks this list live before converting anything.

Passes through untouched

  • plain text and source code
  • anything already Markdown
  • video and audio files
  • any extension not on the list

If a document’s meaning is in its layout, attach it as-is. Conversion helps where the content is the text.

06 · Failure

When something fails

The hook fails open. If the API key is missing, the extensions list is unreachable, the file type isn’t supported, or the convert call fails for any reason — rate limit, size limit, timeout — the original file is read unmodified.

Fig C.2 · fail-open path
attach report.pdf
PreToolUse hook
original file
convert
context

wire routes around the convert node · original file reaches context unchanged

No error is surfaced to the user for this case — the read proceeds as if nothing happened.

07 · Configuration

Configuration

There is no allowlist or size limit to tune yet — configuration today is two environment variables, set in your shell profile.

~/.zshrc (or your shell profile)
export ANNOTATE_API_KEY="mdvk_..."          # required — mint at Settings → API Keys
export ANNOTATE_API_BASE_URL="..."          # optional — defaults to getannotate.dev

08 · The rest of Annotate

After the model answers

Conversion is one half of the round trip. Annotate also reads agent output as a document, so you can highlight the lines that are wrong and send exact notes back instead of re-pasting the file.

See how the loop closes →