signet

signet

Open-source MCP server that exposes Signet cryptographic tools over stdio. It provides tools to generate Ed25519 keypairs, sign MCP actions, verify Signet receipts, and compute canonical content hashes for AI agent audit and accountability workflows.

Category
访问服务器

README

<h1 align="center">Signet</h1>

<p align="center"> <strong>Signed audit trails for AI agent tool calls</strong><br/> <sub>See exactly which agent called which tool, when, and with what params hash. Verify offline in 3 lines.</sub> </p>

<p align="center"> <a href="https://github.com/Prismer-AI/signet/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/Prismer-AI/signet/ci.yml?branch=main&style=flat-square&labelColor=black&label=CI" alt="CI"></a> <a href="https://github.com/Prismer-AI/signet/releases/latest"><img src="https://img.shields.io/github/v/release/Prismer-AI/signet?style=flat-square&labelColor=black&color=green&label=release" alt="Release"></a> <a href="https://github.com/Prismer-AI/signet/blob/main/LICENSE-APACHE"><img src="https://img.shields.io/badge/license-Apache--2.0%20%2F%20MIT-blue?labelColor=black&style=flat-square" alt="License"></a> <a href="https://github.com/Prismer-AI/signet/stargazers"><img src="https://img.shields.io/github/stars/Prismer-AI/signet?style=flat-square&labelColor=black&color=yellow" alt="Stars"></a> </p>

<p align="center"> <img src="https://img.shields.io/badge/SDKs-333?style=flat-square" alt="SDKs"> <a href="https://crates.io/crates/signet-core"><img src="https://img.shields.io/crates/v/signet-core?style=flat-square&labelColor=black&color=dea584&logo=rust&logoColor=white&label=signet--core" alt="crates.io"></a> <a href="https://www.npmjs.com/package/@signet-auth/mcp"><img src="https://img.shields.io/npm/v/@signet-auth/mcp?style=flat-square&labelColor=black&color=cb3837&logo=npm&logoColor=white&label=mcp" alt="npm"></a> <a href="https://pypi.org/project/signet-auth/"><img src="https://img.shields.io/pypi/v/signet-auth?style=flat-square&labelColor=black&color=3775A9&logo=python&logoColor=white&label=signet--auth" alt="PyPI"></a> </p>

<p align="center"> <a href="./README.md"><img alt="English" src="https://img.shields.io/badge/English-d9d9d9"></a> <a href="./README.zh.md"><img alt="简体中文" src="https://img.shields.io/badge/简体中文-d9d9d9"></a> </p>

AI agents can open tickets, call MCP tools, run shell commands, and ship code with almost no built-in accountability. Signet gives each agent an Ed25519 identity, signs every tool call, writes a hash-chained audit log, and lets you verify receipts offline.

If Signet is useful to you, star this repo to help more teams find it.

<p align="center"> <img src="demo-cli.svg" alt="Signet demo" width="820"> </p>

<p align="center"> <sub>See also the <a href="./demo-mcp.svg">MCP flow diagram</a>.</sub> </p>

Why Signet

Signet adds a lightweight trust layer for agent actions:

  • Sign every tool call with the agent's cryptographic key
  • Audit what happened with an append-only, hash-chained local log
  • Verify any action receipt offline, no network needed
  • Integrate with Claude Code, Codex CLI, MCP clients and servers, Python frameworks, and Vercel AI SDK

Try It In 30 Seconds

pip install signet-auth
from signet_auth import SigningAgent

agent = SigningAgent.create("my-agent", owner="team")
receipt = agent.sign("github_create_issue", params={"title": "fix bug"})

assert agent.verify(receipt)
print(receipt.id)

Prefer a different entry point? See the sections below for Claude Code, Codex CLI, the CLI, MCP integration, Python frameworks, and Vercel AI SDK.

When Teams Reach For Signet

  • You need an audit trail for coding agents, MCP tools, or CI automation
  • You want to prove which agent requested an action after an incident
  • You need receipts that can be verified offline without depending on a hosted service
  • You want signed tool-call evidence without adding a proxy or gateway to your stack

