Install
$ agentstack add mcp-capiscio-capiscio-mcp-python ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
MCP Guard
Tool-level trust enforcement for Model Context Protocol servers.
[](https://badge.fury.io/py/capiscio-mcp) [](https://www.python.org/downloads/) [](https://opensource.org/licenses/Apache-2.0)
MCP Guard (pip install capiscio-mcp) provides trust badges and identity verification for Model Context Protocol (MCP) tool calls. It implements:
- RFC-006: MCP Tool Authority and Evidence
- RFC-007: MCP Server Identity Disclosure and Verification
Installation
pip install capiscio-mcp
For MCP SDK integration (FastMCP wrapper):
pip install capiscio-mcp[mcp]
Why MCP Guard?
MCP servers expose powerful tools to autonomous agents—file systems, databases, APIs. But MCP itself doesn't define how to:
- Authenticate which agent is calling a tool
- Authorize whether that agent should have access
- Audit what happened for post-incident review
MCP Guard solves this with:
| Feature | Description | |---------|-------------| | @guard decorator | Protect tools with trust-level requirements | | Evidence logging | Cryptographic audit trail for every invocation | | Server identity | Verify MCP servers before connecting | | Server registration | Generate keypairs and register server DIDs | | Trust levels | 0 (self-signed) → 4 (extended validation) |
Quickstarts
> Building an MCP server? Start with [Quickstart 1](#quickstart-1-server-side-tool-guarding). > Connecting to MCP servers? Start with [Quickstart 2](#quickstart-2-client-side-server-verification). > Registering a server identity? Start with [Quickstart 3](#quickstart-3-server-registration).
Quickstart 1: Server-Side (Tool Guarding)
Protect your MCP tools with trust-level requirements:
from capiscio_mcp import guard
@guard(min_trust_level=2)
async def read_database(query: str) -> list[dict]:
"""Only agents with Trust Level 2+ can execute this tool."""
# ... database query logic
pass
# Sync version available
from capiscio_mcp import guard_sync
@guard_sync(min_trust_level=2)
def read_database_sync(query: str) -> list[dict]:
pass
With Full Configuration
from capiscio_mcp import guard, GuardConfig
config = GuardConfig(
min_trust_level=2,
trusted_issuers=["did:web:registry.capisc.io"],
allowed_tools=["read_*", "list_*"],
require_badge=True, # Deny anonymous access
)
@guard(config=config)
async def execute_query(sql: str) -> list[dict]:
pass
Quickstart 2: Client-Side (Server Verification)
Verify the identity of MCP servers you connect to:
from capiscio_mcp import verify_server, ServerState
result = await verify_server(
server_did="did:web:mcp.example.com",
server_badge="eyJhbGc...",
transport_origin="https://mcp.example.com",
)
if result.state == ServerState.VERIFIED_PRINCIPAL:
print(f"Trusted server at Level {result.trust_level}")
elif result.state == ServerState.DECLARED_PRINCIPAL:
print("Server identity declared but not verified")
elif result.state == ServerState.UNVERIFIED_ORIGIN:
print("Warning: Server did not disclose identity")
Quickstart 3: Server Registration
Register your MCP server's identity with the CapiscIO registry:
from capiscio_mcp import setup_server_identity
# One-step setup: generate keys + register with registry
result = await setup_server_identity(
server_id="550e8400-e29b-41d4-a716-446655440000", # From dashboard
api_key="sk_live_...", # Registry API key
ca_url="https://registry.capisc.io", # Optional, defaults to production
output_dir="./keys",
)
print(f"Server DID: {result['did']}")
# did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK
print(f"Private key saved to: {result['private_key_path']}")
Step-by-Step Registration
from capiscio_mcp import generate_server_keypair, register_server_identity
# Step 1: Generate keypair
keys = await generate_server_keypair(output_dir="./keys")
# Step 2: Register with registry
await register_server_identity(
server_id="550e8400-e29b-41d4-a716-446655440000",
api_key="sk_live_...",
did=keys["did_key"],
public_key=keys["public_key_pem"],
ca_url="https://registry.capisc.io", # Optional, defaults to production
)
MCP SDK Integration
For seamless integration with the official MCP Python SDK, install with the mcp extra:
pip install capiscio-mcp[mcp]
Server with FastMCP Wrapper
Create an MCP server with built-in trust enforcement:
from capiscio_mcp.integrations.mcp import CapiscioMCPServer
# db is your application's database connection (asyncpg, databases, etc.)
db = ... # e.g. databases.Database("postgresql://...")
server = CapiscioMCPServer.connect()
@server.tool(min_trust_level=2)
async def get_user(user_id: int) -> dict:
"""Only agents with Trust Level 2+ can read user data."""
return await db.fetch_one("SELECT * FROM users WHERE id = $1", user_id)
@server.tool(min_trust_level=1)
async def list_tables() -> list[str]:
"""Agents with a valid badge (Trust Level 1+) can list tables."""
return await db.get_table_names()
# Run the server (stdio transport)
server.run()
Client with Trust Verification
Connect to MCP servers via stdio transport:
from capiscio_mcp.integrations.mcp import CapiscioMCPClient
async with CapiscioMCPClient(
command="python",
args=["my_mcp_server.py"],
min_trust_level=1,
badge="eyJhbGc...", # Your client badge
) as client:
# List available tools
tools = await client.list_tools()
print(f"Available tools: {[t['name'] for t in tools]}")
# Call a tool
result = await client.call_tool("read_file", {"path": "/data/config.json"})
print(result)
CapiscioMCPServer.connect() — “Let's Encrypt” Style Setup
Register your MCP server and get a badge with a single call:
from capiscio_mcp.integrations.mcp import CapiscioMCPServer
server = CapiscioMCPServer.connect()
print(server.did) # did:web:registry.capisc.io:servers:550e8400-...
print(server.badge) # Current badge JWS (auto-issued)
Using Environment Variables
server = CapiscioMCPServer.connect()
| Variable | Required | Description | |----------|----------|-------------| | CAPISCIO_SERVER_ID | Yes | Server UUID from dashboard | | CAPISCIO_API_KEY | Yes | Registry API key | | CAPISCIO_SERVER_URL | No | Registry URL (default: production) | | CAPISCIO_SERVER_DOMAIN | No | Domain for badge issuance | | CAPISCIO_SERVER_PRIVATE_KEY_PEM | No | PEM-encoded Ed25519 private key for ephemeral environments |
Deploying to Containers / Serverless
In ephemeral environments (Docker, Lambda, Cloud Run) the local ~/.capiscio/ directory doesn't survive restarts. On first run the SDK generates a keypair and logs a capture hint:
╔══════════════════════════════════════════════════════════╗
║ New server identity generated — save key for persistence ║
╚══════════════════════════════════════════════════════════╝
Add to your secrets manager / .env:
CAPISCIO_SERVER_PRIVATE_KEY_PEM='-----BEGIN PRIVATE KEY-----\nMC4C...\n-----END PRIVATE KEY-----\n'
Copy that value into your secrets manager and set it as an environment variable. On subsequent starts the SDK will recover the same DID without generating a new identity.
Key resolution priority: env var → local file → generate new.
# docker-compose.yml
services:
mcp-server:
environment:
CAPISCIO_SERVER_ID: "550e8400-..."
CAPISCIO_API_KEY: "sk_live_..."
CAPISCIO_SERVER_PRIVATE_KEY_PEM: "${MCP_SERVER_KEY}" # from secrets
See the Deployment Guide for full examples.
Core Connection Modes
MCP Guard connects to capiscio-core for cryptographic operations:
Embedded Mode (Default)
SDK automatically downloads and manages the core binary:
pip install capiscio-mcp
# Just works! Binary downloaded on first use.
External Mode
Connect to a separately managed core service:
# Start core in another terminal
capiscio mcp serve --listen localhost:50051
# SDK connects to external core
export CAPISCIO_CORE_ADDR="localhost:50051"
Trust Levels
Per RFC-002 v1.4:
| Level | Name | Validation | Use Case | |-------|------|------------|----------| | 0 | Self-Signed (SS) | None, did:key issuer | Local dev, testing, demos | | 1 | Registered (REG) | Account registration | Development, internal agents | | 2 | Domain Validated (DV) | DNS/HTTP challenge | Production, B2B agents | | 3 | Organization Validated (OV) | DUNS/legal entity | High-trust production | | 4 | Extended Validated (EV) | Manual review + legal | Regulated industries |
Evidence Logging
Every tool invocation—allowed or denied—produces an evidence record:
from capiscio_mcp import guard, GuardError
@guard(min_trust_level=2)
async def sensitive_operation(data: dict) -> dict:
pass
try:
result = await sensitive_operation(data={"key": "value"})
except GuardError as e:
# Evidence logged even on denial
print(f"Denied: {e.reason}")
print(f"Evidence ID: {e.evidence_id}") # For audit trail
Evidence includes:
- Tool name and parameters hash (not raw params—PII safe)
- Caller identity (agent DID, badge JTI, auth level)
- Decision and reason
- Timestamp and unique evidence ID
Configuration Reference
GuardConfig
from capiscio_mcp import GuardConfig
config = GuardConfig(
min_trust_level=2, # Minimum trust level (0-4)
accept_level_zero=False, # Accept self-signed badges?
trusted_issuers=[ # List of trusted issuer DIDs
"did:web:registry.capisc.io",
],
allowed_tools=[ # Glob patterns for allowed tools
"read_*",
"list_*",
],
require_badge=True, # Deny anonymous/API key access
policy_version="v1.0", # Policy version for tracking
)
VerifyConfig
from capiscio_mcp import VerifyConfig
config = VerifyConfig(
trusted_issuers=[...], # Trusted issuer DIDs
min_trust_level=2, # Minimum required level
accept_level_zero=False, # Accept self-signed servers?
offline_mode=False, # Skip revocation checks?
skip_origin_binding=False, # Skip host/path binding?
)
Environment Variables
| Variable | Description | Default | |----------|-------------|---------| | CAPISCIO_SERVER_ID | Server UUID (for MCPServerIdentity) | — | | CAPISCIO_API_KEY | Registry API key (for MCPServerIdentity) | — | | CAPISCIO_SERVER_URL | Registry server URL | https://registry.capisc.io | | CAPISCIO_SERVER_DOMAIN | Domain for badge issuance | (derived from server URL) | | CAPISCIO_SERVER_PRIVATE_KEY_PEM | PEM-encoded Ed25519 private key (ephemeral envs) | — | | CAPISCIO_CORE_ADDR | External core address | (embedded mode) | | CAPISCIO_SERVER_ORIGIN | Server origin for guard | (auto-detect) | | CAPISCIO_LOG_LEVEL | Logging verbosity | info |
API Reference
Guard (RFC-006)
guard(config=None, min_trust_level=None, tool_name=None)— Async decoratorguard_sync(...)— Sync decoratorevaluate_tool_access(tool_name, params, credential, config)— Low-level APIcompute_params_hash(params)— Deterministic parameter hashingGuardConfig— Configuration dataclassGuardResult— Evaluation result dataclassGuardError— Exception for denied access
Server (RFC-007)
verify_server(server_did, server_badge, transport_origin, endpoint_path, config)— Async verificationverify_server_sync(...)— Sync verificationverify_server_strict(...)— Raises ServerVerifyError on any verification failureparse_http_headers(headers)— Extract identity from HTTP headersparse_jsonrpc_meta(meta)— Extract identity from MCP _metaVerifyConfig— Configuration dataclassVerifyResult— Verification result dataclassServerVerifyError— Exception for verification failures
Registration (Server Identity)
generate_server_keypair(key_id, output_dir)— Generate Ed25519 keypairgenerate_server_keypair_sync(...)— Sync versionregister_server_identity(server_id, api_key, did, public_key, ca_url)— Register DID with registryregister_server_identity_sync(...)— Sync versionsetup_server_identity(server_id, api_key, ca_url, output_dir, key_id)— Combined setupsetup_server_identity_sync(...)— Sync versionRegistrationError— Exception for registration failuresKeyGenerationError— Exception for key generation failures
Types
Decision— ALLOW / DENYAuthLevel— ANONYMOUS / API_KEY / BADGEDenyReason— Enumeration of denial reasonsTrustLevel— Trust levels 0-4 per RFC-002ServerState— VERIFIEDPRINCIPAL / DECLAREDPRINCIPAL / UNVERIFIED_ORIGINServerErrorCode— Enumeration of verification error codes
MCP SDK Integration (optional)
Requires pip install capiscio-mcp[mcp]:
CapiscioMCPServer.connect()— One-liner: load identity from env and create serverCapiscioMCPServer(name, did, badge, ...)— FastMCP wrapper with trust enforcementCapiscioMCPServer.tool(min_trust_level=...)— Decorator for guarded toolsCapiscioMCPServer.run(transport="stdio")— Run the serverCapiscioMCPClient(command, args, ...)— Client for stdio transport*CapiscioMCPClient.call_tool(name, args)— Call a tool on the serverCapiscioMCPClient.list_tools()— List available tools
*Note: Server identity verification in CapiscioMCPClient requires MCP SDK support for _meta passthrough in initialize responses. This is not yet available, so min_trust_level and fail_on_unverified parameters are currently not enforced. Server-side trust enforcement via @server.tool(min_trust_level=...) works fully.
Documentation
- RFC-006: MCP Tool Authority and Evidence
- RFC-007: MCP Server Identity Disclosure
- Server Registration Guide
- Server-Side Guide
- Client-Side Guide
- Evidence Logging Guide
Development
# Clone repository
git clone https://github.com/capiscio/capiscio-mcp-python.git
cd capiscio-mcp-python
# Install development dependencies
pip install -e ".[dev]"
# Run tests
pytest -v
# Run tests with coverage
pytest --cov=capiscio_mcp --cov-report=html
# Type checking
mypy capiscio_mcp
# Linting
ruff check capiscio_mcp
Related Packages
| Package | What it does | Install | |---------|-------------|---------| | Agent Guard | Runtime trust verification for A2A agents | pip install capiscio-sdk | | CapiscIO CLI | Agent validation for CI/CD pipelines | pip install capiscio | | capiscio-core | Go library, CLI binary, and gateway | Install guide |
Documentation · Website · Platform
License
Apache License 2.0
Contributing
See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: capiscio
- Source: capiscio/capiscio-mcp-python
- License: Apache-2.0
- Homepage: https://capisc.io/products/mcp-guard
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.