@index9/mcp 5.0.0 → 5.1.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 +60 -27
- package/manifest.json +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -31,6 +31,16 @@ var COMMON_PROVIDERS = [
|
|
|
31
31
|
// ../core/dist/schemas/common.js
|
|
32
32
|
import { z } from "zod";
|
|
33
33
|
var ErrorResponseSchema = z.object({ error: z.string() }).strict();
|
|
34
|
+
var RateLimitMetaSchema = z.object({
|
|
35
|
+
limit: z.string().optional(),
|
|
36
|
+
remaining: z.string().optional(),
|
|
37
|
+
reset: z.string().optional()
|
|
38
|
+
});
|
|
39
|
+
var Index9MetaSchema = z.object({
|
|
40
|
+
apiBaseUrl: z.string(),
|
|
41
|
+
retryAfterSeconds: z.number().optional(),
|
|
42
|
+
rateLimit: RateLimitMetaSchema.optional()
|
|
43
|
+
});
|
|
34
44
|
var UserContentTextPartSchema = z.strictObject({
|
|
35
45
|
type: z.literal("text"),
|
|
36
46
|
text: z.string().trim().min(1)
|
|
@@ -68,56 +78,54 @@ var LIMITS = {
|
|
|
68
78
|
var MODEL_COUNT = "300+";
|
|
69
79
|
var WORKFLOW_INSTRUCTIONS = `Index9 provides 3 tools for AI model discovery, inspection, and benchmarking.
|
|
70
80
|
|
|
81
|
+
IMPORTANT \u2014 your model knowledge is stale by default.
|
|
82
|
+
New AI models ship weekly; pricing, aliases, and capabilities change. Treat any specific model ID, "flagship" name, or "good default" you recall from training as potentially out of date. Before naming, recommending, or benchmarking models, call find_models to anchor on what is actually live right now. Good first calls:
|
|
83
|
+
- sortBy=created (newest first) to see what has recently landed
|
|
84
|
+
- a semantic query describing the task to see current task-fit candidates
|
|
85
|
+
Skip find_models only when the user has typed a specific provider/model-id.
|
|
86
|
+
|
|
71
87
|
Typical workflow:
|
|
72
|
-
1.
|
|
73
|
-
2.
|
|
74
|
-
3.
|
|
88
|
+
1. find_models \u2014 Discover models by semantic query or filters. Start here unless the user named a specific model.
|
|
89
|
+
2. get_models \u2014 Full metadata for specific IDs or aliases. Use after search, or directly when the user names a model.
|
|
90
|
+
3. test_model \u2014 Run live inference, or set dryRun=true to estimate token usage/cost without running inference.
|
|
75
91
|
|
|
76
92
|
Key rules:
|
|
77
93
|
- find_models requires \`q\` when \`sortBy=relevance\` (the default). Omit \`q\` only with \`sortBy=created\` or \`sortBy=price\`.
|
|
78
|
-
- get_models accepts aliases (display names, short names) \u2014 not just full IDs.
|
|
94
|
+
- get_models accepts aliases (display names, short names) \u2014 not just full IDs. If a model you "know from memory" returns in missingIds, that is a signal to call find_models.
|
|
79
95
|
- Use test_model with \`dryRun=true\` to estimate cost before live testing.
|
|
80
96
|
- test_model with \`dryRun=false\` (default) requires OPENROUTER_API_KEY and incurs real usage costs.
|
|
97
|
+
- Reasoning-capable models (capabilities includes "reasoning") burn hidden reasoning tokens against \`maxTokens\` before emitting visible text. Leave \`maxTokens\` unset, or set it to at least 2000, when testing reasoning models \u2014 otherwise results may fail with finish_reason=length.
|
|
81
98
|
- Cursors are opaque and tied to query/sort/filters. Reuse the same query/sort/filters when paginating. \`limit\` may change between pages.`;
|
|
82
99
|
var TOOLS = {
|
|
83
100
|
find_models: {
|
|
84
101
|
name: "find_models",
|
|
102
|
+
title: "Search AI models",
|
|
85
103
|
summary: "Search and paginate AI models by semantic query or filters",
|
|
86
104
|
description: `Search and filter ${MODEL_COUNT} AI models. Returns ranked results with pricing, context windows, and capabilities.
|
|
87
105
|
|
|
88
|
-
Call this
|
|
106
|
+
Call this first unless the user named a specific model \u2014 your training-data list of "good" models is likely stale.
|
|
89
107
|
|
|
90
|
-
|
|
91
|
-
When the user mentions numeric or categorical constraints, you MUST map them to the structured filter parameters below instead of relying solely on \`q\`. The \`q\` parameter drives semantic ranking but does NOT enforce hard constraints.
|
|
108
|
+
Extract filters from user queries. \`q\` drives semantic ranking; numeric and categorical constraints MUST go in structured filters. Shorthand: 1K=1000, 1M=1000000. Prices are USD per million input tokens.
|
|
92
109
|
|
|
93
110
|
Examples:
|
|
94
|
-
- "
|
|
95
|
-
- "cheap vision model from openai" \u2192 q="cheap vision model", capabilitiesAll="vision", provider="openai"
|
|
96
|
-
- "function calling under $0.50 with 128K
|
|
97
|
-
- "best coding model" \u2192 q="best coding model"
|
|
111
|
+
- "1M context under $1" \u2192 q="model", minContext=1000000, maxPrice=1
|
|
112
|
+
- "cheap vision model from openai" \u2192 q="cheap vision model", capabilitiesAll=["vision"], provider="openai"
|
|
113
|
+
- "function calling under $0.50 with 128K" \u2192 q="function calling", capabilitiesAll=["function_calling"], maxPrice=0.5, minContext=128000
|
|
114
|
+
- "best coding model" \u2192 q="best coding model"
|
|
115
|
+
- "what's new" \u2192 sortBy="created" (no q needed)
|
|
98
116
|
|
|
99
|
-
|
|
117
|
+
Valid capabilities: ${CAPABILITIES.join(", ")}.
|
|
100
118
|
|
|
101
|
-
|
|
102
|
-
- q: Semantic search query \u2014 use for intent/quality ranking, not for numeric constraints
|
|
103
|
-
- provider: Filter by provider(s). Comma-separated for multiple (e.g., 'openai,anthropic')
|
|
104
|
-
- minPrice, maxPrice: Price bounds in USD per million input tokens
|
|
105
|
-
- minContext: Minimum context window in tokens
|
|
106
|
-
- capabilitiesAll: Capabilities the model MUST have (AND logic). Valid: ${CAPABILITIES.join(", ")}
|
|
107
|
-
- capabilitiesAny: Capabilities where at least one must be present (OR logic)
|
|
108
|
-
- sortBy: 'relevance' (default), 'created', 'price'
|
|
109
|
-
- limit: Page size
|
|
110
|
-
- cursor: Opaque pagination cursor
|
|
119
|
+
Each result: id, name, description, created (unix seconds), createdAt (ISO 8601), contextLength, maxOutputTokens, pricing.{promptPerMillion, completionPerMillion} (numbers, USD per million tokens), capabilities[], score.
|
|
111
120
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
Scores: 0-100, higher = more relevant. The best match in each page scores 100; others are scaled proportionally. Combines semantic similarity and keyword matching. Null when sorting by price or date.
|
|
121
|
+
\`score\` is 0-100: the best match per page scores 100; others scale proportionally. Combines semantic similarity and keyword matching. Null when sorting by price or date.
|
|
115
122
|
|
|
116
123
|
Pass result.id to get_models for full specs or to test_model for live testing.`,
|
|
117
124
|
requiresKey: false
|
|
118
125
|
},
|
|
119
126
|
get_models: {
|
|
120
127
|
name: "get_models",
|
|
128
|
+
title: "Inspect AI models",
|
|
121
129
|
summary: "Get full model metadata by IDs or aliases (batch, up to 100)",
|
|
122
130
|
description: `Get full specs for one or more models by id or alias. Accepts up to ${LIMITS.getModelsMax} ids per call \u2014 use this for batch comparison.
|
|
123
131
|
|
|
@@ -137,6 +145,7 @@ Entries in results are null when the id is unknown; those ids appear in missingI
|
|
|
137
145
|
},
|
|
138
146
|
test_model: {
|
|
139
147
|
name: "test_model",
|
|
148
|
+
title: "Test AI models live",
|
|
140
149
|
summary: "Run live inference or dry-run cost estimation across up to 10 models",
|
|
141
150
|
description: `Run model tests on 1-${LIMITS.testModelsMax} models. Use dryRun=true to estimate token usage/cost, or dryRun=false (default) to run live OpenRouter inference.
|
|
142
151
|
|
|
@@ -518,6 +527,9 @@ var SearchResponseSchema = z2.object({
|
|
|
518
527
|
ranking: z2.literal("hybrid_rrf")
|
|
519
528
|
})
|
|
520
529
|
});
|
|
530
|
+
var FindModelsToolResultSchema = SearchResponseSchema.extend({
|
|
531
|
+
_index9: Index9MetaSchema
|
|
532
|
+
});
|
|
521
533
|
|
|
522
534
|
// ../core/dist/schemas/model.js
|
|
523
535
|
import { z as z3 } from "zod";
|
|
@@ -559,6 +571,13 @@ var BatchModelLookupResponseSchema = z3.object({
|
|
|
559
571
|
resolvedAliases: z3.record(z3.string(), z3.string()).optional(),
|
|
560
572
|
ambiguousAliases: z3.record(z3.string(), z3.array(z3.string())).optional()
|
|
561
573
|
}).strict();
|
|
574
|
+
var GetModelsToolResultSchema = z3.object({
|
|
575
|
+
results: z3.array(ModelResponseSchema.nullable()),
|
|
576
|
+
missingIds: z3.array(z3.string()),
|
|
577
|
+
resolvedAliases: z3.record(z3.string(), z3.string()).optional(),
|
|
578
|
+
ambiguousAliases: z3.record(z3.string(), z3.array(z3.string())).optional(),
|
|
579
|
+
_index9: Index9MetaSchema
|
|
580
|
+
});
|
|
562
581
|
|
|
563
582
|
// ../core/dist/schemas/test.js
|
|
564
583
|
import { z as z4 } from "zod";
|
|
@@ -756,10 +775,14 @@ function baseHeaders(ctx) {
|
|
|
756
775
|
return h;
|
|
757
776
|
}
|
|
758
777
|
function toResponse(payload, isError = false) {
|
|
759
|
-
|
|
778
|
+
const response = {
|
|
760
779
|
content: [{ type: "text", text: JSON.stringify(payload) }],
|
|
761
780
|
isError: isError || void 0
|
|
762
781
|
};
|
|
782
|
+
if (!isError && typeof payload === "object" && payload !== null && !Array.isArray(payload)) {
|
|
783
|
+
response.structuredContent = payload;
|
|
784
|
+
}
|
|
785
|
+
return response;
|
|
763
786
|
}
|
|
764
787
|
function parseRetryAfterSeconds(value) {
|
|
765
788
|
if (!value) return void 0;
|
|
@@ -891,6 +914,7 @@ async function createServer() {
|
|
|
891
914
|
server.registerTool(
|
|
892
915
|
"find_models",
|
|
893
916
|
{
|
|
917
|
+
title: TOOLS.find_models.title,
|
|
894
918
|
description: TOOLS.find_models.description,
|
|
895
919
|
inputSchema: {
|
|
896
920
|
q: z5.string().min(1).optional().describe(PARAM_DESCRIPTIONS.q),
|
|
@@ -908,6 +932,7 @@ async function createServer() {
|
|
|
908
932
|
modality: z5.enum(OUTPUT_MODALITIES).optional().describe(PARAM_DESCRIPTIONS.modality),
|
|
909
933
|
provider: z5.string().min(1).optional().describe(PARAM_DESCRIPTIONS.provider)
|
|
910
934
|
},
|
|
935
|
+
outputSchema: FindModelsToolResultSchema.shape,
|
|
911
936
|
annotations: { readOnlyHint: true }
|
|
912
937
|
},
|
|
913
938
|
async (args) => handleSearchModels(ctx, args)
|
|
@@ -915,11 +940,13 @@ async function createServer() {
|
|
|
915
940
|
server.registerTool(
|
|
916
941
|
"get_models",
|
|
917
942
|
{
|
|
943
|
+
title: TOOLS.get_models.title,
|
|
918
944
|
description: TOOLS.get_models.description,
|
|
919
945
|
inputSchema: {
|
|
920
946
|
ids: z5.array(z5.string().min(1)).min(1).max(100).describe("Model identifiers or aliases. Up to 100."),
|
|
921
947
|
maxDescriptionChars: z5.number().int().min(0).max(2e3).optional().describe("Truncate descriptions to this many characters.")
|
|
922
948
|
},
|
|
949
|
+
outputSchema: GetModelsToolResultSchema.shape,
|
|
923
950
|
annotations: { readOnlyHint: true }
|
|
924
951
|
},
|
|
925
952
|
async (args) => handleGetModels(ctx, args)
|
|
@@ -927,6 +954,7 @@ async function createServer() {
|
|
|
927
954
|
server.registerTool(
|
|
928
955
|
"test_model",
|
|
929
956
|
{
|
|
957
|
+
title: TOOLS.test_model.title,
|
|
930
958
|
description: TOOLS.test_model.description,
|
|
931
959
|
inputSchema: {
|
|
932
960
|
prompt: z5.string().min(1).optional().describe("Prompt sent to each model."),
|
|
@@ -937,7 +965,9 @@ async function createServer() {
|
|
|
937
965
|
expectedCompletionTokens: z5.number().int().min(1).optional().describe(PARAM_DESCRIPTIONS.expectedCompletionTokens),
|
|
938
966
|
models: z5.array(z5.string().min(1)).min(1).max(LIMITS.testModelsMax).describe(`Model IDs to evaluate (1-${LIMITS.testModelsMax}).`),
|
|
939
967
|
timeoutMs: z5.number().int().min(1).optional().describe("Per-model timeout in ms (default 15000, max 60000)."),
|
|
940
|
-
maxTokens: z5.number().int().min(1).optional().describe(
|
|
968
|
+
maxTokens: z5.number().int().min(1).optional().describe(
|
|
969
|
+
"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."
|
|
970
|
+
),
|
|
941
971
|
systemPrompt: z5.string().min(1).optional().describe("System instruction prepended to prompt."),
|
|
942
972
|
temperature: z5.number().min(0).max(2).optional().describe("Sampling temperature (0-2)."),
|
|
943
973
|
topP: z5.number().gt(0).max(1).optional().describe("Nucleus sampling (0-1]."),
|
|
@@ -948,6 +978,9 @@ async function createServer() {
|
|
|
948
978
|
enforceJson: z5.boolean().optional().describe("When true, output must parse as JSON."),
|
|
949
979
|
retries: z5.number().int().min(0).max(3).optional().describe("Retries for transient failures.")
|
|
950
980
|
},
|
|
981
|
+
// No outputSchema: test_model returns a z.union of dry-run and live shapes.
|
|
982
|
+
// The SDK supports only ZodRawShape | AnySchema for outputSchema; a discriminated-union
|
|
983
|
+
// output is represented accurately in the tool description instead.
|
|
951
984
|
annotations: { readOnlyHint: false }
|
|
952
985
|
},
|
|
953
986
|
async (args) => handleTestModels(ctx, args)
|
package/manifest.json
CHANGED