image-provenance-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@image-provenance-mcpis this image AI-generated, edited, or real? ~/Pictures/IMG_2043.jpg"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
image-provenance-mcp
Read the signature before guessing from pixels.
An MCP server for one question: is this image AI-made, edited, or real? It answers in two tiers, in the only order that makes sense:
C2PA Content Credentials — signed, machine-verifiable provenance. When the file carries a manifest, that is the answer and we stop.
Pixel heuristics — noise, ELA, spectral decay, colour, EXIF. Used only when tier 1 has nothing to say, and always labelled as a guess.
No API keys, no cloud calls, no telemetry. Tier 1 needs nothing but the Python standard library
plus the openssl binary you already have.
Why the order matters
Running this on a ChatGPT (gpt-image) PNG:
signal | says |
noise uniformity score | "natural-looking" |
no camera EXIF, square-ish crop | "suspicious" |
C2PA manifest |
|
The heuristics hedged both ways and would have produced a confident-sounding POSSIBLY AI-GENERATED. The manifest produced a fact. Same pipeline, opposite direction on a WeChat
re-upload: the messenger strips EXIF, the heuristics fire META_NO_CAMERA plus uniform ELA, and
you get an AI accusation built entirely from metadata that was removed in transit.
Heuristics describe artifacts; C2PA describes authorship. Do not let the first impersonate the second.
Related MCP server: c2pa-mcp
Tools
tool | tier | what it returns |
| 1 → 2 | the whole pipeline, tier 1 first; stubs out tier 2 if a manifest exists |
| 1 | signed provenance only — faster, and works with zero pixel deps |
| 2 | all heuristic analysers plus a combined verdict |
| 2 | the individual analysers |
Tier-2 tools are vendored from surewht/image-forensics-mcp
(MIT — see NOTICE.md). They need the [pixel] extra; without it they simply are not
registered and the C2PA tools keep working.
Verdicts (tier 1)
verdict | meaning |
| the signer declares |
| signed action history contains |
| only capture-side actions were signed |
| manifest present but pixels no longer match the signed hash — modified after signing |
| nothing signed in this file — says nothing about authenticity |
Install
git clone https://github.com/DanZai233/image-provenance-mcp
cd image-provenance-mcp
pip install -e '.[pixel]' # omit [pixel] for C2PA onlyNo network to a package index? Skip packaging entirely and run from the tree:
PYTHONPATH=src python -m provenance_mcp photo.jpg
PYTHONPATH=src python -m provenance_mcp --mcp # stdio MCP serverTier 1 needs only the standard library and openssl, so that works on a bare
interpreter.
CLI
image-provenance photo.jpg # tier 1, then tier 2 if needed
image-provenance photo.jpg --mode c2pa # signature only
image-provenance photo.jpg --mode pixels
image-provenance photo.jpg --json # parsed manifest as JSON
image-provenance --mcp # stdio MCP serverExit codes: 0 a manifest was found, 1 no manifest, 2 usage error.
Wire it into an MCP client
Generic stdio config:
{
"mcpServers": {
"image-provenance": {
"command": "image-provenance",
"args": ["--mcp"]
}
}
}DeepSeek Harness (~/.dsh/profiles/web/cordis.patch.yml):
- insert:
- id: mcp-image-provenance
name: '@deepseek-ai/dsh-mcp-client'
config:
serverName: image_provenance
transport: stdio
command: image-provenance
args: ['--mcp']
toolCallTimeoutMs: 180000Check the wiring without any SDK — the probe speaks raw JSON-RPC over stdio:
python examples/probe_mcp.py image-provenance --mcpAgent skill: forensic triage
The CLI answers "what does this file prove". The hard part is everything around it: deciding what to run first, which findings to trust, and how far the evidence can be pushed before the answer becomes a lie. That reasoning is packaged as a skill your agent can load.
skills/image-forensic-triage/
├── SKILL.md # the protocol: tier 1 → tier 2 → human layer → grade
├── references/
│ ├── evidence-grading.md # A/B/C/D, and what each grade may NOT be used for
│ ├── false-positives.md # seven failures observed in real files, with the numbers
│ └── worked-examples.md # three cases end to end, including a wrong first answer
└── scripts/triage.py # batch ledger → markdown + jsonGive it to an agent (Claude Code, DSH and anything else that reads ~/.dsh/skills or a repo
skills/ folder) either in place or by symlink:
ln -s "$PWD/skills/image-forensic-triage" ~/.dsh/skills/image-forensic-triageThen a plain question gets a graded answer instead of a guess:
python skills/image-forensic-triage/scripts/triage.py inbox/*.jpg| file | size | dims | C2PA | notes | grade |
|---|---|---|---|---|---|
| `hmi.jpg` | 100 KB | 540×618 | none | annotation #ba1807×4630; EXIF stripped | C (vector annotation present — not the camera original) |
| `doc.jpg` | 461 KB | 1773×2364 | none | EXIF stripped; block-noise outlier ×40.49 | C (no EXIF; cannot exclude re-encoding) |
| `signed.png` | 1852 KB | 841×1870 | AI_GENERATED (OpenAI Media Service API) | block-noise outlier ×28.28 | A (signed, pixel hash verified) |The script is the deterministic part; SKILL.md is what keeps an agent from reporting the middle
row as "authentic" and the first row as "AI-generated".
What is actually verified
The test suite builds its own fixtures byte by byte (tests/fixture_builders.py); no
photograph is committed. That proves the reader handles the structure, not that any
particular vendor's output is genuine — for that, run it on a file you already trust.
test | result |
synthetic manifest, bound to its pixels |
|
tamper: flip one byte inside IDAT, keep the manifest |
|
PNG without a manifest |
|
truncated file |
|
real-world check (maintainer, out of tree) | a ChatGPT/gpt-image PNG read as |
27 unit tests |
|
Limitations (read these)
No cryptographic signature verification. This tool checks the sha256 hard binding and prints the COSE
x5chain; it does not verify the signature, check revocation, or validate against a trust anchor. SoINVALID_HASHis trustworthy (pure hashing), while "this chain is genuine" is currently only "this chain looks right". For the full check usec2patoolorc2pa-python.C2PA presence is not C2PA ubiquity. Most cameras, every messenger, every screenshot pipeline and every CDN re-encode strips manifests.
NO_C2PAis the common case, not a red flag.JPEG APP11 multi-segment reassembly follows the spec but has no end-to-end test with a real signed JPEG; only PNG manifests were validated here.
Old XMP-embedded
c2pafields (early Adobe style) are not parsed; only JUMBF.Tier-2 thresholds are upstream's and were tuned on a small sample. Treat every tier-2 verdict as a hint.
Tier 2 needs
numpy,scipy,pillow.
License
MIT for this project. Vendored tier-2 code is MIT, © 2026 surewht — see NOTICE.md and LICENSES-image-forensics-mcp.txt.
This server cannot be deployed
Maintenance
Related MCP Connectors
Verify photos are real camera captures, not AI: C2PA and RAW+JPEG forensics. OAuth or API key.
Inspect and remove C2PA content credentials from AI-generated images, video and audio. Free, no key.
Free read-only checks for evidence of AI use in text, links, images, saved prompts and C2PA.
51Free C2PA 2.4 triage and reproducible official trust snapshot. No media, keys, or payment.
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables reading and verifying C2PA Content Credentials from images and videos through both embedded manifests and invisible watermarks. Supports direct filesystem access, URL checking, and provides structured provenance data including creator identity, AI generation info, and content authenticity.2MIT
- AlicenseAqualityBmaintenanceVerifies C2PA Content Credentials for local files or URLs and returns an LLM-ready verdict on trust, AI generation, and provenance.411 npm2Apache 2.0
- AlicenseAqualityDmaintenanceProvides MCP-compatible AI agents with a verify_image tool to check a photo's capture time and provenance using C2PA, EXIF, XMP metadata, and pixel forensics, returning a verdict and confidence score.116 npm2MIT
- AlicenseNot gradedqualityBmaintenanceProvides AI content watermarking and C2PA compliance for EU AI Act Article 50, enabling detection, verification, and batch processing of authenticated content.2 npmMIT