What Signet Is And Isn't

  • Signet is an attestation layer for agent actions: sign, audit, and verify
  • Signet is designed to fit into existing agent stacks with SDKs, plugins, and MCP middleware
  • Signet is not a policy engine, firewall, or action blocker
  • Signet is not a replacement for gateways; it complements prevention and enforcement tools

Install

# CLI
cargo install signet-cli

# Python
pip install signet-auth

# TypeScript (MCP middleware)
npm install @signet-auth/core @signet-auth/mcp

# TypeScript (MCP server verification)
npm install @signet-auth/mcp-server

# TypeScript (Vercel AI SDK middleware)
npm install @signet-auth/vercel-ai

Quick Start

Claude Code Plugin

Auto-sign every tool call in Claude Code with zero configuration:

# From marketplace (if available)
claude plugin add signet

# Or from Git
claude plugin add --from https://github.com/Prismer-AI/signet

# Or via CLI
signet claude install

Every tool call is signed with Ed25519 and logged to a hash-chained audit trail at ~/.signet/audit/.

Alternative: add a hook directly to ~/.claude/settings.json without the plugin system:

{
  "hooks": {
    "PostToolUse": [{
      "matcher": "*",
      "hooks": [{
        "type": "command",
        "command": "node ~/signet/plugins/claude-code/bin/sign.cjs",
        "timeout": 5
      }]
    }]
  }
}

Codex Plugin

Auto-sign every Bash tool call in Codex CLI:

git clone https://github.com/Prismer-AI/signet.git
cp -r signet/plugins/codex ~/.codex/plugins/signet

Then add the hook to ~/.codex/hooks.json:

{
  "hooks": {
    "PostToolUse": [{
      "matcher": "Bash",
      "hooks": [{
        "type": "command",
        "command": "node \"$HOME/.codex/plugins/signet/bin/sign.cjs\"",
        "timeout": 5
      }]
    }]
  }
}

Or use the MCP server for on-demand signing tools:

codex mcp add signet -- npx @signet-auth/mcp-tools

CLI

# Generate an agent identity
signet identity generate --name my-agent

# Sign an action
signet sign --key my-agent --tool "github_create_issue" \
  --params '{"title":"fix bug"}' --target mcp://github.local

# Verify a receipt
signet verify receipt.json --pubkey my-agent

# Audit recent actions
signet audit --since 24h

# Verify log integrity
signet verify --chain

MCP Integration (TypeScript)

<p align="center"> <img src="demo-mcp.svg" alt="Signet MCP bilateral flow demo" width="820"> </p>

import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
import { generateKeypair } from "@signet-auth/core";
import { SigningTransport } from "@signet-auth/mcp";

// Generate an agent identity
const { secretKey } = generateKeypair();

// Wrap any MCP transport -- all tool calls are now signed
const inner = new StdioClientTransport({ command: "my-mcp-server" });
const transport = new SigningTransport(inner, secretKey, "my-agent");

const client = new Client({ name: "my-agent", version: "1.0" }, {});
await client.connect(transport);

// Every callTool() is now cryptographically signed
const result = await client.callTool({
  name: "echo",
  arguments: { message: "Hello!" },
});

Every tools/call request gets a signed receipt injected into params._meta._signet. MCP servers can optionally verify these signatures:

import { verifyRequest } from "@signet-auth/mcp-server";

server.setRequestHandler(CallToolRequestSchema, async (request) => {
  const verified = verifyRequest(request, {
    trustedKeys: ["ed25519:..."],
    maxAge: 300,
  });
  if (!verified.ok) return { content: [{ type: "text", text: verified.error }], isError: true };
  console.log(`Verified: ${verified.signerName}`);
  // process tool call...
});

<p align="center"> <img src="demo-mcp.svg" alt="Signet MCP end-to-end demo" width="820"> </p>

