{"_id":"@emilia-protocol/mcp-guard","_rev":"10-f2090bdbcea7f3b61d0364c8d18eb606","name":"@emilia-protocol/mcp-guard","dist-tags":{"latest":"0.6.0"},"versions":{"0.1.0":{"name":"@emilia-protocol/mcp-guard","version":"0.1.0","keywords":["emilia-protocol","mcp","model-context-protocol","ai-agent","tool-calling","irreversible-actions","human-in-the-loop","class-a-signoff","ep-receipt-v1","provenance","402","agent-accountability"],"license":"Apache-2.0","_id":"@emilia-protocol/mcp-guard@0.1.0","maintainers":[{"name":"emiliaprotocol","email":"iman.schrock@gmail.com"}],"homepage":"https://www.emiliaprotocol.ai/agent-guard","bugs":{"url":"https://github.com/emiliaprotocol/emilia-protocol/issues"},"dist":{"shasum":"a625501660bd677e1be65ed1f29a33bd939ea573","tarball":"https://registry.npmjs.org/@emilia-protocol/mcp-guard/-/mcp-guard-0.1.0.tgz","fileCount":4,"integrity":"sha512-cNjaJikVVThfmrkeKzRB05oqU7mE6WJQfwx1B2A4KLdPaOpYFGSkiyspm1ZB3xSm9J7JtHM7tSbR+lCVb+fLGQ==","signatures":[{"sig":"MEUCIQDdbQAS0qz/+EUoNzlXKYHXHOyC/ncJvxcfz/2cCEn6yAIgKXGCgE8ao3jsDx5ClIFribu503A7n4kw10AG+yO4U0s=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":44534},"main":"index.js","type":"module","engines":{"node":">=18"},"exports":{".":{"import":"./index.js"}},"gitHead":"85fad23c9c8067c7014d75db2c7d8f38fe99fe86","_npmUser":{"name":"emiliaprotocol","email":"iman.schrock@gmail.com"},"repository":{"url":"git+https://github.com/emiliaprotocol/emilia-protocol.git","type":"git","directory":"packages/mcp-guard"},"_npmVersion":"11.11.0","description":"EP-MCP middleware (reference implementation). Wraps an MCP tool-call handler: irreversible tool calls route through consent → Class-A signoff → an emitted EP-RECEIPT-v1 + an appended provenance entry; everything else passes through. Includes the demand ho","directories":{},"_nodeVersion":"25.8.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"@emilia-protocol/require-receipt":"^0.1.0"},"_npmOperationalInternal":{"tmp":"tmp/mcp-guard_0.1.0_1782190297949_0.06133213407582483","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@emilia-protocol/mcp-guard","version":"0.1.1","keywords":["emilia-protocol","mcp","model-context-protocol","ai-agent","tool-calling","irreversible-actions","human-in-the-loop","class-a-signoff","ep-receipt-v1","provenance","402","agent-accountability"],"license":"Apache-2.0","_id":"@emilia-protocol/mcp-guard@0.1.1","maintainers":[{"name":"emiliaprotocol","email":"iman.schrock@gmail.com"}],"homepage":"https://www.emiliaprotocol.ai/agent-guard","bugs":{"url":"https://github.com/emiliaprotocol/emilia-protocol/issues"},"dist":{"shasum":"c7f448835cb77a3858d3dc8b278fae07c7e0c24f","tarball":"https://registry.npmjs.org/@emilia-protocol/mcp-guard/-/mcp-guard-0.1.1.tgz","fileCount":4,"integrity":"sha512-EoZDYTjoVwSVBmNPvw6/vsOXwyL+NfZZ+TUtHC5scybqRzKxZDoA6m8EgZ4+kkpvTPSOGoujWHetexAD0qKquw==","signatures":[{"sig":"MEQCIQCEY8OXeOkwdRvjXYwWZ3nu2BxJQZk8H27DcM5/0SY0WgIfXfYpHEH/46WkNTva1ZYZj0i1MXtQIe64wiuNFHSZMQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":50065},"main":"index.js","type":"module","engines":{"node":">=18"},"exports":{".":{"import":"./index.js"}},"gitHead":"e5139782dceb47627868601e6aa2eb9d775ed7df","_npmUser":{"name":"emiliaprotocol","email":"iman.schrock@gmail.com"},"repository":{"url":"git+https://github.com/emiliaprotocol/emilia-protocol.git","type":"git","directory":"packages/mcp-guard"},"_npmVersion":"11.11.0","description":"EP-MCP middleware (reference implementation). Wraps an MCP tool-call handler: irreversible tool calls route through consent → Class-A signoff → an emitted EP-RECEIPT-v1 + an appended provenance entry; everything else passes through. Includes the demand ho","directories":{},"_nodeVersion":"25.8.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"@emilia-protocol/require-receipt":"^0.1.0"},"_npmOperationalInternal":{"tmp":"tmp/mcp-guard_0.1.1_1782232727441_0.810988357281323","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@emilia-protocol/mcp-guard","version":"0.2.0","keywords":["emilia-protocol","mcp","model-context-protocol","ai-agent","tool-calling","irreversible-actions","human-in-the-loop","class-a-signoff","ep-receipt-v1","provenance","402","agent-accountability"],"license":"Apache-2.0","_id":"@emilia-protocol/mcp-guard@0.2.0","maintainers":[{"name":"emiliaprotocol","email":"iman.schrock@gmail.com"}],"homepage":"https://www.emiliaprotocol.ai/agent-guard","bugs":{"url":"https://github.com/emiliaprotocol/emilia-protocol/issues"},"dist":{"shasum":"056cd3d78eb20041457efd24c7c5c9106e9fee8d","tarball":"https://registry.npmjs.org/@emilia-protocol/mcp-guard/-/mcp-guard-0.2.0.tgz","fileCount":4,"integrity":"sha512-d6F0M2EvY1mAtR40rtqtTOaccjUjYbVSSV9h+VFJ1pCdU/a5pyofhLFcilXNOf6F3DbE3RfbOTiLg5N0GV1h7A==","signatures":[{"sig":"MEYCIQCtXvCWDiVfDoJGlqpsvLX0d4tTMRVKm5xx8xBn6Y80DwIhAKx94YlFyUqvFS7/QC5rqVlSNGyygWVUCsdQBHa568MJ","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":51284},"main":"index.js","type":"module","engines":{"node":">=18"},"exports":{".":{"import":"./index.js"}},"gitHead":"3b1ec521e12128a169ff9d4bb9151201eb4d6fa9","_npmUser":{"name":"emiliaprotocol","email":"iman.schrock@gmail.com"},"repository":{"url":"git+https://github.com/emiliaprotocol/emilia-protocol.git","type":"git","directory":"packages/mcp-guard"},"_npmVersion":"11.11.0","description":"EP-MCP middleware (reference implementation). Wraps an MCP tool-call handler: irreversible tool calls route through consent → Class-A signoff → an emitted EP-RECEIPT-v1 + an appended provenance entry; everything else passes through. Includes the demand ho","directories":{},"_nodeVersion":"25.8.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"@emilia-protocol/require-receipt":"^0.4.0"},"_npmOperationalInternal":{"tmp":"tmp/mcp-guard_0.2.0_1782966184137_0.00023655960980351054","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@emilia-protocol/mcp-guard","version":"0.4.0","keywords":["emilia-protocol","mcp","model-context-protocol","ai-agent","tool-calling","irreversible-actions","human-in-the-loop","class-a-signoff","ep-receipt-v1","provenance","402","agent-accountability"],"license":"Apache-2.0","_id":"@emilia-protocol/mcp-guard@0.4.0","maintainers":[{"name":"emiliaprotocol","email":"team@emiliaprotocol.ai"}],"homepage":"https://www.emiliaprotocol.ai/agent-guard","bugs":{"url":"https://github.com/emiliaprotocol/emilia-protocol/issues"},"dist":{"shasum":"436a78cf17e7e2db24d15eb6d1f2a5f8ded672fd","tarball":"https://registry.npmjs.org/@emilia-protocol/mcp-guard/-/mcp-guard-0.4.0.tgz","fileCount":4,"integrity":"sha512-G5DabMOSQ12g6yIZ4gw0k9Bt8fjRKY3TWJS+V9jCIMghuXWtabI6kgX0OjFO9ieX3Pk0Rl+gTaEGFfDFsJTIhw==","signatures":[{"sig":"MEYCIQCc8MIbiqq9E16ioDGjeOeYwdkeVq1Up84ZR4eO8aY0ngIhAL+5+rS8QYAOOfwE10MfHQ5dDVoTec71qnYDh72d2HqN","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@emilia-protocol%2fmcp-guard@0.4.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":58425},"main":"index.js","type":"module","_from":"file:release-artifacts/mcp-guard/emilia-protocol-mcp-guard-0.4.0.tgz","engines":{"node":">=18"},"exports":{".":{"import":"./index.js"}},"scripts":{"test":"cd ../.. && npx vitest run tests/mcp-guard-boundary.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:44fe1510-135f-4f14-a6b7-927e15b5ca0c"}},"_resolved":"/home/runner/work/emilia-protocol/emilia-protocol/release-artifacts/mcp-guard/emilia-protocol-mcp-guard-0.4.0.tgz","_integrity":"sha512-G5DabMOSQ12g6yIZ4gw0k9Bt8fjRKY3TWJS+V9jCIMghuXWtabI6kgX0OjFO9ieX3Pk0Rl+gTaEGFfDFsJTIhw==","repository":{"url":"git+https://github.com/emiliaprotocol/emilia-protocol.git","type":"git","directory":"packages/mcp-guard"},"_npmVersion":"11.18.0","description":"Fail-closed MCP receipt middleware with exact-action binding, one-time consumption, strict receipt parsing, and escalation-only treatment of untrusted tool metadata.","directories":{},"_nodeVersion":"24.18.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"@emilia-protocol/require-receipt":"^0.6.0"},"_npmOperationalInternal":{"tmp":"tmp/mcp-guard_0.4.0_1784276129671_0.7126898288280465","host":"s3://npm-registry-packages-npm-production"}},"0.4.1":{"name":"@emilia-protocol/mcp-guard","version":"0.4.1","keywords":["emilia-protocol","mcp","model-context-protocol","ai-agent","tool-calling","irreversible-actions","human-in-the-loop","class-a-signoff","ep-receipt-v1","provenance","402","agent-accountability"],"license":"Apache-2.0","_id":"@emilia-protocol/mcp-guard@0.4.1","maintainers":[{"name":"emiliaprotocol","email":"team@emiliaprotocol.ai"}],"homepage":"https://www.emiliaprotocol.ai/agent-guard","bugs":{"url":"https://github.com/emiliaprotocol/emilia-protocol/issues"},"dist":{"shasum":"fe9416af5ae4736127f1a7745141638ce0782dbf","tarball":"https://registry.npmjs.org/@emilia-protocol/mcp-guard/-/mcp-guard-0.4.1.tgz","fileCount":10,"integrity":"sha512-ZvpgW7jfDMXrcBT0L5gSexk/V10PAxGY3v3s0a+BUQCnPcbtmwtwn22y/495IzEMmpXLTq3YuWqaKzTg+nsRTg==","signatures":[{"sig":"MEUCIDBOKfxrvgp5RXvPm8M89L1iE9s1uJ4zljf9D0VoTMXTAiEA06i2xl4dX7av/2tufSTm+hOV4AO5j+Yr1JaWGXPEsUY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@emilia-protocol%2fmcp-guard@0.4.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":131795},"main":"index.js","type":"module","_from":"file:release-artifacts/mcp-guard/emilia-protocol-mcp-guard-0.4.1.tgz","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./index.js"}},"scripts":{"test":"cd ../.. && npx vitest run tests/mcp-guard-boundary.test.ts","build":"tsc -p tsconfig.json","pretest":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:44fe1510-135f-4f14-a6b7-927e15b5ca0c"}},"_resolved":"/home/runner/work/emilia-protocol/emilia-protocol/release-artifacts/mcp-guard/emilia-protocol-mcp-guard-0.4.1.tgz","_integrity":"sha512-ZvpgW7jfDMXrcBT0L5gSexk/V10PAxGY3v3s0a+BUQCnPcbtmwtwn22y/495IzEMmpXLTq3YuWqaKzTg+nsRTg==","repository":{"url":"git+https://github.com/emiliaprotocol/emilia-protocol.git","type":"git","directory":"packages/mcp-guard"},"_npmVersion":"11.18.0","description":"Fail-closed MCP receipt middleware with exact-action binding, one-time consumption, strict receipt parsing, and escalation-only treatment of untrusted tool metadata.","directories":{},"_nodeVersion":"24.18.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"@emilia-protocol/require-receipt":"^0.6.0"},"_npmOperationalInternal":{"tmp":"tmp/mcp-guard_0.4.1_1784698558044_0.7753202962870931","host":"s3://npm-registry-packages-npm-production"}},"0.4.3":{"name":"@emilia-protocol/mcp-guard","version":"0.4.3","keywords":["emilia-protocol","mcp","model-context-protocol","ai-agent","tool-calling","irreversible-actions","human-in-the-loop","class-a-signoff","ep-receipt-v1","provenance","402","agent-accountability"],"license":"Apache-2.0","_id":"@emilia-protocol/mcp-guard@0.4.3","maintainers":[{"name":"emiliaprotocol","email":"team@emiliaprotocol.ai"}],"homepage":"https://www.emiliaprotocol.ai/agent-guard","bugs":{"url":"https://github.com/emiliaprotocol/emilia-protocol/issues"},"dist":{"shasum":"e782a0fa7d0e868d545590e76cd9836dded04f4d","tarball":"https://registry.npmjs.org/@emilia-protocol/mcp-guard/-/mcp-guard-0.4.3.tgz","fileCount":12,"integrity":"sha512-cujkLUZdEKlRAMNUwBwFlEzG4hycS8Yk82uY+NmU1bulT2ySB3/iJ411GI1A7Gk/hq1o2ZCrGup0lKoAASexKA==","signatures":[{"sig":"MEUCIGI3QB/Ph3e45O6sRtQzn+BzubIG5iqSsGCiYjDrggN9AiEAzT15vbQxNewyVy1qjZ3HNg99l2Y1uxC/A0bqwQLMQtI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@emilia-protocol%2fmcp-guard@0.4.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":163664},"main":"index.js","type":"module","_from":"file:publisher-input/emilia-protocol-mcp-guard-0.4.3.tgz","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./index.js"},"./sql/provenance-ledger-v1.sql":"./sql/provenance-ledger-v1.sql"},"scripts":{"test":"cd ../.. && npx vitest run tests/mcp-guard-boundary.test.ts","build":"tsc -p tsconfig.json","pretest":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:44fe1510-135f-4f14-a6b7-927e15b5ca0c"}},"_resolved":"/home/runner/work/emilia-protocol/emilia-protocol/publisher-input/emilia-protocol-mcp-guard-0.4.3.tgz","_integrity":"sha512-cujkLUZdEKlRAMNUwBwFlEzG4hycS8Yk82uY+NmU1bulT2ySB3/iJ411GI1A7Gk/hq1o2ZCrGup0lKoAASexKA==","repository":{"url":"git+https://github.com/emiliaprotocol/emilia-protocol.git","type":"git","directory":"packages/mcp-guard"},"_npmVersion":"11.16.0","description":"Fail-closed MCP receipt middleware with exact-action binding, one-time consumption, strict receipt parsing, and escalation-only treatment of untrusted tool metadata.","directories":{},"_nodeVersion":"24.18.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"@emilia-protocol/require-receipt":"^0.6.0"},"_npmOperationalInternal":{"tmp":"tmp/mcp-guard_0.4.3_1785655453014_0.03719017497064114","host":"s3://npm-registry-packages-npm-production"}},"0.4.4":{"name":"@emilia-protocol/mcp-guard","version":"0.4.4","keywords":["emilia-protocol","mcp","model-context-protocol","ai-agent","tool-calling","irreversible-actions","human-in-the-loop","class-a-signoff","ep-receipt-v1","provenance","402","agent-accountability"],"license":"Apache-2.0","_id":"@emilia-protocol/mcp-guard@0.4.4","maintainers":[{"name":"emiliaprotocol","email":"team@emiliaprotocol.ai"}],"homepage":"https://www.emiliaprotocol.ai/agent-guard","bugs":{"url":"https://github.com/emiliaprotocol/emilia-protocol/issues"},"dist":{"shasum":"d2a36c84991888e277391000910989b04b8834eb","tarball":"https://registry.npmjs.org/@emilia-protocol/mcp-guard/-/mcp-guard-0.4.4.tgz","fileCount":12,"integrity":"sha512-DIxG5MEvwpa8i8arCrwyog4m3OXYC1OQBS6fDWOSUCC+lXRUY6Bt/JTxJXcESt2ihoowCOPl+riVwmrVyL+zUQ==","signatures":[{"sig":"MEUCIQC8E1J0MN5qeeREIQDR4TcN3qWnnzbgERzQ/zODZAFHdwIgJkE3yKRJXY2jex+QAL1bSggxhvtg1AaDh4PC/svRvYY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@emilia-protocol%2fmcp-guard@0.4.4","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":164726},"main":"index.js","type":"module","_from":"file:publisher-input/emilia-protocol-mcp-guard-0.4.4.tgz","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./index.js"},"./sql/provenance-ledger-v1.sql":"./sql/provenance-ledger-v1.sql"},"scripts":{"test":"cd ../.. && npx vitest run tests/mcp-guard-boundary.test.ts","build":"tsc -p tsconfig.json","pretest":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:44fe1510-135f-4f14-a6b7-927e15b5ca0c"}},"_resolved":"/home/runner/work/emilia-protocol/emilia-protocol/publisher-input/emilia-protocol-mcp-guard-0.4.4.tgz","_integrity":"sha512-DIxG5MEvwpa8i8arCrwyog4m3OXYC1OQBS6fDWOSUCC+lXRUY6Bt/JTxJXcESt2ihoowCOPl+riVwmrVyL+zUQ==","repository":{"url":"git+https://github.com/emiliaprotocol/emilia-protocol.git","type":"git","directory":"packages/mcp-guard"},"_npmVersion":"11.16.0","description":"Fail-closed MCP receipt middleware with exact-action binding, one-time consumption, strict receipt parsing, and escalation-only treatment of untrusted tool metadata.","directories":{},"_nodeVersion":"24.18.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"@emilia-protocol/require-receipt":"^0.7.0"},"_npmOperationalInternal":{"tmp":"tmp/mcp-guard_0.4.4_1785735744910_0.8418845857360864","host":"s3://npm-registry-packages-npm-production"}},"0.4.5":{"name":"@emilia-protocol/mcp-guard","version":"0.4.5","keywords":["emilia-protocol","mcp","model-context-protocol","ai-agent","tool-calling","irreversible-actions","human-in-the-loop","class-a-signoff","ep-receipt-v1","provenance","402","agent-accountability"],"license":"Apache-2.0","_id":"@emilia-protocol/mcp-guard@0.4.5","maintainers":[{"name":"emiliaprotocol","email":"team@emiliaprotocol.ai"}],"homepage":"https://www.emiliaprotocol.ai/agent-guard","bugs":{"url":"https://github.com/emiliaprotocol/emilia-protocol/issues"},"dist":{"shasum":"093320dd07c2fa6396bc1dfb632f562c22276ebe","tarball":"https://registry.npmjs.org/@emilia-protocol/mcp-guard/-/mcp-guard-0.4.5.tgz","fileCount":12,"integrity":"sha512-PT4oTv2rI5h8e825W7sX8z1jj3qLCNz++iOstBhQLuoiz1IbnA1ptCQ1JVWdYmV4EyjCMWnrTKEZHqsNjKulLg==","signatures":[{"sig":"MEUCIQC2kRwAb3BAOTTV0CvR2T53LxDYBbNXmDL/keOiL7CuPgIgK0K4MtTzGqy7jaQM7+/2KmZl1g6KiiLpi6ZjlXhjoYQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@emilia-protocol%2fmcp-guard@0.4.5","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":166543},"main":"index.js","type":"module","_from":"file:publisher-input/emilia-protocol-mcp-guard-0.4.5.tgz","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./index.js"},"./sql/provenance-ledger-v1.sql":"./sql/provenance-ledger-v1.sql"},"scripts":{"test":"cd ../.. && npx vitest run tests/mcp-guard-boundary.test.ts","build":"tsc -p tsconfig.json","pretest":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:44fe1510-135f-4f14-a6b7-927e15b5ca0c"}},"_resolved":"/home/runner/work/emilia-protocol/emilia-protocol/publisher-input/emilia-protocol-mcp-guard-0.4.5.tgz","_integrity":"sha512-PT4oTv2rI5h8e825W7sX8z1jj3qLCNz++iOstBhQLuoiz1IbnA1ptCQ1JVWdYmV4EyjCMWnrTKEZHqsNjKulLg==","repository":{"url":"git+https://github.com/emiliaprotocol/emilia-protocol.git","type":"git","directory":"packages/mcp-guard"},"_npmVersion":"11.16.0","description":"Fail-closed MCP receipt middleware with exact-action binding, one-time consumption, strict receipt parsing, and escalation-only treatment of untrusted tool metadata.","directories":{},"_nodeVersion":"24.18.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"@emilia-protocol/require-receipt":"^0.7.0"},"_npmOperationalInternal":{"tmp":"tmp/mcp-guard_0.4.5_1785750434905_0.11819568723191787","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@emilia-protocol/mcp-guard","version":"0.5.0","keywords":["emilia-protocol","mcp","model-context-protocol","ai-agent","tool-calling","irreversible-actions","human-in-the-loop","class-a-signoff","ep-receipt-v1","provenance","402","agent-accountability"],"license":"Apache-2.0","_id":"@emilia-protocol/mcp-guard@0.5.0","maintainers":[{"name":"emiliaprotocol","email":"team@emiliaprotocol.ai"}],"homepage":"https://www.emiliaprotocol.ai/agent-guard","bugs":{"url":"https://github.com/emiliaprotocol/emilia-protocol/issues"},"dist":{"shasum":"a30da5226164f8333065d844534e7840e2ea07b7","tarball":"https://registry.npmjs.org/@emilia-protocol/mcp-guard/-/mcp-guard-0.5.0.tgz","fileCount":12,"integrity":"sha512-kHMHz6Q1SXqpgIljZxbWWqD6L8baX0xY4KWH3cyeaAJo/5yeHv+Xm0eYj2xkPa37h1n3ygbU8YVermMnEmgnbw==","signatures":[{"sig":"MEUCIHSDclAmBwrXnTl9JJX6D3X0KRvUHMOrsM9ls7BqBZkrAiEA/hg0XK+oRHN7VetRxRQLQJS1wOnzKLgnf6UnhF+vsgc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@emilia-protocol%2fmcp-guard@0.5.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":185461},"main":"index.js","type":"module","_from":"file:publisher-input/emilia-protocol-mcp-guard-0.5.0.tgz","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./index.js"},"./sql/provenance-ledger-v1.sql":"./sql/provenance-ledger-v1.sql"},"scripts":{"test":"cd ../.. && npx vitest run tests/mcp-guard-boundary.test.ts","build":"tsc -p tsconfig.json","pretest":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:44fe1510-135f-4f14-a6b7-927e15b5ca0c"}},"_resolved":"/home/runner/work/emilia-protocol/emilia-protocol/publisher-input/emilia-protocol-mcp-guard-0.5.0.tgz","_integrity":"sha512-kHMHz6Q1SXqpgIljZxbWWqD6L8baX0xY4KWH3cyeaAJo/5yeHv+Xm0eYj2xkPa37h1n3ygbU8YVermMnEmgnbw==","repository":{"url":"git+https://github.com/emiliaprotocol/emilia-protocol.git","type":"git","directory":"packages/mcp-guard"},"_npmVersion":"11.17.0","description":"Fail-closed MCP receipt middleware with exact-action binding, one-time consumption, strict receipt parsing, and escalation-only treatment of untrusted tool metadata.","directories":{},"_nodeVersion":"24.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"@emilia-protocol/require-receipt":"^0.8.0"},"_npmOperationalInternal":{"tmp":"tmp/mcp-guard_0.5.0_1786831071490_0.9166383041082768","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"_id":"@emilia-protocol/mcp-guard@0.6.0","bugs":{"url":"https://github.com/emiliaprotocol/emilia-protocol/issues"},"dist":{"shasum":"027ac2724656be8cadb7335411a625ad34c0329e","tarball":"https://registry.npmjs.org/@emilia-protocol/mcp-guard/-/mcp-guard-0.6.0.tgz","fileCount":12,"integrity":"sha512-dPpVHshutyel0FMvwJq79SCm2yb70IS3ievlCnd66L71Pel+0h9lM7hoDG4aNkO1e1P+P5M+/0k1/iLL74afTQ==","signatures":[{"sig":"MEQCIAx/8Twqmr9v5HfPQOsurSmE9Kz2uhqwW+34p6/V9d77AiA3EHo0Es+weZhzfHwW8ihtgJ9TO9OnjahcGXH8gGgRjg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIEO4vacLgB8fUFBygtowIfv5jbjcE/x8SaOFvQdTdSSzAiEA52Bl50ruWVr0LBST54uSQ+0hbmPRcXTgU4Uc9zput44="}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@emilia-protocol%2fmcp-guard@0.6.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":202836},"main":"index.js","name":"@emilia-protocol/mcp-guard","type":"module","_from":"file:publisher-input/emilia-protocol-mcp-guard-0.6.0.tgz","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./index.js"},"./sql/provenance-ledger-v1.sql":"./sql/provenance-ledger-v1.sql"},"license":"Apache-2.0","scripts":{"test":"cd ../.. && npx vitest run tests/mcp-guard-boundary.test.ts","build":"tsc -p tsconfig.json","pretest":"npm run build"},"version":"0.6.0","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:44fe1510-135f-4f14-a6b7-927e15b5ca0c"}},"homepage":"https://www.emiliaprotocol.ai/agent-guard","keywords":["emilia-protocol","mcp","model-context-protocol","ai-agent","tool-calling","irreversible-actions","human-in-the-loop","class-a-signoff","ep-receipt-v1","provenance","402","agent-accountability"],"_resolved":"/home/runner/work/emilia-protocol/emilia-protocol/publisher-input/emilia-protocol-mcp-guard-0.6.0.tgz","_integrity":"sha512-dPpVHshutyel0FMvwJq79SCm2yb70IS3ievlCnd66L71Pel+0h9lM7hoDG4aNkO1e1P+P5M+/0k1/iLL74afTQ==","repository":{"url":"git+https://github.com/emiliaprotocol/emilia-protocol.git","type":"git","directory":"packages/mcp-guard"},"_npmVersion":"11.19.0","description":"Fail-closed MCP receipt middleware with exact-action binding, one-time consumption, strict receipt parsing, and escalation-only treatment of untrusted tool metadata.","directories":{},"maintainers":[{"name":"emiliaprotocol","email":"team@emiliaprotocol.ai"}],"_nodeVersion":"24.20.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"@emilia-protocol/require-receipt":"^0.8.1"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/mcp-guard_0.6.0_1789286373667_0.9898702017550283"}}},"time":{"created":"2026-06-23T04:51:37.733Z","modified":"2026-09-13T07:59:34.067Z","0.1.0":"2026-06-23T04:51:38.088Z","0.1.1":"2026-06-23T16:38:47.592Z","0.2.0":"2026-07-02T04:23:04.274Z","0.4.0":"2026-07-17T08:15:29.802Z","0.4.1":"2026-07-22T05:35:58.192Z","0.4.3":"2026-08-02T07:24:13.139Z","0.4.4":"2026-08-03T05:42:25.046Z","0.4.5":"2026-08-03T09:47:15.067Z","0.5.0":"2026-08-15T21:57:51.630Z","0.6.0":"2026-09-13T07:59:33.754Z"},"bugs":{"url":"https://github.com/emiliaprotocol/emilia-protocol/issues"},"license":"Apache-2.0","homepage":"https://www.emiliaprotocol.ai/agent-guard","keywords":["emilia-protocol","mcp","model-context-protocol","ai-agent","tool-calling","irreversible-actions","human-in-the-loop","class-a-signoff","ep-receipt-v1","provenance","402","agent-accountability"],"repository":{"url":"git+https://github.com/emiliaprotocol/emilia-protocol.git","type":"git","directory":"packages/mcp-guard"},"description":"Fail-closed MCP receipt middleware with exact-action binding, one-time consumption, strict receipt parsing, and escalation-only treatment of untrusted tool metadata.","maintainers":[{"name":"emiliaprotocol","email":"team@emiliaprotocol.ai"}],"readme":"# @emilia-protocol/mcp-guard\n\n**EP-MCP middleware — accountability for irreversible MCP tool calls.**\nReference implementation, **experimental**.\n\nIt wraps the function your MCP server already uses to dispatch a tool call. If a\ntool call is flagged **irreversible** (by policy or annotation), it routes\nthrough **consent → Class-A signoff → an emitted EP-RECEIPT-v1 → an appended\nprovenance entry**, then runs the tool. Everything else **passes straight\nthrough** with no added overhead.\n\nIt also ships the **demand hook**: a helper that enforces *\"no irreversible tool\ncall without a valid receipt\"* and returns a clear legacy MCP refusal object —\nso a well-behaved agent knows exactly what to bring and retries on its own.\n\n```bash\nnpm install @emilia-protocol/mcp-guard @emilia-protocol/require-receipt\n```\n\n## Sentinel loop breaker\n\nThe package now includes a local, zero-network identical-call circuit breaker.\nIt fingerprints the complete material tool call, ignores receipt carrier fields,\nand bounds both its time window and memory:\n\n```js\nimport { withMcpLoopBreaker } from '@emilia-protocol/mcp-guard';\n\nconst dispatch = withMcpLoopBreaker(handleTool, {\n  maxIdenticalCalls: 3,\n  windowMs: 10_000,\n  maxEntries: 2_048,\n});\n```\n\nThe fourth identical call in the default ten-second window returns a truthful\n429 `emilia_identical_tool_loop` refusal. Different arguments have different\nfingerprints. This is a cost/safety circuit breaker, not execution authority;\ncompose it outside `withMcpGuard` when both controls are required.\n\nSecret detection must block or quarantine the original call. This package does\nnot silently redact an already-approved payload, because that would execute a\ndifferent action than the one whose digest was authorized.\n\n## What this is — and what it is NOT\n\n- **Reference implementation.** It exercises the control flow, the demand\n  hook, the EP-RECEIPT-v1 emission *shape*, and an append-only provenance ledger\n  — all in-process with pluggable adapters. Status: experimental.\n- **The EP Core is FROZEN.** This package **never** mints, mutates,\n  re-canonicalizes, or re-signs an `EP-RECEIPT-v1`. Issuance and consent/signoff\n  are delegated to **caller-supplied adapters** (an EP host,\n  [`@emilia-protocol/issue`](https://www.npmjs.com/package/@emilia-protocol/issue),\n  a WebAuthn authenticator).\n- **Composition, not ownership.** The \"provenance entry\" is an **additive\n  composite** that *bundles references* to existing v1 receipts (by `receipt_id`\n  + content hash). It is **not** a new wire format for receipts and changes\n  nothing about Core. The full chained object (`EP-PROVENANCE-CHAIN-v1`) is a\n  **spec proposal governed by a PIP** — this package only anchors the minimal\n  in-process ledger.\n- **No new trust.** Verification reuses\n  [`@emilia-protocol/require-receipt`](https://www.npmjs.com/package/@emilia-protocol/require-receipt)\n  (offline Ed25519, pinned issuer keys). Re-verifying provenance = re-verifying\n  each linked v1 receipt + checking the append-only hash chain.\n- **Fails closed.** Missing receipt, broken signature, wrong action binding,\n  stale receipt, tampered ledger entry → **refusal**, never silent pass.\n- **Agent identity is a CLAIM** (scoped, attestable) — this package does not\n  assert EP proves strong agent identity. **Liability attestation** names an\n  accountable owner; it is *evidence, not a legal determination*.\n\n## The flow\n\n```\nMCP tool call ── classify ─┬─ reversible / read-only ─────────────────► run tool\n                           │\n                           └─ irreversible\n                               ├─ receipt presented ─► demand hook (offline verify)\n                               │                         ├─ invalid ─► refusal (STOP)\n                               │                         └─ valid ──► append provenance ─► run\n                               └─ no receipt ─► consent ─► Class-A signoff ─► issueReceipt\n                                                  │           │                  │\n                                                  └─ deny ─► refusal (STOP) ◄┘ (any stage)\n                                                                                  │\n                                       self-verify issued EP-RECEIPT-v1 (fail closed)\n                                                                                  │\n                                                          append provenance ─► run tool\n```\n\n## Wiring it into an MCP server's tool dispatch\n\n### Customer-owned protection activation\n\n`withCustomerOwnedProtectionGateway()` is the production assembly path for a\ncustomer-signed Consequence Firewall protection plan. Gate verifies the signed\n`EP-PROTECTION-ACTIVATION-v1` artifact first. The owning process then pins its\nexact digest, customer identity, customer key, tenant, and gateway before this\nwrapper derives the MCP tool map.\n\n```js\nimport { withCustomerOwnedProtectionGateway } from '@emilia-protocol/mcp-guard';\nimport { verifyProtectionActivation } from '@emilia-protocol/gate/protection-activation';\n\nconst verifiedActivation = verifyProtectionActivation(activation, {\n  trusted_keys: customerKeys,\n  expected: {\n    activation_id: 'activation:finance:01',\n    tenant_id: 'tenant:finance',\n    gateway_id: 'gateway:finance:mcp',\n    authorizer_id: 'customer:finance',\n  },\n});\n\nconst dispatch = withCustomerOwnedProtectionGateway(handleTool, {\n  verifiedActivation,\n  expectedActivationDigest: pinnedActivationDigest,\n  expectedOwnerId: 'customer:finance',\n  expectedOwnerKeyId: 'key:finance-protection',\n  tenantId: 'tenant:finance',\n  gatewayId: 'gateway:finance:mcp',\n  ledger: durableProvenanceLedger,\n  store: durableReceiptConsumptionStore,\n  readOnlyTools: ['get_balance'],\n});\n```\n\nSelected MCP tools inherit the signed manifest's action family and assurance\nfloor. Unknown tools remain irreversible by default. Only a locally configured\nread-only set passes without a receipt. The wrapper receives the tool handler,\nnot provider credentials, so the executor keeps credential custody.\n\nThe signed activation is gateway configuration. It is not per-action\nauthorization, proof that a connector was installed, proof of complete\nmediation, or proof of an external effect. Production assembly requires both a\ndurable one-time consumption store and a durable, startup-verified provenance\nledger.\n\n`withMcpGuard` wraps the dispatcher the server already calls. It does **not**\ntouch transport, schemas, or the tool list.\n\n```js\nimport {\n  createPostgresProvenanceLedgerStore,\n  ProvenanceLedger,\n  withMcpGuard,\n} from '@emilia-protocol/mcp-guard';\n\nconst provenanceStore = createPostgresProvenanceLedgerStore({\n  query: (text, params) => pgPool.query(text, params),\n  tenantId: 'tenant:production',\n  ledgerId: 'mcp:primary',\n});\nconst provenanceLedger = await ProvenanceLedger.open({ store: provenanceStore });\n\n// `handleTool(name, args, extra)` is your server's existing dispatcher.\nconst guardedHandleTool = withMcpGuard(handleTool, {\n  // 1) Which tools are irreversible? (annotation > policy > default)\n  annotations: {\n    release_payment: { irreversible: true, action: 'payment.release' },\n    delete_record:   { irreversible: true, action: 'record.delete' },\n    search_entities: { irreversible: false },          // trusted local policy: pass through\n  },\n  policy: (name) => /^(release|delete|wire|transfer)_/.test(name),\n  defaultIrreversible: true, // secure default; explicitly annotate read-only tools\n\n  // 2) Demand hook config (offline verify; pin the issuers you trust).\n  verifyOpts: {\n    trustedKeys: [process.env.EMILIA_ISSUER_PUBKEY],   // base64url SPKI\n    maxAgeSec: 900,\n    allowedOutcomes: ['allow', 'allow_with_signoff'],\n    assuranceClass: 'class_a',\n    approverKeys: ENROLLED_APPROVER_KEYS,\n    rpId: 'tools.example.com',\n    allowedOrigins: ['https://tools.example.com'],\n    // Required for quorum: relying-party-pinned roster, threshold, roles,\n    // initiator exclusion, and distinct-human/key requirements.\n    quorumPolicy: HIGH_RISK_TOOL_QUORUM_POLICY,\n  },\n\n  // 3) One-time consumption. reserve() is an atomic insert-if-absent; commit\n  // and release are ownership-fenced. Use one durable store across the fleet.\n  store: durableReceiptStore, // { reserve, commit, release }\n\n  // 4) Durable provenance. Startup reloads and verifies the stored chain;\n  // each entry commits before the protected handler is called.\n  ledger: provenanceLedger,\n\n  // 5) Adapters — REQUIRED to exercise Path B (mint a new receipt).\n  //    Without them the middleware fails closed at the first missing stage.\n  requestConsent:       async (ctx) => ({ approved: await askUser(ctx) }),\n  requestClassASignoff: async (ctx) => ({ approved: await webauthnAssert(ctx) }),\n  issueReceipt:         async (ctx) => ({ receipt: await epHost.mint(ctx) }), // EP-RECEIPT-v1\n});\n\n// Then dispatch through the guarded function instead of the raw one.\nconst result = await guardedHandleTool(name, args, { _meta: request.params._meta });\n```\n\nBoth presented receipts and receipts minted by Path B are reserved before the\ntool is invoked and committed after any invocation attempt. A replay, concurrent\npresentation, or uncertain effect cannot reuse the same approval. The default\nstore is process-local for examples only; production fleets must inject the\nshared durable store shown above.\n\nFor every irreversible call, the middleware binds the receipt to the configured\naction family **and** a strict-canonical digest of the tool name and material\narguments. For example, `payment.release` becomes\n`payment.release:sha256:<digest>`. Changing an amount, destination, or any other\nargument therefore produces a different required action. Values outside EP's\nexecutor canonical profile (including unsafe integers, `NaN`, `undefined`, and\ncyclic objects) refuse before an adapter or tool executes. Finite decimal\nmeasurements are accepted and bound to their exact JSON representation.\n`issueReceipt(ctx)` must mint the exact `ctx.action` supplied by the guard.\n\n> **Do not edit the shared mcp-server in this repo to adopt this.** The exact,\n> minimal change is a one-line swap at the dispatch site\n> (`handleTool(...)` → `guardedHandleTool(...)`) plus constructing the wrapper\n> once at startup. See **\"Exact wiring\"** at the bottom.\n\n## Live v1 enforcement with the SDK\n\nIf you want the system-of-record guarantee, use `withMcpReceiptGuard` with\n`@emilia-protocol/sdk`. The MCP wrapper classifies the tool call; the SDK drives\nthe live v1 loop: create receipt → request signoff if required → consume before\nthe write → run the tool → emit execution attestation.\n\n```js\nimport { EPClient } from '@emilia-protocol/sdk';\nimport { withMcpReceiptGuard } from '@emilia-protocol/mcp-guard';\n\nconst ep = new EPClient({\n  apiKey: process.env.EP_API_KEY,\n  baseUrl: process.env.EP_BASE_URL,\n});\n\nconst guardedHandleTool = withMcpReceiptGuard(handleTool, {\n  client: ep,\n  executingSystem: 'acme-mcp-server',\n  annotations: {\n    release_payment: {\n      irreversible: true,\n      actionType: 'large_payment_release',\n      targetResourceId: (args) => args.payment_id,\n      afterState: (args) => ({ payment_id: args.payment_id, amount: args.amount, currency: args.currency }),\n      amount: (args) => args.amount,\n      currency: (args) => args.currency,\n      approverId: 'ap_controller_jane',\n      onSignoffRequired: async ({ signoff }) => waitForApprovedSignoff(signoff?.signoff_id),\n    },\n    search_payments: { irreversible: false },\n  },\n});\n\n// One-line dispatch swap:\nconst result = await guardedHandleTool(name, args, { _meta: request.params._meta });\n```\n\nIf consume fails, `handleTool` is never called. If signoff is required and\n`onSignoffRequired` is omitted, the SDK fails closed and the irreversible tool\ndoes not run.\n\n## The demand hook on its own\n\nUse it anywhere you can read a tool call. Returns a verified result or a\nready-to-return legacy refusal **object** (not an HTTP response), so it drops\ninto any MCP tool-dispatch path.\n\n```js\nimport { demandReceipt } from '@emilia-protocol/mcp-guard';\n\nconst d = demandReceipt({\n  action: 'payment.release',\n  args,                                  // carries __ep.receipt / __ep.receipt_b64 / emilia_receipt\n  meta: request.params._meta,            // or x-emilia-receipt header passthrough\n  verifyOpts: { trustedKeys: [issuerPubKey], maxAgeSec: 900 },\n});\n\nif (!d.ok) return d.refusal;             // FAIL CLOSED — hand this back to the agent\n// d.verified = { ok, outcome, subject, receipt_id, signer }\n```\n\nThe refusal object (legacy MCP problem-details shape):\n\n```json\n{\n  \"ep_refused\": true,\n  \"status\": 402,\n  \"code\": \"emilia_receipt_required\",\n  \"title\": \"EMILIA Receipt Required\",\n  \"required\": {\n    \"action\": \"payment.release\",\n    \"header\": \"X-EMILIA-Receipt: base64(<EP-RECEIPT-v1 JSON>)\",\n    \"retry_with\": \"__ep.receipt = <EP-RECEIPT-v1 JSON>  (or __ep.receipt_b64 = base64(JSON))\",\n    \"how\": \"Gate this action first (ep_guard_action / the trust gate), obtain an EP-RECEIPT-v1, then retry this tool with __ep.receipt set.\"\n  }\n}\n```\n\n## Where the agent puts the receipt\n\nThe middleware looks, in order, at:\n\n1. `args.__ep.receipt` — the EP-RECEIPT-v1 object inline\n2. `args.__ep.receipt_b64` — `base64(JSON)`\n3. `args.emilia_receipt` — object, body-style (matches require-receipt)\n4. `_meta['x-emilia-receipt']` — `base64(JSON)`, header-style passthrough\n\nEP control fields (`__ep`, `emilia_receipt`) are stripped before the real tool\nruns.\n\n## Classification rules (first hit wins)\n\n1. **Per-call escalation** — `args.__ep.irreversible === true` (caller data cannot downgrade)\n2. **Trusted local annotation** — `annotations[name].irreversible`.\n   `destructiveHint` may only escalate. MCP `readOnlyHint` is advisory and is\n   ignored by default; set `trustReadOnlyHints: true` only after independently\n   validating the metadata source.\n3. **Policy fn** — `policy(name, args) → boolean` (a throwing policy is treated\n   as irreversible — fail safe)\n4. **Default** — `defaultIrreversible` (true unless you explicitly lower it)\n\n`getAnnotations()` is treated as untrusted registry metadata: it may contribute\nonly `destructiveHint`/`readOnlyHint`, cannot replace a locally pinned action or\n`irreversible` decision, and a throwing resolver fails closed.\n\n## Provenance ledger\n\n```js\nimport {\n  createPostgresProvenanceLedgerStore,\n  ProvenanceLedger,\n} from '@emilia-protocol/mcp-guard';\n\nconst store = createPostgresProvenanceLedgerStore({\n  query: (text, params) => pgPool.query(text, params),\n  tenantId: 'tenant:production',\n  ledgerId: 'mcp:primary',\n});\nconst ledger = await ProvenanceLedger.open({ store });\n// ... after some guarded irreversible calls:\nledger.verifyChain();   // { ok: true, length } or { ok:false, reason, index } — fails closed\nledger.entries;         // frozen EP-PROVENANCE-ENTRY-v1 snapshot\n```\n\nEach entry references one v1 receipt (`receipt_id` + content hash), the verified\nsummary (outcome/subject/signer), the scoped **agent claim**, and the\n**liability** owner. `verifyChain()` proves that the supplied entry array is\nself-consistent. It cannot by itself detect truncation to an earlier valid\nprefix and does **not** replace per-receipt verification. The shipped\nPostgreSQL store supplies the durable append-only head and atomic\ncompare-and-append that the in-memory chain alone cannot provide.\n\n`withMcpGuard()` requires a durable, startup-opened ledger by default. The\nliteral `allowEphemeralLedger: true` escape hatch exists only for tests and\nlocal demonstrations; it must not be used for a production audit trail. Install\n`sql/provenance-ledger-v1.sql`, grant its two RPCs to a dedicated runtime role,\nand grant no table privileges. Before granting the runtime role, the deployment\nowner calls `ep_mcp_provenance_bind(tenant_id, ledger_id)` once. The binding is\npermanent: one installed schema is one tenant/ledger authority domain, so a\nruntime that bypasses the adapter cannot select another tenant's history.\n\n## What needs a live MCP host / signer to exercise\n\nThis is a reference implementation. The following require real infrastructure\nand are intentionally adapter-shaped (no-op defaults **fail closed**):\n\n| Capability | Needs | Adapter |\n| --- | --- | --- |\n| End-to-end tool dispatch | a running MCP host calling `handleTool` | wire `withMcpGuard` at the dispatch site |\n| Real consent UX | a user-facing consent surface | `requestConsent` |\n| Class-A signoff | a WebAuthn / hardware authenticator + a named approver | `requestClassASignoff` |\n| Mint EP-RECEIPT-v1 | an EP host **or** `@emilia-protocol/issue` + signing keys | `issueReceipt` |\n| Offline verify | pinned issuer public keys | `verifyOpts.trustedKeys` |\n\nWithout adapters you can still exercise: classification, the **demand hook**\nagainst a pre-issued receipt, the **402 refusal** path, and the **provenance\nledger** chain verification — all offline, no network. Construct an ephemeral\nledger only with `allowEphemeralLedger: true` and only for that purpose.\n\n## Exact wiring (no edits to the shared mcp-server)\n\n1. **Install** `@emilia-protocol/mcp-guard` and `@emilia-protocol/require-receipt`.\n2. **At server startup**, open and verify the durable provenance ledger, then\n   build the wrapper once:\n   ```js\n   import { ProvenanceLedger, withMcpGuard } from '@emilia-protocol/mcp-guard';\n   const guardedHandleTool = withMcpGuard(handleTool, {\n     ledger: await ProvenanceLedger.open({ store: durableProvenanceStore }),\n     /* annotations, policy, verifyOpts, adapters */\n   });\n   ```\n3. **At the dispatch site** (inside the `CallToolRequestSchema` handler), change\n   the single call:\n   ```diff\n   - const out = await handleTool(name, args, { _meta: req.params._meta });\n   + const out = await guardedHandleTool(name, args, { _meta: req.params._meta });\n   ```\n   That single substitution is the whole adoption. Nothing else changes — the\n   tool list, schemas, and transport are untouched.\n4. **Return the refusal verbatim.** When the result is `{ ep_refused: true }`,\n   surface it as the tool result so the agent can read `required.retry_with` and\n   come back with a receipt.\n5. Monitor append failures. A failed durable append prevents the protected\n   handler from running; it is never silently downgraded to memory.\n\nApache-2.0 · part of [EMILIA Protocol](https://www.emiliaprotocol.ai) ·\n**reference implementation, experimental**\n```\n","readmeFilename":"README.md"}