Skip to main content
Glama
i2mint

Enlace Metering MCP

by i2mint

enlace_metering

Usage tracking and credit/quota access-gating for enlace MCP connectors — the platform's "usage & access-policy" layer, sibling to enlace_auth (identity) and enlace_connector (deploy).

Whether a principal may use a resource is a strategy (a pure function), and recording what they spent is a separate concern from deciding whether to let them. That separation is the core design principle (see Research below).

import enlace_metering as em

# 1. record (the meter) — a durable ledger over any MutableMapping (dict here; a
#    dol file store in prod, growing to s3dol/sqldol untouched).
ledger = em.UsageLedger(store={})

# 2. gate (the strategy) — parameterized credit formulas, composable.
policy = em.per_principal(
    {"owner@example.com": em.unlimited()},          # owner: no cap
    default=em.require_all(                          # everyone else:
        em.per_call_cap(2.00),                       #   ≤ $2 per call, AND
        em.credit_cap(20.00, period="month"),        #   ≤ $20 / calendar month
    ),
)

# 3. enforce (the glue) — one FastMCP middleware over EVERY tool call, fail-closed.
#    (needs `pip install enlace_metering[mcp]`)
from enlace_metering import MeteringMiddleware
mw = MeteringMiddleware(ledger, policy=policy, allowed={"owner@example.com"})
# app = py2mcp.http.mk_http_app(refs, auth=AUTH, middleware=[mw], stateless_http=True)

Why (the three concerns)

Concern

Where

Shape

Enforce — may this call proceed?

policy

pure GatePolicy = (GateRequest) -> Decision

Record — what did it cost?

ledger

UsageLedger over a MutableMapping

Glue — identity + gate + write-ahead

middleware ([mcp])

a FastMCP Middleware

The gate runs before the ledger sees the event — enforcement is a distinct layer from billing. The core (policy + ledger) is dependency-free and unit-testable against a dict; only the middleware needs fastmcp.

Policies (the strategy library)

All are constructors returning a GatePolicy; compose with require_all / per_principal.

  • unlimited() — always allow (record only).

  • credit_cap(usd_per_period, period="month") — prepaid/metered cap per calendar period (resets on the boundary).

  • rolling_window_cap(usd, window=timedelta(days=1)) — sliding-window cap (rate control).

  • per_call_cap(usd) — reject a single call whose estimated cost exceeds usd.

  • call_count_cap(n, period="day") — count-based quota (no cost model needed).

  • balance_gate(get_balance) — true prepaid credits: deny when a host-managed balance can't cover the call.

  • per_principal({email: policy}, default=…) — tiered plans (owner unlimited, others capped).

  • require_all(*policies) — AND / most-restrictive (first denial wins).

Forward-looking gating (deny a call that would cross a cap) needs a proposed-cost estimate — pass estimate_cost=(tool, args) -> usd|None to the middleware. Without one, caps block on already-accumulated usage ("you've hit your limit").

Ledger layout

Keyed {principal}/{YYYY-MM}/{id}.json so "what did X spend this month" is a cheap subtree scan. The middleware writes write-ahead (starteddone/error under one id): a costed call never spends on a shared key without a recoverable trace. The store is injected, so it grows from a local dol.Files to s3dol/sqldol without touching callers.

Install

pip install enlace_metering           # core: policy + ledger (no deps)
pip install 'enlace_metering[mcp]'    # + the FastMCP middleware

Research — how usage-based metering / quotas are built

The design follows the settled industry pattern: entitlement/quota enforcement is a separate layer from the billing meter — enforcement decides before usage is recorded [1][2]. Common formulas this package parameterizes:

  • Prepaid credits / credit blocks — buy a bundle, burn down; blocks carry their own amount + expiry with priority burn-down [3][4]. → credit_cap, balance_gate.

  • Metered caps + real-time balance / grace — per-feature quotas with live balance tracking [1][5]. → credit_cap, call_count_cap.

  • Token-bucket rate limiting — tokens replenish at a rate; a request costs N; deny if insufficient [2]. → rolling_window_cap (the sliding-window cousin).

Keeping the decision a pure strategy (not baked into the middleware) is what lets a host swap "owner unlimited" for "prepaid credits" or "monthly cap" without touching the connector — the open-closed shape the enlace family favors.

References

  1. Lago. How to architect billing systems to power usage-based pricing. getlago.com/blog/architect-billing-systems

  2. OpenMeter. Metering and billing for AI, API and DevOps. github.com/openmeterio/openmeter

  3. Kong. Stop AI token overspend: prepaid credits in Konnect. konghq.com/blog/product-releases/metering-billing-prepaid-credits

  4. Solvimon. AI billing software built for tokens, credits, and inference pricing. solvimon.com/blog/6-ai-billing-software-platforms-built-for-credits

  5. Zuora. Metered billing: architecture, metrics, and monetization models. zuora.com/glossary/metered-billing

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/i2mint/enlace_metering'

If you have feedback or need assistance with the MCP directory API, please join our Discord server