mcp-metacritic 1.1.2 → 1.2.1
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/README.md +4 -0
- package/dist/index.js +160 -109
- package/dist/index.js.map +1 -1
- package/dist/mc/client.js +1 -1
- package/dist/mc/client.js.map +1 -1
- package/package.json +2 -2
- package/server.json +4 -4
package/README.md
CHANGED
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/mcp-metacritic)
|
|
4
4
|
[](https://github.com/smeet666/mcp-metacritic/actions/workflows/ci.yml)
|
|
5
5
|
[](./LICENSE)
|
|
6
|
+
[](https://registry.modelcontextprotocol.io/v0/servers?search=io.github.smeet666/mcp-metacritic)
|
|
7
|
+
[](https://glama.ai/mcp/servers/smeet666/mcp-metacritic)
|
|
8
|
+
[](https://cursor.com/en/install-mcp?name=metacritic&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIm1jcC1tZXRhY3JpdGljIl19)
|
|
9
|
+
[](https://insiders.vscode.dev/redirect/mcp/install?name=metacritic&config=%7B%22name%22%3A%22metacritic%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22mcp-metacritic%22%5D%7D)
|
|
6
10
|
|
|
7
11
|
An [MCP](https://modelcontextprotocol.io) server for
|
|
8
12
|
[Metacritic](https://www.metacritic.com). Search films, shows and games, read
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
5
5
|
|
|
6
6
|
// src/version.ts
|
|
7
|
-
var PKG_VERSION = "1.
|
|
7
|
+
var PKG_VERSION = "1.2.1";
|
|
8
8
|
var REPO_URL = "https://github.com/smeet666/mcp-metacritic";
|
|
9
9
|
|
|
10
10
|
// src/config.ts
|
|
@@ -129,7 +129,7 @@ function createLogger(level) {
|
|
|
129
129
|
|
|
130
130
|
// src/server.ts
|
|
131
131
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
132
|
-
import { z as
|
|
132
|
+
import { z as z7 } from "zod";
|
|
133
133
|
|
|
134
134
|
// src/mc/cache.ts
|
|
135
135
|
var TtlLruCache = class {
|
|
@@ -898,24 +898,75 @@ var McClient = class {
|
|
|
898
898
|
};
|
|
899
899
|
|
|
900
900
|
// src/tools/browseTitles.ts
|
|
901
|
-
import { z as
|
|
901
|
+
import { z as z3 } from "zod";
|
|
902
902
|
|
|
903
|
-
// src/tools/
|
|
903
|
+
// src/tools/arguments.ts
|
|
904
904
|
import { z } from "zod";
|
|
905
|
+
var INVALID_INPUT = "invalid_input";
|
|
906
|
+
function strictInput(shape) {
|
|
907
|
+
const declared = Object.keys(shape);
|
|
908
|
+
const errorMap = (issue, ctx) => issue.code === z.ZodIssueCode.unrecognized_keys ? { message: unknownArgumentMessage(issue.keys, declared) } : { message: ctx.defaultError };
|
|
909
|
+
return z.strictObject(shape, { errorMap });
|
|
910
|
+
}
|
|
911
|
+
function unknownArgumentMessage(keys, declared) {
|
|
912
|
+
const named = keys.map((key) => {
|
|
913
|
+
const near = nearestArgument(key, declared);
|
|
914
|
+
return near ? `'${key}' (did you mean '${near}'?)` : `'${key}'`;
|
|
915
|
+
}).join(", ");
|
|
916
|
+
return `[${INVALID_INPUT}] Unknown ${keys.length > 1 ? "arguments" : "argument"} ${named}. This tool takes: ${declared.join(", ")}.`;
|
|
917
|
+
}
|
|
918
|
+
function nearestArgument(key, declared) {
|
|
919
|
+
const flatten = (name) => name.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
920
|
+
const flat = flatten(key);
|
|
921
|
+
if (flat.length === 0) return void 0;
|
|
922
|
+
const sameName = declared.find((name) => flatten(name) === flat);
|
|
923
|
+
if (sameName) return sameName;
|
|
924
|
+
const overlapping = declared.find((name) => {
|
|
925
|
+
const other = flatten(name);
|
|
926
|
+
const [shorter, longer] = other.length < flat.length ? [other, flat] : [flat, other];
|
|
927
|
+
return shorter.length >= 3 && (longer.startsWith(shorter) || longer.endsWith(shorter));
|
|
928
|
+
});
|
|
929
|
+
if (overlapping) return overlapping;
|
|
930
|
+
let closest;
|
|
931
|
+
let shortest = Number.POSITIVE_INFINITY;
|
|
932
|
+
for (const name of declared) {
|
|
933
|
+
const distance = editDistance(flat, flatten(name));
|
|
934
|
+
if (distance < shortest) {
|
|
935
|
+
shortest = distance;
|
|
936
|
+
closest = name;
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
return shortest <= Math.max(1, Math.floor(flat.length / 3)) ? closest : void 0;
|
|
940
|
+
}
|
|
941
|
+
function editDistance(left, right) {
|
|
942
|
+
let previous = Array.from({ length: right.length + 1 }, (_, index) => index);
|
|
943
|
+
for (let row = 1; row <= left.length; row += 1) {
|
|
944
|
+
const current = [row];
|
|
945
|
+
for (let column = 1; column <= right.length; column += 1) {
|
|
946
|
+
const substitution = previous[column - 1] + (left[row - 1] === right[column - 1] ? 0 : 1);
|
|
947
|
+
current[column] = Math.min(substitution, previous[column] + 1, current[column - 1] + 1);
|
|
948
|
+
}
|
|
949
|
+
previous = current;
|
|
950
|
+
}
|
|
951
|
+
return previous[right.length];
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
// src/tools/shared.ts
|
|
955
|
+
import { z as z2 } from "zod";
|
|
905
956
|
var MAX_TEXT_MIRROR_CHARS = 2e3;
|
|
906
957
|
var ATTRIBUTION = "Source: Metacritic";
|
|
907
|
-
var kindSchema =
|
|
908
|
-
var titleSummarySchema =
|
|
909
|
-
id:
|
|
910
|
-
kind:
|
|
911
|
-
title:
|
|
912
|
-
slug:
|
|
913
|
-
year:
|
|
914
|
-
release_date:
|
|
915
|
-
rating:
|
|
916
|
-
metascore:
|
|
917
|
-
user_score:
|
|
918
|
-
source_url:
|
|
958
|
+
var kindSchema = z2.enum(["movie", "show", "game"]).describe("Which catalogue the entry belongs to. Pass it back with the slug.");
|
|
959
|
+
var titleSummarySchema = z2.object({
|
|
960
|
+
id: z2.number().int(),
|
|
961
|
+
kind: z2.enum(["movie", "show", "game"]),
|
|
962
|
+
title: z2.string(),
|
|
963
|
+
slug: z2.string().describe("Identifier to pass to get_title and get_reviews, with 'kind'."),
|
|
964
|
+
year: z2.number().int().nullable(),
|
|
965
|
+
release_date: z2.string().nullable(),
|
|
966
|
+
rating: z2.string().nullable().describe("Age rating as published, such as R or TV-MA."),
|
|
967
|
+
metascore: z2.number().nullable().describe("Critic score, out of 100. Not comparable to user_score without rescaling."),
|
|
968
|
+
user_score: z2.number().nullable().describe("Audience score, out of 10. Not comparable to metascore without rescaling."),
|
|
969
|
+
source_url: z2.string().describe("Metacritic page. Show this when citing the entry.")
|
|
919
970
|
});
|
|
920
971
|
function toTitleSummaryOut(title) {
|
|
921
972
|
return {
|
|
@@ -931,14 +982,14 @@ function toTitleSummaryOut(title) {
|
|
|
931
982
|
source_url: title.sourceUrl
|
|
932
983
|
};
|
|
933
984
|
}
|
|
934
|
-
var scoreSchema =
|
|
935
|
-
score:
|
|
936
|
-
max:
|
|
937
|
-
review_count:
|
|
938
|
-
positive_count:
|
|
939
|
-
neutral_count:
|
|
940
|
-
negative_count:
|
|
941
|
-
sentiment:
|
|
985
|
+
var scoreSchema = z2.object({
|
|
986
|
+
score: z2.number().nullable(),
|
|
987
|
+
max: z2.number().describe("Scale this score is on: 100 for critics, 10 for users."),
|
|
988
|
+
review_count: z2.number().int().nullable(),
|
|
989
|
+
positive_count: z2.number().int().nullable(),
|
|
990
|
+
neutral_count: z2.number().int().nullable(),
|
|
991
|
+
negative_count: z2.number().int().nullable(),
|
|
992
|
+
sentiment: z2.string().nullable().describe("Metacritic's own wording for the verdict.")
|
|
942
993
|
});
|
|
943
994
|
function toScoreOut(score) {
|
|
944
995
|
return {
|
|
@@ -1027,26 +1078,26 @@ var browseTitlesDescription = [
|
|
|
1027
1078
|
"Scores come back on their own scales, 100 for critics and 10 for users.",
|
|
1028
1079
|
"Paging is approximate: Metacritic does not order tied entries stably, so an entry can appear on two consecutive pages. Deduplicate by slug rather than counting rows."
|
|
1029
1080
|
].join(" ");
|
|
1030
|
-
var
|
|
1031
|
-
kind:
|
|
1032
|
-
sort:
|
|
1081
|
+
var browseTitlesInput = strictInput({
|
|
1082
|
+
kind: z3.enum(["movie", "show", "game"]).default("movie").describe("Which catalogue to list."),
|
|
1083
|
+
sort: z3.enum(["score", "recent", "popular"]).default("score").describe(
|
|
1033
1084
|
"'score' is the critic ranking, 'recent' is by release date, 'popular' is current attention."
|
|
1034
1085
|
),
|
|
1035
|
-
genre:
|
|
1036
|
-
limit:
|
|
1037
|
-
offset:
|
|
1038
|
-
};
|
|
1086
|
+
genre: z3.string().optional().describe("Single genre name, such as Horror. Omit for all genres."),
|
|
1087
|
+
limit: z3.number().int().min(1).max(50).default(20).describe("How many rows to return."),
|
|
1088
|
+
offset: z3.number().int().min(0).default(0).describe("How many rows to skip, for paging.")
|
|
1089
|
+
});
|
|
1039
1090
|
var browseTitlesOutputShape = {
|
|
1040
|
-
kind:
|
|
1041
|
-
sort:
|
|
1042
|
-
genre:
|
|
1043
|
-
results:
|
|
1044
|
-
total_available:
|
|
1045
|
-
offset:
|
|
1046
|
-
next_offset:
|
|
1091
|
+
kind: z3.string(),
|
|
1092
|
+
sort: z3.string(),
|
|
1093
|
+
genre: z3.string().nullable(),
|
|
1094
|
+
results: z3.array(titleSummarySchema),
|
|
1095
|
+
total_available: z3.number().int().describe("How many entries match upstream, which is the size of what this samples."),
|
|
1096
|
+
offset: z3.number().int(),
|
|
1097
|
+
next_offset: z3.number().int().nullable().describe(
|
|
1047
1098
|
"Pass as 'offset' for the next page. Tied entries are not ordered stably upstream, so deduplicate by slug across pages."
|
|
1048
1099
|
),
|
|
1049
|
-
notes:
|
|
1100
|
+
notes: z3.array(z3.string())
|
|
1050
1101
|
};
|
|
1051
1102
|
async function runBrowseTitles(client, args) {
|
|
1052
1103
|
try {
|
|
@@ -1098,7 +1149,7 @@ ${renderTitleList(results)}`;
|
|
|
1098
1149
|
}
|
|
1099
1150
|
|
|
1100
1151
|
// src/tools/getReviews.ts
|
|
1101
|
-
import { z as
|
|
1152
|
+
import { z as z4 } from "zod";
|
|
1102
1153
|
var MAX_QUOTE_CHARS = 600;
|
|
1103
1154
|
var getReviewsDescription = [
|
|
1104
1155
|
"Read individual reviews of a Metacritic entry, from critics or from users.",
|
|
@@ -1108,34 +1159,34 @@ var getReviewsDescription = [
|
|
|
1108
1159
|
"Critic reviews carry the publication and a link to the original article: quote them with both.",
|
|
1109
1160
|
"Critic scores run to 100 and user scores to 10, so do not average the two together."
|
|
1110
1161
|
].join(" ");
|
|
1111
|
-
var
|
|
1112
|
-
slug:
|
|
1162
|
+
var getReviewsInput = strictInput({
|
|
1163
|
+
slug: z4.string().min(1).describe("Identifier from search_titles, such as 'the-matrix'."),
|
|
1113
1164
|
kind: kindSchema,
|
|
1114
|
-
source:
|
|
1115
|
-
sentiment:
|
|
1116
|
-
limit:
|
|
1117
|
-
offset:
|
|
1118
|
-
};
|
|
1119
|
-
var reviewSchema =
|
|
1120
|
-
quote:
|
|
1121
|
-
score:
|
|
1122
|
-
max:
|
|
1123
|
-
publication:
|
|
1124
|
-
author:
|
|
1125
|
-
url:
|
|
1126
|
-
date:
|
|
1165
|
+
source: z4.enum(["critic", "user"]).default("critic").describe("'critic' is the professional press, 'user' is the audience."),
|
|
1166
|
+
sentiment: z4.enum(["all", "positive", "neutral", "negative"]).default("all").describe("Which slice to read. Metacritic groups reviews this way itself."),
|
|
1167
|
+
limit: z4.number().int().min(1).max(50).default(10).describe("How many reviews to return from the sample Metacritic publishes."),
|
|
1168
|
+
offset: z4.number().int().min(0).default(0).describe("How many of the sampled reviews to skip. The sample itself cannot be paged past.")
|
|
1169
|
+
});
|
|
1170
|
+
var reviewSchema = z4.object({
|
|
1171
|
+
quote: z4.string().nullable().describe("Excerpt as published, truncated if long."),
|
|
1172
|
+
score: z4.number().nullable(),
|
|
1173
|
+
max: z4.number().describe("Scale for this review's score: 100 for critics, 10 for users."),
|
|
1174
|
+
publication: z4.string().nullable().describe("Who ran it. Name it when quoting."),
|
|
1175
|
+
author: z4.string().nullable(),
|
|
1176
|
+
url: z4.string().nullable().describe("Original article. Link it when quoting."),
|
|
1177
|
+
date: z4.string().nullable()
|
|
1127
1178
|
});
|
|
1128
1179
|
var getReviewsOutputShape = {
|
|
1129
|
-
slug:
|
|
1130
|
-
kind:
|
|
1131
|
-
source_url:
|
|
1132
|
-
source:
|
|
1133
|
-
sentiment:
|
|
1134
|
-
reviews:
|
|
1135
|
-
total_available:
|
|
1136
|
-
offset:
|
|
1137
|
-
next_offset:
|
|
1138
|
-
notes:
|
|
1180
|
+
slug: z4.string(),
|
|
1181
|
+
kind: z4.string(),
|
|
1182
|
+
source_url: z4.string().describe("Metacritic page these reviews belong to. Cite it when an article link is missing."),
|
|
1183
|
+
source: z4.string(),
|
|
1184
|
+
sentiment: z4.string(),
|
|
1185
|
+
reviews: z4.array(reviewSchema),
|
|
1186
|
+
total_available: z4.number().int().describe("How many reviews Metacritic counts in total. Usually far more than it serves here."),
|
|
1187
|
+
offset: z4.number().int(),
|
|
1188
|
+
next_offset: z4.number().int().nullable().describe("Pass as 'offset' for the next page."),
|
|
1189
|
+
notes: z4.array(z4.string())
|
|
1139
1190
|
};
|
|
1140
1191
|
async function runGetReviews(client, args) {
|
|
1141
1192
|
try {
|
|
@@ -1219,7 +1270,7 @@ ${listing}`;
|
|
|
1219
1270
|
}
|
|
1220
1271
|
|
|
1221
1272
|
// src/tools/getTitle.ts
|
|
1222
|
-
import { z as
|
|
1273
|
+
import { z as z5 } from "zod";
|
|
1223
1274
|
var SECTIONS = ["basic", "scores", "awards", "production", "networks", "where_to_watch"];
|
|
1224
1275
|
var getTitleDescription = [
|
|
1225
1276
|
"Read one Metacritic entry by slug and kind, both from search_titles.",
|
|
@@ -1229,38 +1280,38 @@ var getTitleDescription = [
|
|
|
1229
1280
|
"'networks' lists the broadcasters of a show; 'where_to_watch' costs an extra request and covers films and shows only.",
|
|
1230
1281
|
"A long description paginates: when 'truncated' is true, call again with 'offset' set to 'next_offset'."
|
|
1231
1282
|
].join(" ");
|
|
1232
|
-
var
|
|
1233
|
-
slug:
|
|
1283
|
+
var getTitleInput = strictInput({
|
|
1284
|
+
slug: z5.string().min(1).describe("Identifier from search_titles, such as 'the-matrix'."),
|
|
1234
1285
|
kind: kindSchema,
|
|
1235
|
-
sections:
|
|
1236
|
-
max_chars:
|
|
1237
|
-
offset:
|
|
1238
|
-
};
|
|
1286
|
+
sections: z5.array(z5.enum(SECTIONS)).default(["basic", "scores"]).describe("Which parts to return. Each extra section beyond the default costs a request."),
|
|
1287
|
+
max_chars: z5.number().int().min(200).max(2e4).default(4e3).describe("Character budget for the description."),
|
|
1288
|
+
offset: z5.number().int().min(0).default(0).describe("Where to resume the description.")
|
|
1289
|
+
});
|
|
1239
1290
|
var getTitleOutputShape = {
|
|
1240
1291
|
title: titleSummarySchema,
|
|
1241
|
-
description:
|
|
1242
|
-
tagline:
|
|
1243
|
-
genres:
|
|
1244
|
-
duration_minutes:
|
|
1245
|
-
imdb_id:
|
|
1246
|
-
total_chars:
|
|
1247
|
-
returned_chars:
|
|
1248
|
-
offset:
|
|
1249
|
-
next_offset:
|
|
1250
|
-
truncated:
|
|
1292
|
+
description: z5.string().nullable(),
|
|
1293
|
+
tagline: z5.string().nullable(),
|
|
1294
|
+
genres: z5.array(z5.string()),
|
|
1295
|
+
duration_minutes: z5.number().int().nullable().describe("Runtime in minutes for a film, or the length of a typical episode for a show."),
|
|
1296
|
+
imdb_id: z5.string().nullable().describe("IMDb identifier, usable to cross-reference other sources."),
|
|
1297
|
+
total_chars: z5.number().int().describe("Length of the full description."),
|
|
1298
|
+
returned_chars: z5.number().int(),
|
|
1299
|
+
offset: z5.number().int(),
|
|
1300
|
+
next_offset: z5.number().int().nullable().describe("Pass as 'offset' to read the rest."),
|
|
1301
|
+
truncated: z5.boolean(),
|
|
1251
1302
|
critic_score: scoreSchema.nullable(),
|
|
1252
1303
|
user_score: scoreSchema.nullable(),
|
|
1253
|
-
awards:
|
|
1254
|
-
|
|
1255
|
-
ceremony:
|
|
1256
|
-
wins:
|
|
1257
|
-
nominations:
|
|
1304
|
+
awards: z5.array(
|
|
1305
|
+
z5.object({
|
|
1306
|
+
ceremony: z5.string().describe("Awards body, such as 'Academy Awards, USA'."),
|
|
1307
|
+
wins: z5.number().int().nullable().describe("Null when the source records no win."),
|
|
1308
|
+
nominations: z5.number().int().nullable()
|
|
1258
1309
|
})
|
|
1259
1310
|
).optional().describe("One tally per ceremony. Metacritic publishes no per-category detail."),
|
|
1260
|
-
networks:
|
|
1261
|
-
production:
|
|
1262
|
-
where_to_watch:
|
|
1263
|
-
notes:
|
|
1311
|
+
networks: z5.array(z5.string()).optional().describe("Broadcasters, for shows."),
|
|
1312
|
+
production: z5.array(z5.object({ name: z5.string(), id: z5.number().int().nullable() })).optional(),
|
|
1313
|
+
where_to_watch: z5.array(z5.object({ provider: z5.string(), kind: z5.string(), url: z5.string().nullable() })).optional(),
|
|
1314
|
+
notes: z5.array(z5.string())
|
|
1264
1315
|
};
|
|
1265
1316
|
async function runGetTitle(client, args) {
|
|
1266
1317
|
try {
|
|
@@ -1416,7 +1467,7 @@ function render(item, description, critic, user, wanted, offers, production) {
|
|
|
1416
1467
|
}
|
|
1417
1468
|
|
|
1418
1469
|
// src/tools/searchTitles.ts
|
|
1419
|
-
import { z as
|
|
1470
|
+
import { z as z6 } from "zod";
|
|
1420
1471
|
var searchTitlesDescription = [
|
|
1421
1472
|
"Search Metacritic for films, shows and games by title.",
|
|
1422
1473
|
"Returns one compact row per match, carrying the critic Metascore, so a question about the critical verdict needs no second call.",
|
|
@@ -1425,18 +1476,18 @@ var searchTitlesDescription = [
|
|
|
1425
1476
|
"There is no paging: 'limit' is the only lever, and results always start from the most relevant match.",
|
|
1426
1477
|
"This searches titles only. It cannot find an entry from a plot detail, a person or a studio."
|
|
1427
1478
|
].join(" ");
|
|
1428
|
-
var
|
|
1429
|
-
query:
|
|
1430
|
-
kind:
|
|
1431
|
-
limit:
|
|
1432
|
-
};
|
|
1479
|
+
var searchTitlesInput = strictInput({
|
|
1480
|
+
query: z6.string().min(1).describe("Title or part of one, for example 'the matrix'."),
|
|
1481
|
+
kind: z6.enum(["movie", "show", "game", "any"]).default("any").describe("Restrict results to one catalogue. Metacritic searches all three at once."),
|
|
1482
|
+
limit: z6.number().int().min(1).max(50).default(10).describe("How many rows to return.")
|
|
1483
|
+
});
|
|
1433
1484
|
var searchTitlesOutputShape = {
|
|
1434
|
-
query:
|
|
1435
|
-
results:
|
|
1436
|
-
total_available:
|
|
1485
|
+
query: z6.string(),
|
|
1486
|
+
results: z6.array(titleSummarySchema),
|
|
1487
|
+
total_available: z6.number().int().describe(
|
|
1437
1488
|
"How many entries Metacritic counted. For a query of several words it counts entries matching any one of them, so the number is far larger than the useful matches and should not be read as a match count."
|
|
1438
1489
|
),
|
|
1439
|
-
notes:
|
|
1490
|
+
notes: z6.array(z6.string())
|
|
1440
1491
|
};
|
|
1441
1492
|
async function runSearchTitles(client, args) {
|
|
1442
1493
|
try {
|
|
@@ -1502,8 +1553,8 @@ function createServer(options = {}) {
|
|
|
1502
1553
|
{
|
|
1503
1554
|
title: "Search Metacritic",
|
|
1504
1555
|
description: searchTitlesDescription,
|
|
1505
|
-
inputSchema:
|
|
1506
|
-
outputSchema:
|
|
1556
|
+
inputSchema: searchTitlesInput,
|
|
1557
|
+
outputSchema: z7.object(searchTitlesOutputShape),
|
|
1507
1558
|
annotations: READ_ONLY
|
|
1508
1559
|
},
|
|
1509
1560
|
async (args) => runSearchTitles(client, args)
|
|
@@ -1513,8 +1564,8 @@ function createServer(options = {}) {
|
|
|
1513
1564
|
{
|
|
1514
1565
|
title: "Read an entry",
|
|
1515
1566
|
description: getTitleDescription,
|
|
1516
|
-
inputSchema:
|
|
1517
|
-
outputSchema:
|
|
1567
|
+
inputSchema: getTitleInput,
|
|
1568
|
+
outputSchema: z7.object(getTitleOutputShape),
|
|
1518
1569
|
annotations: READ_ONLY
|
|
1519
1570
|
},
|
|
1520
1571
|
async (args) => runGetTitle(client, args)
|
|
@@ -1524,8 +1575,8 @@ function createServer(options = {}) {
|
|
|
1524
1575
|
{
|
|
1525
1576
|
title: "Read reviews",
|
|
1526
1577
|
description: getReviewsDescription,
|
|
1527
|
-
inputSchema:
|
|
1528
|
-
outputSchema:
|
|
1578
|
+
inputSchema: getReviewsInput,
|
|
1579
|
+
outputSchema: z7.object(getReviewsOutputShape),
|
|
1529
1580
|
annotations: READ_ONLY
|
|
1530
1581
|
},
|
|
1531
1582
|
async (args) => runGetReviews(client, args)
|
|
@@ -1535,8 +1586,8 @@ function createServer(options = {}) {
|
|
|
1535
1586
|
{
|
|
1536
1587
|
title: "Browse rankings",
|
|
1537
1588
|
description: browseTitlesDescription,
|
|
1538
|
-
inputSchema:
|
|
1539
|
-
outputSchema:
|
|
1589
|
+
inputSchema: browseTitlesInput,
|
|
1590
|
+
outputSchema: z7.object(browseTitlesOutputShape),
|
|
1540
1591
|
annotations: READ_ONLY
|
|
1541
1592
|
},
|
|
1542
1593
|
async (args) => runBrowseTitles(client, args)
|