Figma Context MCP
Give your coding agent access to your Figma data. Implement designs in any framework in one-shot.
Description from the maker (original English)
Invisible per-recipient image watermarks. Mark one copy per recipient, then identify a leaked copy.
These three are never merged into one score: opinions, measurements and popularity are different things.
We have not written a plain-language summary for this one yet. Below are the facts we read from the registry.
Pick the AI app you use, then copy the settings.
You need
Which app do you use?
Pick your app above. We remember it, so next time the button says “Install in …”.
Open Claude Desktop → Settings → Developer → Edit Config, and paste this into claude_desktop_config.json
{
"mcpServers": {
"faintmark": {
"command": "uvx",
"args": [
"faintmark",
"mcp"
]
}
}
}Run this in your terminal
claude mcp add faintmark -- uvx faintmark mcpPaste into .cursor/mcp.json in your project, or ~/.cursor/mcp.json
{
"mcpServers": {
"faintmark": {
"command": "uvx",
"args": [
"faintmark",
"mcp"
]
}
}
}Your browser asks to open the app, then the app shows the settings and asks you to confirm. Key values are left empty for you to fill in.
Paste into .vscode/mcp.json in your project
{
"servers": {
"faintmark": {
"type": "stdio",
"command": "uvx",
"args": [
"faintmark",
"mcp"
]
}
}
}Your browser asks to open the app, then the app shows the settings and asks you to confirm. Key values are left empty for you to fill in.
This one runs on your computer, and ChatGPT can only connect to servers on the internet. Pick another app.
Your choice stays on this device in a cookie; no account needed.
These settings are generated from the maker’s registry entry. If the README says otherwise, follow the README.
Runs on your computer; the tool list appears in your AI app after you install it.
We check information anyone can see; we have not read the code. Checks that do not apply are left out of the count. · Checked Nov 7, 2026
The registry name was verified with the GitHub account matchalatteguy, which owns the repo
We have not read this repo from GitHub yet
We have not read this repo from GitHub yet
This one runs on your computer; there is no internet endpoint
Runs on your computer and uses local settings instead
Runs on your computer; we can only read tool lists from internet endpoints
Compared with every active server in this category in the registry. Stars count only when the publisher owns the repo.
It passed 1 of 1 applicable basic checks. We have not read the code. Before adding a key or token, see what access the server asks for and use a key with only the permissions you need.
The registry does not list a required key, though some servers ask you to sign in on first use.
It runs on your computer. Your AI app starts it when needed, and data does not pass through the maker’s servers (unless it calls an online service itself).
The GitHub repo last changed –, and the latest version (0.1.0) reached the registry 27 days ago.
Apps that support MCP, such as Claude Desktop, Claude Code, Cursor and VS Code. You also need Python (uv) on your computer.
In the same category: Figma Context MCP, Claude Real Video, Figma MCP Server
Servers in the same category from other makers, sorted by stars.
Reading a card:★ GitHub starsiThree pillars: reviews · checks · usageiUpdated = latest version published to the registryi
Give your coding agent access to your Figma data. Implement designs in any framework in one-shot.
Let any LLM watch a video locally — and search everything it has ever watched.
Figma’s official server gives AI your design data so it can turn designs into code or describe them accurately. Connects to Figma’s cloud.
Copied from the maker’s repo as written. PopNx MCP has not reviewed or endorsed it. HTML, images and scripts are removed. Links lead off this site.
Invisible per-recipient image watermarks. Create one marked copy per recipient, then identify which copy a shared or leaked image is. Designed to tolerate the recompression and resizing chat apps apply; see the app tests and limits below. Runs locally, no account, no upload. Python CLI and MCP server.
$ faintmark mark photo.jpg alice bob
alice 991e318a21 /Users/me/Pictures/marked/photo-991e318a21.jpg bob 746ac9fa88 /Users/me/Pictures/marked/photo-746ac9fa88.jpg 2 copies in /Users/me/Pictures/marked
$ faintmark check ~/Downloads/forwarded.jpg matched: alice 991e318a21 marked 2026-10-06T23:11:54Z
Send each person only their own file; file names carry the id, not the name. A match identifies the label the copy was issued under, not who shared it. The mark is intended to be visually unobtrusive on photographs. JPEG, PNG and WebP keep their format; HEIC becomes JPEG.
uvx faintmark mark photo.jpg alice bob # runs without installing; needs uv
uv tool install faintmark # or: pipx install faintmark
Python 3.11 or newer on macOS, Linux or Windows (Intel Macs: 3.11 to 3.13). uv can install Python and run FaintMark. The first mark or check downloads Adobe's TrustMark Q models (65 MB, SHA-256 verified) into ~/.faintmark. For HEIC input install faintmark[heic]: uv tool install 'faintmark[heic]', or without a persistent install uvx --from 'faintmark[heic]' faintmark mark photo.heic alice. uv tool uninstall faintmark removes the command and leaves ~/.faintmark in place.
faintmark mark IMAGE RECIPIENT... [-o DIR] [--format png|jpeg|webp] [--json]
faintmark check IMAGE [--deep] [--files] [--json] faintmark list [-n N] [--files] [--json]
Copies go into marked/ beside the image unless -o says otherwise. Quote labels with spaces: faintmark mark photo.jpg 'Alice Smith'. One run marks 1 to 100 recipients. --json prints the result the matching MCP tool returns; mark includes the source file name and output paths, check and list omit file names and paths unless --files is set. check --deep also tries a flip and small rotations, and when nothing is detected lists up to three registered ids within 26 of 96 codeword bits of the raw decoder output as candidates, with their bit distance. Those are uncalibrated and can be coincidental or forged; they are never a match. With --json, errors print {"error": "..."}. check exits 0 for matched, 1 for unregistered or not_detected, 2 for an error.
mark accepts non-animated JPEG, PNG, WebP and HEIC up to 25 megapixels without transparency (16-bit RGB is read at 8 bits; 16-bit grayscale and CMYK are rejected) and needs about 1.5 GB of memory at that size. check reads the first frame of anything Pillow opens, up to 100 megapixels.
claude mcp add --scope user faintmark -- uvx faintmark mcp
codex mcp add faintmark -- uvx faintmark mcp gemini mcp add -s user faintmark uvx faintmark mcp
Any other client that reads an mcpServers config (Claude Desktop, Cursor, Windsurf): add this entry to the client's MCP configuration. The client must find uvx on its PATH; set FAINTMARK_HOME in the server's environment to use another registry.
{ "mcpServers": { "faintmark": { "type": "stdio", "command": "uvx", "args": ["faintmark", "mcp"] } } }
Choose one route per client; plugins and extensions bundle the skill too. For HEIC input start the server as uvx --from 'faintmark[heic]' faintmark mcp; the bundled launchers use the base package.
claude plugin marketplace add matchalatteguy/FaintMark then claude plugin install faintmark@faintmarkcodex plugin marketplace add matchalatteguy/FaintMark then codex plugin add faintmark@faintmarkgemini extensions install https://github.com/matchalatteguy/FaintMarknpx skills add matchalatteguy/FaintMark| Tool | Arguments | Returns |
|---|---|---|
mark_image | image_path, recipients, optional output_dir, format | output folder and each copy's id, path, warnings |
check_image | image_path, optional files, deep | status of matched (with recipient, id, marked_at, and same_image when a stored hash exists), unregistered (with id) or not_detected; with deep, transform naming the flip or rotation that recovered the result, and suspects (id, recipient, bit_errors, same_image) plus registry_size when nothing was detected |
list_copies | optional limit, files | registered copies, newest first |
Give tools absolute paths. unregistered means an id was decoded but it is not in this machine's registry; not_detected means no readable mark, which says nothing about where the image came from. same_image compares perceptual hashes with the issued copy: false means they differ beyond the threshold, which cropping or an id copied into another picture can cause; the comparison can also miss differences.
check_image and faintmark check --json return one of these: the three plain statuses (a match with same_image: false means the picture differs from the issued copy); with deep, a result recovered by a transform, or a miss with candidates (suspects is empty when no registered id is within the cutoff). The CLI prints errors as the last line; MCP tools raise them as tool errors (isError): messages from the service match, argument validation messages differ.
{"status": "matched", "id": "991e318a21", "recipient": "alice", "marked_at": "2026-10-06T23:11:54Z", "same_image": true}
{"status": "matched", "id": "991e318a21", "recipient": "alice", "marked_at": "2026-10-06T23:11:54Z", "same_image": false} {"status": "unregistered", "id": "3123f6f877"} {"status": "not_detected"} {"status": "matched", "id": "991e318a21", "recipient": "alice", "marked_at": "2026-10-06T23:11:54Z", "same_image": true, "transform": "rotated 4"} {"status": "not_detected", "suspects": [{"id": "991e318a21", "recipient": "alice", "bit_errors": 21, "same_image": true}], "registry_size": 100} {"error": "forwarded.jpg: no such file"}
mark_image and faintmark mark --json return the first line; list_copies and faintmark list --json return the second, newest first:
{"original": "photo.jpg", "output_dir": "/Users/me/Pictures/marked", "copies": [{"id": "991e318a21", "recipient": "alice", "path": "/Users/me/Pictures/marked/photo-991e318a21.jpg", "warnings": []}]}
{"copies": [{"id": "991e318a21", "recipient": "alice", "marked_at": "2026-10-06T23:11:54Z", "warnings": []}]}
7 October 2026, FaintMark 0.1.0, three source photos (an iPhone scene, a CC0 portrait, a CC0 sunset). Each row reports the samples actually sent on that route at default photo quality. Screenshot rows are screenshots of the receiving phone, cropped to the photo before checking. These are individual round-trip observations, not recovery rates or guarantees for an app.
| Route | Received | Result |
|---|---|---|
| WhatsApp photo, all three | long edge 1600 px, 155 to 317 KB | matched 3/3 |
| Discord attachment, scene | original size, 1.7 MB | matched 1/1 |
| Discord sticker made from the scene | 217x285 PNG | matched 1/1 |
| Telegram photo, scene | 960x1280, 102 KB | matched 1/1 |
| WeChat photo, portrait and sunset | long edge 1644 to 1920 px, 67 to 302 KB | matched 2/2 |
| Instagram DM, portrait | 1206x804, 176 KB | matched 1/1 |
| Chat screenshots on WhatsApp, Discord, Telegram, WeChat, Instagram | photo long edge 286 to 1022 px | matched 9/9 |
| Tinder profile card, portrait (screenshot) | heavy crop | not detected 0/1 |
Every match also reported same_image: true. The originals, every received file, the screenshots, the crops and a manifest of expected ids and results (docs/evidence-2026-10-07.json) are in the evidence release. On a machine without this registry, the received files return unregistered with the id from the manifest; the originals and the Tinder crop return not_detected. X, Signal, iMessage and Instagram stories were not tested.
TrustMark Q (Adobe, MIT) embeds a 40-bit id as an image-wide pattern designed to tolerate JPEG recompression, WebP conversion and moderate resizing. This is forensic watermarking, not steganography: anyone with TrustMark can read the id; only your registry maps it to a name. FaintMark draws a random id per recipient, writes the copy in the source format (JPEG at the source's own quantization tables, PNG, WebP; HEIC becomes JPEG), decodes the saved copy to verify its id is recoverable, and records id, recipient, file and a perceptual hash of the copy in a local SQLite registry. On a registered match, check compares perceptual hashes and reports same_image: false when their distance exceeds the threshold. A JPEG whose source settings lose the mark is saved at quality 95 instead, and says so in its warnings. Marking an image that already carries a mark replaces it and says so. A preflight re-encodes each copy at JPEG quality 70, at full size (skipped with a warning when a side exceeds 65,500 px, JPEG's limit) and resized to 1280 px (half size when the image is smaller), and warns when the id does not survive; send those copies as a file rather than a photo.
ICC profiles are kept so Display P3 photos stay the same colour. EXIF and other metadata are not copied.
Compatibility with Adobe's implementation is checked in: tests/fixtures holds BCH vectors and two images marked by upstream TrustMark 0.9.2; FaintMark decodes their ids and reproduces their marked pixels within one value per RGB channel. A chat-app style ladder in the real-model tests (resize to 1600, 1280 and 1024 px with JPEG 70 to 80, WebP 75, and a chained resize-plus-JPEG pass, on delivered JPEG bytes) recovers the id on two 12-megapixel synthetic covers and the 320 px fixture, except WebP 75 on the fixture.
Someone who has this repository and a copy can do the following; measured on three photos at 2000 px, two ids each, full tables in the attack report attached to the evidence release.
check then says not_detected, exactly as for an unmarked photo.check --deep lists at least one colluder in 253 ofOnly the beginning is shown; read the rest in the repo