@index9/mcp 6.5.3 → 6.5.5
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 +183 -207
- package/manifest.json +1 -1
- package/package.json +1 -1
- package/server.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -262,8 +262,9 @@ var SITE = {
|
|
|
262
262
|
installCta: "Install"
|
|
263
263
|
},
|
|
264
264
|
hero: {
|
|
265
|
-
title: "
|
|
266
|
-
|
|
265
|
+
title: "Live model catalog for coding assistants",
|
|
266
|
+
titleLines: ["Live model catalog", "for coding assistants"],
|
|
267
|
+
subtitle: "MCP tools for Claude Code, Cursor, VS Code, and Codex to search, compare, cost-model, and live-test 300+ models.",
|
|
267
268
|
pricingNote: "Free to install. Live tests use your OpenRouter key.",
|
|
268
269
|
seeHowItWorks: "See a real session",
|
|
269
270
|
updatedBadge: "OpenRouter data \xB7 refreshed ",
|
|
@@ -277,11 +278,11 @@ var SITE = {
|
|
|
277
278
|
},
|
|
278
279
|
problem: {
|
|
279
280
|
label: "Why this exists",
|
|
280
|
-
heading: "Your assistant
|
|
281
|
+
heading: "Your assistant has no live model catalog",
|
|
281
282
|
body: [
|
|
282
|
-
|
|
283
|
-
"
|
|
284
|
-
|
|
283
|
+
"New models ship weekly. Pricing, aliases, and capabilities change with them.",
|
|
284
|
+
"With no catalog to query, it uses training-time memory or web snippets. Pricing, context limits, and model ids in the answer may be wrong.",
|
|
285
|
+
`Index9 caches ${MODEL_COUNT} models, refreshes every 30 minutes, and exposes the catalog as five MCP tools in your editor.`
|
|
285
286
|
]
|
|
286
287
|
},
|
|
287
288
|
howItWorks: {
|
|
@@ -292,7 +293,7 @@ var SITE = {
|
|
|
292
293
|
{
|
|
293
294
|
number: "1",
|
|
294
295
|
title: "You ask in chat",
|
|
295
|
-
body: '"Pick the
|
|
296
|
+
body: '"Pick a model for the support agent in our backend: real quality on 4k-token threads at ~30k calls a day, without frontier per-token rates."'
|
|
296
297
|
},
|
|
297
298
|
{
|
|
298
299
|
number: "2",
|
|
@@ -309,76 +310,13 @@ var SITE = {
|
|
|
309
310
|
caseStudy: {
|
|
310
311
|
label: "Real session",
|
|
311
312
|
heading: "A real session, not a mockup",
|
|
312
|
-
subheading: "
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
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."
|
|
316
|
-
},
|
|
317
|
-
toolCalls: {
|
|
318
|
-
title: "What the assistant did",
|
|
319
|
-
subtitle: "4 calls, 42s",
|
|
320
|
-
calls: [
|
|
321
|
-
{
|
|
322
|
-
tool: "find_models",
|
|
323
|
-
params: "sortBy=created, function_calling + structured_output",
|
|
324
|
-
note: "skip stale training picks"
|
|
325
|
-
},
|
|
326
|
-
{
|
|
327
|
-
tool: "find_models",
|
|
328
|
-
params: "code review, maxPrice=$5/M, minContext=64K",
|
|
329
|
-
note: "task fit"
|
|
330
|
-
},
|
|
331
|
-
{
|
|
332
|
-
tool: "compare_models",
|
|
333
|
-
params: "4 finalists, 3,000 prompt + 800 completion",
|
|
334
|
-
note: "per-PR cost diff"
|
|
335
|
-
},
|
|
336
|
-
{
|
|
337
|
-
tool: "test_model",
|
|
338
|
-
params: "dry-run \xD7 4, same token budget",
|
|
339
|
-
note: "cost confirmation"
|
|
340
|
-
}
|
|
341
|
-
]
|
|
342
|
-
},
|
|
313
|
+
subheading: "Picking a model for a customer-support agent: live tool trace and measured verdict.",
|
|
314
|
+
promptTitle: "The ask",
|
|
315
|
+
toolCallsTitle: "What the assistant did",
|
|
343
316
|
consideredTitle: "Candidates evaluated",
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
id: "anthropic/claude-opus-4.7-fast",
|
|
348
|
-
age: "5d ago",
|
|
349
|
-
decision: "skip",
|
|
350
|
-
reason: "$30/M input, above the maxPrice filter"
|
|
351
|
-
},
|
|
352
|
-
{
|
|
353
|
-
id: "mistralai/devstral-medium",
|
|
354
|
-
age: "10mo ago",
|
|
355
|
-
decision: "tested",
|
|
356
|
-
reason: "$0.40/M input, $2/M output, $0.0028 per PR"
|
|
357
|
-
},
|
|
358
|
-
{
|
|
359
|
-
id: "qwen/qwen3-coder",
|
|
360
|
-
age: "10mo ago",
|
|
361
|
-
decision: "tested",
|
|
362
|
-
reason: "$0.22/M input, 1M context, no file_input, $0.0021 per PR"
|
|
363
|
-
},
|
|
364
|
-
{
|
|
365
|
-
id: "google/gemini-3.1-flash-lite",
|
|
366
|
-
age: "1w ago",
|
|
367
|
-
decision: "tested",
|
|
368
|
-
reason: "$0.25/M input, newest finalist, reasoning + vision, $0.00195 per PR"
|
|
369
|
-
},
|
|
370
|
-
{
|
|
371
|
-
id: "mistralai/codestral-2508",
|
|
372
|
-
age: "9mo ago",
|
|
373
|
-
decision: "shortlisted",
|
|
374
|
-
reason: "$0.30/M input, coding-specific, $0.00162 per PR"
|
|
375
|
-
}
|
|
376
|
-
],
|
|
377
|
-
verdict: {
|
|
378
|
-
title: "The pick",
|
|
379
|
-
model: "mistralai/codestral-2508",
|
|
380
|
-
body: "$0.00162 per PR (3K diff + 800 review, dry-run). Coding-specific, structured output, file input, 256K context. About 100\xD7 cheaper on input than claude-opus-4.7-fast."
|
|
381
|
-
}
|
|
317
|
+
verdictTitle: "The pick",
|
|
318
|
+
capturedPrefix: "Captured ",
|
|
319
|
+
sourcePrefix: " \xB7 source "
|
|
382
320
|
},
|
|
383
321
|
toolsSection: {
|
|
384
322
|
label: "Tools",
|
|
@@ -451,7 +389,7 @@ var SITE = {
|
|
|
451
389
|
},
|
|
452
390
|
{
|
|
453
391
|
question: "Who is index9 for?",
|
|
454
|
-
answer: "Developers in Claude Code, Cursor, VS Code, or Codex who want model picks from live data, not training memory.",
|
|
392
|
+
answer: "Developers in Claude Code, Cursor, VS Code, or Codex who want model picks from live data, not training-time memory.",
|
|
455
393
|
link: null
|
|
456
394
|
},
|
|
457
395
|
{
|
|
@@ -552,7 +490,7 @@ var SITE = {
|
|
|
552
490
|
},
|
|
553
491
|
footer: {
|
|
554
492
|
brand: "index9",
|
|
555
|
-
tagline: "Live model
|
|
493
|
+
tagline: "Live model catalog, via MCP.",
|
|
556
494
|
copyrightSuffix: "index9",
|
|
557
495
|
github: "GitHub",
|
|
558
496
|
privacy: "Privacy",
|
|
@@ -767,56 +705,94 @@ var ListFacetsToolResultSchema = FacetsResponseSchema.extend({
|
|
|
767
705
|
_index9: Index9MetaSchema
|
|
768
706
|
});
|
|
769
707
|
|
|
770
|
-
// ../core/dist/schemas/
|
|
708
|
+
// ../core/dist/schemas/case-study.js
|
|
771
709
|
import { z as z6 } from "zod";
|
|
772
|
-
var
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
710
|
+
var CaseStudyDecisionSchema = z6.enum(["shortlisted", "tested", "selected"]);
|
|
711
|
+
var CaseStudyToolCallSchema = z6.object({
|
|
712
|
+
tool: z6.string(),
|
|
713
|
+
params: z6.string()
|
|
714
|
+
}).strict();
|
|
715
|
+
var CaseStudyCandidateSchema = z6.object({
|
|
716
|
+
id: z6.string(),
|
|
717
|
+
createdAt: z6.string().nullable(),
|
|
718
|
+
decision: CaseStudyDecisionSchema,
|
|
719
|
+
promptPerMillion: z6.number().nullable(),
|
|
720
|
+
completionPerMillion: z6.number().nullable(),
|
|
721
|
+
perPromptCostUsd: z6.number().nullable()
|
|
722
|
+
}).strict();
|
|
723
|
+
var CaseStudyVerdictSchema = z6.object({
|
|
724
|
+
model: z6.string().nullable(),
|
|
725
|
+
body: z6.string()
|
|
726
|
+
}).strict();
|
|
727
|
+
var displayPromptBody = z6.string().max(220).refine((s) => !s.includes("\n"), "promptBody must be a single line").refine((s) => !/walk me through/i.test(s), "promptBody must not include eval harness steps").refine((s) => !/##\s*recommendation/i.test(s), "promptBody must not include extraction template");
|
|
728
|
+
var CaseStudySchema = z6.object({
|
|
729
|
+
capturedAt: z6.string(),
|
|
730
|
+
generatedAt: z6.string(),
|
|
731
|
+
sourceRun: z6.string(),
|
|
732
|
+
evaluatorModelId: z6.string(),
|
|
733
|
+
promptId: z6.string(),
|
|
734
|
+
promptBody: displayPromptBody,
|
|
735
|
+
promptContext: z6.string().max(80).optional(),
|
|
736
|
+
totalLatencyMs: z6.number().int(),
|
|
737
|
+
totalCostUsd: z6.number().nullable(),
|
|
738
|
+
toolCallCount: z6.number().int(),
|
|
739
|
+
candidateCount: z6.number().int(),
|
|
740
|
+
selectedModelId: z6.string().nullable(),
|
|
741
|
+
toolCalls: z6.array(CaseStudyToolCallSchema),
|
|
742
|
+
candidates: z6.array(CaseStudyCandidateSchema),
|
|
743
|
+
verdict: CaseStudyVerdictSchema
|
|
744
|
+
}).strict();
|
|
745
|
+
|
|
746
|
+
// ../core/dist/schemas/test.js
|
|
747
|
+
import { z as z7 } from "zod";
|
|
748
|
+
var ResponseFormatSchema = z7.object({
|
|
749
|
+
type: z7.string().min(1)
|
|
750
|
+
}).catchall(z7.unknown()).optional();
|
|
751
|
+
var ProviderSortSchema = z7.enum(["throughput", "price", "latency"]);
|
|
752
|
+
var TestRequestSchema = z7.object({
|
|
753
|
+
prompt: z7.string().min(1).optional(),
|
|
754
|
+
userContent: z7.array(UserContentPartSchema).min(1).optional(),
|
|
755
|
+
dryRun: z7.boolean().optional(),
|
|
756
|
+
expectedPromptTokens: z7.number().int().positive().optional(),
|
|
757
|
+
expectedCompletionTokens: z7.number().int().positive().optional(),
|
|
758
|
+
models: z7.array(z7.string().min(1)).min(1, "Models are required").max(LIMITS.testModelsMax, `Models must contain between 1 and ${LIMITS.testModelsMax} model IDs`),
|
|
759
|
+
timeoutMs: z7.number().int().positive().optional(),
|
|
760
|
+
maxTokens: z7.number().int().positive().optional(),
|
|
761
|
+
systemPrompt: z7.string().min(1).optional(),
|
|
762
|
+
temperature: z7.number().min(0).max(2).optional(),
|
|
763
|
+
topP: z7.number().gt(0).lte(1).optional(),
|
|
764
|
+
seed: z7.number().int().optional(),
|
|
789
765
|
responseFormat: ResponseFormatSchema,
|
|
790
|
-
enforceJson:
|
|
791
|
-
retries:
|
|
766
|
+
enforceJson: z7.boolean().optional(),
|
|
767
|
+
retries: z7.number().int().min(0).max(3).optional(),
|
|
792
768
|
// Use OpenRouter's SSE streaming endpoint so capacity/refusal errors
|
|
793
769
|
// surface in ~1s instead of waiting the full per-model timeout for an
|
|
794
770
|
// empty 200 OK. Cost/tokens are still returned via stream_options.
|
|
795
|
-
stream:
|
|
771
|
+
stream: z7.boolean().optional(),
|
|
796
772
|
// First-token deadline (streaming only). If the upstream sends no
|
|
797
773
|
// delta within this window, abort the request. Defaults to 10s when
|
|
798
774
|
// streaming. Ignored when stream=false.
|
|
799
|
-
firstTokenTimeoutMs:
|
|
775
|
+
firstTokenTimeoutMs: z7.number().int().positive().optional(),
|
|
800
776
|
// Forwards as `provider.sort` to OpenRouter — opt into routing toward
|
|
801
777
|
// higher-throughput providers when running benchmarks.
|
|
802
778
|
providerSort: ProviderSortSchema.optional(),
|
|
803
779
|
// Forwards as `provider.order` — try these provider slugs first in the
|
|
804
780
|
// given order before falling back. Capped to stay within reasonable
|
|
805
781
|
// limits and prevent abuse.
|
|
806
|
-
providerOrder:
|
|
782
|
+
providerOrder: z7.array(z7.string().min(1)).min(1).max(8).optional(),
|
|
807
783
|
// Forwards as the top-level `models` array (NOT `model`). OpenRouter
|
|
808
784
|
// tries each in order if the primary is unavailable. Different intent
|
|
809
785
|
// from providerOrder, which routes within a single model.
|
|
810
|
-
fallbackModels:
|
|
786
|
+
fallbackModels: z7.array(z7.string().min(1)).min(1).max(5).optional(),
|
|
811
787
|
// When true, attach a `debug` field on each result with the raw
|
|
812
788
|
// upstream finish_reason, error message, provider name, refusal, and
|
|
813
789
|
// usage. Used to diagnose "missing assistant text" without re-running.
|
|
814
|
-
debug:
|
|
790
|
+
debug: z7.boolean().optional()
|
|
815
791
|
}).strict().superRefine((data, ctx) => {
|
|
816
792
|
if (data.dryRun === true) {
|
|
817
793
|
if (!data.prompt && data.expectedPromptTokens === void 0) {
|
|
818
794
|
ctx.addIssue({
|
|
819
|
-
code:
|
|
795
|
+
code: z7.ZodIssueCode.custom,
|
|
820
796
|
message: "dryRun requires either prompt or expectedPromptTokens",
|
|
821
797
|
path: ["prompt"]
|
|
822
798
|
});
|
|
@@ -825,24 +801,24 @@ var TestRequestSchema = z6.object({
|
|
|
825
801
|
}
|
|
826
802
|
if (!data.prompt && !data.userContent?.length) {
|
|
827
803
|
ctx.addIssue({
|
|
828
|
-
code:
|
|
804
|
+
code: z7.ZodIssueCode.custom,
|
|
829
805
|
message: "Prompt or userContent is required",
|
|
830
806
|
path: ["prompt"]
|
|
831
807
|
});
|
|
832
808
|
}
|
|
833
809
|
});
|
|
834
|
-
var UsageTokensSchema =
|
|
835
|
-
prompt:
|
|
836
|
-
completion:
|
|
810
|
+
var UsageTokensSchema = z7.object({
|
|
811
|
+
prompt: z7.number().min(0),
|
|
812
|
+
completion: z7.number().min(0)
|
|
837
813
|
});
|
|
838
|
-
var TestPricingUsedSchema =
|
|
839
|
-
promptPerToken:
|
|
840
|
-
completionPerToken:
|
|
841
|
-
promptPerMillion:
|
|
842
|
-
completionPerMillion:
|
|
843
|
-
requestUsd:
|
|
814
|
+
var TestPricingUsedSchema = z7.object({
|
|
815
|
+
promptPerToken: z7.number().nullable().optional(),
|
|
816
|
+
completionPerToken: z7.number().nullable().optional(),
|
|
817
|
+
promptPerMillion: z7.number().nullable().optional(),
|
|
818
|
+
completionPerMillion: z7.number().nullable().optional(),
|
|
819
|
+
requestUsd: z7.number().nullable().optional()
|
|
844
820
|
});
|
|
845
|
-
var TestFailureReasonSchema =
|
|
821
|
+
var TestFailureReasonSchema = z7.enum([
|
|
846
822
|
"insufficient_credits",
|
|
847
823
|
"model_unavailable",
|
|
848
824
|
"rate_limited",
|
|
@@ -854,86 +830,86 @@ var TestFailureReasonSchema = z6.enum([
|
|
|
854
830
|
"invalid_request",
|
|
855
831
|
"unknown"
|
|
856
832
|
]);
|
|
857
|
-
var TestDebugInfoSchema =
|
|
858
|
-
upstreamId:
|
|
859
|
-
providerName:
|
|
860
|
-
modelPublisher:
|
|
861
|
-
finishReason:
|
|
862
|
-
upstreamError:
|
|
863
|
-
refusal:
|
|
864
|
-
hasToolCalls:
|
|
865
|
-
usage:
|
|
866
|
-
promptTokens:
|
|
867
|
-
completionTokens:
|
|
868
|
-
totalTokens:
|
|
833
|
+
var TestDebugInfoSchema = z7.object({
|
|
834
|
+
upstreamId: z7.string().optional(),
|
|
835
|
+
providerName: z7.string().optional(),
|
|
836
|
+
modelPublisher: z7.string().optional(),
|
|
837
|
+
finishReason: z7.string().optional(),
|
|
838
|
+
upstreamError: z7.string().optional(),
|
|
839
|
+
refusal: z7.string().optional(),
|
|
840
|
+
hasToolCalls: z7.boolean().optional(),
|
|
841
|
+
usage: z7.object({
|
|
842
|
+
promptTokens: z7.number().optional(),
|
|
843
|
+
completionTokens: z7.number().optional(),
|
|
844
|
+
totalTokens: z7.number().optional()
|
|
869
845
|
}).optional()
|
|
870
846
|
});
|
|
871
|
-
var TestModelMetadataSchema =
|
|
872
|
-
id:
|
|
873
|
-
name:
|
|
874
|
-
created:
|
|
875
|
-
createdAt:
|
|
847
|
+
var TestModelMetadataSchema = z7.object({
|
|
848
|
+
id: z7.string(),
|
|
849
|
+
name: z7.string(),
|
|
850
|
+
created: z7.number().nullable().optional(),
|
|
851
|
+
createdAt: z7.string().nullable().optional(),
|
|
876
852
|
pricingUsed: TestPricingUsedSchema.optional()
|
|
877
853
|
});
|
|
878
|
-
var TestResultSuccessSchema =
|
|
879
|
-
modelId:
|
|
880
|
-
resolvedModelId:
|
|
881
|
-
ok:
|
|
854
|
+
var TestResultSuccessSchema = z7.object({
|
|
855
|
+
modelId: z7.string(),
|
|
856
|
+
resolvedModelId: z7.string().optional(),
|
|
857
|
+
ok: z7.literal(true),
|
|
882
858
|
model: TestModelMetadataSchema,
|
|
883
|
-
response:
|
|
884
|
-
latencyMs:
|
|
859
|
+
response: z7.string(),
|
|
860
|
+
latencyMs: z7.number().min(0),
|
|
885
861
|
tokens: UsageTokensSchema,
|
|
886
|
-
cost:
|
|
887
|
-
truncated:
|
|
862
|
+
cost: z7.number().nullable().optional(),
|
|
863
|
+
truncated: z7.boolean().optional(),
|
|
888
864
|
debug: TestDebugInfoSchema.optional()
|
|
889
865
|
});
|
|
890
|
-
var TestResultFailureSchema =
|
|
891
|
-
modelId:
|
|
892
|
-
resolvedModelId:
|
|
893
|
-
ok:
|
|
866
|
+
var TestResultFailureSchema = z7.object({
|
|
867
|
+
modelId: z7.string(),
|
|
868
|
+
resolvedModelId: z7.string().optional(),
|
|
869
|
+
ok: z7.literal(false),
|
|
894
870
|
model: TestModelMetadataSchema,
|
|
895
|
-
error:
|
|
871
|
+
error: z7.string(),
|
|
896
872
|
failureReason: TestFailureReasonSchema.optional(),
|
|
897
|
-
latencyMs:
|
|
873
|
+
latencyMs: z7.number().min(0),
|
|
898
874
|
debug: TestDebugInfoSchema.optional()
|
|
899
875
|
});
|
|
900
|
-
var TestResultSchema =
|
|
876
|
+
var TestResultSchema = z7.discriminatedUnion("ok", [
|
|
901
877
|
TestResultSuccessSchema,
|
|
902
878
|
TestResultFailureSchema
|
|
903
879
|
]);
|
|
904
|
-
var TestEstimateResultSchema =
|
|
905
|
-
modelId:
|
|
906
|
-
resolvedModelId:
|
|
880
|
+
var TestEstimateResultSchema = z7.object({
|
|
881
|
+
modelId: z7.string(),
|
|
882
|
+
resolvedModelId: z7.string().optional(),
|
|
907
883
|
model: TestModelMetadataSchema,
|
|
908
884
|
tokens: UsageTokensSchema,
|
|
909
|
-
estimatedCost:
|
|
910
|
-
tokenCostUsd:
|
|
911
|
-
requestCostUsd:
|
|
912
|
-
totalCostUsd:
|
|
885
|
+
estimatedCost: z7.number().nullable().optional(),
|
|
886
|
+
tokenCostUsd: z7.number().nullable().optional(),
|
|
887
|
+
requestCostUsd: z7.number().nullable().optional(),
|
|
888
|
+
totalCostUsd: z7.number().nullable().optional(),
|
|
913
889
|
estimatedCostBasis: PricingBasisSchema.optional()
|
|
914
890
|
});
|
|
915
891
|
var TestResolutionFieldsSchema = {
|
|
916
|
-
missingIds:
|
|
917
|
-
resolvedAliases:
|
|
918
|
-
ambiguousAliases:
|
|
919
|
-
suggestions:
|
|
920
|
-
missingDiagnostics:
|
|
892
|
+
missingIds: z7.array(z7.string()).optional(),
|
|
893
|
+
resolvedAliases: z7.record(z7.string(), z7.string()).optional(),
|
|
894
|
+
ambiguousAliases: z7.record(z7.string(), z7.array(z7.string())).optional(),
|
|
895
|
+
suggestions: z7.record(z7.string(), z7.array(SuggestionEntrySchema)).optional(),
|
|
896
|
+
missingDiagnostics: z7.record(z7.string(), MissingModelDiagnosticSchema).optional()
|
|
921
897
|
};
|
|
922
|
-
var TestDryRunResponseSchema =
|
|
923
|
-
dryRun:
|
|
924
|
-
results:
|
|
925
|
-
disclaimer:
|
|
898
|
+
var TestDryRunResponseSchema = z7.object({
|
|
899
|
+
dryRun: z7.literal(true),
|
|
900
|
+
results: z7.array(TestEstimateResultSchema),
|
|
901
|
+
disclaimer: z7.string(),
|
|
926
902
|
...TestResolutionFieldsSchema
|
|
927
903
|
});
|
|
928
|
-
var TestLiveResponseSchema =
|
|
929
|
-
results:
|
|
904
|
+
var TestLiveResponseSchema = z7.object({
|
|
905
|
+
results: z7.array(TestResultSchema),
|
|
930
906
|
...TestResolutionFieldsSchema
|
|
931
907
|
});
|
|
932
|
-
var TestResponseSchema =
|
|
908
|
+
var TestResponseSchema = z7.union([TestDryRunResponseSchema, TestLiveResponseSchema]);
|
|
933
909
|
|
|
934
910
|
// src/server.ts
|
|
935
911
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
936
|
-
import { z as
|
|
912
|
+
import { z as z8 } from "zod";
|
|
937
913
|
|
|
938
914
|
// src/config.ts
|
|
939
915
|
var DEFAULT_BASE_URL = "https://index9.dev";
|
|
@@ -1230,22 +1206,22 @@ async function createServer() {
|
|
|
1230
1206
|
title: TOOLS.find_models.title,
|
|
1231
1207
|
description: TOOLS.find_models.description,
|
|
1232
1208
|
inputSchema: {
|
|
1233
|
-
q:
|
|
1234
|
-
limit:
|
|
1235
|
-
cursor:
|
|
1236
|
-
sortBy:
|
|
1237
|
-
sortOrder:
|
|
1238
|
-
createdAfter:
|
|
1239
|
-
createdBefore:
|
|
1240
|
-
minPrice:
|
|
1241
|
-
maxPrice:
|
|
1242
|
-
minContext:
|
|
1243
|
-
capabilitiesAll:
|
|
1244
|
-
capabilitiesAny:
|
|
1245
|
-
modality:
|
|
1246
|
-
provider:
|
|
1247
|
-
excludeFree:
|
|
1248
|
-
requireKeywordMatch:
|
|
1209
|
+
q: z8.string().min(1).optional().describe(PARAM_DESCRIPTIONS.q),
|
|
1210
|
+
limit: z8.number().int().min(1).max(100).default(20).describe("Page size (1-100, default 20)."),
|
|
1211
|
+
cursor: z8.string().min(1).optional().describe(PARAM_DESCRIPTIONS.cursor),
|
|
1212
|
+
sortBy: z8.enum(["relevance", "created", "price"]).default("relevance").describe(PARAM_DESCRIPTIONS.sortBy),
|
|
1213
|
+
sortOrder: z8.enum(["asc", "desc"]).optional().describe("Sort order. Defaults by sortBy."),
|
|
1214
|
+
createdAfter: z8.string().optional().describe("Lower bound for model created timestamp."),
|
|
1215
|
+
createdBefore: z8.string().optional().describe("Upper bound for model created timestamp."),
|
|
1216
|
+
minPrice: z8.number().min(0).optional().describe(PARAM_DESCRIPTIONS.minPrice),
|
|
1217
|
+
maxPrice: z8.number().min(0).optional().describe(PARAM_DESCRIPTIONS.maxPrice),
|
|
1218
|
+
minContext: z8.number().int().min(1).optional().describe("Minimum context window in tokens."),
|
|
1219
|
+
capabilitiesAll: z8.array(z8.enum(CAPABILITIES)).optional().describe(PARAM_DESCRIPTIONS.capabilitiesAll),
|
|
1220
|
+
capabilitiesAny: z8.array(z8.enum(CAPABILITIES)).optional().describe(PARAM_DESCRIPTIONS.capabilitiesAny),
|
|
1221
|
+
modality: z8.enum(OUTPUT_MODALITIES).optional().describe(PARAM_DESCRIPTIONS.modality),
|
|
1222
|
+
provider: z8.array(z8.string().min(1)).optional().describe(PARAM_DESCRIPTIONS.provider),
|
|
1223
|
+
excludeFree: z8.boolean().optional().describe(PARAM_DESCRIPTIONS.excludeFree),
|
|
1224
|
+
requireKeywordMatch: z8.boolean().optional().describe(PARAM_DESCRIPTIONS.requireKeywordMatch)
|
|
1249
1225
|
},
|
|
1250
1226
|
outputSchema: FindModelsToolResultSchema.shape,
|
|
1251
1227
|
annotations: { readOnlyHint: true }
|
|
@@ -1258,8 +1234,8 @@ async function createServer() {
|
|
|
1258
1234
|
title: TOOLS.get_models.title,
|
|
1259
1235
|
description: TOOLS.get_models.description,
|
|
1260
1236
|
inputSchema: {
|
|
1261
|
-
ids:
|
|
1262
|
-
maxDescriptionChars:
|
|
1237
|
+
ids: z8.array(z8.string().min(1)).min(1).max(100).describe("Model identifiers or aliases. Up to 100."),
|
|
1238
|
+
maxDescriptionChars: z8.number().int().min(0).max(2e3).optional().describe("Truncate descriptions to this many characters.")
|
|
1263
1239
|
},
|
|
1264
1240
|
outputSchema: GetModelsToolResultSchema.shape,
|
|
1265
1241
|
annotations: { readOnlyHint: true }
|
|
@@ -1272,13 +1248,13 @@ async function createServer() {
|
|
|
1272
1248
|
title: TOOLS.compare_models.title,
|
|
1273
1249
|
description: TOOLS.compare_models.description,
|
|
1274
1250
|
inputSchema: {
|
|
1275
|
-
ids:
|
|
1251
|
+
ids: z8.array(z8.string().min(1)).min(2).max(LIMITS.compareModelsMax).describe(
|
|
1276
1252
|
`Model identifiers or aliases to compare (2-${LIMITS.compareModelsMax}). Same alias formats as get_models.`
|
|
1277
1253
|
),
|
|
1278
|
-
expectedPromptTokens:
|
|
1254
|
+
expectedPromptTokens: z8.number().int().min(1).optional().describe(
|
|
1279
1255
|
"Optional. When set with expectedCompletionTokens, computes total per-call cost for each model and picks cheapestForRealisticWorkload \u2014 closes the gap where promptPerMillion alone misleads when prompt:completion price ratios diverge."
|
|
1280
1256
|
),
|
|
1281
|
-
expectedCompletionTokens:
|
|
1257
|
+
expectedCompletionTokens: z8.number().int().min(1).optional().describe(
|
|
1282
1258
|
"Optional. Pair with expectedPromptTokens to surface workloadCosts and cheapestForRealisticWorkload. Both must be set to enable workload costing."
|
|
1283
1259
|
)
|
|
1284
1260
|
},
|
|
@@ -1304,39 +1280,39 @@ async function createServer() {
|
|
|
1304
1280
|
title: TOOLS.test_model.title,
|
|
1305
1281
|
description: TOOLS.test_model.description,
|
|
1306
1282
|
inputSchema: {
|
|
1307
|
-
prompt:
|
|
1308
|
-
userContent:
|
|
1309
|
-
dryRun:
|
|
1283
|
+
prompt: z8.string().min(1).optional().describe("Prompt sent to each model."),
|
|
1284
|
+
userContent: z8.array(UserContentPartSchema).min(1).optional().describe("Multimodal user content. At least one of prompt or userContent required."),
|
|
1285
|
+
dryRun: z8.boolean().optional().describe(
|
|
1310
1286
|
"When true, returns estimated token usage and cost without calling OpenRouter (no API key required)."
|
|
1311
1287
|
),
|
|
1312
|
-
expectedPromptTokens:
|
|
1313
|
-
expectedCompletionTokens:
|
|
1314
|
-
models:
|
|
1315
|
-
timeoutMs:
|
|
1316
|
-
maxTokens:
|
|
1288
|
+
expectedPromptTokens: z8.number().int().min(1).optional().describe(PARAM_DESCRIPTIONS.expectedPromptTokens),
|
|
1289
|
+
expectedCompletionTokens: z8.number().int().min(1).optional().describe(PARAM_DESCRIPTIONS.expectedCompletionTokens),
|
|
1290
|
+
models: z8.array(z8.string().min(1)).min(1).max(LIMITS.testModelsMax).describe(`Model IDs to evaluate (1-${LIMITS.testModelsMax}).`),
|
|
1291
|
+
timeoutMs: z8.number().int().min(1).optional().describe("Per-model timeout in ms (default 15000, max 60000)."),
|
|
1292
|
+
maxTokens: z8.number().int().min(1).optional().describe(
|
|
1317
1293
|
"Completion token cap. For reasoning-capable models, set \u2265 2000 (or omit) \u2014 reasoning tokens count against this before visible output, and too-low caps cause finish_reason=length."
|
|
1318
1294
|
),
|
|
1319
|
-
systemPrompt:
|
|
1320
|
-
temperature:
|
|
1321
|
-
topP:
|
|
1322
|
-
seed:
|
|
1295
|
+
systemPrompt: z8.string().min(1).optional().describe("System instruction prepended to prompt."),
|
|
1296
|
+
temperature: z8.number().min(0).max(2).optional().describe("Sampling temperature (0-2)."),
|
|
1297
|
+
topP: z8.number().gt(0).max(1).optional().describe("Nucleus sampling (0-1]."),
|
|
1298
|
+
seed: z8.number().int().optional().describe("Seed for repeatable outputs."),
|
|
1323
1299
|
responseFormat: ResponseFormatSchema.describe(
|
|
1324
1300
|
"Structured output shape request forwarded to OpenRouter (e.g., { type: 'json_object' })."
|
|
1325
1301
|
),
|
|
1326
|
-
enforceJson:
|
|
1327
|
-
retries:
|
|
1328
|
-
stream:
|
|
1302
|
+
enforceJson: z8.boolean().optional().describe("When true, output must parse as JSON."),
|
|
1303
|
+
retries: z8.number().int().min(0).max(3).optional().describe("Retries for transient failures."),
|
|
1304
|
+
stream: z8.boolean().optional().describe(
|
|
1329
1305
|
"Use OpenRouter SSE streaming so capacity/refusal errors surface quickly. Defaults to false."
|
|
1330
1306
|
),
|
|
1331
|
-
firstTokenTimeoutMs:
|
|
1307
|
+
firstTokenTimeoutMs: z8.number().int().min(1).optional().describe("Streaming-only first-token deadline in ms. Defaults to 10000."),
|
|
1332
1308
|
providerSort: ProviderSortSchema.optional().describe(
|
|
1333
1309
|
'OpenRouter provider routing sort: "throughput", "price", or "latency".'
|
|
1334
1310
|
),
|
|
1335
|
-
providerOrder:
|
|
1336
|
-
fallbackModels:
|
|
1311
|
+
providerOrder: z8.array(z8.string().min(1)).min(1).max(8).optional().describe("Provider slugs to try first, in order. Up to 8."),
|
|
1312
|
+
fallbackModels: z8.array(z8.string().min(1)).min(1).max(5).optional().describe(
|
|
1337
1313
|
"Fallback model IDs OpenRouter may try if the primary is unavailable. Up to 5."
|
|
1338
1314
|
),
|
|
1339
|
-
debug:
|
|
1315
|
+
debug: z8.boolean().optional().describe(
|
|
1340
1316
|
"When true, include upstream finish_reason, provider, error, refusal, and usage."
|
|
1341
1317
|
)
|
|
1342
1318
|
},
|
package/manifest.json
CHANGED
package/package.json
CHANGED
package/server.json
CHANGED
|
@@ -7,13 +7,13 @@
|
|
|
7
7
|
"url": "https://github.com/index9-org/mcp",
|
|
8
8
|
"source": "github"
|
|
9
9
|
},
|
|
10
|
-
"version": "6.5.
|
|
10
|
+
"version": "6.5.5",
|
|
11
11
|
"packages": [
|
|
12
12
|
{
|
|
13
13
|
"registryType": "npm",
|
|
14
14
|
"registryBaseUrl": "https://registry.npmjs.org",
|
|
15
15
|
"identifier": "@index9/mcp",
|
|
16
|
-
"version": "6.5.
|
|
16
|
+
"version": "6.5.5",
|
|
17
17
|
"transport": {
|
|
18
18
|
"type": "stdio"
|
|
19
19
|
},
|