@index9/mcp 6.5.2 → 6.5.4
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 +176 -203
- package/manifest.json +1 -1
- package/package.json +1 -1
- package/server.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -262,8 +262,8 @@ var SITE = {
|
|
|
262
262
|
installCta: "Install"
|
|
263
263
|
},
|
|
264
264
|
hero: {
|
|
265
|
-
title: "Index9 helps coding assistants pick
|
|
266
|
-
subtitle: "MCP tools for Claude Code, Cursor, VS Code, and Codex
|
|
265
|
+
title: "Index9 helps coding assistants pick from live model data.",
|
|
266
|
+
subtitle: "MCP tools for Claude Code, Cursor, VS Code, and Codex to search, compare, cost-model, and live-test 300+ models.",
|
|
267
267
|
pricingNote: "Free to install. Live tests use your OpenRouter key.",
|
|
268
268
|
seeHowItWorks: "See a real session",
|
|
269
269
|
updatedBadge: "OpenRouter data \xB7 refreshed ",
|
|
@@ -279,9 +279,9 @@ var SITE = {
|
|
|
279
279
|
label: "Why this exists",
|
|
280
280
|
heading: "Your assistant's model knowledge is stale",
|
|
281
281
|
body: [
|
|
282
|
-
|
|
283
|
-
"Without live data, your assistant
|
|
284
|
-
"Index9
|
|
282
|
+
"New models ship every week. Prices, aliases, and capabilities change with them.",
|
|
283
|
+
"Without live data, your assistant falls back to training-time memory \u2014 usually a model that's been superseded by something cheaper or better-suited.",
|
|
284
|
+
"Index9 lets it check the live catalog before recommending."
|
|
285
285
|
]
|
|
286
286
|
},
|
|
287
287
|
howItWorks: {
|
|
@@ -309,76 +309,13 @@ var SITE = {
|
|
|
309
309
|
caseStudy: {
|
|
310
310
|
label: "Real session",
|
|
311
311
|
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
|
-
},
|
|
312
|
+
subheading: "A real eval run picking a model for a TypeScript code-review bot. Real prompt, real tool calls, real verdict.",
|
|
313
|
+
promptTitle: "The prompt",
|
|
314
|
+
toolCallsTitle: "What the assistant did",
|
|
343
315
|
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
|
-
}
|
|
316
|
+
verdictTitle: "The pick",
|
|
317
|
+
capturedPrefix: "Captured ",
|
|
318
|
+
sourcePrefix: " \xB7 source "
|
|
382
319
|
},
|
|
383
320
|
toolsSection: {
|
|
384
321
|
label: "Tools",
|
|
@@ -767,56 +704,92 @@ var ListFacetsToolResultSchema = FacetsResponseSchema.extend({
|
|
|
767
704
|
_index9: Index9MetaSchema
|
|
768
705
|
});
|
|
769
706
|
|
|
770
|
-
// ../core/dist/schemas/
|
|
707
|
+
// ../core/dist/schemas/case-study.js
|
|
771
708
|
import { z as z6 } from "zod";
|
|
772
|
-
var
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
709
|
+
var CaseStudyDecisionSchema = z6.enum(["shortlisted", "tested"]);
|
|
710
|
+
var CaseStudyToolCallSchema = z6.object({
|
|
711
|
+
tool: z6.string(),
|
|
712
|
+
params: z6.string()
|
|
713
|
+
}).strict();
|
|
714
|
+
var CaseStudyCandidateSchema = z6.object({
|
|
715
|
+
id: z6.string(),
|
|
716
|
+
createdAt: z6.string().nullable(),
|
|
717
|
+
decision: CaseStudyDecisionSchema,
|
|
718
|
+
promptPerMillion: z6.number().nullable(),
|
|
719
|
+
completionPerMillion: z6.number().nullable(),
|
|
720
|
+
perPromptCostUsd: z6.number().nullable()
|
|
721
|
+
}).strict();
|
|
722
|
+
var CaseStudyVerdictSchema = z6.object({
|
|
723
|
+
model: z6.string().nullable(),
|
|
724
|
+
body: z6.string()
|
|
725
|
+
}).strict();
|
|
726
|
+
var CaseStudySchema = z6.object({
|
|
727
|
+
capturedAt: z6.string(),
|
|
728
|
+
generatedAt: z6.string(),
|
|
729
|
+
sourceRun: z6.string(),
|
|
730
|
+
evaluatorModelId: z6.string(),
|
|
731
|
+
promptId: z6.string(),
|
|
732
|
+
promptBody: z6.string(),
|
|
733
|
+
totalLatencyMs: z6.number().int(),
|
|
734
|
+
totalCostUsd: z6.number().nullable(),
|
|
735
|
+
toolCallCount: z6.number().int(),
|
|
736
|
+
candidateCount: z6.number().int(),
|
|
737
|
+
selectedModelId: z6.string().nullable(),
|
|
738
|
+
toolCalls: z6.array(CaseStudyToolCallSchema),
|
|
739
|
+
candidates: z6.array(CaseStudyCandidateSchema),
|
|
740
|
+
verdict: CaseStudyVerdictSchema
|
|
741
|
+
}).strict();
|
|
742
|
+
|
|
743
|
+
// ../core/dist/schemas/test.js
|
|
744
|
+
import { z as z7 } from "zod";
|
|
745
|
+
var ResponseFormatSchema = z7.object({
|
|
746
|
+
type: z7.string().min(1)
|
|
747
|
+
}).catchall(z7.unknown()).optional();
|
|
748
|
+
var ProviderSortSchema = z7.enum(["throughput", "price", "latency"]);
|
|
749
|
+
var TestRequestSchema = z7.object({
|
|
750
|
+
prompt: z7.string().min(1).optional(),
|
|
751
|
+
userContent: z7.array(UserContentPartSchema).min(1).optional(),
|
|
752
|
+
dryRun: z7.boolean().optional(),
|
|
753
|
+
expectedPromptTokens: z7.number().int().positive().optional(),
|
|
754
|
+
expectedCompletionTokens: z7.number().int().positive().optional(),
|
|
755
|
+
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`),
|
|
756
|
+
timeoutMs: z7.number().int().positive().optional(),
|
|
757
|
+
maxTokens: z7.number().int().positive().optional(),
|
|
758
|
+
systemPrompt: z7.string().min(1).optional(),
|
|
759
|
+
temperature: z7.number().min(0).max(2).optional(),
|
|
760
|
+
topP: z7.number().gt(0).lte(1).optional(),
|
|
761
|
+
seed: z7.number().int().optional(),
|
|
789
762
|
responseFormat: ResponseFormatSchema,
|
|
790
|
-
enforceJson:
|
|
791
|
-
retries:
|
|
763
|
+
enforceJson: z7.boolean().optional(),
|
|
764
|
+
retries: z7.number().int().min(0).max(3).optional(),
|
|
792
765
|
// Use OpenRouter's SSE streaming endpoint so capacity/refusal errors
|
|
793
766
|
// surface in ~1s instead of waiting the full per-model timeout for an
|
|
794
767
|
// empty 200 OK. Cost/tokens are still returned via stream_options.
|
|
795
|
-
stream:
|
|
768
|
+
stream: z7.boolean().optional(),
|
|
796
769
|
// First-token deadline (streaming only). If the upstream sends no
|
|
797
770
|
// delta within this window, abort the request. Defaults to 10s when
|
|
798
771
|
// streaming. Ignored when stream=false.
|
|
799
|
-
firstTokenTimeoutMs:
|
|
772
|
+
firstTokenTimeoutMs: z7.number().int().positive().optional(),
|
|
800
773
|
// Forwards as `provider.sort` to OpenRouter — opt into routing toward
|
|
801
774
|
// higher-throughput providers when running benchmarks.
|
|
802
775
|
providerSort: ProviderSortSchema.optional(),
|
|
803
776
|
// Forwards as `provider.order` — try these provider slugs first in the
|
|
804
777
|
// given order before falling back. Capped to stay within reasonable
|
|
805
778
|
// limits and prevent abuse.
|
|
806
|
-
providerOrder:
|
|
779
|
+
providerOrder: z7.array(z7.string().min(1)).min(1).max(8).optional(),
|
|
807
780
|
// Forwards as the top-level `models` array (NOT `model`). OpenRouter
|
|
808
781
|
// tries each in order if the primary is unavailable. Different intent
|
|
809
782
|
// from providerOrder, which routes within a single model.
|
|
810
|
-
fallbackModels:
|
|
783
|
+
fallbackModels: z7.array(z7.string().min(1)).min(1).max(5).optional(),
|
|
811
784
|
// When true, attach a `debug` field on each result with the raw
|
|
812
785
|
// upstream finish_reason, error message, provider name, refusal, and
|
|
813
786
|
// usage. Used to diagnose "missing assistant text" without re-running.
|
|
814
|
-
debug:
|
|
787
|
+
debug: z7.boolean().optional()
|
|
815
788
|
}).strict().superRefine((data, ctx) => {
|
|
816
789
|
if (data.dryRun === true) {
|
|
817
790
|
if (!data.prompt && data.expectedPromptTokens === void 0) {
|
|
818
791
|
ctx.addIssue({
|
|
819
|
-
code:
|
|
792
|
+
code: z7.ZodIssueCode.custom,
|
|
820
793
|
message: "dryRun requires either prompt or expectedPromptTokens",
|
|
821
794
|
path: ["prompt"]
|
|
822
795
|
});
|
|
@@ -825,24 +798,24 @@ var TestRequestSchema = z6.object({
|
|
|
825
798
|
}
|
|
826
799
|
if (!data.prompt && !data.userContent?.length) {
|
|
827
800
|
ctx.addIssue({
|
|
828
|
-
code:
|
|
801
|
+
code: z7.ZodIssueCode.custom,
|
|
829
802
|
message: "Prompt or userContent is required",
|
|
830
803
|
path: ["prompt"]
|
|
831
804
|
});
|
|
832
805
|
}
|
|
833
806
|
});
|
|
834
|
-
var UsageTokensSchema =
|
|
835
|
-
prompt:
|
|
836
|
-
completion:
|
|
807
|
+
var UsageTokensSchema = z7.object({
|
|
808
|
+
prompt: z7.number().min(0),
|
|
809
|
+
completion: z7.number().min(0)
|
|
837
810
|
});
|
|
838
|
-
var TestPricingUsedSchema =
|
|
839
|
-
promptPerToken:
|
|
840
|
-
completionPerToken:
|
|
841
|
-
promptPerMillion:
|
|
842
|
-
completionPerMillion:
|
|
843
|
-
requestUsd:
|
|
811
|
+
var TestPricingUsedSchema = z7.object({
|
|
812
|
+
promptPerToken: z7.number().nullable().optional(),
|
|
813
|
+
completionPerToken: z7.number().nullable().optional(),
|
|
814
|
+
promptPerMillion: z7.number().nullable().optional(),
|
|
815
|
+
completionPerMillion: z7.number().nullable().optional(),
|
|
816
|
+
requestUsd: z7.number().nullable().optional()
|
|
844
817
|
});
|
|
845
|
-
var TestFailureReasonSchema =
|
|
818
|
+
var TestFailureReasonSchema = z7.enum([
|
|
846
819
|
"insufficient_credits",
|
|
847
820
|
"model_unavailable",
|
|
848
821
|
"rate_limited",
|
|
@@ -854,86 +827,86 @@ var TestFailureReasonSchema = z6.enum([
|
|
|
854
827
|
"invalid_request",
|
|
855
828
|
"unknown"
|
|
856
829
|
]);
|
|
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:
|
|
830
|
+
var TestDebugInfoSchema = z7.object({
|
|
831
|
+
upstreamId: z7.string().optional(),
|
|
832
|
+
providerName: z7.string().optional(),
|
|
833
|
+
modelPublisher: z7.string().optional(),
|
|
834
|
+
finishReason: z7.string().optional(),
|
|
835
|
+
upstreamError: z7.string().optional(),
|
|
836
|
+
refusal: z7.string().optional(),
|
|
837
|
+
hasToolCalls: z7.boolean().optional(),
|
|
838
|
+
usage: z7.object({
|
|
839
|
+
promptTokens: z7.number().optional(),
|
|
840
|
+
completionTokens: z7.number().optional(),
|
|
841
|
+
totalTokens: z7.number().optional()
|
|
869
842
|
}).optional()
|
|
870
843
|
});
|
|
871
|
-
var TestModelMetadataSchema =
|
|
872
|
-
id:
|
|
873
|
-
name:
|
|
874
|
-
created:
|
|
875
|
-
createdAt:
|
|
844
|
+
var TestModelMetadataSchema = z7.object({
|
|
845
|
+
id: z7.string(),
|
|
846
|
+
name: z7.string(),
|
|
847
|
+
created: z7.number().nullable().optional(),
|
|
848
|
+
createdAt: z7.string().nullable().optional(),
|
|
876
849
|
pricingUsed: TestPricingUsedSchema.optional()
|
|
877
850
|
});
|
|
878
|
-
var TestResultSuccessSchema =
|
|
879
|
-
modelId:
|
|
880
|
-
resolvedModelId:
|
|
881
|
-
ok:
|
|
851
|
+
var TestResultSuccessSchema = z7.object({
|
|
852
|
+
modelId: z7.string(),
|
|
853
|
+
resolvedModelId: z7.string().optional(),
|
|
854
|
+
ok: z7.literal(true),
|
|
882
855
|
model: TestModelMetadataSchema,
|
|
883
|
-
response:
|
|
884
|
-
latencyMs:
|
|
856
|
+
response: z7.string(),
|
|
857
|
+
latencyMs: z7.number().min(0),
|
|
885
858
|
tokens: UsageTokensSchema,
|
|
886
|
-
cost:
|
|
887
|
-
truncated:
|
|
859
|
+
cost: z7.number().nullable().optional(),
|
|
860
|
+
truncated: z7.boolean().optional(),
|
|
888
861
|
debug: TestDebugInfoSchema.optional()
|
|
889
862
|
});
|
|
890
|
-
var TestResultFailureSchema =
|
|
891
|
-
modelId:
|
|
892
|
-
resolvedModelId:
|
|
893
|
-
ok:
|
|
863
|
+
var TestResultFailureSchema = z7.object({
|
|
864
|
+
modelId: z7.string(),
|
|
865
|
+
resolvedModelId: z7.string().optional(),
|
|
866
|
+
ok: z7.literal(false),
|
|
894
867
|
model: TestModelMetadataSchema,
|
|
895
|
-
error:
|
|
868
|
+
error: z7.string(),
|
|
896
869
|
failureReason: TestFailureReasonSchema.optional(),
|
|
897
|
-
latencyMs:
|
|
870
|
+
latencyMs: z7.number().min(0),
|
|
898
871
|
debug: TestDebugInfoSchema.optional()
|
|
899
872
|
});
|
|
900
|
-
var TestResultSchema =
|
|
873
|
+
var TestResultSchema = z7.discriminatedUnion("ok", [
|
|
901
874
|
TestResultSuccessSchema,
|
|
902
875
|
TestResultFailureSchema
|
|
903
876
|
]);
|
|
904
|
-
var TestEstimateResultSchema =
|
|
905
|
-
modelId:
|
|
906
|
-
resolvedModelId:
|
|
877
|
+
var TestEstimateResultSchema = z7.object({
|
|
878
|
+
modelId: z7.string(),
|
|
879
|
+
resolvedModelId: z7.string().optional(),
|
|
907
880
|
model: TestModelMetadataSchema,
|
|
908
881
|
tokens: UsageTokensSchema,
|
|
909
|
-
estimatedCost:
|
|
910
|
-
tokenCostUsd:
|
|
911
|
-
requestCostUsd:
|
|
912
|
-
totalCostUsd:
|
|
882
|
+
estimatedCost: z7.number().nullable().optional(),
|
|
883
|
+
tokenCostUsd: z7.number().nullable().optional(),
|
|
884
|
+
requestCostUsd: z7.number().nullable().optional(),
|
|
885
|
+
totalCostUsd: z7.number().nullable().optional(),
|
|
913
886
|
estimatedCostBasis: PricingBasisSchema.optional()
|
|
914
887
|
});
|
|
915
888
|
var TestResolutionFieldsSchema = {
|
|
916
|
-
missingIds:
|
|
917
|
-
resolvedAliases:
|
|
918
|
-
ambiguousAliases:
|
|
919
|
-
suggestions:
|
|
920
|
-
missingDiagnostics:
|
|
889
|
+
missingIds: z7.array(z7.string()).optional(),
|
|
890
|
+
resolvedAliases: z7.record(z7.string(), z7.string()).optional(),
|
|
891
|
+
ambiguousAliases: z7.record(z7.string(), z7.array(z7.string())).optional(),
|
|
892
|
+
suggestions: z7.record(z7.string(), z7.array(SuggestionEntrySchema)).optional(),
|
|
893
|
+
missingDiagnostics: z7.record(z7.string(), MissingModelDiagnosticSchema).optional()
|
|
921
894
|
};
|
|
922
|
-
var TestDryRunResponseSchema =
|
|
923
|
-
dryRun:
|
|
924
|
-
results:
|
|
925
|
-
disclaimer:
|
|
895
|
+
var TestDryRunResponseSchema = z7.object({
|
|
896
|
+
dryRun: z7.literal(true),
|
|
897
|
+
results: z7.array(TestEstimateResultSchema),
|
|
898
|
+
disclaimer: z7.string(),
|
|
926
899
|
...TestResolutionFieldsSchema
|
|
927
900
|
});
|
|
928
|
-
var TestLiveResponseSchema =
|
|
929
|
-
results:
|
|
901
|
+
var TestLiveResponseSchema = z7.object({
|
|
902
|
+
results: z7.array(TestResultSchema),
|
|
930
903
|
...TestResolutionFieldsSchema
|
|
931
904
|
});
|
|
932
|
-
var TestResponseSchema =
|
|
905
|
+
var TestResponseSchema = z7.union([TestDryRunResponseSchema, TestLiveResponseSchema]);
|
|
933
906
|
|
|
934
907
|
// src/server.ts
|
|
935
908
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
936
|
-
import { z as
|
|
909
|
+
import { z as z8 } from "zod";
|
|
937
910
|
|
|
938
911
|
// src/config.ts
|
|
939
912
|
var DEFAULT_BASE_URL = "https://index9.dev";
|
|
@@ -1230,22 +1203,22 @@ async function createServer() {
|
|
|
1230
1203
|
title: TOOLS.find_models.title,
|
|
1231
1204
|
description: TOOLS.find_models.description,
|
|
1232
1205
|
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:
|
|
1206
|
+
q: z8.string().min(1).optional().describe(PARAM_DESCRIPTIONS.q),
|
|
1207
|
+
limit: z8.number().int().min(1).max(100).default(20).describe("Page size (1-100, default 20)."),
|
|
1208
|
+
cursor: z8.string().min(1).optional().describe(PARAM_DESCRIPTIONS.cursor),
|
|
1209
|
+
sortBy: z8.enum(["relevance", "created", "price"]).default("relevance").describe(PARAM_DESCRIPTIONS.sortBy),
|
|
1210
|
+
sortOrder: z8.enum(["asc", "desc"]).optional().describe("Sort order. Defaults by sortBy."),
|
|
1211
|
+
createdAfter: z8.string().optional().describe("Lower bound for model created timestamp."),
|
|
1212
|
+
createdBefore: z8.string().optional().describe("Upper bound for model created timestamp."),
|
|
1213
|
+
minPrice: z8.number().min(0).optional().describe(PARAM_DESCRIPTIONS.minPrice),
|
|
1214
|
+
maxPrice: z8.number().min(0).optional().describe(PARAM_DESCRIPTIONS.maxPrice),
|
|
1215
|
+
minContext: z8.number().int().min(1).optional().describe("Minimum context window in tokens."),
|
|
1216
|
+
capabilitiesAll: z8.array(z8.enum(CAPABILITIES)).optional().describe(PARAM_DESCRIPTIONS.capabilitiesAll),
|
|
1217
|
+
capabilitiesAny: z8.array(z8.enum(CAPABILITIES)).optional().describe(PARAM_DESCRIPTIONS.capabilitiesAny),
|
|
1218
|
+
modality: z8.enum(OUTPUT_MODALITIES).optional().describe(PARAM_DESCRIPTIONS.modality),
|
|
1219
|
+
provider: z8.array(z8.string().min(1)).optional().describe(PARAM_DESCRIPTIONS.provider),
|
|
1220
|
+
excludeFree: z8.boolean().optional().describe(PARAM_DESCRIPTIONS.excludeFree),
|
|
1221
|
+
requireKeywordMatch: z8.boolean().optional().describe(PARAM_DESCRIPTIONS.requireKeywordMatch)
|
|
1249
1222
|
},
|
|
1250
1223
|
outputSchema: FindModelsToolResultSchema.shape,
|
|
1251
1224
|
annotations: { readOnlyHint: true }
|
|
@@ -1258,8 +1231,8 @@ async function createServer() {
|
|
|
1258
1231
|
title: TOOLS.get_models.title,
|
|
1259
1232
|
description: TOOLS.get_models.description,
|
|
1260
1233
|
inputSchema: {
|
|
1261
|
-
ids:
|
|
1262
|
-
maxDescriptionChars:
|
|
1234
|
+
ids: z8.array(z8.string().min(1)).min(1).max(100).describe("Model identifiers or aliases. Up to 100."),
|
|
1235
|
+
maxDescriptionChars: z8.number().int().min(0).max(2e3).optional().describe("Truncate descriptions to this many characters.")
|
|
1263
1236
|
},
|
|
1264
1237
|
outputSchema: GetModelsToolResultSchema.shape,
|
|
1265
1238
|
annotations: { readOnlyHint: true }
|
|
@@ -1272,13 +1245,13 @@ async function createServer() {
|
|
|
1272
1245
|
title: TOOLS.compare_models.title,
|
|
1273
1246
|
description: TOOLS.compare_models.description,
|
|
1274
1247
|
inputSchema: {
|
|
1275
|
-
ids:
|
|
1248
|
+
ids: z8.array(z8.string().min(1)).min(2).max(LIMITS.compareModelsMax).describe(
|
|
1276
1249
|
`Model identifiers or aliases to compare (2-${LIMITS.compareModelsMax}). Same alias formats as get_models.`
|
|
1277
1250
|
),
|
|
1278
|
-
expectedPromptTokens:
|
|
1251
|
+
expectedPromptTokens: z8.number().int().min(1).optional().describe(
|
|
1279
1252
|
"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
1253
|
),
|
|
1281
|
-
expectedCompletionTokens:
|
|
1254
|
+
expectedCompletionTokens: z8.number().int().min(1).optional().describe(
|
|
1282
1255
|
"Optional. Pair with expectedPromptTokens to surface workloadCosts and cheapestForRealisticWorkload. Both must be set to enable workload costing."
|
|
1283
1256
|
)
|
|
1284
1257
|
},
|
|
@@ -1304,39 +1277,39 @@ async function createServer() {
|
|
|
1304
1277
|
title: TOOLS.test_model.title,
|
|
1305
1278
|
description: TOOLS.test_model.description,
|
|
1306
1279
|
inputSchema: {
|
|
1307
|
-
prompt:
|
|
1308
|
-
userContent:
|
|
1309
|
-
dryRun:
|
|
1280
|
+
prompt: z8.string().min(1).optional().describe("Prompt sent to each model."),
|
|
1281
|
+
userContent: z8.array(UserContentPartSchema).min(1).optional().describe("Multimodal user content. At least one of prompt or userContent required."),
|
|
1282
|
+
dryRun: z8.boolean().optional().describe(
|
|
1310
1283
|
"When true, returns estimated token usage and cost without calling OpenRouter (no API key required)."
|
|
1311
1284
|
),
|
|
1312
|
-
expectedPromptTokens:
|
|
1313
|
-
expectedCompletionTokens:
|
|
1314
|
-
models:
|
|
1315
|
-
timeoutMs:
|
|
1316
|
-
maxTokens:
|
|
1285
|
+
expectedPromptTokens: z8.number().int().min(1).optional().describe(PARAM_DESCRIPTIONS.expectedPromptTokens),
|
|
1286
|
+
expectedCompletionTokens: z8.number().int().min(1).optional().describe(PARAM_DESCRIPTIONS.expectedCompletionTokens),
|
|
1287
|
+
models: z8.array(z8.string().min(1)).min(1).max(LIMITS.testModelsMax).describe(`Model IDs to evaluate (1-${LIMITS.testModelsMax}).`),
|
|
1288
|
+
timeoutMs: z8.number().int().min(1).optional().describe("Per-model timeout in ms (default 15000, max 60000)."),
|
|
1289
|
+
maxTokens: z8.number().int().min(1).optional().describe(
|
|
1317
1290
|
"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
1291
|
),
|
|
1319
|
-
systemPrompt:
|
|
1320
|
-
temperature:
|
|
1321
|
-
topP:
|
|
1322
|
-
seed:
|
|
1292
|
+
systemPrompt: z8.string().min(1).optional().describe("System instruction prepended to prompt."),
|
|
1293
|
+
temperature: z8.number().min(0).max(2).optional().describe("Sampling temperature (0-2)."),
|
|
1294
|
+
topP: z8.number().gt(0).max(1).optional().describe("Nucleus sampling (0-1]."),
|
|
1295
|
+
seed: z8.number().int().optional().describe("Seed for repeatable outputs."),
|
|
1323
1296
|
responseFormat: ResponseFormatSchema.describe(
|
|
1324
1297
|
"Structured output shape request forwarded to OpenRouter (e.g., { type: 'json_object' })."
|
|
1325
1298
|
),
|
|
1326
|
-
enforceJson:
|
|
1327
|
-
retries:
|
|
1328
|
-
stream:
|
|
1299
|
+
enforceJson: z8.boolean().optional().describe("When true, output must parse as JSON."),
|
|
1300
|
+
retries: z8.number().int().min(0).max(3).optional().describe("Retries for transient failures."),
|
|
1301
|
+
stream: z8.boolean().optional().describe(
|
|
1329
1302
|
"Use OpenRouter SSE streaming so capacity/refusal errors surface quickly. Defaults to false."
|
|
1330
1303
|
),
|
|
1331
|
-
firstTokenTimeoutMs:
|
|
1304
|
+
firstTokenTimeoutMs: z8.number().int().min(1).optional().describe("Streaming-only first-token deadline in ms. Defaults to 10000."),
|
|
1332
1305
|
providerSort: ProviderSortSchema.optional().describe(
|
|
1333
1306
|
'OpenRouter provider routing sort: "throughput", "price", or "latency".'
|
|
1334
1307
|
),
|
|
1335
|
-
providerOrder:
|
|
1336
|
-
fallbackModels:
|
|
1308
|
+
providerOrder: z8.array(z8.string().min(1)).min(1).max(8).optional().describe("Provider slugs to try first, in order. Up to 8."),
|
|
1309
|
+
fallbackModels: z8.array(z8.string().min(1)).min(1).max(5).optional().describe(
|
|
1337
1310
|
"Fallback model IDs OpenRouter may try if the primary is unavailable. Up to 5."
|
|
1338
1311
|
),
|
|
1339
|
-
debug:
|
|
1312
|
+
debug: z8.boolean().optional().describe(
|
|
1340
1313
|
"When true, include upstream finish_reason, provider, error, refusal, and usage."
|
|
1341
1314
|
)
|
|
1342
1315
|
},
|
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.4",
|
|
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.4",
|
|
17
17
|
"transport": {
|
|
18
18
|
"type": "stdio"
|
|
19
19
|
},
|