Plug 1 — your calls in
Install, point it at your deployment, and instrument one workflow. The key comes from /start, issued on the spot.
pip install margin-meter
export MARGIN_INGEST_URL="https://trymargin.io"
export MARGIN_INGEST_KEY="mgk_…"Then wrap the calls in the one workflow you are measuring. instrument_all monkeypatches the installed OpenAI, Anthropic and Gemini SDKs and hooks litellm, so a whole repo is a few lines:
from margin_meter import MarginMeter, instrument_all
meter = MarginMeter() # reads the two env vars above
instrument_all(meter, workflow_id="support-triage")A TypeScript SDK has the same shape (npm install margin-meter), but the npm package trails the repo: the eval adapters below are not in a plain npm install yet. /start sets you up on what is published.
Instrument one workflow, not everything. A workflow with no defined outcome floods the meter with calls that can never resolve to a cost-per-outcome, and the denominator is the whole measurement.
Plug 2 — your evals in
The outcome is the number everything else divides by, and only you can define it: a merged PR, a passed eval, a resolved ticket. If a harness already grades the workflow, an adapter reads the results file it writes anyway and records one outcome per graded case, pass or fail, with its grading stated.
We divide by the outcomes you define, so if your evals are generic, so is the denominator. The console shows what graded them, and flags a suite that passes or fails nearly every case, because that suite cannot rank two routes.
Adapters ship for promptfoo · Braintrust · LangSmith · Ragas · deepeval · Langfuse · pytest · vitest / jest.
A skipped or errored case is never counted as a verdict, and no adapter adds a harness of ours to your suite. If you have no eval harness, report it directly:
meter.record_outcome(workflow_id="support-triage", passed=True)MCP — let your agents query Margin
Margin runs an MCP server over JSON-RPC 2.0. Point any MCP client at it with your ingest key. The key resolves to that project’s own rows, so an agent sees your estate and nobody else’s.
POST https://trymargin.io/api/mcp
Authorization: Bearer mgk_…
Content-Type: application/json
{"jsonrpc":"2.0","id":1,"method":"tools/call",
"params":{"name":"margin_parity_prior",
"arguments":{"task_class":"extraction"}}}GET /api/mcp returns the server descriptor and every tool schema, so a client can discover the surface without credentials.
The one worth building against
margin_parity_prior answers a question an agent can act on before it spends: for this kind of work, how often has a cheaper model already held outcome parity? Margin stops being a page you read and becomes a thing your agents consult at runtime.
Let a coding agent do the integration
margin_instrument_plan returns the exact edits for your language and the command that verifies them, so Claude Code or Cursor can do install → instrument → verify without you writing any of it.
⛔ It does not scan your repository, and it says so. Margin’s server runs on Margin’s infrastructure and cannot see your code — a plan that implied otherwise would be a guess your agent would act on. The scan runs where the code is:
python -m margin_meter.doctor --jsondoctor is pure stdlib, makes no network call and never imports your modules. It lists every provider call site and whether the meter covers it, fail-closed: a gap it cannot prove covered is reported. It exists because of a real bill where 3 of 6 call sites were unmetered and carried all of the cache-write spend. In Python the plan is one edit at the entrypoint, because instrument_all is global; TypeScript instruments per client, so it touches every file that constructs one.
Read tools
margin_portfolio_summary | how many projects exist, how many emit real economics |
margin_portfolio_economics | cross-project spend, cost-per-outcome, savings at stake |
margin_fix_this_first | the ranked highest-$-impact opportunities across the estate |
margin_list_projects | every project and its connection state |
margin_project_economics | one project: spend, cost-per-outcome, token yield, retry tax |
margin_project_money_map | one project's workflows as spend-blocks, with the node-flow |
margin_project_recommendations | the recommendation feed, biggest-$-impact first |
margin_activity_log | measured calls, outcomes and closed-loop actions, in time order |
margin_parity_prior | for a task class: how often a cheaper model has held parity |
margin_lever_library | the catalogue of safe-gated optimisation levers |
margin_power_projection | the projected date to the parity confidence floor (88 all-passing trials, the Wilson 95% lower-bound sample size — not statistical power) at the current cadence |
margin_agent_margins | spend change split into agent headcount vs per-agent intensity |
margin_cost_per_outcome_decomposition | blended unit-cost change split into within vs between |
margin_baumol_assurance_trend | the rework share of unit cost, over time |
margin_roi_summary | the parity-gated ROI proof for the estate |
margin_flow_roi | one flow's before-bill, proven route, and counterfactual after-bill |
margin_instrument_plan | the exact edits to instrument a repo, and the command that verifies them |
margin_stage_plan | per-STEP model, effort, context, length and retry advice, at the bar your chain length demands |
margin_config_half_life | how fast a tuned config is going obsolete — the half-life of its outcomes-per-dollar |
Act tools, and why you cannot call them over HTTP
These three close the loop. They are fail-closed over HTTP — GET /api/mcp reports act_enabled: false — and are served only on the local stdio transport with an operator’s sign-off.
margin_approve_recommendation | pending → approved. Ratifies; enacts nothing. |
margin_apply_recommendation | adopt a proven route and re-measure before → after. |
margin_revert_recommendation | back an adopted route out. Requires a reason. |
⛔ Margin has no mechanism to change your routing. There is no endpoint that tells your code which model to run. We publish a decision, promote, hold or revert, and your code applies it or ignores it. The parity gate and the revert rule are ours; the switch is yours.
Start in staging. Three rungs, stop at any of them
| 1. Staging | A separate project and key, with environment=staging. Because source is forced server-side to the key’s project, a staging key cannot read or write production rows. Zero production exposure — production is not instrumented yet. |
| 2. Production, meter only | The same SDK with a production key. Still zero production effect — we only record what already happened. Staging traffic is not representative of a bill, so this is where the number becomes real. |
| 3. Act | Apply a published decision in your own code. Nothing moves until you do. |
What this does not do yet
An account starts empty. Signing up is an email: the sign-in link creates the account, and a key is issued on the spot. What it cannot do alone is say what an outcome IS. If you run evals, they are the definition. If you don’t, someone has to agree with you on one before a cost-per-outcome means anything.
No SOC 2, no ISO 27001. We are pre-revenue with no customers yet, and claiming a certification posture we do not have is the fastest way to deserve none of your trust.
No value is ever invented. value_usd is filled only by you. Supply nothing and every figure Margin computes is cost per outcome, labelled as one.
The full field list, every column and which ones are free text you choose, is on /security. Questions go to the founder: subh@trymargin.io.