local-model-suitability-mcp 1.1.24 → 1.1.25

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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/server.js +9 -3
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "local-model-suitability-mcp",
3
3
  "mcpName": "io.github.OjasKord/local-model-suitability-mcp",
4
- "version": "1.1.24",
4
+ "version": "1.1.25",
5
5
  "description": "AI model router for agents. Checks whether a local model can handle the task before calling cloud inference. LOCAL/CLOUD verdict saves cost on every call.",
6
6
  "main": "src/server.js",
7
7
  "type": "module",
package/src/server.js CHANGED
@@ -3,7 +3,7 @@ import { createHmac, timingSafeEqual } from 'crypto';
3
3
  import { readFileSync, writeFileSync } from 'fs';
4
4
  import Anthropic from '@anthropic-ai/sdk';
5
5
 
6
- const VERSION = '1.1.24';
6
+ const VERSION = '1.1.25';
7
7
  const FIRST_DEPLOYED = '2026-04-13T06:41:38Z';
8
8
  const LIFETIME_CALLS_REDIS_KEY = 'lms:lifetime_calls';
9
9
  const UPTIME_HEARTBEAT_KEY = 'lms:uptime:heartbeat_count';
@@ -24,7 +24,7 @@ function nowISO() { return new Date().toISOString(); }
24
24
  const cors = {
25
25
  'Access-Control-Allow-Origin': '*',
26
26
  'Access-Control-Allow-Methods': 'GET, POST, OPTIONS, HEAD',
27
- 'Access-Control-Allow-Headers': 'Content-Type, x-api-key, x-stats-key'
27
+ 'Access-Control-Allow-Headers': 'Content-Type, x-api-key, x-stats-key, x-owner-key'
28
28
  };
29
29
 
30
30
  // ── Stats persistence ─────────────────────────────────────────────────────────
@@ -312,6 +312,7 @@ async function saveFreeTierToRedis() {
312
312
 
313
313
  // ── Anthropic client ──────────────────────────────────────────────────────────
314
314
  const anthropic = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });
315
+ const OWNER_KEY = process.env.OWNER_KEY || '';
315
316
 
316
317
  // ── Cloud pricing reference (approximate, per 1K tokens, mid-2026) ───────────
317
318
  const CLOUD_PRICING = {
@@ -885,7 +886,12 @@ const server = createServer(async (req, res) => {
885
886
  result: { content: [{ type: 'text', text: JSON.stringify({ error: 'task is required — describe what you are about to send to the cloud model', likely_cause: 'required field missing or malformed', retryable: false, retry_after_ms: null, fallback_tool: null, agent_action: 'PROVIDE_REQUIRED_FIELD', category: 'invalid_input', trace_id: nowISO(), _disclaimer: LEGAL_DISCLAIMER }) }] }
886
887
  };
887
888
  } else {
888
- const access = await checkAccess(clientIp, apiKey);
889
+ const isOwner = OWNER_KEY !== '' && (req.headers['x-owner-key'] || request.owner_key || '') === OWNER_KEY;
890
+ if (isOwner) {
891
+ redisIncr('lms:owner_calls:' + new Date().toISOString().slice(0, 7)).catch(() => {});
892
+ console.log('[owner] owner key used');
893
+ }
894
+ const access = isOwner ? { allowed: true, tier: 'owner', plan: 'owner', remaining: Infinity } : await checkAccess(clientIp, apiKey);
889
895
 
890
896
  if (!access.allowed) {
891
897
  statusCode = 402;