@index9/mcp 6.3.0 → 6.5.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.
- package/dist/cli.js +53 -43
- package/manifest.json +1 -1
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -224,7 +224,7 @@ Parameters:
|
|
|
224
224
|
- providerSort: "throughput" | "price" | "latency" \u2014 opt-in OpenRouter provider routing. Defaults to OpenRouter's load-balanced choice.
|
|
225
225
|
- providerOrder: ordered list of provider slugs (up to 8). Try these providers first before falling back. Useful for steering around an overloaded provider for a single model.
|
|
226
226
|
- fallbackModels: ordered list of model ids (up to 5). OpenRouter automatically retries the request against the next id when the primary is unavailable. Use sparingly \u2014 a benchmark should usually test the model you asked for, not a substitute.
|
|
227
|
-
- debug: When true, each result includes a \`debug\` field with the raw upstream finish_reason, error message, provider
|
|
227
|
+
- debug: When true, each result includes a \`debug\` field with the raw upstream finish_reason, error message, \`providerName\` (OpenRouter routing/fulfillment provider \u2014 can differ from the publisher, e.g. an anthropic/* model served via Google Vertex), \`modelPublisher\` (derived from the canonical id prefix \u2014 e.g. "anthropic", "x-ai"), refusal, and usage. Use to diagnose "missing assistant text" without re-running.
|
|
228
228
|
|
|
229
229
|
Results (live): each result carries modelId (the id you passed), resolvedModelId (canonical id, present when the input was an alias), ok, response, latencyMs, tokens { prompt, completion }, cost (USD; live from OpenRouter when available, else estimated from cached pricing), and truncated=true when finish_reason is "length". On failure, results include \`error\` (free-form) plus \`failureReason\` ("insufficient_credits" | "model_unavailable" | "rate_limited" | "capacity" | "timeout" | "invalid_request" | "unknown") so callers can pick a retry strategy without parsing the error string. \`capacity\` indicates the provider is overloaded \u2014 apply a longer backoff or set \`fallbackModels\` and retry. When \`debug: true\` is set, each result also carries a \`debug\` block with the upstream provider's diagnostic fields.
|
|
230
230
|
|
|
@@ -245,13 +245,16 @@ var PARAM_DESCRIPTIONS = {
|
|
|
245
245
|
excludeFree: `When true, exclude models with id ending in ':free'. Useful for sortBy=price (which would otherwise be dominated by free-tier preview models) and when you want a paid SLA. Default false.`,
|
|
246
246
|
requireKeywordMatch: `When true, suppress weak vector-only results from semantic queries. If no candidate has a BM25 keyword hit, returns an empty page with meta.confidence='low' and meta.lowConfidenceReason \u2014 instead of returning misleading nearest-neighbor matches. Filter-only queries (sortBy=created or sortBy=price without q) ignore this flag. Default false.`,
|
|
247
247
|
expectedPromptTokens: `Expected number of prompt tokens for dryRun cost estimation. When set, overrides the heuristic that counts characters from the literal \`prompt\` string \u2014 use this for capacity planning ("what would 6000-token reviews cost?") without pasting filler. If both are omitted, the prompt string is tokenized at ~4 chars/token.`,
|
|
248
|
-
expectedCompletionTokens: `Expected number of completion tokens for cost estimation (default: 256). Typical ranges: 100-500 for quick tests, 1000-2000 for code generation, 4000+ for long-form content. This is a heuristic \u2014 actual billed tokens may differ
|
|
248
|
+
expectedCompletionTokens: `Expected number of completion tokens for cost estimation (default: 256). Typical ranges: 100-500 for quick tests, 1000-2000 for code generation, 4000+ for long-form content. This is a heuristic \u2014 actual billed tokens may differ.`,
|
|
249
|
+
minPrice: `Minimum effective prompt price in USD per million tokens. Matches the basis exposed in \`pricing.effectivePromptPerMillion\` and \`pageInfo.priceSortBasis\` \u2014 token price plus per-request fees scaled to per-million, so a model with $0.30/M tokens and a $0.30 per-request fee evaluates as $0.60/M effective. Models with no resolvable price (zero-token, no per-request fee, non-\`:free\` id) are excluded when this bound is set.`,
|
|
250
|
+
maxPrice: `Maximum effective prompt price in USD per million tokens. Matches the basis exposed in \`pricing.effectivePromptPerMillion\` and \`pageInfo.priceSortBasis\` \u2014 token price plus per-request fees scaled to per-million, so a model with $0.30/M tokens and a $0.30 per-request fee evaluates as $0.60/M effective and is excluded by \`maxPrice: 0.55\`. Models with no resolvable price (zero-token, no per-request fee, non-\`:free\` id) are excluded when this bound is set.`
|
|
249
251
|
};
|
|
250
252
|
var SITE = {
|
|
251
253
|
nav: {
|
|
252
254
|
brand: "index9",
|
|
253
255
|
tools: "Tools",
|
|
254
256
|
howItWorks: "How it works",
|
|
257
|
+
caseStudy: "Case study",
|
|
255
258
|
install: "Install",
|
|
256
259
|
faq: "FAQ",
|
|
257
260
|
github: "GitHub",
|
|
@@ -259,19 +262,18 @@ var SITE = {
|
|
|
259
262
|
installCta: "Install"
|
|
260
263
|
},
|
|
261
264
|
hero: {
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
subtitle: "An MCP server your coding assistant uses to search, compare, and live-test 300+ models for the task you're on.",
|
|
265
|
+
title: "Pick AI models from live data, not your assistant's memory.",
|
|
266
|
+
subtitle: "An MCP server with five tools for Claude Code, Cursor, VS Code, and Codex. Search, compare, cost-model, and live-test 300+ models.",
|
|
265
267
|
pricingNote: "Free. You only pay OpenRouter for live model calls.",
|
|
266
268
|
seeHowItWorks: "See a real session",
|
|
267
269
|
updatedBadge: "OpenRouter data \xB7 refreshed ",
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
270
|
+
toolList: [
|
|
271
|
+
{ name: "list_facets", role: "vocabulary" },
|
|
272
|
+
{ name: "find_models", role: "search & filter" },
|
|
273
|
+
{ name: "get_models", role: "full specs" },
|
|
274
|
+
{ name: "compare_models", role: "side-by-side diff" },
|
|
275
|
+
{ name: "test_model", role: "live inference" }
|
|
276
|
+
]
|
|
275
277
|
},
|
|
276
278
|
problem: {
|
|
277
279
|
label: "Why this exists",
|
|
@@ -304,70 +306,77 @@ var SITE = {
|
|
|
304
306
|
]
|
|
305
307
|
},
|
|
306
308
|
caseStudy: {
|
|
307
|
-
label: "
|
|
309
|
+
label: "Real session",
|
|
308
310
|
heading: "A real session, not a mockup",
|
|
309
|
-
subheading: "
|
|
311
|
+
subheading: "Claude Sonnet 4.6 driven through the index9 MCP server, picking a model for a TypeScript code-review bot. Real prompt, real tool calls, real verdict.",
|
|
310
312
|
prompt: {
|
|
311
313
|
title: "The prompt",
|
|
312
|
-
body: "Pick a model for a TypeScript code-review bot that runs on every PR. I want quality without paying frontier rates
|
|
314
|
+
body: "Pick a model for a TypeScript code-review bot that runs on every PR. I want real quality without paying frontier rates. Quote model ids verbatim from the tool responses."
|
|
313
315
|
},
|
|
314
316
|
toolCalls: {
|
|
315
317
|
title: "What the assistant did",
|
|
316
|
-
subtitle: "
|
|
318
|
+
subtitle: "4 calls, 42s",
|
|
317
319
|
calls: [
|
|
318
|
-
{ tool: "find_models", params: "newest first", note: "skip stale training picks" },
|
|
319
320
|
{
|
|
320
321
|
tool: "find_models",
|
|
321
|
-
params: "
|
|
322
|
+
params: "sortBy=created, function_calling + structured_output",
|
|
323
|
+
note: "skip stale training picks"
|
|
324
|
+
},
|
|
325
|
+
{
|
|
326
|
+
tool: "find_models",
|
|
327
|
+
params: "code review, maxPrice=$5/M, minContext=64K",
|
|
322
328
|
note: "task fit"
|
|
323
329
|
},
|
|
324
|
-
{ tool: "find_models", params: "max $2/M, every-PR budget", note: "rule out frontier" },
|
|
325
|
-
{ tool: "get_models", params: "8 candidates", note: "metadata lookup" },
|
|
326
330
|
{
|
|
327
331
|
tool: "compare_models",
|
|
328
|
-
params: "4 finalists,
|
|
329
|
-
note: "per-PR cost
|
|
332
|
+
params: "4 finalists, 3,000 prompt + 800 completion",
|
|
333
|
+
note: "per-PR cost diff"
|
|
330
334
|
},
|
|
331
|
-
{ tool: "test_model", params: "dry-run \xD7 4", note: "cost estimate" },
|
|
332
335
|
{
|
|
333
336
|
tool: "test_model",
|
|
334
|
-
params: "
|
|
335
|
-
note: "
|
|
337
|
+
params: "dry-run \xD7 4, same token budget",
|
|
338
|
+
note: "cost confirmation"
|
|
336
339
|
}
|
|
337
340
|
]
|
|
338
341
|
},
|
|
339
|
-
consideredTitle: "
|
|
340
|
-
consideredSubtitle: "
|
|
342
|
+
consideredTitle: "Candidates the session evaluated",
|
|
343
|
+
consideredSubtitle: "Lifted from the tool responses. Per-PR cost is the dry-run test_model output for a 3,000 token diff and an 800 token review.",
|
|
341
344
|
consideredRows: [
|
|
342
345
|
{
|
|
343
|
-
id: "
|
|
344
|
-
age: "
|
|
346
|
+
id: "anthropic/claude-opus-4.7-fast",
|
|
347
|
+
age: "5d ago",
|
|
345
348
|
decision: "skip",
|
|
346
|
-
reason: "
|
|
349
|
+
reason: "$30/M input, filtered out by the maxPrice constraint on the second find_models call"
|
|
350
|
+
},
|
|
351
|
+
{
|
|
352
|
+
id: "mistralai/devstral-medium",
|
|
353
|
+
age: "10mo ago",
|
|
354
|
+
decision: "tested",
|
|
355
|
+
reason: "$0.40/M input, completion-heavy at $2/M, $0.0028 per PR"
|
|
347
356
|
},
|
|
348
357
|
{
|
|
349
|
-
id: "
|
|
350
|
-
age: "
|
|
358
|
+
id: "qwen/qwen3-coder",
|
|
359
|
+
age: "10mo ago",
|
|
351
360
|
decision: "tested",
|
|
352
|
-
reason: "
|
|
361
|
+
reason: "$0.22/M input, 1M context but no file_input, $0.0021 per PR"
|
|
353
362
|
},
|
|
354
363
|
{
|
|
355
|
-
id: "
|
|
356
|
-
age: "
|
|
364
|
+
id: "google/gemini-3.1-flash-lite",
|
|
365
|
+
age: "1w ago",
|
|
357
366
|
decision: "tested",
|
|
358
|
-
reason: "
|
|
367
|
+
reason: "$0.25/M input, newest of the shortlist, adds reasoning and vision, $0.00195 per PR"
|
|
359
368
|
},
|
|
360
369
|
{
|
|
361
|
-
id: "
|
|
362
|
-
age: "
|
|
370
|
+
id: "mistralai/codestral-2508",
|
|
371
|
+
age: "9mo ago",
|
|
363
372
|
decision: "shortlisted",
|
|
364
|
-
reason: "
|
|
373
|
+
reason: "$0.30/M input, Mistral's coding-specific model, $0.00162 per PR"
|
|
365
374
|
}
|
|
366
375
|
],
|
|
367
376
|
verdict: {
|
|
368
377
|
title: "The pick",
|
|
369
|
-
model: "
|
|
370
|
-
body: "
|
|
378
|
+
model: "mistralai/codestral-2508",
|
|
379
|
+
body: "Lowest realistic per-PR cost at $0.00162 on a 3,000 token diff and an 800 token review. Mistral's coding-specific model, structured output, file input for diffs, 256K context. About 100\xD7 cheaper on input than running claude-opus-4.7-fast on every commit."
|
|
371
380
|
}
|
|
372
381
|
},
|
|
373
382
|
toolsSection: {
|
|
@@ -832,6 +841,7 @@ var TestFailureReasonSchema = z6.enum([
|
|
|
832
841
|
var TestDebugInfoSchema = z6.object({
|
|
833
842
|
upstreamId: z6.string().optional(),
|
|
834
843
|
providerName: z6.string().optional(),
|
|
844
|
+
modelPublisher: z6.string().optional(),
|
|
835
845
|
finishReason: z6.string().optional(),
|
|
836
846
|
upstreamError: z6.string().optional(),
|
|
837
847
|
refusal: z6.string().optional(),
|
|
@@ -1211,8 +1221,8 @@ async function createServer() {
|
|
|
1211
1221
|
sortOrder: z7.enum(["asc", "desc"]).optional().describe("Sort order. Defaults by sortBy."),
|
|
1212
1222
|
createdAfter: z7.string().optional().describe("Lower bound for model created timestamp."),
|
|
1213
1223
|
createdBefore: z7.string().optional().describe("Upper bound for model created timestamp."),
|
|
1214
|
-
minPrice: z7.number().min(0).optional().describe(
|
|
1215
|
-
maxPrice: z7.number().min(0).optional().describe(
|
|
1224
|
+
minPrice: z7.number().min(0).optional().describe(PARAM_DESCRIPTIONS.minPrice),
|
|
1225
|
+
maxPrice: z7.number().min(0).optional().describe(PARAM_DESCRIPTIONS.maxPrice),
|
|
1216
1226
|
minContext: z7.number().int().min(1).optional().describe("Minimum context window in tokens."),
|
|
1217
1227
|
capabilitiesAll: z7.array(z7.enum(CAPABILITIES)).optional().describe(PARAM_DESCRIPTIONS.capabilitiesAll),
|
|
1218
1228
|
capabilitiesAny: z7.array(z7.enum(CAPABILITIES)).optional().describe(PARAM_DESCRIPTIONS.capabilitiesAny),
|
package/manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@index9/mcp",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.5.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"tsup": "^8.5.1",
|
|
29
29
|
"typescript": "6.0.3",
|
|
30
30
|
"vitest": "^4.1.6",
|
|
31
|
-
"@index9/core": "2.
|
|
31
|
+
"@index9/core": "2.8.0"
|
|
32
32
|
},
|
|
33
33
|
"engines": {
|
|
34
34
|
"node": ">=20"
|