A production-ready Rust library that bridges Visa's Trusted Agent Protocol (TAP) with Anthropic's Model Context Protocol (MCP), enabling AI agents like Claude to securely authenticate with merchants and execute payment transactions.
The TAP-MCP Bridge acts as a protocol adapter, translating between:
- MCP layer: Application-layer tool calls (JSON-RPC 2.0 over stdio/HTTP)
- TAP layer: Transport-layer cryptographic authentication (RFC 9421 HTTP Message Signatures)
This enables AI agents to:
- β Authenticate with TAP-protected merchants using Ed25519 cryptographic signatures
- β Execute secure payment transactions with PCI-DSS compliant encryption
- β Browse merchant catalogs with verified agent identity
- β Maintain session state across multi-step interactions
TAP Compliance: 100% (18/18 requirements) Algorithm Correctness: 100% vs Visa reference implementation Test Coverage: 155 tests (100% passing) Security: PCI-DSS compliant with RFC 7516 JWE encryption
βββββββββββββββββββ
β AI Agent β Claude or other MCP-compatible agent
β (Claude) β
ββββββββββ¬βββββββββ
β MCP Protocol (JSON-RPC 2.0)
β
ββββββββββΌβββββββββββββββββββββββββββββββββββββββ
β TAP-MCP Bridge (this crate) β
β ββββββββββββββββ ββββββββββββββββββββ β
β β MCP Tools ββββββββ TAP Signatures β β
β β - checkout β β - RFC 9421 β β
β β - browse β β - Ed25519 β β
β β - verify β β - JWE (APC) β β
β ββββββββββββββββ ββββββββββββββββββββ β
ββββββββββ¬βββββββββββββββββββββββββββββββββββββββ
β HTTPS + TAP Signatures
β
ββββββββββΌβββββββββ
β TAP Merchant β E-commerce merchant with TAP support
βββββββββββββββββββ
- MCP Server Wrapper - Exposes TAP operations as MCP tools
- Protocol Adapter - Translates between MCP and TAP protocols
- TAP Client - Generates RFC 9421 HTTP Message Signatures with Ed25519
- Cryptographic Engine - JWE encryption, signature generation, key management
- β RFC 9421 HTTP Message Signatures with Ed25519
- β JWK Thumbprint key identifiers (RFC 7638)
- β Content-Digest header (RFC 9530, SHA-256)
- β Signature Expiration (8-minute maximum validity window)
- β Replay Protection (unique nonce per request, UUID v4)
- β
Interaction Type Tags (
agent-browser-auth,agent-payer-auth) - β
Public Key Directory (JWKS at
/.well-known/http-message-signatures-directory) - β ID Token (JWT) generation for consumer authentication
- β ACRO (Agentic Consumer Recognition Object)
- β APC (Agentic Payment Container) with RFC 7516 JWE encryption
- β PCI-DSS Compliance: JWE encryption for payment data (A256GCM + RSA-OAEP-256)
- β Defense-in-Depth: Application-level JWE + transport-level TLS
- β Memory Safety: Automatic zeroization of sensitive data
- β Type Safety: Rust's ownership model prevents cryptographic errors
- β Input Validation: HTTPS-only URLs, consumer ID format validation
- β Secure Key Management: No plaintext secrets in logs or errors
- β Async/Await: Built on Tokio for concurrent operations
- β Comprehensive Documentation: Rustdoc with examples for all public APIs
- β
Type-Safe Errors: Context-rich errors via
thiserror - β Extensive Testing: 155 automated tests (104 unit + 51 doc)
- β Zero Warnings: Strict clippy lints enforced
Add this to your Cargo.toml:
[dependencies]
tap-mcp-bridge = "0.1.0"
ed25519-dalek = "2.1" # For signing key generationuse ed25519_dalek::SigningKey;
use tap_mcp_bridge::{
mcp::{checkout_with_tap, CheckoutParams},
tap::{TapSigner, apc::{CardData, PaymentMethod, RsaPublicKey}},
};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Initialize TAP signer with agent credentials
let signing_key = SigningKey::from_bytes(&[0u8; 32]);
let signer = TapSigner::new(
signing_key,
"agent-123",
"https://agent.example.com"
);
// Create payment method (card)
let card = CardData {
number: "4111111111111111".to_owned(),
exp_month: "12".to_owned(),
exp_year: "25".to_owned(),
cvv: "123".to_owned(),
cardholder_name: "John Doe".to_owned(),
};
// Load merchant's public key for payment encryption
let merchant_pem = std::fs::read("merchant_public_key.pem")?;
let merchant_key = RsaPublicKey::from_pem(&merchant_pem)?;
// Configure checkout parameters
let params = CheckoutParams {
merchant_url: "https://merchant.example.com".to_string(),
consumer_id: "user-456".to_string(),
intent: "payment".to_string(),
payment_method: Some(PaymentMethod::Card(card)),
merchant_public_key: Some(merchant_key),
};
// Execute checkout with TAP authentication
let result = checkout_with_tap(&signer, params).await?;
println!("Transaction completed: {}", result.status);
Ok(())
}use tap_mcp_bridge::{
mcp::{browse_merchant, BrowseParams},
tap::TapSigner,
};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let signer = TapSigner::new(/* ... */);
let params = BrowseParams {
merchant_url: "https://merchant.example.com/catalog".to_string(),
consumer_id: "user-456".to_string(),
};
let result = browse_merchant(&signer, params).await?;
println!("Available products: {}", result.data);
Ok(())
}use tap_mcp_bridge::tap::{
TapSigner,
apc::{CardData, PaymentMethod, RsaPublicKey},
};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let signer = TapSigner::new(/* ... */);
// Create payment method
let card = CardData { /* ... */ };
let payment = PaymentMethod::Card(card);
// Load merchant's public key
let merchant_pem = std::fs::read("merchant_key.pem")?;
let merchant_key = RsaPublicKey::from_pem(&merchant_pem)?;
// Generate APC with JWE-encrypted payment data
let nonce = uuid::Uuid::new_v4().to_string();
let apc = signer.generate_apc(&nonce, &payment, &merchant_key)?;
println!("APC created with encrypted payment data");
println!("JWE format: {}", apc.encrypted_payment_data);
Ok(())
}The examples/ directory contains complete working examples:
- basic_checkout.rs - Simple checkout flow with error handling
- browse_catalog.rs - Browsing merchant catalogs
- apc_generation.rs - Payment container with JWE encryption
- signature_generation.rs - Low-level TAP signatures
Run examples:
cargo run --example basic_checkout
cargo run --example apc_generationGenerate and view the full API documentation:
cargo doc --no-deps --all-features --open- TAP Specification - Detailed TAP protocol implementation guide
- MCP Integration - MCP protocol and tool integration
- Main Library Docs - Architecture overview and integration guide
- Error Types - All error variants with recovery strategies
- Rust 1.75+ (Edition 2024)
- Cargo
- Optional:
cargo-make,cargo-nextest,cargo-deny
# Clone the repository
git clone https://github.com/bug-ops/tap-mcp-bridge.git
cd tap-mcp-bridge
# Install development tools (optional but recommended)
cargo install cargo-make cargo-nextest cargo-deny cargo-udepsInstall and configure sccache for dramatically faster incremental builds:
# Install sccache
cargo install sccache
# Configure Cargo (add to ~/.cargo/config.toml)
mkdir -p ~/.cargo
cat >> ~/.cargo/config.toml << 'EOF'
[build]
rustc-wrapper = "sccache"
incremental = true
[env]
SCCACHE_DIR = { value = "~/.cache/sccache", force = true }
SCCACHE_CACHE_SIZE = { value = "10G", force = true }
EOF
# Verify - rebuild is 10x faster!
cargo clean && cargo build --release # ~22s first time
cargo clean && cargo build --release # ~2-3s second time (cached)Using cargo-make (recommended):
# Quick pre-commit checks
cargo make pre-commit
# Full verification
cargo make verify
# Individual tasks
cargo make format # Format with nightly rustfmt
cargo make clippy # Strict lint checks
cargo make test # Run tests with nextest
cargo make doc-open # Build and open docsDirect cargo commands:
# Build
cargo build
# Test (155 tests)
cargo nextest run --all-features
cargo test --doc --all-features
# Code quality
cargo clippy --all-targets --all-features -- -D warnings
cargo +nightly fmt --all
# Security checks
cargo deny check
cargo +nightly udeps --all-targetsThis project follows the Microsoft Rust Guidelines for soundness and idiomatic design.
Key principles:
- No unsafe code - 100% safe Rust
- Strong types - Domain-specific types instead of primitives
- Comprehensive error handling - Context-rich errors with recovery guidance
- API Guidelines compliance - Following Rust API Guidelines
- Zero warnings - Strict clippy lints enforced
- PCI-DSS Compliant: Payment credentials encrypted with RFC 7516 JWE
- Encryption: A256GCM content encryption + RSA-OAEP-256 key encryption
- Defense-in-Depth: Application-level JWE + transport-level TLS
- Memory Safety: Automatic zeroization of card numbers, CVV, etc.
- No Plaintext: Payment data never logged or exposed in errors
- Signature Expiration: Requests expire after 8 minutes (TAP requirement)
- Replay Protection: Unique nonce (UUID v4) per request
- Timestamp Validation: Created/expires parameters enforce time windows
- HTTPS Only: All merchant URLs validated (no localhost)
- Input Validation: Consumer IDs, URLs, payment data sanitized
- Nonce Correlation: Same nonce across signature, ID token, ACRO, APC
- Private Keys: Ed25519 signing keys must be stored securely (HSM, KMS, encrypted vault)
- Public Keys: Distributed via HTTPS-only JWKS endpoint
- Key Rotation: Supported through JWKS updates
- Key Identification: JWK Thumbprint (RFC 7638) for each key
Test Coverage: 155 automated tests (100% passing)
- 104 unit and integration tests
- 51 documentation tests
- Signature generation and verification
- JWE encryption/decryption roundtrip
- ACRO and APC creation
- Nonce correlation validation
- Error handling and edge cases
Run tests:
# All tests
cargo nextest run --all-features
# Doc tests
cargo test --doc --all-features
# Specific module
cargo nextest run --all-features tap::apcContributions are welcome! Before contributing:
- Review the architecture in library documentation
- Check TAP Specification for protocol details
- Ensure all tests pass:
cargo nextest run - Run quality checks:
cargo make verify - Format code:
cargo +nightly fmt
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
- TAP Specification: Official Visa documentation
- Visa Reference Implementation: Python reference code
- TAP Implementation Guide: This project's TAP guide
- RFC 9421: HTTP Message Signatures
- RFC 7638: JWK Thumbprint
- RFC 7516: JSON Web Encryption (JWE)
- RFC 9530: Digest Fields
- RFC 8032: Ed25519 Signature Algorithm
- MCP Documentation: Anthropic's Model Context Protocol
- MCP Integration Guide: This project's MCP guide
- rmcp Crate: Rust MCP SDK
- Microsoft Rust Guidelines: Soundness and best practices
- Rust API Guidelines: API design patterns