@agentistics/mcp 2.101.1 → 2.102.0

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.
@@ -1,5 +1,41 @@
1
1
  #!/usr/bin/env node
2
2
 
3
+ // orphan-guard.ts
4
+ function installOrphanGuard(d) {
5
+ const initial = d.getPpid();
6
+ let done = false;
7
+ const bye = () => {
8
+ if (done)
9
+ return;
10
+ done = true;
11
+ d.exit(0);
12
+ };
13
+ for (const ev of ["end", "close", "error"])
14
+ d.stdin.on(ev, bye);
15
+ d.stdout.on("error", bye);
16
+ for (const sig of ["SIGHUP", "SIGPIPE"])
17
+ d.proc.on(sig, bye);
18
+ const handle = d.setInterval(() => {
19
+ if (d.getPpid() !== initial)
20
+ bye();
21
+ }, d.intervalMs ?? 500);
22
+ handle?.unref?.();
23
+ return () => d.clearInterval(handle);
24
+ }
25
+
26
+ // orphan-guard-boot.ts
27
+ if (process.env.AGENTISTICS_MCP_NO_ORPHAN_GUARD !== "1") {
28
+ installOrphanGuard({
29
+ stdin: process.stdin,
30
+ stdout: process.stdout,
31
+ proc: process,
32
+ getPpid: () => process.ppid,
33
+ exit: (c) => process.exit(c),
34
+ setInterval: (f, ms) => setInterval(f, ms),
35
+ clearInterval: (h) => clearInterval(h)
36
+ });
37
+ }
38
+
3
39
  // agentistics-mcp.ts
4
40
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
5
41
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
@@ -85,6 +121,7 @@ var BASE_MODEL_PRICING = {
85
121
  "gpt-5": { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 1.25 }
86
122
  };
87
123
  var MODEL_PRICING = Object.fromEntries(Object.entries(BASE_MODEL_PRICING).map(([id, p]) => [id, { ...p, cacheWrite1h: p.input * 2 }]));
124
+ var UNPRICED_PRICE = Object.freeze({ input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cacheWrite1h: 0 });
88
125
  function getModelPrice(modelId) {
89
126
  if (MODEL_PRICING[modelId])
90
127
  return MODEL_PRICING[modelId];
@@ -103,10 +140,9 @@ function getModelPrice(modelId) {
103
140
  }
104
141
  }
105
142
  const hit = forwardKey || reverseKey;
106
- if (hit)
107
- return MODEL_PRICING[hit];
108
- return { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75, cacheWrite1h: 6 };
143
+ return hit ? MODEL_PRICING[hit] : UNPRICED_PRICE;
109
144
  }
