mcp-cost-tracker 1.0.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.
Files changed (44) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +99 -0
  3. package/dist/dashboard/generator.d.ts +54 -0
  4. package/dist/dashboard/generator.d.ts.map +1 -0
  5. package/dist/dashboard/generator.js +577 -0
  6. package/dist/dashboard/generator.js.map +1 -0
  7. package/dist/index.d.ts +12 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +60 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/pricing/models.d.ts +48 -0
  12. package/dist/pricing/models.d.ts.map +1 -0
  13. package/dist/pricing/models.js +207 -0
  14. package/dist/pricing/models.js.map +1 -0
  15. package/dist/storage/database.d.ts +129 -0
  16. package/dist/storage/database.d.ts.map +1 -0
  17. package/dist/storage/database.js +374 -0
  18. package/dist/storage/database.js.map +1 -0
  19. package/dist/tools/index.d.ts +4 -0
  20. package/dist/tools/index.d.ts.map +1 -0
  21. package/dist/tools/index.js +660 -0
  22. package/dist/tools/index.js.map +1 -0
  23. package/dist/tools/prompts.d.ts +3 -0
  24. package/dist/tools/prompts.d.ts.map +1 -0
  25. package/dist/tools/prompts.js +111 -0
  26. package/dist/tools/prompts.js.map +1 -0
  27. package/dist/tools/resources.d.ts +4 -0
  28. package/dist/tools/resources.d.ts.map +1 -0
  29. package/dist/tools/resources.js +138 -0
  30. package/dist/tools/resources.js.map +1 -0
  31. package/dist/utils/helpers.d.ts +29 -0
  32. package/dist/utils/helpers.d.ts.map +1 -0
  33. package/dist/utils/helpers.js +81 -0
  34. package/dist/utils/helpers.js.map +1 -0
  35. package/package.json +52 -0
  36. package/src/dashboard/generator.ts +628 -0
  37. package/src/index.ts +73 -0
  38. package/src/pricing/models.ts +246 -0
  39. package/src/storage/database.ts +525 -0
  40. package/src/tools/index.ts +780 -0
  41. package/src/tools/prompts.ts +124 -0
  42. package/src/tools/resources.ts +171 -0
  43. package/src/utils/helpers.ts +71 -0
  44. package/tsconfig.json +20 -0
