is-it-ai-mcp
Click on "Install 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., "@is-it-ai-mcpCheck if the image at /home/user/pic.jpg is AI-generated."
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.
is-it-ai-mcp
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.
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.
Related MCP server: image-forensics-mcp
Install
Running the server
is-it-ai-mcp is published on PyPI. Run it with:
uvx is-it-ai-mcpInstall 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:
uvx --from git+https://github.com/JohannsenLum/is-it-ai-mcp is-it-ai-mcpOr run from a local clone:
git clone https://github.com/JohannsenLum/is-it-ai-mcp
cd is-it-ai-mcp
uv syncNo account, API key, or environment variable is required. The server only reads local files you point it at.
Claude Code and Claude Desktop
{
"mcpServers": {
"is-it-ai": {
"command": "uvx",
"args": ["is-it-ai-mcp"]
}
}
}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:
{
"mcpServers": {
"is-it-ai": {
"command": "uvx",
"args": ["is-it-ai-mcp"]
}
}
}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
Verdict | Means | Reachable only when |
| The file's manifest asserts AI or algorithmic generation | A manifest is present, its signature verifies, and it carries an IPTC digital-source-type marking AI involvement |
| The file's manifest asserts a real-world capture | A manifest is present, its signature verifies, and it carries an IPTC digital-source-type marking a capture (camera, film, print, minor edits) |
| Nothing usable was established | Everything else, including no manifest, a broken signature, or a manifest that never recorded a source type |
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
uv sync --extra dev
uv run pytest -v--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.
Available Tools
2 toolscheck_image_provenanceCheck Image ProvenanceARead-onlyIdempotent
Read the C2PA Content Credential embedded in a single image file and report what it declares about the image's origin: whether it asserts AI generation or a real-world capture, and whether that assertion's cryptographic signature still verifies. This reads metadata the file already carries; it does not analyze pixels and cannot detect AI generation on its own. A missing or invalid credential is not evidence the image is human made, an AI image loses its credential the moment it is screenshotted or re-saved. Always read the result's 'what_this_does_not_mean' field before repeating its verdict.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Path to the local image file to inspect. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds significant behavioral context beyond the annotations (readOnlyHint, idempotentHint) by explaining the tool reads metadata, the caveat about screenshots, and the meaning of missing credentials. It also instructs the agent to always read the 'what_this_does_not_mean' field, which is a useful transparency detail not available from annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three well-structured sentences that front-load the main purpose and then efficiently covers caveats and an instruction. Every sentence adds necessary value with no fluff, making it appropriately sized for the tool's complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only tool with a single parameter and existing output schema, the description addresses the key pitfalls (false negatives, data loss on re-save, misinterpretation). It explains what the tool does and does not do, and points to a result field for further context, making it complete for its scope.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% as the single 'path' parameter has a description. The description text does not add extra parameter-level details, but given the high schema coverage, the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description starts with a specific verb ('Read') and detailed resource ('C2PA Content Credential embedded in a single image file'), clearly stating what the tool does and what it reports. It also distinguishes itself from being a generic image analyzer by explicitly saying it does not analyze pixels, which differentiates from sibling 'scan_directory'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context on what the tool does and its limitations (e.g., 'cannot detect AI generation on its own', 'missing or invalid credential is not evidence'). It implicitly covers when-not-to-use by warning against overreliance on its output, though it doesn't name an alternative tool or provide an explicit 'use this when' statement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
scan_directoryScan DirectoryARead-onlyIdempotent
Walk a directory of images and report how many carry a C2PA Content Credential, broken down by verdict (AI_DECLARED, NO_AI_DECLARED, UNKNOWN) and by signer. This reproduces the sweep behind this project's own finding that roughly 96.5% of real images carry no credential at all. It reads only file metadata, never pixels, and touches no network. Returns counts and a capped sample of credentialed files, not a full file listing, so a large directory does not flood the response. If the directory has more images than 'limit', the scan is partial and the result says so explicitly rather than silently truncating.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Path to the local directory to scan. | |
| limit | No | Maximum number of image files to scan. If exceeded, the scan is partial and the result says so. | |
| recursive | No | Recurse into subdirectories. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Even with annotations (readOnlyHint=true, idempotentHint=true, destructiveHint=false) already covering the safety profile, the description adds substantial behavior: 'It reads only file metadata, never pixels, and touches no network.' It also discloses the capped sample return and explicit partial-scan signaling, which go well beyond what annotations convey. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single well-structured paragraph that front-loads the core purpose, then adds useful details without fluff. Every sentence contributes either to what the tool does, its safety characteristics, or its output behavior. Length is justified by the tool's complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's moderate complexity (3 params, recursive, limit), the description covers all key aspects: purpose, partial scanning, non-flooding behavior, and safety. Since an output schema exists, the description need not explain return values in detail. The description is comprehensive for an agent to decide and invoke correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description does not add much beyond the schema for parameters; it reiterates the 'limit' behavior but that is already in the schema. It does not clarify additional nuances like how 'recursive' affects the scan or default behaviors beyond what's in the schema. Meets baseline but doesn't exceed it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description is highly specific: 'Walk a directory of images and report how many carry a C2PA Content Credential, broken down by verdict and by signer.' It clearly distinguishes from the sibling tool check_image_provenance by focusing on directory-level scanning rather than individual file checks, and explicitly notes it returns counts and a capped sample rather than a full file listing.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context for when to use the tool—reproducing a sweep for C2PA credential statistics—and notes its partial-scan behavior when limits are exceeded. However, it does not explicitly state when not to use it or mention the sibling tool as an alternative for single-image checks, so it falls short of the highest bar.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
2 tool updates
v0.1.0- First observed
check_image_provenance - First observed
scan_directory
TDQS
Scored across 2 tools
The two tools have clearly distinct purposes: one checks a single image's provenance, while the other scans a directory. There is no overlap or ambiguity between them.
Both tool names follow a consistent verb_noun pattern (check_image_provenance, scan_directory), making them predictable and easy to understand.
With exactly two tools, the set is minimal and well-scoped for the task of inspecting image provenance, covering both individual and batch operations without excess.
The tool set covers the core workflow: verifying a single image and scanning a directory, which addresses the stated purpose comprehensively. No obvious gaps exist.
Maintenance
Related MCP Connectors
Remote MCP for C2PA intake verifier MCP, structured receipts, audit logs, and reviewer-ready evidenc
Official MCP server for Certifier to issue, manage, and track certificates and badges.
Experimental MCP server for current empirical verification of explicit public HTTPS endpoint claims.
Remote MCP for C2PA disclosure policy MCP, structured receipts, audit logs, and reviewer-ready evide
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceMCP server for reading C2PA content provenance manifests from media files, enabling natural language queries about AI-generated content, signatures, and provenance.2MIT
- AlicenseNot gradedqualityDmaintenanceAn MCP server that enables AI assistants to analyze images for AI-generated content using noise maps, error level analysis, frequency analysis, spectral decay, color analysis, and metadata inspection.MIT
- AlicenseNot gradedqualityDmaintenanceMCP server for querying versioned C2PA specification knowledge graphs, enabling AI agents to browse entity definitions, validation rules, and version diffs via natural language.3Apache 2.0
- AlicenseNot gradedqualityDmaintenanceA hosted remote MCP server for C2PA disclosure policy, enabling AI governance teams to check disclosure policies, validate C2PA status, issue AI media receipts, explain region rules, and export disclosure logs.MIT