Vercel AI SDK Integration

import { generateText } from "ai";
import { generateKeypair } from "@signet-auth/core";
import { createSignetCallbacks } from "@signet-auth/vercel-ai";

const { secretKey } = generateKeypair();
const callbacks = createSignetCallbacks(secretKey, "my-agent");

const result = await generateText({
  model: openai("gpt-4"),
  tools: { myTool },
  ...callbacks,
  prompt: "...",
});

// Every tool call is now signed
console.log(callbacks.receipts);

Reference MCP Server

This repo also includes a minimal MCP reference server that demonstrates server-side verification with @signet-auth/mcp-server.

cd examples/mcp-agent
npm ci
npm run verifier-server

Available tools:

  • inspect_current_request — verifies the current MCP tool call if it includes params._meta._signet
  • verify_receipt — verifies a raw Signet receipt against a public key
  • verify_request_payload — verifies a synthetic MCP tools/call payload offline

Environment variables:

  • SIGNET_TRUSTED_KEYS — comma-separated ed25519:<base64> public keys
  • SIGNET_REQUIRE_SIGNATUREtrue or false (default false)
  • SIGNET_MAX_AGE — max receipt age in seconds (default 300)
  • SIGNET_EXPECTED_TARGET — optional expected receipt.action.target

Standalone MCP Signing Server

@signet-auth/mcp-tools exposes Signet signing, verification, and audit as MCP tools — plug into any MCP-compatible client:

npx @signet-auth/mcp-tools

Available tools: signet_sign, signet_verify, signet_audit, signet_identity.

Python (LangChain / CrewAI / AutoGen + 6 more)

pip install signet-auth
from signet_auth import SigningAgent

# Create an agent identity (saved to ~/.signet/keys/)
agent = SigningAgent.create("my-agent", owner="willamhou")

# Sign any tool call -- receipt is auto-appended to audit log
receipt = agent.sign("github_create_issue", params={"title": "fix bug"})

# Verify
assert agent.verify(receipt)

# Query audit log
for record in agent.audit_query(since="24h"):
    print(f"{record.receipt.ts} {record.receipt.action.tool}")

LangChain Integration

from signet_auth import SigningAgent
from signet_auth.langchain import SignetCallbackHandler

agent = SigningAgent("my-agent")
handler = SignetCallbackHandler(agent)

# Every tool call is now signed + audited
chain.invoke(input, config={"callbacks": [handler]})

# Async chains supported too
from signet_auth.langchain import AsyncSignetCallbackHandler

CrewAI Integration

from signet_auth import SigningAgent
from signet_auth.crewai import install_hooks

agent = SigningAgent("my-agent")
install_hooks(agent)

# All CrewAI tool calls are now globally signed
crew.kickoff()

AutoGen Integration

from signet_auth import SigningAgent
from signet_auth.autogen import signed_tool, sign_tools

agent = SigningAgent("my-agent")

# Wrap a single tool
wrapped = signed_tool(tool, agent)

# Or wrap all tools at once
wrapped_tools = sign_tools([tool1, tool2], agent)

LangGraph Integration

LangGraph uses LangChain's callback system — the same handler works directly:

from signet_auth import SigningAgent
from signet_auth.langgraph import SignetCallbackHandler

agent = SigningAgent("my-agent")
handler = SignetCallbackHandler(agent)

result = graph.invoke(input, config={"callbacks": [handler]})

LlamaIndex Integration

from signet_auth import SigningAgent
from signet_auth.llamaindex import install_handler

agent = SigningAgent("my-agent")
handler = install_handler(agent)

# All tool call events are now signed
index = ... # your LlamaIndex setup
response = index.as_query_engine().query("What is Signet?")

# Access receipts
print(handler.receipts)

Pydantic AI Integration

from signet_auth import SigningAgent
from signet_auth.pydantic_ai_integration import SignetCapability

agent = SigningAgent("my-agent")
capability = SignetCapability(agent)

pydantic_agent = Agent(model, capabilities=[capability])

