
Is It AI MCP
io.github.JohannsenLum由 GitHub 账号 JohannsenLum 发布v0.1.0更新于 Oct 24, 2026
MCP server that reads C2PA Content Credentials: what an image declares about its own origin
概览
读取图片中嵌入的 C2PA 内容凭证,报告文件对自身来源的声明,以及该签名是否仍然有效。
- 可以做什么
- 提供两个工具。check_image_provenance 接收一个图片文件路径,返回判定结果(AI_DECLARED、NO_AI_DECLARED 或 UNKNOWN)、判定依据、原始签名验证状态,以及声明的签名者、声明生成器、签名时间和 IPTC 来源类型。scan_directory 遍历文件夹,对找到的每张图片执行相同检查,返回按判定和签名者汇总的计数以及有上限的样本。它只读取签名清单,不分析像素,也不根据视觉痕迹猜测。
- 适用场景
- 当助手需要查看图片内嵌的来源记录,而不是根据外观推断是否为 AI 生成时适用,例如检查单个文件或扫描整个图片目录。由于带凭证的图片很少,大多数文件会返回 UNKNOWN。
- 运行要求
- 以 PyPI 包 is-it-ai-mcp 通过 stdio 在本地运行,使用 uvx 启动,因此需要带 uv/uvx 的 Python 环境。无需账号、API 密钥或环境变量。它需要磁盘上的真实文件路径,而不是内联图片字节,因此粘贴的图片必须先保存到磁盘。
安装
在 SourceWeft 中
- 打开 控制台中的 Is It AI MCP,将其添加到工作区。
- 为需要使用其工具的对话启用该服务。
Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。
其他 MCP 客户端
参照 仓库 中的启动说明。
README
is-it-ai-mcp
Read the file's own claim about itself, and check whether that claim still holds.
An image can carry a signed Content Credential declaring how it was made.
This server reads it, checks the signature against the bytes, and hands both
back to your AI assistant, which cannot see either on its own.
An MCP server that reads the C2PA Content Credential embedded in an image and reports what the file declares about its own origin, plus whether that declaration still verifies against the bytes in front of you.
📖 Documentation: mcp.johannsenlum.com/is-it-ai · install guide · tool reference
🔍 Try it without installing anything: ai.johannsenlum.com/is-it-ai runs the same checks in your browser, on your machine, with nothing uploaded.
[PyPI] [Python 3.11+] [License: MIT]
What it does
It opens an image, looks for an embedded C2PA manifest (a Content Credential), and if one exists, reports two separate things: what the manifest claims about how the image was made, and whether the cryptographic signature over that manifest still matches the file's current bytes. It does not look at pixels and it does not guess. If there is no manifest, or the manifest exists but the signature is broken, it says so plainly instead of inventing an answer.
See docs/pass-fail.md for why "the signature verified" and "the claim is true" are two different questions, and why this server only ever answers the first one.
Install
Running the server
is-it-ai-mcp is published on PyPI. Run it with:
Install from source (contributors / unreleased main). Not part of the normal
install path above, only needed if you want the latest unreleased code instead of the
published PyPI release:
Or run from a local clone:
No account, API key, or environment variable is required. The server only reads local files you point it at.
Claude Code and Claude Desktop
Claude Code: ~/.claude.json
Claude Desktop: claude_desktop_config.json
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
Copy this JSON in via Settings → Developer → Edit Config:
Tools
check_image_provenance
Give it the path to one image file on disk. It returns:
verdict: one of the three states below (AI_DECLARED,NO_AI_DECLARED,UNKNOWN).reason: the specific basis for that verdict, for exampleno-credential,credential-invalid,ai-source-type,capture-source-type, orcredential-silent.what_this_does_not_mean: a plain-language caveat attached to every verdict, so the result cannot be quietly upgraded into a stronger claim than the evidence supports.signature: the rawvalidation_state, averifiedboolean, and anyfailure_codesthe signature check produced.declared: what the manifest claims when one exists.signer,claim_generator, andsigned_atare free text pulled straight from the file, so each is guarded per the Security section below before it reaches you.source_types(IPTC digital-source-type URIs, drawn from a closed vocabulary) andwatermark_declared(a boolean) cannot carry attacker-authored text, so both are returned as-is and are never fenced.
A file that cannot be read (bad path, unsupported format) comes back as a distinct
error result rather than a fake UNKNOWN. It needs a real path on disk, not the image
bytes themselves. See Note on file paths.
scan_directory
Give it a folder. It walks the tree, runs every image it finds through the same check, and returns aggregate counts by verdict and by signer, plus a capped sample of the files that carried a credential, rather than a line per file. This is the tool that reproduces this project's own 401-image sweep (see below) against any directory you point it at.
The three verdicts
UNKNOWN is the default and by far the most common answer. In a scan of 401 real
images, only 14 carried a Content Credential at all, and every one of those was from
OpenAI: about 96.5% had no credential whatsoever. Expect UNKNOWN on almost everything
you check. That is not a bug in this server, it is the current state of image
provenance in the wild.
What this cannot tell you
- It does not detect AI from pixels. There is no image analysis here at all, no model looking at the picture. Every verdict comes from a cryptographically signed text record, or from the absence of one.
- A missing credential is not evidence of anything. An unmarked AI image and an
unmarked photograph are indistinguishable to this tool. Screenshotting, re-saving, or
passing an image through almost any editor strips the credential, AI-made or not.
UNKNOWNmeans "no usable record survived," never "no AI was involved." - A valid signature does not make the signer's claims true. The signature proves the manifest has not been altered since it was signed and confirms who signed it. It proves nothing about whether the signer told the truth. Anyone can generate their own certificate, sign their own file, and assert whatever origin they like: it will verify perfectly and still be false. Verification is about the seal, not the letter. See docs/pass-fail.md.
Why it exists
When you attach an image to a model, the image is decoded to pixels and re-encoded before the model ever sees it. Container metadata, including any C2PA manifest, never reaches the model: the model sees an RGB array, nothing more. Without a tool, it cannot read a manifest at all, and it will tend to guess whether an image is AI-generated from visual artefacts instead. Published benchmarks put that guess at roughly 18 to 31% accuracy, little better than chance. This server exists so the model reads the actual signed record on disk instead of pattern-matching on JPEG compression artefacts.
Security
Every human-readable string returned by this server originated inside the file being inspected: signer name, claim-generator string, and any free-text reason or label. That text was written by whoever produced the file, not by you, and it lands in the same context window as your own instructions. A field labelled "signer" carries an air of verified authority, but the signature covers the asset's bytes, not the honesty of any string inside the manifest. Anyone can sign their own file with their own certificate and write anything they like in it.
Before any such string is returned, it is cleaned of control characters, length-capped, and wrapped in a fenced boundary that marks it explicitly as untrusted data rather than instructions, with a random nonce the file's author could not have pre-guessed. Structural values, the verdict itself, the validation state, and the IPTC source-type URIs are drawn from closed vocabularies this server controls and are never fenced, since they cannot carry attacker-authored text.
See src/is_it_ai_mcp/safety.py for the implementation
and the full threat model in its module docstring.
Note on file paths
This tool takes a file path, not image bytes. In Claude Code, an image you paste into the conversation is written to disk first, so its path is reachable and this just works. In other clients, a pasted or attached image may exist only as inline data with no path on the filesystem the server can reach, in which case there is nothing for this tool to open. If a check comes back unable to find the file, save the image to disk first and point the tool at that path.
Development
--extra dev matters: without it, pytest-asyncio (needed for asyncio_mode = "auto"
in pyproject.toml) is not installed, and pytest prints an "Unknown config option:
asyncio_mode" warning on every run.
Tests run against the fixtures in fixtures/, a real signed image plus
tampered and stripped variants with hand-verified expected outcomes. See
fixtures/GROUND-TRUTH.md for how each was produced and
what each is expected to prove.
Licence
MIT © 2026 Johannsen Lum.
Use it, change it, redistribute it, build something commercial on it: the only condition is that you keep the copyright notice and licence text. It comes with no warranty of any kind.
Contributions are accepted under the same licence.
来源:README.md,提交 f587c10
工具
0版本历史
1- v0.1.0最新Sep 16, 2026
评分
已满足适用检查项的 50%
该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。
- 近 30 天内可连通25 分
请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。
- 已声明认证方式10 分
请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。
- 已列出工具15 分
请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。
- 描述必需15 分
- 图标10 分
- 文档15 分
- 许可证10 分