JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 29
  • Score
    100M100P100Q82816F
  • License MIT

MCP server for MarginFront. Lets AI agents (Claude, Cursor, Copilot) record usage events, query revenue / cost / MRR analytics, manage customers + subscriptions + pricing plans, browse the supported-services catalog, generate and email invoices, and manage customer portal sessions via plain English. 31 tools covering the full billing surface.

Package Exports

  • @marginfront/mcp
  • @marginfront/mcp/dist/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@marginfront/mcp) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

@marginfront/mcp

npm version License: MIT Docs

Official Model Context Protocol server for MarginFront. Lets you ask Claude, ChatGPT, Gemini, or any other MCP-compatible AI client to operate on your MarginFront account in plain English. Look up customers, query revenue, run backfills, fix unrecognized models, and trigger admin actions without writing code.

Full Documentation · Tools Reference · LLM-friendly docs (for agents) · MarginFront Docs

What this is for

MCP is the operator interface for human-to-LLM ops on a MarginFront account. Use it when:

  • You want to ask an AI to backfill historical events from a CSV or SQL dump.
  • You're debugging in the dashboard and want to ask Claude to look up a specific customer's revenue or fix unrecognized models in bulk.
  • You're a non-developer customer-success or finance person who wants to query MarginFront without learning the API.

MCP is not how you instrument your product. For per-event tracking from your own production code, use the @marginfront/sdk package or call the REST API directly. SDK and API calls are typed, fast, and meant to run inline with your product logic. MCP runs through an LLM, which is great for ad-hoc work and terrible for per-request hot paths.

What you get

31 tools that any MCP-compatible AI client can call directly. Organized by purpose:

Connection

  • verify: confirm the API key works and see which organization it belongs to

Usage recording

  • record_usage / record_usage_batch: log what your customers are using (tokens, quantity, metadata)

Customer lookup

  • list_customers / get_customer / create_customer: manage your customer list

Invoices

  • list_invoices / get_invoice: read finalized bills and line items
  • generate_invoice: build a draft invoice from a subscription's actual usage events — line items + totals computed from the period's real activity, ready to preview/edit/send
  • send_invoice: email an invoice to the customer with a Stripe Checkout pay-now button (auto-finalizes drafts to "issued" as a side effect)

Events

  • list_events: browse recorded usage events with filters (pass customerExternalId to scope by your own customer ID)

Analytics (canonical)

  • get_usage_analytics: aggregated usage totals plus margin (pass customerExternalId to scope by your own customer ID)
  • get_customer_revenue: canonical revenue, cost, margin, and marginPercent for a single customer over a window
  • get_cost_metrics: canonical cost totals plus breakdown by agent, customer, signal, day, plan, and model
  • get_mrr: canonical MRR (canonical, run-rate, committed, or all three)

Subscriptions

  • list_subscriptions / create_subscription: track which customer is on which pricing plan

Customer portal

  • create_portal_session / get_portal_session / list_portal_sessions / revoke_portal_session: mint, inspect, list, and revoke single-use 1-hour portal links so customers can view their plan, invoices, and usage without exposing your API key

Pricing setup

  • create_pricing_plan / list_pricing_plans / get_pricing_plan: manage pricing plans
  • create_pricing_strategy / list_pricing_strategies: add pricing rules (usage, recurring, credit pool, etc.) to plans
  • link_plan_to_agent: connect a plan to an agent before subscribing customers

Data repair

  • get_needs_attention / map_model: find and resolve events with unrecognized models
  • get_missing_volume / fill_volume: find and resolve events with missing token or quantity counts

Catalog discovery

  • list_catalog_services: browse the global service_pricing catalog so the AI can look up canonical model + provider names before firing usage events (avoids the "guess and check until cost resolves" cycle)

The signal-naming rule for AI agents

When you use record_usage via this MCP server, the signal_name you pick becomes the line item your user's customer reads on their invoice. Pick it deliberately:

  1. Fire ONE call per business outcome. A 50-page report that just finished is ONE record_usage call with quantity: 50, not 50 calls with quantity: 1. Looping multiplies the bill.
  2. Match the signal name to how the user wants to bill. Before creating a signal on a user's behalf, ask them what unit goes on the invoice. "Per page" → signal_name: "pages". "Per report" → signal_name: "reports". "Per minute" → signal_name: "minutes".
  3. Don't invent internal-sounding names. Bad: llm_call, gpt-4o-call, api-requests. Good: messages, reports-generated, pages, sms-sent, minutes.
  4. quantity is the count of that billing unit for this one outcome. A 50-page report fired as pages has quantity: 50. Fired as reports, quantity: 1. Same underlying LLM call, different invoice.

Full mental model (including a three-way comparison of the same LLM call billed three different ways): Choosing your signal name and quantity.

Installation

The MCP server runs as a Node.js process over stdio. You don't npm install it into your app; you configure your MCP client (Claude Desktop, Claude Code, etc.) to spawn it.