145
+ var isUnpricedModel = (modelId) => getModelPrice(modelId) === UNPRICED_PRICE;
110
146
  function sessionModelUsage(s, fallbackModel) {
111
147
  const breakdown = s.model_usage;
112
148
  if (breakdown && typeof breakdown === "object") {
@@ -132,7 +168,22 @@ function sessionCostUSD(s, fallbackModel) {
132
168
  const entries = sessionModelUsage(s, fallbackModel);
133
169
  if (entries.length === 0)
134
170
  return null;
135
- return entries.reduce((sum, [model, u]) => sum + calcCost(u, model), 0);
171
+ const priced = entries.filter(([model]) => !isUnpricedModel(model));
172
+ if (priced.length === 0)
173
+ return null;
174
+ return priced.reduce((sum, [model, u]) => sum + calcCost(u, model), 0);
175
+ }
176
+ var usageTokens = (u) => u.inputTokens + u.outputTokens + u.cacheReadInputTokens + u.cacheCreationInputTokens;
177
+ function unpricedTokens(from, fallbackModel) {
178
+ if (Array.isArray(from)) {
179
+ return from.reduce((sum, [model, u]) => sum + (isUnpricedModel(model) ? usageTokens(u) : 0), 0);
180
+ }
181
+ const sess = from;
182
+ const entries = sessionModelUsage(sess, fallbackModel);
183
+ if (entries.length === 0) {
184
+ return (sess.input_tokens ?? 0) + (sess.output_tokens ?? 0) + (sess.cache_read_input_tokens ?? 0) + (sess.cache_creation_input_tokens ?? 0);
185
+ }
186
+ return entries.reduce((sum, [model, u]) => sum + (isUnpricedModel(model) ? usageTokens(u) : 0), 0);
136
187
  }
137
188
  function calcCost(usage, modelId) {
138
189
  const price = getModelPrice(modelId);
@@ -142,7 +193,7 @@ function calcCost(usage, modelId) {
142
193
  }
143
194
  // ../core/src/tokens.ts
144
195
  var EMPTY_TOKENS = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
145
- function usageTokens(u) {
196
+ function usageTokens2(u) {
146
197
  return {
147
198
  input: u?.inputTokens ?? 0,
148
199
  output: u?.outputTokens ?? 0,
@@ -168,7 +219,7 @@ function totalTokens(b) {
168
219
  return b.input + b.output + b.cacheRead + b.cacheWrite;
169
220
  }
170
221
  function usageTokenTotal(u) {
171
- return totalTokens(usageTokens(u));
222
+ return totalTokens(usageTokens2(u));
172
223
  }
173
224
  // ../core/src/team.ts
174
225
  var DEFAULT_TEAM = Object.freeze({
@@ -955,7 +1006,7 @@ function sessionTokens2(s) {
955
1006
  const output = s.output_tokens ?? 0;
956
1007
  const cacheRead = s.cache_read_input_tokens ?? 0;
957
1008
  const cacheWrite = s.cache_creation_input_tokens ?? 0;
958
- const cost = sessionCostUSD({
1009
+ const priced = {
959
1010
  model: s.model,
960
1011
  model_usage: s.model_usage,
961
1012
  input_tokens: input,
@@ -964,22 +1015,17 @@ function sessionTokens2(s) {
964
1015
  cache_creation_input_tokens: cacheWrite,
965
1016
  cache_creation_1h_input_tokens: s.cache_creation_1h_input_tokens,
966
1017
  cache_creation_5m_input_tokens: s.cache_creation_5m_input_tokens
967
- }) ?? calcCost({
968
- inputTokens: input,
969
- outputTokens: output,
970
- cacheReadInputTokens: cacheRead,
971
- cacheCreationInputTokens: cacheWrite,
972
- webSearchRequests: 0,
973
- costUSD: 0
974
- }, "");
975
- return { input, output, cacheRead, cacheWrite, cost };
1018
+ };
1019
+ const cost = sessionCostUSD(priced) ?? 0;
1020
+ const unpriced = unpricedTokens(priced);
1021
+ return { input, output, cacheRead, cacheWrite, cost, unpriced };
976
1022
  }
977
1023
  function sessionMessages(s) {
978
1024
  return (s.user_message_count ?? 0) + (s.assistant_message_count ?? 0);
979
1025
  }
980
1026
  function statsCacheTotals(sc) {
981
1027
  const entries = Object.entries(sc?.modelUsage ?? {});
982
- const b = sumTokens(entries.map(([, u]) => usageTokens(u)));
1028
+ const b = sumTokens(entries.map(([, u]) => usageTokens2(u)));
983
1029
  let cost = 0;
984
1030
  let top = null;
985
1031
  for (const [model, u] of entries) {
@@ -1245,12 +1291,14 @@ function legacySummary(data, harness) {
1245
1291
  const totals = statsCacheTotals(sc);
1246
1292
  const allSessions = filterSessions(data.sessions ?? [], harness);
1247
1293
  let totalCostUSD = 0;
1294
+ let totalUnpriced = 0;
1248
1295
  let totalInput = 0, totalOutput = 0, totalCacheRead = 0, totalCacheWrite = 0;
1249
1296
  const modelTokens = {};
1250
1297
  const projectSessions = {};
1251
1298
  const activeDates = new Set;
1252
1299
  for (const s of allSessions) {
1253
- const { input, output, cacheRead, cacheWrite, cost } = sessionTokens2(s);
1300
+ const { input, output, cacheRead, cacheWrite, cost, unpriced } = sessionTokens2(s);
1301
+ totalUnpriced += unpriced;
1254
1302
  totalInput += input;
1255
1303
  totalOutput += output;
1256
1304
  totalCacheRead += cacheRead;
@@ -1275,6 +1323,7 @@ function legacySummary(data, harness) {
1275
1323
  totalCacheReadTokens: totalCacheRead || (claudeFallback ? totals.cacheRead : 0),
1276
1324
  totalCacheWriteTokens: totalCacheWrite || (claudeFallback ? totals.cacheWrite : 0),
1277
1325
  estimatedCostUSD: Math.round((totalCostUSD || (claudeFallback ? totals.cost : 0)) * 100) / 100,
1326
+ ...totalUnpriced > 0 ? { unpricedTokens: totalUnpriced, costNote: "estimatedCostUSD excludes usage of models with no price (+ unpriced usage)" } : {},
1278
1327
  totalSessions: allSessions.length,
1279
1328
  topModel,
1280
1329
  topProject,
@@ -2445,7 +2494,7 @@ async function callTool(req) {
2445
2494
  const harness = args?.harness;
2446
2495
  const data = await apiGet("/api/data");
2447
2496
  const rows = filterSessions(data.sessions ?? [], harness).slice(0, limit).map((s) => {
2448
- const { input, output, cacheRead, cacheWrite, cost } = sessionTokens2(s);
2497
+ const { input, output, cacheRead, cacheWrite, cost, unpriced } = sessionTokens2(s);
2449
2498
  return {
2450
2499
  id: s.session_id,
2451
2500
  harness: sessionHarness(s),
@@ -2458,7 +2507,8 @@ async function callTool(req) {
2458
2507
  cacheReadTokens: cacheRead,
2459
2508
  cacheWriteTokens: cacheWrite,
2460
2509
  totalTokens: input + output + cacheRead + cacheWrite,
2461
- estimatedCostUSD: Math.round(cost * 1e4) / 1e4,
2510
+ estimatedCostUSD: unpriced > 0 && unpriced === input + output + cacheRead + cacheWrite ? null : Math.round(cost * 1e4) / 1e4,
2511
+ ...unpriced > 0 ? { unpricedTokens: unpriced } : {},
2462
2512
  model: s.model ?? null
2463
2513
  };
2464
2514
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentistics/mcp",
3
- "version": "2.101.1",
3
+ "version": "2.102.0",
4
4
  "description": "Agentistics MCP server — Claude Code analytics for Claude Desktop and Claude Code",
5
5
  "type": "module",
6
6
  "main": "./dist/agentistics-mcp.js",