@lerianstudio/matcher-mcp 6.0.0-beta.2 → 6.0.0-beta.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@lerianstudio/matcher-mcp",
3
- "version": "6.0.0-beta.2",
3
+ "version": "6.0.0-beta.20",
4
4
  "type": "module",
5
5
  "description": "Model Context Protocol server for the Matcher reconciliation engine",
6
- "license": "Apache-2.0",
6
+ "license": "LicenseRef-Lerian-Proprietary",
7
7
  "author": "Lerian Studio",
8
8
  "keywords": [
9
9
  "model-context-protocol",
@@ -24,10 +24,10 @@
24
24
  "files": [
25
25
  "dist"
26
26
  ],
27
- "packageManager": "pnpm@11.5.2",
27
+ "packageManager": "pnpm@11.28.6",
28
28
  "engines": {
29
29
  "node": ">=22",
30
- "pnpm": ">=11.5.2 <12"
30
+ "pnpm": ">=11.28.6 <12"
31
31
  },
32
32
  "bin": {
33
33
  "matcher-mcp": "./dist/server.js"
@@ -1,111 +0,0 @@
1
- // `workspace_usage` — curated GET /v1/workspace/billing, the ONE tenant-usage
2
- // surface, plus the single derived number the answer needs.
3
- //
4
- // "How much of my free tier is left?" is the question the copilot is expected to
5
- // answer (and to raise proactively), and until now it could only be reached by
6
- // the generic trio — which requires the model to already know the operationId
7
- // `workspace-billing`. Cost of curating it: one tool, no input, read-only.
8
- //
9
- // The backend is the authority on the verdict: `trialExpired` / `expiryReason` /
10
- // `daysRemaining` / `linesRemaining` are all derived by the TrialExpiry oracle
11
- // server-side and are relayed VERBATIM here — this tool never re-decides whether
12
- // a trial is over. It adds exactly one field, `usedPercent`, because that is
13
- // presentation (the shape of the answer), not enforcement.
14
- //
15
- // There is no input at all: the tenant comes from the relayed token's claims, so
16
- // there is nothing for a caller to pass — and nothing that could be spoofed.
17
- import { dispatchToolRequest } from '../shared-dispatch.js';
18
- /** The billing read path (tenant-scoped; tenant resolved from the token, not the path). */
19
- const WORKSPACE_BILLING_PATH = '/v1/workspace/billing';
20
- /**
21
- * Free-tier consumption as an already-scaled percent, rounded to one decimal, or
22
- * `null` when no honest percentage exists.
23
- *
24
- * Normally 0..100, but NOT clamped there: the matched-line counter is monotonic
25
- * and uncapped and the quota gate only refuses the next request, so a run already
26
- * in flight overshoots the cap. Clamping would hide the overshoot; the true
27
- * number is the honest answer, and the tool description says it can exceed 100.
28
- *
29
- * `null` off-trial is the point, not a fallback: the backend reads the
30
- * matched-line counter ONLY for a trialing workspace, so a converted/paid tenant
31
- * comes back with `matchedLines: 0` against a non-zero limit. Reporting that as
32
- * "0% consumed" would tell the model a paid plan has a full free allotment
33
- * waiting — it has no free-tier cap at all. Same for a non-positive limit or a
34
- * missing figure: no denominator, no percentage.
35
- */
36
- export function usedPercent(body) {
37
- if (body?.billingStatus !== 'trialing') {
38
- return null;
39
- }
40
- const { matchedLines, matchedLineLimit } = body;
41
- if (typeof matchedLines !== 'number' || typeof matchedLineLimit !== 'number') {
42
- return null;
43
- }
44
- if (!(matchedLineLimit > 0)) {
45
- return null;
46
- }
47
- // One decimal is all a spoken answer needs, and it keeps float noise
48
- // (82.00000000000001) out of the model's context.
49
- return Math.round((matchedLines / matchedLineLimit) * 1000) / 10;
50
- }
51
- /**
52
- * Register `workspace_usage`. Reads the caller's own commercial state through the
53
- * SHARED fail-closed relay — the additive percent rides its success-body
54
- * transform, so the credential refusal and the RFC 9457 mapping are the shared
55
- * ones rather than a local copy (that copy was BUG-06) — and returns the body
56
- * verbatim plus `usedPercent`. A matcher error
57
- * (404 for a tenant with no self-serve workspace, 403 MTCH-0021 for a
58
- * billing-suspended one) surfaces via the shared toToolError, so the model can
59
- * branch on `status`/`code` exactly as it does on every other tool.
60
- */
61
- export function registerWorkspaceUsageTool(server) {
62
- server.registerTool('workspace_usage', {
63
- description: "Report how much of the free tier is left for the caller's own " +
64
- 'workspace. Takes NO arguments — the workspace is resolved from your ' +
65
- 'relayed credential, so there is no tenant to pass. Returns the ' +
66
- 'commercial state as the backend derives it: plan; billingStatus ' +
67
- '(trialing, active, past_due, suspended); the TIME axis (trialEndsAt, ' +
68
- 'daysRemaining); the VOLUME axis (matchedLines consumed, ' +
69
- 'matchedLineLimit, linesRemaining); the unified verdict (trialExpired, ' +
70
- 'and expiryReason — "", "time", "volume", or "time_and_volume"); plus ' +
71
- 'usedPercent, the volume axis as a percentage — normally 0..100, but it ' +
72
- 'can exceed 100 when a match run already in flight walks past the cap ' +
73
- '(the counter is uncapped and the quota gate only refuses the NEXT ' +
74
- 'request), and it is reported unclamped so the overshoot stays visible. ' +
75
- 'usedPercent is ' +
76
- 'null when the workspace is NOT trialing: a paid plan has no free-tier ' +
77
- 'cap, so its zeroed volume figures mean "not measured", not "nothing ' +
78
- 'consumed" — say the plan has no free-tier limit rather than quoting ' +
79
- '0%. Never re-derive whether the trial is over; trialExpired and ' +
80
- 'expiryReason are the authority. Returns a structured RFC 9457 error on ' +
81
- 'failure (404 when the caller has no self-serve workspace, 403 ' +
82
- 'MTCH-0021 when billing has suspended it). Also returns the money in ' +
83
- 'both directions, in integer BRL cents: overageCreditBalanceCents ' +
84
- '(prepaid credit left) and overageUncoveredCents (overage already ' +
85
- 'incurred that the credit did not cover — what the workspace OWES). ' +
86
- 'The second is a receivable, not a negative balance: a new billing ' +
87
- 'period does not clear it, so never tell a customer a rollover settled ' +
88
- 'it, and never report it as a credit. ' +
89
- 'When a commercial ACTION on this workspace is refused, the refusal ' +
90
- 'carries a code from onboarding\'s own MTCH-08xx family and the code is ' +
91
- 'the answer, not the sentence: 0801 no payment processor is configured ' +
92
- '(retrying never clears it) vs 0802 the processor could not be asked ' +
93
- '(retry) — both arrive as a 503 whose detail is scrubbed to "internal ' +
94
- 'error"; 0803 a subscription the processor can still bill; 0804 only ' +
95
- 'the enterprise plan is operator-assigned; 0805 the billing status ' +
96
- 'forbids the change; 0806 the plan is set by contract, so nothing ' +
97
- 'self-serve applies; 0807 already subscribed; 0808 a checkout is open ' +
98
- 'for a different plan or interval; 0809 a checkout is being opened ' +
99
- 'right now; 0810 no billing account yet; 0811 a billing event id was ' +
100
- 'replayed with different content; 0812 the workspace exists and may be ' +
101
- 'the caller\'s own; 0813 the name belongs to another account; 0814 the ' +
102
- 'plan is not sold self-serve; 0815 the credit amount is out of range.',
103
- }, async (extra) => dispatchToolRequest({ method: 'GET', path: WORKSPACE_BILLING_PATH }, extra, undefined,
104
- // Spread, don't rebuild: the backend's fields are relayed unchanged and
105
- // the derived percent is purely additive.
106
- (billing) => ({
107
- ...billing,
108
- usedPercent: usedPercent(billing),
109
- })));
110
- }
111
- //# sourceMappingURL=usage.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"usage.js","sourceRoot":"","sources":["../../../src/tools/workspace/usage.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,4DAA4D;AAC5D,EAAE;AACF,iFAAiF;AACjF,+EAA+E;AAC/E,8EAA8E;AAC9E,2EAA2E;AAC3E,EAAE;AACF,iFAAiF;AACjF,+EAA+E;AAC/E,iFAAiF;AACjF,6EAA6E;AAC7E,2DAA2D;AAC3D,EAAE;AACF,iFAAiF;AACjF,6EAA6E;AAI7E,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAA;AAE3D,2FAA2F;AAC3F,MAAM,sBAAsB,GAAG,uBAAuB,CAAA;AAatD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,WAAW,CACzB,IAAsC;IAEtC,IAAI,IAAI,EAAE,aAAa,KAAK,UAAU,EAAE,CAAC;QACvC,OAAO,IAAI,CAAA;IACb,CAAC;IAED,MAAM,EAAE,YAAY,EAAE,gBAAgB,EAAE,GAAG,IAAI,CAAA;IAC/C,IAAI,OAAO,YAAY,KAAK,QAAQ,IAAI,OAAO,gBAAgB,KAAK,QAAQ,EAAE,CAAC;QAC7E,OAAO,IAAI,CAAA;IACb,CAAC;IAED,IAAI,CAAC,CAAC,gBAAgB,GAAG,CAAC,CAAC,EAAE,CAAC;QAC5B,OAAO,IAAI,CAAA;IACb,CAAC;IAED,qEAAqE;IACrE,kDAAkD;IAClD,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,YAAY,GAAG,gBAAgB,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;AAClE,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,0BAA0B,CAAC,MAAiB;IAC1D,MAAM,CAAC,YAAY,CACjB,iBAAiB,EACjB;QACE,WAAW,EACT,gEAAgE;YAChE,sEAAsE;YACtE,iEAAiE;YACjE,kEAAkE;YAClE,uEAAuE;YACvE,0DAA0D;YAC1D,wEAAwE;YACxE,uEAAuE;YACvE,yEAAyE;YACzE,uEAAuE;YACvE,oEAAoE;YACpE,yEAAyE;YACzE,iBAAiB;YACjB,wEAAwE;YACxE,sEAAsE;YACtE,sEAAsE;YACtE,kEAAkE;YAClE,yEAAyE;YACzE,gEAAgE;YAChE,sEAAsE;YACtE,mEAAmE;YACnE,mEAAmE;YACnE,qEAAqE;YACrE,oEAAoE;YACpE,wEAAwE;YACxE,uCAAuC;YACvC,qEAAqE;YACrE,yEAAyE;YACzE,wEAAwE;YACxE,sEAAsE;YACtE,uEAAuE;YACvE,sEAAsE;YACtE,oEAAoE;YACpE,mEAAmE;YACnE,uEAAuE;YACvE,oEAAoE;YACpE,sEAAsE;YACtE,wEAAwE;YACxE,wEAAwE;YACxE,sEAAsE;KACzE,EACD,KAAK,EAAE,KAAK,EAAE,EAAE,CACd,mBAAmB,CACjB,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,sBAAsB,EAAE,EAC/C,KAAK,EACL,SAAS;IACT,wEAAwE;IACxE,0CAA0C;IAC1C,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACZ,GAAI,OAA4C;QAChD,WAAW,EAAE,WAAW,CAAC,OAA2C,CAAC;KACtE,CAAC,CACH,CACJ,CAAA;AACH,CAAC"}