{"_id":"@c2paviewer/c2pa-mcp","_rev":"6-20c6019380402b7e732f7f0e506ec61e","name":"@c2paviewer/c2pa-mcp","dist-tags":{"latest":"0.2.1"},"versions":{"0.1.0":{"name":"@c2paviewer/c2pa-mcp","version":"0.1.0","keywords":["c2pa","mcp","model-context-protocol","content-credentials","provenance","ai-detection","content-authenticity","deepfake"],"author":{"name":"c2paviewer.com"},"license":"MIT OR Apache-2.0","_id":"@c2paviewer/c2pa-mcp@0.1.0","maintainers":[{"name":"harelrech","email":"harelrech@gmail.com"}],"homepage":"https://github.com/harelrech/c2pa-mcp#readme","bugs":{"url":"https://github.com/harelrech/c2pa-mcp/issues"},"bin":{"c2pa-mcp":"dist/index.js"},"dist":{"shasum":"02d4016f19903bf41fda337a39a4ed86c1a708a4","tarball":"https://registry.npmjs.org/@c2paviewer/c2pa-mcp/-/c2pa-mcp-0.1.0.tgz","fileCount":32,"integrity":"sha512-DiIXF74HQT2uIHvHQ/cfcBOALwVUoZKHGDnIP58bUI8qS34kOlYZXofeGovsk4pBM2mq8KetPGA3UQPmVn5c8w==","signatures":[{"sig":"MEYCIQCOdM/krGeI6vnQZx6z/Ha/Sedk4Ppl04gsZG/2QwOsmAIhAOj1Z0yT0371qGDXLuksen041Ghnn8LvC34V2fFhDOAX","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":109719},"type":"module","engines":{"node":">=18"},"gitHead":"a624e49d5a507b01d046f715ae011f58adca2670","scripts":{"test":"npm run build && node --test","build":"tsc","start":"node dist/index.js","prepublishOnly":"npm run build"},"_npmUser":{"name":"harelrech","email":"harelrech@gmail.com"},"repository":{"url":"git+https://github.com/harelrech/c2pa-mcp.git","type":"git"},"_npmVersion":"11.7.0","description":"An open-source MCP server that verifies C2PA content credentials and returns LLM-ready provenance verdicts. Built by c2paviewer.com.","directories":{},"_nodeVersion":"24.12.0","dependencies":{"zod":"^3.23.8","undici":"^6.26.0","@contentauth/c2pa-node":"^0.5.5","@contentauth/c2pa-types":"^0.6.0","@modelcontextprotocol/sdk":"^1.12.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.5.0","@types/node":"^20.14.0"},"_npmOperationalInternal":{"tmp":"tmp/c2pa-mcp_0.1.0_1781503962275_0.5325233347161409","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@c2paviewer/c2pa-mcp","version":"0.1.1","keywords":["c2pa","mcp","model-context-protocol","content-credentials","provenance","ai-detection","content-authenticity","deepfake"],"author":{"name":"c2paviewer.com"},"license":"MIT OR Apache-2.0","_id":"@c2paviewer/c2pa-mcp@0.1.1","maintainers":[{"name":"harelrech","email":"harelrech@gmail.com"}],"homepage":"https://github.com/harelrech/c2pa-mcp#readme","bugs":{"url":"https://github.com/harelrech/c2pa-mcp/issues"},"bin":{"c2pa-mcp":"dist/index.js"},"dist":{"shasum":"c79d5ba486acd127d4a61e15f39f9ad6f7a55365","tarball":"https://registry.npmjs.org/@c2paviewer/c2pa-mcp/-/c2pa-mcp-0.1.1.tgz","fileCount":32,"integrity":"sha512-JLTxtT/v32cWX1NnXGA9MvaNHqJU5/Op5sbYmcVAoqegK7D1RvfZlv6wGlVSSSKqquXPY199sHDnTpo8MXh0EQ==","signatures":[{"sig":"MEUCIBbHU2A5TXQNMIPG2jSEbmV5DooEazvj0cmQTNkK/2TBAiEAtHlXIAgxON/QQSbXJ8UhlMyxm8LnRBLdg4V21O3321Y=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":109719},"type":"module","engines":{"node":">=18"},"gitHead":"fd19ed50f9a94155ca6a181716b8760dac989da2","scripts":{"test":"npm run build && node --test","build":"tsc","start":"node dist/index.js","prepublishOnly":"npm run build"},"_npmUser":{"name":"harelrech","email":"harelrech@gmail.com"},"repository":{"url":"git+https://github.com/harelrech/c2pa-mcp.git","type":"git"},"_npmVersion":"11.7.0","description":"An open-source MCP server that verifies C2PA content credentials and returns LLM-ready provenance verdicts. Built by c2paviewer.com.","directories":{},"_nodeVersion":"24.12.0","dependencies":{"zod":"^3.23.8","undici":"^6.26.0","@contentauth/c2pa-node":"^0.5.5","@contentauth/c2pa-types":"^0.6.0","@modelcontextprotocol/sdk":"^1.12.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.5.0","@types/node":"^20.14.0"},"_npmOperationalInternal":{"tmp":"tmp/c2pa-mcp_0.1.1_1782064504245_0.7078295383282085","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@c2paviewer/c2pa-mcp","version":"0.1.2","keywords":["c2pa","mcp","model-context-protocol","content-credentials","provenance","ai-detection","content-authenticity","deepfake"],"author":{"name":"c2paviewer.com"},"license":"MIT OR Apache-2.0","_id":"@c2paviewer/c2pa-mcp@0.1.2","maintainers":[{"name":"harelrech","email":"harelrech@gmail.com"}],"homepage":"https://github.com/harelrech/c2pa-mcp#readme","bugs":{"url":"https://github.com/harelrech/c2pa-mcp/issues"},"bin":{"c2pa-mcp":"dist/index.js"},"dist":{"shasum":"b43a2cdb7e445e6f0ccfe89b89421b69c6f75f40","tarball":"https://registry.npmjs.org/@c2paviewer/c2pa-mcp/-/c2pa-mcp-0.1.2.tgz","fileCount":32,"integrity":"sha512-pUjVcliSoCmmzJ2CdhwcODN4vt8G7YEnxGg1cO67J9YnIySeXBDk52PI92MrEbAGUhnQb9smO5qFcqqvR3O8/w==","signatures":[{"sig":"MEUCIGvqDQZTsJyE+N6AHye5rp9wXqVHiXItB14avpZLeXIbAiEA9cG6yxGaOKPfT124VUA6MD5c/KYqSfTfDuH+phzdevA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":112439},"type":"module","engines":{"node":">=18"},"gitHead":"5f913dc4fcda27f9b61faa32393c9319b2f60565","scripts":{"test":"npm run build && node --test","build":"tsc","start":"node dist/index.js","prepublishOnly":"npm run build"},"_npmUser":{"name":"harelrech","email":"harelrech@gmail.com"},"repository":{"url":"git+https://github.com/harelrech/c2pa-mcp.git","type":"git"},"_npmVersion":"11.7.0","description":"An open-source MCP server that verifies C2PA content credentials and returns LLM-ready provenance verdicts. Built by c2paviewer.com.","directories":{},"_nodeVersion":"24.12.0","dependencies":{"zod":"^3.23.8","undici":"^6.26.0","@contentauth/c2pa-node":"0.5.5","@contentauth/c2pa-types":"^0.6.0","@modelcontextprotocol/sdk":"^1.12.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.5.0","@types/node":"^20.14.0"},"_npmOperationalInternal":{"tmp":"tmp/c2pa-mcp_0.1.2_1782064615269_0.5818539452433267","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@c2paviewer/c2pa-mcp","version":"0.1.3","keywords":["c2pa","mcp","model-context-protocol","content-credentials","provenance","ai-detection","content-authenticity","deepfake"],"author":{"name":"c2paviewer.com"},"license":"MIT OR Apache-2.0","_id":"@c2paviewer/c2pa-mcp@0.1.3","maintainers":[{"name":"harelrech","email":"harelrech@gmail.com"}],"homepage":"https://github.com/harelrech/c2pa-mcp#readme","bugs":{"url":"https://github.com/harelrech/c2pa-mcp/issues"},"bin":{"c2pa-mcp":"dist/index.js"},"dist":{"shasum":"1f319007d5177045fdb09d0deb5b366d601986da","tarball":"https://registry.npmjs.org/@c2paviewer/c2pa-mcp/-/c2pa-mcp-0.1.3.tgz","fileCount":34,"integrity":"sha512-skYAHMc8LeZr6U/VxeoUPnrqaZhtKIa+p+yweXDfwTnDDEc/x3FmNBqdzDesTJYVEXoengr6BfxAVNS9I/fOGA==","signatures":[{"sig":"MEQCIGod/mLZ+arDiCcDBOXT0sQ7yCg2pVRsppgWQdp5In3KAiBMa1Tw5U35dbgSakN3a+r+ZsfYBO0PP+4f35YudSci9A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@c2paviewer%2fc2pa-mcp@0.1.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":120361},"type":"module","engines":{"node":">=18"},"gitHead":"22277ee4caca29e0193fa95ffe0789e057c03bf7","scripts":{"test":"npm run build && node --test","build":"tsc","start":"node dist/index.js","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:7bc8d00a-8366-43d3-9d30-3d8bb8d959dd"}},"repository":{"url":"git+https://github.com/harelrech/c2pa-mcp.git","type":"git"},"_npmVersion":"12.0.1","description":"An open-source MCP server that verifies C2PA content credentials and returns LLM-ready provenance verdicts. Built by c2paviewer.com.","directories":{},"_nodeVersion":"22.23.1","dependencies":{"zod":"^3.23.8","undici":"^6.26.0","@contentauth/c2pa-node":"0.5.5","@contentauth/c2pa-types":"^0.6.0","@modelcontextprotocol/sdk":"^1.12.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.5.0","@types/node":"^20.14.0"},"_npmOperationalInternal":{"tmp":"tmp/c2pa-mcp_0.1.3_1784878306627_0.03461643046272522","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@c2paviewer/c2pa-mcp","version":"0.2.0","keywords":["c2pa","mcp","model-context-protocol","content-credentials","provenance","ai-detection","content-authenticity","deepfake"],"author":{"name":"c2paviewer.com"},"license":"MIT OR Apache-2.0","_id":"@c2paviewer/c2pa-mcp@0.2.0","maintainers":[{"name":"harelrech","email":"harelrech@gmail.com"}],"homepage":"https://github.com/harelrech/c2pa-mcp#readme","bugs":{"url":"https://github.com/harelrech/c2pa-mcp/issues"},"bin":{"c2pa-mcp":"dist/index.js"},"dist":{"shasum":"fdbc37756bc3e16220519292534f3e8496a68d43","tarball":"https://registry.npmjs.org/@c2paviewer/c2pa-mcp/-/c2pa-mcp-0.2.0.tgz","fileCount":36,"integrity":"sha512-E5KfwGwBTbyA71AWxrEiNkGrJRjs05iqayk1At0Aq6I6ulCjxTtudiOCmArQ/kxBY8JAmv6zHQQq9pxqEn3y5Q==","signatures":[{"sig":"MEUCIA4MWPJ2itaFmBhxkaxt9J1R/4p6+Pq4QpIMG0ungkA7AiEA/NcinTgn+AxMtetVLpJG96z2x6VRkIYgjIVFxMrpZFY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQCLrioPlMw1SHCpWnqebNrz7EmXa39X1ufqS2f48/602QIgSBN1xQT11uU3kF6MOTOwc8pKMS45ljjEi4wFifjf6zc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@c2paviewer%2fc2pa-mcp@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":154025},"type":"module","engines":{"node":">=18"},"gitHead":"15ca943159387756a1ffb3a4671fe88b26026c75","scripts":{"test":"npm run build && node --test","build":"tsc","start":"node dist/index.js","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:7bc8d00a-8366-43d3-9d30-3d8bb8d959dd"}},"repository":{"url":"git+https://github.com/harelrech/c2pa-mcp.git","type":"git"},"_npmVersion":"12.0.2","description":"An open-source MCP server that verifies C2PA content credentials and returns LLM-ready provenance verdicts. Built by c2paviewer.com.","directories":{},"_nodeVersion":"22.23.2","dependencies":{"zod":"^3.23.8","undici":"^6.26.0","@contentauth/c2pa-node":"0.6.3","@contentauth/c2pa-types":"^0.6.0","@modelcontextprotocol/sdk":"^1.12.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.5.0","@types/node":"^20.14.0"},"_npmOperationalInternal":{"tmp":"tmp/c2pa-mcp_0.2.0_1789992159946_0.0705259411214243","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"_id":"@c2paviewer/c2pa-mcp@0.2.1","bin":{"c2pa-mcp":"dist/index.js"},"bugs":{"url":"https://github.com/harelrech/c2pa-mcp/issues"},"dist":{"shasum":"853beb0f5e3416838fe61a00a86a75fcaf09de0f","tarball":"https://registry.npmjs.org/@c2paviewer/c2pa-mcp/-/c2pa-mcp-0.2.1.tgz","fileCount":36,"integrity":"sha512-XxN2p3panglyOYxJ4B2AeroX3J4pf1dJTsfYaTPXlUCskMdkCxeljacG8xtBfJow/15PclsZ6Ya9Ye7ujw9LVQ==","signatures":[{"sig":"MEUCIQCspyOUMF3IEaLIgSb+Sk7m/xxPZgDlviaIjsykxpF+9QIged92vRuEeU7z9i9otkPyPFVdGlCibFVXy5THKgzzzV0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIBSfoSjvfdnrOOvl7S6lvP+S4meSaFIVRY846GfCSYotAiEAzVnQby4t4FRtSqD9d4QnuGzRkMs7aaWjMQVuUlj/+q0="}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@c2paviewer%2fc2pa-mcp@0.2.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":154075},"name":"@c2paviewer/c2pa-mcp","type":"module","author":{"name":"c2paviewer.com"},"engines":{"node":">=22"},"gitHead":"59005bf64409eebcff277126f3277fccd75ee7d8","license":"MIT OR Apache-2.0","scripts":{"test":"npm run build && node --test","build":"tsc","start":"node dist/index.js","prepublishOnly":"npm run build"},"version":"0.2.1","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:7bc8d00a-8366-43d3-9d30-3d8bb8d959dd"}},"homepage":"https://github.com/harelrech/c2pa-mcp#readme","keywords":["c2pa","mcp","model-context-protocol","content-credentials","provenance","ai-detection","content-authenticity","deepfake"],"repository":{"url":"git+https://github.com/harelrech/c2pa-mcp.git","type":"git"},"_npmVersion":"12.0.2","description":"An open-source MCP server that verifies C2PA content credentials and returns LLM-ready provenance verdicts. Built by c2paviewer.com.","directories":{},"maintainers":[{"name":"harelrech","email":"harelrech@gmail.com"}],"_nodeVersion":"22.23.2","dependencies":{"zod":"^3.23.8","undici":"^6.26.0","@contentauth/c2pa-node":"0.6.3","@contentauth/c2pa-types":"^0.6.0","@modelcontextprotocol/sdk":"^1.12.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.5.0","@types/node":"^20.14.0"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/c2pa-mcp_0.2.1_1789992989843_0.29337501023114165"}}},"time":{"created":"2026-06-15T06:12:42.093Z","modified":"2026-09-21T12:16:30.329Z","0.1.0":"2026-06-15T06:12:42.453Z","0.1.1":"2026-06-21T17:55:04.376Z","0.1.2":"2026-06-21T17:56:55.409Z","0.1.3":"2026-07-24T07:31:46.768Z","0.2.0":"2026-09-21T12:02:40.043Z","0.2.1":"2026-09-21T12:16:29.943Z"},"bugs":{"url":"https://github.com/harelrech/c2pa-mcp/issues"},"author":{"name":"c2paviewer.com"},"license":"MIT OR Apache-2.0","homepage":"https://github.com/harelrech/c2pa-mcp#readme","keywords":["c2pa","mcp","model-context-protocol","content-credentials","provenance","ai-detection","content-authenticity","deepfake"],"repository":{"url":"git+https://github.com/harelrech/c2pa-mcp.git","type":"git"},"description":"An open-source MCP server that verifies C2PA content credentials and returns LLM-ready provenance verdicts. Built by c2paviewer.com.","maintainers":[{"name":"harelrech","email":"harelrech@gmail.com"}],"readme":"# c2pa-mcp\n\n**An MCP server that verifies C2PA Content Credentials and returns an LLM-ready verdict.**\n\nPoint any MCP client (Claude Desktop, Claude Code, Cursor, ...) at a local file or a URL and get back a plain-language answer: is this image/video/audio **trusted, valid, tampered, or unsigned**? Who signed it? Is it **AI-generated**? What's its edit history and provenance lineage?\n\nBuilt by [c2paviewer.com](https://c2paviewer.com). Verification runs locally on the [official C2PA Rust engine](https://github.com/contentauth/c2pa-rs) via `@contentauth/c2pa-node`. Files never leave your machine.\n\n> **Read-only.** This server verifies and inspects Content Credentials. It does not sign or create them.\n\n## Install\n\nNo global install needed. Add it to your MCP client config and it runs via `npx`:\n\n```json\n{\n  \"mcpServers\": {\n    \"c2pa\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@c2paviewer/c2pa-mcp\"]\n    }\n  }\n}\n```\n\n- **Claude Desktop**: Settings → Developer → Edit Config, add the block above.\n- **Claude Code**: `claude mcp add c2pa -- npx -y @c2paviewer/c2pa-mcp`\n- **Cursor / others**: add the same `mcpServers` entry to the client's MCP config.\n\nRequires Node.js 22+ (the `@contentauth/c2pa-node` engine requires it).\n\n> **First run:** the underlying engine (`@contentauth/c2pa-node`) downloads a ~18MB native binary on first install. On a slow connection this can outlast an MCP client's startup timeout — if the very first launch seems to hang, let the download finish and relaunch; subsequent runs are instant.\n\n## Tools\n\n| Tool | What it does |\n|------|--------------|\n| `verify_c2pa_file` | Verify a local image/video/audio/PDF by path. |\n| `verify_c2pa_url` | Download a public https media URL and verify it (SSRF-guarded). |\n| `scan_c2pa_directory` | Audit a folder: which files have credentials, their verdict, signer, AI status. |\n| `c2pa_info` | Report engine version, supported media types, and trust-list status. |\n\nEach verify tool returns a human-readable summary plus a structured digest:\n\n```jsonc\n{\n  \"verdict\": \"valid_untrusted\",    // trusted | valid_untrusted | valid_trust_unknown | invalid | no_credentials | error\n  \"summary\": \"Content Credentials are cryptographically valid, but the signer ... 1 earlier version in its provenance chain failed validation; this file's own signature is unaffected.\",\n  \"signer\": { \"name\": \"Example Signer\", \"trusted\": false },\n  \"aiGenerated\": { \"isAI\": true, \"tools\": [\"DALL-E\"], \"digitalSourceTypes\": [\"...trainedAlgorithmicMedia\"] },\n  \"provenance\": [\n    { \"depth\": 0, \"title\": \"This file\", \"relationship\": \"This file\", \"verdict\": \"valid\", \"manifestLabel\": \"urn:...\", \"issues\": [] },\n    { \"depth\": 1, \"title\": \"source.jpg\", \"relationship\": \"Edited from\", \"verdict\": \"invalid\", \"manifestLabel\": \"urn:...\",\n      \"issues\": [ { \"code\": \"claimSignature.mismatch\", \"severity\": \"error\", \"explanation\": \"...\" } ] }\n  ],\n  \"edits\": [ { \"label\": \"Created\", \"agent\": \"Photoshop\", \"when\": \"...\", \"detail\": \"\" } ],\n  \"watermarks\": [ { \"kind\": \"synthid\", \"assertionLabel\": \"...\", \"algorithm\": \"\" } ],\n  \"issues\": [ { \"code\": \"signingCredential.untrusted\", \"severity\": \"warning\",   // THIS file's own problems (plus whatever drove an Invalid verdict)\n               \"explanation\": \"The signature is cryptographically valid, but ...\" } ],\n  \"ingredientIssues\": [                                                           // problems on earlier versions in the chain\n    { \"ingredientTitle\": \"source.jpg\", \"manifestLabel\": \"urn:...\", \"worstSeverity\": \"error\",\n      \"codes\": [ { \"code\": \"claimSignature.mismatch\", \"severity\": \"error\", \"explanation\": \"...\" } ] }\n  ],\n  \"trust\": { \"evaluated\": true, \"partial\": false, \"listSource\": \"https://.../C2PA-TRUST-LIST.pem, ...\" }\n}\n```\n\n### Provenance chain vs. the file itself\n\n`issues` and `verdict` describe the **active manifest** — this file's own signature and content. Problems found on **ingredients** (earlier versions or components the file was made from) are reported separately in `ingredientIssues` and on the matching `provenance[].issues`, and never change the file's verdict. This follows C2PA 2.2 §15.11 (a validator must report a failing ingredient, but the active manifest keeps its own result) and matches what [CAI Verify](https://verify.contentauthenticity.org) shows. So a file re-signed from a tampered original can legitimately be `trusted` while its lineage shows an `invalid` node — the model should read both.\n\nPass `\"includeRaw\": true` to also get the full raw manifest store.\n\n## Trust list\n\nTo report a signer as **`trusted`** (not just cryptographically valid), the server checks the signing certificate against the **same five trust inputs c2paviewer.com uses**, **fetched live and cached** (24h TTL) so decisions stay current without a release:\n\n**Official C2PA Conformance Program** (going-forward signers)\n- [`C2PA-TRUST-LIST.pem`](https://github.com/c2pa-org/conformance-public) — CA anchors for claim signers\n- [`C2PA-TSA-TRUST-LIST.pem`](https://github.com/c2pa-org/conformance-public) — CA anchors for Time-Stamp Authorities (folded into the same anchor bundle; without it valid files can carry `timeStamp.untrusted`)\n\n**CAI Interim Trust List** (frozen Jan 2026, officially temporary, but still the only thing that recognizes pre-conformance signers — Adobe, Leica, Truepic, Canon, Samsung, Fastly, and most real-world content today)\n- [`anchors.pem`](https://verify.contentauthenticity.org/trust/anchors.pem) — legacy CA anchors\n- [`allowed.sha256.txt`](https://verify.contentauthenticity.org/trust/allowed.sha256.txt) — allow-list of specific end-entity certificate hashes; a signer whose leaf cert is listed is trusted even when nothing chains to an anchor\n- [`store.cfg`](https://verify.contentauthenticity.org/trust/store.cfg) — accepted Extended Key Usage OIDs\n\nWithout the interim group, mainstream signed content reads as `valid_untrusted`.\n\nIf an input can't be fetched, the server **degrades loudly**: with at least one anchor list loaded it still evaluates trust but sets `trust.partial: true` and names the missing input in `trust.reason` (signers recognized only by that input will read as untrusted); with no anchors at all the verdict becomes `valid_trust_unknown` and `trust.evaluated` is `false`. It never silently treats an unknown signer as trusted, and never silently uses a stale snapshot.\n\nEnvironment overrides:\n\n| Variable | Default | Purpose |\n|----------|---------|---------|\n| `C2PA_TRUST_LIST_URL` | conformance + TSA + ITL anchors | Comma-separated PEM URLs. Replaces the default anchor set. |\n| `C2PA_TRUST_ALLOWED_LIST_URL` | CAI `allowed.sha256.txt` | End-entity allow-list URL. Set to an empty string to disable. |\n| `C2PA_TRUST_CONFIG_URL` | CAI `store.cfg` | EKU config URL. Set to an empty string to disable. |\n| `C2PA_TRUST_TTL_SECONDS` | `86400` | Cache lifetime for the fetched trust list. |\n| `C2PA_MAX_FETCH_BYTES` | `104857600` | Max download size for `verify_c2pa_url` (100 MB). |\n| `C2PA_MAX_FILE_BYTES` | `524288000` | Max size of a local file the file/scan tools will verify (500 MB). |\n| `C2PA_ALLOWED_ROOTS` | (unset) | Comma/semicolon-separated absolute paths. When set, `verify_c2pa_file` and `scan_c2pa_directory` refuse any path outside these roots. |\n\n## Security\n\n- **Local processing.** Files are read and verified on your machine; nothing is uploaded.\n- **SSRF-guarded URL fetching.** `verify_c2pa_url` allows only public `https`, pins the resolved IP against DNS rebinding, re-validates every redirect, sends no cookies or auth, and enforces a content-type allowlist plus size cap.\n- **Local path safety.** The file/scan tools reject remote `file://` and UNC paths, resolve symlinks before the allowed-roots check, and return a generic error for inaccessible paths.\n- **Set `C2PA_ALLOWED_ROOTS` in any untrusted context.** The file/scan tools expose the host filesystem by design, so a prompt-injected model could point them anywhere. Confining them to a specific directory is the single most important hardening setting.\n- **Trust integrity.** Trust lists are fetched over HTTPS (integrity rests on TLS and the upstream sources); the cache is per-user (`0700`/`0600`, ownership-checked) and bound to the configured URL set.\n\n## Limitations\n\n- **Experimental. Not legal evidence.** C2PA tooling and trust infrastructure are still evolving. Do not rely on these verdicts for legal, compliance, or safety-critical decisions.\n- **Watermarks are reported as declared, not pixel-verified.** A `synthid` entry means the manifest *declares* a SynthID watermark; confirming the signal in the pixels requires the vendor's detector.\n- **AI-generation reflects what the manifest declares** via IPTC `digitalSourceType`. Absence of an AI declaration is not proof the content is not AI-generated.\n\n## Troubleshooting\n\n- **Every verification fails with \"Verification engine failed to load\".** The native `@contentauth/c2pa-node` binary was interrupted or corrupted during install (common on slow/unreliable connections). Run `c2pa_info` — it reports `engine: FAILED: <reason>` when this happens. Fix: reinstall the dependency (delete `node_modules/@contentauth/c2pa-node` and reinstall, or `npm cache clean --force` then re-run). Checksum/retry hardening of that download lives in the upstream `@contentauth/c2pa-node` postinstall script, which this project doesn't control.\n- **`verify_c2pa_url` fails with \"timed out after ...ms\".** The fetch exceeded `C2PA_FETCH_TIMEOUT_MS` (default 30000). Raise it if you're verifying URLs from a slow host.\n\n## Development\n\n```bash\nnpm install\nnpm run build\nnpm test          # builds, then runs unit + end-to-end tests (network needed for the trust list)\n```\n\n## License\n\nSource code is dual-licensed under [MIT](./LICENSE-MIT) or [Apache-2.0](./LICENSE-APACHE), at your option.\n\nThe test images under [`test/fixtures/`](./test/fixtures/) are redistributed unmodified from [`c2pa-org/public-testfiles`](https://github.com/c2pa-org/public-testfiles) and are licensed separately under [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/).\n\n> Note: if you publish under an unscoped name instead of `@c2paviewer/c2pa-mcp`, change `name` in `package.json` and the `args` in the install block above; nothing else depends on the package name.\n","readmeFilename":"README.md"}