Notary

Verify a notarization

A Kenwea record is a signed statement of what an artifact did — the exact bytes, run under stated constraints, at a moment in time. Paste one here and check it against our published key. This runs entirely in your browser — the payload and signature are never sent anywhere, including to us.

That is deliberate. A page where Kenwea tells you Kenwea's signature is fine would prove nothing; the whole point of signing a verdict is that you do not have to take our word for it. Better still, don't use this page at all — verify it in your own code. This exists so you can see it work before you write any.

Step one

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 fetches the exact bytes npm would install, runs the package's own declared install scripts in a container with no network, all capabilities dropped and a read-only filesystem, and prints a verdict signed under our published Ed25519 key and bound to the sha256 of what it read. A Python wheel or source zip is unpacked with the standard library only, each top-level package is imported, and a declared console script is invoked with --help. The signedAttestation block in the result is what the box below checks.

What it does not do, so nobody is surprised: dependencies are not installed, so it measures a package's own install surface and not the transitive tree. Code that only runs when the consuming app calls it is out of reach. Anonymous keys get 20 checks an hour. When the limit is ours, a runtime we do not have for instance, the result says manual_review and names our limit rather than blaming your code.

As a CI gate, the same check is a GitHub Action:

- uses: kenwea-protocol/kenwea-notary-action@v1
  with:
    package: your-package-name
    fail-on: rejected
Step two

Use it inside your tools

The notary is also an MCP server with three tools and no key: kenwea.notary.check takes an npm package name or an https URL, kenwea.notary.verify checks a signed record, and kenwea.notary.getPublicKey returns the key so you can check it with your own code. Any MCP client can use it, 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"
    }
  }
}

Windsurf is now Devin Desktop. Cascade reads mcp_config.json from %APPDATA%\devin\ on Windows or ~/.config/devin/ elsewhere; Devin Local reads .devin/mcp_config.json in the project or your user config, where the field is url rather than serverUrl. The command above writes it for you.

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_verify

The three framework snippets were run against the live server on 29 September 2026 (langchain-mcp-adapters 0.3.2, llama-index-tools-mcp 0.4.8, crewai-tools 1.15.23). Without a key the limit is 20 checks an hour per network address.

What a record does and does not say

  • The claim is about the hash, not the URL. A valid signature says those exact bytes produced that verdict. The address can serve something else tomorrow — hash what you hold and compare it to contentSha256.
  • An unreadable artifact is never signed. If we could not fetch the bytes there is no signature at all, rather than a signed “we could not read it” that an attestation scanner would count as a finding.
  • A signature is not an endorsement. It says what happened under stated constraints. approved means it ran and exited zero — not that the code is good, safe for your use, or does what it claims.

Public key: /.well-known/kenwea-attestation-key