Claude Desktop

Edit ~/Library/Application Support/Claude/claude_desktop_config.json on macOS (or the equivalent on Windows/Linux):

{
  "mcpServers": {
    "marginfront": {
      "command": "npx",
      "args": ["-y", "@marginfront/mcp"],
      "env": {
        "MF_API_SECRET_KEY": "mf_sk_your_secret_key_here"
      }
    }
  }
}

Restart Claude Desktop. The MarginFront tools appear automatically.

Claude Code

Add to your project's .mcp.json:

{
  "mcpServers": {
    "marginfront": {
      "command": "npx",
      "args": ["-y", "@marginfront/mcp"],
      "env": {
        "MF_API_SECRET_KEY": "${MF_API_SECRET_KEY}",
        "MF_API_BASE_URL": "${MF_API_BASE_URL:-https://api.marginfront.com/v1}"
      }
    }
  }
}

Full setup walkthroughs (including screenshots) are in the MCP setup docs.

Environment variables

Name Required? Purpose
MF_API_SECRET_KEY yes Your secret API key (mf_sk_*). Get one from the MarginFront Developer Zone.
MF_API_BASE_URL no Override the API endpoint. Defaults to https://api.marginfront.com/v1. Useful for testing against staging.

Example: backfilling historical events

The most common reason to fire events through MCP is a one-time backfill. You hand the AI a list of past activity, it records each event for you, and you can move on.

"I have 47 prospect reports my agent generated last week that never got recorded. Each one used Claude Opus with around 4000 input tokens and 1500 output tokens. The customer was acme-001, the agent was outreach-agent, the signal is prospect_reports, and quantity is 1 per report. Record them all."

The assistant calls record_usage_batch and returns a confirmation:

Processed 47 event(s): 47 succeeded, 0 failed.

If any model isn't in the pricing catalog yet, those events are still saved with cost: null and flagged NEEDS_COST_BACKFILL. The assistant can then call map_model to fix it, and every flagged past event with that model gets a real cost retroactively.

For per-event tracking from your production code, use the SDK instead. MCP fires events through an LLM, which is fine for ad-hoc batches and terrible for the hot path.

Example: AI agent recording multi-service usage

When one outcome uses several services (e.g. a cold-outreach report that searches the web, calls an LLM, and sends an email), MCP records it as ONE event with a services array. The customer is billed per signal; MarginFront tracks per-service cost under the hood. Same backfill pattern as above:

"Record one prospect report for acme-001 on outreach-agent, signal prospect_reports, quantity 1. The services were 12 Exa search calls, Claude Opus 4 with 4200 input plus 1800 output tokens, and 3 SendGrid emails."

The assistant calls record_usage with the multi-service shape and gets one confirmation:

Processed 1 event(s): 1 succeeded, 0 failed.

Successful:
  - acme-001 / prospect_reports: $0.142 across 3 services (event: 5de8fbf1-...)

Per-service cost lines live under the parent event for margin reporting. The customer's invoice shows one line: prospect_reports x 1.

Example: asking about revenue and cost

The canonical analytics tools answer business questions in plain English:

"What revenue did we get from customer acme-001 in April?"

Calls get_customer_revenue (after resolving the UUID via list_customers) and returns { revenue, cost, margin, marginPercent } plus a per-strategy-type breakdown.

"What did we spend on model providers this month?"

Calls get_cost_metrics and returns total cost plus breakdowns by agent, customer, signal, day, plan, and model.

"What's our MRR right now?"

Calls get_mrr (defaults to MRR1, last complete calendar month). Ask for "all three" to get MRR1 (actually billed), MRR2 (run-rate trajectory), and MRR3 (contractual floor) in one response.

How it relates to the SDK

  • Use @marginfront/sdk to instrument your product. Every time your agent does work for a customer, your code fires a typed function call (client.usage.record({ ... })). This is the integration path.
  • Use @marginfront/mcp for human-to-LLM ops on the MarginFront account: backfills, batch fixes, queries, admin actions. This is the operator path.

Both wrap the same REST API. They are not interchangeable: the SDK is built for production hot paths, MCP runs through an LLM and is built for conversational use. Pick the one that matches the job.

Troubleshooting

"Missing MF_API_SECRET_KEY environment variable" Your MCP client didn't pass the env var. Check the env block in your MCP config.

"Authentication failed. The API key is invalid or missing" The key was passed but rejected. Verify the key in the Developer Zone and confirm you're using a mf_sk_* secret key (not a mf_pk_* publishable key).

"Could not reach the MarginFront API" Your host is blocking the outbound connection to api.marginfront.com. If you're running a local API for development, set MF_API_BASE_URL=http://localhost:4000/v1.

Source & issues

This package is developed in the Lowcountry-AI/platform monorepo under packages/mcp/.

Report bugs or request features on the issues page.

License

MIT