Google ADK Integration

from signet_auth import SigningAgent
from signet_auth.google_adk import SignetPlugin

agent = SigningAgent("my-agent")
plugin = SignetPlugin(agent)

# Pass as callback to ADK agent

Smolagents Integration

from signet_auth import SigningAgent
from signet_auth.smolagents import signet_step_callback

agent = SigningAgent("my-agent")
callback = signet_step_callback(agent)

bot = CodeAgent(tools=[...], model=model, step_callbacks=[callback])

OpenAI Agents SDK Integration

from signet_auth import SigningAgent
from signet_auth.openai_agents import SignetAgentHooks

agent = SigningAgent("my-agent")

oai_agent = Agent(
    name="assistant",
    hooks=SignetAgentHooks(agent),
    tools=[...],
)

Note: Tool call arguments are not yet available in the hook API (issue #939). Only the tool name is signed.

Low-Level API

from signet_auth import generate_keypair, sign, verify, Action

kp = generate_keypair()
action = Action("github_create_issue", params={"title": "fix bug"})
receipt = sign(kp.secret_key, action, "my-agent", "willamhou")
assert verify(receipt, kp.public_key)

Bilateral Receipt (Server Co-signing)

from signet_auth import generate_keypair, sign, sign_bilateral, verify_bilateral, Action

# Agent signs the tool call
agent_kp = generate_keypair()
action = Action("github_create_issue", params={"title": "fix bug"})
agent_receipt = sign(agent_kp.secret_key, action, "my-agent")

# Server co-signs with the response
server_kp = generate_keypair()
bilateral = sign_bilateral(
    server_kp.secret_key, agent_receipt,
    {"content": [{"type": "text", "text": "issue #42 created"}]},
    "github-server",
)
assert verify_bilateral(bilateral, server_kp.public_key)
assert bilateral.v == 3  # v3 = bilateral receipt

How It Works

Your Agent
    |
    v
SigningTransport (wraps any MCP transport)
    |
    +---> Signs each tool call (Ed25519)
    +---> Appends Action Receipt to local audit log (hash-chained)
    +---> Forwards request to MCP server (unchanged)

Agent-side only. MCP servers don't need to change.

Action Receipt

Every tool call produces a signed receipt:

{
  "v": 1,
  "id": "rec_e7039e7e7714e84f...",
  "action": {
    "tool": "github_create_issue",
    "params": {"title": "fix bug"},
    "params_hash": "sha256:b878192252cb...",
    "target": "mcp://github.local",
    "transport": "stdio"
  },
  "signer": {
    "pubkey": "ed25519:0CRkURt/tc6r...",
    "name": "demo-bot",
    "owner": "willamhou"
  },
  "ts": "2026-03-29T23:24:03.309Z",
  "nonce": "rnd_dcd4e135799393...",
  "sig": "ed25519:6KUohbnSmehP..."
}

The signature covers the entire receipt body (action + signer + timestamp + nonce) using RFC 8785 (JCS) canonical JSON. Modifying any field invalidates the signature.

CLI Commands

Command Description
signet identity generate --name <n> Generate Ed25519 identity (encrypted by default)
signet identity generate --unencrypted Generate without encryption (for CI)
signet identity list List all identities
signet identity export --name <n> Export public key as JSON
signet sign --key <n> --tool <t> --params <json> --target <uri> Sign an action
signet sign --hash-only Store only params hash (not raw params)
signet sign --output <file> Write receipt to file instead of stdout
signet sign --no-log Skip audit log append
signet verify <receipt.json> --pubkey <name> Verify a receipt signature
signet verify --chain Verify audit log hash chain integrity
signet audit List recent actions
signet audit --since <duration> Filter by time (e.g. 24h, 7d)
signet audit --tool <substring> Filter by tool name
signet audit --verify Verify all receipt signatures
signet audit --export <file> Export records as JSON
signet claude install Install Claude Code plugin (PostToolUse signing hook)
signet claude uninstall Remove Claude Code plugin

Passphrase via interactive prompt or SIGNET_PASSPHRASE env var for CI.

Documentation

Doc Description
Architecture System design, component overview, data flow
Security Crypto primitives, threat model, key storage
MCP Integration Guide Step-by-step MCP setup with SigningTransport
CI/CD Integration GitHub Actions example, key management for CI
Audit Log Guide Querying, filtering, hash chain verification
Contributing Build instructions, development workflow
Changelog Version history

Project Structure

signet/
├── crates/signet-core/       Rust core: identity, sign, verify, audit, keystore
├── signet-cli/               CLI tool (signet binary)
├── bindings/
│   ├── signet-ts/            WASM binding (wasm-bindgen)
│   └── signet-py/            Python binding (PyO3 + maturin)
├── plugins/
│   ├── claude-code/          Claude Code plugin (WASM signing + audit)
│   └── codex/                Codex CLI plugin (WASM signing + audit)
├── packages/
│   ├── signet-core/          @signet-auth/core — TypeScript wrapper
│   ├── signet-mcp/           @signet-auth/mcp — MCP SigningTransport middleware
│   ├── signet-mcp-server/    @signet-auth/mcp-server — Server verification
│   ├── signet-mcp-tools/     @signet-auth/mcp-tools — Standalone MCP signing server
│   └── signet-vercel-ai/     @signet-auth/vercel-ai — Vercel AI SDK middleware
├── examples/
│   ├── wasm-roundtrip/       WASM validation tests
│   └── mcp-agent/            MCP agent, echo server, and verifier server example
├── docs/                     Design docs, specs, plans
├── LICENSE-APACHE
└── LICENSE-MIT

Building from Source

Prerequisites

  • Rust (1.70+)
  • wasm-pack
  • Node.js (18+)
  • Python (3.10+) + maturin (for Python binding)

Build

# Rust core + CLI
cargo build --release -p signet-cli

# WASM binding
wasm-pack build bindings/signet-ts --target nodejs --out-dir ../../packages/signet-core/wasm

# TypeScript packages
cd packages/signet-core && npm run build
cd packages/signet-mcp && npm run build
cd packages/signet-mcp-tools && npm run build
# Python binding
cd bindings/signet-py
pip install maturin
maturin develop

Test

# Rust tests (95 tests)
cargo test --workspace

# Python tests (160 tests)
cd bindings/signet-py && pytest tests/ -v

# WASM roundtrip (8 tests)
node examples/wasm-roundtrip/test.mjs

# TypeScript tests (26 tests)
cd packages/signet-core && npm test
cd packages/signet-mcp && npm test
cd packages/signet-mcp-server && npm test
cd packages/signet-mcp-tools && npm test

# Plugin tests (54 tests)
cd plugins/claude-code && npm test
cd plugins/codex && npm test

# Vercel AI SDK tests (5 tests)
cd packages/signet-vercel-ai && npm test

# Reference verifier server smoke test
cd examples/mcp-agent && npm run smoke

Security

  • Ed25519 signatures (128-bit security level, ed25519-dalek)
  • Argon2id key derivation (OWASP recommended minimum)
  • XChaCha20-Poly1305 key encryption with authenticated associated data (AAD)
  • SHA-256 hash chain for tamper-evident audit log
  • RFC 8785 (JCS) canonical JSON for deterministic signatures

Keys stored at ~/.signet/keys/ with 0600 permissions. Override with SIGNET_HOME env var.

What Signet proves

  • Agent key X signed intent to call tool Y with params Z at time T

What Signet does NOT prove (yet)

  • That the MCP server executed the action (use bilateral receipts with signResponse() for server co-signing — shipped in v0.4)
  • That signer.owner actually controls the key (planned: identity registry)

Signet is an attestation tool (proving what happened), not a prevention tool (blocking bad actions). It complements policy enforcement tools like firewalls and gateways.

License

Apache-2.0 + MIT dual license.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选