feat(mcp): add list_fees and get_fee tools#51
Merged
Conversation
## Context Customers building custom revenue and MRR reporting (initial driver: Foxglove) need fee-level access through the AI assistant. Today the MCP exposes invoice-level operations but no way to drill into the fee breakdown — so MRR variants that include selected usage charges (e.g., seats, storage) alongside subscription fees are impossible to compute from agentic tooling. ## Description Adds two read-only MCP tools backed by Lago's `/fees` endpoint: - **list_fees**: list with optional filtering by fee_type, billable metric code, customer, subscription, currency, payment status, and created-at date range. The tool description specifically calls out the MRR use case so the LLM surfaces this tool for revenue questions. - **get_fee**: retrieve a single fee by its Lago ID. Implementation mirrors the existing `invoice.rs` pattern: schemars-derived args structs, a FeeService that maps args to a ListFeesRequest, and explicit `#[tool(description=...)]` registrations on LagoMcpServer.
## Context `lago-client 0.1.25` (with `list_fees` / `get_fee` methods) and `lago-types 0.1.23` (with the fee filter/request/response types) are now published on crates.io. Consuming them unlocks the MCP fee tools added in the previous commit. ## Description - `mcp/Cargo.toml`: `lago-client = "0.1.23"` → `"0.1.25"` - `mcp/Cargo.toml`: `lago-types = "0.1.21"` → `"0.1.23"` - `mcp/Cargo.lock`: regenerated; both deps resolve from the registry
sarkissianraffi
approved these changes
May 20, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds two read-only MCP tools that expose Lago's
/feesendpoint to AI agents:list_fees— list with rich filters (fee type, billable metric code, customer, subscription, currency, payment status, created-at date range, pagination)get_fee— single fee by Lago ID (UUID)This is the third PR in a chain. Depends on:
lago-types 0.1.23via refactor(billable_metric): Use lago-client for update_billable_metric #45)list_fees/get_feemethods (merged, published aslago-client 0.1.25)Code changes
mcp/src/tools/fee.rs(new)ListFeesArgs,GetFeeArgs,FeeServicewithbuild_request,list_fees,get_feehandlers. Mirrors the existinginvoice.rspattern.mcp/src/tools.rspub mod fee;mcp/src/server.rsFeeService, adds field toLagoMcpServer, instantiates innew(), registers two#[tool(description=...)]methods.mcp/Cargo.tomllago-clientto 0.1.25 andlago-typesto 0.1.23.README.md### Feessection under Available Tools.Tool descriptions (what the LLM reads)
The
#[tool(description=...)]strings shape when the model decides to call these tools:list_feesdescription explicitly mentions "MRR calculations" and "selected usage charges (e.g., seats, storage)". This is the surface that connects "What's our MRR including seats?" to alist_feescall withbillable_metric_code=seats.get_feeis a standard drill-down by Lago ID — used as a follow-up to alist_feesresult.Happy to adjust wording if there's a preferred phrasing.
What this PR does NOT do
list_feesandget_feeschemas into the Mistral agent. Tracked as operational followup.per_pagemax enforcement. The arg description says "max: 100" but the JSON Schema doesn't enforce it. Matches the existing pattern ininvoice.rsand every other paginated tool. Worth a separate cleanup PR.Test plan
Verified end-to-end locally against a real Lago account (4,521 fees in test data):
cargo build— cleancargo fmt --all -- --check— cleancargo clippy --all-targets -- -D warnings— cleancargo test— passes/healthrespondstools/listadvertises both new tools (55 total, up from 53)tools/call list_feeswithper_page=3returned 3 real fees with valid pagination metadatatools/call get_feewith a UUID from the list response returned the matching single feetools/call list_feeswithfee_type=subscriptioncorrectly filtered server-sideCommits