architecture
A metering engine built like a ledger
Corridor's engine is deliberately boring where it counts: double-entry accounting, serializable isolation, idempotency everywhere — and deliberately fast where it counts: policy and pricing decisions inside a hard authorize budget.
your product
API · MCP server · data feed — instrumented with the SDK or called directly
corridor engine
meter → price → policy → ledger · Go, Postgres, hot-path latency budget
rail adapters
one canonical event model; rail-specific data stays in adapter metadata
stripe connect · stripe mpp
full-stack money path · metering on the Stripe account you keep
A ledger you can audit, not a counter
Money state lives in a double-entry ledger written under serializable isolation, with an append-only, hash-chained audit log and idempotent writes. Every ledger invariant ships as both a runtime assertion and a property test.
Authorize before the work happens
Usage follows an authorize-then-capture lifecycle: policy and pricing run before your tool executes, at a hard latency budget (under 10ms added at authorize, p99) — guardrails at machine speed, not on the invoice.
Per-agent identity, first-class
Every metered event attributes to an agent identity — not an account, not an API key. Attribution, spend, and limits are per-agent from the schema up.
Rails are backends, not the product
The event model is rail-agnostic; adapters for Stripe Connect (full-stack) and Stripe's Machine Payments Protocol (metering-only) plug in behind the same interface. Rail-specific data never leaks into canonical types.
One wrap() away for MCP servers
The TypeScript SDK, @corridor/mcp, follows the official MCP SDK's conventions: a low-level client (authorize / capture / void) plus a one-line server wrapper.
import { CorridorClient, wrap } from "@corridor/mcp";
const corridor = new CorridorClient({ apiKey: process.env.CORRIDOR_API_KEY });
// One call instruments an MCP server: every tool invocation is
// authorized, metered, and priced per-agent before it runs.
wrap(server, corridor, {
currency: "USD",
pricing: {
tools: { search_corpus: { type: "flat", amount_cents: 100 } },
default: "deny",
},
agentIdentityResolver: resolveAgent,
});Stack, plainly: a Go engine on Postgres; a typed TypeScript SDK; a Next.js provider dashboard; structured logs, metrics, and traces on every engine decision. Specs first — every subsystem is written down before it is built, and the invariants in those specs run as tests.