@iris-eval/mcp-server 0.2.3 → 0.3.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.
@@ -38,13 +38,20 @@ function loadConfigFile(path) {
38
38
  throw new Error(`Invalid JSON in config file ${path}: ${err.message}`);
39
39
  }
40
40
  }
41
+ function parsePortEnv(value, name) {
42
+ const n = parseInt(value, 10);
43
+ if (!Number.isFinite(n) || n < 1 || n > 65535) {
44
+ throw new Error(`${name}=${JSON.stringify(value)} is not a valid port (must be an integer 1-65535)`);
45
+ }
46
+ return n;
47
+ }
41
48
  function loadEnvVars() {
42
49
  const config = {};
43
50
  if (process.env.IRIS_TRANSPORT) {
44
51
  config.transport = { type: process.env.IRIS_TRANSPORT };
45
52
  }
46
53
  if (process.env.IRIS_PORT) {
47
- config.transport = { ...config.transport, port: parseInt(process.env.IRIS_PORT) };
54
+ config.transport = { ...config.transport, port: parsePortEnv(process.env.IRIS_PORT, 'IRIS_PORT') };
48
55
  }
49
56
  if (process.env.IRIS_HOST) {
50
57
  config.transport = { ...config.transport, host: process.env.IRIS_HOST };
@@ -61,7 +68,7 @@ function loadEnvVars() {
61
68
  if (process.env.IRIS_DASHBOARD_PORT) {
62
69
  config.dashboard = {
63
70
  ...config.dashboard,
64
- port: parseInt(process.env.IRIS_DASHBOARD_PORT),
71
+ port: parsePortEnv(process.env.IRIS_DASHBOARD_PORT, 'IRIS_DASHBOARD_PORT'),
65
72
  };
66
73
  }
67
74
  if (process.env.IRIS_API_KEY) {
@@ -0,0 +1,49 @@
1
+ export type Provider = 'anthropic' | 'openai';
2
+ export interface ModelPricing {
3
+ /** USD per 1M input tokens. */
4
+ inputPerMillion: number;
5
+ /** USD per 1M output tokens. */
6
+ outputPerMillion: number;
7
+ }
8
+ /**
9
+ * Pricing as of 2026-04-21. Verify against provider documentation
10
+ * at minor-release boundaries.
11
+ *
12
+ * Sources:
13
+ * - Anthropic: anthropic.com/pricing
14
+ * - OpenAI: openai.com/api/pricing
15
+ */
16
+ export declare const PRICING: Record<Provider, Record<string, ModelPricing>>;
17
+ export interface EstimateInput {
18
+ provider: Provider;
19
+ /** Model name. Match keys in PRICING for exact pricing; otherwise estimate returns null. */
20
+ model: string;
21
+ /** Input token count for this call. */
22
+ tokensIn: number;
23
+ /** Output token count for this call. */
24
+ tokensOut: number;
25
+ }
26
+ export interface CostEstimate {
27
+ /** USD cost for the call. */
28
+ totalUsd: number;
29
+ /** USD cost for input tokens only. */
30
+ inputUsd: number;
31
+ /** USD cost for output tokens only. */
32
+ outputUsd: number;
33
+ }
34
+ /**
35
+ * Estimate USD cost for a single LLM call given token counts + model.
36
+ * Returns null if the model is not in the pricing table — caller should
37
+ * either supply pricing override or accept "unknown cost" for that call.
38
+ */
39
+ export declare function estimateCost(input: EstimateInput): CostEstimate | null;
40
+ /**
41
+ * Sum cost estimates across multiple calls. Skips calls where the model
42
+ * is not in the pricing table; the caller can detect via the return's
43
+ * `unknownModelCount`.
44
+ */
45
+ export declare function estimateBatch(inputs: EstimateInput[]): {
46
+ totalUsd: number;
47
+ estimatedCount: number;
48
+ unknownModelCount: number;
49
+ };
@@ -0,0 +1,72 @@
1
+ /*
2
+ * Cost estimator — converts (token-count × model) into USD cost.
3
+ *
4
+ * Pricing tables embedded here for the major providers. Updated when
5
+ * provider pricing changes; provider documentation is the source of truth.
6
+ *
7
+ * v0.3.1 — first public surface.
8
+ */
9
+ /**
10
+ * Pricing as of 2026-04-21. Verify against provider documentation
11
+ * at minor-release boundaries.
12
+ *
13
+ * Sources:
14
+ * - Anthropic: anthropic.com/pricing
15
+ * - OpenAI: openai.com/api/pricing
16
+ */
17
+ export const PRICING = {
18
+ anthropic: {
19
+ 'claude-opus-4': { inputPerMillion: 15, outputPerMillion: 75 },
20
+ 'claude-sonnet-4': { inputPerMillion: 3, outputPerMillion: 15 },
21
+ 'claude-haiku-4-5': { inputPerMillion: 1, outputPerMillion: 5 },
22
+ 'claude-3-5-sonnet': { inputPerMillion: 3, outputPerMillion: 15 },
23
+ 'claude-3-5-haiku': { inputPerMillion: 0.8, outputPerMillion: 4 },
24
+ },
25
+ openai: {
26
+ 'gpt-4o': { inputPerMillion: 2.5, outputPerMillion: 10 },
27
+ 'gpt-4o-mini': { inputPerMillion: 0.15, outputPerMillion: 0.6 },
28
+ 'o1': { inputPerMillion: 15, outputPerMillion: 60 },
29
+ 'o1-mini': { inputPerMillion: 3, outputPerMillion: 12 },
30
+ },
31
+ };
32
+ /**
33
+ * Estimate USD cost for a single LLM call given token counts + model.
34
+ * Returns null if the model is not in the pricing table — caller should
35
+ * either supply pricing override or accept "unknown cost" for that call.
36
+ */
37
+ export function estimateCost(input) {
38
+ const providerTable = PRICING[input.provider];
39
+ if (!providerTable)
40
+ return null;
41
+ const pricing = providerTable[input.model];
42
+ if (!pricing)
43
+ return null;
44
+ const inputUsd = (input.tokensIn / 1_000_000) * pricing.inputPerMillion;
45
+ const outputUsd = (input.tokensOut / 1_000_000) * pricing.outputPerMillion;
46
+ return {
47
+ totalUsd: inputUsd + outputUsd,
48
+ inputUsd,
49
+ outputUsd,
50
+ };
51
+ }
52
+ /**
53
+ * Sum cost estimates across multiple calls. Skips calls where the model
54
+ * is not in the pricing table; the caller can detect via the return's
55
+ * `unknownModelCount`.
56
+ */
57
+ export function estimateBatch(inputs) {
58
+ let totalUsd = 0;
59
+ let estimatedCount = 0;
60
+ let unknownModelCount = 0;
61
+ for (const input of inputs) {
62
+ const est = estimateCost(input);
63
+ if (est === null) {
64
+ unknownModelCount += 1;
65
+ }
66
+ else {
67
+ totalUsd += est.totalUsd;
68
+ estimatedCount += 1;
69
+ }
70
+ }
71
+ return { totalUsd, estimatedCount, unknownModelCount };
72
+ }