Canonical Swift SDK for the Machine Payments Protocol (MPP) — pay for and charge for machine-to-machine API calls over HTTP 402.
mpp-swift is an early-stage Swift project in the AI payments / x402 ecosystem, focused on agentic-payments, http-402, machine-payments-protocol, mpp. It currently has 7 GitHub stars and 1 forks, and sits alongside related tools like routeweiler-python-sdk, pay-kit, mpp-sdk, awesome-mpp, inflow-cli, mcp-pay.
The Swift SDK for the Machine Payments Protocol (MPP): pay for, and charge for, machine-to-machine API calls over HTTP 402.
MPP standardizes machine-to-machine payments using a challenge → credential → receipt flow: a server answers 402 Payment Required with a WWW-Authenticate: Payment challenge, the client replies with an Authorization: Payment credential, and the server returns the resource plus a Payment-Receipt. It works over HTTP, JSON-RPC/MCP, and WebSocket, with pluggable payment rails (Tempo, Stripe, and more).
This is the canonical Swift implementation of the protocol. The client and server are independent: a Swift client can pay any MPP server in any language, and a Swift server can charge any client.
An auto-generated code wiki is browsable at DeepWiki for a quick tour of the codebase. The official badge above keeps it auto-refreshed weekly, but it can still lag the newest modules; this README and ARCHITECTURE.md are the authoritative, current references.
Status: broad and feature-complete, released at 1.0.0, built one module at a time with a strict quality bar (spec-traced tests, cross-SDK conformance vs the reference SDKs, no flaky tests). The protocol core, body-digest, server middleware, the 402 client flow, and the EVM message-signing layer (Keccak-256, secp256k1, EIP-712 proof + session voucher) are implemented. The Tempo rail is well advanced: the zero-amount proof charge, the session-channel server (open/topUp/voucher/close), the blob-free on-chain layer (a JSON-RPC client, the escrow
getChannelread, and an RPC-backed channel-state provider), and the bespoke0x76transaction builder (open/topUp/close, an opt-in Rust FFI to Tempo's owntempo-primitives, linking on macOS/iOS/Linux) are all in. The full write path is proven on-chain: a gated end-to-end test opens and closes a real payment channel against the live Moderato testnet. The 402 channel-payment client (TempoChannelMethod: open/voucher/topUp/close, an injected deposit policy, on-chain channel recovery, and a separate access-key signer) is in, and the whole channel rail is cross-SDK conformance-proven against the reference SDK in both directions, live on Moderato (open → voucher → close, settled on-chain). Discovery (parse + generate + validate), the 402-protected reverse proxy (MPPProxy, with a live Hummingbird bindingMPPHummingbird), and the JSON-RPC / MCP binding (MPPMCP, cross-SDK conformance-proven both directions over stdio) are in. The subscription rail is in, end to end: a signed Tempo key authorization (TempoKeyAuthorization, RLP, byte-verified against the chain's own codec), the client (TempoSubscriptionMethod) and server (TempoSubscriptionVerifier, which re-encodes the expected authorization and compares so it never trusts the client decode), aSubscriptionStorewith a two-phase atomic renewal engine, and a concrete on-chain renewer (TempoSubscriptionRenewerover anAccessKeyStore+ the0x76charge builder) that settles the recurringtransferWithMemolive, with fee-payer gas sponsorship so the charge fits the access key's spending limit. It is cross-SDK conformance-proven against the reference SDK in both directions (activation offline, and a recurring charge settled live on Moderato). Metered streaming is in too: a pay-as-you-goSessionStreamthat meters chunks against a channel over both Server-Sent Events and WebSocket frames, with cross-SDK codec parity for both, plus a live WebSocket transport (MPPWebSocketorchestration +MPPWebSocketLiveswift-websocket adapters, server and client) that drives a metered session over a real socket. The Stripe rail is in (MPPStripeclient +MPPStripeServer: a Shared Payment Token charge into a PaymentIntent, full Connect parity, live-verified against a real test-mode charge), and so is the x402-on-Base rail (MPPX402/MPPX402Server: an EIP-3009transferWithAuthorizationover USDC on Base, a version-negotiated bridge between MPP and x402 for v1 and v2, and an x402-facilitator settler). A server can also render a self-contained HTML payment page (MPPHTML/MPPHTMLServer: multi-method tabs + a service worker, content-negotiated by the middleware) for a human-facing 402. Server hardening is in -- single-use replay, idempotency (409), rate limiting (429), sensitive-surface redaction, and opt-in CORS/HEAD -- alongside receipt persistence (theReceiptStoreseam), an atomic running-budgetPaymentAuthorizer(BudgetAuthorizer), anmpp.dev/servicesdirectory client (ServiceDirectory), and a SwiftNIOAsyncHTTPClienttransport (MPPClientAsyncHTTP) for long-lived server / Linux processes. And a shippedmppcommand-line tool (paya 402 URL curl-style, plussign/discover/account/services/init) rides a vendor-neutralPaymentAuthorizerapproval seam (MPPAuth: per-request Touch ID, a TTY prompt, or headless auto with a spending cap). The original 1.0 gate -- server hardening, the HTML page, and conformance-vector completeness -- is now closed, and the package is released at 1.0.0. See what's covered and the module table below.
MPP composes along three axes: the transport the 402 flow rides, the rail that moves value, and the side you are (payer/client vs payee/server). Client and server are independent products, so a Swift client can pay any-language server and a Swift server can charge any client. Here is the surface:
Transports (the wire the challenge / credential / receipt flow rides):
MPPServer middleware + MPPClient (over URLSessionTransport); a live server binding (MPPHummingbird) and a 402-protected reverse proxy (MPPProxy).MPPMCP gates a tools/call and pays it transparently; conformance-proven both directions over stdio.MPPWebSocket (transport-agnostic session orchestration, server + client) + MPPWebSocketLive (live swift-websocket adapters), plus the Server-Sent Events codec.MPPHTML / MPPHTMLServer: a self-contained, themeable HTML 402 page (multi-method tabs + a service worker) that MPPServerMiddleware content-negotiates for a human-facing payer, alongside the machine problem+json.Rails (how value actually settles):
MPPTempo / MPPTempoServer: a zero-amount proof-of-wallet-control charge; a full payment-channel session (open / voucher / topUp / close, settled on-chain); a subscription rail (a signed key authorization, a two-phase atomic renewal engine, and a concrete on-chain renewer with fee-payer gas sponsorship); and metered streaming over the channel. The 0x76 channel / charge transactions are built by a pinned Rust FFI (MPPTempoFFI), so only a wallet links it.MPPStripe / MPPStripeServer: a Shared Payment Token charge into a PaymentIntent, full Stripe Connect parity, live-verified.MPPX402 / MPPX402Server: the Coinbase x402 exact scheme (an EIP-3009 transferWithAuthorization over USDC on Base), plus a version-negotiated bridge between MPP and x402 (v1 + v2) and an x402-facilitator settler, so the SDK interoperates with the real x402 ecosystem in both directions.Client building blocks:
PaymentAuthorizer - the vendor-neutral consent/budget seam consulted once at the credential-build chokepoint: AllowAllAuthorizer, SpendingCapAuthorizer, and BudgetAuthorizer (an atomic running-budget check-and-debit, TOCTOU-safe -- the spending-cap / margin enforcer for a long-lived broker).ReceiptStore - a persistence seam the client records each Payment-Receipt to after settle (auditing, never a gate).MPPClientAsyncHTTP - a SwiftNIO AsyncHTTPClient transport, the Linux/server counterpart to URLSessionTransport for a long-lived gateway or broker process.Server hardening: single-use ReplayStore, IdempotencyStore (safe-retry, 409), RateLimiter (429), sensitive-surface redaction, and an opt-in CORS/HEAD policy on the discovery surfaces -- all in MPPServer / MPPProxy.
Tooling:
mpp - a shipped command-line tool: pay a 402 URL (curl-like), sign a challenge, discover / validate, account (macOS Keychain), services, init. Approval rides a vendor-neutral PaymentAuthorizer seam (MPPAuth): per-request Touch ID, a TTY prompt, or headless auto with a spending cap.MPPDiscovery - OpenAPI x-payment-info discovery (parse, generate, validate) plus a ServiceDirectory client that reads the mpp.dev/services directory.Cross-SDK conformance: every rail and transport with a reference peer is proven against the reference TypeScript SDK (mppx) in both directions (our client against their server, and their client against our server), offline in CI and, for the on-chain Tempo paths, live on the Moderato testnet. See CONFORMANCE.md.
Swift Package Manager:
.package(url: "https://github.com/amitach/mpp-swift", from: "1.0.0")
Then depend on the products you need (you pull only those):
.product(name: "MPPCore", package: "mpp-swift"),
A consumer that builds Tempo channel transactions (a wallet) additionally depends on
MPPTempoFFI; on Apple this downloads the checksum-pinned tempo-tx-ffi xcframework (no
Rust toolchain). Every other product links zero Rust.
| Product | Status | Purpose |
|---|---|---|
MPPCore |
available | Protocol primitives: Challenge, Credential, JCS, Amount, ProblemDetails, RouteBinding, multi-challenge parsing |
MPPBodyDigest |
available | RFC 9530 Content-Digest (SHA-256) |
MPPServer |
available | Framework-agnostic middleware over swift-http-types: challenge mint, replay, verify pipeline, plus the hardening seams -- IdempotencyStore (safe-retry, 409), RateLimiter (429), FileReplayStore, sensitive-surface redaction, and a pluggable HTML payment-page presenter (content-negotiated against problem+json) |
MPPClient |
available | The 402 client flow (send → parse → select → build → retry) over URLSessionTransport (with redirect-downgrade protection), recording each Payment-Receipt to a ReceiptStore seam after settle; plus the vendor-neutral PaymentAuthorizer consent seam (the protocol + AllowAllAuthorizer + SpendingCapAuthorizer + the atomic running-budget BudgetAuthorizer) consulted once at the credential-build chokepoint, shared by the HTTP and MCP clients |
MPPClientAsyncHTTP |
available | An MPPHTTPTransport over swift-server/async-http-client (SwiftNIO): the Linux/server-native counterpart to URLSessionTransport for a long-lived broker or gateway, with connection pooling and redirects disallowed (credential-leak parity with URLSession). The same 402 flow runs over it unchanged |
MPPAuth |
available | The interactive/headless payment-approval implementations + the macOS key store, used by the mpp CLI: TTYPaymentAuthorizer (y/n prompt) and BiometricPaymentAuthorizer (LocalAuthentication Touch ID), the displaySafe terminal sanitizer for server-controlled strings, and KeychainAccountStore (biometric-gated secp256k1 key items) |
MPPEVM |
available | EVM message-signing + JSON-RPC: Keccak-256, secp256k1 recoverable signer, EIP-712 zero-amount proof + did:pkh source, session voucher, channel id, 0x-hex codec; plus TempoKeyAuthorization (the subscription key authorization) and a strict-canonical pure-Swift RLP codec, byte-verified against the chain's own tempo-primitives codec |
MPPTempo |
available | Tempo rail: zero-amount proof charge; the 402 channel-payment client TempoChannelMethod (auto open + accumulating vouchers, client-initiated topUp/close, an injected deposit policy, on-chain channel recovery, optional access-key signer) behind the TempoOpenTxBuilder / TempoTopUpTxBuilder / TempoCloseTxBuilder seams; the EVMRPC JSON-RPC client; the escrow getChannel read (TempoEscrow → OnChainChannel); ChannelAmount. The 0x76 builders are the rust/tempo-tx-ffi FFI (below); the TempoChannelSession actor (in MPPTempoFFI) is the direct-wallet lifecycle. Also the subscription client TempoSubscriptionMethod (decodes the tempo/subscription 402, signs the TempoKeyAuthorization delegating the server-issued access key to the recurring transferWithMemo) and SubscriptionRequest. The 0x76 subscription-charge builder (and its optional fee-payer gas sponsor) lives in MPPTempoFFI. Cross-SDK conformance-proven both directions, live |
MPPTempoServer |
available | Tempo SERVER side: zero-amount proof verify, the 4-action SessionMethod (open/topUp/voucher/close), ChannelStore, and RPCChannelStateProvider (reads + relays signed txs + settle via the seam). A session reuses one challenge across its lifecycle, so the verifier honours PaymentMethodServer.reusesChallenge (the channel-store cumulative is the anti-replay). Plus the subscription server TempoSubscriptionVerifier (re-encode-and-compare: rebuilds the expected key authorization from its own challenge and requires byte-equality, never trusting the client decode), the SubscriptionStore + two-phase atomic renewal SubscriptionEngine (claim → charge via an injected SubscriptionRenewer seam → commit, with timeout takeover and supersession), the concrete on-chain renewer TempoSubscriptionRenewer (settles the recurring transferWithMemo via the 0x76 charge builder, signed by the server-held access key from the AccessKeyStore as a Tempo V2 keychain signature, with an idempotency Attribution memo and optional fee-payer gas sponsorship; the first charge attaches the key authorization to provision the access key on-chain), and metered streaming: SessionStream (pay-as-you-go: each chunk draws one tick, emits payment-need-voucher when short, then the terminal receipt) with the SSE codec SessionStreamEvent and the WebSocket frame codec SessionWebSocketFrame |
MPPTempoFFI |
available (opt-in) | The Rust 0x76 transaction builders over an FFI boundary: FFITempoTxBuilder (channel open/topUp/close) and FFISubscriptionChargeTxBuilder (the recurring transferWithMemo, with an optional fee-payer gas sponsor), plus the TempoChannelSession direct-wallet lifecycle actor. Only a transaction-building consumer (a wallet) links it; on Apple a checksum-pinned tempo-tx-ffi xcframework (no Rust toolchain), Linux builds from source. See below |
MPPDiscovery |
available | OpenAPI x-payment-info discovery: parse, generate an OpenAPI 3.1 document from routes (auto-declaring the required 402), and structural + semantic validate (a payable op MUST have a 402, SHOULD have a requestBody); served at /openapi.json. Also a ServiceDirectory client that decodes the mpp.dev/services registry into rail-agnostic entries (a malformed entry URL never fails decoding of the whole directory) |
MPPMCP |
available | JSON-RPC / Model Context Protocol payment binding (over the official MCP Swift SDK): a server gate (tools/call → 402 challenge / verify / receipt) and a client wrapper that pays transparently. Cross-SDK conformance-proven both directions over stdio. Requires Swift 6.2 (the MCP SDK's transitive graph) |
MPPProxy |
available | Framework-neutral 402-protected reverse proxy: routes /{service}/... to upstream origins, gates each route with MPPServerMiddleware, scrubs credential/cookie/hop-by-hop headers in both directions, injects upstream auth, and serves /openapi.json + /llms.txt (with an opt-in CORSPolicy + HEAD on those discovery surfaces only, never on proxied routes). Pure request/response logic over swift-http-types; no server dependency |
MPPHummingbird |
available | The live HTTP-server binding for MPPProxy (and single gated routes), over Hummingbird 2. The only product that links swift-nio; requires macOS 14 / iOS 17 |
MPPStripe |
available | Stripe rail CLIENT: presents a Shared Payment Token in the credential (no Stripe secret, no crypto) |
MPPStripeServer |
available | Stripe rail SERVER: StripeChargeVerifier mints a PaymentIntent from the SPT via StripePaymentIntentClient (Basic auth, hashed Idempotency-Key, no secret leak), maps status → receipt/reject; full Stripe Connect parity. Live-verified against a real test-mode PaymentIntent |
MPPX402 |
available | x402-on-Base rail CLIENT: the Coinbase x402 exact scheme over an EIP-3009 transferWithAuthorization (USDC on Base), the X402ChargeMethod payer, and a version-negotiated bridge between MPP and x402 (v1 + v2 wire: headers, PaymentRequirements, PaymentPayload). The signing digest is anchored to the canonical EIP-3009 type hash and the on-chain USDC-Base domain separator |
MPPX402Server |
available | x402-on-Base rail SERVER: X402ChargeVerifier recovers + validates the EIP-3009 authorization against the challenge (.rejectHighS, single-use replay), then settles via an X402Settlement seam -- a concrete FacilitatorSettlement posts to an x402 facilitator's /verify + /settle (TLS-guarded, fail-closed parsing) |
MPPHTML |
available | Renders a self-contained, themeable HTML payment page from a Challenge: per-method form fragments + an embedded config object, multi-method tabs, a sanitized/preflighted style. A human-facing alternative to problem+json |
MPPHTMLServer |
available | Wires MPPHTML into MPPServerMiddleware via a PaymentPagePresenter (content-negotiates HTML vs problem+json), plus the client script and a registerable service worker (MPPHTMLServiceWorker) that re-attaches the credential on the paid retry |
MPPWebSocket |
available | Metered-session WebSocket transport, transport-agnostic: SessionWebSocketServer (drives SessionStream over a socket; actor-serialized) + SessionWebSocketClient (consumes it, auto-answers payment-need-voucher with a fresh voucher), over the {mpp:...} SessionWebSocketFrame codec. No external deps |
MPPWebSocketLive |
available | The live socket adapters for MPPWebSocket, on hummingbird's swift-websocket (WSCore inbound/outbound + WSClient); bridges a real WebSocket into the orchestration and confines the nio WebSocket graph to this target |
mpp (executable) |
available | The shipped command-line tool: pay a 402 URL (curl-like), sign a challenge, discover generate/validate, account (macOS Keychain), services, init. swift-argument-parser; curl-like exit codes; approval via the MPPAuth seam |
The bespoke Tempo 0x76 transaction (channel open/topUp/close) is the one piece we deliberately do not build in Swift. Swift could encode it, but the format is Tempo-specific and evolving, so binding Tempo's own tempo-primitives (the chain's canonical implementation) gives byte-for-byte parity and turns an upgrade into a version bump, instead of a drift-prone Swift port we would have to chase by hand. It is produced by rust/tempo-tx-ffi and exposed to Swift over an FFI boundary. It is only needed by a consumer that builds Tempo channel transactions (a wallet): a non-Tempo consumer, or a Tempo server that only verifies and reads, should link none of it. It builds the three channel-bookend transactions (open / topUp / close) and the recurring subscription charge (a transferWithMemo, signed by an access key as a Tempo V2 keychain signature, with an optional fee-payer gas sponsor), and is wired into the Swift package behind the dedicated opt-in MPPTempoFFI product (the FFITempoTxBuilder and FFISubscriptionChargeTxBuilder), so only a transaction-building consumer pulls the binary and the default graph links zero Rust (see ARCHITECTURE.md). It links on macOS (universal), iOS (device + simulator), and Linux. It is a build input that ships in the artifact (unlike the dev-only npm test tooling); its dependency tree is pinned (Cargo.lock), built in CI on macOS and Linux, byte-golden-tested, and cargo audit-scanned. Its output is proven on-chain: a gated live Moderato e2e opens and closes a real channel through it. It is published as a checksummed GitHub-release xcframework (.github/workflows/release-ffi.yml, tag tempo-tx-ffi-v*), so an external Apple consumer installs it with no env var and no Rust toolchain. The from-source MPP_TEMPO_FFI path remains for dev/CI, and a Linux consumer always builds from source (SwiftPM has no Linux library binary artifact). See SECURITY.md.
Prerequisites: a Swift 6.2 toolchain (Xcode 26+ on macOS, or the Swift 6.2 toolchain on Linux). The 6.2 floor comes from MPPMCP's dependency on the official MCP Swift SDK, whose transitive graph (swift-log 1.13) requires tools 6.2. The Rust FFI crate additionally needs a Rust toolchain >= 1.93 (rustup update stable), but only if you build that crate - the Swift package builds and tests with no Rust.
git clone https://github.com/amitach/mpp-swift && cd mpp-swift
swift build # builds all products
swift test # runs the full suite (hermetic; no network)
Both must pass on macOS and Linux. Lint matches CI:
swiftformat --lint . # formatting
swiftlint --strict # style; zero warnings
Cross-SDK conformance (exercises the wire format against the reference TypeScript SDK; needs Node):
Scripts/conformance/run.sh # offline, vs a local mppx server
Scripts/conformance/run.sh --testnet # against the live Moderato node
Live-chain tests (read path against the real Moderato testnet) are gated so the default suite stays hermetic; opt in with an env var:
MPP_MODERATO_E2E=1 swift test --filter Moderato
The Rust FFI crate (the 0x76 transaction builder) is separate from the Swift package:
cd rust/tempo-tx-ffi
cargo test # builds the crate (clones tempo + compiles the tree) and runs the byte-golden test
cargo audit # scans the Rust dependency tree against the RustSec advisory DB
CI runs all of the above; the Swift Tests jobs and the Rust FFI job both run on macOS and Linux. See the architecture overview for how the pieces fit and SECURITY.md for the supply-chain posture.
swift-* package norms.Dual-licensed under either of Apache License 2.0 or MIT license at your option.
This product includes software developed by Marcin Krzyzanowski (https://krzyzanowskim.com/), the CryptoSwift library, used for Keccak-256.
Security policy: see SECURITY.md. Contributing: see CONTRIBUTING.md.
The financial operating system for AI agents. A single HTTP client that intercepts '402 Payment Required', routes across x402, L402, and MPP, persists credentials as recoverable assets, enforces per-envelope budgets, and emits a structured trace.
Building blocks for Agentic payments (x402, MPP, AP2) for TypeScript, Rust, Go, Python, Ruby, PHP, Lua, Kotlin and Swift.
Building blocks for Agentic payments (x402, MPP, AP2) for TypeScript, Rust, Go, Python, Ruby, PHP, Lua, Kotlin and Swift.
The MPP registry — 100+ Machine Payments Protocol tools, SDKs, services, and payment methods across 15+ chains. The definitive directory for Stripe + Tempo agent payments.
A wallet for your agents to onboard and pay. Agentic MPP / x402 payments from your machine - CLI + MCP server.
Payment awareness layer for MCP (Model Context Protocol)
TypeScript Interface for Machine Payments Protocol
Alephant is an open-source AI Agent Gateway for routing, tracking, and controlling LLM usage across AI agents, members, and workflows, and for publishing agent capabilities as paid endpoints with x402 and MPP payment rails.
Specifications for the Machine Payments Protocol - powered by the "Payment" HTTP authentication scheme
Rust SDK for the Machine Payments Protocol
Website for the Machine Payments Protocol
A universal framework designed to allow agents and other utilities to transparently make machine payments using web infrastructure.