@cite42/mcp 0.8.3 → 0.9.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 +8 -0
- package/dist/stdio.cjs +42 -9
- package/dist/stdio.mjs +42 -9
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -55,6 +55,14 @@ claude mcp add --transport http --scope user cite42 https://mcp.cite42.dev && cl
|
|
|
55
55
|
|
|
56
56
|
Your browser opens to sign in. Then start Claude Code, or restart it if it was already open, and check with `/mcp`.
|
|
57
57
|
|
|
58
|
+
Or install Cite42 as a plugin from inside Claude Code:
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
/plugin install cite42 --marketplace Cite42/mcp
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Claude Code versions before 2.1.275 need two steps: `/plugin marketplace add Cite42/mcp`, then `/plugin install cite42@cite42`. Then open `/mcp`, pick the Cite42 server and sign in.
|
|
65
|
+
|
|
58
66
|
### Codex CLI
|
|
59
67
|
|
|
60
68
|
```bash
|
package/dist/stdio.cjs
CHANGED
|
@@ -141,11 +141,11 @@ var import_mcp = require("@mastra/mcp");
|
|
|
141
141
|
// src/tools.ts
|
|
142
142
|
var import_tools = require("@mastra/core/tools");
|
|
143
143
|
var import_zod = require("zod");
|
|
144
|
-
var modelEnum = import_zod.z.enum(["chatgpt", "claude", "perplexity", "gemini", "google_ai_overview"]);
|
|
144
|
+
var modelEnum = import_zod.z.enum(["chatgpt", "claude", "perplexity", "gemini", "google_ai_overview", "chatgpt_app"]);
|
|
145
145
|
var QUERY_MAX_CHARS = 2e3;
|
|
146
146
|
var SHORT_TEXT_MAX_CHARS = 200;
|
|
147
147
|
var TIMEFRAME_MAX_CHARS = 80;
|
|
148
|
-
var MODEL_SELECTION_DESCRIPTION = "AI surfaces to query, each billed separately; pass a subset when the user names surfaces or wants a lower cost. Omit for the defaults (chatgpt, perplexity, gemini); fullSweep queries all five. google_ai_overview accepts queries up to 700 characters, the others 2000.";
|
|
148
|
+
var MODEL_SELECTION_DESCRIPTION = "AI surfaces to query, each billed separately; pass a subset when the user names surfaces or wants a lower cost. Omit for the defaults (chatgpt, perplexity, gemini); fullSweep queries all five. google_ai_overview accepts queries up to 700 characters, the others 2000. chatgpt_app (answers captured from the ChatGPT app itself) is opt-in and runs in trackers only for now.";
|
|
149
149
|
var FULL_SWEEP_DESCRIPTION = "Query all five AI surfaces (adds claude and google_ai_overview) for full cross-surface coverage, at a higher cost. Ignored when models is given.";
|
|
150
150
|
var PAID_TOOL_BILLING = "Billed in USD (result field cite42Billing) to the user's prepaid Cite42 balance; exact prices from cite42_pricing (free). For plans over 20 calls or $5, estimate the cost and confirm with the user first.";
|
|
151
151
|
var RECOMMENDATIONS_INPUT_NOTE = "Its requestId can be passed to cite42_recommendations when the user asks for improvement advice.";
|
|
@@ -217,6 +217,15 @@ function optionalShortText(description) {
|
|
|
217
217
|
}
|
|
218
218
|
var modelsInput = import_zod.z.array(modelEnum).nonempty().optional().describe(MODEL_SELECTION_DESCRIPTION);
|
|
219
219
|
var fullSweepInput = import_zod.z.boolean().optional().describe(FULL_SWEEP_DESCRIPTION);
|
|
220
|
+
var AI_MARKETS_ENABLED = true;
|
|
221
|
+
var aiMarketInput = AI_MARKETS_ENABLED ? {
|
|
222
|
+
country: import_zod.z.string().trim().max(8).optional().describe(
|
|
223
|
+
`Optional ISO-2 country to measure from, e.g. "gb". Omit for each surface's default. Gemini has no country setting and ignores it.`
|
|
224
|
+
),
|
|
225
|
+
language: import_zod.z.string().trim().max(8).optional().describe(
|
|
226
|
+
"Optional ISO-2 language for google_ai_overview and chatgpt_app, which read in it. Needs country; defaults to the country's main language."
|
|
227
|
+
)
|
|
228
|
+
} : {};
|
|
220
229
|
var competitorList = import_zod.z.array(shortText("Competitor brand/domain name.")).nonempty().max(20);
|
|
221
230
|
async function fetchBalance() {
|
|
222
231
|
const usage = await aivGet("/usage");
|
|
@@ -277,7 +286,8 @@ var aivSearch = (0, import_tools.createTool)({
|
|
|
277
286
|
inputSchema: import_zod.z.object({
|
|
278
287
|
query: queryText("The concise AI-search/market-research query to run against the selected models."),
|
|
279
288
|
models: modelsInput,
|
|
280
|
-
fullSweep: fullSweepInput
|
|
289
|
+
fullSweep: fullSweepInput,
|
|
290
|
+
...aiMarketInput
|
|
281
291
|
}),
|
|
282
292
|
execute: async (input) => aivPost("/search", input)
|
|
283
293
|
});
|
|
@@ -289,7 +299,8 @@ var aivCitations = (0, import_tools.createTool)({
|
|
|
289
299
|
query: queryText("The concise query to look up cited sources for."),
|
|
290
300
|
url: import_zod.z.string().trim().max(500).optional().describe("Optional URL to check whether it was cited."),
|
|
291
301
|
models: modelsInput,
|
|
292
|
-
fullSweep: fullSweepInput
|
|
302
|
+
fullSweep: fullSweepInput,
|
|
303
|
+
...aiMarketInput
|
|
293
304
|
}),
|
|
294
305
|
execute: async (input) => aivPost("/citations", input)
|
|
295
306
|
});
|
|
@@ -301,7 +312,8 @@ var aivRankings = (0, import_tools.createTool)({
|
|
|
301
312
|
query: queryText("The concise query to measure brand/competitor visibility on."),
|
|
302
313
|
competitors: competitorList.describe("Brand or domain names to track within the AI-generated answers."),
|
|
303
314
|
models: modelsInput,
|
|
304
|
-
fullSweep: fullSweepInput
|
|
315
|
+
fullSweep: fullSweepInput,
|
|
316
|
+
...aiMarketInput
|
|
305
317
|
}),
|
|
306
318
|
execute: async (input) => aivPost("/rankings", input)
|
|
307
319
|
});
|
|
@@ -314,7 +326,8 @@ var aivCompare = (0, import_tools.createTool)({
|
|
|
314
326
|
brand: shortText("Your brand, ranked alongside the competitors."),
|
|
315
327
|
competitors: import_zod.z.array(shortText("Competitor brand/domain name.")).nonempty().max(10).describe("Competitor brand/domain names (up to 10) to rank against your brand."),
|
|
316
328
|
models: modelsInput,
|
|
317
|
-
fullSweep: fullSweepInput
|
|
329
|
+
fullSweep: fullSweepInput,
|
|
330
|
+
...aiMarketInput
|
|
318
331
|
}),
|
|
319
332
|
execute: async (input) => aivPost("/compare", input)
|
|
320
333
|
});
|
|
@@ -326,7 +339,8 @@ var aivSentiment = (0, import_tools.createTool)({
|
|
|
326
339
|
query: queryText("The concise query whose answers are scored for brand sentiment."),
|
|
327
340
|
brand: shortText("The brand to score sentiment for in each model answer."),
|
|
328
341
|
models: modelsInput,
|
|
329
|
-
fullSweep: fullSweepInput
|
|
342
|
+
fullSweep: fullSweepInput,
|
|
343
|
+
...aiMarketInput
|
|
330
344
|
}),
|
|
331
345
|
execute: async (input) => aivPost("/sentiment", input)
|
|
332
346
|
});
|
|
@@ -363,6 +377,24 @@ var aivKeywordsBatch = (0, import_tools.createTool)({
|
|
|
363
377
|
}),
|
|
364
378
|
execute: async (input) => aivPost("/keywords/batch", input)
|
|
365
379
|
});
|
|
380
|
+
var aivKeywordRankings = (0, import_tools.createTool)({
|
|
381
|
+
id: "cite42_keyword_rankings",
|
|
382
|
+
mcp: readOnly("Get Google keyword rankings"),
|
|
383
|
+
description: `Where a site ranks in Google organic results (top 100) for one to five keywords in one country, desktop or mobile: position, ranking URL, competitor positions, the top 10 and whether the AI Overview cites the site. Billed per keyword checked; a keyword that fails is free. Each check is one live sample. ${PAID_TOOL_BILLING}`,
|
|
384
|
+
inputSchema: import_zod.z.object({
|
|
385
|
+
keywords: import_zod.z.array(import_zod.z.string().trim().min(1).max(200)).min(1).max(5).refine(
|
|
386
|
+
(keywords) => new Set(keywords.map((keyword) => keyword.toLowerCase().replace(/\s+/g, " "))).size === keywords.length,
|
|
387
|
+
"Keywords must be distinct."
|
|
388
|
+
).describe("One to five distinct search terms, as people type them into Google. Each is billed separately."),
|
|
389
|
+
domain: import_zod.z.string().trim().max(253).optional().describe("Your site, e.g. example.com. Covers www and subdomains. Omit to get only the top results."),
|
|
390
|
+
url: import_zod.z.string().trim().max(500).optional().describe("Optional page that should rank, as a full URL or a path such as /pricing."),
|
|
391
|
+
competitors: import_zod.z.array(import_zod.z.string().trim().min(1).max(253)).max(5).optional().describe("Up to 5 competitor domains to report positions for."),
|
|
392
|
+
country: import_zod.z.string().trim().max(8).optional().describe('ISO-2 country code of the Google market to check. Defaults to "us".'),
|
|
393
|
+
language: import_zod.z.string().trim().max(8).optional().describe("Optional ISO-2 language code. Defaults to the country's main language."),
|
|
394
|
+
device: import_zod.z.enum(["desktop", "mobile"]).optional().describe("Desktop or mobile results. Defaults to desktop.")
|
|
395
|
+
}),
|
|
396
|
+
execute: async (input) => aivPost("/keywords/rankings", input)
|
|
397
|
+
});
|
|
366
398
|
var aivTrends = (0, import_tools.createTool)({
|
|
367
399
|
id: "cite42_trends",
|
|
368
400
|
mcp: readOnly("Get Google Trends data"),
|
|
@@ -546,7 +578,7 @@ var trackerDefinitionFields = {
|
|
|
546
578
|
),
|
|
547
579
|
url: import_zod.z.string().trim().min(1).max(500).nullish().describe("Citations only: a URL to report on as cited or not cited."),
|
|
548
580
|
models: import_zod.z.array(modelEnum).nonempty().nullish().describe(
|
|
549
|
-
"AI surfaces to query for every prompt. Omit for the three defaults (chatgpt, perplexity, gemini), or list surfaces explicitly
|
|
581
|
+
"AI surfaces to query for every prompt. Omit for the three defaults (chatgpt, perplexity, gemini), or list surfaces explicitly to set the recurring cost; chatgpt_app (the ChatGPT app itself) is opt-in. There is no fullSweep here: a saved tracker stores the exact list it was authorized for."
|
|
550
582
|
)
|
|
551
583
|
};
|
|
552
584
|
var TRACKER_BILLING_DESCRIPTION = "Managing trackers and reading reports is free; each run bills one call per prompt at the per-surface rates.";
|
|
@@ -639,6 +671,7 @@ var CITE42_TOOLS = {
|
|
|
639
671
|
cite42_recommendations: aivRecommendations,
|
|
640
672
|
cite42_keywords: aivKeywords,
|
|
641
673
|
cite42_keywords_batch: aivKeywordsBatch,
|
|
674
|
+
cite42_keyword_rankings: aivKeywordRankings,
|
|
642
675
|
cite42_trends: aivTrends,
|
|
643
676
|
cite42_reddit_trends: aivRedditTrends,
|
|
644
677
|
cite42_youtube_trends: aivYoutubeTrends,
|
|
@@ -674,7 +707,7 @@ if (!resolveApiKey()) {
|
|
|
674
707
|
);
|
|
675
708
|
process.exit(1);
|
|
676
709
|
}
|
|
677
|
-
buildCite42Server("0.
|
|
710
|
+
buildCite42Server("0.9.1").startStdio().catch((error) => {
|
|
678
711
|
console.error("[@cite42/mcp] Fatal error:", error);
|
|
679
712
|
process.exit(1);
|
|
680
713
|
});
|
package/dist/stdio.mjs
CHANGED
|
@@ -140,11 +140,11 @@ import { MCPServer } from "@mastra/mcp";
|
|
|
140
140
|
// src/tools.ts
|
|
141
141
|
import { createTool } from "@mastra/core/tools";
|
|
142
142
|
import { z } from "zod";
|
|
143
|
-
var modelEnum = z.enum(["chatgpt", "claude", "perplexity", "gemini", "google_ai_overview"]);
|
|
143
|
+
var modelEnum = z.enum(["chatgpt", "claude", "perplexity", "gemini", "google_ai_overview", "chatgpt_app"]);
|
|
144
144
|
var QUERY_MAX_CHARS = 2e3;
|
|
145
145
|
var SHORT_TEXT_MAX_CHARS = 200;
|
|
146
146
|
var TIMEFRAME_MAX_CHARS = 80;
|
|
147
|
-
var MODEL_SELECTION_DESCRIPTION = "AI surfaces to query, each billed separately; pass a subset when the user names surfaces or wants a lower cost. Omit for the defaults (chatgpt, perplexity, gemini); fullSweep queries all five. google_ai_overview accepts queries up to 700 characters, the others 2000.";
|
|
147
|
+
var MODEL_SELECTION_DESCRIPTION = "AI surfaces to query, each billed separately; pass a subset when the user names surfaces or wants a lower cost. Omit for the defaults (chatgpt, perplexity, gemini); fullSweep queries all five. google_ai_overview accepts queries up to 700 characters, the others 2000. chatgpt_app (answers captured from the ChatGPT app itself) is opt-in and runs in trackers only for now.";
|
|
148
148
|
var FULL_SWEEP_DESCRIPTION = "Query all five AI surfaces (adds claude and google_ai_overview) for full cross-surface coverage, at a higher cost. Ignored when models is given.";
|
|
149
149
|
var PAID_TOOL_BILLING = "Billed in USD (result field cite42Billing) to the user's prepaid Cite42 balance; exact prices from cite42_pricing (free). For plans over 20 calls or $5, estimate the cost and confirm with the user first.";
|
|
150
150
|
var RECOMMENDATIONS_INPUT_NOTE = "Its requestId can be passed to cite42_recommendations when the user asks for improvement advice.";
|
|
@@ -216,6 +216,15 @@ function optionalShortText(description) {
|
|
|
216
216
|
}
|
|
217
217
|
var modelsInput = z.array(modelEnum).nonempty().optional().describe(MODEL_SELECTION_DESCRIPTION);
|
|
218
218
|
var fullSweepInput = z.boolean().optional().describe(FULL_SWEEP_DESCRIPTION);
|
|
219
|
+
var AI_MARKETS_ENABLED = true;
|
|
220
|
+
var aiMarketInput = AI_MARKETS_ENABLED ? {
|
|
221
|
+
country: z.string().trim().max(8).optional().describe(
|
|
222
|
+
`Optional ISO-2 country to measure from, e.g. "gb". Omit for each surface's default. Gemini has no country setting and ignores it.`
|
|
223
|
+
),
|
|
224
|
+
language: z.string().trim().max(8).optional().describe(
|
|
225
|
+
"Optional ISO-2 language for google_ai_overview and chatgpt_app, which read in it. Needs country; defaults to the country's main language."
|
|
226
|
+
)
|
|
227
|
+
} : {};
|
|
219
228
|
var competitorList = z.array(shortText("Competitor brand/domain name.")).nonempty().max(20);
|
|
220
229
|
async function fetchBalance() {
|
|
221
230
|
const usage = await aivGet("/usage");
|
|
@@ -276,7 +285,8 @@ var aivSearch = createTool({
|
|
|
276
285
|
inputSchema: z.object({
|
|
277
286
|
query: queryText("The concise AI-search/market-research query to run against the selected models."),
|
|
278
287
|
models: modelsInput,
|
|
279
|
-
fullSweep: fullSweepInput
|
|
288
|
+
fullSweep: fullSweepInput,
|
|
289
|
+
...aiMarketInput
|
|
280
290
|
}),
|
|
281
291
|
execute: async (input) => aivPost("/search", input)
|
|
282
292
|
});
|
|
@@ -288,7 +298,8 @@ var aivCitations = createTool({
|
|
|
288
298
|
query: queryText("The concise query to look up cited sources for."),
|
|
289
299
|
url: z.string().trim().max(500).optional().describe("Optional URL to check whether it was cited."),
|
|
290
300
|
models: modelsInput,
|
|
291
|
-
fullSweep: fullSweepInput
|
|
301
|
+
fullSweep: fullSweepInput,
|
|
302
|
+
...aiMarketInput
|
|
292
303
|
}),
|
|
293
304
|
execute: async (input) => aivPost("/citations", input)
|
|
294
305
|
});
|
|
@@ -300,7 +311,8 @@ var aivRankings = createTool({
|
|
|
300
311
|
query: queryText("The concise query to measure brand/competitor visibility on."),
|
|
301
312
|
competitors: competitorList.describe("Brand or domain names to track within the AI-generated answers."),
|
|
302
313
|
models: modelsInput,
|
|
303
|
-
fullSweep: fullSweepInput
|
|
314
|
+
fullSweep: fullSweepInput,
|
|
315
|
+
...aiMarketInput
|
|
304
316
|
}),
|
|
305
317
|
execute: async (input) => aivPost("/rankings", input)
|
|
306
318
|
});
|
|
@@ -313,7 +325,8 @@ var aivCompare = createTool({
|
|
|
313
325
|
brand: shortText("Your brand, ranked alongside the competitors."),
|
|
314
326
|
competitors: z.array(shortText("Competitor brand/domain name.")).nonempty().max(10).describe("Competitor brand/domain names (up to 10) to rank against your brand."),
|
|
315
327
|
models: modelsInput,
|
|
316
|
-
fullSweep: fullSweepInput
|
|
328
|
+
fullSweep: fullSweepInput,
|
|
329
|
+
...aiMarketInput
|
|
317
330
|
}),
|
|
318
331
|
execute: async (input) => aivPost("/compare", input)
|
|
319
332
|
});
|
|
@@ -325,7 +338,8 @@ var aivSentiment = createTool({
|
|
|
325
338
|
query: queryText("The concise query whose answers are scored for brand sentiment."),
|
|
326
339
|
brand: shortText("The brand to score sentiment for in each model answer."),
|
|
327
340
|
models: modelsInput,
|
|
328
|
-
fullSweep: fullSweepInput
|
|
341
|
+
fullSweep: fullSweepInput,
|
|
342
|
+
...aiMarketInput
|
|
329
343
|
}),
|
|
330
344
|
execute: async (input) => aivPost("/sentiment", input)
|
|
331
345
|
});
|
|
@@ -362,6 +376,24 @@ var aivKeywordsBatch = createTool({
|
|
|
362
376
|
}),
|
|
363
377
|
execute: async (input) => aivPost("/keywords/batch", input)
|
|
364
378
|
});
|
|
379
|
+
var aivKeywordRankings = createTool({
|
|
380
|
+
id: "cite42_keyword_rankings",
|
|
381
|
+
mcp: readOnly("Get Google keyword rankings"),
|
|
382
|
+
description: `Where a site ranks in Google organic results (top 100) for one to five keywords in one country, desktop or mobile: position, ranking URL, competitor positions, the top 10 and whether the AI Overview cites the site. Billed per keyword checked; a keyword that fails is free. Each check is one live sample. ${PAID_TOOL_BILLING}`,
|
|
383
|
+
inputSchema: z.object({
|
|
384
|
+
keywords: z.array(z.string().trim().min(1).max(200)).min(1).max(5).refine(
|
|
385
|
+
(keywords) => new Set(keywords.map((keyword) => keyword.toLowerCase().replace(/\s+/g, " "))).size === keywords.length,
|
|
386
|
+
"Keywords must be distinct."
|
|
387
|
+
).describe("One to five distinct search terms, as people type them into Google. Each is billed separately."),
|
|
388
|
+
domain: z.string().trim().max(253).optional().describe("Your site, e.g. example.com. Covers www and subdomains. Omit to get only the top results."),
|
|
389
|
+
url: z.string().trim().max(500).optional().describe("Optional page that should rank, as a full URL or a path such as /pricing."),
|
|
390
|
+
competitors: z.array(z.string().trim().min(1).max(253)).max(5).optional().describe("Up to 5 competitor domains to report positions for."),
|
|
391
|
+
country: z.string().trim().max(8).optional().describe('ISO-2 country code of the Google market to check. Defaults to "us".'),
|
|
392
|
+
language: z.string().trim().max(8).optional().describe("Optional ISO-2 language code. Defaults to the country's main language."),
|
|
393
|
+
device: z.enum(["desktop", "mobile"]).optional().describe("Desktop or mobile results. Defaults to desktop.")
|
|
394
|
+
}),
|
|
395
|
+
execute: async (input) => aivPost("/keywords/rankings", input)
|
|
396
|
+
});
|
|
365
397
|
var aivTrends = createTool({
|
|
366
398
|
id: "cite42_trends",
|
|
367
399
|
mcp: readOnly("Get Google Trends data"),
|
|
@@ -545,7 +577,7 @@ var trackerDefinitionFields = {
|
|
|
545
577
|
),
|
|
546
578
|
url: z.string().trim().min(1).max(500).nullish().describe("Citations only: a URL to report on as cited or not cited."),
|
|
547
579
|
models: z.array(modelEnum).nonempty().nullish().describe(
|
|
548
|
-
"AI surfaces to query for every prompt. Omit for the three defaults (chatgpt, perplexity, gemini), or list surfaces explicitly
|
|
580
|
+
"AI surfaces to query for every prompt. Omit for the three defaults (chatgpt, perplexity, gemini), or list surfaces explicitly to set the recurring cost; chatgpt_app (the ChatGPT app itself) is opt-in. There is no fullSweep here: a saved tracker stores the exact list it was authorized for."
|
|
549
581
|
)
|
|
550
582
|
};
|
|
551
583
|
var TRACKER_BILLING_DESCRIPTION = "Managing trackers and reading reports is free; each run bills one call per prompt at the per-surface rates.";
|
|
@@ -638,6 +670,7 @@ var CITE42_TOOLS = {
|
|
|
638
670
|
cite42_recommendations: aivRecommendations,
|
|
639
671
|
cite42_keywords: aivKeywords,
|
|
640
672
|
cite42_keywords_batch: aivKeywordsBatch,
|
|
673
|
+
cite42_keyword_rankings: aivKeywordRankings,
|
|
641
674
|
cite42_trends: aivTrends,
|
|
642
675
|
cite42_reddit_trends: aivRedditTrends,
|
|
643
676
|
cite42_youtube_trends: aivYoutubeTrends,
|
|
@@ -673,7 +706,7 @@ if (!resolveApiKey()) {
|
|
|
673
706
|
);
|
|
674
707
|
process.exit(1);
|
|
675
708
|
}
|
|
676
|
-
buildCite42Server("0.
|
|
709
|
+
buildCite42Server("0.9.1").startStdio().catch((error) => {
|
|
677
710
|
console.error("[@cite42/mcp] Fatal error:", error);
|
|
678
711
|
process.exit(1);
|
|
679
712
|
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cite42/mcp",
|
|
3
3
|
"mcpName": "dev.cite42/mcp",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.9.1",
|
|
5
5
|
"description": "Cite42 MCP server: AI visibility and SEO data for AI agents. See how the AI models behind ChatGPT, Claude, Perplexity and Gemini, plus Google AI Overviews, mention your brand and which sources they cite, with SEO keyword data, Google, Reddit and YouTube trends, and weekly or monthly trackers that watch a list of prompts over time. Works with Claude Code, Claude Desktop, Codex CLI, Cursor, and any MCP client.",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"type": "module",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@mastra/core": "^1.68.0",
|
|
28
28
|
"@mastra/mcp": "^1.18.0",
|
|
29
|
-
"zod": "^4.
|
|
29
|
+
"zod": "^4.6.7"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
@@ -86,6 +86,7 @@
|
|
|
86
86
|
"@modelcontextprotocol/client": "2.3.1",
|
|
87
87
|
"@modelcontextprotocol/server": "2.3.1",
|
|
88
88
|
"@modelcontextprotocol/server-legacy": "2.3.1",
|
|
89
|
-
"@modelcontextprotocol/node": "2.1.1"
|
|
89
|
+
"@modelcontextprotocol/node": "2.1.1",
|
|
90
|
+
"body-parser@^2.0.0": "^2.4.0"
|
|
90
91
|
}
|
|
91
92
|
}
|