@@ -0,0 +1,577 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.collectDashboardData = collectDashboardData;
4
+ exports.generateDashboardHTML = generateDashboardHTML;
5
+ exports.generateTextReport = generateTextReport;
6
+ function collectDashboardData(db, days = 30) {
7
+ return {
8
+ summary: db.getSummary(),
9
+ costByModel: db.getCostByModel(),
10
+ costByProvider: db.getCostByProvider(),
11
+ costByDay: db.getCostByDay({ days }),
12
+ costByProject: db.getCostByProject(),
13
+ topExpensive: db.getTopExpensiveRequests(10).map(r => ({
14
+ timestamp: r.timestamp,
15
+ provider: r.provider,
16
+ model: r.model,
17
+ total_cost: r.total_cost,
18
+ total_tokens: r.total_tokens,
19
+ description: r.description,
20
+ })),
21
+ generatedAt: new Date().toISOString(),
22
+ };
23
+ }
24
+ function generateDashboardHTML(data) {
25
+ const providerColors = {
26
+ openai: '#10a37f',
27
+ anthropic: '#d4a574',
28
+ google: '#4285f4',
29
+ deepseek: '#0066ff',
30
+ mistral: '#ff7000',
31
+ meta: '#0668E1',
32
+ cohere: '#39594d',
33
+ xai: '#1DA1F2',
34
+ };
35
+ const getColor = (provider, alpha = 1) => {
36
+ const hex = providerColors[provider.toLowerCase()] || '#6b7280';
37
+ const r = parseInt(hex.slice(1, 3), 16);
38
+ const g = parseInt(hex.slice(3, 5), 16);
39
+ const b = parseInt(hex.slice(5, 7), 16);
40
+ return `rgba(${r}, ${g}, ${b}, ${alpha})`;
41
+ };
42
+ const formatCost = (cost) => `$${cost.toFixed(4)}`;
43
+ const formatTokens = (tokens) => {
44
+ if (tokens >= 1_000_000)
45
+ return `${(tokens / 1_000_000).toFixed(2)}M`;
46
+ if (tokens >= 1_000)
47
+ return `${(tokens / 1_000).toFixed(1)}K`;
48
+ return tokens.toString();
49
+ };
50
+ return `<!DOCTYPE html>
51
+ <html lang="en" data-theme="dark">
52
+ <head>
53
+ <meta charset="UTF-8">
54
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
55
+ <title>MCP Cost Tracker Dashboard</title>
56
+ <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
57
+ <style>
58
+ :root {
59
+ --bg-primary: #0f172a;
60
+ --bg-secondary: #1e293b;
61
+ --bg-card: #1e293b;
62
+ --bg-card-hover: #334155;
63
+ --text-primary: #f1f5f9;
64
+ --text-secondary: #94a3b8;
65
+ --text-muted: #64748b;
66
+ --border: #334155;
67
+ --accent: #3b82f6;
68
+ --accent-green: #10b981;
69
+ --accent-red: #ef4444;
70
+ --accent-yellow: #f59e0b;
71
+ --accent-purple: #8b5cf6;
72
+ --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.3);
73
+ }
74
+
75
+ * { margin: 0; padding: 0; box-sizing: border-box; }
76
+
77
+ body {
78
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;
79
+ background: var(--bg-primary);
80
+ color: var(--text-primary);
81
+ line-height: 1.6;
82
+ min-height: 100vh;
83
+ }
84
+
85
+ .container {
86
+ max-width: 1400px;
87
+ margin: 0 auto;
88
+ padding: 24px;
89
+ }
90
+
91
+ header {
92
+ text-align: center;
93
+ padding: 32px 0;
94
+ border-bottom: 1px solid var(--border);
95
+ margin-bottom: 32px;
96
+ }
97
+
98
+ header h1 {
99
+ font-size: 2.5rem;
100
+ font-weight: 800;
101
+ background: linear-gradient(135deg, #3b82f6, #8b5cf6, #ec4899);
102
+ -webkit-background-clip: text;
103
+ -webkit-text-fill-color: transparent;
104
+ margin-bottom: 8px;
105
+ }
106
+
107
+ header p {
108
+ color: var(--text-secondary);
109
+ font-size: 0.95rem;
110
+ }
111
+
112
+ .stats-grid {
113
+ display: grid;
114
+ grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
115
+ gap: 16px;
116
+ margin-bottom: 32px;
117
+ }
118
+
119
+ .stat-card {
120
+ background: var(--bg-card);
121
+ border: 1px solid var(--border);
122
+ border-radius: 12px;
123
+ padding: 24px;
124
+ transition: all 0.2s;
125
+ }
126
+
127
+ .stat-card:hover {
128
+ background: var(--bg-card-hover);
129
+ transform: translateY(-2px);
130
+ box-shadow: var(--shadow);
131
+ }
132
+
133
+ .stat-card .label {
134
+ font-size: 0.8rem;
135
+ text-transform: uppercase;
136
+ letter-spacing: 0.05em;
137
+ color: var(--text-muted);
138
+ margin-bottom: 8px;
139
+ }
140
+
141
+ .stat-card .value {
142
+ font-size: 1.8rem;
143
+ font-weight: 700;
144
+ }
145
+
146
+ .stat-card .sub {
147
+ font-size: 0.85rem;
148
+ color: var(--text-secondary);
149
+ margin-top: 4px;
150
+ }
151
+
152
+ .cost-value { color: var(--accent-green); }
153
+ .token-value { color: var(--accent); }
154
+ .request-value { color: var(--accent-purple); }
155
+ .avg-value { color: var(--accent-yellow); }
156
+
157
+ .charts-grid {
158
+ display: grid;
159
+ grid-template-columns: repeat(auto-fit, minmax(500px, 1fr));
160
+ gap: 24px;
161
+ margin-bottom: 32px;
162
+ }
163
+
164
+ .chart-card {
165
+ background: var(--bg-card);
166
+ border: 1px solid var(--border);
167
+ border-radius: 12px;
168
+ padding: 24px;
169
+ }
170
+
171
+ .chart-card h3 {
172
+ font-size: 1.1rem;
173
+ margin-bottom: 16px;
174
+ color: var(--text-primary);
175
+ }
176
+
177
+ .chart-container {
178
+ position: relative;
179
+ height: 300px;
180
+ }
181
+
182
+ table {
183
+ width: 100%;
184
+ border-collapse: collapse;
185
+ font-size: 0.9rem;
186
+ }
187
+
188
+ th {
189
+ text-align: left;
190
+ padding: 12px 16px;
191
+ border-bottom: 2px solid var(--border);
192
+ color: var(--text-muted);
193
+ font-weight: 600;
194
+ text-transform: uppercase;
195
+ font-size: 0.75rem;
196
+ letter-spacing: 0.05em;
197
+ }
198
+
199
+ td {
200
+ padding: 12px 16px;
201
+ border-bottom: 1px solid var(--border);
202
+ color: var(--text-secondary);
203
+ }
204
+
205
+ tr:hover td {
206
+ background: var(--bg-card-hover);
207
+ }
208
+
209
+ .provider-badge {
210
+ display: inline-block;
211
+ padding: 2px 10px;
212
+ border-radius: 9999px;
213
+ font-size: 0.75rem;
214
+ font-weight: 600;
215
+ text-transform: uppercase;
216
+ }
217
+
218
+ .table-card {
219
+ background: var(--bg-card);
220
+ border: 1px solid var(--border);
221
+ border-radius: 12px;
222
+ padding: 24px;
223
+ margin-bottom: 24px;
224
+ overflow-x: auto;
225
+ }
226
+
227
+ .table-card h3 {
228
+ font-size: 1.1rem;
229
+ margin-bottom: 16px;
230
+ }
231
+
232
+ footer {
233
+ text-align: center;
234
+ padding: 24px 0;
235
+ border-top: 1px solid var(--border);
236
+ color: var(--text-muted);
237
+ font-size: 0.85rem;
238
+ }
239
+
240
+ @media (max-width: 768px) {
241
+ .charts-grid { grid-template-columns: 1fr; }
242
+ .container { padding: 16px; }
243
+ header h1 { font-size: 1.8rem; }
244
+ }
245
+ </style>
246
+ </head>
247
+ <body>
248
+ <div class="container">
249
+ <header>
250
+ <h1>MCP Cost Tracker</h1>
251
+ <p>LLM API Usage & Cost Dashboard — Generated ${data.generatedAt}</p>
252
+ </header>
253
+
254
+ <div class="stats-grid">
255
+ <div class="stat-card">
256
+ <div class="label">Total Spend</div>
257
+ <div class="value cost-value">${formatCost(data.summary.total_cost)}</div>
258
+ <div class="sub">${data.summary.total_requests} API calls</div>
259
+ </div>
260
+ <div class="stat-card">
261
+ <div class="label">Input Tokens</div>
262
+ <div class="value token-value">${formatTokens(data.summary.total_input_tokens)}</div>
263
+ <div class="sub">prompt tokens consumed</div>
264
+ </div>
265
+ <div class="stat-card">
266
+ <div class="label">Output Tokens</div>
267
+ <div class="value token-value">${formatTokens(data.summary.total_output_tokens)}</div>
268
+ <div class="sub">completion tokens generated</div>
269
+ </div>
270
+ <div class="stat-card">
271
+ <div class="label">Cached Tokens</div>
272
+ <div class="value request-value">${formatTokens(data.summary.total_cached_tokens)}</div>
273
+ <div class="sub">tokens served from cache</div>
274
+ </div>
275
+ <div class="stat-card">
276
+ <div class="label">Avg Cost / Request</div>
277
+ <div class="value avg-value">${formatCost(data.summary.avg_cost_per_request)}</div>
278
+ <div class="sub">per API call</div>
279
+ </div>
280
+ </div>
281
+
282
+ <div class="charts-grid">
283
+ <div class="chart-card">
284
+ <h3>Daily Cost Trend</h3>
285
+ <div class="chart-container">
286
+ <canvas id="dailyCostChart"></canvas>
287
+ </div>
288
+ </div>
289
+ <div class="chart-card">
290
+ <h3>Cost by Provider</h3>
291
+ <div class="chart-container">
292
+ <canvas id="providerChart"></canvas>
293
+ </div>
294
+ </div>
295
+ <div class="chart-card">
296
+ <h3>Cost by Model</h3>
297
+ <div class="chart-container">
298
+ <canvas id="modelChart"></canvas>
299
+ </div>
300
+ </div>
301
+ <div class="chart-card">
302
+ <h3>Cost by Project</h3>
303
+ <div class="chart-container">
304
+ <canvas id="projectChart"></canvas>
305
+ </div>
306
+ </div>
307
+ </div>
308
+
309
+ <div class="table-card">
310
+ <h3>Cost Breakdown by Model</h3>
311
+ <table>
312
+ <thead>
313
+ <tr>
314
+ <th>Provider</th>
315
+ <th>Model</th>
316
+ <th>Requests</th>
317
+ <th>Input Tokens</th>
318
+ <th>Output Tokens</th>
319
+ <th>Total Cost</th>
320
+ </tr>
321
+ </thead>
322
+ <tbody>
323
+ ${data.costByModel.map(m => `
324
+ <tr>
325
+ <td><span class="provider-badge" style="background:${getColor(m.provider, 0.2)};color:${getColor(m.provider)}">${m.provider}</span></td>
326
+ <td>${m.model}</td>
327
+ <td>${m.request_count}</td>
328
+ <td>${formatTokens(m.total_input_tokens)}</td>
329
+ <td>${formatTokens(m.total_output_tokens)}</td>
330
+ <td style="color:var(--accent-green);font-weight:600">${formatCost(m.total_cost)}</td>
331
+ </tr>`).join('')}
332
+ </tbody>
333
+ </table>
334
+ </div>
335
+
336
+ <div class="table-card">
337
+ <h3>Top 10 Most Expensive Requests</h3>
338
+ <table>
339
+ <thead>
340
+ <tr>
341
+ <th>Timestamp</th>
342
+ <th>Provider</th>
343
+ <th>Model</th>
344
+ <th>Tokens</th>
345
+ <th>Cost</th>
346
+ <th>Description</th>
347
+ </tr>
348
+ </thead>
349
+ <tbody>
350
+ ${data.topExpensive.map(r => `
351
+ <tr>
352
+ <td>${r.timestamp}</td>
353
+ <td><span class="provider-badge" style="background:${getColor(r.provider, 0.2)};color:${getColor(r.provider)}">${r.provider}</span></td>
354
+ <td>${r.model}</td>
355
+ <td>${formatTokens(r.total_tokens)}</td>
356
+ <td style="color:var(--accent-green);font-weight:600">${formatCost(r.total_cost)}</td>
357
+ <td>${r.description || '—'}</td>
358
+ </tr>`).join('')}
359
+ </tbody>
360
+ </table>
361
+ </div>
362
+
363
+ <footer>
364
+ <p>Generated by <strong>mcp-cost-tracker</strong> — Open source MCP server for LLM cost tracking</p>
365
+ </footer>
366
+ </div>
367
+
368
+ <script>
369
+ Chart.defaults.color = '#94a3b8';
370
+ Chart.defaults.borderColor = '#334155';
371
+
372
+ // Daily Cost Trend
373
+ new Chart(document.getElementById('dailyCostChart'), {
374
+ type: 'line',
375
+ data: {
376
+ labels: ${JSON.stringify(data.costByDay.map(d => d.date))},
377
+ datasets: [{
378
+ label: 'Daily Cost ($)',
379
+ data: ${JSON.stringify(data.costByDay.map(d => d.total_cost))},
380
+ borderColor: '#3b82f6',
381
+ backgroundColor: 'rgba(59, 130, 246, 0.1)',
382
+ fill: true,
383
+ tension: 0.4,
384
+ pointRadius: 4,
385
+ pointHoverRadius: 6,
386
+ }]
387
+ },
388
+ options: {
389
+ responsive: true,
390
+ maintainAspectRatio: false,
391
+ plugins: {
392
+ legend: { display: false },
393
+ tooltip: {
394
+ callbacks: {
395
+ label: ctx => '$' + ctx.parsed.y.toFixed(4)
396
+ }
397
+ }
398
+ },
399
+ scales: {
400
+ y: {
401
+ beginAtZero: true,
402
+ ticks: { callback: v => '$' + v.toFixed(2) },
403
+ grid: { color: '#1e293b' }
404
+ },
405
+ x: { grid: { display: false } }
406
+ }
407
+ }
408
+ });
409
+
410
+ // Provider Doughnut
411
+ new Chart(document.getElementById('providerChart'), {
412
+ type: 'doughnut',
413
+ data: {
414
+ labels: ${JSON.stringify(data.costByProvider.map(p => p.provider))},
415
+ datasets: [{
416
+ data: ${JSON.stringify(data.costByProvider.map(p => p.total_cost))},
417
+ backgroundColor: ${JSON.stringify(data.costByProvider.map(p => getColor(p.provider, 0.8)))},
418
+ borderColor: ${JSON.stringify(data.costByProvider.map(p => getColor(p.provider)))},
419
+ borderWidth: 2,
420
+ }]
421
+ },
422
+ options: {
423
+ responsive: true,
424
+ maintainAspectRatio: false,
425
+ plugins: {
426
+ tooltip: {
427
+ callbacks: {
428
+ label: ctx => ctx.label + ': $' + ctx.parsed.toFixed(4)
429
+ }
430
+ },
431
+ legend: {
432
+ position: 'right',
433
+ labels: { padding: 16, usePointStyle: true }
434
+ }
435
+ }
436
+ }
437
+ });
438
+
439
+ // Model Bar Chart
440
+ const modelData = ${JSON.stringify(data.costByModel.slice(0, 10))};
441
+ new Chart(document.getElementById('modelChart'), {
442
+ type: 'bar',
443
+ data: {
444
+ labels: modelData.map(m => m.model),
445
+ datasets: [{
446
+ label: 'Cost ($)',
447
+ data: modelData.map(m => m.total_cost),
448
+ backgroundColor: modelData.map(m => {
449
+ const colors = ${JSON.stringify(providerColors)};
450
+ const hex = colors[m.provider.toLowerCase()] || '#6b7280';
451
+ return hex + 'cc';
452
+ }),
453
+ borderRadius: 6,
454
+ }]
455
+ },
456
+ options: {
457
+ responsive: true,
458
+ maintainAspectRatio: false,
459
+ indexAxis: 'y',
460
+ plugins: {
461
+ legend: { display: false },
462
+ tooltip: {
463
+ callbacks: {
464
+ label: ctx => '$' + ctx.parsed.x.toFixed(4)
465
+ }
466
+ }
467
+ },
468
+ scales: {
469
+ x: {
470
+ beginAtZero: true,
471
+ ticks: { callback: v => '$' + v.toFixed(2) },
472
+ grid: { color: '#1e293b' }
473
+ },
474
+ y: { grid: { display: false } }
475
+ }
476
+ }
477
+ });
478
+
479
+ // Project Chart
480
+ const projectData = ${JSON.stringify(data.costByProject)};
481
+ new Chart(document.getElementById('projectChart'), {
482
+ type: 'bar',
483
+ data: {
484
+ labels: projectData.map(p => p.project),
485
+ datasets: [{
486
+ label: 'Cost ($)',
487
+ data: projectData.map(p => p.total_cost),
488
+ backgroundColor: ['#3b82f6cc', '#8b5cf6cc', '#ec4899cc', '#f59e0bcc', '#10b981cc', '#06b6d4cc'],
489
+ borderRadius: 6,
490
+ }]
491
+ },
492
+ options: {
493
+ responsive: true,
494
+ maintainAspectRatio: false,
495
+ plugins: {
496
+ legend: { display: false },
497
+ tooltip: {
498
+ callbacks: {
499
+ label: ctx => '$' + ctx.parsed.y.toFixed(4)
500
+ }
501
+ }
502
+ },
503
+ scales: {
504
+ y: {
505
+ beginAtZero: true,
506
+ ticks: { callback: v => '$' + v.toFixed(2) },
507
+ grid: { color: '#1e293b' }
508
+ },
509
+ x: { grid: { display: false } }
510
+ }
511
+ }
512
+ });
513
+ </script>
514
+ </body>
515
+ </html>`;
516
+ }
517
+ /**
518
+ * Generate a Markdown text report (for terminal / MCP response).
519
+ */
520
+ function generateTextReport(data) {
521
+ const formatCost = (cost) => `$${cost.toFixed(4)}`;
522
+ const formatTokens = (tokens) => {
523
+ if (tokens >= 1_000_000)
524
+ return `${(tokens / 1_000_000).toFixed(2)}M`;
525
+ if (tokens >= 1_000)
526
+ return `${(tokens / 1_000).toFixed(1)}K`;
527
+ return tokens.toString();
528
+ };
529
+ let report = `# MCP Cost Tracker Report\n`;
530
+ report += `Generated: ${data.generatedAt}\n\n`;
531
+ report += `## Summary\n`;
532
+ report += `| Metric | Value |\n|--------|-------|\n`;
533
+ report += `| Total Spend | ${formatCost(data.summary.total_cost)} |\n`;
534
+ report += `| Total Requests | ${data.summary.total_requests.toLocaleString()} |\n`;
535
+ report += `| Input Tokens | ${formatTokens(data.summary.total_input_tokens)} |\n`;
536
+ report += `| Output Tokens | ${formatTokens(data.summary.total_output_tokens)} |\n`;
537
+ report += `| Cached Tokens | ${formatTokens(data.summary.total_cached_tokens)} |\n`;
538
+ report += `| Avg Cost/Request | ${formatCost(data.summary.avg_cost_per_request)} |\n\n`;
539
+ if (data.costByProvider.length > 0) {
540
+ report += `## Cost by Provider\n`;
541
+ report += `| Provider | Cost | Requests | Input Tokens | Output Tokens |\n`;
542
+ report += `|----------|------|----------|--------------|---------------|\n`;
543
+ for (const p of data.costByProvider) {
544
+ report += `| ${p.provider} | ${formatCost(p.total_cost)} | ${p.request_count} | ${formatTokens(p.total_input_tokens)} | ${formatTokens(p.total_output_tokens)} |\n`;
545
+ }
546
+ report += '\n';
547
+ }
548
+ if (data.costByModel.length > 0) {
549
+ report += `## Cost by Model\n`;
550
+ report += `| Provider | Model | Cost | Requests |\n`;
551
+ report += `|----------|-------|------|----------|\n`;
552
+ for (const m of data.costByModel) {
553
+ report += `| ${m.provider} | ${m.model} | ${formatCost(m.total_cost)} | ${m.request_count} |\n`;
554
+ }
555
+ report += '\n';
556
+ }
557
+ if (data.costByProject.length > 0) {
558
+ report += `## Cost by Project\n`;
559
+ report += `| Project | Cost | Requests | Tokens |\n`;
560
+ report += `|---------|------|----------|--------|\n`;
561
+ for (const p of data.costByProject) {
562
+ report += `| ${p.project} | ${formatCost(p.total_cost)} | ${p.request_count} | ${formatTokens(p.total_tokens)} |\n`;
563
+ }
564
+ report += '\n';
565
+ }
566
+ if (data.costByDay.length > 0) {
567
+ report += `## Daily Trend (Last ${data.costByDay.length} days)\n`;
568
+ report += `| Date | Cost | Requests | Tokens |\n`;
569
+ report += `|------|------|----------|--------|\n`;
570
+ for (const d of data.costByDay) {
571
+ report += `| ${d.date} | ${formatCost(d.total_cost)} | ${d.request_count} | ${formatTokens(d.total_tokens)} |\n`;
572
+ }
573
+ report += '\n';
574
+ }
575
+ return report;
576
+ }
577
+ //# sourceMappingURL=generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator.js","sourceRoot":"","sources":["../../src/dashboard/generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * MCP Cost Tracker
4
+ *
5
+ * An MCP server that automatically tracks LLM API call costs,
6
+ * token usage, and generates visual dashboards.
7
+ *
8
+ * Supports 50+ models across OpenAI, Anthropic, Google, DeepSeek,
9
+ * Mistral, Meta, Cohere, xAI, and more.
10
+ */
11
+ export {};
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;GAQG"}
package/dist/index.js ADDED
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ /**
4
+ * MCP Cost Tracker
5
+ *
6
+ * An MCP server that automatically tracks LLM API call costs,
7
+ * token usage, and generates visual dashboards.
8
+ *
9
+ * Supports 50+ models across OpenAI, Anthropic, Google, DeepSeek,
10
+ * Mistral, Meta, Cohere, xAI, and more.
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
14
+ const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
15
+ const database_js_1 = require("./storage/database.js");
16
+ const index_js_1 = require("./tools/index.js");
17
+ const resources_js_1 = require("./tools/resources.js");
18
+ const prompts_js_1 = require("./tools/prompts.js");
19
+ // ============================================================
20
+ // Configuration
21
+ // ============================================================
22
+ const DB_PATH = process.env.MCP_COST_TRACKER_DB || undefined;
23
+ // ============================================================
24
+ // Server Initialization
25
+ // ============================================================
26
+ const server = new mcp_js_1.McpServer({
27
+ name: 'mcp-cost-tracker',
28
+ version: '1.0.0',
29
+ }, {
30
+ capabilities: {
31
+ logging: {},
32
+ },
33
+ });
34
+ // Initialize database
35
+ const db = new database_js_1.CostDatabase(DB_PATH);
36
+ // Register all tools, resources, and prompts
37
+ (0, index_js_1.registerAllTools)(server, db);
38
+ (0, resources_js_1.registerResources)(server, db);
39
+ (0, prompts_js_1.registerPrompts)(server);
40
+ // ============================================================
41
+ // Transport & Startup
42
+ // ============================================================
43
+ async function main() {
44
+ const transport = new stdio_js_1.StdioServerTransport();
45
+ await server.connect(transport);
46
+ // Handle graceful shutdown
47
+ process.on('SIGINT', () => {
48
+ db.close();
49
+ process.exit(0);
50
+ });
51
+ process.on('SIGTERM', () => {
52
+ db.close();
53
+ process.exit(0);
54
+ });
55
+ }
56
+ main().catch((error) => {
57
+ console.error('Fatal error:', error);
58
+ process.exit(1);
59
+ });
60
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAEA;;;;;;;;GAQG;;AAEH,oEAAoE;AACpE,wEAAiF;AACjF,uDAAqD;AACrD,+CAAoD;AACpD,uDAAyD;AACzD,mDAAqD;AAErD,+DAA+D;AAC/D,gBAAgB;AAChB,+DAA+D;AAE/D,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,SAAS,CAAC;AAE7D,+DAA+D;AAC/D,wBAAwB;AACxB,+DAA+D;AAE/D,MAAM,MAAM,GAAG,IAAI,kBAAS,CAC1B;IACE,IAAI,EAAE,kBAAkB;IACxB,OAAO,EAAE,OAAO;CACjB,EACD;IACE,YAAY,EAAE;QACZ,OAAO,EAAE,EAAE;KACZ;CACF,CACF,CAAC;AAEF,sBAAsB;AACtB,MAAM,EAAE,GAAG,IAAI,0BAAY,CAAC,OAAO,CAAC,CAAC;AAErC,6CAA6C;AAC7C,IAAA,2BAAgB,EAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AAC7B,IAAA,gCAAiB,EAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AAC9B,IAAA,4BAAe,EAAC,MAAM,CAAC,CAAC;AAExB,+DAA+D;AAC/D,sBAAsB;AACtB,+DAA+D;AAE/D,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,IAAI,+BAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEhC,2BAA2B;IAC3B,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;QACxB,EAAE,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;QACzB,EAAE,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}