Verify a notarization
Paste a Kenwea record and check its signature against our published key. It runs in your browser, nothing is sent to us, so you do not have to take our word for it.

Try it first
One command, no account, no key. Name any npm package, or give an https URL to a file, an npm tarball or a Python wheel:
npx -y @kenwea/mcp check lodash
It installs the package in a sealed box with no real network and decoy credentials, and traces what its install steps reach for. The answer starts with one word, from nothing_runs and quiet to sends_credentials (do not install it). The signedAttestation block in the result is what the box below checks. A quiet trace is evidence, not proof.
As a CI gate, the GitHub Action checks your whole lockfile and fails the step on what the signed record says. From a shell: npx -y @kenwea/mcp check-tree package-lock.json.
- uses: kenwea-protocol/kenwea-notary-action@v2
with:
lockfile: package-lock.json # the whole tree
fail-on: network,credentialsUse it inside your tools
In Claude Code, a plugin checks each package before Claude installs it, and asks you first if an install step reaches for the network.
/plugin marketplace add kenwea-protocol/kenwea-claude-plugin /plugin install kenwea-notary-guard@kenwea
The notary is also an MCP server, no key needed, so your agent can ask before it installs something.
https://mcp.kenwea.com/notary/v1
Claude Code
claude mcp add --transport http \ kenwea-notary https://mcp.kenwea.com/notary/v1
Devin Local (Windsurf's default agent)
devin mcp add kenwea-notary \ https://mcp.kenwea.com/notary/v1
Windsurf Cascade (mcp_config.json)
{
"mcpServers": {
"kenwea-notary": {
"serverUrl": "https://mcp.kenwea.com/notary/v1"
}
}
}LangChain
# pip install langchain-mcp-adapters
from langchain_mcp_adapters.client import MultiServerMCPClient
client = MultiServerMCPClient({"kenwea-notary": {
"transport": "streamable_http",
"url": "https://mcp.kenwea.com/notary/v1"}})
tools = await client.get_tools()LlamaIndex
# pip install llama-index-tools-mcp
from llama_index.tools.mcp import (
BasicMCPClient, McpToolSpec)
client = BasicMCPClient("https://mcp.kenwea.com/notary/v1")
tools = await McpToolSpec(
client=client).to_tool_list_async()CrewAI
# pip install "crewai-tools[mcp]"
from crewai_tools import MCPServerAdapter
server = {"url": "https://mcp.kenwea.com/notary/v1",
"transport": "streamable-http"}
with MCPServerAdapter(server) as tools:
... # kenwea_notary_check, kenwea_notary_verifyWithout a key the limit is 20 checks an hour.
Not built yet
For teams: private packages, alerts and a shared history
Private packages, lockfile alerts and one history for a team. This paid tier does not exist yet. Leave an address if you would use it.
What a record does and does not say
- The claim is about the hash, not the URL. Hash what you hold and compare it to contentSha256.
- An unreadable artifact is never signed. No bytes, no signature.
- A signature is not an endorsement. It says what happened, not that the code is good.
Every key we have signed with, and its status: /.well-known/kenwea-attestation-keys.json. The active key alone, as PEM: /.well-known/kenwea-attestation-key. A record signed with a revoked key proves nothing.
Every record is also added to a public, append only transparency log signed with the same key. kenwea_notary_verify checks inclusion for you and says log.included.